From 49239d969d25c25a6945aa297d89d423624998f9 Mon Sep 17 00:00:00 2001 From: Pierre-Jean Leger Date: Sat, 7 Mar 2020 10:37:29 +0100 Subject: [PATCH 0001/5766] Missing format parameter in a serialize call --- components/serializer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index 5f150a212b3..e7ed6f12550 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -625,7 +625,7 @@ defines a ``Person`` entity with a ``firstName`` property: This custom mapping is used to convert property names when serializing and deserializing objects:: - $serialized = $serializer->serialize(new Person("Kévin")); + $serialized = $serializer->serialize(new Person("Kévin"), 'json'); // {"customer_name": "Kévin"} Serializing Boolean Attributes @@ -1450,7 +1450,7 @@ and ``BitBucketCodeRepository`` classes: Once configured, the serializer uses the mapping to pick the correct class:: - $serialized = $serializer->serialize(new GitHubCodeRepository()); + $serialized = $serializer->serialize(new GitHubCodeRepository(), 'json'); // {"type": "github"} $repository = $serializer->deserialize($serialized, CodeRepository::class, 'json'); From 98574f5233c680e0e0a503355fd22ec3e286b4c7 Mon Sep 17 00:00:00 2001 From: Joe Bennett Date: Mon, 8 Jun 2020 15:51:01 +1000 Subject: [PATCH 0002/5766] #37139 Updated Lock MongoDbStore note on readPreference --- components/lock.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index 6dfeb5518dc..257aa2d1cd8 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -647,9 +647,10 @@ about `Expire Data from Collections by Setting TTL`_ in MongoDB. locks don't expire prematurely; the lock TTL should be set with enough extra time in ``expireAfterSeconds`` to account for any clock drift between nodes. -``writeConcern``, ``readConcern`` and ``readPreference`` are not specified by -MongoDbStore meaning the collection's settings will take effect. Read more -about `Replica Set Read and Write Semantics`_ in MongoDB. +``writeConcern`` and ``readConcern`` are not specified by MongoDbStore meaning +the collection's settings will take effect. +``readPreference`` is ``primary`` for all queries. +Read more about `Replica Set Read and Write Semantics`_ in MongoDB. PdoStore ~~~~~~~~~~ From 9b704d57e20072b9f5bcfbe474c99d6eb1b3a771 Mon Sep 17 00:00:00 2001 From: Carlos Pereira De Amorim Date: Fri, 26 Jun 2020 16:09:43 +0200 Subject: [PATCH 0003/5766] Added function to get a specific transition --- workflow.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/workflow.rst b/workflow.rst index 376996534ba..7521705980d 100644 --- a/workflow.rst +++ b/workflow.rst @@ -229,6 +229,8 @@ what actions are allowed on a blog post:: // See all the available transitions for the post in the current state $transitions = $workflow->getEnabledTransitions($post); + // See a specific available transition for the post in the current state + $transition = $workflow->getEnabledTransition($post, 'publish'); Accessing the Workflow in a Class --------------------------------- @@ -649,6 +651,9 @@ of domain logic in your templates: ``workflow_transitions()`` Returns an array with all the transitions enabled for the given object. +``workflow_transition()`` + Returns a specific transitions enabled for the given object and transition name. + ``workflow_marked_places()`` Returns an array with the place names of the given marking. @@ -883,6 +888,15 @@ In Twig templates, metadata is available via the ``workflow_metadata()`` functio {% endfor %}

+

+ to_review Priority +

    +
  • + to_review: + {{ workflow_metadata(blog_post, 'priority', workflow_transition(blog_post, 'to_review')) }} +
  • +
+

Learn more ---------- From af5401a38a622e0cc55b42eca361ae7061852f9b Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Tue, 18 Aug 2020 17:44:19 +0200 Subject: [PATCH 0004/5766] Remove manual enabling of validation and validator annotations --- validation.rst | 72 +------------------------------------------------- 1 file changed, 1 insertion(+), 71 deletions(-) diff --git a/validation.rst b/validation.rst index fd18f003d56..de6cfb755a3 100644 --- a/validation.rst +++ b/validation.rst @@ -207,77 +207,7 @@ Inside the template, you can output the list of errors exactly as needed: Configuration ------------- -Before using the Symfony validator, make sure it's enabled in the main config -file: - -.. configuration-block:: - - .. code-block:: yaml - - # config/packages/framework.yaml - framework: - validation: { enabled: true } - - .. code-block:: xml - - - - - - - - - - - .. code-block:: php - - // config/packages/framework.php - $container->loadFromExtension('framework', [ - 'validation' => [ - 'enabled' => true, - ], - ]); - -Besides, if you plan to use annotations to configure validation, replace the -previous configuration by the following: - -.. configuration-block:: - - .. code-block:: yaml - - # config/packages/framework.yaml - framework: - validation: { enable_annotations: true } - - .. code-block:: xml - - - - - - - - - - - .. code-block:: php - - // config/packages/framework.php - $container->loadFromExtension('framework', [ - 'validation' => [ - 'enable_annotations' => true, - ], - ]); +In the previous Symfony versions, enabling the validator in configuration was a requirement. It's not the case anymore, the validation is enabled by default as long as the Validator component is installed. In the same way, annotations are enabled by default if ``doctrine/annotations`` is installed. .. tip:: From c3b9b2b731336ff22edb83e7f2586545da6d9862 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Thu, 27 Aug 2020 11:55:52 +0200 Subject: [PATCH 0005/5766] Replace overriding twig.paths by twig.default_path --- configuration/override_dir_structure.rst | 12 +++++------- reference/configuration/twig.rst | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/configuration/override_dir_structure.rst b/configuration/override_dir_structure.rst index 16c9a93ef98..38b3a0ab821 100644 --- a/configuration/override_dir_structure.rst +++ b/configuration/override_dir_structure.rst @@ -94,8 +94,8 @@ Override the Templates Directory -------------------------------- If your templates are not stored in the default ``app/Resources/views/`` -directory, use the :ref:`twig.paths ` configuration option to -define your own templates directory (or directories): +directory, use the :ref:`twig.default_path ` configuration option to +define your own templates directory (use :ref:`twig.paths ` for multiple directories): .. configuration-block:: @@ -104,7 +104,7 @@ define your own templates directory (or directories): # app/config/config.yml twig: # ... - paths: ["%kernel.project_dir%/templates"] + default_path: "%kernel.project_dir%/templates" .. code-block:: xml @@ -119,7 +119,7 @@ define your own templates directory (or directories): https://symfony.com/schema/dic/twig/twig-1.0.xsd"> - %kernel.project_dir%/templates + %kernel.project_dir%/templates @@ -128,9 +128,7 @@ define your own templates directory (or directories): // app/config/config.php $container->loadFromExtension('twig', [ - 'paths' => [ - '%kernel.project_dir%/templates', - ], + 'default_path' => '%kernel.project_dir%/templates', ]); .. _override-web-dir: diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 88229859230..0c115fbd154 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -243,6 +243,8 @@ on. Set it to ``0`` to disable all the optimizations. You can even enable or disable these optimizations selectively, as explained in the Twig documentation about `the optimizer extension`_. +.. _config-twig-default-path: + ``default_path`` ~~~~~~~~~~~~~~~~ From b65212f9ed1d3f56e77b4af6e0ac7224dca8e899 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Fri, 28 Aug 2020 22:22:20 +0200 Subject: [PATCH 0006/5766] Some fixes in structure overriding: * Use `default_path` instead of `paths` to change translation directory (default_path is anyway added to paths) * Replace `var` by `vendor` in the public directory section --- configuration/override_dir_structure.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/configuration/override_dir_structure.rst b/configuration/override_dir_structure.rst index fbfa119cc14..54788bb4964 100644 --- a/configuration/override_dir_structure.rst +++ b/configuration/override_dir_structure.rst @@ -141,8 +141,8 @@ Override the Translations Directory ----------------------------------- If your translation files are not stored in the default ``translations/`` -directory, use the :ref:`framework.translator.paths ` -configuration option to define your own translations directory (or directories): +directory, use the :ref:`framework.translator.default_path ` +configuration option to define your own translations directory (use :ref:`framework.translator.paths ` for multiple directories): .. configuration-block:: @@ -152,7 +152,7 @@ configuration option to define your own translations directory (or directories): framework: translator: # ... - paths: ["%kernel.project_dir%/i18n"] + default_path: "%kernel.project_dir%/i18n" .. code-block:: xml @@ -168,7 +168,7 @@ configuration option to define your own translations directory (or directories): - %kernel.project_dir%/i18n + %kernel.project_dir%/i18n @@ -179,9 +179,7 @@ configuration option to define your own translations directory (or directories): // config/packages/translation.php $container->loadFromExtension('framework', [ 'translator' => [ - 'paths' => [ - '%kernel.project_dir%/i18n', - ], + 'default_path' => '%kernel.project_dir%/i18n', ], ]); @@ -192,7 +190,7 @@ Override the Public Directory ----------------------------- If you need to rename or move your ``public/`` directory, the only thing you -need to guarantee is that the path to the ``var/`` directory is still correct in +need to guarantee is that the path to the ``vendor/`` directory is still correct in your ``index.php`` front controller. If you renamed the directory, you're fine. But if you moved it in some way, you may need to modify these paths inside those files:: From c8e5dd6aa9d2f1688dbc81af4072bd909b908ed0 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Sun, 13 Sep 2020 17:02:25 +0200 Subject: [PATCH 0007/5766] Update http_client.rst Integrating the findings of https://github.com/symfony/symfony/issues/38082#issuecomment-690529165 --- http_client.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/http_client.rst b/http_client.rst index 0d8648643b7..14c73d4eb82 100644 --- a/http_client.rst +++ b/http_client.rst @@ -642,6 +642,11 @@ when the streams are large):: 'body' => $formData->bodyToString(), ]); +If you need to add a custom HTTP header to the upload, you can do:: + + $headers = $formData->getPreparedHeaders()->toArray(); + $headers[] = 'X-Foo: bar'; + Cookies ~~~~~~~ From f41ef122c26ec0bb532dab399d2ba4c9f93af8eb Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sat, 30 May 2020 15:42:21 +0200 Subject: [PATCH 0008/5766] [HttpClient] add doc about extending and AsyncDecoratorTrait --- http_client.rst | 104 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) diff --git a/http_client.rst b/http_client.rst index 42a4b0388da..7c4c50932ae 100644 --- a/http_client.rst +++ b/http_client.rst @@ -1322,6 +1322,110 @@ This allows using them where native PHP streams are needed:: // later on if you need to, you can access the response from the stream $response = stream_get_meta_data($streamResource)['wrapper_data']->getResponse(); +Extensibility +------------- + +In order to extend the behavior of a base HTTP client, decoration is the way to go:: + + class MyExtendedHttpClient implements HttpClientInterface + { + private $decoratedClient; + + public function __construct(HttpClientInterface $decoratedClient = null) + { + $this->decoratedClient = $decoratedClient ?? HttpClient::create(); + } + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + // do what you want here with $method, $url and/or $options + + $response = $this->decoratedClient->request(); + + //!\ calling any method on $response here would break async, see below for a better way + + return $response; + } + + public function stream($responses, float $timeout = null): ResponseStreamInterface + { + return $this->decoratedClient->stream($responses, $timeout); + } + } + +A decorator like this one is suited for use cases where processing the +requests' arguments is enough. + +By decorating the ``on_progress`` option, one can +even implement basic monitoring of the response. But since calling responses' +methods forces synchronous operations, doing so in ``request()`` breaks async. +The solution then is to also decorate the response object itself. +:class:`Symfony\\Component\\HttpClient\\TraceableHttpClient` and +:class:`Symfony\\Component\\HttpClient\\Response\\TraceableResponse` are good +examples as a starting point. + +.. versionadded:: 5.2 + + ``AsyncDecoratorTrait`` was introduced in Symfony 5.2. + +In order to help writing more advanced response processors, the component provides +an :class:`Symfony\\Component\\HttpClient\\AsyncDecoratorTrait`. This trait allows +processing the stream of chunks as they come back from the network:: + + class MyExtendedHttpClient implements HttpClientInterface + { + use AsyncDecoratorTrait; + + public function request(string $method, string $url, array $options = []): ResponseInterface + { + // do what you want here with $method, $url and/or $options + + $passthru = function (ChunkInterface $chunk, AsyncContext $context) { + + // do what you want with chunks, e.g. split them + // in smaller chunks, group them, skip some, etc. + + yield $chunk; + }; + + return new AsyncResponse($this->client, $method, $url, $options, $passthru); + } + } + +Because the trait already implements a constructor and the ``stream()`` method, +you don't need to add them. The ``request()`` method should still be defined; +it shall return an +:class:`Symfony\\Component\\HttpClient\\Response\\AsyncResponse`. + +The custom processing of chunks should happen in ``$passthru``: this generator +is where you need to write your logic. It will be called for each chunk yielded by +the underlying client. A ``$passthru`` that does nothing would just ``yield $chunk;``. +Of course, you could also yield a modified chunk, split the chunk into many +ones by yielding several times, or even skip a chunk altogether by issuing a +``return;`` instead of yielding. + +In order to control the stream, the chunk passthru receives an +:class:`Symfony\\Component\\HttpClient\\Response\\AsyncContext` as second +argument. This context object has methods to read the current state of the +response. It also allows altering the response stream with methods to create new +chunks of content, pause the stream, cancel the stream, change the info of the +response, replace the current request by another one or change the chunk passthru +itself. + +Checking the test cases implemented in +:class:`Symfony\\Component\\HttpClient\\Response\\Tests\\AsyncDecoratorTraitTest` +might be a good start to get various working examples for a better understanding. +Here are the use cases that it simulates: + +* retry a failed request; +* send a preflight request, e.g. for authentication needs; +* issue subrequests and include their content in the main response's body. + +The logic in :class:`Symfony\\Component\\HttpClient\\Response\\AsyncResponse` has +many safety checks that will throw a ``LogicException`` if the chunk passthru +doesn't behave correctly; e.g. if a chunk is yielded after an ``isLast()`` one, +or if a content chunk is yielded before an ``isFirst()`` one, etc. + Testing HTTP Clients and Responses ---------------------------------- From 7a89d40780f775277a188aded3dc6c2afc88a4ec Mon Sep 17 00:00:00 2001 From: Simon Rolland Date: Tue, 13 Oct 2020 15:01:05 +0200 Subject: [PATCH 0009/5766] Update ICU project doc website --- reference/forms/types/datetime.rst | 2 +- reference/forms/types/options/date_format.rst.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/forms/types/datetime.rst b/reference/forms/types/datetime.rst index 3bafb96c57f..f5424d49cd0 100644 --- a/reference/forms/types/datetime.rst +++ b/reference/forms/types/datetime.rst @@ -222,4 +222,4 @@ Field Variables +--------------+------------+----------------------------------------------------------------------+ .. _`datetime local`: http://w3c.github.io/html-reference/datatypes.html#form.data.datetime-local -.. _`Date/Time Format Syntax`: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax +.. _`Date/Time Format Syntax`: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax diff --git a/reference/forms/types/options/date_format.rst.inc b/reference/forms/types/options/date_format.rst.inc index c7874b505bd..7a6501a6fd9 100644 --- a/reference/forms/types/options/date_format.rst.inc +++ b/reference/forms/types/options/date_format.rst.inc @@ -29,6 +29,6 @@ For more information on valid formats, see `Date/Time Format Syntax`_:: (the `RFC 3339`_ format) which is the default value if you use the ``single_text`` widget. -.. _`Date/Time Format Syntax`: http://userguide.icu-project.org/formatparse/datetime#TOC-Date-Time-Format-Syntax +.. _`Date/Time Format Syntax`: https://unicode-org.github.io/icu/userguide/format_parse/datetime/#datetime-format-syntax .. _`IntlDateFormatter::MEDIUM`: https://php.net/manual/en/class.intldateformatter.php#intl.intldateformatter-constants .. _`RFC 3339`: https://tools.ietf.org/html/rfc3339 From 3892e26df91cd69892c9564571073a58b0a94a41 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 9 Aug 2020 16:20:30 +0200 Subject: [PATCH 0010/5766] Clarify authentication entry point and access denied handler --- security/access_denied_handler.rst | 181 ++++++++++++++++++++++++++--- 1 file changed, 166 insertions(+), 15 deletions(-) diff --git a/security/access_denied_handler.rst b/security/access_denied_handler.rst index e9e780e75ef..eed7589bee2 100644 --- a/security/access_denied_handler.rst +++ b/security/access_denied_handler.rst @@ -1,17 +1,116 @@ .. index:: single: Security; Creating a Custom Access Denied Handler -How to Create a Custom Access Denied Handler -============================================ +How to Customize Access Denied Responses +======================================== -When your application throws an ``AccessDeniedException``, you can handle this exception -with a service to return a custom response. +In Symfony, you can throw an +:class:`Symfony\\Component\\Security\\Core\\Exception\\AccessDeniedException` +to disallow access to the user. Symfony will handle this exception and +generates a response based on the authentication state: -First, create a class that implements +* **If the user is not authenticated** (or authenticated anonymously), an + authentication entry point is used to generated a response (typically + a redirect to the login page or an *401 Unauthorized* response); +* **If the user is authenticated, but does not have the required + permissions**, a *403 Forbidden* response is generated. + +Customize the Unauthorized Response +----------------------------------- + +You need to create a class that implements +:class:`Symfony\\Component\\Security\\Http\\EntryPoint\\AuthenticationEntryPointInterface`. +This interface has one method (``start()``) that is called whenever an +unauthenticated user tries to access a protected resource:: + + // src/Security/AuthenticationEntryPoint.php + namespace App\Security; + + use Symfony\Component\HttpFoundation\RedirectResponse; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\Security\Core\Exception\AuthenticationException; + use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; + + class AuthenticationEntryPoint implements AuthenticationEntryPointInterface + { + private $urlGenerator; + private $session; + + public function __construct(UrlGeneratorInterface $urlGenerator, SessionInterface $session) + { + $this->urlGenerator = $urlGenerator; + $this->session = $session; + } + + public function start(Request $request, AuthenticationException $authException = null): RedirectResponse + { + // add a custom flash message and redirect to the login page + $this->session->getFlashBag()->add('note', 'You have to login in order to access this page.'); + + return new RedirectResponse($this->urlGenerator->generate('security_login')); + } + } + +That's it if you're using the :ref:`default services.yaml configuration `. +Otherwise, you have to register this service in the container. + +Now, configure this service ID as the entry point for the firewall: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/security.yaml + firewalls: + # ... + + main: + # ... + entry_point: App\Security\AuthenticationEntryPoint + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // config/packages/security.php + use App\Security\AuthenticationEntryPoint; + + $container->loadFromExtension('security', [ + 'firewalls' => [ + 'main' => [ + // ... + 'entry_point' => AuthenticationEntryPoint::class, + ], + ], + ]); + +Customize the Forbidden Response +-------------------------------- + +Create a class that implements :class:`Symfony\\Component\\Security\\Http\\Authorization\\AccessDeniedHandlerInterface`. -This interface defines one method called ``handle()`` where you can implement whatever -logic that should run when access is denied for the current user (e.g. send a -mail, log a message, or generally return a custom response):: +This interface defines one method called ``handle()`` where you can +implement whatever logic that should execute when access is denied for the +current user (e.g. send a mail, log a message, or generally return a custom +response):: namespace App\Security; @@ -49,11 +148,21 @@ configure it under your firewall: .. code-block:: xml - - - App\Security\AccessDeniedHandler - - + + + + + + + + + .. code-block:: php @@ -69,5 +178,47 @@ configure it under your firewall: ], ]); -That's it! Any ``AccessDeniedException`` thrown by code under the ``main`` firewall -will now be handled by your service. +Customizing All Access Denied Responses +--------------------------------------- + +In some cases, you might want to customize both responses or do a specific +action (e.g. logging) for each ``AccessDeniedException``. In this case, +configure a :ref:`kernel.exception listener `:: + + // src/EventListener/AccessDeniedListener.php + namespace App\EventListener; + + use Symfony\Component\EventDispatcher\EventSubscriberInterface; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\HttpKernel\Event\ExceptionEvent; + use Symfony\Component\HttpKernel\KernelEvents; + use Symfony\Component\Security\Core\Exception\AccessDeniedException; + + class AccessDeniedListener implements EventSubscriberInterface + { + public static function getSubscribedEvents(): array + { + return [ + // the priority must be greater than the Security HTTP + // ExceptionListener, to make sure it's called before + // the default exception listener + KernelEvents::EXCEPTION => ['onKernelException', 2], + ]; + } + + public function onKernelException(ExceptionEvent $event): void + { + $exception = $event->getException(); + if (!$exception instanceof AccessDeniedException) { + return; + } + + // ... perform some action (e.g. logging) + + // optionally set the custom response + $event->setResponse(new Response(null, 403)); + + // or stop propagation (prevents the next exception listeners from being called) + //$event->stopPropagation(); + } + } From 8e1af9d7303d2c8e7fc7e84686df7c6f782f33fc Mon Sep 17 00:00:00 2001 From: Matthew Smeets Date: Thu, 15 Oct 2020 20:16:16 +0200 Subject: [PATCH 0011/5766] Adding more information about default translation domain 'messages' --- translation.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/translation.rst b/translation.rst index 9a9effd3527..db50e05cb07 100644 --- a/translation.rst +++ b/translation.rst @@ -655,9 +655,12 @@ priority message files. The filename of the translation files is also important: each message file must be named according to the following path: ``domain.locale.loader``: -* **domain**: An optional way to organize messages into groups. Unless +* **domain**: Domains are a way to organize messages into groups. Unless parts of the application are explicitly separated from each other, it is - recommended to only use default ``messages`` domain; + recommended to only use default ``messages`` domain. + + If no domains are explicitly defined while using the translator, Symfony + will default to the ``messages`` domain (e.g. ``messages.en.yaml``) * **locale**: The locale that the translations are for (e.g. ``en_GB``, ``en``, etc); From feea39804413ee607973e2bed12f433929945744 Mon Sep 17 00:00:00 2001 From: Matthew Smeets Date: Thu, 15 Oct 2020 20:30:28 +0200 Subject: [PATCH 0012/5766] Adding information to the monolog autowire documentation that specifies that the channel must be defined --- logging/channels_handlers.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/logging/channels_handlers.rst b/logging/channels_handlers.rst index b206c1c5137..bac0be76012 100644 --- a/logging/channels_handlers.rst +++ b/logging/channels_handlers.rst @@ -182,8 +182,10 @@ How to Autowire Logger Channels Starting from `MonologBundle`_ 3.5 you can autowire different Monolog channels by type-hinting your service arguments with the following syntax: -``Psr\Log\LoggerInterface $Logger``. For example, to inject the service -related to the ``app`` logger channel use this: +``Psr\Log\LoggerInterface $Logger``. The ```` must have been +predefined in your Monolog configuration. + +An example to inject the service related to the ``app`` logger channel: .. code-block:: diff From 19521c3a25b4d1afb3b4b8e9fe02014ac9312972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 20 Oct 2020 09:53:08 +0200 Subject: [PATCH 0013/5766] Fix documentation about RetryStrategy --- http_client.rst | 7 ++-- reference/configuration/framework.rst | 55 +++++++++------------------ 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/http_client.rst b/http_client.rst index a54e9b125a8..e0a9d6808e3 100644 --- a/http_client.rst +++ b/http_client.rst @@ -710,10 +710,9 @@ original HTTP client:: $client = new RetryableHttpClient(HttpClient::create()); The ``RetryableHttpClient`` uses a -:class:`Symfony\\Component\\HttpClient\\Retry\\RetryDeciderInterface` to -decide if the request should be retried, and a -:class:`Symfony\\Component\\HttpClient\\Retry\\RetryBackOffInterface` to -define the waiting time between each retry. +:class:`Symfony\\Component\\HttpClient\\Retry\\RetryStrategyInterface` to +decide if the request should be retried, and to define the waiting time between +each retry. HTTP Proxies ~~~~~~~~~~~~ diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index cdf5451d94a..a3d6e9fd95a 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -140,8 +140,7 @@ Configuration * :ref:`retry_failed ` - * `backoff_service`_ - * `decider_service`_ + * `retry_strategy`_ * :ref:`enabled ` * `delay`_ * `http_codes`_ @@ -157,8 +156,7 @@ Configuration * :ref:`retry_failed ` - * `backoff_service`_ - * `decider_service`_ + * `retry_strategy`_ * :ref:`enabled ` * `delay`_ * `http_codes`_ @@ -780,8 +778,7 @@ will automatically retry failed HTTP requests. http_client: # ... retry_failed: - # backoff_service: app.custom_backoff - # decider_service: app.custom_decider + # retry_strategy: app.custom_strategy http_codes: [429, 500] max_retries: 2 delay: 1000 @@ -826,21 +823,6 @@ 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. -backoff_service -............... - -**type**: ``string`` - -.. versionadded:: 5.2 - - The ``backoff_service`` option was introduced in Symfony 5.2. - -The service id used to compute the time to wait between retries. By default, it -uses an instance of -:class:`Symfony\\Component\\HttpClient\\Retry\\ExponentialBackOff` configured -with ``delay``, ``max_delay``, ``multiplier`` and ``jitter`` options. This -class has to implement :class:`Symfony\\Component\\HttpClient\\Retry\\RetryBackOffInterface`. - base_uri ........ @@ -909,21 +891,6 @@ ciphers A list of the names of the ciphers allowed for the SSL/TLS connections. They can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM-SHA256'``). -decider_service -............... - -**type**: ``string`` - -.. versionadded:: 5.2 - - The ``decider_service`` option was introduced in Symfony 5.2. - -The service id used to decide if a request should be retried. By default, it -uses an instance of -:class:`Symfony\\Component\\HttpClient\\Retry\\HttpStatusCodeDecider` configured -with the ``http_codes`` option. This class has to implement -:class:`Symfony\\Component\\HttpClient\\Retry\\RetryDeciderInterface`. - delay ..... @@ -1124,6 +1091,22 @@ client and to make your tests easier. The value of this option is an associative array of ``domain => IP address`` (e.g ``['symfony.com' => '46.137.106.254', ...]``). +retry_strategy +............... + +**type**: ``string`` + +.. versionadded:: 5.2 + + The ``retry_strategy`` option was introduced in Symfony 5.2. + +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`. + scope ..... From 4155cc270069850a6281c5cb4566aa3d03d94bbd Mon Sep 17 00:00:00 2001 From: michel v Date: Tue, 20 Oct 2020 10:43:45 +0200 Subject: [PATCH 0014/5766] use the right method when dealing with promises sendRequest() returns a response, not a promise, and we can't use then() on a response --- http_client.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http_client.rst b/http_client.rst index 4db3784f853..7591152da85 100644 --- a/http_client.rst +++ b/http_client.rst @@ -1291,7 +1291,7 @@ Then you're ready to go:: $httpClient = new HttplugClient(); $request = $httpClient->createRequest('GET', 'https://my.api.com/'); - $promise = $httpClient->sendRequest($request) + $promise = $httpClient->sendAsyncRequest($request) ->then( function (ResponseInterface $response) { echo 'Got status '.$response->getStatusCode(); From 09a9aa0d903f154e4c62654e2c652c7750a72c58 Mon Sep 17 00:00:00 2001 From: Ahmed TAILOULOUTE Date: Mon, 30 Dec 2019 08:44:27 +0100 Subject: [PATCH 0015/5766] Update typehints --- components/asset.rst | 4 ++-- configuration/env_var_processors.rst | 2 +- form/data_mappers.rst | 4 ++-- form/type_guesser.rst | 12 ++++++------ forms.rst | 2 +- frontend/custom_version_strategy.rst | 6 +++--- reference/dic_tags.rst | 4 ++-- security/access_control.rst | 2 +- security/custom_authentication_provider.rst | 2 +- security/user_provider.rst | 6 +++--- serializer/custom_encoders.rst | 8 ++++---- session/locale_sticky_session.rst | 2 +- 12 files changed, 27 insertions(+), 27 deletions(-) diff --git a/components/asset.rst b/components/asset.rst index 20b5ce20b2d..48e51754449 100644 --- a/components/asset.rst +++ b/components/asset.rst @@ -200,12 +200,12 @@ every day:: $this->version = date('Ymd'); } - public function getVersion($path) + public function getVersion(string $path) { return $this->version; } - public function applyVersion($path) + public function applyVersion(string $path) { return sprintf('%s?v=%s', $path, $this->getVersion($path)); } diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst index b9782d270cd..464bf7af984 100644 --- a/configuration/env_var_processors.rst +++ b/configuration/env_var_processors.rst @@ -631,7 +631,7 @@ create a class that implements class LowercasingEnvVarProcessor implements EnvVarProcessorInterface { - public function getEnv($prefix, $name, \Closure $getEnv) + public function getEnv(string $prefix, string $name, \Closure $getEnv) { $env = $getEnv($name); diff --git a/form/data_mappers.rst b/form/data_mappers.rst index 15e66ce54b3..54081c09e47 100644 --- a/form/data_mappers.rst +++ b/form/data_mappers.rst @@ -98,7 +98,7 @@ in your form type:: /** * @param Color|null $viewData */ - public function mapDataToForms($viewData, $forms) + public function mapDataToForms($viewData, iterable $forms) { // there is no data yet, so nothing to prepopulate if (null === $viewData) { @@ -119,7 +119,7 @@ in your form type:: $forms['blue']->setData($viewData->getBlue()); } - public function mapFormsToData($forms, &$viewData) + public function mapFormsToData(iterable $forms, &$viewData) { /** @var FormInterface[] $forms */ $forms = iterator_to_array($forms); diff --git a/form/type_guesser.rst b/form/type_guesser.rst index f990aad4115..13f54999692 100644 --- a/form/type_guesser.rst +++ b/form/type_guesser.rst @@ -43,19 +43,19 @@ Start by creating the class and these methods. Next, you'll learn how to fill ea class PHPDocTypeGuesser implements FormTypeGuesserInterface { - public function guessType($class, $property) + public function guessType(string $class, string $property) { } - public function guessRequired($class, $property) + public function guessRequired(string $class, string $property) { } - public function guessMaxLength($class, $property) + public function guessMaxLength(string $class, string $property) { } - public function guessPattern($class, $property) + public function guessPattern(string $class, string $property) { } } @@ -94,7 +94,7 @@ With this knowledge, you can implement the ``guessType()`` method of the class PHPDocTypeGuesser implements FormTypeGuesserInterface { - public function guessType($class, $property) + public function guessType(string $class, string $property) { $annotations = $this->readPhpDocAnnotations($class, $property); @@ -129,7 +129,7 @@ With this knowledge, you can implement the ``guessType()`` method of the } } - protected function readPhpDocAnnotations($class, $property) + protected function readPhpDocAnnotations(string $class, string $property) { $reflectionProperty = new \ReflectionProperty($class, $property); $phpdoc = $reflectionProperty->getDocComment(); diff --git a/forms.rst b/forms.rst index 5867d2f07d1..ec5a04fcfc1 100644 --- a/forms.rst +++ b/forms.rst @@ -672,7 +672,7 @@ Set the ``label`` option on fields to define their labels explicitly:: ->add('dueDate', DateType::class, [ // set it to FALSE to not display the label for this field - 'label' => 'To Be Completed Before', + 'label' => 'To Be Completed Before', ]) .. tip:: diff --git a/frontend/custom_version_strategy.rst b/frontend/custom_version_strategy.rst index 6361ba632c0..0fe3f5ff987 100644 --- a/frontend/custom_version_strategy.rst +++ b/frontend/custom_version_strategy.rst @@ -71,13 +71,13 @@ version string:: * @param string $manifestPath * @param string|null $format */ - public function __construct($manifestPath, $format = null) + public function __construct(string $manifestPath, string $format = null) { $this->manifestPath = $manifestPath; $this->format = $format ?: '%s?%s'; } - public function getVersion($path) + public function getVersion(string $path) { if (!is_array($this->hashes)) { $this->hashes = $this->loadManifest(); @@ -86,7 +86,7 @@ version string:: return isset($this->hashes[$path]) ? $this->hashes[$path] : ''; } - public function applyVersion($path) + public function applyVersion(string $path) { $version = $this->getVersion($path); diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index f7f43dca376..0aca3c91777 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -410,7 +410,7 @@ service class:: class MyClearer implements CacheClearerInterface { - public function clear($cacheDirectory) + public function clear(string $cacheDirectory) { // clear your cache } @@ -1062,7 +1062,7 @@ required option: ``alias``, which defines the name of the extractor:: /** * Sets the prefix that should be used for new found messages. */ - public function setPrefix($prefix) + public function setPrefix(string $prefix) { $this->prefix = $prefix; } diff --git a/security/access_control.rst b/security/access_control.rst index 9b345b87a24..b02b9057424 100644 --- a/security/access_control.rst +++ b/security/access_control.rst @@ -92,7 +92,7 @@ Take the following ``access_control`` entries as an example: 'path' => '^/admin', 'roles' => 'ROLE_USER_METHOD', 'methods' => 'POST, PUT', - ] + ], ], ]); diff --git a/security/custom_authentication_provider.rst b/security/custom_authentication_provider.rst index 3199128b26a..4a0a5be4407 100644 --- a/security/custom_authentication_provider.rst +++ b/security/custom_authentication_provider.rst @@ -410,7 +410,7 @@ to service ids that may not exist yet: ``App\Security\Authentication\Provider\Ws - + diff --git a/security/user_provider.rst b/security/user_provider.rst index 000a7a49a38..5fcf19f3bf2 100644 --- a/security/user_provider.rst +++ b/security/user_provider.rst @@ -135,7 +135,7 @@ interface only requires one method: ``loadUserByUsername($username)``:: { // ... - public function loadUserByUsername($usernameOrEmail) + public function loadUserByUsername(string $usernameOrEmail) { $entityManager = $this->getEntityManager(); @@ -376,7 +376,7 @@ command will generate a nice skeleton to get you started:: * * @throws UsernameNotFoundException if the user is not found */ - public function loadUserByUsername($username) + public function loadUserByUsername(string $username) { // Load a User object from your data source or throw UsernameNotFoundException. // The $username argument may not actually be a username: @@ -412,7 +412,7 @@ command will generate a nice skeleton to get you started:: /** * Tells Symfony to use this provider for this User class. */ - public function supportsClass($class) + public function supportsClass(string $class) { return User::class === $class || is_subclass_of($class, User::class); } diff --git a/serializer/custom_encoders.rst b/serializer/custom_encoders.rst index 5bb78def4e4..e6bae859336 100644 --- a/serializer/custom_encoders.rst +++ b/serializer/custom_encoders.rst @@ -27,22 +27,22 @@ create your own encoder that uses the class YamlEncoder implements EncoderInterface, DecoderInterface { - public function encode($data, $format, array $context = []) + public function encode($data, string $format, array $context = []) { return Yaml::dump($data); } - public function supportsEncoding($format) + public function supportsEncoding(string $format) { return 'yaml' === $format; } - public function decode($data, $format, array $context = []) + public function decode(string $data, string $format, array $context = []) { return Yaml::parse($data); } - public function supportsDecoding($format) + public function supportsDecoding(string $format) { return 'yaml' === $format; } diff --git a/session/locale_sticky_session.rst b/session/locale_sticky_session.rst index f8caef23370..056f2a674cb 100644 --- a/session/locale_sticky_session.rst +++ b/session/locale_sticky_session.rst @@ -28,7 +28,7 @@ correct locale however you want:: { private $defaultLocale; - public function __construct($defaultLocale = 'en') + public function __construct(string $defaultLocale = 'en') { $this->defaultLocale = $defaultLocale; } From b905b571fa8368f1b01600aaf337ae750a4d4956 Mon Sep 17 00:00:00 2001 From: Cristi Contiu Date: Sat, 8 Feb 2020 21:47:34 +0200 Subject: [PATCH 0016/5766] Update deployment docs with new .env loading --- deployment.rst | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/deployment.rst b/deployment.rst index 85b772b3a55..5d02bae0e58 100644 --- a/deployment.rst +++ b/deployment.rst @@ -126,21 +126,29 @@ While developing locally, you'll usually store these in ``.env`` and ``.env.loca 1. Create "real" environment variables. How you set environment variables, depends on your setup: they can be set at the command line, in your Nginx configuration, - or via other methods provided by your hosting service. + or via other methods provided by your hosting service; -2. Or, create a ``.env.local`` file like your local development (see note below) +2. Or, create a ``.env.local`` file like your local development. There is no significant advantage to either of the two options: use whatever is most natural in your hosting environment. -.. note:: +.. tip:: + + You might not want your application to process the ``.env.*`` files on + every request. You can generate an optimized ``.env.local.php`` which + overrides all other configuration files: + + .. code-block:: terminal + + $ composer dump-env prod - If you use the ``.env.*`` files on production, you may need to move your - ``symfony/dotenv`` dependency from ``require-dev`` to ``require`` in ``composer.json``: + The generated file will contain all the configuration stored in ``.env``. If you + want to rely only on environment variables, generate one without any values using: .. code-block:: terminal - $ composer require symfony/dotenv + $ composer dump-env prod --empty C) Install/Update your Vendors ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From e1277a5d37ab10e5b86c2260ea62af0e231b5a60 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 18 Apr 2020 23:55:41 +0200 Subject: [PATCH 0017/5766] Added PHP typehints to getting started guides --- configuration.rst | 3 +- controller.rst | 41 ++++++++++++++------ page_creation.rst | 4 +- routing.rst | 95 ++++++++++++++++++++++++++++++----------------- templates.rst | 13 ++++--- 5 files changed, 102 insertions(+), 54 deletions(-) diff --git a/configuration.rst b/configuration.rst index 6efd3283733..e25e18efd5b 100644 --- a/configuration.rst +++ b/configuration.rst @@ -765,12 +765,13 @@ use the ``getParameter()`` helper:: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; class UserController extends AbstractController { // ... - public function index() + public function index(): Response { $projectDir = $this->getParameter('kernel.project_dir'); $adminEmail = $this->getParameter('app.admin_email'); diff --git a/controller.rst b/controller.rst index d29608e6128..212d0a2b509 100644 --- a/controller.rst +++ b/controller.rst @@ -36,7 +36,7 @@ class:: /** * @Route("/lucky/number/{max}", name="app_lucky_number") */ - public function number($max) + public function number(int $max): Response { $number = random_int(0, $max); @@ -134,7 +134,7 @@ and ``redirect()`` methods:: use Symfony\Component\HttpFoundation\RedirectResponse; // ... - public function index() + public function index(): RedirectResponse { // redirects to the "homepage" route return $this->redirectToRoute('homepage'); @@ -196,12 +196,13 @@ If you need a service in a controller, type-hint an argument with its class (or interface) name. Symfony will automatically pass you the service you need:: use Psr\Log\LoggerInterface; + use Symfony\Component\HttpFoundation\Response; // ... /** * @Route("/lucky/number/{max}") */ - public function number($max, LoggerInterface $logger) + public function number(int $max, LoggerInterface $logger): Response { $logger->info('We are logging!'); // ... @@ -322,10 +323,11 @@ Managing Errors and 404 Pages When things are not found, you should return a 404 response. To do this, throw a special type of exception:: + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; // ... - public function index() + public function index(): Response { // retrieve the object from database $product = ...; @@ -370,8 +372,10 @@ object. To access it in your controller, add it as an argument and **type-hint it with the Request class**:: use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; + // ... - public function index(Request $request, $firstName, $lastName) + public function index(Request $request, string $firstName, string $lastName): Response { $page = $request->query->get('page', 1); @@ -401,9 +405,11 @@ Session storage and other configuration can be controlled under the To get the session, add an argument and type-hint it with :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`:: + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpFoundation\Session\SessionInterface; + // ... - public function index(SessionInterface $session) + public function index(SessionInterface $session): Response { // stores an attribute for reuse during a later user request $session->set('foo', 'bar'); @@ -413,6 +419,8 @@ To get the session, add an argument and type-hint it with // uses a default value if the attribute doesn't exist $filters = $session->get('filters', []); + + // ... } Stored attributes remain in the session for the remainder of that user's session. @@ -435,8 +443,10 @@ from the session automatically as soon as you retrieve them. This feature makes For example, imagine you're processing a :doc:`form ` submission:: use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; + // ... - public function update(Request $request) + public function update(Request $request): Response { // ... @@ -515,8 +525,9 @@ pass the ``Request`` object to any controller argument that is type-hinted with the ``Request`` class:: use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; - public function index(Request $request) + public function index(Request $request): Response { $request->isXmlHttpRequest(); // is it an Ajax request? @@ -572,7 +583,7 @@ To get the value of any :ref:`configuration parameter from a controller, use the ``getParameter()`` helper method:: // ... - public function index() + public function index(): Response { $contentsDir = $this->getParameter('kernel.project_dir').'/contents'; // ... @@ -584,8 +595,10 @@ Returning JSON Response To return JSON from a controller, use the ``json()`` helper method. This returns a ``JsonResponse`` object that encodes the data automatically:: + use Symfony\Component\HttpFoundation\Response; // ... - public function index() + + public function index(): Response { // returns '{"username":"jane.doe"}' and sets the proper Content-Type header return $this->json(['username' => 'jane.doe']); @@ -604,7 +617,10 @@ Streaming File Responses You can use the :method:`Symfony\\Bundle\\FrameworkBundle\\Controller\\AbstractController::file` helper to serve a file from inside a controller:: - public function download() + use Symfony\Component\HttpFoundation\Response; + // ... + + public function download(): Response { // send the file contents and force the browser to download it return $this->file('/path/to/some_file.pdf'); @@ -614,8 +630,9 @@ The ``file()`` helper provides some arguments to configure its behavior:: use Symfony\Component\HttpFoundation\File\File; use Symfony\Component\HttpFoundation\ResponseHeaderBag; + // ... - public function download() + public function download(): Response { // load the file from the filesystem $file = new File('/path/to/some_file.pdf'); diff --git a/page_creation.rst b/page_creation.rst index 1835308804e..90096beb4d4 100644 --- a/page_creation.rst +++ b/page_creation.rst @@ -226,13 +226,15 @@ variable so you can use it in Twig:: // src/Controller/LuckyController.php namespace App\Controller; + use Symfony\Component\HttpFoundation\Response; // ... + class LuckyController extends AbstractController { /** * @Route("/lucky/number") */ - public function number() + public function number(): Response { $number = random_int(0, 100); diff --git a/routing.rst b/routing.rst index 75755c31d40..5aaebf659cd 100644 --- a/routing.rst +++ b/routing.rst @@ -53,6 +53,7 @@ do so, create a :doc:`controller class ` like the following:: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -60,7 +61,7 @@ do so, create a :doc:`controller class ` like the following:: /** * @Route("/blog", name="blog_list") */ - public function list() + public function list(): Response { // ... } @@ -161,14 +162,16 @@ Use the ``methods`` option to restrict the verbs each route should respond to: // src/Controller/BlogApiController.php namespace App\Controller; - // ... + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\Routing\Annotation\Route; class BlogApiController extends AbstractController { /** * @Route("/api/posts/{id}", methods={"GET","HEAD"}) */ - public function show(int $id) + public function show(int $id): Response { // ... return a JSON response with the post } @@ -176,7 +179,7 @@ Use the ``methods`` option to restrict the verbs each route should respond to: /** * @Route("/api/posts/{id}", methods={"PUT"}) */ - public function edit(int $id) + public function edit(int $id): Response { // ... edit a post } @@ -254,6 +257,7 @@ arbitrary matching logic: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class DefaultController extends AbstractController @@ -268,7 +272,7 @@ arbitrary matching logic: * expressions can also include config parameters: * condition: "request.headers.get('User-Agent') matches '%app.allowed_browsers%'" */ - public function contact() + public function contact(): Response { // ... } @@ -406,6 +410,7 @@ defined as ``/blog/{slug}``: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -415,7 +420,7 @@ defined as ``/blog/{slug}``: /** * @Route("/blog/{slug}", name="blog_show") */ - public function show(string $slug) + public function show(string $slug): Response { // $slug will equal the dynamic part of the URL // e.g. at /blog/yay-routing, then $slug='yay-routing' @@ -486,6 +491,7 @@ the ``{page}`` parameter using the ``requirements`` option: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -493,7 +499,7 @@ the ``{page}`` parameter using the ``requirements`` option: /** * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"}) */ - public function list(int $page) + public function list(int $page): Response { // ... } @@ -501,7 +507,7 @@ the ``{page}`` parameter using the ``requirements`` option: /** * @Route("/blog/{slug}", name="blog_show") */ - public function show($slug) + public function show(string $slug): Response { // ... } @@ -597,6 +603,7 @@ concise, but it can decrease route readability when requirements are complex: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -604,7 +611,7 @@ concise, but it can decrease route readability when requirements are complex: /** * @Route("/blog/{page<\d+>}", name="blog_list") */ - public function list(int $page) + public function list(int $page): Response { // ... } @@ -665,6 +672,7 @@ other configuration formats they are defined with the ``defaults`` option: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -672,7 +680,7 @@ other configuration formats they are defined with the ``defaults`` option: /** * @Route("/blog/{page}", name="blog_list", requirements={"page"="\d+"}) */ - public function list(int $page = 1) + public function list(int $page = 1): Response { // ... } @@ -756,6 +764,7 @@ parameter: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -763,7 +772,7 @@ parameter: /** * @Route("/blog/{page<\d+>?1}", name="blog_list") */ - public function list(int $page) + public function list(int $page): Response { // ... } @@ -831,6 +840,7 @@ controller action. Instead of ``string $slug``, add ``BlogPost $post``:: use App\Entity\BlogPost; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -840,7 +850,7 @@ controller action. Instead of ``string $slug``, add ``BlogPost $post``:: /** * @Route("/blog/{slug}", name="blog_show") */ - public function show(BlogPost $post) + public function show(BlogPost $post): Response { // $post is the object whose slug matches the routing parameter @@ -893,7 +903,10 @@ and in route imports. Symfony defines some special attributes with the same name // src/Controller/ArticleController.php namespace App\Controller; - // ... + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\Routing\Annotation\Route; + class ArticleController extends AbstractController { /** @@ -907,7 +920,7 @@ and in route imports. Symfony defines some special attributes with the same name * } * ) */ - public function search() + public function search(): Response { } } @@ -982,14 +995,16 @@ the controllers of the routes: // src/Controller/BlogController.php namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; - class BlogController + class BlogController extends AbstractController { /** * @Route("/blog/{page}", name="blog_index", defaults={"page": 1, "title": "Hello world!"}) */ - public function index(int $page, string $title) + public function index(int $page, string $title): Response { // ... } @@ -1055,14 +1070,16 @@ A possible solution is to change the parameter requirements to be more permissiv // src/Controller/DefaultController.php namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; - class DefaultController + class DefaultController extends AbstractController { /** * @Route("/share/{token}", name="share", requirements={"token"=".+"}) */ - public function share($token) + public function share($token): Response { // ... } @@ -1143,17 +1160,19 @@ the common configuration using options when importing the routes. // src/Controller/BlogController.php namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; /** * @Route("/blog", requirements={"_locale": "en|es|fr"}, name="blog_") */ - class BlogController + class BlogController extends AbstractController { /** * @Route("/{_locale}", name="index") */ - public function index() + public function index(): Response { // ... } @@ -1161,7 +1180,7 @@ the common configuration using options when importing the routes. /** * @Route("/{_locale}/posts/{slug}", name="show") */ - public function show(Post $post) + public function show(Post $post): Response { // ... } @@ -1267,6 +1286,7 @@ information in a controller via the ``Request`` object:: use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -1274,15 +1294,15 @@ information in a controller via the ``Request`` object:: /** * @Route("/blog", name="blog_list") */ - public function list(Request $request) + public function list(Request $request): Response { - // ... - $routeName = $request->attributes->get('_route'); $routeParameters = $request->attributes->get('_route_params'); // use this to get all the available attributes (not only routing ones): $allAttributes = $request->attributes->all(); + + // ... } } @@ -1467,6 +1487,7 @@ host name: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class MainController extends AbstractController @@ -1474,7 +1495,7 @@ host name: /** * @Route("/", name="mobile_homepage", host="m.example.com") */ - public function mobileHomepage() + public function mobileHomepage(): Response { // ... } @@ -1482,7 +1503,7 @@ host name: /** * @Route("/", name="homepage") */ - public function homepage() + public function homepage(): Response { // ... } @@ -1546,6 +1567,7 @@ multi-tenant applications) and these parameters can be validated too with namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class MainController extends AbstractController @@ -1559,7 +1581,7 @@ multi-tenant applications) and these parameters can be validated too with * requirements={"subdomain"="m|mobile"} * ) */ - public function mobileHomepage() + public function mobileHomepage(): Response { // ... } @@ -1567,7 +1589,7 @@ multi-tenant applications) and these parameters can be validated too with /** * @Route("/", name="homepage") */ - public function homepage() + public function homepage(): Response { // ... } @@ -1676,6 +1698,7 @@ avoids the need for duplicating routes, which also reduces the potential bugs: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class CompanyController extends AbstractController @@ -1686,7 +1709,7 @@ avoids the need for duplicating routes, which also reduces the potential bugs: * "nl": "/over-ons" * }, name="about_us") */ - public function about() + public function about(): Response { // ... } @@ -1816,6 +1839,7 @@ use the ``generateUrl()`` helper:: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; @@ -1824,10 +1848,8 @@ use the ``generateUrl()`` helper:: /** * @Route("/blog", name="blog_list") */ - public function list() + public function list(): Response { - // ... - // generate a URL with no route arguments $signUpPage = $this->generateUrl('sign_up'); @@ -1843,6 +1865,8 @@ use the ``generateUrl()`` helper:: // 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->generateUrl('sign_up', ['_locale' => 'nl']); + + // ... } } @@ -2000,7 +2024,7 @@ This information can be configured per command too:: $this->router = $router; } - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): int { // these values override any global configuration $context = $this->router->getContext(); @@ -2101,6 +2125,7 @@ each route explicitly: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class SecurityController extends AbstractController @@ -2108,7 +2133,7 @@ each route explicitly: /** * @Route("/login", name="login", schemes={"https"}) */ - public function login() + public function login(): Response { // ... } @@ -2222,7 +2247,7 @@ Here are some common errors you might see while working with routing: This happens when your controller method has an argument (e.g. ``$slug``):: - public function show($slug) + public function show(string $slug): Response { // ... } diff --git a/templates.rst b/templates.rst index fb30f9a7c03..f415eaa82e3 100644 --- a/templates.rst +++ b/templates.rst @@ -90,12 +90,13 @@ passes to it the needed variables:: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; class UserController extends AbstractController { // ... - public function notifications() + public function notifications(): Response { // get the user information and notifications somehow $userFirstName = '...'; @@ -191,6 +192,7 @@ Consider the following routing configuration: namespace App\Controller; // ... + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class BlogController extends AbstractController @@ -198,7 +200,7 @@ Consider the following routing configuration: /** * @Route("/", name="blog_index") */ - public function index() + public function index(): Response { // ... } @@ -206,7 +208,7 @@ Consider the following routing configuration: /** * @Route("/article/{slug}", name="blog_post") */ - public function show(string $slug) + public function show(string $slug): Response { // ... } @@ -399,7 +401,7 @@ use the ``render()`` helper:: class ProductController extends AbstractController { - public function index() + public function index(): Response { // ... @@ -723,11 +725,12 @@ First, create the controller that renders a certain number of recent articles:: // src/Controller/BlogController.php namespace App\Controller; + use Symfony\Component\HttpFoundation\Response; // ... class BlogController extends AbstractController { - public function recentArticles($max = 3) + public function recentArticles(int $max = 3): Response { // get the recent articles somehow (e.g. making a database query) $articles = ['...', '...', '...']; From a4023d6e51d66745d1120a42ce26bc6cca63418c Mon Sep 17 00:00:00 2001 From: Martin Hujer Date: Wed, 11 Dec 2019 13:18:09 +0100 Subject: [PATCH 0018/5766] Security: How to Build a Login Form: sync with recent Maker Bundle changes --- security/form_login_setup.rst | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index c52847f0dcc..2213e949fe8 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -74,10 +74,15 @@ class that processes the login submit and 4) updates the main security config fi // last username entered by the user $lastUsername = $authenticationUtils->getLastUsername(); - return $this->render('security/login.html.twig', [ - 'last_username' => $lastUsername, - 'error' => $error - ]); + return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]); + } + + /** + * @Route("/logout", name="app_logout") + */ + public function logout() + { + throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall'); } /** @@ -165,10 +170,10 @@ a traditional HTML form that submits to ``/login``: {% endif %}

Please sign in

- - - - + + + + Date: Wed, 21 Oct 2020 15:14:45 +0200 Subject: [PATCH 0019/5766] [#12802] Updated XML and PHP examples --- security/form_login_setup.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index 2213e949fe8..4d9bb9265c8 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -341,6 +341,7 @@ a traditional HTML form that submits to ``/login``: + @@ -360,6 +361,9 @@ a traditional HTML form that submits to ``/login``: LoginFormAuthenticator::class, ] ], + 'logout' => [ + 'path' => 'app_logout', + ], ], ], ]); From 010f62fc460e49461c5d3fb98f2aaceb636c813d Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Wed, 21 Oct 2020 15:49:46 +0200 Subject: [PATCH 0020/5766] Fix markup of configuration-block. --- routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing.rst b/routing.rst index 53088f53a32..4588ba61cd2 100644 --- a/routing.rst +++ b/routing.rst @@ -58,7 +58,7 @@ This configuration tells Symfony to look for routes defined as annotations in any PHP class stored in the ``src/Controller/`` directory. Suppose you want to define a route for the ``/blog`` URL in your application. To -do so, create a :doc:`controller class ` like the following:: +do so, create a :doc:`controller class ` like the following: .. configuration-block:: From 526012ed7a9a1c1aac7c829fcb6f68e2aea67d93 Mon Sep 17 00:00:00 2001 From: Andrii Popov Date: Mon, 21 Oct 2019 21:00:22 +0300 Subject: [PATCH 0021/5766] [Cache] Custom pool namespaces --- cache.rst | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/cache.rst b/cache.rst index 4fc6a4faa87..42a22ca55e3 100644 --- a/cache.rst +++ b/cache.rst @@ -329,6 +329,53 @@ with either :class:`Symfony\\Contracts\\Cache\\CacheInterface` or // ... } +.. tip:: + + If you need the namespace to be interoperable with a third-party app, + you can take control over auto-generation by setting the ``namespace`` + attribute of the ``cache.pool`` service tag. For example, you can + override the service definition of the adapter: + + .. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + app.cache.adapter.redis: + parent: 'cache.adapter.redis' + tags: + - { name: 'cache.pool', namespace: 'my_custom_namespace' } + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + return function(ContainerConfigurator $configurator) { + $services = $configurator->services(); + + $services->set('app.cace.adapter.redis') + ->parent('cache.adapter.redis') + ->tag('cache.pool', ['namespace' => 'my_custom_namespace']) + }; + Custom Provider Options ----------------------- From 1b64a6e791b765e6eb29f9ce91597b85a4ac6911 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 21 Oct 2020 16:01:48 +0200 Subject: [PATCH 0022/5766] Fixed DOCtor --- security/form_login_setup.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index 4d9bb9265c8..abbbb6eb1f2 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -341,7 +341,7 @@ a traditional HTML form that submits to ``/login``: - + From b9a47effa7ceb176e64bec5e59c20141337f469a Mon Sep 17 00:00:00 2001 From: BETARI Date: Thu, 28 Nov 2019 00:03:25 +0100 Subject: [PATCH 0023/5766] Update multiple_kernels.rst --- configuration/multiple_kernels.rst | 43 +++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/configuration/multiple_kernels.rst b/configuration/multiple_kernels.rst index e6110bb69c2..a0069b9be4b 100644 --- a/configuration/multiple_kernels.rst +++ b/configuration/multiple_kernels.rst @@ -88,31 +88,50 @@ files so they don't collide with the files from ``src/Kernel.php``:: class ApiKernel extends Kernel { - // ... + use MicroKernelTrait; public function registerBundles() { - // load only the bundles strictly needed for the API... + // load only the bundles strictly needed for the API + $contents = require $this->getProjectDir().'/config/api_bundles.php'; + foreach ($contents as $class => $envs) { + if ($envs[$this->environment] ?? $envs['all'] ?? false) { + yield new $class(); + } + } + } + + public function getProjectDir(): string + { + return \dirname(__DIR__); } - public function getCacheDir() + public function getCacheDir(): string { - return dirname(__DIR__).'/var/cache/api/'.$this->getEnvironment(); + return $this->getProjectDir().'/var/cache/api/'.$this->getEnvironment(); } - public function getLogDir() + public function getLogDir(): string { - return dirname(__DIR__).'/var/log/api'; + return $this->getProjectDir().'/var/log/api'; } public function configureContainer(ContainerBuilder $container, LoaderInterface $loader) { - // load only the config files strictly needed for the API - $confDir = $this->getProjectDir().'/config'; - $loader->load($confDir.'/api/*'.self::CONFIG_EXTS, 'glob'); - if (is_dir($confDir.'/api/'.$this->environment)) { - $loader->load($confDir.'/api/'.$this->environment.'/**/*'.self::CONFIG_EXTS, 'glob'); - } + $container->addResource(new FileResource($this->getProjectDir().'/config/api_bundles.php')); + $container->setParameter('container.dumper.inline_factories', true); + $confDir = $this->getProjectDir().'/config/api'; + + $loader->load($confDir.'/{packages}/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{packages}/'.$this->environment.'/*'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}'.self::CONFIG_EXTS, 'glob'); + $loader->load($confDir.'/{services}_'.$this->environment.self::CONFIG_EXTS, 'glob'); + } + + protected function configureRoutes(RouteCollectionBuilder $routes): void + { + $confDir = $this->getProjectDir().'/config/api'; + // ... load only the config routes strictly needed for the API } } From 0f91cc9f74a656da845b6a46b225a8351a83ccae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Tue, 20 Oct 2020 09:42:57 +0200 Subject: [PATCH 0024/5766] Add documentation for retry on idempotent methods --- http_client.rst | 8 +++++--- reference/configuration/framework.rst | 7 +++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/http_client.rst b/http_client.rst index e0a9d6808e3..5c899660b62 100644 --- a/http_client.rst +++ b/http_client.rst @@ -694,9 +694,10 @@ Retry Failed Requests Sometimes, requests fail because of network issues or temporary server errors. Symfony's HttpClient allows to retry failed requests automatically using the :ref:`retry_failed option `. When enabled, -each failed request with an HTTP status of ``423``, ``425``, ``429``, ``500``, -``502``, ``503``, ``504``, ``507``, or ``510`` is retried up to 3 times, with an -exponential delay between retries (first retry = 1 second; third retry: 4 seconds). +each failed request with an HTTP status of ``423``, ``425``, ``429``, ``502``, +``503`` or with an `idempotent method`_ and a HTTP status of ``500``, ``504``, +``507`` or ``510`` is retried up to 3 times, with an exponential delay between +retries (first retry = 1 second; third retry: 4 seconds). Check out the full list of configurable :ref:`retry_failed options ` to learn how to tweak each of them to fit your application needs. @@ -1609,3 +1610,4 @@ Then configure Symfony to use your callback: .. _`cURL options`: https://www.php.net/manual/en/function.curl-setopt.php .. _`Server-sent events`: https://html.spec.whatwg.org/multipage/server-sent-events.html .. _`EventSource`: https://www.w3.org/TR/eventsource/#eventsource +.. _`idempotent method`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods_and_web_applications diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index a3d6e9fd95a..b8b0a7887d6 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -779,7 +779,10 @@ will automatically retry failed HTTP requests. # ... retry_failed: # retry_strategy: app.custom_strategy - http_codes: [429, 500] + 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 @@ -923,7 +926,7 @@ value must use the format ``['header-name' => 'value0, value1, ...']``. http_codes .......... -**type**: ``array`` **default**: ``[423, 425, 429, 500, 502, 503, 504, 507, 510]`` +**type**: ``array`` **default**: :method:`Symfony\\Component\\HttpClient\\Retry\\GenericRetryStrategy::DEFAULT_RETRY_STATUS_CODES` .. versionadded:: 5.2 From 689614433c04d186640f563d619c36adc43184c9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 21 Oct 2020 20:14:08 +0200 Subject: [PATCH 0025/5766] Tweak --- http_client.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/http_client.rst b/http_client.rst index 5c899660b62..efc5a14e799 100644 --- a/http_client.rst +++ b/http_client.rst @@ -693,11 +693,13 @@ Retry Failed Requests Sometimes, requests fail because of network issues or temporary server errors. Symfony's HttpClient allows to retry failed requests automatically using the -:ref:`retry_failed option `. When enabled, -each failed request with an HTTP status of ``423``, ``425``, ``429``, ``502``, -``503`` or with an `idempotent method`_ and a HTTP status of ``500``, ``504``, -``507`` or ``510`` is retried up to 3 times, with an exponential delay between -retries (first retry = 1 second; third retry: 4 seconds). +:ref:`retry_failed option `. + +By default, failed requests are retried up to 3 times, with an exponential delay +between retries (first retry = 1 second; third retry: 4 seconds) and only for +the following HTTP status codes: ``423``, ``425``, ``429``, ``502`` and ``503`` +when using any HTTP method and ``500``, ``504``, ``507`` and ``510`` when using +an HTTP `idempotent method`_. Check out the full list of configurable :ref:`retry_failed options ` to learn how to tweak each of them to fit your application needs. From b56568416ffc59993c83007343c0750de519e935 Mon Sep 17 00:00:00 2001 From: Matthias Gutjahr Date: Wed, 21 Oct 2020 11:59:21 +0200 Subject: [PATCH 0026/5766] Update doctrine.rst Correct link to StofDoctrineExtensionsBundle --- doctrine.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine.rst b/doctrine.rst index bb27ad91bfa..eab24ae8f13 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -879,4 +879,4 @@ Learn more .. _`API Platform`: https://api-platform.com/docs/core/validation/ .. _`PDO`: https://www.php.net/pdo .. _`available Doctrine extensions`: https://github.com/Atlantic18/DoctrineExtensions -.. _`StofDoctrineExtensionsBundle`: https://github.com/antishov/StofDoctrineExtensionsBundle +.. _`StofDoctrineExtensionsBundle`: https://github.com/stof/StofDoctrineExtensionsBundle From 9994e7b0dca329678cb7db549bbae7d256d9c7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 21 Oct 2020 20:24:19 +0200 Subject: [PATCH 0027/5766] Use APP_RUNTIME_ENV to define secrets --- configuration/secrets.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration/secrets.rst b/configuration/secrets.rst index 696ce519682..ab49c052dff 100644 --- a/configuration/secrets.rst +++ b/configuration/secrets.rst @@ -48,7 +48,7 @@ running: .. code-block:: terminal - $ php bin/console secrets:generate-keys --env=prod + $ APP_RUNTIME_ENV=prod php bin/console secrets:generate-keys This will generate ``config/secrets/prod/prod.encrypt.public.php`` and ``config/secrets/prod/prod.decrypt.private.php``. @@ -78,7 +78,7 @@ Suppose you want to store your database password as a secret. By using the $ php bin/console secrets:set DATABASE_PASSWORD # set your production value - $ php bin/console secrets:set DATABASE_PASSWORD --env=prod + $ APP_RUNTIME_ENV=prod php bin/console secrets:set DATABASE_PASSWORD This will create a new file for the secret in ``config/secrets/dev`` and another in ``config/secrets/prod``. You can also set the secret in a few other ways: @@ -253,7 +253,7 @@ your secrets during deployment to the "local" vault: .. code-block:: terminal - $ php bin/console secrets:decrypt-to-local --force --env=prod + $ 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). From ded882526e23c22d14455d2e6c191c93e979f5a6 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 21 Oct 2020 23:36:00 +0200 Subject: [PATCH 0028/5766] [#14421] Merged the new description into the current sentence --- translation.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/translation.rst b/translation.rst index db50e05cb07..672518d8f8e 100644 --- a/translation.rst +++ b/translation.rst @@ -657,10 +657,8 @@ must be named according to the following path: ``domain.locale.loader``: * **domain**: Domains are a way to organize messages into groups. Unless parts of the application are explicitly separated from each other, it is - recommended to only use default ``messages`` domain. - - If no domains are explicitly defined while using the translator, Symfony - will default to the ``messages`` domain (e.g. ``messages.en.yaml``) + recommended to only use the default ``messages`` domain (e.g. + ``messages.en.yaml``). * **locale**: The locale that the translations are for (e.g. ``en_GB``, ``en``, etc); From 300da7ba340b6759d6e58614ec0feca9ef460ea6 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 22 Oct 2020 08:58:19 +0200 Subject: [PATCH 0029/5766] Enhancement: New rules for DOCtor-RST. --- .doctor-rst.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 6711c75c8f2..a243e6266b6 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -24,6 +24,8 @@ rules: no_namespace_after_use_statements: ~ no_php_open_tag_in_code_block_php_directive: ~ no_space_before_self_xml_closing_tag: ~ + only_backslashes_in_namespace_in_php_code_block: ~ + only_backslashes_in_use_statements_in_php_code_block: ~ ordered_use_statements: ~ php_prefix_before_bin_console: ~ replace_code_block_types: ~ From 3781df649e39522eddbb612d452c661eb33f33d1 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Fri, 12 Jun 2020 13:46:50 +0200 Subject: [PATCH 0030/5766] [PropertyInfo] Document setting serializer_groups to null in the SerializerExtractor --- components/property_info.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/components/property_info.rst b/components/property_info.rst index d67034b04fa..16aac3299e2 100644 --- a/components/property_info.rst +++ b/components/property_info.rst @@ -435,7 +435,18 @@ with the ``property_info`` service in the Symfony Framework:: $serializerExtractor = new SerializerExtractor($serializerClassMetadataFactory); // List information. - $serializerExtractor->getProperties($class); + $serializerExtractor->getProperties($class, ['serializer_groups' => ['mygroup']]); + +.. note:: + + The ``serializer_groups`` option must be provided in order to have a value different than ``null`` returned. + + 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`` annotation is taken into account). + +.. versionadded:: 5.2 + + Support for the ``null`` value in ``serializer_groups`` was introduced in Symfony 5.2. DoctrineExtractor ~~~~~~~~~~~~~~~~~ From d0abaf04aa169560fa7e791debbc82299991be0e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 09:19:42 +0200 Subject: [PATCH 0031/5766] Tweaks --- components/property_info.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/components/property_info.rst b/components/property_info.rst index 16aac3299e2..b6684d948d8 100644 --- a/components/property_info.rst +++ b/components/property_info.rst @@ -434,15 +434,12 @@ with the ``property_info`` service in the Symfony Framework:: ); $serializerExtractor = new SerializerExtractor($serializerClassMetadataFactory); - // List information. + // the `serializer_groups` option must be configured (may be set to null) $serializerExtractor->getProperties($class, ['serializer_groups' => ['mygroup']]); - -.. note:: - - The ``serializer_groups`` option must be provided in order to have a value different than ``null`` returned. - 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`` annotation is taken into account). +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`` annotation is taken into account). .. versionadded:: 5.2 From f40ec08e5f39763dc62d8035fc228210605970c5 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 22 Oct 2020 09:29:38 +0200 Subject: [PATCH 0032/5766] Fix: DOCtor-RST --- 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 db0501182bc..7aee0061c0c 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -645,7 +645,7 @@ tags, is to implement the static ``getDefaultPriority()`` method on the service itself:: // src/Handler/One.php - namespace App/Handler; + namespace App\Handler; class One { From d084e993a4a6e321c4a8eeb132e273d33e2c408a Mon Sep 17 00:00:00 2001 From: "heddi.nabbisen" Date: Wed, 17 Jun 2020 20:44:36 +0900 Subject: [PATCH 0033/5766] add a note about npm commands equivalent to yarn's --- frontend/encore/simple-example.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index 65b96370059..50dec19e46a 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -74,6 +74,21 @@ To build the assets, run: Stop and restart ``encore`` each time you update your ``webpack.config.js`` file. +.. note:: + + If you prefer npm, run these commands instead: + + .. code-block:: terminal + + # compile assets once + $ npm run dev + + # or, recompile assets automatically when files change + $ npm run watch + + # on deploy, create a production build + $ npm run build + Congrats! You now have three new files: * ``public/build/app.js`` (holds all the JavaScript for your "app" entry) From f3c629e836118404480e71653b759da1ee5f6ab4 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 10:33:32 +0200 Subject: [PATCH 0034/5766] Tweak --- frontend/encore/simple-example.rst | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index 50dec19e46a..6ddcd5bdbd8 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -63,32 +63,23 @@ To build the assets, run: # compile assets once $ yarn encore dev + # if you prefer npm, run: + $ npm run dev # or, recompile assets automatically when files change $ yarn encore dev --watch + # if you prefer npm, run: + $ npm run watch # on deploy, create a production build $ yarn encore production + # if you prefer npm, run: + $ npm run build .. note:: Stop and restart ``encore`` each time you update your ``webpack.config.js`` file. -.. note:: - - If you prefer npm, run these commands instead: - - .. code-block:: terminal - - # compile assets once - $ npm run dev - - # or, recompile assets automatically when files change - $ npm run watch - - # on deploy, create a production build - $ npm run build - Congrats! You now have three new files: * ``public/build/app.js`` (holds all the JavaScript for your "app" entry) From 2a863fb883d82568bcdbbfc80cd73b0d1fa564f2 Mon Sep 17 00:00:00 2001 From: Rezende Date: Thu, 23 Jul 2020 12:06:51 -0300 Subject: [PATCH 0035/5766] =?UTF-8?q?Recommending=20symfony/apache-pack=20?= =?UTF-8?q?when=20installing=20the=20project=20on=20a=20sha=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- deployment.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/deployment.rst b/deployment.rst index 5d02bae0e58..18fd4ec6fa8 100644 --- a/deployment.rst +++ b/deployment.rst @@ -195,6 +195,7 @@ setup: * Add/edit CRON jobs * :ref:`Building and minifying your assets ` with Webpack Encore * Pushing assets to a CDN +* On a shared hosting platform using the Apache web server, you may need to install the :ref:`symfony/apache-pack package ` * ... Application Lifecycle: Continuous Integration, QA, etc. From 060773ef8ce9338c421688a146b316595b557ae1 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 22 Oct 2020 10:40:32 +0200 Subject: [PATCH 0036/5766] [#14422] Minor change in sentence --- logging/channels_handlers.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/logging/channels_handlers.rst b/logging/channels_handlers.rst index bac0be76012..8f6e9aed98a 100644 --- a/logging/channels_handlers.rst +++ b/logging/channels_handlers.rst @@ -182,10 +182,11 @@ How to Autowire Logger Channels Starting from `MonologBundle`_ 3.5 you can autowire different Monolog channels by type-hinting your service arguments with the following syntax: -``Psr\Log\LoggerInterface $Logger``. The ```` must have been -predefined in your Monolog configuration. +``Psr\Log\LoggerInterface $Logger``. The ```` must have been +:ref:`predefined in your Monolog configuration `. -An example to inject the service related to the ``app`` logger channel: +For example to inject the service related to the ``app`` logger channel, +change your constructor like this: .. code-block:: diff From feef663fa650ebc2acaa4b40b2c5660cc3b2d874 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 10:40:48 +0200 Subject: [PATCH 0037/5766] Wrap long lines --- deployment.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/deployment.rst b/deployment.rst index 18fd4ec6fa8..36854742dcc 100644 --- a/deployment.rst +++ b/deployment.rst @@ -195,7 +195,8 @@ setup: * Add/edit CRON jobs * :ref:`Building and minifying your assets ` with Webpack Encore * Pushing assets to a CDN -* On a shared hosting platform using the Apache web server, you may need to install the :ref:`symfony/apache-pack package ` +* On a shared hosting platform using the Apache web server, you may need to + install the :ref:`symfony/apache-pack package ` * ... Application Lifecycle: Continuous Integration, QA, etc. From 369ea13ea891df848615e629bd35e3f539b3eb94 Mon Sep 17 00:00:00 2001 From: Gauthier Gilles Date: Tue, 17 Dec 2019 09:27:31 +0100 Subject: [PATCH 0038/5766] add caution for datetime object --- serializer.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/serializer.rst b/serializer.rst index b1e64881831..31c47e607dc 100644 --- a/serializer.rst +++ b/serializer.rst @@ -115,6 +115,12 @@ Custom normalizers and/or encoders can also be loaded by tagging them as :ref:`serializer.encoder `. It's also possible to set the priority of the tag in order to decide the matching order. +.. caution:: + + Always make sure to load the ``DateTimeNormalizer`` when serializing the + ``DateTime`` or ``DateTimeImmutable`` classes to avoid excessive memory + usage and exposing internal details. + Here is an example on how to load the :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer`, a faster alternative to the `ObjectNormalizer` when data objects always use From 269379fa5c6af4982f2f704c97d91f8eb8d2b8be Mon Sep 17 00:00:00 2001 From: Zairig Imad Date: Sun, 19 Apr 2020 14:11:38 +0200 Subject: [PATCH 0039/5766] replace ExceptionListener by EventListener Deprecated ExceptionListener is replaced by EventListener in Symfony 5.0 --- reference/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/events.rst b/reference/events.rst index b7eec4d8dbd..900d40eb12c 100644 --- a/reference/events.rst +++ b/reference/events.rst @@ -251,7 +251,7 @@ sent as response:: .. note:: - The TwigBundle registers an :class:`Symfony\\Component\\HttpKernel\\EventListener\\ExceptionListener` + The TwigBundle registers an :class:`Symfony\\Component\\HttpKernel\\EventListener\\ErrorListener` that forwards the ``Request`` to a given controller defined by the ``exception_listener.controller`` parameter. From 3bc914cc2043612bfc97e1e9e7c78c95ef695e52 Mon Sep 17 00:00:00 2001 From: Rachid Hammaoui <37940572+makmaoui@users.noreply.github.com> Date: Fri, 14 Aug 2020 18:41:43 +0200 Subject: [PATCH 0040/5766] Fix wrong properties class Fix classname for query and cookies properties --- components/http_foundation.rst | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index dad9990dd64..3a90611edbe 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -83,17 +83,19 @@ can be accessed via several public properties: Each property is a :class:`Symfony\\Component\\HttpFoundation\\ParameterBag` instance (or a sub-class of), which is a data holder class: -* ``request``: :class:`Symfony\\Component\\HttpFoundation\\ParameterBag`; +* ``request``: :class:`Symfony\\Component\\HttpFoundation\\ParameterBag` or + :class:`Symfony\\Component\\HttpFoundation\\InputBag` if the data is + coming from ``$_POST`` parameters; -* ``query``: :class:`Symfony\\Component\\HttpFoundation\\ParameterBag`; +* ``query``: :class:`Symfony\\Component\\HttpFoundation\\InputBag`; -* ``cookies``: :class:`Symfony\\Component\\HttpFoundation\\ParameterBag`; +* ``cookies``: :class:`Symfony\\Component\\HttpFoundation\\InputBag`; * ``attributes``: :class:`Symfony\\Component\\HttpFoundation\\ParameterBag`; -* ``files``: :class:`Symfony\\Component\\HttpFoundation\\FileBag`; +* ``files``: :class:`Symfony\\Component\\HttpFoundation\\FileBag`; -* ``server``: :class:`Symfony\\Component\\HttpFoundation\\ServerBag`; +* ``server``: :class:`Symfony\\Component\\HttpFoundation\\ServerBag`; * ``headers``: :class:`Symfony\\Component\\HttpFoundation\\HeaderBag`. From 9d189ef6b5e1c381923ac894ec3237ed45e620de Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 11:23:38 +0200 Subject: [PATCH 0041/5766] [RateLimiter] Document the RateLimit object --- rate_limiter.rst | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/rate_limiter.rst b/rate_limiter.rst index 6fa7192945f..527357cc011 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -212,6 +212,50 @@ processes by reserving unused tokens. $limit->wait(); } while (!$limit->isAccepted()); +Exposing the Rate Limiter Status +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +When using a rate limiter in APIs, it's common to include some standard HTTP +headers in the response to expose the limit status (e.g. remaining tokens, when +new tokens will be available, etc.) + +Use the :class:`Symfony\\Component\\RateLimiter\\RateLimit` object returned by +the ``consume()`` method (also available via the ``getRateLimit()`` method of +the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the +``reserve()`` method) to get the value of those HTTP headers:: + + // src/Controller/ApiController.php + namespace App\Controller; + + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\RateLimiter\RateLimiter; + + class ApiController extends AbstractController + { + public function index(RateLimiter $anonymousApiLimiter) + { + $limiter = $anonymousApiLimiter->create($request->getClientIp()); + $limit = $limiter->consume(); + $headers = [ + 'X-RateLimit-Remaining' => $limit->getRemainingTokens(), + 'X-RateLimit-Retry-After' => $limit->getRetryAfter()->getTimestamp(), + 'X-RateLimit-Limit' => $limit->getLimit(), + ]; + + if (false === $limit->isAccepted()) { + return new Response(null, Response::HTTP_TOO_MANY_REQUESTS, $headers); + } + + // ... + + $reponse = new Response('...'); + $response->headers->add($headers); + + return $response; + } + } + Rate Limiter Storage and Locking -------------------------------- From 809b7a0e63d9dfb743c6aaea9f6bda485bb3de2a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 09:56:38 +0200 Subject: [PATCH 0042/5766] [Lock] Mention the priority policy of shared locks --- components/lock.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/lock.rst b/components/lock.rst index 518a01c9375..3a92184c85e 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -237,6 +237,11 @@ to acquire the lock in a blocking mode:: $lock = $factory->createLock('user'.$user->id); $lock->acquireRead(true); +.. note:: + + The `priority policy`_ of Symfony's shared locks depends on the underlying + store (e.g. Redis store prioritizes readers vs writers). + When a read-only lock is acquired with the method ``acquireRead()``, it's possible to **promote** the lock, and change it to write lock, by calling the ``acquire()`` method:: @@ -915,3 +920,4 @@ are still running. .. _`Replica Set Read and Write Semantics`: https://docs.mongodb.com/manual/applications/replication/ .. _`ZooKeeper`: https://zookeeper.apache.org/ .. _`readers–writer lock`: https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock +.. _`priority policy`: https://en.wikipedia.org/wiki/Readers%E2%80%93writer_lock#Priority_policies From 864cefbc7a34d3b313019f2c415e2a27d81ff4bd Mon Sep 17 00:00:00 2001 From: Zairig Imad Date: Tue, 9 Jun 2020 22:46:45 +0200 Subject: [PATCH 0043/5766] Update the Snippet with the UserUpgraderInterface --- security/user_provider.rst | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/security/user_provider.rst b/security/user_provider.rst index 13e6a8dfb49..07227868afe 100644 --- a/security/user_provider.rst +++ b/security/user_provider.rst @@ -356,10 +356,11 @@ command will generate a nice skeleton to get you started:: use Symfony\Component\Security\Core\Exception\UnsupportedUserException; use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; + use Symfony\Component\Security\Core\User\PasswordUpgraderInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Core\User\UserProviderInterface; - class UserProvider implements UserProviderInterface + class UserProvider implements UserProviderInterface, PasswordUpgraderInterface { /** * Symfony calls this method if you use features like switch_user @@ -412,6 +413,16 @@ command will generate a nice skeleton to get you started:: { return User::class === $class || is_subclass_of($class, User::class); } + + /** + * Upgrades the encoded password of a user, typically for using a better hash algorithm. + */ + public function upgradePassword(UserInterface $user, string $newEncodedPassword): void + { + // TODO: when encoded passwords are in use, this method should: + // 1. persist the new password in the user storage + // 2. update the $user object with $user->setPassword($newEncodedPassword); + } } Most of the work is already done! Read the comments in the code and update the From 17af86e24d25421f43d61fc019b263739218a7ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dalibor=20Karlovi=C4=87?= Date: Thu, 22 Oct 2020 15:45:29 +0200 Subject: [PATCH 0044/5766] Correct English word order --- mercure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mercure.rst b/mercure.rst index 921a45f7226..9dd6fe205b9 100644 --- a/mercure.rst +++ b/mercure.rst @@ -443,7 +443,7 @@ And here is the controller:: To use the cookie authentication method, the Symfony app and the Hub must be served from the same domain (can be different sub-domains). -Generating Programmatically The JWT Used to Publish +Programmatically Generating The JWT Used to Publish --------------------------------------------------- Instead of directly storing a JWT in the configuration, From 22345e0b151835cbd86c4de6bc8be7fccdd1fe22 Mon Sep 17 00:00:00 2001 From: gary houbre Date: Mon, 5 Oct 2020 21:24:25 +0200 Subject: [PATCH 0045/5766] Fix missing namespace and other wrong wording from Security and Serializer context --- security/access_denied_handler.rst | 1 + security/csrf.rst | 3 +++ security/custom_authentication_provider.rst | 8 ++++++++ security/form_login.rst | 1 + security/form_login_setup.rst | 1 + security/guard_authentication.rst | 7 ++++++- security/impersonating_user.rst | 4 ++++ security/json_login_setup.rst | 1 + security/named_encoders.rst | 4 ++-- serializer/custom_encoders.rst | 1 + serializer/custom_normalizer.rst | 1 + 11 files changed, 29 insertions(+), 3 deletions(-) diff --git a/security/access_denied_handler.rst b/security/access_denied_handler.rst index e9e780e75ef..e9fd7cb15f5 100644 --- a/security/access_denied_handler.rst +++ b/security/access_denied_handler.rst @@ -13,6 +13,7 @@ This interface defines one method called ``handle()`` where you can implement wh logic that should run when access is denied for the current user (e.g. send a mail, log a message, or generally return a custom response):: + // src/Security/AccessDeniedHandler.php namespace App\Security; use Symfony\Component\HttpFoundation\Request; diff --git a/security/csrf.rst b/security/csrf.rst index d54bfc43770..9da64168379 100644 --- a/security/csrf.rst +++ b/security/csrf.rst @@ -83,6 +83,9 @@ protected against CSRF attacks. By default Symfony adds the CSRF token in a hidden field called ``_token``, but this can be customized on a form-by-form basis:: + // src/Form/TaskType.php + namespace App\Form; + // ... use App\Entity\Task; use Symfony\Component\OptionsResolver\OptionsResolver; diff --git a/security/custom_authentication_provider.rst b/security/custom_authentication_provider.rst index d0db9c91168..920c8315f05 100644 --- a/security/custom_authentication_provider.rst +++ b/security/custom_authentication_provider.rst @@ -538,6 +538,11 @@ can have different timeout lengths. You will first need to edit ``WsseFactory`` and define the new option in the ``addConfiguration()`` method:: + // src/DependencyInjection/Security/Factory/WsseFactory.php + namespace App\DependencyInjection\Security\Factory; + + // ... + class WsseFactory implements SecurityFactoryInterface { // ... @@ -556,6 +561,9 @@ contain a ``lifetime`` key, set to 5 minutes (300 seconds) unless otherwise set in the configuration. Pass this argument to your authentication provider in order to put it to use:: + // src/DependencyInjection/Security/Factory/WsseFactory.php + namespace App\DependencyInjection\Security\Factory; + use App\Security\Authentication\Provider\WsseProvider; class WsseFactory implements SecurityFactoryInterface diff --git a/security/form_login.rst b/security/form_login.rst index cd53d277c88..374e21a78b7 100644 --- a/security/form_login.rst +++ b/security/form_login.rst @@ -93,6 +93,7 @@ configuration (``login``): .. code-block:: php-annotations // src/Controller/SecurityController.php + namespace App\Controller; // ... use Symfony\Component\Routing\Annotation\Route; diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index abbbb6eb1f2..f1f646fad47 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -477,6 +477,7 @@ If you also want to apply this behavior to public pages, you can create an :doc:`event subscriber ` to set the target path manually whenever the user browses a page:: + // src/EventSubscriber/RequestSubscriber.php namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; diff --git a/security/guard_authentication.rst b/security/guard_authentication.rst index edbd6f122ee..7a6a25b9618 100644 --- a/security/guard_authentication.rst +++ b/security/guard_authentication.rst @@ -28,6 +28,8 @@ your ``User`` class (the ``make:entity`` command is a good way to do this): .. code-block:: diff // src/Entity/User.php + namespace App\Entity; + // ... class User implements UserInterface @@ -411,6 +413,8 @@ You can throw this from ``getCredentials()``, ``getUser()`` or ``checkCredential to cause a failure:: // src/Security/TokenAuthenticator.php + namespace App\Security; + // ... use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException; @@ -453,8 +457,9 @@ completes registration. To do that, use your authenticator and a service called ``GuardAuthenticatorHandler``:: // src/Controller/RegistrationController.php + namespace App\Controller; + // ... - use App\Security\LoginFormAuthenticator; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst index 308ed5b1e58..5f44a7fad23 100644 --- a/security/impersonating_user.rst +++ b/security/impersonating_user.rst @@ -113,6 +113,9 @@ stored in the token storage will be a ``SwitchUserToken`` instance. Use the following snippet to obtain the original token which gives you access to the impersonator user:: + // src/Service/SomeService.php + namespace App\Service; + use Symfony\Component\Security\Core\Authentication\Token\SwitchUserToken; use Symfony\Component\Security\Core\Security; // ... @@ -256,6 +259,7 @@ be called): Then, create a voter class that responds to this role and includes whatever custom logic you want:: + // src/Service/Voter/SwitchToCustomerVoter.php namespace App\Security\Voter; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; diff --git a/security/json_login_setup.rst b/security/json_login_setup.rst index e1ec17e8587..a4be5dac0e7 100644 --- a/security/json_login_setup.rst +++ b/security/json_login_setup.rst @@ -65,6 +65,7 @@ The next step is to configure a route in your app matching this path: .. code-block:: php-annotations // src/Controller/SecurityController.php + namespace App\Controller; // ... use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; diff --git a/security/named_encoders.rst b/security/named_encoders.rst index aad4d740fb1..22bc333dec4 100644 --- a/security/named_encoders.rst +++ b/security/named_encoders.rst @@ -117,8 +117,8 @@ to use it, the class must implement The interface requires one method - ``getEncoderName()`` - which should return the name of the encoder to use:: - // src/Acme/UserBundle/Entity/User.php - namespace Acme\UserBundle\Entity; + // src/Entity/User.php + namespace App\Entity; use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; use Symfony\Component\Security\Core\User\UserInterface; diff --git a/serializer/custom_encoders.rst b/serializer/custom_encoders.rst index 5bb78def4e4..4c08b410dbd 100644 --- a/serializer/custom_encoders.rst +++ b/serializer/custom_encoders.rst @@ -19,6 +19,7 @@ Imagine you want to serialize and deserialize YAML. For that you'll have to create your own encoder that uses the :doc:`Yaml Component `:: + // src/Serializer/YamlEncoder.php namespace App\Serializer; use Symfony\Component\Serializer\Encoder\DecoderInterface; diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst index 9f2e50fdcf1..6ee7d870ed5 100644 --- a/serializer/custom_normalizer.rst +++ b/serializer/custom_normalizer.rst @@ -17,6 +17,7 @@ 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``:: + // src/Serializer/TopicNormalizer.php namespace App\Serializer; use App\Entity\Topic; From 269f500c45bf4ae3654d5edb92825c9d4e0c66ae Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 17:41:24 +0200 Subject: [PATCH 0046/5766] Added missing namespace --- security/experimental_authenticators.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index 83b3199d9ef..8a1b6081d84 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -472,6 +472,9 @@ the following badges are supported: For instance, if you want to add CSRF and password migration to your custom authenticator, you would initialize the passport like this:: + // src/Service/LoginAuthenticator.php + namespace App\Service; + // ... use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; From e912f23b557bd56ed1c7c296f12b178f48e6dfb5 Mon Sep 17 00:00:00 2001 From: TavoNiievez <64917965+TavoNiievez@users.noreply.github.com> Date: Thu, 22 Oct 2020 13:54:00 -0500 Subject: [PATCH 0047/5766] Typo in impersonator role The correct role is 'IS_IMPERSONATOR'. --- components/security/authorization.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/security/authorization.rst b/components/security/authorization.rst index c074cf14b75..b884ce97ac0 100644 --- a/components/security/authorization.rst +++ b/components/security/authorization.rst @@ -114,12 +114,12 @@ user fully authenticated, or only based on a "remember-me" cookie, or even authenticated anonymously? It also supports the attributes ``IS_ANONYMOUS``, ``IS_REMEMBERED``, -``IS_IMPERSONATED`` to grant access based on a specific state of +``IS_IMPERSONATOR`` to grant access based on a specific state of authentication. .. versionadded:: 5.1 - The ``IS_ANONYMOUS``, ``IS_REMEMBERED`` and ``IS_IMPERSONATED`` + The ``IS_ANONYMOUS``, ``IS_REMEMBERED`` and ``IS_IMPERSONATOR`` attributes were introduced in Symfony 5.1. :: From 745af3cc386fa7efd71a95f6d605138f692f8c21 Mon Sep 17 00:00:00 2001 From: Przemek Maszczynski Date: Thu, 22 Oct 2020 22:46:13 +0200 Subject: [PATCH 0048/5766] Removed duplicate method --- security/form_login_setup.rst | 8 -------- 1 file changed, 8 deletions(-) diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index f1f646fad47..768ce725a72 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -77,14 +77,6 @@ class that processes the login submit and 4) updates the main security config fi return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]); } - /** - * @Route("/logout", name="app_logout") - */ - public function logout() - { - throw new \Exception('This method can be blank - it will be intercepted by the logout key on your firewall'); - } - /** * @Route("/logout", name="app_logout") */ From c630bcb1739638120d1fc7bf2c62c0f14bc7ee1e Mon Sep 17 00:00:00 2001 From: Mathieu Piot Date: Fri, 17 Apr 2020 13:51:19 +0200 Subject: [PATCH 0049/5766] Add Discord notifier --- notifier.rst | 3 ++- notifier/chatters.rst | 53 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 9d0b5148553..d79933b7188 100644 --- a/notifier.rst +++ b/notifier.rst @@ -139,6 +139,7 @@ integration with these chat services: ========== ================================ =========================================================================== Service Package DSN ========== ================================ =========================================================================== +Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?threadKey=THREAD_KEY`` LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://TOKEN@ENDPOINT?channel=CHANNEL`` @@ -156,7 +157,7 @@ Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:APIKEY@ENDPOINT?ch .. versionadded:: 5.2 - The GoogleChat, LinkedIn and Zulip integrations were introduced in Symfony 5.2. + The GoogleChat, LinkedIn, Zulip and Discord integrations were introduced in Symfony 5.2. Chatters are configured using the ``chatter_transports`` setting: diff --git a/notifier/chatters.rst b/notifier/chatters.rst index efbd040593e..b37d17c2040 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -99,3 +99,56 @@ some interactive options called `Block elements`_:: $chatter->send($chatMessage); .. _`Block elements`: https://api.slack.com/reference/block-kit/block-elements + +Adding Interactions to a Discord Message +-------------------------------------- + +With a Discord message, you can use the +:class:`Symfony\\Component\\Notifier\\Bridge\\Discord\\DiscordOptions` to add +some interactive options called `Embed elements`_:: + + use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordEmbed; + use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordFieldEmbedObject; + use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordFooterEmbedObject; + use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordMediaEmbedObject; + use Symfony\Component\Notifier\Bridge\Discord\DiscordOptions; + use Symfony\Component\Notifier\Message\ChatMessage; + + $chatMessage = new ChatMessage(''); + + // Create Discord Embed + $discordOptions = (new DiscordOptions()) + ->username('connor bot') + ->addEmbed((new DiscordEmbed()) + ->color(2021216) + ->title('New song added!') + ->thumbnail((new DiscordMediaEmbedObject()) + ->url('https://i.scdn.co/image/ab67616d0000b2735eb27502aa5cb1b4c9db426b')) + ->addField((new DiscordFieldEmbedObject()) + ->name('Track') + ->value('[Common Ground](https://open.spotify.com/track/36TYfGWUhIRlVjM8TxGUK6)') + ->inline(true) + ) + ->addField((new DiscordFieldEmbedObject()) + ->name('Artist') + ->value('Alasdair Fraser') + ->inline(true) + ) + ->addField((new DiscordFieldEmbedObject()) + ->name('Album') + ->value('Dawn Dance') + ->inline(true) + ) + ->footer((new DiscordFooterEmbedObject()) + ->text('Added ...') + ->iconUrl('https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Spotify_logo_without_text.svg/200px-Spotify_logo_without_text.svg.png') + ) + ) + ; + + // Add the custom options to the chat message and send the message + $chatMessage->options($discordOptions); + + $chatter->send($chatMessage); + +.. _`Embed elements`: https://discord.com/developers/docs/resources/webhook From bf6cca937f6c2e96a0e9a2deeeae0fc768b8a764 Mon Sep 17 00:00:00 2001 From: Baptiste Leduc Date: Fri, 23 Oct 2020 13:45:06 +0200 Subject: [PATCH 0050/5766] Non-standard adder/remover methods --- components/property_access.rst | 39 ++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/components/property_access.rst b/components/property_access.rst index df0f3d99b51..741d3023ad5 100644 --- a/components/property_access.rst +++ b/components/property_access.rst @@ -394,6 +394,45 @@ and ``removeChild()`` methods to access to the ``children`` property. If available, *adder* and *remover* methods have priority over a *setter* method. +Using non-standard adder/remover methods +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Sometimes, adder and remover methods don't use the standard ``add`` or ``remove`` prefix, like in this example:: + + // ... + class PeopleList + { + // ... + + public function joinPeople(string $people): void + { + $this->peoples[] = $people; + } + + public function leavePeople(string $people): void + { + foreach ($this->peoples as $id => $item) { + if ($people === $item) { + unset($this->peoples[$id]); + break; + } + } + } + } + + use Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor; + use Symfony\Component\PropertyAccess\PropertyAccessor; + + $list = new PeopleList(); + $reflectionExtractor = new ReflectionExtractor(null, null, ['join', 'leave']); + $propertyAccessor = new PropertyAccessor(false, false, null, true, $reflectionExtractor, $reflectionExtractor); + $propertyAccessor->setValue($person, 'peoples', ['kevin', 'wouter']); + + var_dump($person->getPeoples()); // ['kevin', 'wouter'] + +Instead of calling ``add()`` and ``remove()``, the PropertyAccess +component will call ``join()`` and ``leave()`` methods. + Checking Property Paths ----------------------- From 3194c224966f6764057d166f7bf9997e689d77b5 Mon Sep 17 00:00:00 2001 From: Robin Chalas Date: Fri, 23 Oct 2020 13:51:30 +0200 Subject: [PATCH 0051/5766] [Security] Remove extra argument from call to EntityManager#flush() --- security/password_migration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/password_migration.rst b/security/password_migration.rst index 9553d46de5a..bb77a0504ab 100644 --- a/security/password_migration.rst +++ b/security/password_migration.rst @@ -190,7 +190,7 @@ storing the newly created password hash:: $user->setPassword($newEncodedPassword); // execute the queries on the database - $this->getEntityManager()->flush($user); + $this->getEntityManager()->flush(); } } From 8fe20c33a49ba1bd21de5eb78477752e5c6fdd1b Mon Sep 17 00:00:00 2001 From: Toni Rudolf Date: Mon, 3 Feb 2020 17:24:10 +0100 Subject: [PATCH 0052/5766] Added redeliver_timeout and claim_interval options --- messenger.rst | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/messenger.rst b/messenger.rst index 54c7fb200a5..9917e5d7c28 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1038,9 +1038,9 @@ a running Redis server (^5.0). A number of options can be configured via the DSN or via the ``options`` key under the transport in ``messenger.yaml``: -================== ===================================== ========================= - Option Description Default -================== ===================================== ========================= +=================== ===================================== ================================= + Option Description Default +=================== ===================================== ================================= stream The Redis stream name messages group The Redis consumer group name symfony consumer Consumer name used in Redis consumer @@ -1056,7 +1056,23 @@ stream_max_entries The maximum number of entries which ``0`` (which means "n it to a large enough number to avoid losing pending messages tls Enable TLS support for the connection false -================== ===================================== ========================= +redeliver_timeout Timeout before retrying a pending ``3600`` + message which is owned by an + abandoned consumer (if a worker died + for some reason, this will occur, + eventually you should retry the + message) - in seconds. +claim_interval Interval on which pending/abandoned ``60000`` (1 Minute) + messages should be checked for to + claim - in milliseconds +=================== ===================================== ================================= + +.. caution:: + + There should never be more than one `messenger:consume` command running with the same + config (stream, group and consumer name) to avoid having a message handled more than once. + Using the ``HOSTNAME`` as the consumer might often be a good idea. In case you are using + Kubernetes to orchestrate your containers, consider using a ``StatefulSet``. .. tip:: From d6988a76ee403c23382fd420dd60dcc69fb083f3 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 23 Oct 2020 15:05:47 +0200 Subject: [PATCH 0053/5766] [#12976] Minor syntax fix --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 9917e5d7c28..78d09d50e9a 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1069,7 +1069,7 @@ claim_interval Interval on which pending/abandoned ``60000`` (1 Minute) .. caution:: - There should never be more than one `messenger:consume` command running with the same + There should never be more than one ``messenger:consume`` command running with the same config (stream, group and consumer name) to avoid having a message handled more than once. Using the ``HOSTNAME`` as the consumer might often be a good idea. In case you are using Kubernetes to orchestrate your containers, consider using a ``StatefulSet``. From 08496685d725a48630e0a019e11188cd1c7c1c91 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Fri, 23 Oct 2020 15:08:55 +0200 Subject: [PATCH 0054/5766] [#12976] Added the new options to the versionadded directive --- messenger.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 78d09d50e9a..3dce638cd70 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1083,7 +1083,8 @@ claim_interval Interval on which pending/abandoned ``60000`` (1 Minute) .. versionadded:: 5.1 - The ``delete_after_ack`` option was introduced in Symfony 5.1. + The ``delete_after_ack``, ``redeliver_timeout`` and ``claim_interval`` + options were introduced in Symfony 5.1. In Memory Transport ~~~~~~~~~~~~~~~~~~~ From f79b26828e2bed575c0fbecf3860b9893103efe4 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 23 Oct 2020 15:14:37 +0200 Subject: [PATCH 0055/5766] Syntax fix --- notifier/chatters.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier/chatters.rst b/notifier/chatters.rst index b37d17c2040..9d03f83987c 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -101,7 +101,7 @@ some interactive options called `Block elements`_:: .. _`Block elements`: https://api.slack.com/reference/block-kit/block-elements Adding Interactions to a Discord Message --------------------------------------- +---------------------------------------- With a Discord message, you can use the :class:`Symfony\\Component\\Notifier\\Bridge\\Discord\\DiscordOptions` to add From 55a6ad049d3c17b4a9c651aa5ecdf4dab5bec5c2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 23 Oct 2020 15:24:54 +0200 Subject: [PATCH 0056/5766] Fixed a syntax issue --- messenger.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/messenger.rst b/messenger.rst index f2c2a8b65be..7f74be71dd6 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1160,21 +1160,21 @@ under the transport in ``messenger.yaml``: =================== ===================================== ================================= Option Description Default =================== ===================================== ================================= -stream The Redis stream name messages -group The Redis consumer group name symfony -consumer Consumer name used in Redis consumer -auto_setup Create the Redis group automatically? true -auth The Redis password -delete_after_ack If ``true``, messages are deleted false - automatically after processing them -serializer How to serialize the final payload ``Redis::SERIALIZER_PHP`` - in Redis (the - ``Redis::OPT_SERIALIZER`` option) -stream_max_entries The maximum number of entries which ``0`` (which means "no trimming") - the stream will be trimmed to. Set - it to a large enough number to - avoid losing pending messages -tls Enable TLS support for the connection false +stream The Redis stream name messages +group The Redis consumer group name symfony +consumer Consumer name used in Redis consumer +auto_setup Create the Redis group automatically? true +auth The Redis password +delete_after_ack If ``true``, messages are deleted false + automatically after processing them +serializer How to serialize the final payload ``Redis::SERIALIZER_PHP`` + in Redis (the + ``Redis::OPT_SERIALIZER`` option) +stream_max_entries The maximum number of entries which ``0`` (which means "no trimming") + the stream will be trimmed to. Set + it to a large enough number to + avoid losing pending messages +tls Enable TLS support for the connection false redeliver_timeout Timeout before retrying a pending ``3600`` message which is owned by an abandoned consumer (if a worker died From 436e2fc6183b80a5f39300d329b654f607ad25d0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 14 Aug 2020 15:06:43 +0200 Subject: [PATCH 0057/5766] [Testing] Updated the contents about getting the container in tests --- testing.rst | 91 ++++++++++++++++++++--------------------------------- 1 file changed, 34 insertions(+), 57 deletions(-) diff --git a/testing.rst b/testing.rst index 4b64d504631..d5d0941b1ea 100644 --- a/testing.rst +++ b/testing.rst @@ -544,74 +544,51 @@ You can also get the objects related to the latest request:: Accessing the Container ~~~~~~~~~~~~~~~~~~~~~~~ -It's highly recommended that a functional test only tests the response. But -under certain very rare circumstances, you might want to access some services -to write assertions. Given that services are private by default, test classes -define a property that stores a special container created by Symfony which -allows fetching both public and all non-removed private services:: - - // gives access to the same services used in your test, unless you're using - // $client->insulate() or using real HTTP requests to test your application - // don't forget to call self::bootKernel() before, otherwise, the container - // will be empty - $container = self::$container; - -For a list of services available in your application, use the ``debug:container`` -command. - -If a private service is *never* used in your application (outside of your test), -it is *removed* from the container and cannot be accessed as described above. In -that case, you can create a public alias in the ``test`` environment and access -it via that alias: +Functional tests should only test the response (e.g. its contents or its HTTP +status code). However, in some rare circumstances you may need to access the +container to use some service. -.. configuration-block:: - - .. code-block:: yaml - - # config/services_test.yaml - services: - # access the service in your test via - # self::$container->get('test.App\Test\SomeTestHelper') - test.App\Test\SomeTestHelper: - # the id of the private service - alias: 'App\Test\SomeTestHelper' - public: true +First, you can get the same container used in the application, which only +includes the public services:: - .. code-block:: xml - - - - + public function testSomething() + { + $client = self::createClient(); + $container = $client->getContainer(); + // $someService = $container->get('the-service-ID'); - - + // ... + } - - - +Symfony tests also have access to a special container that includes both the +public services and the non-removed :ref:`private services ` +services:: - .. code-block:: php + public function testSomething() + { + // this call is needed; otherwise the container will be empty + self::bootKernel(); - // config/services_test.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; + $container = self::$container; + // $someService = $container->get('the-service-ID'); - use App\Service\MessageGenerator; - use App\Service\SiteUpdateManager; + // ... + } - return function(ContainerConfigurator $configurator) { - // ... +Finally, for the most rare edge-cases, Symfony includes a special container +which provides access to all services, public and private. This special +container is a service that can be get via the normal container:: - $services->alias('test.App\Test\SomeTestHelper', 'App\Test\SomeTestHelper')->public(); - }; + public function testSomething() + { + $client = self::createClient(); + $normalContainer = $client->getContainer(); + $specialContainer = $normalContainer->get('test.service_container'); -.. tip:: + // $somePrivateService = $specialContainer->get('the-service-ID'); - The special container that gives access to private services exists only in - the ``test`` environment and is itself a service that you can get from the - real container using the ``test.service_container`` id. + // ... + } .. tip:: From 85b27e554a7e9b6a26e3358f51ca933eee90fec3 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 23 Oct 2020 13:46:16 +0200 Subject: [PATCH 0058/5766] [Messenger] Added Lazy option to redis --- messenger.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 7f74be71dd6..6c2f2e35794 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1167,6 +1167,10 @@ auto_setup Create the Redis group automatically? true auth The Redis password delete_after_ack If ``true``, messages are deleted false automatically after processing them +delete_after_reject If ``true``, messages are deleted true + automatically if they are rejected +lazy Connect only when a connection is false + really needed serializer How to serialize the final payload ``Redis::SERIALIZER_PHP`` in Redis (the ``Redis::OPT_SERIALIZER`` option) @@ -1207,7 +1211,7 @@ claim_interval Interval on which pending/abandoned ``60000`` (1 Minute) .. versionadded:: 5.2 - The ``delete_after_reject`` option was introduced in Symfony 5.2. + The ``delete_after_reject`` and ``lazy`` options were introduced in Symfony 5.2. In Memory Transport ~~~~~~~~~~~~~~~~~~~ From 38da641b42976ddeef37903c4a0ddd64226f1bab Mon Sep 17 00:00:00 2001 From: Takashi Kanemoto Date: Sat, 24 Oct 2020 18:50:56 +0900 Subject: [PATCH 0059/5766] Fix typo --- testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index d028fc2e713..371b986496c 100644 --- a/testing.rst +++ b/testing.rst @@ -757,7 +757,7 @@ their type:: $form['photo']->upload('/path/to/lucas.jpg'); // In the case of a multiple file upload - $form['my_form[field][O]']->upload('/path/to/lucas.jpg'); + $form['my_form[field][0]']->upload('/path/to/lucas.jpg'); $form['my_form[field][1]']->upload('/path/to/lisa.jpg'); .. tip:: From 87fe4cc0cc5ae0b0c30c254ba5ee38cc51e4f538 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Sun, 25 Oct 2020 07:58:38 +0100 Subject: [PATCH 0060/5766] Remove paragraph about .htaccess files Htaccess files aren't in SF repository anymore (since sf4 and Flex, it's in the apache-pack optional recipe) --- setup/web_server_configuration.rst | 7 ------- 1 file changed, 7 deletions(-) diff --git a/setup/web_server_configuration.rst b/setup/web_server_configuration.rst index 2fc2c74e648..e4fef9b3d99 100644 --- a/setup/web_server_configuration.rst +++ b/setup/web_server_configuration.rst @@ -374,13 +374,6 @@ The **minimum configuration** to get your application running under Nginx is: After you deploy to production, make sure that you **cannot** access the ``index.php`` script (i.e. ``http://example.com/index.php``). -.. note:: - - By default, Symfony applications include several ``.htaccess`` files to - configure redirections and to prevent unauthorized access to some sensitive - directories. Those files are only useful when using Apache, so you can - safely remove them when using Nginx. - For advanced Nginx configuration options, read the official `Nginx documentation`_. .. _`Apache documentation`: https://httpd.apache.org/docs/ From 2fcc6fe060af8fcdb7d7010130e535e548a6d919 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 25 Oct 2020 16:37:19 +0100 Subject: [PATCH 0061/5766] [RateLimit] Make sure we mention policy instead of limit --- rate_limiter.rst | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index 527357cc011..22a56168498 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -16,11 +16,11 @@ Symfony uses these rate limiters in built-in features like "login throttling", which limits how many failed login attempts a user can make in a given period of time, but you can use them for your own features too. -Rate Limiting Strategies ------------------------- +Rate Limiting Policies +---------------------- -Symfony's rate limiter implements some of the most common strategies to enforce -rate limits: **fixed window**, **sliding window** and **token bucket**. +Symfony's rate limiter implements some of the most common policies to enforce +rate limits: **fixed window**, **sliding window**, **token bucket**. Fixed Window Rate Limiter ~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -86,12 +86,12 @@ enforce different levels of service (free or paid): framework: rate_limiter: anonymous_api: - # use 'sliding_window' if you prefer that strategy - strategy: 'fixed_window' + # use 'sliding_window' if you prefer that policy + policy: 'fixed_window' limit: 100 interval: '60 minutes' authenticated_api: - strategy: 'token_bucket' + policy: 'token_bucket' limit: 5000 rate: { interval: '15 minutes', amount: 500 } @@ -124,13 +124,13 @@ the number of requests to the API:: use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; - use Symfony\Component\RateLimiter\RateLimiter; + use Symfony\Component\RateLimiter\RateLimiterFactory; 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(RateLimiter $anonymousApiLimiter) + public function index(RateLimiterFactory $anonymousApiLimiter) { // 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.) @@ -171,11 +171,11 @@ using the ``reserve()`` method:: use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; - use Symfony\Component\RateLimiter\RateLimiter; + use Symfony\Component\RateLimiter\RateLimiterFactory; class ApiController extends AbstractController { - public function registerUser(Request $request, RateLimiter $authenticatedApiLimiter) + public function registerUser(Request $request, RateLimiterFactory $authenticatedApiLimiter) { $apiKey = $request->headers->get('apikey'); $limiter = $authenticatedApiLimiter->create($apiKey); @@ -229,11 +229,11 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\RateLimiter\RateLimiter; + use Symfony\Component\RateLimiter\RateLimiterFactory; class ApiController extends AbstractController { - public function index(RateLimiter $anonymousApiLimiter) + public function index(RateLimiterFactory $anonymousApiLimiter) { $limiter = $anonymousApiLimiter->create($request->getClientIp()); $limit = $limiter->consume(); From 3e0c21cc3eb8b8ed493b982a2c0c3cc77afb76aa Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 25 Oct 2020 16:39:18 +0100 Subject: [PATCH 0062/5766] Update wrong use statement --- translation.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/translation.rst b/translation.rst index cb774e70f7a..4c4b4b9a07b 100644 --- a/translation.rst +++ b/translation.rst @@ -307,16 +307,16 @@ parts of your application and mocking it in your tests. Instead of translating a string at the time of creation, you can use a "translatable object", which is an instance of the -:class:`Symfony\\Component\\Translation\\Translatable` class. This object stores +:class:`Symfony\\Component\\Translation\\TranslatableMessage` class. This object stores all the information needed to fully translate its contents when needed:: - use Symfony\Component\Translation\Translatable; + use Symfony\Component\Translation\TranslatableMessage; // the first argument is required and it's the original message - $message = new Translatable('Symfony is great!'); + $message = new TranslatableMessage('Symfony is great!'); // the optional second argument defines the translation parameters and // the optional third argument is the translation domain - $status = new Translatable('order.status', ['%status%' => $order->getStatus()], 'store'); + $status = new TranslatableMessage('order.status', ['%status%' => $order->getStatus()], 'store'); Templates are now much simpler because you can pass translatable objects to the ``trans`` filter: From 08ded89b8f12598e8a65b694d2c208545cdd884a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=A4fer?= Date: Sun, 25 Oct 2020 11:46:38 +0100 Subject: [PATCH 0063/5766] Change "-t" to "--track" to be more explicit --- 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 1060e0d80a8..c0cd2259250 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -159,7 +159,7 @@ Or, if you want to provide a bug fix for the ``3.4`` branch, first track the rem .. code-block:: terminal - $ git checkout -t origin/3.4 + $ git checkout --track origin/3.4 Then create a new branch off the ``3.4`` branch to work on the bug fix: From 42f4d233dc1269f94bce774879506fba76e30420 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20K=C3=A4fer?= Date: Sun, 25 Oct 2020 11:27:09 +0100 Subject: [PATCH 0064/5766] Change branch "master" to "5.x" Not sure if this is correct but I'm sure that I cannot find "master" anymore. --- contributing/code/pull_requests.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst index c0cd2259250..816130b1168 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -129,7 +129,7 @@ work: ` (you may have to choose a higher branch if the feature you are fixing was introduced in a later version); -* ``master``, if you are adding a new feature. +* ``5.x``, if you are adding a new feature. The only exception is when a new :doc:`major Symfony version ` (4.0, 5.0, etc.) comes out every two years. Because of the @@ -142,7 +142,7 @@ work: All bug fixes merged into maintenance branches are also merged into more recent branches on a regular basis. For instance, if you submit a PR for the ``3.4`` branch, the PR will also be applied by the core team on - the ``master`` branch. + the ``5.x`` branch. Create a Topic Branch ~~~~~~~~~~~~~~~~~~~~~ @@ -152,7 +152,7 @@ topic branch: .. code-block:: terminal - $ git checkout -b BRANCH_NAME master + $ git checkout -b BRANCH_NAME 5.x Or, if you want to provide a bug fix for the ``3.4`` branch, first track the remote ``3.4`` branch locally: @@ -277,15 +277,15 @@ while to finish your changes): .. code-block:: terminal - $ git checkout master + $ git checkout 5.x $ git fetch upstream - $ git merge upstream/master + $ git merge upstream/5.x $ git checkout BRANCH_NAME - $ git rebase master + $ git rebase 5.x .. tip:: - Replace ``master`` with the branch you selected previously (e.g. ``3.4``) + Replace ``5.x`` with the branch you selected previously (e.g. ``3.4``) if you are working on a bug fix. When doing the ``rebase`` command, you might have to fix merge conflicts. @@ -402,12 +402,12 @@ Rework your Pull Request ~~~~~~~~~~~~~~~~~~~~~~~~ Based on the feedback on the pull request, you might need to rework your -PR. Before re-submitting the PR, rebase with ``upstream/master`` or +PR. Before re-submitting the PR, rebase with ``upstream/5.x`` or ``upstream/3.4``, don't merge; and force the push to the origin: .. code-block:: terminal - $ git rebase -f upstream/master + $ git rebase -f upstream/5.x $ git push --force origin BRANCH_NAME .. note:: From 464904fa2d95fca3f3759e9c61162d1d5d2579ef Mon Sep 17 00:00:00 2001 From: Francois CONTE Date: Sat, 24 Oct 2020 22:20:51 +0200 Subject: [PATCH 0065/5766] [Security] Update examples of Login Link --- security/login_link.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/login_link.rst b/security/login_link.rst index 3db4f34f8eb..b92dd694178 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -253,7 +253,7 @@ number:: 'Welcome to MY WEBSITE!' // email subject ); // create a recipient for this user - $recipient = (new Recipient())->email($user->getEmail()); + $recipient = new Recipient($user->getEmail()); // send the notification to the user $notifier->send($notification, $recipient); @@ -620,7 +620,7 @@ user create this POST request (e.g. by clicking a button):: /** * @Route("/login_check", name="login_check") */ - public function check() + public function check(Request $request) { // get the login link query parameters $expires = $request->query->get('expires'); From 1776c69a192042c6999fafc629a88f3c5d646ad0 Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Sun, 25 Oct 2020 23:53:32 +0100 Subject: [PATCH 0066/5766] [DependencyInjection] Fix markup of configuration-block --- service_container/autowiring.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst index 4a2b606c538..e62f75f7513 100644 --- a/service_container/autowiring.rst +++ b/service_container/autowiring.rst @@ -609,7 +609,7 @@ you can use the ``@required`` annotation instead. Despite property injection has some :ref:`drawbacks `, autowiring with ``#[Required]`` or ``@required`` can also be applied to public -typed properties:: +typed properties: .. configuration-block:: From 5094d7f5e59a75b48279925822d58e16d538cb7d Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 26 Oct 2020 11:50:23 +0100 Subject: [PATCH 0067/5766] Fixed table margin --- messenger.rst | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/messenger.rst b/messenger.rst index 3dce638cd70..e9253431bd4 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1041,21 +1041,21 @@ under the transport in ``messenger.yaml``: =================== ===================================== ================================= Option Description Default =================== ===================================== ================================= -stream The Redis stream name messages -group The Redis consumer group name symfony -consumer Consumer name used in Redis consumer -auto_setup Create the Redis group automatically? true -auth The Redis password -delete_after_ack If ``true``, messages are deleted false - automatically after processing them -serializer How to serialize the final payload ``Redis::SERIALIZER_PHP`` - in Redis (the - ``Redis::OPT_SERIALIZER`` option) -stream_max_entries The maximum number of entries which ``0`` (which means "no trimming") - the stream will be trimmed to. Set - it to a large enough number to - avoid losing pending messages -tls Enable TLS support for the connection false +stream The Redis stream name messages +group The Redis consumer group name symfony +consumer Consumer name used in Redis consumer +auto_setup Create the Redis group automatically? true +auth The Redis password +delete_after_ack If ``true``, messages are deleted false + automatically after processing them +serializer How to serialize the final payload ``Redis::SERIALIZER_PHP`` + in Redis (the + ``Redis::OPT_SERIALIZER`` option) +stream_max_entries The maximum number of entries which ``0`` (which means "no trimming") + the stream will be trimmed to. Set + it to a large enough number to + avoid losing pending messages +tls Enable TLS support for the connection false redeliver_timeout Timeout before retrying a pending ``3600`` message which is owned by an abandoned consumer (if a worker died From 792968b78e2257368c6fb1dc3346d931a85c95fb Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 22 Oct 2020 13:02:02 +0200 Subject: [PATCH 0068/5766] Add the new doc build system --- .gitignore | 3 + _build/build.php | 44 + _build/composer.json | 21 + _build/composer.lock | 2197 ++++++++++++++++++++++++++++++++++++++++++ docs.json | 3 + 5 files changed, 2268 insertions(+) create mode 100755 _build/build.php create mode 100644 _build/composer.json create mode 100644 _build/composer.lock create mode 100644 docs.json diff --git a/.gitignore b/.gitignore index 6a20088680a..1d25940e5c8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,7 @@ /_build/doctrees /_build/spelling /_build/html +/_build/logs.txt +/_build/vendor +/_build/output *.pyc diff --git a/_build/build.php b/_build/build.php new file mode 100755 index 00000000000..5a2fd660bda --- /dev/null +++ b/_build/build.php @@ -0,0 +1,44 @@ +#!/usr/bin/env php +register('build-docs') + ->addOption('generate-fjson-files', null, InputOption::VALUE_NONE, 'Use this option to generate docs both in HTML and JSON formats') + ->addOption('disable-cache', null, InputOption::VALUE_NONE, 'Use this option to force a full regeneration of all doc contents') + ->setCode(function(InputInterface $input, OutputInterface $output) { + $command = [ + 'php', + 'vendor/symfony/docs-builder/bin/console', + 'build:docs', + sprintf('--save-errors=%s', __DIR__.'/logs.txt'), + __DIR__.'/../', + __DIR__.'/output/', + ]; + + if ($input->getOption('generate-fjson-files')) { + $command[] = '--output-json'; + } + + if ($input->getOption('disable-cache')) { + $command[] = '--disable-cache'; + } + + $process = new Process($command); + $process->setTimeout(3600); + $process->run(); + + if (!$process->isSuccessful()) { + throw new ProcessFailedException($process); + } + }) + ->getApplication() + ->setDefaultCommand('build-docs', true) + ->run(); diff --git a/_build/composer.json b/_build/composer.json new file mode 100644 index 00000000000..30de6365ecb --- /dev/null +++ b/_build/composer.json @@ -0,0 +1,21 @@ +{ + "minimum-stability": "dev", + "repositories": [ + { "type": "git", "url": "https://github.com/weaverryan/docs-builder" } + ], + "config": { + "platform": { + "php": "7.2.9" + }, + "preferred-install": { + "*": "dist" + }, + "sort-packages": true + }, + "require": { + "php": ">=7.2.9", + "symfony/console": "^4.1", + "symfony/docs-builder": "dev-master", + "symfony/process": "9999999-dev" + } +} diff --git a/_build/composer.lock b/_build/composer.lock new file mode 100644 index 00000000000..101c85b4165 --- /dev/null +++ b/_build/composer.lock @@ -0,0 +1,2197 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "6ee53de4a5225f7f273333a94e84fdd1", + "packages": [ + { + "name": "doctrine/event-manager", + "version": "1.1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "348f72ec92c7e0b1f5462f6616af2b448ba3cbb1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/348f72ec92c7e0b1f5462f6616af2b448ba3cbb1", + "reference": "348f72ec92c7e0b1f5462f6616af2b448ba3cbb1", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpunit/phpunit": "^7.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + }, + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com" + } + ], + "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/event-manager.html", + "keywords": [ + "event", + "event dispatcher", + "event manager", + "event system", + "events" + ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager", + "type": "tidelift" + } + ], + "time": "2020-10-05T12:08:55+00:00" + }, + { + "name": "doctrine/rst-parser", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/doctrine/rst-parser.git", + "reference": "1873475b3791954f1ca1539d4063cfcbd1c9e351" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/1873475b3791954f1ca1539d4063cfcbd1c9e351", + "reference": "1873475b3791954f1ca1539d4063cfcbd1c9e351", + "shasum": "" + }, + "require": { + "doctrine/event-manager": "^1.0", + "php": "^7.1", + "symfony/filesystem": "^4.1|^5.0", + "twig/twig": "^2.9.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "gajus/dindent": "^2.0.2", + "phpstan/phpstan": "^0.10", + "phpstan/phpstan-deprecation-rules": "^0.10", + "phpstan/phpstan-phpunit": "^0.10", + "phpstan/phpstan-strict-rules": "^0.10", + "phpunit/phpunit": "^7.0" + }, + "default-branch": true, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\RST\\": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Grégoire Passault", + "email": "g.passault@gmail.com", + "homepage": "http://www.gregwar.com/" + }, + { + "name": "Jonathan H. Wage", + "email": "jonwage@gmail.com", + "homepage": "https://jwage.com" + } + ], + "description": "PHP library to parse reStructuredText documents and generate HTML or LaTeX documents.", + "homepage": "https://github.com/doctrine/rst-parser", + "keywords": [ + "html", + "latex", + "markup", + "parser", + "reStructuredText", + "rst" + ], + "support": { + "issues": "https://github.com/doctrine/rst-parser/issues", + "source": "https://github.com/doctrine/rst-parser/tree/master" + }, + "time": "2020-10-23T00:13:24+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "6.5.x-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "e8ed4dbf49b260ff129ff0e0400718c3269971bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/e8ed4dbf49b260ff129ff0e0400718c3269971bf", + "reference": "e8ed4dbf49b260ff129ff0e0400718c3269971bf", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.6.1", + "php": ">=5.5", + "symfony/polyfill-intl-idn": "^1.17.0" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.1" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/6.5" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://github.com/alexeyshockov", + "type": "github" + }, + { + "url": "https://github.com/gmponos", + "type": "github" + }, + { + "url": "https://github.com/sagikazarmark", + "type": "github" + } + ], + "time": "2020-07-02T06:52:04+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "ddfeedfff2a52661429437da0702979f708e6ac6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/ddfeedfff2a52661429437da0702979f708e6ac6", + "reference": "ddfeedfff2a52661429437da0702979f708e6ac6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/master" + }, + "time": "2020-10-19T16:50:15+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "1.x-dev", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "25f7f893f0b52b7b14e244a16679d72b1f0088de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/25f7f893f0b52b7b14e244a16679d72b1f0088de", + "reference": "25f7f893f0b52b7b14e244a16679d72b1f0088de", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5 || ^3.0.0" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "ext-zlib": "*", + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/1.x" + }, + "time": "2020-10-22T07:42:05+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.100", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", + "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", + "shasum": "" + }, + "require": { + "php": ">= 7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" + }, + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", + "keywords": [ + "csprng", + "polyfill", + "pseudorandom", + "random" + ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, + "time": "2020-10-15T08:29:30+00:00" + }, + { + "name": "psr/container", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "381524e8568e07f31d504a945b88556548c8c42e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/381524e8568e07f31d504a945b88556548c8c42e", + "reference": "381524e8568e07f31d504a945b88556548c8c42e", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/master" + }, + "time": "2020-10-13T07:07:53+00:00" + }, + { + "name": "psr/http-message", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", + "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2019-08-29T13:16:46+00:00" + }, + { + "name": "psr/log", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "dd738d0b4491f32725492cf345f6b501f5922fec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/dd738d0b4491f32725492cf345f6b501f5922fec", + "reference": "dd738d0b4491f32725492cf345f6b501f5922fec", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/master" + }, + "time": "2020-09-18T06:44:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "scrivo/highlight.php", + "version": "9.18.x-dev", + "source": { + "type": "git", + "url": "https://github.com/scrivo/highlight.php.git", + "reference": "006e334dbf8e0a30573174e2cb6e11682b224f15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/006e334dbf8e0a30573174e2cb6e11682b224f15", + "reference": "006e334dbf8e0a30573174e2cb6e11682b224f15", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "php": ">=5.4" + }, + "require-dev": { + "phpunit/phpunit": "^4.8|^5.7", + "sabberworm/php-css-parser": "^8.3", + "symfony/finder": "^2.8|^3.4", + "symfony/var-dumper": "^2.8|^3.4" + }, + "suggest": { + "ext-dom": "Needed to make use of the features in the utilities namespace" + }, + "type": "library", + "autoload": { + "psr-0": { + "Highlight\\": "", + "HighlightUtilities\\": "" + }, + "files": [ + "HighlightUtilities/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Geert Bergman", + "homepage": "http://www.scrivo.org/", + "role": "Project Author" + }, + { + "name": "Vladimir Jimenez", + "homepage": "https://allejo.io", + "role": "Maintainer" + }, + { + "name": "Martin Folkers", + "homepage": "https://twobrain.io", + "role": "Contributor" + } + ], + "description": "Server side syntax highlighter that supports 185 languages. It's a PHP port of highlight.js", + "keywords": [ + "code", + "highlight", + "highlight.js", + "highlight.php", + "syntax" + ], + "support": { + "issues": "https://github.com/scrivo/highlight.php/issues", + "source": "https://github.com/scrivo/highlight.php" + }, + "funding": [ + { + "url": "https://github.com/allejo", + "type": "github" + } + ], + "time": "2020-10-17T21:12:39+00:00" + }, + { + "name": "symfony/console", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "a30dd52eb2129e90e2e15bf107f91eab2219b52c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/a30dd52eb2129e90e2e15bf107f91eab2219b52c", + "reference": "a30dd52eb2129e90e2e15bf107f91eab2219b52c", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Console Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-13T13:20:53+00:00" + }, + { + "name": "symfony/css-selector", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "e529efc81e4b3f06932e6ac4e0dab9d536e6afd1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/e529efc81e4b3f06932e6ac4e0dab9d536e6afd1", + "reference": "e529efc81e4b3f06932e6ac4e0dab9d536e6afd1", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony CssSelector Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-13T13:20:53+00:00" + }, + { + "name": "symfony/docs-builder", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/weaverryan/docs-builder", + "reference": "5def2fef2e7c8acade040d74d55b9b96fb8ed262" + }, + "require": { + "doctrine/rst-parser": "dev-master", + "ext-curl": "*", + "ext-json": "*", + "guzzlehttp/guzzle": "~6.0", + "scrivo/highlight.php": "^9.12.0", + "symfony/console": "^4.1", + "symfony/css-selector": "^4.1", + "symfony/dom-crawler": "^4.1", + "symfony/filesystem": "^4.1", + "symfony/finder": "^4.1", + "symfony/http-client": "^4.3", + "twig/twig": "^2.7.3" + }, + "require-dev": { + "gajus/dindent": "^2.0", + "symfony/phpunit-bridge": "^4.1", + "symfony/process": "^4.2" + }, + "default-branch": true, + "type": "project", + "autoload": { + "psr-4": { + "SymfonyDocsBuilder\\": "src" + } + }, + "license": [ + "MIT" + ], + "description": "The build system for Symfony's documentation", + "time": "2020-10-23T00:22:44+00:00" + }, + { + "name": "symfony/dom-crawler", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/dom-crawler.git", + "reference": "0e6f7848438ec672ce9230f774d5272ec02e47dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/0e6f7848438ec672ce9230f774d5272ec02e47dc", + "reference": "0e6f7848438ec672ce9230f774d5272ec02e47dc", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "masterminds/html5": "<2.6" + }, + "require-dev": { + "masterminds/html5": "^2.6", + "symfony/css-selector": "^3.4|^4.0|^5.0" + }, + "suggest": { + "symfony/css-selector": "" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\DomCrawler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony DomCrawler Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-13T13:20:53+00:00" + }, + { + "name": "symfony/filesystem", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "0921fda04596119d1bcbe6a17cf9989fadd71095" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/0921fda04596119d1bcbe6a17cf9989fadd71095", + "reference": "0921fda04596119d1bcbe6a17cf9989fadd71095", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-ctype": "~1.8" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Filesystem Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-21T04:38:54+00:00" + }, + { + "name": "symfony/finder", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "591f0fa22eaf3ad819332ac3de1d4ea67cca5932" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/591f0fa22eaf3ad819332ac3de1d4ea67cca5932", + "reference": "591f0fa22eaf3ad819332ac3de1d4ea67cca5932", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-13T13:20:53+00:00" + }, + { + "name": "symfony/http-client", + "version": "4.4.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "64db2909fb9311545a118bc46ed620d110cd2e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/64db2909fb9311545a118bc46ed620d110cd2e25", + "reference": "64db2909fb9311545a118bc46ed620d110cd2e25", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/log": "^1.0", + "symfony/http-client-contracts": "^1.1.10|^2", + "symfony/polyfill-php73": "^1.11", + "symfony/service-contracts": "^1.0|^2" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "1.1" + }, + "require-dev": { + "guzzlehttp/promises": "^1.3.1", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/dependency-injection": "^4.3|^5.0", + "symfony/http-kernel": "^4.4.13", + "symfony/process": "^4.2|^5.0" + }, + "type": "library", + "extra": { + "branch-version": "4.4" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpClient component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-client/tree/4.4" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-20T13:38:40+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "41db680a15018f9c1d4b23516059633ce280ca33" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41db680a15018f9c1d4b23516059633ce280ca33", + "reference": "41db680a15018f9c1d4b23516059633ce280ca33", + "shasum": "" + }, + "require": { + "php": ">=7.2.5" + }, + "suggest": { + "symfony/http-client-implementation": "" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-version": "2.3", + "branch-alias": { + "dev-main": "2.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-14T17:08:19+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", + "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "fd17ae0603e76ae99d041f567e8611a97d899b03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/fd17ae0603e76ae99d041f567e8611a97d899b03", + "reference": "fd17ae0603e76ae99d041f567e8611a97d899b03", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php70": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/main" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:34:17+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8db0ae7936b42feb370840cf24de1a144fb0ef27", + "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b5f7b932ee6fa802fc792eabd77c4c88084517ce", + "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-php70", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php70.git", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e", + "shasum": "" + }, + "require": { + "paragonie/random_compat": "~1.0|~2.0|~9.99", + "php": ">=5.3.3" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php70\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php70/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "beecef6b463b06954638f02378f52496cb84bacc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/beecef6b463b06954638f02378f52496cb84bacc", + "reference": "beecef6b463b06954638f02378f52496cb84bacc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "9d920e3218205554171b2503bb3e4a1366824a16" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9d920e3218205554171b2503bb3e4a1366824a16", + "reference": "9d920e3218205554171b2503bb3e4a1366824a16", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "f54ef00f4678f348f133097fa8c3701d197ff44d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/f54ef00f4678f348f133097fa8c3701d197ff44d", + "reference": "f54ef00f4678f348f133097fa8c3701d197ff44d", + "shasum": "" + }, + "require": { + "php": ">=7.0.8" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.19-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.19.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T09:01:57+00:00" + }, + { + "name": "symfony/process", + "version": "5.x-dev", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "f3957bcc7ec492baf22812c48e7cccf152491770" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/f3957bcc7ec492baf22812c48e7cccf152491770", + "reference": "f3957bcc7ec492baf22812c48e7cccf152491770", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-version": "5.2" + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Process Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.2.0-BETA2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-13T13:22:54+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "dev-main", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "0aeee2f70f4550e6c48c9a796d98f5ceda58dfda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/0aeee2f70f4550e6c48c9a796d98f5ceda58dfda", + "reference": "0aeee2f70f4550e6c48c9a796d98f5ceda58dfda", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "default-branch": true, + "type": "library", + "extra": { + "branch-version": "2.3", + "branch-alias": { + "dev-main": "2.3-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/main" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-14T17:08:19+00:00" + }, + { + "name": "twig/twig", + "version": "2.x-dev", + "source": { + "type": "git", + "url": "https://github.com/twigphp/Twig.git", + "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/78173b3c850e344cb8515fc2a05138d39a6c39e0", + "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-mbstring": "^1.3" + }, + "require-dev": { + "psr/container": "^1.0", + "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.14-dev" + } + }, + "autoload": { + "psr-0": { + "Twig_": "lib/" + }, + "psr-4": { + "Twig\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com", + "homepage": "http://fabien.potencier.org", + "role": "Lead Developer" + }, + { + "name": "Twig Team", + "role": "Contributors" + }, + { + "name": "Armin Ronacher", + "email": "armin.ronacher@active-4.com", + "role": "Project Founder" + } + ], + "description": "Twig, the flexible, fast, and secure template language for PHP", + "homepage": "https://twig.symfony.com", + "keywords": [ + "templating" + ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/2.x" + }, + "funding": [ + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/twig/twig", + "type": "tidelift" + } + ], + "time": "2020-10-21T12:45:52+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "symfony/docs-builder": 20, + "symfony/process": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=7.2.9" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.2.9" + }, + "plugin-api-version": "2.0.0" +} diff --git a/docs.json b/docs.json new file mode 100644 index 00000000000..70c1a299f0e --- /dev/null +++ b/docs.json @@ -0,0 +1,3 @@ +{ + "exclude": ["_build"] +} From b152b91d6d58cc71e0cc11f822ad26a9c69bfe8d Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 25 Oct 2020 13:56:48 +0100 Subject: [PATCH 0069/5766] Added Github actions integration --- .github/workflows/ci.yaml | 38 +++ _build/build.php | 3 +- _build/composer.json | 1 + _build/composer.lock | 528 +++++++++++++------------------------- 4 files changed, 225 insertions(+), 345 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 26f0e537118..dd7599889d0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -43,6 +43,44 @@ jobs: - name: "Build documentation" run: make -C _build SPHINXOPTS="-nqW -j auto" html + build-php: + name: Symfony doc builder + + runs-on: ubuntu-latest + + continue-on-error: true + + steps: + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Set-up PHP" + uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + coverage: none + tools: "composer:v2" + + - name: Get composer cache directory + id: composercache + working-directory: _build + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: "Install dependencies" + working-directory: _build + run: composer install --prefer-dist --no-progress + + - name: "Build the docs" + working-directory: _build + run: php build.php -vvv + doctor-rst: name: DOCtor-RST diff --git a/_build/build.php b/_build/build.php index 5a2fd660bda..9dba64d5145 100755 --- a/_build/build.php +++ b/_build/build.php @@ -33,7 +33,8 @@ $process = new Process($command); $process->setTimeout(3600); - $process->run(); + + $this->getHelper('process')->run($output, $process); if (!$process->isSuccessful()) { throw new ProcessFailedException($process); diff --git a/_build/composer.json b/_build/composer.json index 30de6365ecb..ea0ef4eee25 100644 --- a/_build/composer.json +++ b/_build/composer.json @@ -1,5 +1,6 @@ { "minimum-stability": "dev", + "prefer-stable": true, "repositories": [ { "type": "git", "url": "https://github.com/weaverryan/docs-builder" } ], diff --git a/_build/composer.lock b/_build/composer.lock index 101c85b4165..8a5ab63dcb7 100644 --- a/_build/composer.lock +++ b/_build/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6ee53de4a5225f7f273333a94e84fdd1", + "content-hash": "e580f6d54e3fe0b71ca6103550882138", "packages": [ { "name": "doctrine/event-manager", - "version": "1.1.x-dev", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "348f72ec92c7e0b1f5462f6616af2b448ba3cbb1" + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/348f72ec92c7e0b1f5462f6616af2b448ba3cbb1", - "reference": "348f72ec92c7e0b1f5462f6616af2b448ba3cbb1", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", "shasum": "" }, "require": { @@ -30,7 +30,6 @@ "doctrine/coding-standard": "^6.0", "phpunit/phpunit": "^7.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -99,7 +98,7 @@ "type": "tidelift" } ], - "time": "2020-10-05T12:08:55+00:00" + "time": "2020-05-29T18:28:51+00:00" }, { "name": "doctrine/rst-parser", @@ -107,12 +106,12 @@ "source": { "type": "git", "url": "https://github.com/doctrine/rst-parser.git", - "reference": "1873475b3791954f1ca1539d4063cfcbd1c9e351" + "reference": "68419cbf92d60177b95e44d79a79cae1098a91ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/1873475b3791954f1ca1539d4063cfcbd1c9e351", - "reference": "1873475b3791954f1ca1539d4063cfcbd1c9e351", + "url": "https://api.github.com/repos/doctrine/rst-parser/zipball/68419cbf92d60177b95e44d79a79cae1098a91ef", + "reference": "68419cbf92d60177b95e44d79a79cae1098a91ef", "shasum": "" }, "require": { @@ -167,20 +166,20 @@ "issues": "https://github.com/doctrine/rst-parser/issues", "source": "https://github.com/doctrine/rst-parser/tree/master" }, - "time": "2020-10-23T00:13:24+00:00" + "time": "2020-10-26T13:37:24+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "6.5.x-dev", + "version": "6.5.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "e8ed4dbf49b260ff129ff0e0400718c3269971bf" + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/e8ed4dbf49b260ff129ff0e0400718c3269971bf", - "reference": "e8ed4dbf49b260ff129ff0e0400718c3269971bf", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "shasum": "" }, "require": { @@ -238,42 +237,20 @@ "issues": "https://github.com/guzzle/guzzle/issues", "source": "https://github.com/guzzle/guzzle/tree/6.5" }, - "funding": [ - { - "url": "https://github.com/GrahamCampbell", - "type": "github" - }, - { - "url": "https://github.com/Nyholm", - "type": "github" - }, - { - "url": "https://github.com/alexeyshockov", - "type": "github" - }, - { - "url": "https://github.com/gmponos", - "type": "github" - }, - { - "url": "https://github.com/sagikazarmark", - "type": "github" - } - ], - "time": "2020-07-02T06:52:04+00:00" + "time": "2020-06-16T21:01:06+00:00" }, { "name": "guzzlehttp/promises", - "version": "dev-master", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "ddfeedfff2a52661429437da0702979f708e6ac6" + "reference": "60d379c243457e073cff02bc323a2a86cb355631" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/ddfeedfff2a52661429437da0702979f708e6ac6", - "reference": "ddfeedfff2a52661429437da0702979f708e6ac6", + "url": "https://api.github.com/repos/guzzle/promises/zipball/60d379c243457e073cff02bc323a2a86cb355631", + "reference": "60d379c243457e073cff02bc323a2a86cb355631", "shasum": "" }, "require": { @@ -282,7 +259,6 @@ "require-dev": { "symfony/phpunit-bridge": "^4.4 || ^5.1" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -314,22 +290,22 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/master" + "source": "https://github.com/guzzle/promises/tree/1.4.0" }, - "time": "2020-10-19T16:50:15+00:00" + "time": "2020-09-30T07:37:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "1.x-dev", + "version": "1.7.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "25f7f893f0b52b7b14e244a16679d72b1f0088de" + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/25f7f893f0b52b7b14e244a16679d72b1f0088de", - "reference": "25f7f893f0b52b7b14e244a16679d72b1f0088de", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/53330f47520498c0ae1f61f7e2c90f55690c06a3", + "reference": "53330f47520498c0ae1f61f7e2c90f55690c06a3", "shasum": "" }, "require": { @@ -389,82 +365,31 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/1.x" + "source": "https://github.com/guzzle/psr7/tree/1.7.0" }, - "time": "2020-10-22T07:42:05+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "time": "2020-10-15T08:29:30+00:00" + "time": "2020-09-30T07:37:11+00:00" }, { "name": "psr/container", - "version": "dev-master", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "381524e8568e07f31d504a945b88556548c8c42e" + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/381524e8568e07f31d504a945b88556548c8c42e", - "reference": "381524e8568e07f31d504a945b88556548c8c42e", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=5.3.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -479,7 +404,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -495,26 +420,25 @@ "issues": "https://github.com/php-fig/container/issues", "source": "https://github.com/php-fig/container/tree/master" }, - "time": "2020-10-13T07:07:53+00:00" + "time": "2017-02-14T16:28:37+00:00" }, { "name": "psr/http-message", - "version": "dev-master", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4" + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", - "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -549,26 +473,25 @@ "support": { "source": "https://github.com/php-fig/http-message/tree/master" }, - "time": "2019-08-29T13:16:46+00:00" + "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "dev-master", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "dd738d0b4491f32725492cf345f6b501f5922fec" + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/dd738d0b4491f32725492cf345f6b501f5922fec", - "reference": "dd738d0b4491f32725492cf345f6b501f5922fec", + "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", + "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", "shasum": "" }, "require": { "php": ">=5.3.0" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -587,7 +510,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -598,9 +521,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/master" + "source": "https://github.com/php-fig/log/tree/1.1.3" }, - "time": "2020-09-18T06:44:51+00:00" + "time": "2020-03-23T09:12:05+00:00" }, { "name": "ralouphie/getallheaders", @@ -648,16 +571,16 @@ }, { "name": "scrivo/highlight.php", - "version": "9.18.x-dev", + "version": "v9.18.1.3", "source": { "type": "git", "url": "https://github.com/scrivo/highlight.php.git", - "reference": "006e334dbf8e0a30573174e2cb6e11682b224f15" + "reference": "6a1699707b099081f20a488ac1f92d682181018c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/006e334dbf8e0a30573174e2cb6e11682b224f15", - "reference": "006e334dbf8e0a30573174e2cb6e11682b224f15", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/6a1699707b099081f20a488ac1f92d682181018c", + "reference": "6a1699707b099081f20a488ac1f92d682181018c", "shasum": "" }, "require": { @@ -723,20 +646,20 @@ "type": "github" } ], - "time": "2020-10-17T21:12:39+00:00" + "time": "2020-10-16T07:43:22+00:00" }, { "name": "symfony/console", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a30dd52eb2129e90e2e15bf107f91eab2219b52c" + "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a30dd52eb2129e90e2e15bf107f91eab2219b52c", - "reference": "a30dd52eb2129e90e2e15bf107f91eab2219b52c", + "url": "https://api.github.com/repos/symfony/console/zipball/90933b39c7b312fc3ceaa1ddeac7eb48cb953124", + "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124", "shasum": "" }, "require": { @@ -772,7 +695,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -799,7 +724,7 @@ "description": "Symfony Console Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/4.4" + "source": "https://github.com/symfony/console/tree/v4.4.15" }, "funding": [ { @@ -815,20 +740,20 @@ "type": "tidelift" } ], - "time": "2020-10-13T13:20:53+00:00" + "time": "2020-09-15T07:58:55+00:00" }, { "name": "symfony/css-selector", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "e529efc81e4b3f06932e6ac4e0dab9d536e6afd1" + "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/e529efc81e4b3f06932e6ac4e0dab9d536e6afd1", - "reference": "e529efc81e4b3f06932e6ac4e0dab9d536e6afd1", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/bf17dc9f6ce144e41f786c32435feea4d8e11dcc", + "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc", "shasum": "" }, "require": { @@ -836,7 +761,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -867,7 +794,7 @@ "description": "Symfony CssSelector Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/4.4" + "source": "https://github.com/symfony/css-selector/tree/v4.4.15" }, "funding": [ { @@ -883,7 +810,7 @@ "type": "tidelift" } ], - "time": "2020-10-13T13:20:53+00:00" + "time": "2020-07-05T09:39:30+00:00" }, { "name": "symfony/docs-builder", @@ -891,7 +818,7 @@ "source": { "type": "git", "url": "https://github.com/weaverryan/docs-builder", - "reference": "5def2fef2e7c8acade040d74d55b9b96fb8ed262" + "reference": "e388a6f8cd7a98c34cdc913d18adc9e92ef73441" }, "require": { "doctrine/rst-parser": "dev-master", @@ -923,20 +850,20 @@ "MIT" ], "description": "The build system for Symfony's documentation", - "time": "2020-10-23T00:22:44+00:00" + "time": "2020-10-26T22:58:16+00:00" }, { "name": "symfony/dom-crawler", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "0e6f7848438ec672ce9230f774d5272ec02e47dc" + "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/0e6f7848438ec672ce9230f774d5272ec02e47dc", - "reference": "0e6f7848438ec672ce9230f774d5272ec02e47dc", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bdcb7633a501770a0daefbf81d2e6b28c3864f2b", + "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b", "shasum": "" }, "require": { @@ -956,7 +883,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -983,7 +912,7 @@ "description": "Symfony DomCrawler Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/4.4" + "source": "https://github.com/symfony/dom-crawler/tree/v4.4.15" }, "funding": [ { @@ -999,20 +928,20 @@ "type": "tidelift" } ], - "time": "2020-10-13T13:20:53+00:00" + "time": "2020-10-02T07:34:48+00:00" }, { "name": "symfony/filesystem", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "0921fda04596119d1bcbe6a17cf9989fadd71095" + "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/0921fda04596119d1bcbe6a17cf9989fadd71095", - "reference": "0921fda04596119d1bcbe6a17cf9989fadd71095", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/ebc51494739d3b081ea543ed7c462fa73a4f74db", + "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db", "shasum": "" }, "require": { @@ -1021,7 +950,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -1048,7 +979,7 @@ "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/4.4" + "source": "https://github.com/symfony/filesystem/tree/v4.4.15" }, "funding": [ { @@ -1064,20 +995,20 @@ "type": "tidelift" } ], - "time": "2020-10-21T04:38:54+00:00" + "time": "2020-09-27T13:54:16+00:00" }, { "name": "symfony/finder", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "591f0fa22eaf3ad819332ac3de1d4ea67cca5932" + "reference": "60d08560f9aa72997c44077c40d47aa28a963230" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/591f0fa22eaf3ad819332ac3de1d4ea67cca5932", - "reference": "591f0fa22eaf3ad819332ac3de1d4ea67cca5932", + "url": "https://api.github.com/repos/symfony/finder/zipball/60d08560f9aa72997c44077c40d47aa28a963230", + "reference": "60d08560f9aa72997c44077c40d47aa28a963230", "shasum": "" }, "require": { @@ -1085,7 +1016,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -1112,7 +1045,7 @@ "description": "Symfony Finder Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/4.4" + "source": "https://github.com/symfony/finder/tree/v4.4.15" }, "funding": [ { @@ -1128,20 +1061,20 @@ "type": "tidelift" } ], - "time": "2020-10-13T13:20:53+00:00" + "time": "2020-10-02T07:34:48+00:00" }, { "name": "symfony/http-client", - "version": "4.4.x-dev", + "version": "v4.4.15", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "64db2909fb9311545a118bc46ed620d110cd2e25" + "reference": "b1cb966898aaf8df37280fde537a27b6724b3bc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/64db2909fb9311545a118bc46ed620d110cd2e25", - "reference": "64db2909fb9311545a118bc46ed620d110cd2e25", + "url": "https://api.github.com/repos/symfony/http-client/zipball/b1cb966898aaf8df37280fde537a27b6724b3bc4", + "reference": "b1cb966898aaf8df37280fde537a27b6724b3bc4", "shasum": "" }, "require": { @@ -1168,7 +1101,9 @@ }, "type": "library", "extra": { - "branch-version": "4.4" + "branch-alias": { + "dev-master": "4.4-dev" + } }, "autoload": { "psr-4": { @@ -1195,7 +1130,7 @@ "description": "Symfony HttpClient component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/4.4" + "source": "https://github.com/symfony/http-client/tree/v4.4.15" }, "funding": [ { @@ -1211,11 +1146,11 @@ "type": "tidelift" } ], - "time": "2020-10-20T13:38:40+00:00" + "time": "2020-10-02T13:41:48+00:00" }, { "name": "symfony/http-client-contracts", - "version": "dev-main", + "version": "v2.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", @@ -1233,7 +1168,6 @@ "suggest": { "symfony/http-client-implementation": "" }, - "default-branch": true, "type": "library", "extra": { "branch-version": "2.3", @@ -1295,29 +1229,28 @@ }, { "name": "symfony/polyfill-ctype", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-ctype": "For best performance" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1355,7 +1288,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" }, "funding": [ { @@ -1371,36 +1304,34 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "fd17ae0603e76ae99d041f567e8611a97d899b03" + "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/fd17ae0603e76ae99d041f567e8611a97d899b03", - "reference": "fd17ae0603e76ae99d041f567e8611a97d899b03", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117", + "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=7.1", "symfony/polyfill-intl-normalizer": "^1.10", - "symfony/polyfill-php70": "^1.10", "symfony/polyfill-php72": "^1.10" }, "suggest": { "ext-intl": "For best performance" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1444,7 +1375,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/main" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.20.0" }, "funding": [ { @@ -1460,33 +1391,32 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:34:17+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27" + "reference": "727d1096295d807c309fb01a851577302394c897" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8db0ae7936b42feb370840cf24de1a144fb0ef27", - "reference": "8db0ae7936b42feb370840cf24de1a144fb0ef27", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", + "reference": "727d1096295d807c309fb01a851577302394c897", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-intl": "For best performance" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1529,7 +1459,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0" }, "funding": [ { @@ -1545,33 +1475,32 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce" + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b5f7b932ee6fa802fc792eabd77c4c88084517ce", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, "suggest": { "ext-mbstring": "For best performance" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1610,7 +1539,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" }, "funding": [ { @@ -1626,111 +1555,29 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "dev-main", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/3fe414077251a81a1b15b1c709faf5c2fbae3d4e", - "reference": "3fe414077251a81a1b15b1c709faf5c2fbae3d4e", - "shasum": "" - }, - "require": { - "paragonie/random_compat": "~1.0|~2.0|~9.99", - "php": ">=5.3.3" - }, - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.19-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php70\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php70/tree/v1.19.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php72", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "beecef6b463b06954638f02378f52496cb84bacc" + "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/beecef6b463b06954638f02378f52496cb84bacc", - "reference": "beecef6b463b06954638f02378f52496cb84bacc", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", + "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1768,7 +1615,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0" }, "funding": [ { @@ -1784,30 +1631,29 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php73", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "9d920e3218205554171b2503bb3e4a1366824a16" + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9d920e3218205554171b2503bb3e4a1366824a16", - "reference": "9d920e3218205554171b2503bb3e4a1366824a16", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.1" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1848,7 +1694,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0" }, "funding": [ { @@ -1864,30 +1710,29 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/polyfill-php80", - "version": "dev-main", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "f54ef00f4678f348f133097fa8c3701d197ff44d" + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/f54ef00f4678f348f133097fa8c3701d197ff44d", - "reference": "f54ef00f4678f348f133097fa8c3701d197ff44d", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", "shasum": "" }, "require": { - "php": ">=7.0.8" + "php": ">=7.1" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" + "dev-main": "1.20-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1932,7 +1777,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0" }, "funding": [ { @@ -1948,7 +1793,7 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2020-10-23T14:02:19+00:00" }, { "name": "symfony/process", @@ -1956,12 +1801,12 @@ "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "f3957bcc7ec492baf22812c48e7cccf152491770" + "reference": "88d47196a2fe06db8f90f0c2a986651e91ee3660" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/f3957bcc7ec492baf22812c48e7cccf152491770", - "reference": "f3957bcc7ec492baf22812c48e7cccf152491770", + "url": "https://api.github.com/repos/symfony/process/zipball/88d47196a2fe06db8f90f0c2a986651e91ee3660", + "reference": "88d47196a2fe06db8f90f0c2a986651e91ee3660", "shasum": "" }, "require": { @@ -1970,9 +1815,6 @@ }, "default-branch": true, "type": "library", - "extra": { - "branch-version": "5.2" - }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" @@ -1998,7 +1840,7 @@ "description": "Symfony Process Component", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.2.0-BETA2" + "source": "https://github.com/symfony/process/tree/5.x" }, "funding": [ { @@ -2014,20 +1856,20 @@ "type": "tidelift" } ], - "time": "2020-10-13T13:22:54+00:00" + "time": "2020-10-24T12:08:07+00:00" }, { "name": "symfony/service-contracts", - "version": "dev-main", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "0aeee2f70f4550e6c48c9a796d98f5ceda58dfda" + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/0aeee2f70f4550e6c48c9a796d98f5ceda58dfda", - "reference": "0aeee2f70f4550e6c48c9a796d98f5ceda58dfda", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", "shasum": "" }, "require": { @@ -2037,12 +1879,10 @@ "suggest": { "symfony/service-implementation": "" }, - "default-branch": true, "type": "library", "extra": { - "branch-version": "2.3", "branch-alias": { - "dev-main": "2.3-dev" + "dev-master": "2.2-dev" }, "thanks": { "name": "symfony/contracts", @@ -2079,7 +1919,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/main" + "source": "https://github.com/symfony/service-contracts/tree/master" }, "funding": [ { @@ -2095,20 +1935,20 @@ "type": "tidelift" } ], - "time": "2020-10-14T17:08:19+00:00" + "time": "2020-09-07T11:33:47+00:00" }, { "name": "twig/twig", - "version": "2.x-dev", + "version": "v2.14.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0" + "reference": "d495243dade48c39b6a5261c26cdbd8c5703f6a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/78173b3c850e344cb8515fc2a05138d39a6c39e0", - "reference": "78173b3c850e344cb8515fc2a05138d39a6c39e0", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d495243dade48c39b6a5261c26cdbd8c5703f6a0", + "reference": "d495243dade48c39b6a5261c26cdbd8c5703f6a0", "shasum": "" }, "require": { @@ -2162,7 +2002,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/2.x" + "source": "https://github.com/twigphp/Twig/tree/v2.14.0" }, "funding": [ { @@ -2174,7 +2014,7 @@ "type": "tidelift" } ], - "time": "2020-10-21T12:45:52+00:00" + "time": "2020-10-21T12:35:06+00:00" } ], "packages-dev": [], @@ -2184,7 +2024,7 @@ "symfony/docs-builder": 20, "symfony/process": 20 }, - "prefer-stable": false, + "prefer-stable": true, "prefer-lowest": false, "platform": { "php": ">=7.2.9" From 3eeb845cd5269fec8fb338043300396e15e47a13 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 26 Oct 2020 16:43:31 +0100 Subject: [PATCH 0070/5766] Use PHP docs builder for SymfonyCloud deploys --- .symfony.cloud.yaml | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/.symfony.cloud.yaml b/.symfony.cloud.yaml index faa3c24780e..bcb1a48bf08 100644 --- a/.symfony.cloud.yaml +++ b/.symfony.cloud.yaml @@ -5,12 +5,12 @@ name: symfonydocs # The toolstack used to build the application. -type: "python:3.7" +type: "php:7.2" # The configuration of app when it is exposed to the web. web: # The public directory of the app, relative to its root. - document_root: "/_build/html" + document_root: "/_build/output" index_files: - index.html whitelist: @@ -40,19 +40,9 @@ web: # The size of the persistent disk of the application (in MB). disk: 512 -# Build time dependencies. -dependencies: - python: - virtualenv: 15.1.0 - # The hooks that will be performed when the package is deployed. hooks: build: | - virtualenv .virtualenv - . .virtualenv/bin/activate - # SymfonyCloud currently sets PIP_USER=1. - export PIP_USER= - pip install pip==9.0.1 wheel==0.29.0 - pip install -r _build/.requirements.txt - find .virtualenv -type f -name "*.rst" -delete - make -C _build html + cd _build + composer install --prefer-dist --no-progress + php build.php From 09be97abda04f5b6a865baa0ecefd1029e2d067d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20Eugon=C3=A9?= Date: Mon, 26 Oct 2020 10:34:08 +0100 Subject: [PATCH 0071/5766] [DependencyInjection] Fix tagged service priority inconsistent method name --- service_container/tags.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/service_container/tags.rst b/service_container/tags.rst index 7aee0061c0c..7ec5fcc5637 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -655,8 +655,9 @@ service itself:: } } -If you want to have another method defining the priority, you can define it -in the configuration of the collecting service: +If you want to have another method defining the priority +(e.g. ``getPriority()`` rather than ``getDefaultPriority()``), +you can define it in the configuration of the collecting service: .. configuration-block:: From 0d182b33c00c00977d8cd468a068ca463c71bc9d Mon Sep 17 00:00:00 2001 From: Med Ghaith Sellami Date: Tue, 27 Oct 2020 20:35:28 +0100 Subject: [PATCH 0072/5766] update PHP callable docs link --- components/event_dispatcher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/event_dispatcher.rst b/components/event_dispatcher.rst index e89441e6a08..0344acf4e8e 100644 --- a/components/event_dispatcher.rst +++ b/components/event_dispatcher.rst @@ -532,4 +532,4 @@ Learn More .. _Mediator: https://en.wikipedia.org/wiki/Mediator_pattern .. _Observer: https://en.wikipedia.org/wiki/Observer_pattern .. _Closures: https://www.php.net/manual/en/functions.anonymous.php -.. _PHP callable: https://www.php.net/manual/en/language.pseudo-types.php#language.types.callback +.. _PHP callable: https://www.php.net/manual/en/language.types.callable.php From 46ba35933a1480ac981c7a1ccf0d53534f544815 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 30 Oct 2020 08:58:52 +0100 Subject: [PATCH 0073/5766] Update to twig/cssinliner-extra --- components/mime.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/mime.rst b/components/mime.rst index ce884a51193..95206fa22e3 100644 --- a/components/mime.rst +++ b/components/mime.rst @@ -103,12 +103,12 @@ extension: .. code-block:: terminal - $ composer require twig/cssinliner-extension + $ composer require twig/cssinliner-extra Now, enable the extension:: // ... - use Twig\CssInliner\CssInlinerExtension; + use Twig\Extra\CssInliner\CssInlinerExtension; $loader = new FilesystemLoader(__DIR__.'/templates'); $twig = new Environment($loader); From 5a36f03d309624c8dd2d251d9db5a0c666e7c7df Mon Sep 17 00:00:00 2001 From: Wouter J Date: Fri, 30 Oct 2020 10:39:54 +0100 Subject: [PATCH 0074/5766] Fixed code block rendering --- components/process.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/process.rst b/components/process.rst index 8664ddead85..f89935036f1 100644 --- a/components/process.rst +++ b/components/process.rst @@ -394,7 +394,7 @@ Using a Prepared Command Line You can run a process by using a prepared command line with double quote variable notation. This allows you to use placeholders so that only the -parameterized values can be changed, but not the rest of the script: +parameterized values can be changed, but not the rest of the script:: use Symfony\Component\Process\Process; From d8658352e0cc152aa3ec1f5c9e006a3a1c54ca3f Mon Sep 17 00:00:00 2001 From: Quentin Dequippe Date: Thu, 29 Oct 2020 15:34:43 +0100 Subject: [PATCH 0075/5766] Update doctrine fetchAll deprecated --- doctrine.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine.rst b/doctrine.rst index eab24ae8f13..fb491df8c2b 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -812,7 +812,7 @@ In addition, you can query directly with SQL if you need to:: $stmt->execute(['price' => $price]); // returns an array of arrays (i.e. a raw data set) - return $stmt->fetchAll(); + return $stmt->fetchAllAssociative(); } With SQL, you will get back raw data, not objects (unless you use the `NativeQuery`_ From 64058aa3c6a3da18112ac9d92e638137490783c0 Mon Sep 17 00:00:00 2001 From: freezy Date: Wed, 28 Oct 2020 14:15:13 +0100 Subject: [PATCH 0076/5766] Mention supported hex colors --- console/coloring.rst | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/console/coloring.rst b/console/coloring.rst index 3684d71709d..913805b5cea 100644 --- a/console/coloring.rst +++ b/console/coloring.rst @@ -40,13 +40,22 @@ It is possible to define your own styles using the use Symfony\Component\Console\Formatter\OutputFormatterStyle; // ... - $outputStyle = new OutputFormatterStyle('red', 'yellow', ['bold', 'blink']); + $outputStyle = new OutputFormatterStyle('red', '#ff0', ['bold', 'blink']); $output->getFormatter()->setStyle('fire', $outputStyle); $output->writeln('foo'); -Available foreground and background colors are: ``black``, ``red``, ``green``, -``yellow``, ``blue``, ``magenta``, ``cyan`` and ``white``. +Any hex color is supported for foreground and background colors. Besides that, these named colors are supported: +``black``, ``red``, ``green``, ``yellow``, ``blue``, ``magenta``, ``cyan`` and ``white``. + +.. versionadded:: 5.2 + + True (hex) color support was introduced in Symfony 5.2 + +.. note:: + + If the terminal doesn't support true colors, the nearest named color is used. + E.g. ``#c0392b`` is degraded to ``red`` or ``#f1c40f`` is degraded to ``yellow``. And available options are: ``bold``, ``underscore``, ``blink``, ``reverse`` (enables the "reverse video" mode where the background and foreground colors @@ -59,6 +68,9 @@ You can also set these colors and options directly inside the tag name:: // green text $output->writeln('foo'); + // red text + $output->writeln('foo'); + // black text on a cyan background $output->writeln('foo'); From 24312cb7292bf9f3aceefbf7f8c4ec9c68ee7b02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=CC=81=20R?= Date: Wed, 28 Oct 2020 15:37:11 +0100 Subject: [PATCH 0077/5766] [Cache] Adds mention of using FileSystemTagAwareAdatpter --- components/cache/adapters/filesystem_adapter.rst | 13 +++++++++++++ components/cache/cache_invalidation.rst | 3 ++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst index 33097fbd202..3939d5f568f 100644 --- a/components/cache/adapters/filesystem_adapter.rst +++ b/components/cache/adapters/filesystem_adapter.rst @@ -55,5 +55,18 @@ and cache root path as constructor parameters:: :ref:`pruning of expired cache items ` by calling its ``prune()`` method. + +.. _filesystem-tag-aware-adapter: + +Working with Tags +----------------- + +In order to use tag-based invalidation, you can wrap your adapter in :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter`, but it's often more interesting to use the dedicated :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemTagAwareAdapter`. Since tag invalidation logic is implemented using links on filesystem, this adapter offers better read performance when using tag-based invalidation:: + + use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; + + $cache = new FilesystemTagAwareAdapter(); + + .. _`tmpfs`: https://wiki.archlinux.org/index.php/tmpfs .. _`RAM disk solutions`: https://en.wikipedia.org/wiki/List_of_RAM_drive_software diff --git a/components/cache/cache_invalidation.rst b/components/cache/cache_invalidation.rst index 22f5830cf3e..084cee4cb70 100644 --- a/components/cache/cache_invalidation.rst +++ b/components/cache/cache_invalidation.rst @@ -61,7 +61,8 @@ method. .. note:: When using a Redis backend, consider using :ref:`RedisTagAwareAdapter ` - which is optimized for this purpose. + which is optimized for this purpose. When using File system, likewise consider to use + :ref:`FilesystemTagAwareAdapter `. The :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` class implements instantaneous invalidation (time complexity is ``O(N)`` where ``N`` is the number From 34a16a8624c6ae61cda9b974ee2146f05ca36040 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 30 Oct 2020 13:47:57 +0100 Subject: [PATCH 0078/5766] Fix: Typo --- components/cache/cache_invalidation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cache/cache_invalidation.rst b/components/cache/cache_invalidation.rst index 084cee4cb70..bef2c29b0b7 100644 --- a/components/cache/cache_invalidation.rst +++ b/components/cache/cache_invalidation.rst @@ -61,7 +61,7 @@ method. .. note:: When using a Redis backend, consider using :ref:`RedisTagAwareAdapter ` - which is optimized for this purpose. When using File system, likewise consider to use + which is optimized for this purpose. When using filesystem, likewise consider to use :ref:`FilesystemTagAwareAdapter `. The :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` class implements From 5cd490de3d32acf820be5f3bbd18457ce631336e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 30 Oct 2020 13:48:58 +0100 Subject: [PATCH 0079/5766] Fix: Add line breaks --- components/cache/adapters/filesystem_adapter.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst index 3939d5f568f..c4db3a7fb76 100644 --- a/components/cache/adapters/filesystem_adapter.rst +++ b/components/cache/adapters/filesystem_adapter.rst @@ -61,7 +61,11 @@ and cache root path as constructor parameters:: Working with Tags ----------------- -In order to use tag-based invalidation, you can wrap your adapter in :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter`, but it's often more interesting to use the dedicated :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemTagAwareAdapter`. Since tag invalidation logic is implemented using links on filesystem, this adapter offers better read performance when using tag-based invalidation:: +In order to use tag-based invalidation, you can wrap your adapter in +:class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter`, but it's often +more interesting to use the dedicated :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemTagAwareAdapter`. +Since tag invalidation logic is implemented using links on filesystem, this +adapter offers better read performance when using tag-based invalidation:: use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; From ace5e3a8cc5b984b53a699a4e16e413dad084ccc Mon Sep 17 00:00:00 2001 From: Quentin Dequippe Date: Fri, 9 Oct 2020 10:31:46 +0200 Subject: [PATCH 0080/5766] Add warning on Docker integration --- setup/symfony_server.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index 70155de0637..a8374aaca4a 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -378,6 +378,16 @@ 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:: + + When using Symfony binary with ``php bin/console`` (``symfony console ...``) + the binay will **always** use environment variables detected via Docker and will + ignore local environment variables. + For example if you set up a different database name in your ``.env.test`` file + (``DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/test``) and if you run + ``symfony console doctrine:database:drop --force --env=test`` the command will drop the database + defined in your Docker configuration and not the "test" one. + SymfonyCloud Integration ------------------------ From 8d1614e2e2c4a3ec22b9ca91cb7ad48b8ec14f6e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 30 Oct 2020 14:01:09 +0100 Subject: [PATCH 0081/5766] Enhancement: Private member variables in code example --- create_framework/separation_of_concerns.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/create_framework/separation_of_concerns.rst b/create_framework/separation_of_concerns.rst index e1e46f3ebe3..24d34f0e82b 100644 --- a/create_framework/separation_of_concerns.rst +++ b/create_framework/separation_of_concerns.rst @@ -27,9 +27,9 @@ request handling logic into its own ``Simplex\Framework`` class:: class Framework { - protected $matcher; - protected $controllerResolver; - protected $argumentResolver; + private $matcher; + private $controllerResolver; + private $argumentResolver; public function __construct(UrlMatcher $matcher, ControllerResolver $controllerResolver, ArgumentResolver $argumentResolver) { From ae45622a92dfd8bd8b206a2c0f70e0310481d702 Mon Sep 17 00:00:00 2001 From: Ca-Jou Date: Wed, 28 Oct 2020 16:30:54 +0100 Subject: [PATCH 0082/5766] =?UTF-8?q?spotted=20minor=20EN=20mistakes=20and?= =?UTF-8?q?=20coherence=20issues=20between=20the=20different=20=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- create_framework/dependency_injection.rst | 2 +- create_framework/event_dispatcher.rst | 2 +- create_framework/front_controller.rst | 2 +- create_framework/http_foundation.rst | 4 ++-- create_framework/http_kernel_controller_resolver.rst | 2 +- create_framework/http_kernel_httpkernelinterface.rst | 7 ++++--- 6 files changed, 10 insertions(+), 9 deletions(-) diff --git a/create_framework/dependency_injection.rst b/create_framework/dependency_injection.rst index b38241e3ce2..cd20a947251 100644 --- a/create_framework/dependency_injection.rst +++ b/create_framework/dependency_injection.rst @@ -205,7 +205,7 @@ Now, here is how you can register a custom listener in the front controller:: ->addMethodCall('addSubscriber', [new Reference('listener.string_response')]) ; -Beside describing your objects, the dependency injection container can also be +Besides describing your objects, the dependency injection container can also be configured via parameters. Let's create one that defines if we are in debug mode or not:: diff --git a/create_framework/event_dispatcher.rst b/create_framework/event_dispatcher.rst index fd655a93ebf..bf872a5bb50 100644 --- a/create_framework/event_dispatcher.rst +++ b/create_framework/event_dispatcher.rst @@ -23,7 +23,7 @@ version of this pattern: How does it work? The *dispatcher*, the central object of the event dispatcher system, notifies *listeners* of an *event* dispatched to it. Put another way: your code dispatches an event to the dispatcher, the dispatcher notifies all -registered listeners for the event, and each listener do whatever it wants +registered listeners for the event, and each listener does whatever it wants with the event. As an example, let's create a listener that transparently adds the Google diff --git a/create_framework/front_controller.rst b/create_framework/front_controller.rst index 39286ba8c16..e6a7293fa6b 100644 --- a/create_framework/front_controller.rst +++ b/create_framework/front_controller.rst @@ -132,7 +132,7 @@ its sub-directories (only if needed -- see above tip). like ``$request = Request::create('/hello?name=Fabien');`` where the argument is the URL path you want to simulate. -Now that the web server always access the same script (``front.php``) for all +Now that the web server always accesses the same script (``front.php``) for all pages, we can secure the code further by moving all other PHP files outside the web root directory: diff --git a/create_framework/http_foundation.rst b/create_framework/http_foundation.rst index b56834319a8..99dff5c1faf 100644 --- a/create_framework/http_foundation.rst +++ b/create_framework/http_foundation.rst @@ -273,7 +273,7 @@ cases by yourself. Why not using a technology that already works? a look at the ``Symfony\Component\HttpFoundation`` API or read its dedicated :doc:`documentation `. -Believe or not but we have our first framework. You can stop now if you want. +Believe it or not but we have our first framework. You can stop now if you want. Using just the Symfony HttpFoundation component already allows you to write better and more testable code. It also allows you to write code faster as many day-to-day problems have already been solved for you. @@ -282,7 +282,7 @@ As a matter of fact, projects like Drupal have adopted the HttpFoundation component; if it works for them, it will probably work for you. Don't reinvent the wheel. -I've almost forgot to talk about one added benefit: using the HttpFoundation +I've almost forgotten to talk about one added benefit: using the HttpFoundation component is the start of better interoperability between all frameworks and `applications using it`_ (like `Symfony`_, `Drupal 8`_, `phpBB 3`_, `Laravel`_ and `ezPublish 5`_, and `more`_). diff --git a/create_framework/http_kernel_controller_resolver.rst b/create_framework/http_kernel_controller_resolver.rst index bac631073e6..12d9efead6e 100644 --- a/create_framework/http_kernel_controller_resolver.rst +++ b/create_framework/http_kernel_controller_resolver.rst @@ -31,7 +31,7 @@ The move is pretty straightforward and makes a lot of sense as soon as you create more pages but you might have noticed a non-desirable side effect... The ``LeapYearController`` class is *always* instantiated, even if the requested URL does not match the ``leap_year`` route. This is bad for one main -reason: performance wise, all controllers for all routes must now be +reason: performance-wise, all controllers for all routes must now be instantiated for every request. It would be better if controllers were lazy-loaded so that only the controller associated with the matched route is instantiated. diff --git a/create_framework/http_kernel_httpkernelinterface.rst b/create_framework/http_kernel_httpkernelinterface.rst index 9207ba342b0..9bda9e5c731 100644 --- a/create_framework/http_kernel_httpkernelinterface.rst +++ b/create_framework/http_kernel_httpkernelinterface.rst @@ -46,8 +46,8 @@ Update your framework so that it implements this interface:: } } -Even if this change looks not too complex, it brings us a lot! Let's talk about one of -the most impressive one: transparent :doc:`HTTP caching ` support. +With this change, a little goes a long way! Let's talk about one of +the most impressive upsides: transparent :doc:`HTTP caching ` support. The ``HttpCache`` class implements a fully-featured reverse proxy, written in PHP; it implements ``HttpKernelInterface`` and wraps another @@ -64,7 +64,8 @@ PHP; it implements ``HttpKernelInterface`` and wraps another new HttpKernel\HttpCache\Store(__DIR__.'/../cache') ); - $framework->handle($request)->send(); + $response = $framework->handle($request); + $response->send(); That's all it takes to add HTTP caching support to our framework. Isn't it amazing? From f746ec156d528b76e69872d31e2101232b56af5a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 30 Oct 2020 16:54:28 +0100 Subject: [PATCH 0083/5766] [Performance] Mention Symfony Stowatch in some doc sections --- performance.rst | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/performance.rst b/performance.rst index ec9d44e5610..65859141433 100644 --- a/performance.rst +++ b/performance.rst @@ -211,21 +211,24 @@ deployment process too): .. _profiling-applications: -Profiling Applications ----------------------- +Profiling Symfony Applications +------------------------------ + +Profiling with Blackfire +~~~~~~~~~~~~~~~~~~~~~~~~ `Blackfire`_ is the best tool to profile and optimize performance of Symfony applications during development, test and production. It's a commercial service, but provides free features that you can use to find bottlenecks in your projects. +Profilwing with Symfony Stopwatch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Symfony provides a basic performance profiler in the development :ref:`config environment `. Click on the "time panel" of the :ref:`web debug toolbar ` to see how much time Symfony spent on tasks such as making database queries and rendering templates. -Custom Profiling -~~~~~~~~~~~~~~~~ - You can measure the execution time and memory consumption of your own code and display the result in the Symfony profiler thanks to the `Stopwatch component`_. From 950f2552731f63827330b65abe4f2944d12a921f Mon Sep 17 00:00:00 2001 From: Zairig Imad Date: Tue, 9 Jun 2020 21:48:07 +0200 Subject: [PATCH 0084/5766] add _failure_path option to reference --- reference/configuration/security.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index 9c7f5da8755..399794e2402 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -528,6 +528,14 @@ target_path_parameter When using a login form, if you include an HTML element to set the target path, this option lets you change the name of the HTML element itself. +failure_path_parameter +...................... + +**type**: ``string`` **default**: ``_failure_path`` + +When using a login form, if you include an HTML element to set the failure path, +this option lets you change the name of the HTML element itself. + use_referer ........... From 53abe31aae73f39a68bd13d81c581b4389ab9a2c Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 31 Oct 2020 22:57:24 +0100 Subject: [PATCH 0085/5766] Use Symfony Flex and do not favor any CI tool --- bundles/best_practices.rst | 124 ++++++++++++++++--------------------- 1 file changed, 55 insertions(+), 69 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index e80050e2fce..010ba551832 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -171,73 +171,59 @@ Continuous Integration Testing bundle code continuously, including all its commits and pull requests, is a good practice called Continuous Integration. There are several services -providing this feature for free for open source projects. The most popular -service for Symfony bundles is called `Travis CI`_. - -Here is the recommended configuration file (``.travis.yml``) for Symfony bundles, -which test the two latest :doc:`LTS versions ` -of Symfony and the latest beta release: - -.. code-block:: yaml - - language: php - - cache: - directories: - - $HOME/.composer/cache/files - - $HOME/symfony-bridge/.phpunit - - env: - global: - - PHPUNIT_FLAGS="-v" - - SYMFONY_PHPUNIT_DIR="$HOME/symfony-bridge/.phpunit" - - matrix: - fast_finish: true - include: - # Minimum supported dependencies with the latest and oldest PHP version - - php: 7.2 - env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" SYMFONY_DEPRECATIONS_HELPER="max[self]=0" - - php: 7.1 - env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" SYMFONY_DEPRECATIONS_HELPER="max[self]=0" - - # Test the latest stable release - - php: 7.1 - - php: 7.2 - env: COVERAGE=true PHPUNIT_FLAGS="-v --coverage-text" - - # Test LTS versions. This makes sure we do not use Symfony packages with version greater - # than 2 or 3 respectively. Read more at https://github.com/symfony/lts - - php: 7.2 - env: DEPENDENCIES="symfony/lts:^2" - - php: 7.2 - env: DEPENDENCIES="symfony/lts:^3" - - # Latest commit to master - - php: 7.2 - env: STABILITY="dev" - - allow_failures: - # Dev-master is allowed to fail. - - env: STABILITY="dev" - - before_install: - - if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi - - if ! [ -z "$STABILITY" ]; then composer config minimum-stability ${STABILITY}; fi; - - if ! [ -v "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi; - - install: - - composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction - - ./vendor/bin/simple-phpunit install - - script: - - composer validate --strict --no-check-lock - # simple-phpunit is the PHPUnit wrapper provided by the PHPUnit Bridge component and - # it helps with testing legacy code and deprecations (composer require symfony/phpunit-bridge) - - ./vendor/bin/simple-phpunit $PHPUNIT_FLAGS - -Consider using the `Travis cron`_ tool to make sure your project is built even if -there are no new pull requests or commits. +providing this feature for free for open source projects, like `GitHub Actions`_ +and `Travis CI`_. + +A bundle should at least test: + +* The lower bound of their dependencies (by running ``composer update --prefer-lowest``); +* The supported PHP versions; +* All supported major Symfony versions (e.g. both ``3.x`` and ``4.x`` if + support is claimed for both). + +Thus, a bundle support PHP 7.3, 7.4 and 8.0, and Symfony 3.4 and 4.x should +have at least this test matrix: + +=========== =============== =================== +PHP version Symfony version Composer flags +=========== =============== =================== +7.3 ``3.*`` ``--prefer-lowest`` +7.4 ``4.*`` +8.0 ``4.*`` +=========== =============== =================== + +.. tip:: + + The tests should be run with the ``SYMFONY_DEPRECATIONS_HELPER`` + env variable set to ``max[direct]=0``. This ensures no code in the + bundle uses deprecated features directly. + + The lowest dependency tests can be run with this variable set to + ``disabled=1``. + +Require a Specific Symfony Version +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +You can use the special ``SYMFONY_REQUIRE`` environment variable together +with Symfony Flex to install a specific Symfony version: + +.. code-block:: bash + + # this requires Symfony 5.x for all Symfony packages + export SYMFONY_REQUIRE=5.* + + # install Symfony Flex in the CI environment + composer global require --no-progress --no-scripts --no-plugins symfony/flex + + # install the dependencies (using --prefer-dist and --no-progress is + # recommended to have a better output and faster download time) + composer update --prefer-dist --no-progress + +.. caution:: + + If you want to cache your Composer dependencies, **do not** cache the + ``vendor/`` directory as this has side-effects. Instead cache + ``$HOME/.composer/cache/files``. Installation ------------ @@ -529,5 +515,5 @@ Learn more .. _`Packagist`: https://packagist.org/ .. _`choose any license`: https://choosealicense.com/ .. _`valid license identifier`: https://spdx.org/licenses/ -.. _`Travis CI`: https://travis-ci.org/ -.. _`Travis cron`: https://docs.travis-ci.com/user/cron-jobs/ +.. _`GitHub Actions`: https://docs.github.com/en/free-pro-team@latest/actions +.. _`Travis CI`: https://docs.travis-ci.com/ From 50dfc9097da5fe075e353bc95c1b609dd484a0f0 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Tue, 19 May 2020 16:51:17 +0200 Subject: [PATCH 0086/5766] Update form_customization.rst --- form/bootstrap4.rst | 2 ++ form/form_customization.rst | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/form/bootstrap4.rst b/form/bootstrap4.rst index cc19dd2f8c9..e96db1afb3b 100644 --- a/form/bootstrap4.rst +++ b/form/bootstrap4.rst @@ -77,6 +77,8 @@ If you prefer to apply the Bootstrap styles on a form to form basis, include the {{ form(form) }} {% endblock %} +.. _reference-forms-bootstrap-error-messages: + Error Messages -------------- diff --git a/form/form_customization.rst b/form/form_customization.rst index 3094eb08f40..9c4a32919f2 100644 --- a/form/form_customization.rst +++ b/form/form_customization.rst @@ -255,6 +255,11 @@ Renders any errors for the given field. {# render any "global" errors not associated to any form field #} {{ form_errors(form) }} +.. caution:: + + In the Bootstrap 4 form theme, ``form_errors()`` is already included + in ``form_label()``, see ":ref:`reference-forms-bootstrap-error-messages`" + .. _reference-forms-twig-widget: form_widget(form_view, variables) From cb1a140e0ff208e0b5d78786e7918d18e255c26e Mon Sep 17 00:00:00 2001 From: Carlos Pereira De Amorim Date: Fri, 28 Aug 2020 23:28:38 +0200 Subject: [PATCH 0087/5766] Clarify how workflow can be injected --- workflow.rst | 61 ++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/workflow.rst b/workflow.rst index 3ca81fbea6c..7f7acffaa3a 100644 --- a/workflow.rst +++ b/workflow.rst @@ -236,28 +236,28 @@ what actions are allowed on a blog post:: Accessing the Workflow in a Class --------------------------------- -To access workflow inside a class, use dependency injection and inject the -registry in the constructor:: +You can use the workflow inside a class by using +:doc:`service autowiring ` and using +``camelCased workflow name + Workflow`` as parameter name:: use App\Entity\BlogPost; - use Symfony\Component\Workflow\Registry; + use Symfony\Component\Workflow\WorkflowInterface; class MyClass { - private $workflowRegistry; + private $blogPublishingWorkflow; - public function __construct(Registry $workflowRegistry) + // this injects the blog_publishing workflow configured before + public function __construct(WorkflowInterface $blogPublishingWorkflow) { - $this->workflowRegistry = $workflowRegistry; + $this->blogPublishingWorkflow = $blogPublishingWorkflow; } public function toReview(BlogPost $post) { - $workflow = $this->workflowRegistry->get($post); - // Update the currentState on the post try { - $workflow->apply($post, 'to_review'); + $this->blogPublishingWorkflow->apply($post, 'to_review'); } catch (LogicException $exception) { // ... } @@ -265,6 +265,33 @@ registry in the constructor:: } } +Alternatively, use the registry:: + + use App\Entity\BlogPost; + use Symfony\Component\Workflow\Registry; + + class MyClass + { + private $workflowRegistry; + + public function __construct(Registry $workflowRegistry) + { + $this->workflowRegistry = $workflowRegistry; + } + + public function toReview(BlogPost $post) + { + $blogPublishingWorkflow = $this->workflowRegistry->get($post); + + // ... + } + } + +.. tip:: + + You can find the list of available workflow services with the + ``php bin/console debug:autowiring workflow`` command. + Using Events ------------ @@ -829,25 +856,23 @@ Then you can access this metadata in your controller as follows:: // src/App/Controller/BlogPostController.php use App\Entity\BlogPost; - use Symfony\Component\Workflow\Registry; + use Symfony\Component\Workflow\WorkflowInterface; // ... - public function myAction(Registry $registry, BlogPost $post) + public function myAction(WorkflowInterface $blogPublishingWorkflow, BlogPost $post) { - $workflow = $registry->get($post); - - $title = $workflow + $title = $blogPublishingWorkflow ->getMetadataStore() ->getWorkflowMetadata()['title'] ?? 'Default title' ; - $maxNumOfWords = $workflow + $maxNumOfWords = $blogPublishingWorkflow ->getMetadataStore() ->getPlaceMetadata('draft')['max_num_of_words'] ?? 500 ; - $aTransition = $workflow->getDefinition()->getTransitions()[0]; - $priority = $workflow + $aTransition = $blogPublishingWorkflow->getDefinition()->getTransitions()[0]; + $priority = $blogPublishingWorkflow ->getMetadataStore() ->getTransitionMetadata($aTransition)['priority'] ?? 0 ; @@ -870,7 +895,7 @@ In a :ref:`flash message ` in your controller:: // $transition = ...; (an instance of Transition) - // $workflow is a Workflow instance retrieved from the Registry (see above) + // $workflow is a Workflow instance retrieved from the Registry or injected directly (see above) $title = $workflow->getMetadataStore()->getMetadata('title', $transition); $this->addFlash('info', "You have successfully applied the transition with title: '$title'"); From 104c8f01ee465fe9b95553504d8c115d64799bf5 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Sun, 1 Nov 2020 14:37:17 +0100 Subject: [PATCH 0088/5766] Update routing.rst Fixing argument number. Function signature is: ```php final public function import($resource, string $type = null, bool $ignoreErrors = false, $exclude = null): ImportConfigurator ``` --- routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing.rst b/routing.rst index 5aaebf659cd..d88ebb773a5 100644 --- a/routing.rst +++ b/routing.rst @@ -1243,7 +1243,7 @@ the common configuration using options when importing the routes. use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator; return function (RoutingConfigurator $routes) { - // use the optional fifth argument of import() to exclude some files + // use the optional fourth argument of import() to exclude some files // or subdirectories when loading annotations $routes->import('../../src/Controller/', 'annotation') // this is added to the beginning of all imported route URLs From e62f4c73b4458bc3f485ebf067d14b5a3fb528cd Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 2 Nov 2020 09:24:49 +0100 Subject: [PATCH 0089/5766] - --- performance.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/performance.rst b/performance.rst index 65859141433..de0d7883a04 100644 --- a/performance.rst +++ b/performance.rst @@ -221,8 +221,8 @@ Profiling with Blackfire applications during development, test and production. It's a commercial service, but provides free features that you can use to find bottlenecks in your projects. -Profilwing with Symfony Stopwatch -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Profiling with Symfony Stopwatch +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Symfony provides a basic performance profiler in the development :ref:`config environment `. Click on the "time panel" From 953845cddc63f9a12a54fff135fff7a9485bdb78 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 2 Nov 2020 13:57:47 +0100 Subject: [PATCH 0090/5766] some minor tweaks --- setup/symfony_server.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index a8374aaca4a..0f4d88904d6 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -380,12 +380,12 @@ its location, same as for ``docker-compose``: .. caution:: - When using Symfony binary with ``php bin/console`` (``symfony console ...``) - the binay will **always** use environment variables detected via Docker and will + When using the Symfony binary with ``php bin/console`` (``symfony console ...``), + the binary will **always** use environment variables detected via Docker and will ignore local environment variables. For example if you set up a different database name in your ``.env.test`` file (``DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/test``) and if you run - ``symfony console doctrine:database:drop --force --env=test`` the command will drop the database + ``symfony console doctrine:database:drop --force --env=test``, the command will drop the database defined in your Docker configuration and not the "test" one. SymfonyCloud Integration From 8cdbb3935bf9b42428f97583d2a1e2d73a96d7e0 Mon Sep 17 00:00:00 2001 From: Ilya Bakhlin Date: Tue, 3 Nov 2020 08:49:36 +0100 Subject: [PATCH 0091/5766] Updating the Installer Related Instructions --- setup.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.rst b/setup.rst index b2fe9ab23bd..1bf907318d9 100644 --- a/setup.rst +++ b/setup.rst @@ -67,7 +67,7 @@ with the ``new`` command: .. code-block:: terminal - $ symfony new my_project_name --version=3.4 + $ symfony new my_project_name 3.4 This command creates a new directory called ``my_project_name/`` that contains an empty project based on the most recent stable Symfony version available. In @@ -111,14 +111,14 @@ In case your project needs to be based on a specific Symfony version, use the .. code-block:: terminal # use the most recent version in any Symfony branch - $ symfony new my_project_name --version=3.3 - $ symfony new my_project_name --version=3.4 + $ symfony new my_project_name 3.3 + $ symfony new my_project_name 3.4 # use the most recent 'lts' version (Long Term Support version) - $ symfony new my_project_name --version=lts + $ symfony new my_project_name lts # use the 'next' Symfony version to be released (still in development) - $ symfony new my_project_name --version=next + $ symfony new my_project_name next Each version has its *own* documentation, which you can select on any documentation page. From 2e848b41189b82cee4d46a1277f2116e5ab75bac Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 3 Nov 2020 15:43:05 +0100 Subject: [PATCH 0092/5766] Minor: Use Twig code block this way it can easily be copied --- routing.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/routing.rst b/routing.rst index 5aaebf659cd..ed7e5df48f8 100644 --- a/routing.rst +++ b/routing.rst @@ -2266,8 +2266,11 @@ generating the route:: $this->generateUrl('blog_show', ['slug' => 'slug-value']); - // or, in Twig - // {{ path('blog_show', {slug: 'slug-value'}) }} +or, in Twig: + +.. code-block:: twig + + {{ path('blog_show', {slug: 'slug-value'}) }} Learn more about Routing ------------------------ From dbed899b608229706ed88b84fb36d5e7a7ba7da1 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 25 Oct 2020 16:42:30 +0100 Subject: [PATCH 0093/5766] [Notifier][Discord] Use correct use statements --- notifier/chatters.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/notifier/chatters.rst b/notifier/chatters.rst index 9d03f83987c..7fe42a02f67 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -107,11 +107,11 @@ With a Discord message, you can use the :class:`Symfony\\Component\\Notifier\\Bridge\\Discord\\DiscordOptions` to add some interactive options called `Embed elements`_:: - use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordEmbed; - use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordFieldEmbedObject; - use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordFooterEmbedObject; - use Symfony\Component\Notifier\Bridge\Discord\Block\DiscordMediaEmbedObject; use Symfony\Component\Notifier\Bridge\Discord\DiscordOptions; + use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordEmbed; + use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordFieldEmbedObject; + use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordFooterEmbedObject; + use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordMediaEmbedObject; use Symfony\Component\Notifier\Message\ChatMessage; $chatMessage = new ChatMessage(''); From 958aeafd32cb4bd44aefb540efb59442911d3e1e Mon Sep 17 00:00:00 2001 From: Florian Hermann Date: Tue, 3 Nov 2020 16:47:40 +0100 Subject: [PATCH 0094/5766] Add priority order explanation for tagged services --- service_container/tags.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/service_container/tags.rst b/service_container/tags.rst index 7ec5fcc5637..bbe7df1af6b 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -596,8 +596,9 @@ Tagged Services with Priority The ability to prioritize tagged services was introduced in Symfony 4.4. -The tagged services can be prioritized using the ``priority`` attribute, -thus providing a way to inject a sorted collection of services: +The tagged services can be prioritized using the ``priority`` attribute. +The priority is a positive or negative integer. The higher the number, +the earlier the tagged service will be located in the collection: .. configuration-block:: @@ -655,7 +656,7 @@ service itself:: } } -If you want to have another method defining the priority +If you want to have another method defining the priority (e.g. ``getPriority()`` rather than ``getDefaultPriority()``), you can define it in the configuration of the collecting service: From 447065dc4fe6fb83fd658bf4ea1bd10c65821d60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 4 Nov 2020 10:03:11 +0100 Subject: [PATCH 0095/5766] Add documentation about GetQueueUrl and DSN format in SQS transport --- messenger.rst | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/messenger.rst b/messenger.rst index 6c2f2e35794..2e41a0ca86f 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1300,7 +1300,7 @@ Amazon SQS .. versionadded:: 5.1 - The Amazon SQS transport as introduced in Symfony 5.1. + The Amazon SQS transport has been introduced in Symfony 5.1. The Amazon SQS transport is perfect for application hosted on AWS. Install it by running: @@ -1314,7 +1314,7 @@ The SQS transport DSN may looks like this: .. code-block:: env # .env - MESSENGER_TRANSPORT_DSN=sqs://AKIAIOSFODNN7EXAMPLE:j17M97ffSVoKI0briFoo9a@sqs.eu-west-3.amazonaws.com/messages + MESSENGER_TRANSPORT_DSN=https://AKIAIOSFODNN7EXAMPLE:j17M97ffSVoKI0briFoo9a@sqs.eu-west-3.amazonaws.com/123456789012/messages MESSENGER_TRANSPORT_DSN=sqs://localhost:9494/messages?sslmode=disable .. note:: @@ -1322,6 +1322,17 @@ The SQS transport DSN may looks like this: The transport will automatically create queues that are needed. This can be disabled setting the ``auto_setup`` option to ``false``. +.. tip:: + + Before sending or receiving a message, Symfony needs to convert the queue + name into an AWS queue URL by calling the ``GetQueueUrl`` API in AWS. This + extra API call can be avoided by providing a DSN which is the queue URL. + +.. versionadded:: 5.2 + + Providing a DSN equals to the queue URL to avoid call to ``GetQueueUrl`` + has been introduced in Symfony 5.2. + The transport has a number of options: ====================== ====================================== =================================== From 2a48c4410f659638d42c51c0e8388cfe7a177030 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 5 Nov 2020 10:26:53 +0100 Subject: [PATCH 0096/5766] Tweaks --- messenger.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/messenger.rst b/messenger.rst index 2e41a0ca86f..ac07b40c624 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1300,7 +1300,7 @@ Amazon SQS .. versionadded:: 5.1 - The Amazon SQS transport has been introduced in Symfony 5.1. + The Amazon SQS transport was introduced in Symfony 5.1. The Amazon SQS transport is perfect for application hosted on AWS. Install it by running: @@ -1328,10 +1328,9 @@ The SQS transport DSN may looks like this: name into an AWS queue URL by calling the ``GetQueueUrl`` API in AWS. This extra API call can be avoided by providing a DSN which is the queue URL. -.. versionadded:: 5.2 + .. versionadded:: 5.2 - Providing a DSN equals to the queue URL to avoid call to ``GetQueueUrl`` - has been introduced in Symfony 5.2. + The feature to provide the queue URL in the DSN was introduced in Symfony 5.2. The transport has a number of options: From 3abecebd33c11c0373a775f0b9de1d0c491798e4 Mon Sep 17 00:00:00 2001 From: Thibaut Cheymol Date: Sun, 4 Oct 2020 22:53:49 +0200 Subject: [PATCH 0097/5766] [Collection forms] Make javascript generic --- form/form_collections.rst | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index 1d0b56c244a..068b4c84985 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -242,7 +242,13 @@ the following ``data-prototype`` attribute to the existing ``
    `` in your temp .. code-block:: html+twig -
      +
        + +Now add a button just next to the ``
          `` to dynamically add a new tag + +.. code-block:: html+twig + + On the rendered page, the result will look something like this: @@ -285,27 +291,18 @@ will be show next): .. code-block:: javascript - var $collectionHolder; - - // setup an "add a tag" link - var $addTagButton = $(''); - var $newLinkLi = $('
        • ').append($addTagButton); - jQuery(document).ready(function() { // Get the ul that holds the collection of tags - $collectionHolder = $('ul.tags'); - - // add the "add a tag" anchor and li to the tags ul - $collectionHolder.append($newLinkLi); - + var $tagsCollectionHolder = $('ul.tags'); // count the current form inputs we have (e.g. 2), use that as the new // index when inserting a new item (e.g. 2) - $collectionHolder.data('index', $collectionHolder.find('input').length); + $tagsCollectionHolder.data('index', $tagsCollectionHolder.find('input').length); - $addTagButton.on('click', function(e) { + $('body').on('click', '.add_item_link', function(e) { + var $collectionHolderClass = $(e.currentTarget).data('collectionHolderClass'); // add a new tag form (see next code block) - addTagForm($collectionHolder, $newLinkLi); - }); + addFormToCollection($collectionHolderClass); + }) }); The ``addTagForm()`` function's job will be to use the ``data-prototype`` attribute @@ -319,7 +316,10 @@ one example: .. code-block:: javascript - function addTagForm($collectionHolder, $newLinkLi) { + function addFormToCollection($collectionHolderClass) { + // Get the ul that holds the collection of tags + var $collectionHolder = $('.' + $collectionHolderClass); + // Get the data-prototype explained earlier var prototype = $collectionHolder.data('prototype'); @@ -341,7 +341,8 @@ one example: // Display the form in the page in an li, before the "Add a tag" link li var $newFormLi = $('
        • ').append(newForm); - $newLinkLi.before($newFormLi); + // Add the new form at the end of the list + $collectionHolder.append($newFormLi) } .. note:: From acfe6b620538d4bc21b9e2d9bd81bb8be0aef4fb Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 5 Nov 2020 15:11:29 +0100 Subject: [PATCH 0098/5766] [#14340] Some minor textual changes --- form/form_collections.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index 068b4c84985..405ffed53e4 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -280,14 +280,12 @@ On the rendered page, the result will look something like this: and you need to adjust the following JavaScript accordingly. The goal of this section will be to use JavaScript to read this attribute -and dynamically add new tag forms when the user clicks a "Add a tag" link. +and dynamically add new tag forms when the user clicks the "Add a tag" button. This example uses jQuery and assumes you have it included somewhere on your page. -Add a ``script`` tag somewhere on your page so you can start writing some JavaScript. - -First, add a link to the bottom of the "tags" list via JavaScript. Second, -bind to the "click" event of that link so you can add a new tag form (``addTagForm()`` -will be show next): +Add a ``script`` tag somewhere on your page so you can start writing some +JavaScript. In this script, bind to the "click" event of the "Add a tag" +button so you can add a new tag form (``addFormToCollection()`` will be show next): .. code-block:: javascript From 4bdab6fb8fc7f06eb05b3c5141a1ed415b1b035c Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Sun, 3 May 2020 21:36:09 +0200 Subject: [PATCH 0099/5766] Add wither behavior with PHP8 static return type --- service_container/calls.rst | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/service_container/calls.rst b/service_container/calls.rst index 11dea241613..8496caa724a 100644 --- a/service_container/calls.rst +++ b/service_container/calls.rst @@ -90,9 +90,6 @@ instead of mutating the object they were called on:: { private $logger; - /** - * @return static - */ public function withLogger(LoggerInterface $logger) { $new = clone $this; @@ -146,3 +143,19 @@ The configuration to tell the container it should do so would be like: $container->register(MessageGenerator::class) ->addMethodCall('withLogger', [new Reference('logger')], true); + +If autowire is enabled, you can also use annotations; with the previous exemple it would be:: + + /** + * @required + * @return static + */ + public function withLogger(LoggerInterface $logger) + { + $new = clone $this; + $new->logger = $logger; + + return $new; + } + +You can also leverage the PHP8 ``static`` return type instead of the ``@return static`` annotation. Note if you don't want a method with a PHP8 ``static`` return type and a ``@required`` annotation to behave as a wither, you can add a ``@return $this`` annotation to disable the *returns clone* feature. From 281d758f331081bf27e6046958169474b5bff53c Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 5 Nov 2020 16:12:49 +0100 Subject: [PATCH 0100/5766] [#13619] Moved text into a note and added versionadded --- service_container/calls.rst | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/service_container/calls.rst b/service_container/calls.rst index 8496caa724a..7f12a38ac4c 100644 --- a/service_container/calls.rst +++ b/service_container/calls.rst @@ -144,18 +144,30 @@ The configuration to tell the container it should do so would be like: $container->register(MessageGenerator::class) ->addMethodCall('withLogger', [new Reference('logger')], true); -If autowire is enabled, you can also use annotations; with the previous exemple it would be:: +.. tip:: - /** - * @required - * @return static - */ - public function withLogger(LoggerInterface $logger) - { - $new = clone $this; - $new->logger = $logger; + If autowire is enabled, you can also use annotations; with the previous + example it would be:: - return $new; - } + /** + * @required + * @return static + */ + public function withLogger(LoggerInterface $logger) + { + $new = clone $this; + $new->logger = $logger; + + return $new; + } + + You can also leverage the PHP 8 ``static`` return type instead of the + ``@return static`` annotation. If you don't want a method with a + PHP 8 ``static`` return type and a ``@required`` annotation to behave as + a wither, you can add a ``@return $this`` annotation to disable the + *returns clone* feature. + + .. versionadded:: 5.1 -You can also leverage the PHP8 ``static`` return type instead of the ``@return static`` annotation. Note if you don't want a method with a PHP8 ``static`` return type and a ``@required`` annotation to behave as a wither, you can add a ``@return $this`` annotation to disable the *returns clone* feature. + Support for the PHP 8 ``static`` return type was introduced in + Symfony 5.1. From 9176faa6375ed46433c14487f9753425b75f1cef Mon Sep 17 00:00:00 2001 From: LucileDT Date: Wed, 13 May 2020 17:56:48 +0200 Subject: [PATCH 0101/5766] Add array example on ChoiceType choice_attr option --- reference/forms/types/options/choice_attr.rst.inc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc index ac149f3999d..b86b7450778 100644 --- a/reference/forms/types/options/choice_attr.rst.inc +++ b/reference/forms/types/options/choice_attr.rst.inc @@ -13,6 +13,20 @@ If an array, the keys of the ``choices`` array must be used as keys:: use Symfony\Component\Form\Extension\Core\Type\ChoiceType; // ... + $builder->add('fruits', ChoiceType::class, [ + 'choices' => [ + 'Apple' => 1, + 'Banana' => 2, + 'Durian' => 3, + ], + 'choice_attr' => [ + 'Apple' => ['data-color' => 'Red'], + 'Banana' => ['data-color' => 'Yellow'], + 'Durian' => ['data-color' => 'Green'], + ], + ]); + + // or use a callable $builder->add('attending', ChoiceType::class, [ 'choices' => [ 'Yes' => true, From 0163ab399562c2a84acee070dee73b79d843434d Mon Sep 17 00:00:00 2001 From: armin-github Date: Thu, 27 Feb 2020 17:50:51 +0100 Subject: [PATCH 0102/5766] addressed issue #11786 The following issue has been addressed: Repeated entry in the Serializer components doc #11786 The separate documentations for XMLEncoder were put into one section with minor changes in text. The documentation now contains one single section for XMLEncoder. --- components/serializer.rst | 110 +++++++++++++++----------------------- 1 file changed, 42 insertions(+), 68 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index eba1e0a57cc..fdc34fb6f44 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -841,8 +841,20 @@ The ``XmlEncoder`` will encode this object like that:: 1 -Be aware that this encoder will consider keys beginning with ``@`` as attributes, and will use -the key ``#comment`` for encoding XML comments:: +The special ``#`` key can be used to define the data of a node:: + + ['foo' => ['@bar' => 'value', '#' => 'baz']]; + + // is encoded as follows: + // + // + // + // baz + // + // + +Furthermore, keys beginning with ``@`` will be considered attributes, and +the key ``#comment`` can be used for encoding XML comments:: $encoder = new XmlEncoder(); $encoder->encode([ @@ -869,6 +881,34 @@ always as a collection. changed with the optional ``$encoderIgnoredNodeTypes`` argument of the ``XmlEncoder`` class constructor. +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: + +``xml_format_output`` + If set to true, formats the generated XML with line breaks and indentation. + +``xml_version`` + Sets the XML version attribute (default: ``1.1``). + +``xml_encoding`` + Sets the XML encoding attribute (default: ``utf-8``). + +``xml_standalone`` + Adds standalone attribute in the generated XML (default: ``true``). + +``xml_root_node_name`` + Sets the root node name (default: ``response``). + +``remove_empty_tags`` + If set to true, removes all empty tags in the generated XML (default: ``false``). + The ``YamlEncoder`` ~~~~~~~~~~~~~~~~~~~ @@ -1192,72 +1232,6 @@ you indicate that you're expecting an array instead of a single object:: $data = ...; // The serialized data from the previous example $persons = $serializer->deserialize($data, 'Acme\Person[]', 'json'); -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`` encodes this object as follows: - -.. code-block:: xml - - - - 1 - 2 - 1 - - -The array keys beginning with ``@`` are considered XML attributes:: - - ['foo' => ['@bar' => 'value']]; - - // is encoded as follows: - // - // - // - // - -Use the special ``#`` key to define the data of a node:: - - ['foo' => ['@bar' => 'value', '#' => 'baz']]; - - // is encoded as follows: - // - // - // baz - // - -Context -~~~~~~~ - -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: - -``xml_format_output`` - If set to true, formats the generated XML with line breaks and indentation. - -``xml_version`` - Sets the XML version attribute (default: ``1.1``). - -``xml_encoding`` - Sets the XML encoding attribute (default: ``utf-8``). - -``xml_standalone`` - Adds standalone attribute in the generated XML (default: ``true``). - -``xml_root_node_name`` - Sets the root node name (default: ``response``). - -``remove_empty_tags`` - If set to true, removes all empty tags in the generated XML (default: ``false``). The ``CsvEncoder`` ------------------ From adf1978d322bcf2977cdc7c5c8ce01a4b5402886 Mon Sep 17 00:00:00 2001 From: Maarten de Keizer Date: Sun, 8 Nov 2020 10:08:32 +0100 Subject: [PATCH 0103/5766] Correct case of suffix in example rate limiter The suffix should be with an uppercase (`limiter` -> `Limiter) --- rate_limiter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index 22a56168498..f5473607fe7 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -129,7 +129,7 @@ the number of requests to the API:: class ApiController extends AbstractController { // if you're using service autowiring, the variable name must be: - // "rate limiter name" (in camelCase) + "limiter" suffix + // "rate limiter name" (in camelCase) + "Limiter" suffix public function index(RateLimiterFactory $anonymousApiLimiter) { // create a limiter based on a unique identifier of the client From d397c38b43ba4fddcc49326ae1d415049e805d69 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 5 Nov 2020 18:47:02 +0100 Subject: [PATCH 0104/5766] Merge encoder sections and show options in a table --- components/serializer.rst | 108 ++++++++++++++++---------------------- 1 file changed, 44 insertions(+), 64 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index fdc34fb6f44..20d31fa8c0c 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -823,6 +823,38 @@ 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_escape_char`` Sets the escape character (at most one character) +``csv_key_separator`` Sets the separator for array's keys during its ``.`` + flattening +``csv_headers`` Sets the headers for the data ``[]``, inferred from input data's keys +``csv_escape_formulas`` Escapes fields containg formulas by prepending them ``false`` + with a ``\t`` character +``as_collection`` Always returns results as a collection, even if only + one line is decoded. +``no_headers`` Disables header in the encoded CSV ``false`` +``output_utf8_bom`` Outputs special `UTF-8 BOM`_ along with encoded data ``false`` +======================= ==================================================== ========================== + +.. versionadded:: 4.4 + + The ``output_utf8_bom`` option was introduced in Symfony 4.4. + The ``XmlEncoder`` ~~~~~~~~~~~~~~~~~~ @@ -891,23 +923,18 @@ which defines the configuration options for the XmlEncoder an associative array: These are the options available: -``xml_format_output`` - If set to true, formats the generated XML with line breaks and indentation. - -``xml_version`` - Sets the XML version attribute (default: ``1.1``). - -``xml_encoding`` - Sets the XML encoding attribute (default: ``utf-8``). - -``xml_standalone`` - Adds standalone attribute in the generated XML (default: ``true``). - -``xml_root_node_name`` - Sets the root node name (default: ``response``). - -``remove_empty_tags`` - If set to true, removes all empty tags in the generated XML (default: ``false``). +====================== ==================================================== ========================== +Option Description Default +====================== ==================================================== ========================== +``xml_format_output`` If set to true, formats the generated XML with line + breaks and indentation. +``xml_version`` Sets the XML version attribute ``1.1`` +``xml_encoding`` Sets the XML encoding attribute ``utf-8`` +``xml_standalone`` Adds standalone attribute in the generated XML ``true`` +``xml_root_node_name`` Sets the root node name (default: ``response``). +``remove_empty_tags`` If set to true, removes all empty tags in the ``false`` + generated XML +====================== ==================================================== ========================== The ``YamlEncoder`` ~~~~~~~~~~~~~~~~~~~ @@ -1232,53 +1259,6 @@ you indicate that you're expecting an array instead of a single object:: $data = ...; // The serialized data from the previous example $persons = $serializer->deserialize($data, 'Acme\Person[]', 'json'); - -The ``CsvEncoder`` ------------------- - -This encoder transforms arrays into CSV and vice versa. - -Context -~~~~~~~ - -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: - -``csv_delimiter`` - Sets the field delimiter separating values (one character only, default: ``,``). - -``csv_enclosure`` - Sets the field enclosure (one character only, default: ``"``). - -``csv_escape_char`` - Sets the escape character (at most one character, default: empty string). - -``csv_key_separator`` - Sets the separator for array's keys during its flattening (default: ``.``). - -``csv_headers`` - Sets the headers for the data (default: ``[]``, inferred from input data's keys). - -``csv_escape_formulas`` - Escapes fields containg formulas by prepending them with a ``\t`` character (default: ``false``). - -``as_collection`` - Always returns results as a collection, even if only one line is decoded. - -``no_headers`` - Disables header in the encoded CSV (default: ``false``). - -``output_utf8_bom`` - Outputs special `UTF-8 BOM`_ along with encoded data (default: ``false``). - -.. versionadded:: 4.4 - - The ``output_utf8_bom`` option was introduced in Symfony 4.4. - Handling Constructor Arguments ------------------------------ From bdbd7a697ea722e4a5e076b590d52e4472f06521 Mon Sep 17 00:00:00 2001 From: Yoann Chocteau Date: Mon, 9 Nov 2020 09:28:21 +0100 Subject: [PATCH 0105/5766] Update simple-example.rst Just a little typo, now we use ./styles and not ../css --- frontend/encore/simple-example.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index 3d38686ce05..d0ed86a5922 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -17,7 +17,7 @@ application: it will *require* all of the dependencies it needs (e.g. jQuery or // assets/app.js // ... - import '../css/app.css'; + import './styles/app.css'; // var $ = require('jquery'); From 6d51c6c80038ef53d5948837681fd2b46a25c595 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20H=C3=A9lias?= Date: Sun, 4 Oct 2020 04:06:32 +0200 Subject: [PATCH 0106/5766] [Serializer] move note on Custom Normalizer page about cacheable performance --- components/serializer.rst | 26 -------------------------- serializer/custom_normalizer.rst | 29 +++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 26 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index 345642c9770..515773d18c3 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -1499,32 +1499,6 @@ Once configured, the serializer uses the mapping to pick the correct class:: $repository = $serializer->deserialize($serialized, CodeRepository::class, 'json'); // instanceof GitHubCodeRepository -Performance ------------ - -To figure which normalizer (or denormalizer) must be used to handle an object, -the :class:`Symfony\\Component\\Serializer\\Serializer` class will call the -:method:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface::supportsNormalization` -(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 ` - as well the ones included in `API Platform`_ natively implement this interface. - Learn more ---------- diff --git a/serializer/custom_normalizer.rst b/serializer/custom_normalizer.rst index 9f2e50fdcf1..2c7c7eedf88 100644 --- a/serializer/custom_normalizer.rst +++ b/serializer/custom_normalizer.rst @@ -60,3 +60,32 @@ Before using this normalizer in a Symfony application it must be registered as a service and :doc:`tagged ` with ``serializer.normalizer``. If you're using the :ref:`default services.yaml configuration `, this is done automatically! + +Performance +----------- + +To figure which normalizer (or denormalizer) must be used to handle an object, +the :class:`Symfony\\Component\\Serializer\\Serializer` class will call the +:method:`Symfony\\Component\\Serializer\\Normalizer\\NormalizerInterface::supportsNormalization` +(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 ` + as well the ones included in `API Platform`_ natively implement this interface. + +.. _`API Platform`: https://api-platform.com + From cca746686382f80f3a9307915d92669e9c3c6d5e Mon Sep 17 00:00:00 2001 From: Romain Monteil Date: Thu, 5 Nov 2020 15:18:19 +0100 Subject: [PATCH 0107/5766] [Encore] Fix CSS path --- frontend/encore/installation.rst | 2 +- frontend/encore/simple-example.rst | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/encore/installation.rst b/frontend/encore/installation.rst index 8241dbcd0b2..bbd6469a1c3 100644 --- a/frontend/encore/installation.rst +++ b/frontend/encore/installation.rst @@ -143,7 +143,7 @@ Next, open the new ``assets/app.js`` file which contains some JavaScript code */ // any CSS you import will output into a single css file (app.css in this case) - import '../css/app.css'; + import './styles/app.css'; // Need jQuery? Install it with "yarn add jquery", then uncomment to import it. // import $ from 'jquery'; diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index d0ed86a5922..23c215b1105 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -19,7 +19,7 @@ application: it will *require* all of the dependencies it needs (e.g. jQuery or import './styles/app.css'; - // var $ = require('jquery'); + // import $ from 'jquery'; Encore's job (via Webpack) is simple: to read and follow *all* of the ``require()`` statements and create one final ``app.js`` (and ``app.css``) that contains *everything* @@ -204,8 +204,8 @@ To import values, use ``import``: .. code-block:: diff // assets/app.js - - require('../css/app.css'); - + import '../css/app.css'; + - require('../styles/app.css'); + + import './styles/app.css'; - var $ = require('jquery'); + import $ from 'jquery'; @@ -292,8 +292,8 @@ file to ``app.scss`` and update the ``import`` statement: .. code-block:: diff // assets/app.js - - import '../css/app.css'; - + import '../css/app.scss'; + - import './styles/app.css'; + + import './styles/app.scss'; Then, tell Encore to enable the Sass pre-processor: From 66491462f0cc583c4b4fab40c7901bd3dcf84d51 Mon Sep 17 00:00:00 2001 From: Greg Suraci Date: Tue, 10 Nov 2020 08:11:38 +0100 Subject: [PATCH 0108/5766] Remove simple quotes in config/routes/annotations.yaml I find it weird to have both quoted and un-quoted values for `resource:` key in this code block. I went to an actual project to double check the content of `config/routes/annotations.yaml` provided by the recipe (https://github.com/symfony/recipes/blob/master/doctrine/annotations/1.0/config/routes/annotations.yaml) and found out that both `resource:` are unquoted. Versions : 4.4, 5.0, 5.1, 5.2 Have a good day ;) --- routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing.rst b/routing.rst index cfcbeb39b73..5fd4ad30225 100644 --- a/routing.rst +++ b/routing.rst @@ -36,7 +36,7 @@ following configuration file: # config/routes/annotations.yaml controllers: - resource: '../../src/Controller/' + resource: ../../src/Controller/ type: annotation kernel: From 2c0cad0155fe7ec66b5f853388e40d6acb149b22 Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Wed, 11 Nov 2020 08:34:42 +0100 Subject: [PATCH 0109/5766] Use int type instead integer Uses the same type hint `int` for all the page Used in `optimizations` config --- reference/configuration/twig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index e00d7f63958..055568b1f2e 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -269,7 +269,7 @@ every ``number_format`` filter call. decimals ........ -**type**: ``integer`` **default**: ``0`` +**type**: ``int`` **default**: ``0`` The number of decimals used to format numeric values when no specific number is passed as argument to the ``number_format`` filter. From beea71cbcbac5af0104886aee217968981bfc1a2 Mon Sep 17 00:00:00 2001 From: Kamil P Date: Mon, 9 Nov 2020 09:09:22 +0100 Subject: [PATCH 0110/5766] Update mailer.rst The registeted namespace is "styles", not "css". --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index 025a5c43813..ac83f41fe1e 100644 --- a/mailer.rst +++ b/mailer.rst @@ -586,7 +586,7 @@ arguments to the filter: .. code-block:: html+twig - {% apply inline_css(source('@css/email.css')) %} + {% apply inline_css(source('@styles/email.css')) %}

          Welcome {{ username }}!

          {# ... #} {% endapply %} From 2062d4aba76006465689198102bbe69f8d69c68f Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 12 Nov 2020 09:58:52 +0100 Subject: [PATCH 0111/5766] Minor: Fix namespace --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index ac83f41fe1e..025a5c43813 100644 --- a/mailer.rst +++ b/mailer.rst @@ -586,7 +586,7 @@ arguments to the filter: .. code-block:: html+twig - {% apply inline_css(source('@styles/email.css')) %} + {% apply inline_css(source('@css/email.css')) %}

          Welcome {{ username }}!

          {# ... #} {% endapply %} From 71b3d30cbc50f750479a4afce29148cb6f64f90e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 12 Nov 2020 10:00:04 +0100 Subject: [PATCH 0112/5766] Minor: Fix namespace --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index a932050c049..dffbd25b3ed 100644 --- a/mailer.rst +++ b/mailer.rst @@ -605,7 +605,7 @@ arguments to the filter: .. code-block:: html+twig - {% apply inline_css(source('@css/email.css')) %} + {% apply inline_css(source('@styles/email.css')) %}

          Welcome {{ username }}!

          {# ... #} {% endapply %} From b3ef599517f14edf6be9ec602faa3c97f51512ac Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Wed, 11 Nov 2020 08:44:53 +0100 Subject: [PATCH 0113/5766] add html extension to snake_case recommendation examples Some readers may inconsciently memorize the syntax `file_name.twig` and ignores the second `recommendation` (declaring two extension `html.twig`), it can happen if someone looks only for `snak_case` keyword without reading whole page. I suggest to add `html` extension on the first examples to make sure recommendations cannot escape reader. --- templates.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates.rst b/templates.rst index f415eaa82e3..1431e0244a9 100644 --- a/templates.rst +++ b/templates.rst @@ -118,8 +118,8 @@ Template Naming Symfony recommends the following for template names: -* Use `snake case`_ for filenames and directories (e.g. ``blog_posts.twig``, - ``admin/default_theme/blog/index.twig``, etc.); +* Use `snake case`_ for filenames and directories (e.g. ``blog_posts.html.twig``, + ``admin/default_theme/blog/index.html.twig``, etc.); * Define two extensions for filenames (e.g. ``index.html.twig`` or ``blog_posts.xml.twig``) being the first extension (``html``, ``xml``, etc.) the final format that the template will generate. From 35474186058890bf32c6fa286425ce6cf1a27225 Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Wed, 11 Nov 2020 09:23:48 +0100 Subject: [PATCH 0114/5766] Throw Exception if twig variable is not found An exception of type `Twig\Error\RuntimeError` is thrown when a variable is not found and `strict_variables` is enabled --- templates.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates.rst b/templates.rst index 1431e0244a9..67fdf4a07ef 100644 --- a/templates.rst +++ b/templates.rst @@ -164,7 +164,7 @@ in the following order: #. ``$foo->getBar()`` (object and *getter* method); #. ``$foo->isBar()`` (object and *isser* method); #. ``$foo->hasBar()`` (object and *hasser* method); -#. If none of the above exists, use ``null``. +#. If none of the above exists, use ``null`` or throw a ``Twig\Error\RuntimeError`` exception if ``strict_variables`` config is enabled. This allows to evolve your application code without having to change the template code (you can start with array variables for the application proof of From 6d1fac84859b31e8de699f2a62c5e75d334ea3c7 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Nov 2020 10:21:51 +0100 Subject: [PATCH 0115/5766] Tweak --- reference/configuration/twig.rst | 2 ++ templates.rst | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 1d11db3e3da..96f596d1db6 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -382,6 +382,8 @@ the directory defined in the :ref:`default_path option `. +.. _config-twig-strict-variables: + strict_variables ~~~~~~~~~~~~~~~~ diff --git a/templates.rst b/templates.rst index 67fdf4a07ef..09314868c2d 100644 --- a/templates.rst +++ b/templates.rst @@ -164,7 +164,9 @@ in the following order: #. ``$foo->getBar()`` (object and *getter* method); #. ``$foo->isBar()`` (object and *isser* method); #. ``$foo->hasBar()`` (object and *hasser* method); -#. If none of the above exists, use ``null`` or throw a ``Twig\Error\RuntimeError`` exception if ``strict_variables`` config is enabled. +#. If none of the above exists, use ``null`` (or throw a ``Twig\Error\RuntimeError`` + exception if the :ref:`strict_variables ` + option is enabled). This allows to evolve your application code without having to change the template code (you can start with array variables for the application proof of From 1e4a70f50564bb01b5cab5111797f02cc3016ea6 Mon Sep 17 00:00:00 2001 From: Alessio Pierobon Date: Wed, 11 Nov 2020 00:07:48 +0100 Subject: [PATCH 0116/5766] Fix a typo on Messenger handler results example --- messenger/handler_results.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger/handler_results.rst b/messenger/handler_results.rst index dc4c1fd0821..2ab36a2b40d 100644 --- a/messenger/handler_results.rst +++ b/messenger/handler_results.rst @@ -40,7 +40,7 @@ handler is registered. The ``HandleTrait`` can be used in any class that has a namespace App\Action; use App\Message\ListItemsQuery; - use App\MessageHandler\ListItemsQueryResult; + use App\MessageHandler\ListItemsResult; use Symfony\Component\Messenger\HandleTrait; use Symfony\Component\Messenger\MessageBusInterface; From d84c04c25043e92f0aa28b47d1696dcb424254fe Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 12 Nov 2020 10:26:50 +0100 Subject: [PATCH 0117/5766] Tweak --- messenger/handler_results.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger/handler_results.rst b/messenger/handler_results.rst index 2ab36a2b40d..ee3b09dc99d 100644 --- a/messenger/handler_results.rst +++ b/messenger/handler_results.rst @@ -40,7 +40,7 @@ handler is registered. The ``HandleTrait`` can be used in any class that has a namespace App\Action; use App\Message\ListItemsQuery; - use App\MessageHandler\ListItemsResult; + use App\MessageHandler\ListItemsQueryResult; use Symfony\Component\Messenger\HandleTrait; use Symfony\Component\Messenger\MessageBusInterface; @@ -62,7 +62,7 @@ handler is registered. The ``HandleTrait`` can be used in any class that has a } // Creating such a method is optional, but allows type-hinting the result - private function query(ListItemsQuery $query): ListItemsResult + private function query(ListItemsQuery $query): ListItemsQueryResult { return $this->handle($query); } From fc220753a708416e2f007f9317bae266b0ffee2e Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Thu, 12 Nov 2020 12:04:48 +0100 Subject: [PATCH 0118/5766] Use integer typehint instead int --- reference/configuration/twig.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 055568b1f2e..100d168b792 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -269,7 +269,7 @@ every ``number_format`` filter call. decimals ........ -**type**: ``int`` **default**: ``0`` +**type**: ``integer`` **default**: ``0`` The number of decimals used to format numeric values when no specific number is passed as argument to the ``number_format`` filter. @@ -294,7 +294,7 @@ no specific character is passed as argument to the ``number_format`` filter. optimizations ~~~~~~~~~~~~~ -**type**: ``int`` **default**: ``-1`` +**type**: ``integer`` **default**: ``-1`` Twig includes an extension called ``optimizer`` which is enabled by default in Symfony applications. This extension analyzes the templates to optimize them From 120290daedd1f928c7c78d781d3911f4d754a60f Mon Sep 17 00:00:00 2001 From: Youssef BENHSSAIEN Date: Thu, 12 Nov 2020 14:16:44 +0100 Subject: [PATCH 0119/5766] Replace bool by boolean --- reference/configuration/framework.rst | 4 ++-- reference/constraints/AtLeastOneOf.rst | 2 +- reference/constraints/Hostname.rst | 2 +- reference/constraints/NotBlank.rst | 2 +- reference/constraints/Traverse.rst | 2 +- reference/forms/types/color.rst | 2 +- reference/forms/types/options/help_html.rst.inc | 2 +- reference/forms/types/options/label_html.rst.inc | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index d4058e76c82..c353f73f163 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -801,7 +801,7 @@ outgoing network interface. buffer ...... -**type**: ``bool`` | ``Closure`` +**type**: ``boolean`` | ``Closure`` Buffering the response means that you can access its content multiple times without performing the request again. Buffering is enabled by default when the @@ -2851,7 +2851,7 @@ Name of the workflow you want to create. audit_trail """"""""""" -**type**: ``bool`` +**type**: ``boolean`` If set to ``true``, the :class:`Symfony\\Component\\Workflow\\EventListener\\AuditTrailListener` will be enabled. diff --git a/reference/constraints/AtLeastOneOf.rst b/reference/constraints/AtLeastOneOf.rst index 6a48c44a4fd..b69894184d6 100644 --- a/reference/constraints/AtLeastOneOf.rst +++ b/reference/constraints/AtLeastOneOf.rst @@ -163,7 +163,7 @@ has to be satisfied in order for the validation to succeed. includeInternalMessages ~~~~~~~~~~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` If set to ``true``, the message that is shown if the validation fails, will include the list of messages for the internal constraints. See option diff --git a/reference/constraints/Hostname.rst b/reference/constraints/Hostname.rst index 4cbe606ccb4..a08425f5fa2 100644 --- a/reference/constraints/Hostname.rst +++ b/reference/constraints/Hostname.rst @@ -117,7 +117,7 @@ Parameter Description ``requireTld`` ~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` By default, hostnames are considered valid only when they are fully qualified and include their TLDs (top-level domain names). For instance, ``example.com`` diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst index c3c16f21eae..a87b8696824 100644 --- a/reference/constraints/NotBlank.rst +++ b/reference/constraints/NotBlank.rst @@ -85,7 +85,7 @@ Options allowNull ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` If set to ``true``, ``null`` values are considered valid and won't trigger a constraint violation. diff --git a/reference/constraints/Traverse.rst b/reference/constraints/Traverse.rst index 852f17cdd01..aea7e051ee1 100644 --- a/reference/constraints/Traverse.rst +++ b/reference/constraints/Traverse.rst @@ -146,7 +146,7 @@ The ``groups`` option is not available for this constraint. ``traverse`` ~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` Instances of ``\Traversable`` are traversed by default, use this option to disable validating: diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst index a290b31e673..5dfd61915ce 100644 --- a/reference/forms/types/color.rst +++ b/reference/forms/types/color.rst @@ -49,7 +49,7 @@ Field Options html5 ~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` .. versionadded:: 5.1 diff --git a/reference/forms/types/options/help_html.rst.inc b/reference/forms/types/options/help_html.rst.inc index 83bbe583ca6..2a5dccfb32e 100644 --- a/reference/forms/types/options/help_html.rst.inc +++ b/reference/forms/types/options/help_html.rst.inc @@ -1,7 +1,7 @@ help_html ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` By default, the contents of the ``help`` option are escaped before rendering them in the template. Set this option to ``true`` to not escape them, which is diff --git a/reference/forms/types/options/label_html.rst.inc b/reference/forms/types/options/label_html.rst.inc index 06568ed08f4..a87ad4ab6db 100644 --- a/reference/forms/types/options/label_html.rst.inc +++ b/reference/forms/types/options/label_html.rst.inc @@ -1,7 +1,7 @@ ``label_html`` ~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` .. versionadded:: 5.1 From df7682967fc887e516779ea015b4787728f69d6e Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Wed, 11 Nov 2020 08:34:42 +0100 Subject: [PATCH 0120/5766] Use integer type instead of int & boolean instead of bool --- reference/configuration/framework.rst | 4 ++-- reference/configuration/twig.rst | 2 +- reference/constraints/AtLeastOneOf.rst | 2 +- reference/constraints/Hostname.rst | 2 +- reference/constraints/NotBlank.rst | 2 +- reference/constraints/Traverse.rst | 2 +- reference/forms/types/color.rst | 2 +- reference/forms/types/options/help_html.rst.inc | 2 +- reference/forms/types/options/label_html.rst.inc | 2 +- 9 files changed, 10 insertions(+), 10 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index d4058e76c82..c353f73f163 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -801,7 +801,7 @@ outgoing network interface. buffer ...... -**type**: ``bool`` | ``Closure`` +**type**: ``boolean`` | ``Closure`` Buffering the response means that you can access its content multiple times without performing the request again. Buffering is enabled by default when the @@ -2851,7 +2851,7 @@ Name of the workflow you want to create. audit_trail """"""""""" -**type**: ``bool`` +**type**: ``boolean`` If set to ``true``, the :class:`Symfony\\Component\\Workflow\\EventListener\\AuditTrailListener` will be enabled. diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index e00d7f63958..100d168b792 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -294,7 +294,7 @@ no specific character is passed as argument to the ``number_format`` filter. optimizations ~~~~~~~~~~~~~ -**type**: ``int`` **default**: ``-1`` +**type**: ``integer`` **default**: ``-1`` Twig includes an extension called ``optimizer`` which is enabled by default in Symfony applications. This extension analyzes the templates to optimize them diff --git a/reference/constraints/AtLeastOneOf.rst b/reference/constraints/AtLeastOneOf.rst index 6a48c44a4fd..b69894184d6 100644 --- a/reference/constraints/AtLeastOneOf.rst +++ b/reference/constraints/AtLeastOneOf.rst @@ -163,7 +163,7 @@ has to be satisfied in order for the validation to succeed. includeInternalMessages ~~~~~~~~~~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` If set to ``true``, the message that is shown if the validation fails, will include the list of messages for the internal constraints. See option diff --git a/reference/constraints/Hostname.rst b/reference/constraints/Hostname.rst index 4cbe606ccb4..a08425f5fa2 100644 --- a/reference/constraints/Hostname.rst +++ b/reference/constraints/Hostname.rst @@ -117,7 +117,7 @@ Parameter Description ``requireTld`` ~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` By default, hostnames are considered valid only when they are fully qualified and include their TLDs (top-level domain names). For instance, ``example.com`` diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst index c3c16f21eae..a87b8696824 100644 --- a/reference/constraints/NotBlank.rst +++ b/reference/constraints/NotBlank.rst @@ -85,7 +85,7 @@ Options allowNull ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` If set to ``true``, ``null`` values are considered valid and won't trigger a constraint violation. diff --git a/reference/constraints/Traverse.rst b/reference/constraints/Traverse.rst index 852f17cdd01..aea7e051ee1 100644 --- a/reference/constraints/Traverse.rst +++ b/reference/constraints/Traverse.rst @@ -146,7 +146,7 @@ The ``groups`` option is not available for this constraint. ``traverse`` ~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` Instances of ``\Traversable`` are traversed by default, use this option to disable validating: diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst index a290b31e673..5dfd61915ce 100644 --- a/reference/forms/types/color.rst +++ b/reference/forms/types/color.rst @@ -49,7 +49,7 @@ Field Options html5 ~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` .. versionadded:: 5.1 diff --git a/reference/forms/types/options/help_html.rst.inc b/reference/forms/types/options/help_html.rst.inc index 83bbe583ca6..2a5dccfb32e 100644 --- a/reference/forms/types/options/help_html.rst.inc +++ b/reference/forms/types/options/help_html.rst.inc @@ -1,7 +1,7 @@ help_html ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` By default, the contents of the ``help`` option are escaped before rendering them in the template. Set this option to ``true`` to not escape them, which is diff --git a/reference/forms/types/options/label_html.rst.inc b/reference/forms/types/options/label_html.rst.inc index 06568ed08f4..a87ad4ab6db 100644 --- a/reference/forms/types/options/label_html.rst.inc +++ b/reference/forms/types/options/label_html.rst.inc @@ -1,7 +1,7 @@ ``label_html`` ~~~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` .. versionadded:: 5.1 From da74408ae32e30e55f527915feb48bec6b5bd724 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 12 Nov 2020 14:37:29 +0100 Subject: [PATCH 0121/5766] Minor --- reference/configuration/framework.rst | 4 ++-- reference/configuration/twig.rst | 2 +- reference/constraints/NotBlank.rst | 2 +- reference/constraints/Traverse.rst | 2 +- reference/forms/types/options/help_html.rst.inc | 2 +- reference/forms/types/timezone.rst | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index f388b5c9eb5..cd76b908c64 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -829,7 +829,7 @@ outgoing network interface. buffer ...... -**type**: ``bool`` | ``Closure`` +**type**: ``boolean`` | ``Closure`` Buffering the response means that you can access its content multiple times without performing the request again. Buffering is enabled by default when the @@ -2960,7 +2960,7 @@ Name of the workflow you want to create. audit_trail """"""""""" -**type**: ``bool`` +**type**: ``boolean`` If set to ``true``, the :class:`Symfony\\Component\\Workflow\\EventListener\\AuditTrailListener` will be enabled. diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 96f596d1db6..5fc8b95313c 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -318,7 +318,7 @@ no specific character is passed as argument to the ``number_format`` filter. optimizations ~~~~~~~~~~~~~ -**type**: ``int`` **default**: ``-1`` +**type**: ``integer`` **default**: ``-1`` Twig includes an extension called ``optimizer`` which is enabled by default in Symfony applications. This extension analyzes the templates to optimize them diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst index 19ac9542ec9..342293b2394 100644 --- a/reference/constraints/NotBlank.rst +++ b/reference/constraints/NotBlank.rst @@ -85,7 +85,7 @@ Options allowNull ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` If set to ``true``, ``null`` values are considered valid and won't trigger a constraint violation. diff --git a/reference/constraints/Traverse.rst b/reference/constraints/Traverse.rst index 852f17cdd01..aea7e051ee1 100644 --- a/reference/constraints/Traverse.rst +++ b/reference/constraints/Traverse.rst @@ -146,7 +146,7 @@ The ``groups`` option is not available for this constraint. ``traverse`` ~~~~~~~~~~~~ -**type**: ``bool`` **default**: ``true`` +**type**: ``boolean`` **default**: ``true`` Instances of ``\Traversable`` are traversed by default, use this option to disable validating: diff --git a/reference/forms/types/options/help_html.rst.inc b/reference/forms/types/options/help_html.rst.inc index 83bbe583ca6..2a5dccfb32e 100644 --- a/reference/forms/types/options/help_html.rst.inc +++ b/reference/forms/types/options/help_html.rst.inc @@ -1,7 +1,7 @@ help_html ~~~~~~~~~ -**type**: ``bool`` **default**: ``false`` +**type**: ``boolean`` **default**: ``false`` By default, the contents of the ``help`` option are escaped before rendering them in the template. Set this option to ``true`` to not escape them, which is diff --git a/reference/forms/types/timezone.rst b/reference/forms/types/timezone.rst index 1cdba0d5d78..9458e3a7d1a 100644 --- a/reference/forms/types/timezone.rst +++ b/reference/forms/types/timezone.rst @@ -101,7 +101,7 @@ with the ``choice_translation_locale`` option. ``regions`` ~~~~~~~~~~~ -**type**: ``int`` **default**: ``\DateTimeZone::ALL`` +**type**: ``integer`` **default**: ``\DateTimeZone::ALL`` .. deprecated:: 4.2 From 7b5bb01370ce749e2eeaacd6c061008b9f9ca34f Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 12 Nov 2020 11:40:34 +0100 Subject: [PATCH 0122/5766] Enhancement: Add new rule "string_replacement" --- .doctor-rst.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index e8f02a9fb05..52a1fc2ba4a 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -34,6 +34,7 @@ rules: short_array_syntax: ~ space_between_label_and_link_in_doc: ~ space_between_label_and_link_in_ref: ~ + string_replacement: ~ typo: ~ unused_links: ~ use_deprecated_directive_instead_of_versionadded: ~ From 1aa619a120c847a796ce2bebcd37c9189acd8534 Mon Sep 17 00:00:00 2001 From: HypeMC Date: Fri, 13 Nov 2020 17:49:22 +0100 Subject: [PATCH 0123/5766] Fix broken configuration block --- lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lock.rst b/lock.rst index 51f375adc33..3fde32ee190 100644 --- a/lock.rst +++ b/lock.rst @@ -223,7 +223,7 @@ Named Lock ---------- If the application needs different kind of Stores alongside each other, Symfony -provides :ref:`named lock `:: +provides :ref:`named lock `: .. configuration-block:: From 6b7c7fb1bfbdd64052c900423c50e3223abbd9b7 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:40:26 +0100 Subject: [PATCH 0124/5766] [Validator] Remove empty line from annotation --- reference/constraints/DivisibleBy.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/reference/constraints/DivisibleBy.rst b/reference/constraints/DivisibleBy.rst index c93052a248a..f4ae78ab0f8 100644 --- a/reference/constraints/DivisibleBy.rst +++ b/reference/constraints/DivisibleBy.rst @@ -33,7 +33,6 @@ The following constraints ensure that: class Item { - /** * @Assert\DivisibleBy(0.25) */ From b781296cf0e084b00ee8f4f4aee78c7604c60099 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sat, 14 Nov 2020 15:27:25 +0100 Subject: [PATCH 0125/5766] [Validator] Fix ExpressionLanguageSyntax example --- reference/constraints/ExpressionLanguageSyntax.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/reference/constraints/ExpressionLanguageSyntax.rst b/reference/constraints/ExpressionLanguageSyntax.rst index 2ca0355dfaf..18c465e8a9d 100644 --- a/reference/constraints/ExpressionLanguageSyntax.rst +++ b/reference/constraints/ExpressionLanguageSyntax.rst @@ -40,13 +40,13 @@ The following constraints ensure that: class Order { /** - * @Assert\ExpressionLanguageSyntax() + * @Assert\ExpressionLanguageSyntax */ protected $promotion; /** * @Assert\ExpressionLanguageSyntax( - * allowedVariables = ['user', 'shipping_centers'] + * allowedVariables={"user", "shipping_centers"} * ) */ protected $shippingOptions; @@ -77,7 +77,10 @@ The following constraints ensure that: - + From 2496ee7b29ea29da22f3da1b2dec6ea062c38dfe Mon Sep 17 00:00:00 2001 From: Arman Hosseini Date: Sun, 15 Nov 2020 02:16:52 +0330 Subject: [PATCH 0126/5766] Update README.markdown Clarify the Note section --- README.markdown | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.markdown b/README.markdown index 1d94f6f1ff0..8923f022322 100644 --- a/README.markdown +++ b/README.markdown @@ -11,9 +11,9 @@ Symfony documentation, please read [Contributing to the Documentation](https://symfony.com/doc/current/contributing/documentation/overview.html) > **Note** -> Unless you're documenting a feature that was introduced *after* Symfony 3.4 -> (e.g. in Symfony 4.4), all pull requests must be based off of the **3.4** branch, -> **not** the master or older branches. +> All pull requests must be based off of the **3.4** branch, +> unless you're documenting a feature that was introduced *after* Symfony 3.4 +> (e.g. in Symfony 4.4), **not** the master or older branches. SymfonyCloud ------------ From a08f0959917ba5a647796759466e3603cbaa8adc Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sat, 14 Nov 2020 10:09:28 +0100 Subject: [PATCH 0127/5766] [Validator] Remove extra space --- reference/constraints/Isbn.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/constraints/Isbn.rst b/reference/constraints/Isbn.rst index d2ad1e2c909..2820fce0052 100644 --- a/reference/constraints/Isbn.rst +++ b/reference/constraints/Isbn.rst @@ -37,7 +37,7 @@ on an object that will contain an ISBN. /** * @Assert\Isbn( * type = "isbn10", - * message = "This value is not valid." + * message = "This value is not valid." * ) */ protected $isbn; @@ -51,7 +51,7 @@ on an object that will contain an ISBN. isbn: - Isbn: type: isbn10 - message: This value is not valid. + message: This value is not valid. .. code-block:: xml @@ -65,7 +65,7 @@ on an object that will contain an ISBN. - + From bea2e77e83412a560bc9503ec473e2243551b3e6 Mon Sep 17 00:00:00 2001 From: obsirdian Date: Sat, 14 Nov 2020 12:44:14 -0600 Subject: [PATCH 0128/5766] Fix user entity import --- 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 83e1dc0554b..d5374e44b03 100644 --- a/security/user_checkers.rst +++ b/security/user_checkers.rst @@ -21,8 +21,8 @@ or :class:`Symfony\\Component\\Security\\Core\\Exception\\AuthenticationExceptio namespace App\Security; + use App\Entity\User as AppUser; use App\Exception\AccountDeletedException; - use App\Security\User as AppUser; use Symfony\Component\Security\Core\Exception\AccountExpiredException; use Symfony\Component\Security\Core\User\UserCheckerInterface; use Symfony\Component\Security\Core\User\UserInterface; From 3189563ce824beb9871f4ef27195eed21a3a07d2 Mon Sep 17 00:00:00 2001 From: Arman Hosseini Date: Sun, 15 Nov 2020 21:48:36 +0330 Subject: [PATCH 0129/5766] Use AppBundle instead of Acme\UserBundle AppBundle is used in all contexts and it is better to keep this name until the end in this branch. --- security/named_encoders.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/named_encoders.rst b/security/named_encoders.rst index 803f3d16992..78d3094ebbf 100644 --- a/security/named_encoders.rst +++ b/security/named_encoders.rst @@ -52,7 +52,7 @@ to apply to all instances of a specific class: Another option is to use a "named" encoder and then select which encoder you want to use dynamically. -In the previous example, you've set the ``sha512`` algorithm for ``Acme\UserBundle\Entity\User``. +In the previous example, you've set the ``sha512`` algorithm for ``AppBundle\Entity\User``. This may be secure enough for a regular user, but what if you want your admins to have a stronger algorithm, for example ``bcrypt``. This can be done with named encoders: @@ -113,8 +113,8 @@ to use it, the class must implement The interface requires one method - ``getEncoderName()`` - which should return the name of the encoder to use:: - // src/Acme/UserBundle/Entity/User.php - namespace Acme\UserBundle\Entity; + // src/AppBundle/Entity/User.php + namespace AppBundle\Entity\User; use Symfony\Component\Security\Core\Encoder\EncoderAwareInterface; use Symfony\Component\Security\Core\User\UserInterface; From 3a439bddc1646c482f3f6f78894391c0153199da Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 16 Nov 2020 00:02:25 +0100 Subject: [PATCH 0130/5766] [#14011] Documented the NullToken usage --- security/experimental_authenticators.rst | 36 ++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index d0813795b12..45c0edb882d 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -135,6 +135,42 @@ unauthenticated access (e.g. the login page): ], ]); +Granting Anonymous Users Access in a Custom Voter +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 5.2 + + The ``NullToken`` class was introduced in Symfony 5.2. + +If you're using a :doc:`custom voter `, you can allow +anonymous users access by checking for a special +:class:`Symfony\\Component\\Security\\Core\\Authentication\\Token\\NullToken`. This token is used +in the voters to represent the unauthenticated access:: + + // src/Security/PostVoter.php + namespace App\Security; + + // ... + use Symfony\Component\Security\Core\Authentication\Token\NullToken; + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + use Symfony\Component\Security\Core\Authorization\Voter\Voter; + + class PostVoter extends Voter + { + // ... + + protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool + { + // ... + + if ($token instanceof NullToken) { + // the user is not authenticated, e.g. only allow them to + // see public posts + return $subject->isPublic(); + } + } + } + .. _authenticators-required-entry-point: Configuring the Authentication Entry Point From 0eae59cf1d7b3c8a02d6610127ea89115dd628dd Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 16 Nov 2020 00:12:03 +0100 Subject: [PATCH 0131/5766] Documented passport attributes --- security/experimental_authenticators.rst | 37 ++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index d0813795b12..0a713e6b0ca 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -502,3 +502,40 @@ authenticator, you would initialize the passport like this:: ]); } } + +.. tip:: + + Besides badges, passports can define attributes, which allows the + ``authenticate()`` method to store arbitrary information in the + passport to access it from other authenticator methods (e.g. + ``createAuthenticatedToken()``):: + + // ... + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + + class LoginAuthenticator extends AbstractAuthenticator + { + // ... + + public function authenticate(Request $request): PassportInterface + { + // ... process the request + + $passport = new SelfValidatingPassport($username, []); + + // set a custom attribute (e.g. scope) + $passport->setAttribute('scope', $oauthScope); + + return $passport; + } + + public function createAuthenticatedToken(PassportInterface $passport, string $firewallName): TokenInterface + { + // read the attribute value + return new CustomOauthToken($passport->getUser(), $passport->getAttribute('scope')); + } + } + +.. versionadded:: 5.2 + + Passport attributes were introduced in Symfony 5.2. From 4129e8ece169f80d10741eb2baf2b7ab5af1fb6a Mon Sep 17 00:00:00 2001 From: jmsche Date: Mon, 16 Nov 2020 11:20:31 +0100 Subject: [PATCH 0132/5766] [Event Dispatcher] Fix typo for __invoke() --- event_dispatcher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event_dispatcher.rst b/event_dispatcher.rst index c7fa7b7d905..3462659efb5 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -122,7 +122,7 @@ listener class: the ``kernel.exception`` event); #. If that method is not defined either, try to call the ``__invoke()`` magic method (which makes event listeners invokable); -#. If the ``_invoke()`` method is not defined either, throw an exception. +#. If the ``__invoke()`` method is not defined either, throw an exception. .. note:: From 4e0bdc59bff163866ddae899e11f002a8dd91439 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Mon, 16 Nov 2020 19:55:01 +0100 Subject: [PATCH 0133/5766] [Validator] Fix namespace of UserPassword and UserPasswordValidator --- reference/constraints/UserPassword.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/constraints/UserPassword.rst b/reference/constraints/UserPassword.rst index 9655380bf95..91017168a82 100644 --- a/reference/constraints/UserPassword.rst +++ b/reference/constraints/UserPassword.rst @@ -20,8 +20,8 @@ Applies to :ref:`property or method ` Options - `groups`_ - `message`_ - `payload`_ -Class :class:`Symfony\\Component\\Validator\\Constraints\\UserPassword` -Validator :class:`Symfony\\Component\\Validator\\Constraints\\UserPasswordValidator` +Class :class:`Symfony\\Component\\Security\\Core\\Validator\\Constraints\\UserPassword` +Validator :class:`Symfony\\Component\\Security\\Core\\Validator\\Constraints\\UserPasswordValidator` ========== =================================================================== Basic Usage From cb81bdeac1a0e24532742193c5858cd8be69c06a Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 17 Nov 2020 10:24:42 +0100 Subject: [PATCH 0134/5766] Removed 3.3 DI changes article --- _build/redirection_map | 1 + service_container/3.3-di-changes.rst | 873 --------------------------- setup/flex.rst | 2 +- 3 files changed, 2 insertions(+), 874 deletions(-) delete mode 100644 service_container/3.3-di-changes.rst diff --git a/_build/redirection_map b/_build/redirection_map index 66fc6db1b47..6c49dc6bed6 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -508,3 +508,4 @@ /components/mailer /mailer /messenger/message-recorder messenger/dispatch_after_current_bus /components/stopwatch https://github.com/symfony/stopwatch +/service_container/3.3-di-changes https://symfony.com/doc/3.4/service_container/3.3-di-changes.html diff --git a/service_container/3.3-di-changes.rst b/service_container/3.3-di-changes.rst deleted file mode 100644 index d57be2c0e5b..00000000000 --- a/service_container/3.3-di-changes.rst +++ /dev/null @@ -1,873 +0,0 @@ -The Symfony 3.3 DI Container Changes Explained (autowiring, _defaults, etc) -=========================================================================== - -If you look at the ``services.yaml`` file in a new Symfony 3.3 or newer project, you'll -notice some big changes: ``_defaults``, ``autowiring``, ``autoconfigure`` and more. -These features are designed to *automate* configuration and make development faster, -without sacrificing predictability, which is very important! Another goal is to make -controllers and services behave more consistently. In Symfony 3.3, controllers *are* -services by default. - -The documentation has already been updated to assume you have these new features -enabled. If you're an existing Symfony user and want to understand the "what" -and "why" behind these changes, this article is for you! - -All Changes are Optional ------------------------- - -Most importantly, **you can upgrade to Symfony 3.3 today without making any changes to your app**. -Symfony has a strict :doc:`backwards compatibility promise `, -which means it's always safe to upgrade across minor versions. - -All of the new features are **optional**: they are not enabled by default, so you -need to actually change your configuration files to use them. - -.. _`service-33-default_definition`: - -The new Default services.yaml File ----------------------------------- - -To understand the changes, look at the new default ``services.yaml`` file (this is -what the file looks like in Symfony 4): - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - # default configuration for services in *this* file - _defaults: - autowire: true # Automatically injects dependencies in your services. - autoconfigure: true # Automatically registers your services as commands, event subscribers, etc. - public: false # Allows optimizing the container by removing unused services; this also means - # fetching services directly from the container via $container->get() won't work. - # The best practice is to be explicit about your dependencies anyway. - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests}' - - # controllers are imported separately to make sure services can be injected - # as action arguments even if you don't extend any base controller class - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - # add more service definitions when explicit configuration is needed - # please note that last definitions always *replace* previous ones - - .. code-block:: xml - - - - - - - - - - - - - - - - - - - .. code-block:: php - - // config/services.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; - - return function(ContainerConfigurator $configurator) { - // default configuration for services in *this* file - $services = $configurator->services() - ->defaults() - ->autowire() // Automatically injects dependencies in your services. - ->autoconfigure() // Automatically registers your services as commands, event subscribers, etc. - ; - - // 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/{Entity,Migrations,Tests}'); - - // controllers are imported separately to make sure services can be injected - // as action arguments even if you don't extend any base controller class - $services->load('App\\Controller\\', '../src/Controller') - ->tag('controller.service_arguments'); - - // add more service definitions when explicit configuration is needed - // please note that last definitions always *replace* previous ones - }; - -This small bit of configuration contains a paradigm shift of how services -are configured in Symfony. - -.. _`service-33-changes-automatic-registration`: - -1) Services are Loaded Automatically ------------------------------------- - -.. seealso:: - - Read the documentation for :ref:`automatic service loading `. - -The first big change is that services do *not* need to be defined one-by-one anymore, -thanks to the following config: - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - # ... - - # makes classes in src/ available to be used as services - # this creates a service per class whose id is the fully-qualified class name - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests}' - - .. code-block:: xml - - - - - - - - - - - - - .. code-block:: php - - // config/services.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; - - return function(ContainerConfigurator $configurator) { - // ... - - // 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/{Entity,Migrations,Tests}'); - }; - -This means that every class in ``src/`` is *available* to be used as a -service. And thanks to the ``_defaults`` section at the top of the file, all of -these services are **autowired** and **private** (i.e. ``public: false``). - -The service ids are equal to the class name (e.g. ``App\Service\InvoiceGenerator``). -And that's another change you'll notice in Symfony 3.3: we recommend that you use -the class name as your service id, unless you have :ref:`multiple services for the same class `. - - But how does the container know the arguments to my services? - -Since each service is :ref:`autowired `, the container is able -to determine most arguments automatically. But, you can always override the service -and :ref:`manually configure arguments ` or anything -else special about your service. - - But wait, if I have some model (non-service) classes in my ``src/`` - directory, doesn't this mean that *they* will also be registered as services? - Isn't that a problem? - -Actually, this is *not* a problem. Since all the new services are :ref:`private ` -(thanks to ``_defaults``), if any of the services are *not* used in your code, they're -automatically removed from the compiled container. This means that the number of -services in your container should be the *same* whether your explicitly configure -each service or load them all at once with this method. - - Ok, but can I exclude some paths that I *know* won't contain services? - -Yes! The ``exclude`` key is a glob pattern that can be used to *ignore* paths -that you do *not* want to be included as services. But, since unused services are -automatically removed from the container, ``exclude`` is not that important. The -biggest benefit is that those paths are not *tracked* by the container, and so may -result in the container needing to be rebuilt less-often in the ``dev`` environment. - -2) Autowiring by Default: Use Type-hint instead of Service id -------------------------------------------------------------- - -The second big change is that autowiring is enabled (via ``_defaults``) for all -services you register. This also means that service id's are now *less* important -and "types" (i.e. class or interface names) are now *more* important. - -For example, before Symfony 3.3 (and this is still allowed), you could pass one -service as an argument to another with the following config: - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - app.invoice_generator: - class: App\Service\InvoiceGenerator - - app.invoice_mailer: - class: App\Service\InvoiceMailer - arguments: - - '@app.invoice_generator' - - .. code-block:: xml - - - - - - - - - - - - - - - - .. code-block:: php - - // config/services.php - use App\Service\InvoiceGenerator; - use App\Service\InvoiceMailer; - use Symfony\Component\DependencyInjection\Reference; - - $container->register('app.invoice_generator', InvoiceGenerator::class); - $container->register('app.invoice_mailer', InvoiceMailer::class) - ->setArguments([new Reference('app.invoice_generator')]); - -To pass the ``InvoiceGenerator`` as an argument to ``InvoiceMailer``, you needed -to specify the service's *id* as an argument: ``app.invoice_generator``. Service -id's were the main way that you configured things. - -But in Symfony 3.3, thanks to autowiring, all you need to do is type-hint the -argument with ``InvoiceGenerator``:: - - // src/Service/InvoiceMailer.php - namespace App\Service; - - // ... - - class InvoiceMailer - { - private $generator; - - public function __construct(InvoiceGenerator $generator) - { - $this->generator = $generator - } - - // ... - } - -That's it! Both services are :ref:`automatically registered ` -and set to autowire. Without *any* configuration, the container knows to pass the -auto-registered ``App\Service\InvoiceGenerator`` as the first argument. As -you can see, the *type* of the class - ``App\Service\InvoiceGenerator`` - is -what's most important, not the id. You request an *instance* of a specific type and -the container automatically passes you the correct service. - - Isn't that magic? How does it know which service to pass me exactly? What if - I have multiple services of the same instance? - -The autowiring system was designed to be *super* predictable. It first works by looking -for a service whose id *exactly* matches the type-hint. This means you're in full -control of what type-hint maps to what service. You can even use service aliases -to get more control. If you have multiple services for a specific type, *you* choose -which should be used for autowiring. For full details on the autowiring logic, see :ref:`autowiring-logic-explained`. - - But what if I have a scalar (e.g. string) argument? How does it autowire that? - -If you have an argument that is *not* an object, it can't be autowired. But that's -ok! Symfony will give you a clear exception (on the next refresh of *any* page) telling -you which argument of which service could not be autowired. To fix it, you can -:ref:`manually configure *just* that one argument `. -This is the philosophy of autowiring: only configure the parts that you need to. -Most configuration is automated. - - Ok, but autowiring makes your applications less stable. If you change one thing - or make a mistake, unexpected things might happen. Isn't that a problem? - -Symfony has always valued stability, security and predictability first. Autowiring -was designed with that in mind. Specifically: - -* If there is a problem wiring *any* argument to *any* service, a clear exception - is thrown on the next refresh of *any* page, even if you don't use that service - on that page. That's *powerful*: it is *not* possible to make an autowiring mistake - and not realize it. - -* The container determines *which* service to pass in an explicit way: it looks for - a service whose id matches the type-hint exactly. It does *not* scan all services - looking for objects that have that class/interface. - -Autowiring aims to *automate* configuration without magic. - -3) Controllers are Registered as Services ------------------------------------------ - -The third big change is that, in a new Symfony 3.3 project, your controllers are *services*: - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - # ... - - # controllers are imported separately to make sure they're public - # and have a tag that allows actions to type-hint services - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - .. code-block:: xml - - - - - - - - - - - - - - - .. code-block:: php - - // config/services.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; - - return function(ContainerConfigurator $configurator) { - // ... - - // controllers are imported separately to make sure they're public - // and have a tag that allows actions to type-hint services - $services->load('App\\Controller\\', '../src/Controller') - ->tag('controller.service_arguments'); - }; - - -But, you might not even notice this. First, your controllers *can* still extend -the same base controller class (``AbstractController``). -This means you have access to all of the same shortcuts as before. Additionally, -the ``@Route`` annotation and ``_controller`` syntax (e.g. ``App:Default:homepage``) -used in routing will automatically use your controller as a service (as long as its -service id matches its class name, which it *does* in this case). See :doc:`/controller/service` -for more details. You can even create :ref:`invokable controllers ` - -In other words, everything works the same. You can even add the above configuration -to your existing project without any issues: your controllers will behave the same -as before. But now that your controllers are services, you can use dependency injection -and autowiring like any other service. - -To make life even easier, it's now possible to autowire arguments to your controller -action methods, like you can with the constructor of services. For example:: - - // src/Controller/InvoiceController.php - namespace App\Controller; - - use Psr\Log\LoggerInterface; - - class InvoiceController extends AbstractController - { - public function listInvoices(LoggerInterface $logger) - { - $logger->info('A new way to access services!'); - } - } - -This is *only* possible in a controller, and your controller service must be tagged -with ``controller.service_arguments`` to make it happen. This new feature is used -throughout the documentation. - -In general, the new best practice is to use normal constructor dependency injection -(or "action" injection in controllers) instead of fetching public services via -``$this->get()`` (though that does still work). - -.. _service_autoconfigure: - -4) Auto-tagging with autoconfigure ----------------------------------- - -The fourth big change is the ``autoconfigure`` key, which is set to ``true`` under -``_defaults``. Thanks to this, the container will auto-tag services registered in -this file. For example, suppose you want to create an event subscriber. First, you -create the class:: - - // src/EventSubscriber/SetHeaderSusbcriber.php - namespace App\EventSubscriber; - - // ... - - use Symfony\Component\EventDispatcher\EventSubscriberInterface; - use Symfony\Component\HttpKernel\Event\ResponseEvent; - use Symfony\Component\HttpKernel\KernelEvents; - - class SetHeaderSusbcriber implements EventSubscriberInterface - { - public function onKernelResponse(ResponseEvent $event) - { - $event->getResponse()->headers->set('X-SYMFONY-3.3', 'Less config'); - } - - public static function getSubscribedEvents() - { - return [ - KernelEvents::RESPONSE => 'onKernelResponse' - ]; - } - } - -Great! In Symfony 3.2 or lower, you would now need to register this as a service -in ``services.yaml`` and tag it with ``kernel.event_subscriber``. In Symfony 3.3, -you're already done! - -The service is :ref:`automatically registered `. -And thanks to ``autoconfigure``, Symfony automatically tags the service because -it implements ``EventSubscriberInterface``. - - That sounds like magic - it *automatically* tags my services? - -In this case, you've created a class that implements ``EventSubscriberInterface`` -and registered it as a service. This is more than enough for the container to know -that you want this to be used as an event subscriber: more configuration is not needed. -And the tags system is its own, Symfony-specific mechanism. And you can -always set ``autoconfigure`` to ``false`` in ``services.yaml``, or disable it -for a specific service. - - Does this mean tags are dead? Does this work for all tags? - -This does *not* work for all tags. Many tags have *required* attributes, like event -*listeners*, where you also need to specify the event name and method in your tag. -Autoconfigure works only for tags without any required tag attributes, and as you -read the docs for a feature, it'll tell you whether or not the tag is needed. You -can also look at the extension classes (e.g. `FrameworkExtension for 3.3.0`_) to -see what it autoconfigures. - - What if I need to add a priority to my tag? - -Many autoconfigured tags have an optional priority. If you need to specify a priority -(or any other optional tag attribute), no problem! :ref:`Manually configure your service ` -and add the tag. Your tag will take precedence over the one added by auto-configuration. - -5) Auto-configure with _instanceof ----------------------------------- - -And the final big change is ``_instanceof``. It acts as a default definition -template (see `service-33-default_definition`_), but only for services whose -class matches a defined one. - -This can be very useful when many services share some tag that cannot be -inherited from an abstract definition: - -.. configuration-block:: - - .. code-block:: yaml - - # config/services.yaml - services: - # ... - - _instanceof: - App\Domain\LoaderInterface: - public: true - tags: ['app.domain_loader'] - - .. code-block:: xml - - - - - - - - - - - - - - - .. code-block:: php - - // config/services.php - namespace Symfony\Component\DependencyInjection\Loader\Configurator; - - use App\Domain\LoaderInterface; - - return function(ContainerConfigurator $configurator) { - // ... - - $services->instanceof(LoaderInterface::class) - ->public() - ->tag('app.domain_loader'); - }; - -What about Performance ----------------------- - -Symfony is unique because it has a *compiled* container. This means that there is -*no* runtime performance impact for using any of these features. That's also why -the autowiring system can give you such clear errors. - -However, there is some performance impact in the ``dev`` environment. Most importantly, -your container will likely be rebuilt more often when you modify your service classes. -This is because it needs to rebuild whenever you add a new argument to a service, -or add an interface to your class that should be autoconfigured. - -In very big projects, this may be a problem. If it is, you can always opt to *not* -use autowiring. If you think the cache rebuilding system could be smarter in some -situation, please open an issue! - -Upgrading to the new Symfony 3.3 Configuration ----------------------------------------------- - -Ready to upgrade your existing project? Great! Suppose you have the following configuration: - -.. code-block:: yaml - - # config/services.yaml - services: - app.github_notifier: - class: App\Service\GitHubNotifier - arguments: - - '@app.api_client_github' - - markdown_transformer: - class: App\Service\MarkdownTransformer - - app.api_client_github: - class: App\Service\ApiClient - arguments: - - 'https://api.github.com' - - app.api_client_sl_connect: - class: App\Service\ApiClient - arguments: - - 'https://connect.symfony.com/api' - -It's optional, but let's upgrade this to the new Symfony 3.3 configuration step-by-step, -*without* breaking our application. - -Step 1): Adding _defaults -~~~~~~~~~~~~~~~~~~~~~~~~~ - -Start by adding a ``_defaults`` section with ``autowire`` and ``autoconfigure``. - -.. code-block:: diff - - # config/services.yaml - services: - + _defaults: - + autowire: true - + autoconfigure: true - - # ... - -You're already *explicitly* configuring all of your services. So, ``autowire`` -does nothing. You're also already tagging your services, so ``autoconfigure`` -also doesn't change any existing services. - -You have not added ``public: false`` yet. That will come in a minute. - -Step 2) Using Class Service id's -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Right now, the service ids are machine names - e.g. ``app.github_notifier``. To -work well with the new configuration system, your service ids should be class names, -except when you have multiple instances of the same service. - -Start by updating the service ids to class names: - -.. code-block:: diff - - # config/services.yaml - services: - # ... - - - app.github_notifier: - - class: App\Service\GitHubNotifier - + App\Service\GitHubNotifier: - arguments: - - '@app.api_client_github' - - - markdown_transformer: - - class: App\Service\MarkdownTransformer - + App\Service\MarkdownTransformer: ~ - - # keep these ids because there are multiple instances per class - app.api_client_github: - # ... - app.api_client_sl_connect: - # ... - -.. caution:: - - Services associated with global PHP classes (i.e. not using PHP namespaces) - must maintain the ``class`` parameter. For example, when using the old Twig - classes (e.g. ``Twig_Extensions_Extension_Intl`` instead of ``Twig\Extensions\IntlExtension``), - you can't redefine the service as ``Twig_Extensions_Extension_Intl: ~`` and - you must keep the original ``class`` parameter. - -.. caution:: - - If a service is processed by a :doc:`compiler pass `, - you could face a "You have requested a non-existent service" error. - To get rid of this, be sure that the Compiler Pass is using ``findDefinition()`` - instead of ``getDefinition()``. The latter won't take aliases into - account when looking up for services. - Furthermore it is always recommended to check for definition existence - using ``has()`` function. - -.. note:: - - If you get rid of deprecations and make your controllers extend from - ``AbstractController`` instead of ``Controller``, you can skip the rest of - this step because ``AbstractController`` doesn't provide a container where - you can get the services from. All services need to be injected as explained - in the :ref:`step 5 of this article `. - -But, this change will break our app! The old service ids (e.g. ``app.github_notifier``) -no longer exist. The simplest way to fix this is to find all your old service ids -and update them to the new class id: ``app.github_notifier`` to ``App\Service\GitHubNotifier``. - -In large projects, there's a better way: create legacy aliases that map the old id -to the new id. Create a new ``legacy_aliases.yaml`` file: - -.. code-block:: yaml - - # config/legacy_aliases.yaml - services: - _defaults: - public: true - # aliases so that the old service ids can still be accessed - # remove these if/when you are not fetching these directly - # from the container via $container->get() - app.github_notifier: '@App\Service\GitHubNotifier' - markdown_transformer: '@App\Service\MarkdownTransformer' - -Then import this at the top of ``services.yaml``: - -.. code-block:: diff - - # config/services.yaml - + imports: - + - { resource: legacy_aliases.yaml } - - # ... - -That's it! The old service ids still work. Later, (see the cleanup step below), you -can remove these from your app. - -Step 3) Make the Services Private -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Now you're ready to default all services to be private: - -.. code-block:: diff - - # config/services.yaml - # ... - - services: - _defaults: - autowire: true - autoconfigure: true - + public: false - -Thanks to this, any services created in this file cannot be fetched directly from -the container. But, since the old service id's are aliases in a separate file (``legacy_aliases.yaml``), -these *are* still public. This makes sure the app keeps working. - -If you did *not* change the id of some of your services (because there are multiple -instances of the same class), you may need to make those public: - -.. code-block:: diff - - # config/services.yaml - # ... - - services: - # ... - - app.api_client_github: - # ... - - + # remove this if/when you are not fetching this - + # directly from the container via $container->get() - + public: true - - app.api_client_sl_connect: - # ... - + public: true - -This is to guarantee that the application doesn't break. If you're not fetching -these services directly from the container, this isn't needed. In a minute, you'll -clean that up. - -Step 4) Auto-registering Services -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -You're now ready to automatically register all services in ``src/`` -(and/or any other directory/bundle you have): - -.. code-block:: diff - - # config/services.yaml - - services: - _defaults: - # ... - - + App\: - + resource: '../src/*' - + exclude: '../src/{Entity,Migrations,Tests}' - + - + App\Controller\: - + resource: '../src/Controller' - + tags: ['controller.service_arguments'] - - # ... - -That's it! Actually, you're already overriding and reconfiguring all the services -you're using (``App\Service\GitHubNotifier`` and ``App\Service\MarkdownTransformer``). -But now, you won't need to manually register future services. - -Once again, there is one extra complication if you have multiple services of the -same class: - -.. code-block:: diff - - # config/services.yaml - - services: - # ... - - + # alias ApiClient to one of our services below - + # app.api_client_github will be used to autowire ApiClient type-hints - + App\Service\ApiClient: '@app.api_client_github' - - app.api_client_github: - # ... - app.api_client_sl_connect: - # ... - -This guarantees that if you try to autowire an ``ApiClient`` instance, the ``app.api_client_github`` -will be used. If you *don't* have this, the auto-registration feature will try to -register a third ``ApiClient`` service and use that for autowiring (which will fail, -because the class has a non-autowireable argument). - -.. _step-5: - -Step 5) Cleanup! -~~~~~~~~~~~~~~~~ - -To make sure your application didn't break, you did some extra work. Now it's time -to clean things up! First, update your application to *not* use the old service id's (the -ones in ``legacy_aliases.yaml``). This means updating any service arguments (e.g. -``@app.github_notifier`` to ``@App\Service\GitHubNotifier``) and updating your -code to not fetch this service directly from the container. For example: - -.. code-block:: diff - - - public function index() - + public function index(GitHubNotifier $gitHubNotifier, MarkdownTransformer $markdownTransformer) - { - - // the old way of fetching services - - $githubNotifier = $this->container->get('app.github_notifier'); - - $markdownTransformer = $this->container->get('markdown_transformer'); - - // ... - } - -As soon as you do this, you can delete ``legacy_aliases.yaml`` and remove its import. -You should do the same thing for any services that you made public, like -``app.api_client_github`` and ``app.api_client_sl_connect``. Once you're not fetching -these directly from the container, you can remove the ``public: true`` flag: - -.. code-block:: diff - - # config/services.yaml - services: - # ... - - app.api_client_github: - # ... - - public: true - - app.api_client_sl_connect: - # ... - - public: true - -Finally, you can optionally remove any services from ``services.yaml`` whose arguments -can be autowired. The final configuration looks like this: - -.. code-block:: yaml - - services: - _defaults: - autowire: true - autoconfigure: true - public: false - - App\: - resource: '../src/*' - exclude: '../src/{Entity,Migrations,Tests}' - - App\Controller\: - resource: '../src/Controller' - tags: ['controller.service_arguments'] - - App\Service\GitHubNotifier: - # this could be deleted, or I can keep being explicit - arguments: - - '@app.api_client_github' - - # alias ApiClient to one of our services below - # app.api_client_github will be used to autowire ApiClient type-hints - App\Service\ApiClient: '@app.api_client_github' - - # keep these ids because there are multiple instances per class - app.api_client_github: - class: App\Service\ApiClient - arguments: - - 'https://api.github.com' - - app.api_client_sl_connect: - class: App\Service\ApiClient - arguments: - - 'https://connect.symfony.com/api' - -You can now take advantage of the new features going forward. - -.. _`FrameworkExtension for 3.3.0`: https://github.com/symfony/symfony/blob/7938fdeceb03cc1df277a249cf3da70f0b50eb98/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php#L247-L284 diff --git a/setup/flex.rst b/setup/flex.rst index df1bf1eaa14..eaba102d073 100644 --- a/setup/flex.rst +++ b/setup/flex.rst @@ -100,7 +100,7 @@ manual steps: located at ``config/services.yaml``. Copy the contents of the `default services.yaml file`_ and then add your own service configuration. Later you can revisit this file because thanks to Symfony's - :doc:`autowiring feature ` you can remove + :doc:`autowiring feature ` you can remove most of the service configuration. .. note:: From ab4b613ed3859ddb70b9b00356ecef1d1786eddb Mon Sep 17 00:00:00 2001 From: Youssef BENHSSAIEN Date: Tue, 17 Nov 2020 10:02:05 +0100 Subject: [PATCH 0135/5766] Fix option double dashes --- console/input.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/input.rst b/console/input.rst index 3e99b39e515..0813bad58c5 100644 --- a/console/input.rst +++ b/console/input.rst @@ -247,7 +247,7 @@ optionally accepts a value, but it's a bit tricky. Consider this example:: ) ; -This option can be used in 3 ways: ``greet --yell``, ``greet yell=louder``, +This option can be used in 3 ways: ``greet --yell``, ``greet --yell=louder``, and ``greet``. However, it's hard to distinguish between passing the option without a value (``greet --yell``) and not passing the option (``greet``). From ad7a7ce1ef03c63f0ddc5978b56bb74ed7e6cfdd Mon Sep 17 00:00:00 2001 From: David Vigo Date: Tue, 17 Nov 2020 13:42:33 +0100 Subject: [PATCH 0136/5766] Add forgotten use --- security/access_denied_handler.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/security/access_denied_handler.rst b/security/access_denied_handler.rst index 59d6d6bb8d6..8601218ab56 100644 --- a/security/access_denied_handler.rst +++ b/security/access_denied_handler.rst @@ -29,6 +29,7 @@ unauthenticated user tries to access a protected resource:: use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; From b93b1a791900ed8823ef0a566a9d1168e73bf802 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 17 Nov 2020 10:18:36 +0100 Subject: [PATCH 0137/5766] Prepare for 3.4 end of life --- README.markdown | 6 ++-- .../cache/adapters/filesystem_adapter.rst | 8 ++--- .../adapters/pdo_doctrine_dbal_adapter.rst | 2 +- .../cache/adapters/php_files_adapter.rst | 2 +- components/cache/cache_invalidation.rst | 2 +- contributing/code/pull_requests.rst | 32 +++++++++---------- contributing/community/releases.rst | 18 +++++------ contributing/documentation/overview.rst | 14 ++++---- 8 files changed, 41 insertions(+), 43 deletions(-) diff --git a/README.markdown b/README.markdown index 8923f022322..b993cd45ed4 100644 --- a/README.markdown +++ b/README.markdown @@ -11,9 +11,9 @@ Symfony documentation, please read [Contributing to the Documentation](https://symfony.com/doc/current/contributing/documentation/overview.html) > **Note** -> All pull requests must be based off of the **3.4** branch, -> unless you're documenting a feature that was introduced *after* Symfony 3.4 -> (e.g. in Symfony 4.4), **not** the master or older branches. +> All pull requests must be based off of the **4.4** branch, +> unless you're documenting a feature that was introduced *after* Symfony 4.4 +> (e.g. in Symfony 5.2), **not** the ``5.x`` or older branches. SymfonyCloud ------------ diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst index c4db3a7fb76..772a6d7b6a9 100644 --- a/components/cache/adapters/filesystem_adapter.rst +++ b/components/cache/adapters/filesystem_adapter.rst @@ -50,11 +50,9 @@ and cache root path as constructor parameters:: .. note:: - Since Symfony 3.4, this adapter implements - :class:`Symfony\\Component\\Cache\\PruneableInterface`, enabling manual - :ref:`pruning of expired cache items ` by - calling its ``prune()`` method. - + This adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + enabling manual :ref:`pruning of expired cache items ` + by calling its ``prune()`` method. .. _filesystem-tag-aware-adapter: diff --git a/components/cache/adapters/pdo_doctrine_dbal_adapter.rst b/components/cache/adapters/pdo_doctrine_dbal_adapter.rst index 841071dc586..b840da76de7 100644 --- a/components/cache/adapters/pdo_doctrine_dbal_adapter.rst +++ b/components/cache/adapters/pdo_doctrine_dbal_adapter.rst @@ -44,7 +44,7 @@ your code. .. note:: - Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + This adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, allowing for manual :ref:`pruning of expired cache entries ` by calling its ``prune()`` method. diff --git a/components/cache/adapters/php_files_adapter.rst b/components/cache/adapters/php_files_adapter.rst index 5bec5715801..fcb5bcfffd1 100644 --- a/components/cache/adapters/php_files_adapter.rst +++ b/components/cache/adapters/php_files_adapter.rst @@ -63,7 +63,7 @@ directory path as constructor arguments:: .. note:: - Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + This adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, allowing for manual :ref:`pruning of expired cache entries ` by calling its ``prune()`` method. diff --git a/components/cache/cache_invalidation.rst b/components/cache/cache_invalidation.rst index bef2c29b0b7..d7e44031d90 100644 --- a/components/cache/cache_invalidation.rst +++ b/components/cache/cache_invalidation.rst @@ -87,7 +87,7 @@ your fronts and have very fast invalidation checks:: .. note:: - Since Symfony 3.4, :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` + :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, enabling manual :ref:`pruning of expired cache entries ` by diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst index 15c2f6a4484..f76e778763f 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -124,7 +124,7 @@ Choose the right Branch Before working on a PR, you must determine on which branch you need to work: -* ``3.4``, if you are fixing a bug for an existing feature or want to make a +* ``4.4``, if you are fixing a bug for an existing feature or want to make a change that falls into the :doc:`list of acceptable changes in patch versions ` (you may have to choose a higher branch if the feature you are fixing was introduced in a later version); @@ -132,16 +132,16 @@ work: * ``5.x``, if you are adding a new feature. The only exception is when a new :doc:`major Symfony version ` - (4.0, 5.0, etc.) comes out every two years. Because of the + (5.0, 6.0, etc.) comes out every two years. Because of the :ref:`special development process ` of those versions, - you need to use the previous minor version for the features (e.g. use ``3.4`` - instead of ``4.0``, use ``4.4`` instead of ``5.0``, etc.) + you need to use the previous minor version for the features (e.g. use ``4.4`` + instead of ``5.0``, use ``5.4`` instead of ``6.0``, etc.) .. note:: All bug fixes merged into maintenance branches are also merged into more recent branches on a regular basis. For instance, if you submit a PR - for the ``3.4`` branch, the PR will also be applied by the core team on + for the ``4.4`` branch, the PR will also be applied by the core team on the ``5.x`` branch. Create a Topic Branch @@ -154,18 +154,18 @@ topic branch: $ git checkout -b BRANCH_NAME 5.x -Or, if you want to provide a bug fix for the ``3.4`` branch, first track the remote -``3.4`` branch locally: +Or, if you want to provide a bug fix for the ``4.4`` branch, first track the remote +``4.4`` branch locally: .. code-block:: terminal - $ git checkout --track origin/3.4 + $ git checkout --track origin/4.4 -Then create a new branch off the ``3.4`` branch to work on the bug fix: +Then create a new branch off the ``4.4`` branch to work on the bug fix: .. code-block:: terminal - $ git checkout -b BRANCH_NAME 3.4 + $ git checkout -b BRANCH_NAME 4.4 .. tip:: @@ -193,8 +193,8 @@ want to debug are installed by running ``composer install`` inside it. .. tip:: - If symlinks to your local Symfony fork cannot be resolved inside your project due to - your dev environment (for instance when using Vagrant where only the current project + If symlinks to your local Symfony fork cannot be resolved inside your project due to + your dev environment (for instance when using Vagrant where only the current project directory is mounted), you can alternatively use the ``--copy`` option. When finishing testing your Symfony code into your project, you can use the ``--rollback`` option to make your project back to its original dependencies. @@ -285,7 +285,7 @@ while to finish your changes): .. tip:: - Replace ``5.x`` with the branch you selected previously (e.g. ``3.4``) + Replace ``5.x`` with the branch you selected previously (e.g. ``4.4``) if you are working on a bug fix. When doing the ``rebase`` command, you might have to fix merge conflicts. @@ -312,8 +312,8 @@ You can now make a pull request on the ``symfony/symfony`` GitHub repository. .. tip:: - Take care to point your pull request towards ``symfony:3.4`` if you want - the core team to pull a bug fix based on the ``3.4`` branch. + Take care to point your pull request towards ``symfony:4.4`` if you want + the core team to pull a bug fix based on the ``4.4`` branch. To ease the core team work, always include the modified components in your pull request message, like in: @@ -403,7 +403,7 @@ Rework your Pull Request Based on the feedback on the pull request, you might need to rework your PR. Before re-submitting the PR, rebase with ``upstream/5.x`` or -``upstream/3.4``, don't merge; and force the push to the origin: +``upstream/4.4``, don't merge; and force the push to the origin: .. code-block:: terminal diff --git a/contributing/community/releases.rst b/contributing/community/releases.rst index fa8471717f2..80d5033accd 100644 --- a/contributing/community/releases.rst +++ b/contributing/community/releases.rst @@ -7,7 +7,7 @@ release and maintain its different versions. Symfony releases follow the `semantic versioning`_ strategy and they are published through a *time-based model*: -* A new **Symfony patch version** (e.g. 3.4.41, 4.4.9) comes out roughly every +* A new **Symfony patch version** (e.g. 4.4.12, 5.1.9) comes out roughly every month. It only contains bug fixes, so you can safely upgrade your applications; * A new **Symfony minor version** (e.g. 4.4, 5.0, 5.1) comes out every *six months*: one in *May* and one in *November*. It contains bug fixes and new features, but @@ -53,7 +53,7 @@ Maintenance Starting from the Symfony 3.x branch, the number of minor versions is limited to five per branch (X.0, X.1, X.2, X.3 and X.4). The last minor version of a branch -(e.g. 3.4, 4.4, 5.4) is considered a **long-term support version** and the other +(e.g. 4.4, 5.4) is considered a **long-term support version** and the other ones are considered **standard versions**: ======================= ===================== ================================ @@ -87,17 +87,17 @@ learn more about how deprecations are handled in Symfony. .. _major-version-development: This deprecation policy also requires a custom development process for major -versions (4.0, 5.0, 6.0, etc.) In those cases, Symfony develops at the same time -two versions: the new major one (e.g. 4.0) and the latest version of the -previous branch (e.g. 3.4). +versions (5.0, 6.0, etc.) In those cases, Symfony develops at the same time +two versions: the new major one (e.g. 5.0) and the latest version of the +previous branch (e.g. 4.4). Both versions have the same new features, but they differ in the deprecated -features. The oldest version (3.4 in this example) contains all the deprecated -features whereas the new version (4.0 in this example) removes all of them. +features. The oldest version (4.4 in this example) contains all the deprecated +features whereas the new version (5.0 in this example) removes all of them. -This allows you to upgrade your projects to the latest minor version (e.g. 3.4), +This allows you to upgrade your projects to the latest minor version (e.g. 4.4), see all the deprecation messages and fix them. Once you have fixed all those -deprecations, you can upgrade to the new major version (e.g. 4.0) without +deprecations, you can upgrade to the new major version (e.g. 5.0) without effort, because it contains the same features (the only difference are the deprecated features, which your project no longer uses). diff --git a/contributing/documentation/overview.rst b/contributing/documentation/overview.rst index fc6a2c4e5e5..f7d1e4e8a03 100644 --- a/contributing/documentation/overview.rst +++ b/contributing/documentation/overview.rst @@ -112,14 +112,14 @@ memorable name for the new branch (if you are fixing a reported issue, use .. code-block:: terminal - $ git checkout -b improve_install_article upstream/3.4 + $ git checkout -b improve_install_article upstream/4.4 In this example, the name of the branch is ``improve_install_article`` and the -``upstream/3.4`` value tells Git to create this branch based on the ``3.4`` +``upstream/4.4`` value tells Git to create this branch based on the ``4.4`` branch of the ``upstream`` remote, which is the original Symfony Docs repository. Fixes should always be based on the **oldest maintained branch** which contains -the error. Nowadays this is the ``3.4`` branch. If you are instead documenting a +the error. Nowadays this is the ``4.4`` branch. If you are instead documenting a new feature, switch to the first Symfony version that included it, e.g. ``upstream/3.1``. Not sure? That's OK! Just use the ``upstream/master`` branch. @@ -155,7 +155,7 @@ changes should be applied: :align: center In this example, the **base fork** should be ``symfony/symfony-docs`` and -the **base** branch should be the ``3.4``, which is the branch that you selected +the **base** branch should be the ``4.4``, which is the branch that you selected to base your changes on. The **head fork** should be your forked copy of ``symfony-docs`` and the **compare** branch should be ``improve_install_article``, which is the name of the branch you created and where you made your changes. @@ -205,7 +205,7 @@ contribution to the Symfony docs: # create a new branch based on the oldest maintained version $ cd projects/symfony-docs/ $ git fetch upstream - $ git checkout -b my_changes upstream/3.4 + $ git checkout -b my_changes upstream/4.4 # ... do your changes @@ -303,8 +303,8 @@ into multiple branches, corresponding to the different versions of Symfony itsel The ``master`` branch holds the documentation for the development branch of the code. -Unless you're documenting a feature that was introduced after Symfony 3.4, -your changes should always be based on the ``3.4`` branch. Documentation managers +Unless you're documenting a feature that was introduced after Symfony 4.4, +your changes should always be based on the ``4.4`` branch. Documentation managers will use the necessary Git-magic to also apply your changes to all the active branches of the documentation. From e5918146ca5fbd2d54a88965d0df26bd6880a49c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 4 Nov 2020 10:18:54 +0100 Subject: [PATCH 0138/5766] Remove deprecated HEADER_X_FORWARDED_ALL header --- deployment/proxies.rst | 12 ++++++++++-- migration.rst | 2 +- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index 12bf3f1cac1..a7e0aff99b2 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -35,15 +35,22 @@ and what headers your reverse proxy uses to send information:: ['192.0.0.1', '10.0.0.0/8'], // trust *all* "X-Forwarded-*" headers - Request::HEADER_X_FORWARDED_ALL + Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO // or, if your proxy instead uses the "Forwarded" header // Request::HEADER_FORWARDED - // or, if you're using AWS ELB + // or, if you're using a wellknown proxy // Request::HEADER_X_FORWARDED_AWS_ELB + // Request::HEADER_X_FORWARDED_TRAEFIK ); +.. caution:: + + Enabling the ``Request::HEADER_X_FORWARDED_HOST`` option exposes the + application to "`HTTP Host header attacks`_". Make sure the proxy really + send a ``x-forwarded-host`` header. + The Request object has several ``Request::HEADER_*`` constants that control exactly *which* headers from your reverse proxy are trusted. The argument is a bit field, so you can also pass your own value (e.g. ``0b00110``). @@ -114,3 +121,4 @@ In this case, you'll need to set the header ``X-Forwarded-Proto`` with the value .. _`security groups`: https://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html .. _`CloudFront`: https://en.wikipedia.org/wiki/Amazon_CloudFront .. _`CloudFront IP ranges`: https://ip-ranges.amazonaws.com/ip-ranges.json +.. _`HTTP Host header attacks`: https://www.skeletonscribe.net/2013/05/practical-http-host-header-attacks.html diff --git a/migration.rst b/migration.rst index fa8c2bfc24b..5c786c103b9 100644 --- a/migration.rst +++ b/migration.rst @@ -262,7 +262,7 @@ could look something like this:: if ($trustedProxies = $_SERVER['TRUSTED_PROXIES'] ?? $_ENV['TRUSTED_PROXIES'] ?? false) { Request::setTrustedProxies( explode(',', $trustedProxies), - Request::HEADER_X_FORWARDED_ALL ^ Request::HEADER_X_FORWARDED_HOST + Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO ); } From c5dbbd7c07e9c852a3bba6f0edc6fb9bac9612f6 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 18 Nov 2020 10:54:29 +0100 Subject: [PATCH 0139/5766] [#14561] Fixed wrong reference --- serializer/custom_encoders.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/serializer/custom_encoders.rst b/serializer/custom_encoders.rst index 4c08b410dbd..d212f94a2f5 100644 --- a/serializer/custom_encoders.rst +++ b/serializer/custom_encoders.rst @@ -66,7 +66,7 @@ that's done automatically! .. tip:: - If you're not using :ref:`autoconfigure `, make sure + If you're not using :ref:`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! From 42c1ca4fe901ec3e7339f13b00ac7764f8dfada9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 18 Nov 2020 10:54:34 +0100 Subject: [PATCH 0140/5766] Added a deprecation notice --- deployment/proxies.rst | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index a7e0aff99b2..81c1f5c7826 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -40,16 +40,22 @@ and what headers your reverse proxy uses to send information:: // or, if your proxy instead uses the "Forwarded" header // Request::HEADER_FORWARDED - // or, if you're using a wellknown proxy + // or, if you're using a well-known proxy // Request::HEADER_X_FORWARDED_AWS_ELB // Request::HEADER_X_FORWARDED_TRAEFIK ); +.. deprecated:: 5.2 + + In previous Symfony versions, the above example used ``HEADER_X_FORWARDED_ALL`` + to trust all "X-Forwarded-*" headers, but that constant is deprecated since + Symfony 5.2 in favor of the individual ``HEADER_X_FORWARDED_*`` constants. + .. caution:: Enabling the ``Request::HEADER_X_FORWARDED_HOST`` option exposes the - application to "`HTTP Host header attacks`_". Make sure the proxy really - send a ``x-forwarded-host`` header. + application to `HTTP Host header attacks`_. Make sure the proxy really + sends an ``x-forwarded-host`` header. The Request object has several ``Request::HEADER_*`` constants that control exactly *which* headers from your reverse proxy are trusted. The argument is a bit field, From 163c6941e9b8cc0cc7fd2721e34b4445b86c5554 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 18 Nov 2020 11:27:44 +0100 Subject: [PATCH 0141/5766] Fixed a RST syntax issue --- deployment/proxies.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index 81c1f5c7826..cae9e285648 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -48,7 +48,7 @@ and what headers your reverse proxy uses to send information:: .. deprecated:: 5.2 In previous Symfony versions, the above example used ``HEADER_X_FORWARDED_ALL`` - to trust all "X-Forwarded-*" headers, but that constant is deprecated since + to trust all "X-Forwarded-" headers, but that constant is deprecated since Symfony 5.2 in favor of the individual ``HEADER_X_FORWARDED_*`` constants. .. caution:: From 035335cb0ec35b73034f624cb7f9837486efc00d Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 18 Nov 2020 12:59:08 +0100 Subject: [PATCH 0142/5766] Document named arguments BC policy --- contributing/code/bc.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/contributing/code/bc.rst b/contributing/code/bc.rst index d0c82ab1c1f..15f1f03674d 100644 --- a/contributing/code/bc.rst +++ b/contributing/code/bc.rst @@ -72,7 +72,7 @@ backward compatibility promise: +-----------------------------------------------+-----------------------------+ | Type hint against the interface | Yes | +-----------------------------------------------+-----------------------------+ -| Call a method | Yes | +| Call a method | Yes [10]_ | +-----------------------------------------------+-----------------------------+ | **If you implement the interface and...** | **Then we guarantee BC...** | +-----------------------------------------------+-----------------------------+ @@ -114,13 +114,13 @@ covered by our backward compatibility promise: +-----------------------------------------------+-----------------------------+ | Access a public property | Yes | +-----------------------------------------------+-----------------------------+ -| Call a public method | Yes | +| Call a public method | Yes [10]_ | +-----------------------------------------------+-----------------------------+ | **If you extend the class and...** | **Then we guarantee BC...** | +-----------------------------------------------+-----------------------------+ | Access a protected property | Yes | +-----------------------------------------------+-----------------------------+ -| Call a protected method | Yes | +| Call a protected method | Yes [10]_ | +-----------------------------------------------+-----------------------------+ | Override a public property | Yes | +-----------------------------------------------+-----------------------------+ @@ -445,4 +445,8 @@ Turn static into non static No .. [9] Allowed for the ``void`` return type. +.. [10] Parameter names are not part of the compatibility promise. Using + PHP 8's named arguments feature might break your code when upgrading to + newer Symfony versions. + .. _`Semantic Versioning`: https://semver.org/ From 50f3ece07c22e16326616b0b420880d154bea37b Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 18 Nov 2020 17:03:01 +0100 Subject: [PATCH 0143/5766] Add little tip about PHPdocs --- messenger/multiple_buses.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/messenger/multiple_buses.rst b/messenger/multiple_buses.rst index 5136553dac2..6191bc0556c 100644 --- a/messenger/multiple_buses.rst +++ b/messenger/multiple_buses.rst @@ -249,4 +249,9 @@ You can also restrict the list to a specific bus by providing its name as argume handled by App\MessageHandler\MultipleBusesMessageHandler --------------------------------------------------------------------------------------- +.. tip:: + + Since Symfony 5.1, the command will also show the PHPDoc description of + the message and handler classes. + .. _article about CQRS: https://martinfowler.com/bliki/CQRS.html From b47ccb91e9e27ea02a5ca52fdd09f90fcb4adf8d Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Thu, 19 Nov 2020 01:59:09 +0100 Subject: [PATCH 0144/5766] Update testing.rst Hello, I update mysql env variable with server version. --- testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index 479a26be864..365626ceacd 100644 --- a/testing.rst +++ b/testing.rst @@ -990,7 +990,7 @@ need in your ``.env.test`` file: .. code-block:: text # .env.test - DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name_test" + DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name_test?serverVersion=5.7 # use SQLITE # DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" From 3b1ade011908e82d3e5d361d6aea5aa0328208b9 Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Thu, 19 Nov 2020 02:03:13 +0100 Subject: [PATCH 0145/5766] Update doctrine.rst Hello, I update mysql server version. --- reference/configuration/doctrine.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst index fd44b56b2bc..cf49aaaa2b9 100644 --- a/reference/configuration/doctrine.rst +++ b/reference/configuration/doctrine.rst @@ -65,7 +65,7 @@ The following block shows all possible configuration keys: charset: UTF8 logging: '%kernel.debug%' platform_service: App\DBAL\MyDatabasePlatformService - server_version: '5.6' + server_version: '5.7' mapping_types: enum: string types: @@ -99,7 +99,7 @@ The following block shows all possible configuration keys: charset="UTF8" logging="%kernel.debug%" platform-service="App\DBAL\MyDatabasePlatformService" - server-version="5.6"> + server-version="5.7"> bar string @@ -121,8 +121,8 @@ The following block shows all possible configuration keys: Always wrap the server version number with quotes to parse it as a string instead of a float number. Otherwise, the floating-point representation - issues can make your version be considered a different number (e.g. ``5.6`` - will be rounded as ``5.5999999999999996447286321199499070644378662109375``). + issues can make your version be considered a different number (e.g. ``5.7`` + will be rounded as ``5.6999999999999996447286321199499070644378662109375``). If you don't define this option and you haven't created your database yet, you may get ``PDOException`` errors because Doctrine will try to From 5a95590b0c53f9075e0ca814a0ecc86f1f46ed33 Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Thu, 19 Nov 2020 02:05:29 +0100 Subject: [PATCH 0146/5766] Update dbal.rst Hello, I updated mysql env database_url. --- doctrine/dbal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/dbal.rst b/doctrine/dbal.rst index 3d451fb4af6..4b9f26d3f7b 100644 --- a/doctrine/dbal.rst +++ b/doctrine/dbal.rst @@ -35,7 +35,7 @@ Then configure the ``DATABASE_URL`` environment variable in ``.env``: # .env (or override DATABASE_URL in .env.local to avoid committing your changes) # customize this line! - DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name" + DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7 Further things can be configured in ``config/packages/doctrine.yaml`` - see :ref:`reference-dbal-configuration`. Remove the ``orm`` key in that file From c639ea407b86d5e8e63abf34b1cc66c8629ecad1 Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Thu, 19 Nov 2020 02:12:47 +0100 Subject: [PATCH 0147/5766] Update doctrine.rst Hello, I just add env variable for mariadb. --- doctrine.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doctrine.rst b/doctrine.rst index fb491df8c2b..21b14c2ae4c 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -46,6 +46,9 @@ The database connection information is stored as an environment variable called # customize this line! DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7" + # to use mariadb: + DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=mariadb-10.5.8" + # to use sqlite: # DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" From 74de492ada02ece7221a55390825e013e3dedf42 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Thu, 19 Nov 2020 09:23:27 +0100 Subject: [PATCH 0148/5766] Fix strict_variables default value since Symfony 5 The default was changed in https://github.com/symfony/symfony/blob/494ef421c554a78b38c6779c4b7deb9a20d89923/UPGRADE-5.0.md#twigbundle --- reference/configuration/twig.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index c7d77739b1c..5d5edd1d43c 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -363,7 +363,7 @@ Read more about :ref:`template directories and namespaces strict_variables ~~~~~~~~~~~~~~~~ -**type**: ``boolean`` **default**: ``false`` +**type**: ``boolean`` **default**: ``%kernel.debug%`` If set to ``true``, Symfony shows an exception whenever a Twig variable, attribute or method doesn't exist. If set to ``false`` these errors are ignored From 6e2a758b75744cca019edeab55fd651800236fd0 Mon Sep 17 00:00:00 2001 From: Romain Monteil Date: Thu, 19 Nov 2020 17:29:25 +0100 Subject: [PATCH 0149/5766] Replace old ICU Formatting Messages url --- translation.rst | 2 +- translation/message_format.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/translation.rst b/translation.rst index 8fdffe83baa..20025b8b5cd 100644 --- a/translation.rst +++ b/translation.rst @@ -607,7 +607,7 @@ Learn more translation/xliff .. _`i18n`: https://en.wikipedia.org/wiki/Internationalization_and_localization -.. _`ICU MessageFormat`: http://userguide.icu-project.org/formatparse/messages +.. _`ICU MessageFormat`: https://unicode-org.github.io/icu/userguide/format_parse/messages/ .. _`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`: http://atlantic18.github.io/DoctrineExtensions/doc/translatable.html diff --git a/translation/message_format.rst b/translation/message_format.rst index 4ec520682ef..218d479d795 100644 --- a/translation/message_format.rst +++ b/translation/message_format.rst @@ -474,7 +474,7 @@ The ``number`` formatter allows you to format numbers using Intl's :phpclass:`Nu echo $translator->trans('value_of_object', ['value' => 9988776.65]); .. _`online editor`: http://format-message.github.io/icu-message-format-for-translators/ -.. _`ICU MessageFormat`: http://userguide.icu-project.org/formatparse/messages +.. _`ICU MessageFormat`: https://unicode-org.github.io/icu/userguide/format_parse/messages/ .. _`switch statement`: https://www.php.net/control-structures.switch .. _`Language Plural Rules`: http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html .. _`constants defined by the IntlDateFormatter class`: https://www.php.net/manual/en/class.intldateformatter.php From 074db0d1024b99d44918ceca65b5a68c547982d0 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Tue, 17 Nov 2020 22:16:50 +0100 Subject: [PATCH 0150/5766] Complete mailer integration --- mailer.rst | 49 +++++++++++ reference/configuration/framework.rst | 116 +++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 3 deletions(-) diff --git a/mailer.rst b/mailer.rst index 025a5c43813..ebf79865a72 100644 --- a/mailer.rst +++ b/mailer.rst @@ -29,11 +29,58 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, # .env MAILER_DSN=smtp://user:pass@smtp.example.com:port +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/mailer.yaml + framework: + mailer: + dsn: '%env(MAILER_DSN)%' + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // config/packages/mailer.php + use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + return static function (ContainerConfigurator $containerConfigurator): void { + $containerConfigurator->extension('framework', [ + 'mailer' => [ + 'dsn' => '%env(MAILER_DSN)%', + ] + ]); + }; + .. caution:: If you are migrating from Swiftmailer (and the Swiftmailer bundle), be warned that the DSN format is different. +Using built-in transports +~~~~~~~~~~~~~~~~~~~~~~~~~ + +============ ==================================== =========== +DSN protocol Example Description +============ ==================================== =========== +smtp smtp://user:pass@smtp.example.com:25 Mailer uses an SMTP server to send emails +sendmail sendmail://default Mailer uses the local sendmail binary to send emails +============ ==================================== =========== + + Using a 3rd Party Transport ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -822,6 +869,8 @@ and it will select the appropriate certificate depending on the ``To`` option:: $firstEncryptedEmail = $encrypter->encrypt($firstEmail); $secondEncryptedEmail = $encrypter->encrypt($secondEmail); +.. _multiple-email-transports: + Multiple Email Transports ------------------------- diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index cd76b908c64..255adc11fec 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -98,7 +98,7 @@ Configuration * `cafile`_ * `capath`_ * `ciphers`_ - * `headers`_ + * :ref:`headers ` * `http_version`_ * `local_cert`_ * `local_pk`_ @@ -126,7 +126,7 @@ Configuration * `cafile`_ * `capath`_ * `ciphers`_ - * `headers`_ + * :ref:`headers ` * `http_version`_ * `local_cert`_ * `local_pk`_ @@ -151,6 +151,17 @@ Configuration * :ref:`name ` +* `mailer`_ + + * :ref:`dsn ` + * `transports`_ + * `envelope`_ + + * `sender`_ + * `recipients`_ + + * :ref:`headers ` + * `php_errors`_ * `log`_ @@ -159,7 +170,7 @@ Configuration * `profiler`_ * `collect`_ - * `dsn`_ + * :ref:`dsn ` * :ref:`enabled ` * `only_exceptions`_ * `only_master_requests`_ @@ -867,6 +878,8 @@ ciphers A list of the names of the ciphers allowed for the SSL/TLS connections. They can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM-SHA256'``). +.. _http-headers: + headers ....... @@ -1075,6 +1088,8 @@ only_master_requests When this is set to ``true``, the profiler will only be enabled on the master requests (and not on the subrequests). +.. _profiler-dsn: + dsn ... @@ -2888,6 +2903,101 @@ Name of the lock you want to create. decorates: lock.invoice.store arguments: ['@lock.invoice.retry_till_save.store.inner', 100, 50] +mailer +~~~~~~ + +.. _mailer-dsn: + +dsn +... + +**type**: ``string`` + +The DSN used by the mailer. When several DSN may be used, use `transports` (see below) instead. + +transports +.......... + +**type**: ``array`` + +A :ref:`list of DSN ` that can be used by the mailer. A transport name is the key and the dsn is the value. + +envelope +........ + +sender +"""""" + +**type**: ``string`` + +Sender used by the ``Mailer``. Keep in mind that this setting override a sender set in the code. + +recipients +"""""""""" + +**type**: ``array`` + +Recipients used by the ``Mailer``. Keep in mind that this setting override recipients set in the code. + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/mailer.yaml + framework: + mailer: + dsn: 'smtp://localhost:25' + envelope: + recipients: ['admin@symfony.com', 'lead@symfony.com'] + + .. code-block:: xml + + + + + + + + admin@symfony.com + lead@symfony.com + + + + + + .. code-block:: php + + // config/packages/mailer.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + return static function (ContainerConfigurator $containerConfigurator): void { + $containerConfigurator->extension('framework', [ + 'mailer' => [ + 'dsn' => 'smtp://localhost:25', + 'envelope' => [ + 'recipients' => [ + 'admin@symfony.com', + 'lead@symfony.com', + ] + ] + ] + ]); + }; + +.. _mailer-headers: + +headers +....... + +**type**: ``array`` + +Headers to add to emails. key (``name`` attribute in xml format) +is the header name and value the header value. + workflows ~~~~~~~~~ From 649a63397f9dc404294a037ef41deb48e92f3872 Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Fri, 20 Nov 2020 00:34:27 +0100 Subject: [PATCH 0151/5766] [Form] Documented legacy_error_messages --- forms.rst | 43 ++++++++++ reference/forms/types/birthday.rst | 86 ++++++++++---------- reference/forms/types/checkbox.rst | 63 ++++++++------- reference/forms/types/choice.rst | 99 ++++++++++++----------- reference/forms/types/collection.rst | 73 +++++++++-------- reference/forms/types/color.rst | 63 +++++++++------ reference/forms/types/country.rst | 85 +++++++++++--------- reference/forms/types/currency.rst | 81 ++++++++++--------- reference/forms/types/date.rst | 88 ++++++++++---------- reference/forms/types/dateinterval.rst | 94 ++++++++++++---------- reference/forms/types/datetime.rst | 106 +++++++++++++------------ reference/forms/types/email.rst | 59 ++++++++------ reference/forms/types/file.rst | 64 ++++++++------- reference/forms/types/form.rst | 94 +++++++++++----------- reference/forms/types/hidden.rst | 45 ++++++----- reference/forms/types/integer.rst | 69 ++++++++-------- reference/forms/types/language.rst | 87 ++++++++++---------- reference/forms/types/locale.rst | 83 ++++++++++--------- reference/forms/types/money.rst | 77 +++++++++--------- reference/forms/types/number.rst | 75 ++++++++--------- reference/forms/types/password.rst | 60 +++++++------- reference/forms/types/percent.rst | 75 ++++++++--------- reference/forms/types/radio.rst | 69 +++++++++------- reference/forms/types/range.rst | 57 +++++++------ reference/forms/types/repeated.rst | 63 ++++++++------- reference/forms/types/search.rst | 57 +++++++------ reference/forms/types/tel.rst | 59 ++++++++------ reference/forms/types/time.rst | 92 +++++++++++---------- reference/forms/types/timezone.rst | 85 +++++++++++--------- reference/forms/types/url.rst | 63 +++++++++------ reference/forms/types/week.rst | 74 +++++++++-------- 31 files changed, 1269 insertions(+), 1019 deletions(-) diff --git a/forms.rst b/forms.rst index ec5a04fcfc1..6e2c9ec5120 100644 --- a/forms.rst +++ b/forms.rst @@ -553,6 +553,49 @@ To see the second approach - adding constraints to the form - and to learn more about the validation constraints, please refer to the :doc:`Symfony validation documentation `. +.. versionadded:: 5.2 + + Validation messages for forms have been rewritten to be more user-friendly. + These newer messages can be enabled by setting the `legacy_error_messages` + option to "false". Details about these messages can be found in the corresponding + form type documentation. + + .. configuration-block:: + + .. code-block:: yaml + + # config/packages/framework.yaml + framework: + form: + legacy_error_messages: false + + .. code-block:: xml + + + + + + + + + + + .. code-block:: php + + // config/packages/framework.php + $container->loadFromExtension('framework', [ + 'form' => [ + 'legacy-error-messages' => false, + ], + ]); + + Other Common Form Features -------------------------- diff --git a/reference/forms/types/birthday.rst b/reference/forms/types/birthday.rst index 6299dbf1e09..127528bc774 100644 --- a/reference/forms/types/birthday.rst +++ b/reference/forms/types/birthday.rst @@ -14,51 +14,57 @@ This type is essentially the same as the :doc:`DateType `) | -+----------------------+-------------------------------------------------------------------------------+ -| Rendered as | can be three select boxes or 1 or 3 text boxes, based on the `widget`_ option | -+----------------------+-------------------------------------------------------------------------------+ -| Overridden options | - `years`_ | -+----------------------+-------------------------------------------------------------------------------+ -| Inherited options | from the :doc:`DateType `: | -| | | -| | - `choice_translation_domain`_ | -| | - `days`_ | -| | - `placeholder`_ | -| | - `format`_ | -| | - `input`_ | -| | - `input_format`_ | -| | - `model_timezone`_ | -| | - `months`_ | -| | - `view_timezone`_ | -| | - `widget`_ | -| | | -| | from the :doc:`FormType `: | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+-------------------------------------------------------------------------------+ -| Parent type | :doc:`DateType ` | -+----------------------+-------------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\BirthdayType` | -+----------------------+-------------------------------------------------------------------------------+ ++---------------------------+-------------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateTime``, ``string``, ``timestamp``, or ``array`` | +| | (see the :ref:`input option `) | ++---------------------------+-------------------------------------------------------------------------------+ +| Rendered as | can be three select boxes or 1 or 3 text boxes, based on the `widget`_ option | ++---------------------------+-------------------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | +| | - `years`_ | ++---------------------------+-------------------------------------------------------------------------------+ +| Inherited options | from the :doc:`DateType `: | +| | | +| | - `choice_translation_domain`_ | +| | - `days`_ | +| | - `placeholder`_ | +| | - `format`_ | +| | - `input`_ | +| | - `input_format`_ | +| | - `model_timezone`_ | +| | - `months`_ | +| | - `view_timezone`_ | +| | - `widget`_ | +| | | +| | from the :doc:`FormType `: | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+-------------------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid birthdate. | ++---------------------------+-------------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-------------------------------------------------------------------------------+ +| Parent type | :doc:`DateType ` | ++---------------------------+-------------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\BirthdayType` | ++---------------------------+-------------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc Overridden Options ------------------ +.. include:: /reference/forms/types/options/invalid_message.rst.inc + ``years`` ~~~~~~~~~ @@ -128,8 +134,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index aef03ef1e44..1463c542a1e 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -11,34 +11,39 @@ you can specify an array of values that, if submitted, will be evaluated to "false" as well (this differs from what HTTP defines, but can be handy if you want to handle submitted values like "0" or "false"). -+-------------+------------------------------------------------------------------------+ -| Rendered as | ``input`` ``checkbox`` field | -+-------------+------------------------------------------------------------------------+ -| Options | - `false_values`_ | -| | - `value`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | - `empty_data`_ | -+-------------+------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CheckboxType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | ``input`` ``checkbox`` field | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `false_values`_ | +| | - `value`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `empty_data`_ | +| | - `invalid_message`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | The checkbox has an invalid value. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CheckboxType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -74,6 +79,8 @@ Overridden Options .. include:: /reference/forms/types/options/checkbox_empty_data.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index 04efd2fe02c..d0c81a829bd 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -9,52 +9,57 @@ It can be rendered as a ``select`` tag, radio buttons, or checkboxes. To use this field, you must specify *either* ``choices`` or ``choice_loader`` option. -+-------------+------------------------------------------------------------------------------+ -| Rendered as | can be various tags (see below) | -+-------------+------------------------------------------------------------------------------+ -| Options | - `choices`_ | -| | - `choice_attr`_ | -| | - `choice_filter`_ | -| | - `choice_label`_ | -| | - `choice_loader`_ | -| | - `choice_name`_ | -| | - `choice_translation_domain`_ | -| | - `choice_value`_ | -| | - `expanded`_ | -| | - `group_by`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -+-------------+------------------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `trim`_ | -+-------------+------------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `by_reference`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `translation_domain`_ | -| | - `label_translation_parameters`_ | -| | - `attr_translation_parameters`_ | -| | - `help_translation_parameters`_ | -+-------------+------------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+------------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType` | -+-------------+------------------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------+ +| Rendered as | can be various tags (see below) | ++---------------------------+----------------------------------------------------------------------+ +| Options | - `choices`_ | +| | - `choice_attr`_ | +| | - `choice_filter`_ | +| | - `choice_label`_ | +| | - `choice_loader`_ | +| | - `choice_name`_ | +| | - `choice_translation_domain`_ | +| | - `choice_value`_ | +| | - `expanded`_ | +| | - `group_by`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | ++---------------------------+----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `trim`_ | +| | - `invalid_message`_ | ++---------------------------+----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `by_reference`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `translation_domain`_ | +| | - `label_translation_parameters`_ | +| | - `attr_translation_parameters`_ | +| | - `help_translation_parameters`_ | ++---------------------------+----------------------------------------------------------------------+ +| Default `invalid_message` | The selected choice is invalid. | ++---------------------------+----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ChoiceType` | ++---------------------------+----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -272,6 +277,8 @@ the parent field (the form in most cases). .. include:: /reference/forms/types/options/choice_type_trim.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index f3f0c8f4562..a30cc250f6f 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -11,37 +11,43 @@ forms, which is useful when creating forms that expose one-to-many relationships (e.g. a product from where you can manage many related product photos). -+-------------+-----------------------------------------------------------------------------+ -| Rendered as | depends on the `entry_type`_ option | -+-------------+-----------------------------------------------------------------------------+ -| Options | - `allow_add`_ | -| | - `allow_delete`_ | -| | - `delete_empty`_ | -| | - `entry_options`_ | -| | - `entry_type`_ | -| | - `prototype`_ | -| | - `prototype_data`_ | -| | - `prototype_name`_ | -+-------------+-----------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `by_reference`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+-----------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+-----------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CollectionType` | -+-------------+-----------------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------------------------+ +| Rendered as | depends on the `entry_type`_ option | ++---------------------------+--------------------------------------------------------------------------+ +| Options | - `allow_add`_ | +| | - `allow_delete`_ | +| | - `delete_empty`_ | +| | - `entry_options`_ | +| | - `entry_type`_ | +| | - `prototype`_ | +| | - `prototype_data`_ | +| | - `prototype_name`_ | ++---------------------------+--------------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+--------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `by_reference`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+--------------------------------------------------------------------------+ +| Default `invalid_message` | The collection is invalid. | ++---------------------------+--------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+--------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+--------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CollectionType` | ++---------------------------+--------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -396,6 +402,11 @@ If you have several collections in your form, or worse, nested collections you may want to change the placeholder so that unrelated placeholders are not replaced with the same value. +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst index 5dfd61915ce..f3d97c6cd1b 100644 --- a/reference/forms/types/color.rst +++ b/reference/forms/types/color.rst @@ -14,32 +14,38 @@ The value of the underlying ```` field is always a That's why it's not possible to select semi-transparent colors with this element. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``color`` field (a text box) | -+-------------+---------------------------------------------------------------------+ -| Options | - `html5`_ | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ColorType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+---------------------------------------------------------------------+ +| Rendered as | ``input`` ``color`` field (a text box) | ++---------------------------+---------------------------------------------------------------------+ +| Options | - `html5`_ | ++---------------------------+---------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+---------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+---------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid color. | ++---------------------------+---------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+---------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\ColorType` | ++---------------------------+---------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -59,6 +65,11 @@ When this option is set to ``true``, the form type checks that its value matches the `HTML5 color format`_ (``/^#[0-9a-f]{6}$/i``). If it doesn't match it, you'll see the following error message: *"This value is not a valid HTML5 color"*. +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst index f4082e498e8..a2b1527764e 100644 --- a/reference/forms/types/country.rst +++ b/reference/forms/types/country.rst @@ -18,45 +18,50 @@ Unlike the ``ChoiceType``, you don't need to specify a ``choices`` option as the field type automatically uses all of the countries of the world. You *can* specify the option manually, but then you should just use the ``ChoiceType`` directly. -+-------------+-----------------------------------------------------------------------+ -| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | -+-------------+-----------------------------------------------------------------------+ -| Options | - `alpha3`_ | -| | - `choice_translation_locale`_ | -+-------------+-----------------------------------------------------------------------+ -| Overridden | - `choices`_ | -| options | - `choice_translation_domain`_ | -+-------------+-----------------------------------------------------------------------+ -| Inherited | from the :doc:`ChoiceType ` | -| options | | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `expanded`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -| | - `trim`_ | -| | | -| | from the :doc:`FormType ` | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+-----------------------------------------------------------------------+ -| Parent type | :doc:`ChoiceType ` | -+-------------+-----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CountryType` | -+-------------+-----------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------+ +| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | ++---------------------------+-----------------------------------------------------------------------+ +| Options | - `alpha3`_ | +| | - `choice_translation_locale`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Overridden options | - `choices`_ | +| | - `choice_translation_domain`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Inherited options | from the :doc:`ChoiceType ` | +| | | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `expanded`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | +| | - `trim`_ | +| | | +| | from the :doc:`FormType ` | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid country. | ++---------------------------+-----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------+ +| Parent type | :doc:`ChoiceType ` | ++---------------------------+-----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CountryType` | ++---------------------------+-----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -92,6 +97,8 @@ The locale is used to translate the countries names. .. include:: /reference/forms/types/options/choice_translation_domain_disabled.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst index 77da0481942..e8628aa3edf 100644 --- a/reference/forms/types/currency.rst +++ b/reference/forms/types/currency.rst @@ -11,43 +11,48 @@ Unlike the ``ChoiceType``, you don't need to specify a ``choices`` option as the field type automatically uses a large list of currencies. You *can* specify the option manually, but then you should just use the ``ChoiceType`` directly. -+-------------+------------------------------------------------------------------------+ -| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | -+-------------+------------------------------------------------------------------------+ -| Options | - `choice_translation_locale`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `choices`_ | -| options | - `choice_translation_domain`_ | -+-------------+------------------------------------------------------------------------+ -| Inherited | from the :doc:`ChoiceType ` | -| options | | -| | - `error_bubbling`_ | -| | - `expanded`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -| | - `trim`_ | -| | | -| | from the :doc:`FormType ` type | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`ChoiceType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CurrencyType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `choice_translation_locale`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `choices`_ | +| | - `choice_translation_domain`_ | +| | - `invalid_message`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | from the :doc:`ChoiceType ` | +| | | +| | - `error_bubbling`_ | +| | - `expanded`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | +| | - `trim`_ | +| | | +| | from the :doc:`FormType ` type | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid currency. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`ChoiceType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\CurrencyType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -73,6 +78,8 @@ The choices option defaults to all currencies. .. include:: /reference/forms/types/options/choice_translation_domain_disabled.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst index 582b5bef6ff..fa696007803 100644 --- a/reference/forms/types/date.rst +++ b/reference/forms/types/date.rst @@ -10,46 +10,50 @@ different HTML elements. This field can be rendered in a variety of different ways via the `widget`_ option and can understand a number of different input formats via the `input`_ option. -+----------------------+-----------------------------------------------------------------------------+ -| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | -+----------------------+-----------------------------------------------------------------------------+ -| Rendered as | single text box or three select fields | -+----------------------+-----------------------------------------------------------------------------+ -| Options | - `days`_ | -| | - `placeholder`_ | -| | - `format`_ | -| | - `html5`_ | -| | - `input`_ | -| | - `input_format`_ | -| | - `model_timezone`_ | -| | - `months`_ | -| | - `view_timezone`_ | -| | - `widget`_ | -| | - `years`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Overridden options | - `by_reference`_ | -| | - `choice_translation_domain`_ | -| | - `compound`_ | -| | - `data_class`_ | -| | - `error_bubbling`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+----------------------+-----------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateType` | -+----------------------+-----------------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | ++---------------------------+-----------------------------------------------------------------------------+ +| Rendered as | single text box or three select fields | ++---------------------------+-----------------------------------------------------------------------------+ +| Options | - `days`_ | +| | - `placeholder`_ | +| | - `format`_ | +| | - `html5`_ | +| | - `input`_ | +| | - `input_format`_ | +| | - `model_timezone`_ | +| | - `months`_ | +| | - `view_timezone`_ | +| | - `widget`_ | +| | - `years`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Overridden options | - `by_reference`_ | +| | - `choice_translation_domain`_ | +| | - `compound`_ | +| | - `data_class`_ | +| | - `error_bubbling`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid date. | ++---------------------------+-----------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateType` | ++---------------------------+-----------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -210,6 +214,8 @@ The ``DateTime`` classes are treated as immutable objects. **default**: ``false`` +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -231,8 +237,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/dateinterval.rst b/reference/forms/types/dateinterval.rst index 84986f93c87..69147d95bee 100644 --- a/reference/forms/types/dateinterval.rst +++ b/reference/forms/types/dateinterval.rst @@ -12,47 +12,52 @@ The field can be rendered in a variety of different ways (see `widget`_) and can give you a ``DateInterval`` object, an `ISO 8601`_ duration string (e.g. ``P1DT12H``) or an array (see `input`_). -+----------------------+----------------------------------------------------------------------------------+ -| Underlying Data Type | can be ``DateInterval``, string or array (see the ``input`` option) | -+----------------------+----------------------------------------------------------------------------------+ -| Rendered as | single text box, multiple text boxes or select fields - see the `widget`_ option | -+----------------------+----------------------------------------------------------------------------------+ -| Options | - `days`_ | -| | - `hours`_ | -| | - `minutes`_ | -| | - `months`_ | -| | - `seconds`_ | -| | - `weeks`_ | -| | - `input`_ | -| | - `labels`_ | -| | - `placeholder`_ | -| | - `widget`_ | -| | - `with_days`_ | -| | - `with_hours`_ | -| | - `with_invert`_ | -| | - `with_minutes`_ | -| | - `with_months`_ | -| | - `with_seconds`_ | -| | - `with_weeks`_ | -| | - `with_years`_ | -| | - `years`_ | -+----------------------+----------------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+----------------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+----------------------+----------------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateIntervalType` | -+----------------------+----------------------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateInterval``, string or array (see the ``input`` option) | ++---------------------------+----------------------------------------------------------------------------------+ +| Rendered as | single text box, multiple text boxes or select fields - see the `widget`_ option | ++---------------------------+----------------------------------------------------------------------------------+ +| Options | - `days`_ | +| | - `hours`_ | +| | - `minutes`_ | +| | - `months`_ | +| | - `seconds`_ | +| | - `weeks`_ | +| | - `input`_ | +| | - `labels`_ | +| | - `placeholder`_ | +| | - `widget`_ | +| | - `with_days`_ | +| | - `with_hours`_ | +| | - `with_invert`_ | +| | - `with_minutes`_ | +| | - `with_months`_ | +| | - `with_seconds`_ | +| | - `with_weeks`_ | +| | - `with_years`_ | +| | - `years`_ | ++---------------------------+----------------------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+----------------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+----------------------------------------------------------------------------------+ +| Default `invalid_message` | Please choose a valid date interval. | ++---------------------------+----------------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+----------------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateIntervalType` | ++---------------------------+----------------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -333,6 +338,11 @@ when the ``widget`` option is set to ``choice``:: // values displayed to users range from 1 to 100 (both inclusive) 'years' => array_combine(range(1, 100), range(1, 100)), +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -352,8 +362,6 @@ These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/datetime.rst b/reference/forms/types/datetime.rst index ad56b6e2d52..ca61be3e538 100644 --- a/reference/forms/types/datetime.rst +++ b/reference/forms/types/datetime.rst @@ -10,55 +10,59 @@ date and time (e.g. ``1984-06-05 12:15:30``). Can be rendered as a text input or select tags. The underlying format of the data can be a ``DateTime`` object, a string, a timestamp or an array. -+----------------------+-----------------------------------------------------------------------------+ -| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | -+----------------------+-----------------------------------------------------------------------------+ -| Rendered as | single text box or three select fields | -+----------------------+-----------------------------------------------------------------------------+ -| Options | - `choice_translation_domain`_ | -| | - `date_format`_ | -| | - `date_label`_ | -| | - `date_widget`_ | -| | - `days`_ | -| | - `placeholder`_ | -| | - `format`_ | -| | - `hours`_ | -| | - `html5`_ | -| | - `input`_ | -| | - `input_format`_ | -| | - `minutes`_ | -| | - `model_timezone`_ | -| | - `months`_ | -| | - `seconds`_ | -| | - `time_label`_ | -| | - `time_widget`_ | -| | - `view_timezone`_ | -| | - `widget`_ | -| | - `with_minutes`_ | -| | - `with_seconds`_ | -| | - `years`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Overridden options | - `by_reference`_ | -| | - `compound`_ | -| | - `data_class`_ | -| | - `error_bubbling`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+----------------------+-----------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateTimeType` | -+----------------------+-----------------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | ++---------------------------+-----------------------------------------------------------------------------+ +| Rendered as | single text box or three select fields | ++---------------------------+-----------------------------------------------------------------------------+ +| Options | - `choice_translation_domain`_ | +| | - `date_format`_ | +| | - `date_label`_ | +| | - `date_widget`_ | +| | - `days`_ | +| | - `placeholder`_ | +| | - `format`_ | +| | - `hours`_ | +| | - `html5`_ | +| | - `input`_ | +| | - `input_format`_ | +| | - `minutes`_ | +| | - `model_timezone`_ | +| | - `months`_ | +| | - `seconds`_ | +| | - `time_label`_ | +| | - `time_widget`_ | +| | - `view_timezone`_ | +| | - `widget`_ | +| | - `with_minutes`_ | +| | - `with_seconds`_ | +| | - `years`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Overridden options | - `by_reference`_ | +| | - `compound`_ | +| | - `data_class`_ | +| | - `error_bubbling`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid date and time. | ++---------------------------+-----------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\DateTimeType` | ++---------------------------+-----------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -231,6 +235,8 @@ error_bubbling **default**: ``false`` +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -250,8 +256,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index 74eeaa95272..31d6f5db90b 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -7,33 +7,44 @@ EmailType Field The ``EmailType`` field is a text field that is rendered using the HTML5 ```` tag. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``email`` field (a text box) | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\EmailType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+---------------------------------------------------------------------+ +| Rendered as | ``input`` ``email`` field (a text box) | ++---------------------------+---------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+---------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+---------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid email address. | ++---------------------------+---------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+---------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\EmailType` | ++---------------------------+---------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index 66a18560577..f745c9bc1fd 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -6,33 +6,38 @@ FileType Field The ``FileType`` represents a file input in your form. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``file`` field | -+-------------+---------------------------------------------------------------------+ -| Options | - `multiple`_ | -+-------------+---------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | - `data_class`_ | -| | - `empty_data`_ | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `disabled`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------------------+ +| Rendered as | ``input`` ``file`` field | ++---------------------------+--------------------------------------------------------------------+ +| Options | - `multiple`_ | ++---------------------------+--------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `data_class`_ | +| | - `empty_data`_ | +| | - `invalid_message`_ | ++---------------------------+--------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `disabled`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+--------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid file. | ++---------------------------+--------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+--------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+--------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FileType` | ++---------------------------+--------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -120,6 +125,11 @@ This option sets the appropriate file-related data mapper to be used by the type This option determines what value the field will return when the submitted value is empty. +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index 8a0c219f410..e406413bf37 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -7,51 +7,55 @@ FormType Field The ``FormType`` predefines a couple of options that are then available on all types for which ``FormType`` is the parent. -+-----------+--------------------------------------------------------------------+ -| Options | - `action`_ | -| | - `allow_extra_fields`_ | -| | - `by_reference`_ | -| | - `compound`_ | -| | - `constraints`_ | -| | - `data`_ | -| | - `data_class`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `extra_fields_message`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `help_translation_parameters`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `method`_ | -| | - `post_max_size_message`_ | -| | - `property_path`_ | -| | - `required`_ | -| | - `trim`_ | -| | - `validation_groups`_ | -+-----------+--------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `auto_initialize`_ | -| | - `block_name`_ | -| | - `block_prefix`_ | -| | - `disabled`_ | -| | - `label`_ | -| | - `label_html`_ | -| | - `row_attr`_ | -| | - `translation_domain`_ | -| | - `label_translation_parameters`_ | -| | - `attr_translation_parameters`_ | -+-----------+--------------------------------------------------------------------+ -| Parent | none | -+-----------+--------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType` | -+-----------+--------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------------------+ +| Options | - `action`_ | +| | - `allow_extra_fields`_ | +| | - `by_reference`_ | +| | - `compound`_ | +| | - `constraints`_ | +| | - `data`_ | +| | - `data_class`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `extra_fields_message`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `help_translation_parameters`_ | +| | - `inherit_data`_ | +| | - `invalid_message`_ | +| | - `invalid_message_parameters`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `method`_ | +| | - `post_max_size_message`_ | +| | - `property_path`_ | +| | - `required`_ | +| | - `trim`_ | +| | - `validation_groups`_ | ++---------------------------+--------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `auto_initialize`_ | +| | - `block_name`_ | +| | - `block_prefix`_ | +| | - `disabled`_ | +| | - `label`_ | +| | - `label_html`_ | +| | - `row_attr`_ | +| | - `translation_domain`_ | +| | - `label_translation_parameters`_ | +| | - `attr_translation_parameters`_ | ++---------------------------+--------------------------------------------------------------------+ +| 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` | ++---------------------------+--------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc diff --git a/reference/forms/types/hidden.rst b/reference/forms/types/hidden.rst index 1a74e107555..f0bddfa4260 100644 --- a/reference/forms/types/hidden.rst +++ b/reference/forms/types/hidden.rst @@ -6,25 +6,30 @@ HiddenType Field The hidden type represents a hidden input field. -+-------------+----------------------------------------------------------------------+ -| Rendered as | ``input`` ``hidden`` field | -+-------------+----------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | - `error_bubbling`_ | -| | - `required`_ | -+-------------+----------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `empty_data`_ | -| | - `error_mapping`_ | -| | - `mapped`_ | -| | - `property_path`_ | -| | - `row_attr`_ | -+-------------+----------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\HiddenType` | -+-------------+----------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------+ +| Rendered as | ``input`` ``hidden`` field | ++---------------------------+----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `error_bubbling`_ | +| | - `invalid_message`_ | +| | - `required`_ | ++---------------------------+----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `empty_data`_ | +| | - `error_mapping`_ | +| | - `mapped`_ | +| | - `property_path`_ | +| | - `row_attr`_ | ++---------------------------+----------------------------------------------------------------------+ +| Default `invalid_message` | The hidden field is invalid. | ++---------------------------+----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\HiddenType` | ++---------------------------+----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -40,6 +45,8 @@ Overridden Options Pass errors to the root form, otherwise they will not be visible. +.. include:: /reference/forms/types/options/invalid_message.rst.inc + ``required`` ~~~~~~~~~~~~ diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index fa5660158bc..7eb32abf7f9 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -13,37 +13,40 @@ This field has different options on how to handle input values that aren't integers. By default, all non-integer values (e.g. 6.78) will round down (e.g. 6). -+-------------+-----------------------------------------------------------------------+ -| Rendered as | ``input`` ``number`` field | -+-------------+-----------------------------------------------------------------------+ -| Options | - `grouping`_ | -| | - `rounding_mode`_ | -+-------------+-----------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | | -+-------------+-----------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+-----------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+-----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\IntegerType` | -+-------------+-----------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------+ +| Rendered as | ``input`` ``number`` field | ++---------------------------+-----------------------------------------------------------------------+ +| Options | - `grouping`_ | +| | - `rounding_mode`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Default `invalid_message` | Please enter an integer. | ++---------------------------+-----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\IntegerType` | ++---------------------------+-----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -86,6 +89,8 @@ Overridden Options .. include:: /reference/forms/types/options/compound_type.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -115,8 +120,6 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/help_html.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/label.rst.inc diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst index 5fa38697701..420ab1b59a0 100644 --- a/reference/forms/types/language.rst +++ b/reference/forms/types/language.rst @@ -20,46 +20,51 @@ Unlike the ``ChoiceType``, you don't need to specify a ``choices`` option as the field type automatically uses a large list of languages. You *can* specify the option manually, but then you should just use the ``ChoiceType`` directly. -+-------------+------------------------------------------------------------------------+ -| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | -+-------------+------------------------------------------------------------------------+ -| Options | - `alpha3`_ | -| | - `choice_self_translation`_ | -| | - `choice_translation_locale`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `choices`_ | -| options | - `choice_translation_domain`_ | -+-------------+------------------------------------------------------------------------+ -| Inherited | from the :doc:`ChoiceType ` | -| options | | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `expanded`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -| | - `trim`_ | -| | | -| | from the :doc:`FormType ` | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`ChoiceType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LanguageType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `alpha3`_ | +| | - `choice_self_translation`_ | +| | - `choice_translation_locale`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `choices`_ | +| | - `choice_translation_domain`_ | +| | - `invalid_message`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | from the :doc:`ChoiceType ` | +| | | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `expanded`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | +| | - `trim`_ | +| | | +| | from the :doc:`FormType ` | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid language. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`ChoiceType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LanguageType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -114,6 +119,8 @@ The default locale is used to translate the languages names. .. include:: /reference/forms/types/options/choice_translation_domain_disabled.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst index 385cc4f6fd8..be6dde7e950 100644 --- a/reference/forms/types/locale.rst +++ b/reference/forms/types/locale.rst @@ -21,44 +21,49 @@ Unlike the ``ChoiceType``, you don't need to specify a ``choices`` option as the field type automatically uses a large list of locales. You *can* specify these options manually, but then you should just use the ``ChoiceType`` directly. -+-------------+------------------------------------------------------------------------+ -| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | -+-------------+------------------------------------------------------------------------+ -| Options | - `choice_translation_locale`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `choices`_ | -| options | - `choice_translation_domain`_ | -+-------------+------------------------------------------------------------------------+ -| Inherited | from the :doc:`ChoiceType ` | -| options | | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `expanded`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -| | - `trim`_ | -| | | -| | from the :doc:`FormType ` | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`ChoiceType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LocaleType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------+ +| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | ++---------------------------+----------------------------------------------------------------------+ +| Options | - `choice_translation_locale`_ | ++---------------------------+----------------------------------------------------------------------+ +| Overridden options | - `choices`_ | +| | - `choice_translation_domain`_ | +| | - `invalid_message`_ | ++---------------------------+----------------------------------------------------------------------+ +| Inherited options | from the :doc:`ChoiceType ` | +| | | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `expanded`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | +| | - `trim`_ | +| | | +| | from the :doc:`FormType ` | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+----------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid locale. | ++---------------------------+----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------+ +| Parent type | :doc:`ChoiceType ` | ++---------------------------+----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\LocaleType` | ++---------------------------+----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -85,6 +90,8 @@ specify the language. .. include:: /reference/forms/types/options/choice_translation_domain_disabled.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst index bb91d0b08da..ca7a5aceac7 100644 --- a/reference/forms/types/money.rst +++ b/reference/forms/types/money.rst @@ -11,41 +11,44 @@ This field type allows you to specify a currency, whose symbol is rendered next to the text field. There are also several other options for customizing how the input and output of the data is handled. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``text`` field | -+-------------+---------------------------------------------------------------------+ -| Options | - `currency`_ | -| | - `divisor`_ | -| | - `grouping`_ | -| | - `html5`_ | -| | - `rounding_mode`_ | -| | - `scale`_ | -+-------------+---------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\MoneyType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+---------------------------------------------------------------------+ +| Rendered as | ``input`` ``text`` field | ++---------------------------+---------------------------------------------------------------------+ +| Options | - `currency`_ | +| | - `divisor`_ | +| | - `grouping`_ | +| | - `html5`_ | +| | - `rounding_mode`_ | +| | - `scale`_ | ++---------------------------+---------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+---------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+---------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid money amount. | ++---------------------------+---------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+---------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\MoneyType` | ++---------------------------+---------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -122,6 +125,8 @@ Overridden Options .. include:: /reference/forms/types/options/compound_type.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -151,8 +156,6 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/help_html.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/label.rst.inc diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst index 599d0efa4cd..319c84b951e 100644 --- a/reference/forms/types/number.rst +++ b/reference/forms/types/number.rst @@ -8,40 +8,43 @@ Renders an input text field and specializes in handling number input. This type offers different options for the scale, rounding and grouping that you want to use for your number. -+-------------+----------------------------------------------------------------------+ -| Rendered as | ``input`` ``text`` field | -+-------------+----------------------------------------------------------------------+ -| Options | - `grouping`_ | -| | - `html5`_ | -| | - `input`_ | -| | - `scale`_ | -| | - `rounding_mode`_ | -+-------------+----------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | | -+-------------+----------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+----------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\NumberType` | -+-------------+----------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------+ +| Rendered as | ``input`` ``text`` field | ++---------------------------+----------------------------------------------------------------------+ +| Options | - `grouping`_ | +| | - `html5`_ | +| | - `input`_ | +| | - `scale`_ | +| | - `rounding_mode`_ | ++---------------------------+----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+----------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a number. | ++---------------------------+----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\NumberType` | ++---------------------------+----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -86,6 +89,8 @@ Overridden Options .. include:: /reference/forms/types/options/compound_type.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -115,8 +120,6 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/help_html.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/label.rst.inc diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst index 37acff1a616..10b38a5ac8b 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -6,33 +6,37 @@ PasswordType Field The ``PasswordType`` field renders an input password text box. -+-------------+------------------------------------------------------------------------+ -| Rendered as | ``input`` ``password`` field | -+-------------+------------------------------------------------------------------------+ -| Options | - `always_empty`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `trim`_ | -| options | | -+-------------+------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PasswordType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | ``input`` ``password`` field | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `always_empty`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | +| | - `trim`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | The password is invalid. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PasswordType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -54,6 +58,8 @@ entered into the box, set this to false and submit the form. Overridden Options ------------------ +.. include:: /reference/forms/types/options/invalid_message.rst.inc + ``trim`` ~~~~~~~~ diff --git a/reference/forms/types/percent.rst b/reference/forms/types/percent.rst index 4b21f1f2856..3dd47e1d320 100644 --- a/reference/forms/types/percent.rst +++ b/reference/forms/types/percent.rst @@ -12,40 +12,43 @@ you can use this field out-of-the-box. If you store your data as a number When ``symbol`` is not ``false``, the field will render the given string after the input. -+-------------+-----------------------------------------------------------------------+ -| Rendered as | ``input`` ``text`` field | -+-------------+-----------------------------------------------------------------------+ -| Options | - `html5`_ | -| | - `rounding_mode`_ | -| | - `scale`_ | -| | - `symbol`_ | -| | - `type`_ | -+-------------+-----------------------------------------------------------------------+ -| Overridden | - `compound`_ | -| options | | -+-------------+-----------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+-----------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+-----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PercentType` | -+-------------+-----------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------+ +| Rendered as | ``input`` ``text`` field | ++---------------------------+-----------------------------------------------------------------------+ +| Options | - `html5`_ | +| | - `rounding_mode`_ | +| | - `scale`_ | +| | - `symbol`_ | +| | - `type`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a percentage value. | ++---------------------------+-----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\PercentType` | ++---------------------------+-----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -115,6 +118,8 @@ Overridden Options .. include:: /reference/forms/types/options/compound_type.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -144,8 +149,6 @@ The default value is ``''`` (the empty string). .. include:: /reference/forms/types/options/help_html.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/label.rst.inc diff --git a/reference/forms/types/radio.rst b/reference/forms/types/radio.rst index ae0d58d2fe4..579dab0bc1d 100644 --- a/reference/forms/types/radio.rst +++ b/reference/forms/types/radio.rst @@ -13,38 +13,49 @@ The ``RadioType`` isn't usually used directly. More commonly it's used internally by other types such as :doc:`ChoiceType `. If you want to have a boolean field, use :doc:`CheckboxType `. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``radio`` field | -+-------------+---------------------------------------------------------------------+ -| Inherited | from the :doc:`CheckboxType `: | -| options | | -| | - `value`_ | -| | | -| | from the :doc:`FormType `: | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`CheckboxType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RadioType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+---------------------------------------------------------------------+ +| Rendered as | ``input`` ``radio`` field | ++---------------------------+---------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+---------------------------------------------------------------------+ +| Inherited options | from the :doc:`CheckboxType `: | +| | | +| | - `value`_ | +| | | +| | from the :doc:`FormType `: | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+---------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid option. | ++---------------------------+---------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+---------------------------------------------------------------------+ +| Parent type | :doc:`CheckboxType ` | ++---------------------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RadioType` | ++---------------------------+---------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/range.rst b/reference/forms/types/range.rst index e328a1bbe97..ab3a0d15859 100644 --- a/reference/forms/types/range.rst +++ b/reference/forms/types/range.rst @@ -7,29 +7,35 @@ RangeType Field The ``RangeType`` field is a slider that is rendered using the HTML5 ```` tag. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``range`` field (slider in HTML5 supported browser) | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RangeType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+---------------------------------------------------------------------+ +| Rendered as | ``input`` ``range`` field (slider in HTML5 supported browser) | ++---------------------------+---------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+---------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+---------------------------------------------------------------------+ +| Default `invalid_message` | Please choose a valid range. | ++---------------------------+---------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+---------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+---------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RangeType` | ++---------------------------+---------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -48,6 +54,11 @@ Basic Usage ] ]); +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/repeated.rst b/reference/forms/types/repeated.rst index c78e6cc318e..7a9f6d9d9be 100644 --- a/reference/forms/types/repeated.rst +++ b/reference/forms/types/repeated.rst @@ -9,34 +9,37 @@ values must match (or a validation error is thrown). The most common use is when you need the user to repeat their password or email to verify accuracy. -+-------------+------------------------------------------------------------------------+ -| Rendered as | input ``text`` field by default, but see `type`_ option | -+-------------+------------------------------------------------------------------------+ -| Options | - `first_name`_ | -| | - `first_options`_ | -| | - `options`_ | -| | - `second_name`_ | -| | - `second_options`_ | -| | - `type`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `error_bubbling`_ | -| options | | -+-------------+------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RepeatedType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | input ``text`` field by default, but see `type`_ option | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `first_name`_ | +| | - `first_options`_ | +| | - `options`_ | +| | - `second_name`_ | +| | - `second_options`_ | +| | - `type`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `error_bubbling`_ | +| | - `invalid_message`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | The values do not match. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RepeatedType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -184,6 +187,8 @@ Overridden Options **default**: ``false`` +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -201,8 +206,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/help_html.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/search.rst b/reference/forms/types/search.rst index e0f8233aa5b..f9c53733872 100644 --- a/reference/forms/types/search.rst +++ b/reference/forms/types/search.rst @@ -9,32 +9,43 @@ special functionality supported by some browsers. Read about the input search field at `DiveIntoHTML5.info`_ -+-------------+----------------------------------------------------------------------+ -| Rendered as | ``input search`` field | -+-------------+----------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+----------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+----------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\SearchType` | -+-------------+----------------------------------------------------------------------+ ++---------------------------+----------------------------------------------------------------------+ +| Rendered as | ``input search`` field | ++---------------------------+----------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+----------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid search term. | ++---------------------------+----------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+----------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\SearchType` | ++---------------------------+----------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/tel.rst b/reference/forms/types/tel.rst index f6c19391ada..fc45434bc4e 100644 --- a/reference/forms/types/tel.rst +++ b/reference/forms/types/tel.rst @@ -13,33 +13,44 @@ Nevertheless, it may be useful to use this type in web applications because some browsers (e.g. smartphone browsers) adapt the input keyboard to make it easier to input phone numbers. -+-------------+---------------------------------------------------------------------+ -| Rendered as | ``input`` ``tel`` field (a text box) | -+-------------+---------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+---------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+---------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TelType` | -+-------------+---------------------------------------------------------------------+ ++---------------------------+-------------------------------------------------------------------+ +| Rendered as | ``input`` ``tel`` field (a text box) | ++---------------------------+-------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+-------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+-------------------------------------------------------------------+ +| Default `invalid_message` | Please provide a valid phone number. | ++---------------------------+-------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+-------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TelType` | ++---------------------------+-------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/time.rst b/reference/forms/types/time.rst index 042e3e7da0c..08c3efb77f4 100644 --- a/reference/forms/types/time.rst +++ b/reference/forms/types/time.rst @@ -10,48 +10,52 @@ This can be rendered as a text field, a series of text fields (e.g. hour, minute, second) or a series of select fields. The underlying data can be stored as a ``DateTime`` object, a string, a timestamp or an array. -+----------------------+-----------------------------------------------------------------------------+ -| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | -+----------------------+-----------------------------------------------------------------------------+ -| Rendered as | can be various tags (see below) | -+----------------------+-----------------------------------------------------------------------------+ -| Options | - `choice_translation_domain`_ | -| | - `placeholder`_ | -| | - `hours`_ | -| | - `html5`_ | -| | - `input`_ | -| | - `input_format`_ | -| | - `minutes`_ | -| | - `model_timezone`_ | -| | - `reference_date`_ | -| | - `seconds`_ | -| | - `view_timezone`_ | -| | - `widget`_ | -| | - `with_minutes`_ | -| | - `with_seconds`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Overridden options | - `by_reference`_ | -| | - `compound`_ | -| | - `data_class`_ | -| | - `error_bubbling`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Parent type | FormType | -+----------------------+-----------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TimeType` | -+----------------------+-----------------------------------------------------------------------------+ ++---------------------------+-----------------------------------------------------------------------------+ +| Underlying Data Type | can be ``DateTime``, string, timestamp, or array (see the ``input`` option) | ++---------------------------+-----------------------------------------------------------------------------+ +| Rendered as | can be various tags (see below) | ++---------------------------+-----------------------------------------------------------------------------+ +| Options | - `choice_translation_domain`_ | +| | - `placeholder`_ | +| | - `hours`_ | +| | - `html5`_ | +| | - `input`_ | +| | - `input_format`_ | +| | - `minutes`_ | +| | - `model_timezone`_ | +| | - `reference_date`_ | +| | - `seconds`_ | +| | - `view_timezone`_ | +| | - `widget`_ | +| | - `with_minutes`_ | +| | - `with_seconds`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Overridden options | - `by_reference`_ | +| | - `compound`_ | +| | - `data_class`_ | +| | - `error_bubbling`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------------+ +| 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` | ++---------------------------+-----------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -220,6 +224,8 @@ error_bubbling **default**: ``false`` +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -241,8 +247,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc diff --git a/reference/forms/types/timezone.rst b/reference/forms/types/timezone.rst index c18cdbaf339..64e17890de8 100644 --- a/reference/forms/types/timezone.rst +++ b/reference/forms/types/timezone.rst @@ -14,45 +14,50 @@ Unlike the ``ChoiceType``, you don't need to specify a ``choices`` option as the field type automatically uses a large list of timezones. You *can* specify the option manually, but then you should just use the ``ChoiceType`` directly. -+-------------+------------------------------------------------------------------------+ -| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | -+-------------+------------------------------------------------------------------------+ -| Options | - `input`_ | -| | - `intl`_ | -+-------------+------------------------------------------------------------------------+ -| Overridden | - `choices`_ | -| options | - `choice_translation_domain`_ | -+-------------+------------------------------------------------------------------------+ -| Inherited | from the :doc:`ChoiceType ` | -| options | | -| | - `expanded`_ | -| | - `multiple`_ | -| | - `placeholder`_ | -| | - `preferred_choices`_ | -| | - `trim`_ | -| | | -| | from the :doc:`FormType ` | -| | | -| | - `attr`_ | -| | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -+-------------+------------------------------------------------------------------------+ -| Parent type | :doc:`ChoiceType ` | -+-------------+------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TimezoneType` | -+-------------+------------------------------------------------------------------------+ ++---------------------------+------------------------------------------------------------------------+ +| Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | ++---------------------------+------------------------------------------------------------------------+ +| Options | - `input`_ | +| | - `intl`_ | ++---------------------------+------------------------------------------------------------------------+ +| Overridden options | - `choices`_ | +| | - `choice_translation_domain`_ | +| | - `invalid_message`_ | ++---------------------------+------------------------------------------------------------------------+ +| Inherited options | from the :doc:`ChoiceType ` | +| | | +| | - `expanded`_ | +| | - `multiple`_ | +| | - `placeholder`_ | +| | - `preferred_choices`_ | +| | - `trim`_ | +| | | +| | from the :doc:`FormType ` | +| | | +| | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+------------------------------------------------------------------------+ +| Default `invalid_message` | Please select a valid timezone. | ++---------------------------+------------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+------------------------------------------------------------------------+ +| Parent type | :doc:`ChoiceType ` | ++---------------------------+------------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\TimezoneType` | ++---------------------------+------------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -107,6 +112,8 @@ The Timezone type defaults the choices to all timezones returned by .. include:: /reference/forms/types/options/choice_translation_domain_disabled.rst.inc +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst index a03f1532021..e5f782ce088 100644 --- a/reference/forms/types/url.rst +++ b/reference/forms/types/url.rst @@ -8,32 +8,38 @@ The ``UrlType`` field is a text field that prepends the submitted value with a given protocol (e.g. ``http://``) if the submitted value doesn't already have a protocol. -+-------------+-------------------------------------------------------------------+ -| Rendered as | ``input url`` field | -+-------------+-------------------------------------------------------------------+ -| Options | - `default_protocol`_ | -+-------------+-------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -| | - `error_mapping`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `label`_ | -| | - `label_attr`_ | -| | - `label_format`_ | -| | - `mapped`_ | -| | - `required`_ | -| | - `row_attr`_ | -| | - `trim`_ | -+-------------+-------------------------------------------------------------------+ -| Parent type | :doc:`TextType ` | -+-------------+-------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UrlType` | -+-------------+-------------------------------------------------------------------+ ++---------------------------+-------------------------------------------------------------------+ +| Rendered as | ``input url`` field | ++---------------------------+-------------------------------------------------------------------+ +| Options | - `default_protocol`_ | ++---------------------------+-------------------------------------------------------------------+ +| Overridden options | - `invalid_message`_ | ++---------------------------+-------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | +| | - `trim`_ | ++---------------------------+-------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid URL. | ++---------------------------+-------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+-------------------------------------------------------------------+ +| Parent type | :doc:`TextType ` | ++---------------------------+-------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UrlType` | ++---------------------------+-------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -49,6 +55,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. +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- diff --git a/reference/forms/types/week.rst b/reference/forms/types/week.rst index 6967df09bb7..eb526c160af 100644 --- a/reference/forms/types/week.rst +++ b/reference/forms/types/week.rst @@ -10,39 +10,43 @@ This field type allows the user to modify data that represents a specific Can be rendered as a text input or select tags. The underlying format of the data can be a string or an array. -+----------------------+-----------------------------------------------------------------------------+ -| Underlying Data Type | can be a string, or array (see the ``input`` option) | -+----------------------+-----------------------------------------------------------------------------+ -| Rendered as | single text box, two text boxes or two select fields | -+----------------------+-----------------------------------------------------------------------------+ -| Options | - `choice_translation_domain`_ | -| | - `placeholder`_ | -| | - `html5`_ | -| | - `input`_ | -| | - `widget`_ | -| | - `weeks`_ | -| | - `years`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Overridden options | - `compound`_ | -| | - `empty_data`_ | -| | - `error_bubbling`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Inherited | - `attr`_ | -| options | - `data`_ | -| | - `disabled`_ | -| | - `help`_ | -| | - `help_attr`_ | -| | - `help_html`_ | -| | - `inherit_data`_ | -| | - `invalid_message`_ | -| | - `invalid_message_parameters`_ | -| | - `mapped`_ | -| | - `row_attr`_ | -+----------------------+-----------------------------------------------------------------------------+ -| Parent type | :doc:`FormType ` | -+----------------------+-----------------------------------------------------------------------------+ -| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\WeekType` | -+----------------------+-----------------------------------------------------------------------------+ ++---------------------------+--------------------------------------------------------------------+ +| Underlying Data Type | can be a string, or array (see the ``input`` option) | ++---------------------------+--------------------------------------------------------------------+ +| Rendered as | single text box, two text boxes or two select fields | ++---------------------------+--------------------------------------------------------------------+ +| Options | - `choice_translation_domain`_ | +| | - `placeholder`_ | +| | - `html5`_ | +| | - `input`_ | +| | - `widget`_ | +| | - `weeks`_ | +| | - `years`_ | ++---------------------------+--------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `invalid_message`_ | ++---------------------------+--------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `inherit_data`_ | +| | - `invalid_message_parameters`_ | +| | - `mapped`_ | +| | - `row_attr`_ | ++---------------------------+--------------------------------------------------------------------+ +| Default `invalid_message` | Please enter a valid week. | ++---------------------------+--------------------------------------------------------------------+ +| Legacy `invalid_message` | The value {{ value }} is not valid. | ++---------------------------+--------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+--------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\WeekType` | ++---------------------------+--------------------------------------------------------------------+ .. include:: /reference/forms/types/options/_debug_form.rst.inc @@ -138,6 +142,8 @@ error_bubbling **default**: ``false`` +.. include:: /reference/forms/types/options/invalid_message.rst.inc + Inherited Options ----------------- @@ -157,8 +163,6 @@ These options inherit from the :doc:`FormType `: .. include:: /reference/forms/types/options/inherit_data.rst.inc -.. include:: /reference/forms/types/options/invalid_message.rst.inc - .. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc .. include:: /reference/forms/types/options/mapped.rst.inc From 3daed4a14bfeafe81b4af834778b3ff81b758dfe Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 20 Nov 2020 09:02:29 +0100 Subject: [PATCH 0152/5766] Enhancement: New rule for DOCtor-RST --- .doctor-rst.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 52a1fc2ba4a..22269873776 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -20,6 +20,7 @@ rules: no_blank_line_after_filepath_in_yaml_code_block: ~ no_brackets_in_method_directive: ~ no_composer_req: ~ + no_directive_after_shorthand: ~ no_explicit_use_of_code_block_php: ~ no_inheritdoc: ~ no_namespace_after_use_statements: ~ From 92477a8754a84b4518234bfdd28c5fbd793a0e81 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 20 Nov 2020 09:13:15 +0100 Subject: [PATCH 0153/5766] Enhancement: Use actions/cache v2 cc @smoench --- .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 dd7599889d0..881b171ce10 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -98,7 +98,7 @@ jobs: id: extract_base_branch - name: "Cache DOCtor-RST" - uses: actions/cache@v1 + uses: actions/cache@v2 with: path: .cache key: ${{ runner.os }}-doctor-rst-${{ steps.extract_base_branch.outputs.branch }} From ff816cadc7ef69791ae3cff961055824df2e5c4e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 20 Nov 2020 09:45:20 +0100 Subject: [PATCH 0154/5766] Enhancement: New rule for DOCtor-RST --- .doctor-rst.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 22269873776..59971c508f4 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -6,6 +6,7 @@ rules: composer_dev_option_not_at_the_end: ~ correct_code_block_directive_based_on_the_content: ~ deprecated_directive_should_have_version: ~ + ensure_exactly_one_space_between_link_definition_and_link: ~ ensure_order_of_code_blocks_in_configuration_block: ~ extend_abstract_controller: ~ extension_xlf_instead_of_xliff: ~ From 289ca7c128f4c413f75a0606cc54f9833130e5c1 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 20 Nov 2020 10:08:28 +0100 Subject: [PATCH 0155/5766] Fix: DOCtor-RST build --- http_client.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/http_client.rst b/http_client.rst index 2fb102a0fcc..b46a3f7760d 100644 --- a/http_client.rst +++ b/http_client.rst @@ -1616,5 +1616,5 @@ Then configure Symfony to use your callback: .. _`amphp/http-client`: https://packagist.org/packages/amphp/http-client .. _`cURL options`: https://www.php.net/manual/en/function.curl-setopt.php .. _`Server-sent events`: https://html.spec.whatwg.org/multipage/server-sent-events.html -.. _`EventSource`: https://www.w3.org/TR/eventsource/#eventsource -.. _`idempotent method`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods_and_web_applications +.. _`EventSource`: https://www.w3.org/TR/eventsource/#eventsource +.. _`idempotent method`: https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Idempotent_methods_and_web_applications From 12fff0cf5ec2a195709c5ac1ccbad8e04da6bef1 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 20 Nov 2020 09:45:20 +0100 Subject: [PATCH 0156/5766] Enhancement: New rule for DOCtor-RST --- .doctor-rst.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 5c4fadeb132..94d88088d52 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -6,6 +6,7 @@ rules: composer_dev_option_not_at_the_end: ~ correct_code_block_directive_based_on_the_content: ~ deprecated_directive_should_have_version: ~ + ensure_exactly_one_space_between_link_definition_and_link: ~ ensure_order_of_code_blocks_in_configuration_block: ~ extend_abstract_controller: ~ extension_xlf_instead_of_xliff: ~ From 26dfa839ad7242522a97968096403c5801852424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Barray?= Date: Fri, 20 Nov 2020 14:01:55 +0100 Subject: [PATCH 0157/5766] [Messenger] Add mention about serialize in inMemory transport dsn --- messenger.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/messenger.rst b/messenger.rst index ac07b40c624..e5a4da76cf9 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1295,6 +1295,15 @@ during a request:: :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase` or :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase`. +.. tip:: + + Using ``in-memory://?serialize=true`` as dsn will perform message serialization as real asynchronous transport will do. + Useful to test an additional layer, especially when you use your own message serializer. + +.. versionadded:: 5.3 + + The ``in-memory://?serialize=true`` dsn was introduced in Symfony 5.3. + Amazon SQS ~~~~~~~~~~ From 0ccfa6e913782c1788e08032ebfcf14968e72b96 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 20 Nov 2020 15:55:35 +0100 Subject: [PATCH 0158/5766] Tweaks --- forms.rst | 8 +++----- reference/forms/types/birthday.rst | 4 ++-- reference/forms/types/checkbox.rst | 4 ++-- reference/forms/types/choice.rst | 4 ++-- reference/forms/types/collection.rst | 4 ++-- reference/forms/types/color.rst | 4 ++-- reference/forms/types/country.rst | 4 ++-- reference/forms/types/currency.rst | 4 ++-- reference/forms/types/date.rst | 4 ++-- reference/forms/types/dateinterval.rst | 4 ++-- reference/forms/types/datetime.rst | 4 ++-- reference/forms/types/email.rst | 4 ++-- reference/forms/types/file.rst | 4 ++-- reference/forms/types/form.rst | 4 ++-- reference/forms/types/hidden.rst | 4 ++-- reference/forms/types/integer.rst | 4 ++-- reference/forms/types/language.rst | 4 ++-- reference/forms/types/locale.rst | 4 ++-- reference/forms/types/money.rst | 4 ++-- reference/forms/types/number.rst | 4 ++-- reference/forms/types/password.rst | 4 ++-- reference/forms/types/percent.rst | 4 ++-- reference/forms/types/radio.rst | 4 ++-- reference/forms/types/range.rst | 4 ++-- reference/forms/types/repeated.rst | 4 ++-- reference/forms/types/search.rst | 4 ++-- reference/forms/types/tel.rst | 4 ++-- reference/forms/types/time.rst | 4 ++-- reference/forms/types/timezone.rst | 4 ++-- reference/forms/types/url.rst | 4 ++-- reference/forms/types/week.rst | 4 ++-- 31 files changed, 63 insertions(+), 65 deletions(-) diff --git a/forms.rst b/forms.rst index 6e2c9ec5120..8635b8fedbd 100644 --- a/forms.rst +++ b/forms.rst @@ -555,10 +555,9 @@ learn more about the validation constraints, please refer to the .. versionadded:: 5.2 - Validation messages for forms have been rewritten to be more user-friendly. - These newer messages can be enabled by setting the `legacy_error_messages` - option to "false". Details about these messages can be found in the corresponding - form type documentation. + In Symfony 5.2, the form validation messages have been rewritten to be more + user-friendly. Set the ``legacy_error_messages`` option to ``false`` to + enable these new messages: .. configuration-block:: @@ -595,7 +594,6 @@ learn more about the validation constraints, please refer to the ], ]); - Other Common Form Features -------------------------- diff --git a/reference/forms/types/birthday.rst b/reference/forms/types/birthday.rst index 127528bc774..94cff698cb4 100644 --- a/reference/forms/types/birthday.rst +++ b/reference/forms/types/birthday.rst @@ -49,9 +49,9 @@ option defaults to 120 years ago to the current year. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+-------------------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid birthdate. | +| Default invalid message | Please enter a valid birthdate. | +---------------------------+-------------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-------------------------------------------------------------------------------+ | Parent type | :doc:`DateType ` | +---------------------------+-------------------------------------------------------------------------------+ diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index 1463c542a1e..d4fdd17580c 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -36,9 +36,9 @@ if you want to handle submitted values like "0" or "false"). | | - `required`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | The checkbox has an invalid value. | +| Default invalid message | The checkbox has an invalid value. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index d0c81a829bd..affcce9ab54 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -52,9 +52,9 @@ To use this field, you must specify *either* ``choices`` or ``choice_loader`` op | | - `attr_translation_parameters`_ | | | - `help_translation_parameters`_ | +---------------------------+----------------------------------------------------------------------+ -| Default `invalid_message` | The selected choice is invalid. | +| Default invalid message | The selected choice is invalid. | +---------------------------+----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+----------------------------------------------------------------------+ diff --git a/reference/forms/types/collection.rst b/reference/forms/types/collection.rst index a30cc250f6f..9e1eb170933 100644 --- a/reference/forms/types/collection.rst +++ b/reference/forms/types/collection.rst @@ -40,9 +40,9 @@ photos). | | - `required`_ | | | - `row_attr`_ | +---------------------------+--------------------------------------------------------------------------+ -| Default `invalid_message` | The collection is invalid. | +| Default invalid message | The collection is invalid. | +---------------------------+--------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+--------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+--------------------------------------------------------------------------+ diff --git a/reference/forms/types/color.rst b/reference/forms/types/color.rst index f3d97c6cd1b..6bbc28da2a7 100644 --- a/reference/forms/types/color.rst +++ b/reference/forms/types/color.rst @@ -38,9 +38,9 @@ element. | | - `row_attr`_ | | | - `trim`_ | +---------------------------+---------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid color. | +| Default invalid message | Please select a valid color. | +---------------------------+---------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+---------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+---------------------------------------------------------------------+ diff --git a/reference/forms/types/country.rst b/reference/forms/types/country.rst index a2b1527764e..10cf652947a 100644 --- a/reference/forms/types/country.rst +++ b/reference/forms/types/country.rst @@ -54,9 +54,9 @@ the option manually, but then you should just use the ``ChoiceType`` directly. | | - `required`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid country. | +| Default invalid message | Please select a valid country. | +---------------------------+-----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------+ | Parent type | :doc:`ChoiceType ` | +---------------------------+-----------------------------------------------------------------------+ diff --git a/reference/forms/types/currency.rst b/reference/forms/types/currency.rst index e8628aa3edf..e28b39c328a 100644 --- a/reference/forms/types/currency.rst +++ b/reference/forms/types/currency.rst @@ -45,9 +45,9 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `required`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid currency. | +| Default invalid message | Please select a valid currency. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`ChoiceType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/date.rst b/reference/forms/types/date.rst index fa696007803..5a12ad24b9c 100644 --- a/reference/forms/types/date.rst +++ b/reference/forms/types/date.rst @@ -46,9 +46,9 @@ and can understand a number of different input formats via the `input`_ option. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid date. | +| Default invalid message | Please enter a valid date. | +---------------------------+-----------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+-----------------------------------------------------------------------------+ diff --git a/reference/forms/types/dateinterval.rst b/reference/forms/types/dateinterval.rst index 69147d95bee..5248ca88739 100644 --- a/reference/forms/types/dateinterval.rst +++ b/reference/forms/types/dateinterval.rst @@ -50,9 +50,9 @@ or an array (see `input`_). | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+----------------------------------------------------------------------------------+ -| Default `invalid_message` | Please choose a valid date interval. | +| Default invalid message | Please choose a valid date interval. | +---------------------------+----------------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+----------------------------------------------------------------------------------+ diff --git a/reference/forms/types/datetime.rst b/reference/forms/types/datetime.rst index ca61be3e538..e742048fd24 100644 --- a/reference/forms/types/datetime.rst +++ b/reference/forms/types/datetime.rst @@ -55,9 +55,9 @@ the data can be a ``DateTime`` object, a string, a timestamp or an array. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid date and time. | +| Default invalid message | Please enter a valid date and time. | +---------------------------+-----------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+-----------------------------------------------------------------------------+ diff --git a/reference/forms/types/email.rst b/reference/forms/types/email.rst index 31d6f5db90b..3dfe77db44f 100644 --- a/reference/forms/types/email.rst +++ b/reference/forms/types/email.rst @@ -29,9 +29,9 @@ The ``EmailType`` field is a text field that is rendered using the HTML5 | | - `row_attr`_ | | | - `trim`_ | +---------------------------+---------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid email address. | +| Default invalid message | Please enter a valid email address. | +---------------------------+---------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+---------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+---------------------------------------------------------------------+ diff --git a/reference/forms/types/file.rst b/reference/forms/types/file.rst index f745c9bc1fd..50bc55fee88 100644 --- a/reference/forms/types/file.rst +++ b/reference/forms/types/file.rst @@ -30,9 +30,9 @@ The ``FileType`` represents a file input in your form. | | - `required`_ | | | - `row_attr`_ | +---------------------------+--------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid file. | +| Default invalid message | Please select a valid file. | +---------------------------+--------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+--------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+--------------------------------------------------------------------+ diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index e406413bf37..9e1a5d47227 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -48,9 +48,9 @@ on all types for which ``FormType`` is the parent. | | - `label_translation_parameters`_ | | | - `attr_translation_parameters`_ | +---------------------------+--------------------------------------------------------------------+ -| Default `invalid_message` | This value is not valid. | +| Default invalid message | This value is not valid. | +---------------------------+--------------------------------------------------------------------+ -| Legacy `invalid_message` | This value is not valid. | +| Legacy invalid message | This value is not valid. | +---------------------------+--------------------------------------------------------------------+ | Parent | none | +---------------------------+--------------------------------------------------------------------+ diff --git a/reference/forms/types/hidden.rst b/reference/forms/types/hidden.rst index f0bddfa4260..00e858303bf 100644 --- a/reference/forms/types/hidden.rst +++ b/reference/forms/types/hidden.rst @@ -22,9 +22,9 @@ The hidden type represents a hidden input field. | | - `property_path`_ | | | - `row_attr`_ | +---------------------------+----------------------------------------------------------------------+ -| Default `invalid_message` | The hidden field is invalid. | +| Default invalid message | The hidden field is invalid. | +---------------------------+----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+----------------------------------------------------------------------+ diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index 7eb32abf7f9..db774ec2ce9 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -39,9 +39,9 @@ integers. By default, all non-integer values (e.g. 6.78) will round down | | - `required`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------+ -| Default `invalid_message` | Please enter an integer. | +| Default invalid message | Please enter an integer. | +---------------------------+-----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+-----------------------------------------------------------------------+ diff --git a/reference/forms/types/language.rst b/reference/forms/types/language.rst index 420ab1b59a0..f74016d1a0c 100644 --- a/reference/forms/types/language.rst +++ b/reference/forms/types/language.rst @@ -57,9 +57,9 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `required`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid language. | +| Default invalid message | Please select a valid language. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`ChoiceType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/locale.rst b/reference/forms/types/locale.rst index be6dde7e950..bab466d262f 100644 --- a/reference/forms/types/locale.rst +++ b/reference/forms/types/locale.rst @@ -56,9 +56,9 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `required`_ | | | - `row_attr`_ | +---------------------------+----------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid locale. | +| Default invalid message | Please select a valid locale. | +---------------------------+----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------+ | Parent type | :doc:`ChoiceType ` | +---------------------------+----------------------------------------------------------------------+ diff --git a/reference/forms/types/money.rst b/reference/forms/types/money.rst index ca7a5aceac7..162d8543b20 100644 --- a/reference/forms/types/money.rst +++ b/reference/forms/types/money.rst @@ -41,9 +41,9 @@ how the input and output of the data is handled. | | - `required`_ | | | - `row_attr`_ | +---------------------------+---------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid money amount. | +| Default invalid message | Please enter a valid money amount. | +---------------------------+---------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+---------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+---------------------------------------------------------------------+ diff --git a/reference/forms/types/number.rst b/reference/forms/types/number.rst index 319c84b951e..99d80628d33 100644 --- a/reference/forms/types/number.rst +++ b/reference/forms/types/number.rst @@ -37,9 +37,9 @@ that you want to use for your number. | | - `required`_ | | | - `row_attr`_ | +---------------------------+----------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a number. | +| Default invalid message | Please enter a number. | +---------------------------+----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+----------------------------------------------------------------------+ diff --git a/reference/forms/types/password.rst b/reference/forms/types/password.rst index 10b38a5ac8b..18be51b396f 100644 --- a/reference/forms/types/password.rst +++ b/reference/forms/types/password.rst @@ -29,9 +29,9 @@ The ``PasswordType`` field renders an input password text box. | | - `required`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | The password is invalid. | +| Default invalid message | The password is invalid. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/percent.rst b/reference/forms/types/percent.rst index 3dd47e1d320..36ffdcc1e1b 100644 --- a/reference/forms/types/percent.rst +++ b/reference/forms/types/percent.rst @@ -41,9 +41,9 @@ the input. | | - `required`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a percentage value. | +| Default invalid message | Please enter a percentage value. | +---------------------------+-----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+-----------------------------------------------------------------------+ diff --git a/reference/forms/types/radio.rst b/reference/forms/types/radio.rst index 579dab0bc1d..93fbe3ecfd9 100644 --- a/reference/forms/types/radio.rst +++ b/reference/forms/types/radio.rst @@ -40,9 +40,9 @@ If you want to have a boolean field, use :doc:`CheckboxType ` | +---------------------------+---------------------------------------------------------------------+ diff --git a/reference/forms/types/range.rst b/reference/forms/types/range.rst index ab3a0d15859..f8284f1b7eb 100644 --- a/reference/forms/types/range.rst +++ b/reference/forms/types/range.rst @@ -28,9 +28,9 @@ The ``RangeType`` field is a slider that is rendered using the HTML5 | | - `row_attr`_ | | | - `trim`_ | +---------------------------+---------------------------------------------------------------------+ -| Default `invalid_message` | Please choose a valid range. | +| Default invalid message | Please choose a valid range. | +---------------------------+---------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+---------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+---------------------------------------------------------------------+ diff --git a/reference/forms/types/repeated.rst b/reference/forms/types/repeated.rst index 7a9f6d9d9be..8c36c64ddd5 100644 --- a/reference/forms/types/repeated.rst +++ b/reference/forms/types/repeated.rst @@ -32,9 +32,9 @@ accuracy. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | The values do not match. | +| Default invalid message | The values do not match. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/search.rst b/reference/forms/types/search.rst index f9c53733872..d6dceeb0264 100644 --- a/reference/forms/types/search.rst +++ b/reference/forms/types/search.rst @@ -30,9 +30,9 @@ Read about the input search field at `DiveIntoHTML5.info`_ | | - `row_attr`_ | | | - `trim`_ | +---------------------------+----------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid search term. | +| Default invalid message | Please enter a valid search term. | +---------------------------+----------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+----------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+----------------------------------------------------------------------+ diff --git a/reference/forms/types/tel.rst b/reference/forms/types/tel.rst index fc45434bc4e..19847431dd3 100644 --- a/reference/forms/types/tel.rst +++ b/reference/forms/types/tel.rst @@ -35,9 +35,9 @@ to input phone numbers. | | - `row_attr`_ | | | - `trim`_ | +---------------------------+-------------------------------------------------------------------+ -| Default `invalid_message` | Please provide a valid phone number. | +| Default invalid message | Please provide a valid phone number. | +---------------------------+-------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+-------------------------------------------------------------------+ diff --git a/reference/forms/types/time.rst b/reference/forms/types/time.rst index 08c3efb77f4..cac168d569e 100644 --- a/reference/forms/types/time.rst +++ b/reference/forms/types/time.rst @@ -48,9 +48,9 @@ stored as a ``DateTime`` object, a string, a timestamp or an array. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+-----------------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid time. | +| Default invalid message | Please enter a valid time. | +---------------------------+-----------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-----------------------------------------------------------------------------+ | Parent type | FormType | +---------------------------+-----------------------------------------------------------------------------+ diff --git a/reference/forms/types/timezone.rst b/reference/forms/types/timezone.rst index 64e17890de8..987f26c9036 100644 --- a/reference/forms/types/timezone.rst +++ b/reference/forms/types/timezone.rst @@ -50,9 +50,9 @@ manually, but then you should just use the ``ChoiceType`` directly. | | - `required`_ | | | - `row_attr`_ | +---------------------------+------------------------------------------------------------------------+ -| Default `invalid_message` | Please select a valid timezone. | +| Default invalid message | Please select a valid timezone. | +---------------------------+------------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+------------------------------------------------------------------------+ | Parent type | :doc:`ChoiceType ` | +---------------------------+------------------------------------------------------------------------+ diff --git a/reference/forms/types/url.rst b/reference/forms/types/url.rst index e5f782ce088..13f425f1d70 100644 --- a/reference/forms/types/url.rst +++ b/reference/forms/types/url.rst @@ -32,9 +32,9 @@ have a protocol. | | - `row_attr`_ | | | - `trim`_ | +---------------------------+-------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid URL. | +| Default invalid message | Please enter a valid URL. | +---------------------------+-------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+-------------------------------------------------------------------+ | Parent type | :doc:`TextType ` | +---------------------------+-------------------------------------------------------------------+ diff --git a/reference/forms/types/week.rst b/reference/forms/types/week.rst index eb526c160af..99762f803e3 100644 --- a/reference/forms/types/week.rst +++ b/reference/forms/types/week.rst @@ -39,9 +39,9 @@ the data can be a string or an array. | | - `mapped`_ | | | - `row_attr`_ | +---------------------------+--------------------------------------------------------------------+ -| Default `invalid_message` | Please enter a valid week. | +| Default invalid message | Please enter a valid week. | +---------------------------+--------------------------------------------------------------------+ -| Legacy `invalid_message` | The value {{ value }} is not valid. | +| Legacy invalid message | The value {{ value }} is not valid. | +---------------------------+--------------------------------------------------------------------+ | Parent type | :doc:`FormType ` | +---------------------------+--------------------------------------------------------------------+ From 3d274edd4b86473e7eb7275c89b0731fb6067294 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 20 Nov 2020 16:13:49 +0100 Subject: [PATCH 0159/5766] Restore the quotes wraping the DATABASE_URL value --- testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index 365626ceacd..8c9550f64ca 100644 --- a/testing.rst +++ b/testing.rst @@ -990,7 +990,7 @@ need in your ``.env.test`` file: .. code-block:: text # .env.test - DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name_test?serverVersion=5.7 + DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name_test?serverVersion=5.7" # use SQLITE # DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" From ef0b3fb0dcd74caea20fae38896f87f010e1f3fc Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 20 Nov 2020 16:39:17 +0100 Subject: [PATCH 0160/5766] Tweak --- doctrine/dbal.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/dbal.rst b/doctrine/dbal.rst index 4b9f26d3f7b..3ddb98d837f 100644 --- a/doctrine/dbal.rst +++ b/doctrine/dbal.rst @@ -35,7 +35,7 @@ Then configure the ``DATABASE_URL`` environment variable in ``.env``: # .env (or override DATABASE_URL in .env.local to avoid committing your changes) # customize this line! - DATABASE_URL=mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7 + DATABASE_URL="mysql://db_user:db_password@127.0.0.1:3306/db_name?serverVersion=5.7" Further things can be configured in ``config/packages/doctrine.yaml`` - see :ref:`reference-dbal-configuration`. Remove the ``orm`` key in that file From 90c83b214c39c26633c3f7a0d4b8541bef6c6a26 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 8 Nov 2020 14:35:47 +0100 Subject: [PATCH 0161/5766] Added PHP types to the Doctrine related articles --- doctrine.rst | 193 ++++++++++++++++---------- doctrine/associations.rst | 81 +++++++---- doctrine/dbal.rst | 4 +- doctrine/events.rst | 16 +-- doctrine/multiple_entity_managers.rst | 9 +- doctrine/resolve_target_entity.rst | 5 +- 6 files changed, 186 insertions(+), 122 deletions(-) diff --git a/doctrine.rst b/doctrine.rst index 21b14c2ae4c..8226bf22700 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -51,7 +51,7 @@ The database connection information is stored as an environment variable called # to use sqlite: # DATABASE_URL="sqlite:///%kernel.project_dir%/var/app.db" - + # to use postgresql: # DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8" @@ -506,46 +506,60 @@ Fetching an object back out of the database is even easier. Suppose you want to be able to go to ``/product/1`` to see your new product:: // src/Controller/ProductController.php + namespace App\Controller; + + use App\Entity\Product; + use Symfony\Component\HttpFoundation\Response; // ... - /** - * @Route("/product/{id}", name="product_show") - */ - public function show($id) + class ProductController extends AbstractController { - $product = $this->getDoctrine() - ->getRepository(Product::class) - ->find($id); - - if (!$product) { - throw $this->createNotFoundException( - 'No product found for id '.$id - ); - } + /** + * @Route("/product/{id}", name="product_show") + */ + public function show(int $id): Response + { + $product = $this->getDoctrine() + ->getRepository(Product::class) + ->find($id); + + if (!$product) { + throw $this->createNotFoundException( + 'No product found for id '.$id + ); + } - return new Response('Check out this great product: '.$product->getName()); + return new Response('Check out this great product: '.$product->getName()); - // or render a template - // in the template, print things with {{ product.name }} - // return $this->render('product/show.html.twig', ['product' => $product]); + // or render a template + // in the template, print things with {{ product.name }} + // return $this->render('product/show.html.twig', ['product' => $product]); + } } Another possibility is to use the ``ProductRepository`` using Symfony's autowiring and injected by the dependency injection container:: // src/Controller/ProductController.php - // ... + namespace App\Controller; + + use App\Entity\Product; use App\Repository\ProductRepository; + use Symfony\Component\HttpFoundation\Response; + // ... - /** - * @Route("/product/{id}", name="product_show") - */ - public function show($id, ProductRepository $productRepository) + class ProductController extends AbstractController { - $product = $productRepository - ->find($id); + /** + * @Route("/product/{id}", name="product_show") + */ + public function show(int $id, ProductRepository $productRepository): Response + { + $product = $productRepository + ->find($id); - // ... + // ... + } } Try it out! @@ -611,15 +625,23 @@ for you automatically! First, install the bundle in case you don't have it: Now, simplify your controller:: // src/Controller/ProductController.php + namespace App\Controller; + use App\Entity\Product; + use App\Repository\ProductRepository; + use Symfony\Component\HttpFoundation\Response; + // ... - /** - * @Route("/product/{id}", name="product_show") - */ - public function show(Product $product) + class ProductController extends AbstractController { - // use the Product! - // ... + /** + * @Route("/product/{id}", name="product_show") + */ + public function show(Product $product): Response + { + // use the Product! + // ... + } } That's it! The bundle uses the ``{id}`` from the route to query for the ``Product`` @@ -633,26 +655,37 @@ Updating an Object Once you've fetched an object from Doctrine, you interact with it the same as with any PHP model:: - /** - * @Route("/product/edit/{id}") - */ - public function update($id) + // src/Controller/ProductController.php + namespace App\Controller; + + use App\Entity\Product; + use App\Repository\ProductRepository; + use Symfony\Component\HttpFoundation\Response; + // ... + + class ProductController extends AbstractController { - $entityManager = $this->getDoctrine()->getManager(); - $product = $entityManager->getRepository(Product::class)->find($id); + /** + * @Route("/product/edit/{id}") + */ + public function update(int $id): Response + { + $entityManager = $this->getDoctrine()->getManager(); + $product = $entityManager->getRepository(Product::class)->find($id); - if (!$product) { - throw $this->createNotFoundException( - 'No product found for id '.$id - ); - } + if (!$product) { + throw $this->createNotFoundException( + 'No product found for id '.$id + ); + } - $product->setName('New product name!'); - $entityManager->flush(); + $product->setName('New product name!'); + $entityManager->flush(); - return $this->redirectToRoute('product_show', [ - 'id' => $product->getId() - ]); + return $this->redirectToRoute('product_show', [ + 'id' => $product->getId() + ]); + } } Using Doctrine to edit an existing product consists of three steps: @@ -728,7 +761,7 @@ a new method for this to your repository:: /** * @return Product[] */ - public function findAllGreaterThanPrice($price): array + public function findAllGreaterThanPrice(int $price): array { $entityManager = $this->getEntityManager(); @@ -773,25 +806,28 @@ based on PHP conditions):: // src/Repository/ProductRepository.php // ... - public function findAllGreaterThanPrice($price, $includeUnavailableProducts = false): array + class ProductRepository extends ServiceEntityRepository { - // automatically knows to select Products - // the "p" is an alias you'll use in the rest of the query - $qb = $this->createQueryBuilder('p') - ->where('p.price > :price') - ->setParameter('price', $price) - ->orderBy('p.price', 'ASC'); - - if (!$includeUnavailableProducts) { - $qb->andWhere('p.available = TRUE'); - } + public function findAllGreaterThanPrice(int $price, bool $includeUnavailableProducts = false): array + { + // automatically knows to select Products + // the "p" is an alias you'll use in the rest of the query + $qb = $this->createQueryBuilder('p') + ->where('p.price > :price') + ->setParameter('price', $price) + ->orderBy('p.price', 'ASC'); + + if (!$includeUnavailableProducts) { + $qb->andWhere('p.available = TRUE'); + } - $query = $qb->getQuery(); + $query = $qb->getQuery(); - return $query->execute(); + return $query->execute(); - // to get just one result: - // $product = $query->setMaxResults(1)->getOneOrNullResult(); + // to get just one result: + // $product = $query->setMaxResults(1)->getOneOrNullResult(); + } } Querying with SQL @@ -802,20 +838,23 @@ In addition, you can query directly with SQL if you need to:: // src/Repository/ProductRepository.php // ... - public function findAllGreaterThanPrice($price): array + class ProductRepository extends ServiceEntityRepository { - $conn = $this->getEntityManager()->getConnection(); - - $sql = ' - SELECT * FROM product p - WHERE p.price > :price - ORDER BY p.price ASC - '; - $stmt = $conn->prepare($sql); - $stmt->execute(['price' => $price]); - - // returns an array of arrays (i.e. a raw data set) - return $stmt->fetchAllAssociative(); + public function findAllGreaterThanPrice(int $price): array + { + $conn = $this->getEntityManager()->getConnection(); + + $sql = ' + SELECT * FROM product p + WHERE p.price > :price + ORDER BY p.price ASC + '; + $stmt = $conn->prepare($sql); + $stmt->execute(['price' => $price]); + + // returns an array of arrays (i.e. a raw data set) + return $stmt->fetchAllAssociative(); + } } With SQL, you will get back raw data, not objects (unless you use the `NativeQuery`_ diff --git a/doctrine/associations.rst b/doctrine/associations.rst index 8bdddab536b..4a2fafb6467 100644 --- a/doctrine/associations.rst +++ b/doctrine/associations.rst @@ -327,7 +327,7 @@ Now you can see this new code in action! Imagine you're inside a controller:: /** * @Route("/product", name="product") */ - public function index() + public function index(): Response { $category = new Category(); $category->setName('Computer Peripherals'); @@ -378,20 +378,26 @@ When you need to fetch associated objects, your workflow looks like it did before. First, fetch a ``$product`` object and then access its related ``Category`` object:: + // src/Controller/ProductController.php + namespace App\Controller; + use App\Entity\Product; // ... - public function show($id) + class ProductController extends AbstractController { - $product = $this->getDoctrine() - ->getRepository(Product::class) - ->find($id); + public function show(int $id): Response + { + $product = $this->getDoctrine() + ->getRepository(Product::class) + ->find($id); - // ... + // ... - $categoryName = $product->getCategory()->getName(); + $categoryName = $product->getCategory()->getName(); - // ... + // ... + } } In this example, you first query for a ``Product`` object based on the product's @@ -411,15 +417,21 @@ the category (i.e. it's "lazily loaded"). Because we mapped the optional ``OneToMany`` side, you can also query in the other direction:: - public function showProducts($id) + // src/Controller/ProductController.php + + // ... + class ProductController extends AbstractController { - $category = $this->getDoctrine() - ->getRepository(Category::class) - ->find($id); + public function showProducts(int $id): Response + { + $category = $this->getDoctrine() + ->getRepository(Category::class) + ->find($id); - $products = $category->getProducts(); + $products = $category->getProducts(); - // ... + // ... + } } In this case, the same things occur: you first query for a single ``Category`` @@ -475,18 +487,23 @@ can avoid the second query by issuing a join in the original query. Add the following method to the ``ProductRepository`` class:: // src/Repository/ProductRepository.php - public function findOneByIdJoinedToCategory($productId) + + // ... + class ProductRepository extends ServiceEntityRepository { - $entityManager = $this->getEntityManager(); + public function findOneByIdJoinedToCategory(int $productId): ?Product + { + $entityManager = $this->getEntityManager(); - $query = $entityManager->createQuery( - 'SELECT p, c - FROM App\Entity\Product p - INNER JOIN p.category c - WHERE p.id = :id' - )->setParameter('id', $productId); + $query = $entityManager->createQuery( + 'SELECT p, c + FROM App\Entity\Product p + INNER JOIN p.category c + WHERE p.id = :id' + )->setParameter('id', $productId); - return $query->getOneOrNullResult(); + return $query->getOneOrNullResult(); + } } This will *still* return an array of ``Product`` objects. But now, when you call @@ -495,15 +512,21 @@ This will *still* return an array of ``Product`` objects. But now, when you call Now, you can use this method in your controller to query for a ``Product`` object and its related ``Category`` in one query:: - public function show($id) + // src/Controller/ProductController.php + + // ... + class ProductController extends AbstractController { - $product = $this->getDoctrine() - ->getRepository(Product::class) - ->findOneByIdJoinedToCategory($id); + public function show(int $id): Response + { + $product = $this->getDoctrine() + ->getRepository(Product::class) + ->findOneByIdJoinedToCategory($id); - $category = $product->getCategory(); + $category = $product->getCategory(); - // ... + // ... + } } .. _associations-inverse-side: diff --git a/doctrine/dbal.rst b/doctrine/dbal.rst index 3ddb98d837f..80c145d3d6a 100644 --- a/doctrine/dbal.rst +++ b/doctrine/dbal.rst @@ -48,10 +48,12 @@ object:: namespace App\Controller; use Doctrine\DBAL\Driver\Connection; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Response; class UserController extends AbstractController { - public function index(Connection $connection) + public function index(Connection $connection): Response { $users = $connection->fetchAll('SELECT * FROM users'); diff --git a/doctrine/events.rst b/doctrine/events.rst index 1ce0bfa8ac0..309d10a7e12 100644 --- a/doctrine/events.rst +++ b/doctrine/events.rst @@ -74,7 +74,7 @@ define a callback for the ``prePersist`` Doctrine event: /** * @ORM\PrePersist */ - public function setCreatedAtValue() + public function setCreatedAtValue(): void { $this->createdAt = new \DateTime(); } @@ -132,7 +132,7 @@ do so, define a listener for the ``postPersist`` Doctrine event:: { // the listener methods receive an argument which gives you access to // both the entity object of the event and the entity manager itself - public function postPersist(LifecycleEventArgs $args) + public function postPersist(LifecycleEventArgs $args): void { $entity = $args->getObject(); @@ -241,7 +241,7 @@ define a listener for the ``postUpdate`` Doctrine event:: { // the entity listener methods receive two arguments: // the entity instance and the lifecycle event - public function postUpdate(User $user, LifecycleEventArgs $event) + public function postUpdate(User $user, LifecycleEventArgs $event): void { // ... do something to notify the changes } @@ -365,7 +365,7 @@ want to log all the database activity. To do so, define a subscriber for the { // this method can only return the event names; you cannot define a // custom method name to execute when each event triggers - public function getSubscribedEvents() + public function getSubscribedEvents(): array { return [ Events::postPersist, @@ -377,22 +377,22 @@ want to log all the database activity. To do so, define a subscriber for the // callback methods must be called exactly like the events they listen to; // they receive an argument of type LifecycleEventArgs, which gives you access // to both the entity object of the event and the entity manager itself - public function postPersist(LifecycleEventArgs $args) + public function postPersist(LifecycleEventArgs $args): void { $this->logActivity('persist', $args); } - public function postRemove(LifecycleEventArgs $args) + public function postRemove(LifecycleEventArgs $args): void { $this->logActivity('remove', $args); } - public function postUpdate(LifecycleEventArgs $args) + public function postUpdate(LifecycleEventArgs $args): void { $this->logActivity('update', $args); } - private function logActivity(string $action, LifecycleEventArgs $args) + private function logActivity(string $action, LifecycleEventArgs $args): void { $entity = $args->getObject(); diff --git a/doctrine/multiple_entity_managers.rst b/doctrine/multiple_entity_managers.rst index faffc480877..ba3475dbfbc 100644 --- a/doctrine/multiple_entity_managers.rst +++ b/doctrine/multiple_entity_managers.rst @@ -234,12 +234,11 @@ the default entity manager (i.e. ``default``) is returned:: namespace App\Controller; // ... - use Doctrine\ORM\EntityManagerInterface; class UserController extends AbstractController { - public function index(EntityManagerInterface $entityManager) + public function index(EntityManagerInterface $entityManager): Response { // These methods also return the default entity manager, but it's preferred // to get it by injecting EntityManagerInterface in the action method @@ -250,6 +249,8 @@ the default entity manager (i.e. ``default``) is returned:: // Both of these return the "customer" entity manager $customerEntityManager = $this->getDoctrine()->getManager('customer'); $customerEntityManager = $this->get('doctrine.orm.customer_entity_manager'); + + // ... } } @@ -268,7 +269,7 @@ The same applies to repository calls:: class UserController extends AbstractController { - public function index() + public function index(): Response { // Retrieves a repository managed by the "default" em $products = $this->getDoctrine() @@ -287,6 +288,8 @@ The same applies to repository calls:: ->getRepository(Customer::class, 'customer') ->findAll() ; + + // ... } } diff --git a/doctrine/resolve_target_entity.rst b/doctrine/resolve_target_entity.rst index 36038fd9f3c..765f5d187ce 100644 --- a/doctrine/resolve_target_entity.rst +++ b/doctrine/resolve_target_entity.rst @@ -96,10 +96,7 @@ An InvoiceSubjectInterface:: // will need to access on the subject so that you can // be sure that you have access to those methods. - /** - * @return string - */ - public function getName(); + public function getName(): string; } Next, you need to configure the listener, which tells the DoctrineBundle From aec1016d94db1de37eaedb7f8567046168d0805a Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 8 Nov 2020 14:57:22 +0100 Subject: [PATCH 0162/5766] Added PHP types to the Form related articles --- form/create_custom_field_type.rst | 18 ++-- form/create_form_type_extension.rst | 8 +- form/data_based_validation.rst | 6 +- form/data_mappers.rst | 8 +- form/data_transformers.rst | 28 +++--- form/direct_submit.rst | 3 +- form/disabling_validation.rst | 2 +- form/dynamic_form_modification.rst | 31 ++++--- form/embedded.rst | 10 +- form/events.rst | 10 +- form/form_collections.rst | 102 +++++++++++---------- form/form_themes.rst | 10 +- form/inherit_data_option.rst | 12 +-- form/type_guesser.rst | 14 +-- form/use_empty_data.rst | 6 +- form/validation_group_service_resolver.rst | 8 +- form/validation_groups.rst | 2 +- form/without_class.rst | 43 +++++---- forms.rst | 100 +++++++++++--------- 19 files changed, 224 insertions(+), 197 deletions(-) diff --git a/form/create_custom_field_type.rst b/form/create_custom_field_type.rst index 58e265fd2ad..59816006041 100644 --- a/form/create_custom_field_type.rst +++ b/form/create_custom_field_type.rst @@ -38,7 +38,7 @@ By convention they are stored in the ``src/Form/Type/`` directory:: class ShippingType extends AbstractType { - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'choices' => [ @@ -49,7 +49,7 @@ By convention they are stored in the ``src/Form/Type/`` directory:: ]); } - public function getParent() + public function getParent(): string { return ChoiceType::class; } @@ -82,7 +82,7 @@ Now you can add this form type when :doc:`creating Symfony forms `:: class OrderType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder // ... @@ -168,7 +168,7 @@ in the postal address. For the moment, all fields are of type ``TextType``:: { // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('addressLine1', TextType::class, [ @@ -209,7 +209,7 @@ correctly rendered in any template:: class OrderType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder // ... @@ -254,7 +254,7 @@ to define, validate and process their values:: { // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { // this defines the available options and their default values when // they are not configured explicitly when using the form type @@ -293,7 +293,7 @@ Now you can configure these options when using the form type:: class OrderType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder // ... @@ -320,7 +320,7 @@ The last step is to use these options when building the form:: { // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -473,7 +473,7 @@ defined by the form or be completely independent:: // ... - public function buildView(FormView $view, FormInterface $form, array $options) + public function buildView(FormView $view, FormInterface $form, array $options): void { // pass the form type option directly to the template $view->vars['isExtendedAddress'] = $options['is_extended_address']; diff --git a/form/create_form_type_extension.rst b/form/create_form_type_extension.rst index 59b1c06e9fe..55d3d34776f 100644 --- a/form/create_form_type_extension.rst +++ b/form/create_form_type_extension.rst @@ -114,7 +114,7 @@ the database:: // ... - public function getWebPath() + public function getWebPath(): string { // ... $webPath being the full image URL, to be used in templates @@ -149,13 +149,13 @@ For example:: return [FileType::class]; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { // makes it legal for FileType fields to have an image_property option $resolver->setDefined(['image_property']); } - public function buildView(FormView $view, FormInterface $form, array $options) + public function buildView(FormView $view, FormInterface $form, array $options): void { if (isset($options['image_property'])) { // this will be whatever class/entity is bound to your form (e.g. Media) @@ -221,7 +221,7 @@ next to the file field. For example:: class MediaType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name', TextType::class) diff --git a/form/data_based_validation.rst b/form/data_based_validation.rst index 383883ba91f..226284db439 100644 --- a/form/data_based_validation.rst +++ b/form/data_based_validation.rst @@ -12,7 +12,7 @@ to an array callback:: use Symfony\Component\OptionsResolver\OptionsResolver; // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'validation_groups' => [ @@ -32,7 +32,7 @@ example). You can also define whole logic inline by using a ``Closure``:: use Symfony\Component\OptionsResolver\OptionsResolver; // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'validation_groups' => function (FormInterface $form) { @@ -56,7 +56,7 @@ of the entity as well you have to adjust the option as follows:: use Symfony\Component\OptionsResolver\OptionsResolver; // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'validation_groups' => function (FormInterface $form) { diff --git a/form/data_mappers.rst b/form/data_mappers.rst index 15e66ce54b3..c14eabd7683 100644 --- a/form/data_mappers.rst +++ b/form/data_mappers.rst @@ -98,7 +98,7 @@ in your form type:: /** * @param Color|null $viewData */ - public function mapDataToForms($viewData, $forms) + public function mapDataToForms($viewData, $forms): void { // there is no data yet, so nothing to prepopulate if (null === $viewData) { @@ -119,7 +119,7 @@ in your form type:: $forms['blue']->setData($viewData->getBlue()); } - public function mapFormsToData($forms, &$viewData) + public function mapFormsToData($forms, &$viewData): void { /** @var FormInterface[] $forms */ $forms = iterator_to_array($forms); @@ -158,7 +158,7 @@ method:: final class ColorType extends AbstractType implements DataMapperInterface { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('red', IntegerType::class, [ @@ -177,7 +177,7 @@ method:: ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { // when creating a new color, the initial data should be null $resolver->setDefault('empty_data', null); diff --git a/form/data_transformers.rst b/form/data_transformers.rst index 4a087a0aaff..aa0e88789bf 100644 --- a/form/data_transformers.rst +++ b/form/data_transformers.rst @@ -40,12 +40,12 @@ Suppose you have a Task form with a tags ``text`` type:: // ... class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('tags', TextType::class); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Task::class, @@ -72,7 +72,7 @@ class:: class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('tags', TextType::class); @@ -136,7 +136,7 @@ Start by setting up the text field like normal:: // ... class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('description', TextareaType::class) @@ -144,7 +144,7 @@ Start by setting up the text field like normal:: ; } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Task::class, @@ -188,9 +188,8 @@ to and from the issue number and the ``Issue`` object:: * Transforms an object (issue) to a string (number). * * @param Issue|null $issue - * @return string */ - public function transform($issue) + public function transform($issue): string { if (null === $issue) { return ''; @@ -203,10 +202,9 @@ to and from the issue number and the ``Issue`` object:: * Transforms a string (number) to an object (issue). * * @param string $issueNumber - * @return Issue|null * @throws TransformationFailedException if object (issue) is not found. */ - public function reverseTransform($issueNumber) + public function reverseTransform($issueNumber): ?Issue { // no issue number? It's optional, so that's ok if (!$issueNumber) { @@ -273,7 +271,7 @@ and type-hint the new class:: $this->transformer = $transformer; } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('description', TextareaType::class) @@ -306,7 +304,7 @@ end-user error message in the data transformer using the { // ... - public function reverseTransform($issueNumber) + public function reverseTransform($issueNumber): ?Issue { // ... @@ -394,19 +392,19 @@ First, create the custom field type class:: $this->transformer = $transformer; } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->addModelTransformer($this->transformer); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'invalid_message' => 'The selected issue does not exist', ]); } - public function getParent() + public function getParent(): string { return TextType::class; } @@ -427,7 +425,7 @@ As long as you're using :ref:`autowire ` and class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('description', TextareaType::class) diff --git a/form/direct_submit.rst b/form/direct_submit.rst index ef6897611ad..876ad3964b1 100644 --- a/form/direct_submit.rst +++ b/form/direct_submit.rst @@ -11,9 +11,10 @@ to detect when the form has been submitted. However, you can also use the control over when exactly your form is submitted and what data is passed to it:: use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; // ... - public function new(Request $request) + public function new(Request $request): Response { $task = new Task(); $form = $this->createForm(TaskType::class, $task); diff --git a/form/disabling_validation.rst b/form/disabling_validation.rst index f23cc73dbbf..2844d0c865d 100644 --- a/form/disabling_validation.rst +++ b/form/disabling_validation.rst @@ -9,7 +9,7 @@ these cases you can set the ``validation_groups`` option to ``false``:: use Symfony\Component\OptionsResolver\OptionsResolver; - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'validation_groups' => false, diff --git a/form/dynamic_form_modification.rst b/form/dynamic_form_modification.rst index 69339480248..279b5b4118d 100644 --- a/form/dynamic_form_modification.rst +++ b/form/dynamic_form_modification.rst @@ -45,13 +45,13 @@ a bare form class looks like:: class ProductType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('name'); $builder->add('price'); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Product::class, @@ -92,7 +92,7 @@ creating that particular field is delegated to an event listener:: class ProductType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('price'); @@ -109,7 +109,7 @@ object is new (e.g. hasn't been persisted to the database). Based on that, the event listener might look like the following:: // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... $builder->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) { @@ -151,14 +151,14 @@ you can also move the logic for creating the ``name`` field to an class AddNameFieldSubscriber implements EventSubscriberInterface { - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { // Tells the dispatcher that you want to listen on the form.pre_set_data // event and that the preSetData method should be called. return [FormEvents::PRE_SET_DATA => 'preSetData']; } - public function preSetData(FormEvent $event) + public function preSetData(FormEvent $event): void { $product = $event->getData(); $form = $event->getForm(); @@ -179,7 +179,7 @@ Great! Now use that in your form class:: class ProductType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('price'); @@ -217,7 +217,7 @@ Using an event listener, your form might look like this:: class FriendMessageFormType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('subject', TextType::class) @@ -274,7 +274,7 @@ security helper to fill in the listener logic:: $this->security = $security; } - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('subject', TextType::class) @@ -337,10 +337,12 @@ and :doc:`tag it ` with the ``form.type`` tag. In a controller, create the form like normal:: use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; class FriendMessageController extends AbstractController { - public function new(Request $request) + public function new(Request $request): Response { $form = $this->createForm(FriendMessageFormType::class); @@ -351,7 +353,7 @@ In a controller, create the form like normal:: You can also embed the form type into another form:: // inside some other "form type" class - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('message', FriendMessageFormType::class); } @@ -384,7 +386,7 @@ sport like this:: class SportMeetupType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('sport', EntityType::class, [ @@ -448,7 +450,7 @@ The type would now look like:: class SportMeetupType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('sport', EntityType::class, [ @@ -515,11 +517,12 @@ your application. Assume that you have a sport meetup creation controller:: use App\Form\Type\SportMeetupType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; // ... class MeetupController extends AbstractController { - public function create(Request $request) + public function create(Request $request): Response { $meetup = new SportMeetup(); $form = $this->createForm(SportMeetupType::class, $meetup); diff --git a/form/embedded.rst b/form/embedded.rst index 9da8104b143..787580a41d1 100644 --- a/form/embedded.rst +++ b/form/embedded.rst @@ -46,12 +46,12 @@ Next, add a new ``category`` property to the ``Task`` class:: // ... - public function getCategory() + public function getCategory(): ?Category { return $this->category; } - public function setCategory(Category $category = null) + public function setCategory(?Category $category) { $this->category = $category; } @@ -76,12 +76,12 @@ create a form class so that a ``Category`` object can be modified by the user:: class CategoryType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('name'); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Category::class, @@ -97,7 +97,7 @@ class:: use App\Form\CategoryType; use Symfony\Component\Form\FormBuilderInterface; - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... diff --git a/form/events.rst b/form/events.rst index 5620ec96f46..0f2e26e2775 100644 --- a/form/events.rst +++ b/form/events.rst @@ -308,7 +308,7 @@ callback for better readability:: // ... class SubscriptionType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('username', TextType::class) @@ -320,7 +320,7 @@ callback for better readability:: ; } - public function onPreSetData(FormEvent $event) + public function onPreSetData(FormEvent $event): void { // ... } @@ -347,7 +347,7 @@ Consider the following example of a form event subscriber:: class AddEmailFieldListener implements EventSubscriberInterface { - public static function getSubscribedEvents() + public static function getSubscribedEvents(): array { return [ FormEvents::PRE_SET_DATA => 'onPreSetData', @@ -355,7 +355,7 @@ Consider the following example of a form event subscriber:: ]; } - public function onPreSetData(FormEvent $event) + public function onPreSetData(FormEvent $event): void { $user = $event->getData(); $form = $event->getForm(); @@ -367,7 +367,7 @@ Consider the following example of a form event subscriber:: } } - public function onPreSubmit(FormEvent $event) + public function onPreSubmit(FormEvent $event): void { $user = $event->getData(); $form = $event->getForm(); diff --git a/form/form_collections.rst b/form/form_collections.rst index 405ffed53e4..cd1f66a7a8f 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -15,6 +15,7 @@ Let's start by creating a ``Task`` entity:: namespace App\Entity; use Doctrine\Common\Collections\ArrayCollection; + use Doctrine\Common\Collections\Collection; class Task { @@ -26,17 +27,17 @@ Let's start by creating a ``Task`` entity:: $this->tags = new ArrayCollection(); } - public function getDescription() + public function getDescription(): string { return $this->description; } - public function setDescription($description) + public function setDescription(string $description): void { $this->description = $description; } - public function getTags() + public function getTags(): Collection { return $this->tags; } @@ -58,12 +59,12 @@ objects:: { private $name; - public function getName() + public function getName(): string { return $this->name; } - public function setName($name) + public function setName(string $name): void { $this->name = $name; } @@ -81,12 +82,12 @@ Then, create a form class so that a ``Tag`` object can be modified by the user:: class TagType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('name'); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Tag::class, @@ -110,7 +111,7 @@ inside the task form itself:: class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder->add('description'); @@ -120,7 +121,7 @@ inside the task form itself:: ]); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Task::class, @@ -138,10 +139,11 @@ In your controller, you'll create a new form from the ``TaskType``:: use App\Form\TaskType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; class TaskController extends AbstractController { - public function new(Request $request) + public function new(Request $request): Response { $task = new Task(); @@ -224,7 +226,7 @@ it will receive an *unknown* number of tags. Otherwise, you'll see a // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -367,12 +369,12 @@ for the tags in the ``Task`` class:: { // ... - public function addTag(Tag $tag) + public function addTag(Tag $tag): void { $this->tags->add($tag); } - public function removeTag(Tag $tag) + public function removeTag(Tag $tag): void { // ... } @@ -383,7 +385,7 @@ Next, add a ``by_reference`` option to the ``tags`` field and set it to ``false` // src/Form/TaskType.php // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -484,7 +486,7 @@ you will learn about next!). // src/Entity/Task.php // ... - public function addTag(Tag $tag) + public function addTag(Tag $tag): void { // for a many-to-many association: $tag->addTask($this); @@ -501,7 +503,7 @@ you will learn about next!). // src/Entity/Tag.php // ... - public function addTask(Task $task) + public function addTask(Task $task): void { if (!$this->tasks->contains($task)) { $this->tasks->add($task); @@ -521,7 +523,7 @@ Start by adding the ``allow_delete`` option in the form Type:: // src/Form/TaskType.php // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -540,7 +542,7 @@ Now, you need to put some code into the ``removeTag()`` method of ``Task``:: { // ... - public function removeTag(Tag $tag) + public function removeTag(Tag $tag): void { $this->tags->removeElement($tag); } @@ -617,52 +619,56 @@ the relationship between the removed ``Tag`` and ``Task`` object. is handling the "update" of your Task:: // src/Controller/TaskController.php + + // ... use App\Entity\Task; use Doctrine\Common\Collections\ArrayCollection; - // ... - public function edit($id, Request $request, EntityManagerInterface $entityManager) + class TaskController extends AbstractController { - if (null === $task = $entityManager->getRepository(Task::class)->find($id)) { - throw $this->createNotFoundException('No task found for id '.$id); - } + public function edit($id, Request $request, EntityManagerInterface $entityManager): Response + { + if (null === $task = $entityManager->getRepository(Task::class)->find($id)) { + throw $this->createNotFoundException('No task found for id '.$id); + } - $originalTags = new ArrayCollection(); + $originalTags = new ArrayCollection(); - // Create an ArrayCollection of the current Tag objects in the database - foreach ($task->getTags() as $tag) { - $originalTags->add($tag); - } + // Create an ArrayCollection of the current Tag objects in the database + foreach ($task->getTags() as $tag) { + $originalTags->add($tag); + } - $editForm = $this->createForm(TaskType::class, $task); + $editForm = $this->createForm(TaskType::class, $task); - $editForm->handleRequest($request); + $editForm->handleRequest($request); - if ($editForm->isSubmitted() && $editForm->isValid()) { - // remove the relationship between the tag and the Task - foreach ($originalTags as $tag) { - if (false === $task->getTags()->contains($tag)) { - // remove the Task from the Tag - $tag->getTasks()->removeElement($task); + if ($editForm->isSubmitted() && $editForm->isValid()) { + // remove the relationship between the tag and the Task + foreach ($originalTags as $tag) { + if (false === $task->getTags()->contains($tag)) { + // remove the Task from the Tag + $tag->getTasks()->removeElement($task); - // if it was a many-to-one relationship, remove the relationship like this - // $tag->setTask(null); + // if it was a many-to-one relationship, remove the relationship like this + // $tag->setTask(null); - $entityManager->persist($tag); + $entityManager->persist($tag); - // if you wanted to delete the Tag entirely, you can also do that - // $entityManager->remove($tag); + // if you wanted to delete the Tag entirely, you can also do that + // $entityManager->remove($tag); + } } - } - $entityManager->persist($task); - $entityManager->flush(); + $entityManager->persist($task); + $entityManager->flush(); - // redirect back to some edit page - return $this->redirectToRoute('task_edit', ['id' => $id]); - } + // redirect back to some edit page + return $this->redirectToRoute('task_edit', ['id' => $id]); + } - // render some form template + // ... render some form template + } } As you can see, adding and removing the elements correctly can be tricky. diff --git a/form/form_themes.rst b/form/form_themes.rst index 3811b042c28..1b5a3594a2d 100644 --- a/form/form_themes.rst +++ b/form/form_themes.rst @@ -266,7 +266,7 @@ form. You can also define this value explicitly with the ``block_name`` option:: use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\Form\FormBuilderInterface; - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -290,7 +290,7 @@ field without having to :doc:`create a custom form type add('name', TextType::class, [ 'block_prefix' => 'wrapped_text', @@ -316,7 +316,7 @@ following complex example where a ``TaskManagerType`` has a collection of class TaskManagerType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options = []) + public function buildForm(FormBuilderInterface $builder, array $options = []): void { // ... $builder->add('taskLists', CollectionType::class, [ @@ -328,7 +328,7 @@ following complex example where a ``TaskManagerType`` has a collection of class TaskListType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options = []) + public function buildForm(FormBuilderInterface $builder, array $options = []): void { // ... $builder->add('tasks', CollectionType::class, [ @@ -339,7 +339,7 @@ following complex example where a ``TaskManagerType`` has a collection of class TaskType { - public function buildForm(FormBuilderInterface $builder, array $options = []) + public function buildForm(FormBuilderInterface $builder, array $options = []): void { $builder->add('name'); // ... diff --git a/form/inherit_data_option.rst b/form/inherit_data_option.rst index 3321ab2153a..f4161a21111 100644 --- a/form/inherit_data_option.rst +++ b/form/inherit_data_option.rst @@ -52,7 +52,7 @@ Start with building two forms for these entities, ``CompanyType`` and ``Customer class CompanyType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('name', TextType::class) @@ -71,7 +71,7 @@ Start with building two forms for these entities, ``CompanyType`` and ``Customer class CustomerType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('firstName', TextType::class) @@ -94,7 +94,7 @@ for that:: class LocationType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('address', TextareaType::class) @@ -103,7 +103,7 @@ for that:: ->add('country', TextType::class); } - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'inherit_data' => true, @@ -131,7 +131,7 @@ Finally, make this work by adding the location form to your two original forms:: use App\Entity\Company; // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... @@ -148,7 +148,7 @@ Finally, make this work by adding the location form to your two original forms:: use App\Entity\Customer; // ... - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { // ... diff --git a/form/type_guesser.rst b/form/type_guesser.rst index f990aad4115..49488e524ba 100644 --- a/form/type_guesser.rst +++ b/form/type_guesser.rst @@ -40,22 +40,24 @@ Start by creating the class and these methods. Next, you'll learn how to fill ea namespace App\Form\TypeGuesser; use Symfony\Component\Form\FormTypeGuesserInterface; + use Symfony\Component\Form\Guess\TypeGuess; + use Symfony\Component\Form\Guess\ValueGuess; class PHPDocTypeGuesser implements FormTypeGuesserInterface { - public function guessType($class, $property) + public function guessType($class, $property): ?TypeGuess { } - public function guessRequired($class, $property) + public function guessRequired($class, $property): ?ValueGuess { } - public function guessMaxLength($class, $property) + public function guessMaxLength($class, $property): ?ValueGuess { } - public function guessPattern($class, $property) + public function guessPattern($class, $property): ?ValueGuess { } } @@ -94,7 +96,7 @@ With this knowledge, you can implement the ``guessType()`` method of the class PHPDocTypeGuesser implements FormTypeGuesserInterface { - public function guessType($class, $property) + public function guessType($class, $property): ?TypeGuess { $annotations = $this->readPhpDocAnnotations($class, $property); @@ -129,7 +131,7 @@ With this knowledge, you can implement the ``guessType()`` method of the } } - protected function readPhpDocAnnotations($class, $property) + protected function readPhpDocAnnotations(string $class, string $property): array { $reflectionProperty = new \ReflectionProperty($class, $property); $phpdoc = $reflectionProperty->getDocComment(); diff --git a/form/use_empty_data.rst b/form/use_empty_data.rst index 6a567286094..c2cba15ad7f 100644 --- a/form/use_empty_data.rst +++ b/form/use_empty_data.rst @@ -9,7 +9,7 @@ form class. This empty data set would be used if you submit your form, but haven't called ``setData()`` on your form or passed in data when you created your form. For example, in a controller:: - public function index() + public function index(): Response { $blog = ...; @@ -61,7 +61,7 @@ that constructor with no arguments:: } // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'empty_data' => new Blog($this->someDependency), @@ -96,7 +96,7 @@ The closure must accept a ``FormInterface`` instance as the first argument:: use Symfony\Component\OptionsResolver\OptionsResolver; // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'empty_data' => function (FormInterface $form) { diff --git a/form/validation_group_service_resolver.rst b/form/validation_group_service_resolver.rst index e497a7556df..ad741fbdb3a 100644 --- a/form/validation_group_service_resolver.rst +++ b/form/validation_group_service_resolver.rst @@ -23,11 +23,7 @@ parameter:: $this->service2 = $service2; } - /** - * @param FormInterface $form - * @return array - */ - public function __invoke(FormInterface $form) + public function __invoke(FormInterface $form): array { $groups = []; @@ -56,7 +52,7 @@ Then in your form, inject the resolver and set it as the ``validation_groups``:: } // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'validation_groups' => $this->groupResolver, diff --git a/form/validation_groups.rst b/form/validation_groups.rst index 2dfe2889de9..a215ed02aba 100644 --- a/form/validation_groups.rst +++ b/form/validation_groups.rst @@ -20,7 +20,7 @@ following to the ``configureOptions()`` method:: use Symfony\Component\OptionsResolver\OptionsResolver; - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ // ... diff --git a/form/without_class.rst b/form/without_class.rst index 50efc1dbcc7..85838d77ce9 100644 --- a/form/without_class.rst +++ b/form/without_class.rst @@ -12,28 +12,35 @@ But sometimes, you may want to use a form without a class, and get back an array of the submitted data. The ``getData()`` method allows you to do exactly that:: - // make sure you've imported the Request namespace above the class + // src/Controller/ContactController.php + namespace App\Controller; + + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; // ... - public function contact(Request $request) + class ContactController extends AbstractController { - $defaultData = ['message' => 'Type your message here']; - $form = $this->createFormBuilder($defaultData) - ->add('name', TextType::class) - ->add('email', EmailType::class) - ->add('message', TextareaType::class) - ->add('send', SubmitType::class) - ->getForm(); - - $form->handleRequest($request); - - if ($form->isSubmitted() && $form->isValid()) { - // data is an array with "name", "email", and "message" keys - $data = $form->getData(); + public function contact(Request $request): Response + { + $defaultData = ['message' => 'Type your message here']; + $form = $this->createFormBuilder($defaultData) + ->add('name', TextType::class) + ->add('email', EmailType::class) + ->add('message', TextareaType::class) + ->add('send', SubmitType::class) + ->getForm(); + + $form->handleRequest($request); + + if ($form->isSubmitted() && $form->isValid()) { + // data is an array with "name", "email", and "message" keys + $data = $form->getData(); + } + + // ... render the form } - - // ... render the form } By default, a form actually assumes that you want to work with arrays of @@ -85,7 +92,7 @@ but here's a short example:: use Symfony\Component\Validator\Constraints\Length; use Symfony\Component\Validator\Constraints\NotBlank; - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('firstName', TextType::class, [ diff --git a/forms.rst b/forms.rst index 6923660a016..12013e8fbfc 100644 --- a/forms.rst +++ b/forms.rst @@ -49,22 +49,22 @@ following ``Task`` class:: protected $task; protected $dueDate; - public function getTask() + public function getTask(): string { return $this->task; } - public function setTask($task) + public function setTask(string $task): void { $this->task = $task; } - public function getDueDate() + public function getDueDate(): ?\DateTime { return $this->dueDate; } - public function setDueDate(\DateTime $dueDate = null) + public function setDueDate(?\DateTime $dueDate): void { $this->dueDate = $dueDate; } @@ -122,10 +122,11 @@ use the ``createFormBuilder()`` helper:: use Symfony\Component\Form\Extension\Core\Type\SubmitType; use Symfony\Component\Form\Extension\Core\Type\TextType; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; class TaskController extends AbstractController { - public function new(Request $request) + public function new(Request $request): Response { // creates a task object and initializes some data for this example $task = new Task(); @@ -178,7 +179,7 @@ implements the interface and provides some utilities:: class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('task', TextType::class) @@ -206,7 +207,7 @@ use the ``createForm()`` helper (otherwise, use the ``create()`` method of the class TaskController extends AbstractController { - public function new() + public function new(): Response { // creates a task object and initializes some data for this example $task = new Task(); @@ -241,7 +242,7 @@ the ``data_class`` option by adding the following to your form type class:: { // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ 'data_class' => Task::class, @@ -265,10 +266,11 @@ to build another object with the visual representation of the form:: use App\Form\Type\TaskType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; class TaskController extends AbstractController { - public function new(Request $request) + public function new(Request $request): Response { $task = new Task(); // ... @@ -374,34 +376,39 @@ Processing a form means to translate user-submitted data back to the properties of an object. To make this happen, the submitted data from the user must be written into the form object:: + // src/Controller/TaskController.php + // ... use Symfony\Component\HttpFoundation\Request; - public function new(Request $request) + class TaskController extends AbstractController { - // just setup a fresh $task object (remove the example data) - $task = new Task(); + public function new(Request $request): Response + { + // just setup a fresh $task object (remove the example data) + $task = new Task(); - $form = $this->createForm(TaskType::class, $task); + $form = $this->createForm(TaskType::class, $task); - $form->handleRequest($request); - if ($form->isSubmitted() && $form->isValid()) { - // $form->getData() holds the submitted values - // but, the original `$task` variable has also been updated - $task = $form->getData(); + $form->handleRequest($request); + if ($form->isSubmitted() && $form->isValid()) { + // $form->getData() holds the submitted values + // but, the original `$task` variable has also been updated + $task = $form->getData(); - // ... perform some action, such as saving the task to the database - // for example, if Task is a Doctrine entity, save it! - // $entityManager = $this->getDoctrine()->getManager(); - // $entityManager->persist($task); - // $entityManager->flush(); + // ... perform some action, such as saving the task to the database + // for example, if Task is a Doctrine entity, save it! + // $entityManager = $this->getDoctrine()->getManager(); + // $entityManager->persist($task); + // $entityManager->flush(); - return $this->redirectToRoute('task_success'); - } + return $this->redirectToRoute('task_success'); + } - return $this->render('task/new.html.twig', [ - 'form' => $form->createView(), - ]); + return $this->render('task/new.html.twig', [ + 'form' => $form->createView(), + ]); + } } This controller follows a common pattern for handling forms and has three @@ -534,7 +541,7 @@ object. { // ... - public static function loadValidatorMetadata(ClassMetadata $metadata) + public static function loadValidatorMetadata(ClassMetadata $metadata): void { $metadata->addPropertyConstraint('task', new NotBlank()); @@ -571,7 +578,7 @@ argument of ``createForm()``:: class TaskController extends AbstractController { - public function new() + public function new(): Response { $task = new Task(); // use some PHP logic to decide if this form field is required or not @@ -599,7 +606,7 @@ options they accept using the ``configureOptions()`` method:: { // ... - public function configureOptions(OptionsResolver $resolver) + public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ // ..., @@ -623,7 +630,7 @@ Now you can use this new form option inside the ``buildForm()`` method:: class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder // ... @@ -699,6 +706,7 @@ use the ``setAction()`` and ``setMethod()`` methods to change this:: // src/Controller/TaskController.php namespace App\Controller; + // ... use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\Form\Extension\Core\Type\DateType; use Symfony\Component\Form\Extension\Core\Type\SubmitType; @@ -706,7 +714,7 @@ use the ``setAction()`` and ``setMethod()`` methods to change this:: class TaskController extends AbstractController { - public function new() + public function new(): Response { // ... @@ -727,10 +735,11 @@ When building the form in a class, pass the action and method as form options:: use App\Form\TaskType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + // ... class TaskController extends AbstractController { - public function new() + public function new(): Response { // ... @@ -775,10 +784,11 @@ method:: use App\Form\TaskType; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + // ... class TaskController extends AbstractController { - public function new() + public function new(): Response { $task = ...; $form = $this->get('form.factory')->createNamed('my_name', TaskType::class, $task); @@ -839,7 +849,7 @@ pass ``null`` to it, to enable Symfony's "guessing mechanism":: class TaskType extends AbstractType { - public function buildForm(FormBuilderInterface $builder, array $options) + public function buildForm(FormBuilderInterface $builder, array $options): void { $builder // if you don't define field options, you can omit the second argument @@ -897,16 +907,20 @@ If you need extra fields in the form that won't be stored in the object (for example to add an *"I agree with these terms"* checkbox), set the ``mapped`` option to ``false`` in those fields:: + // ... use Symfony\Component\Form\FormBuilderInterface; - public function buildForm(FormBuilderInterface $builder, array $options) + class TaskType extends AbstractType { - $builder - ->add('task') - ->add('dueDate') - ->add('agreeTerms', CheckboxType::class, ['mapped' => false]) - ->add('save', SubmitType::class) - ; + public function buildForm(FormBuilderInterface $builder, array $options): void + { + $builder + ->add('task') + ->add('dueDate') + ->add('agreeTerms', CheckboxType::class, ['mapped' => false]) + ->add('save', SubmitType::class) + ; + } } These "unmapped fields" can be set and accessed in a controller with:: From 8f8621d99c344a3937f505ca12fade3a6e95f04a Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 8 Nov 2020 15:05:59 +0100 Subject: [PATCH 0163/5766] Added PHP types to the DI related articles --- service_container.rst | 4 ++-- service_container/autowiring.rst | 19 +++++++++++-------- service_container/calls.rst | 4 ++-- service_container/compiler_passes.rst | 4 ++-- service_container/configurators.rst | 8 ++++---- service_container/factories.rst | 4 ++-- service_container/injection_types.rst | 6 +++--- service_container/optional_dependencies.rst | 2 +- service_container/parent_services.rst | 2 +- .../service_subscribers_locators.rst | 12 ++++++------ service_container/synthetic_services.rst | 2 +- service_container/tags.rst | 18 ++++++++++-------- 12 files changed, 45 insertions(+), 40 deletions(-) diff --git a/service_container.rst b/service_container.rst index ff80ac27a14..09e26cd4d0b 100644 --- a/service_container.rst +++ b/service_container.rst @@ -340,7 +340,7 @@ you can type-hint the new ``SiteUpdateManager`` class and use it:: // src/Controller/SiteController.php namespace App\Controller; - + // ... use App\Service\SiteUpdateManager; @@ -378,7 +378,7 @@ example, suppose you want to make the admin email configurable: + private $adminEmail; - public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer) - + public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer, $adminEmail) + + public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer, string $adminEmail) { // ... + $this->adminEmail = $adminEmail; diff --git a/service_container/autowiring.rst b/service_container/autowiring.rst index 167fb4562f4..04058c6b9ac 100644 --- a/service_container/autowiring.rst +++ b/service_container/autowiring.rst @@ -29,7 +29,7 @@ Start by creating a ROT13 transformer class:: class Rot13Transformer { - public function transform($value) + public function transform(string $value): string { return str_rot13($value); } @@ -41,6 +41,7 @@ And now a Twitter client using this transformer:: namespace App\Service; use App\Util\Rot13Transformer; + // ... class TwitterClient { @@ -51,7 +52,7 @@ And now a Twitter client using this transformer:: $this->transformer = $transformer; } - public function tweet($user, $key, $status) + public function tweet(User $user, string $key, string $status): void { $transformedStatus = $this->transformer->transform($status); @@ -129,6 +130,8 @@ Now, you can use the ``TwitterClient`` service immediately in a controller:: use App\Service\TwitterClient; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; class DefaultController extends AbstractController @@ -136,7 +139,7 @@ Now, you can use the ``TwitterClient`` service immediately in a controller:: /** * @Route("/tweet", methods={"POST"}) */ - public function tweet(TwitterClient $twitterClient) + public function tweet(TwitterClient $twitterClient, Request $request): Response { // fetch $user, $key, $status from the POST'ed data @@ -288,7 +291,7 @@ To follow this best practice, suppose you decide to create a ``TransformerInterf interface TransformerInterface { - public function transform($value); + public function transform(string $value): string; } Then, you update ``Rot13Transformer`` to implement it:: @@ -388,7 +391,7 @@ Suppose you create a second class - ``UppercaseTransformer`` that implements class UppercaseTransformer implements TransformerInterface { - public function transform($value) + public function transform(string $value): string { return strtoupper($value); } @@ -426,7 +429,7 @@ the injection:: $this->transformer = $shoutyTransformer; } - public function toot($user, $key, $status) + public function toot(User $user, string $key, string $status): void { $transformedStatus = $this->transformer->transform($status); @@ -565,12 +568,12 @@ to inject the ``logger`` service, and decide to use setter-injection:: /** * @required */ - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { $this->logger = $logger; } - public function transform($value) + public function transform(string $value): string { $this->logger->info('Transforming '.$value); // ... diff --git a/service_container/calls.rst b/service_container/calls.rst index 00069a2ccb2..78418aadf13 100644 --- a/service_container/calls.rst +++ b/service_container/calls.rst @@ -22,7 +22,7 @@ example:: { private $logger; - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { $this->logger = $logger; } @@ -97,7 +97,7 @@ instead of mutating the object they were called on:: /** * @return static */ - public function withLogger(LoggerInterface $logger) + public function withLogger(LoggerInterface $logger): self { $new = clone $this; $new->logger = $logger; diff --git a/service_container/compiler_passes.rst b/service_container/compiler_passes.rst index 4d959e93dc6..79f666a4237 100644 --- a/service_container/compiler_passes.rst +++ b/service_container/compiler_passes.rst @@ -52,7 +52,7 @@ and process the services inside the ``process()`` method:: // ... - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { // in this method you can manipulate the service container: // for example, changing some container service: @@ -81,7 +81,7 @@ method in the extension):: class MyBundle extends Bundle { - public function build(ContainerBuilder $container) + public function build(ContainerBuilder $container): void { parent::build($container); diff --git a/service_container/configurators.rst b/service_container/configurators.rst index 92c1afc5794..5331d0ba7ac 100644 --- a/service_container/configurators.rst +++ b/service_container/configurators.rst @@ -28,7 +28,7 @@ You start defining a ``NewsletterManager`` class like this:: { private $enabledFormatters; - public function setEnabledFormatters(array $enabledFormatters) + public function setEnabledFormatters(array $enabledFormatters): void { $this->enabledFormatters = $enabledFormatters; } @@ -45,7 +45,7 @@ and also a ``GreetingCardManager`` class:: { private $enabledFormatters; - public function setEnabledFormatters(array $enabledFormatters) + public function setEnabledFormatters(array $enabledFormatters): void { $this->enabledFormatters = $enabledFormatters; } @@ -65,7 +65,7 @@ in the application:: { // ... - public function getEnabledFormatters() + public function getEnabledFormatters(): array { // code to configure which formatters to use $enabledFormatters = [...]; @@ -92,7 +92,7 @@ to create a configurator class to configure these instances:: $this->formatterManager = $formatterManager; } - public function configure(EmailFormatterAwareInterface $emailManager) + public function configure(EmailFormatterAwareInterface $emailManager): void { $emailManager->setEnabledFormatters( $this->formatterManager->getEnabledFormatters() diff --git a/service_container/factories.rst b/service_container/factories.rst index f6ccd5a1198..9f01e7dc7a6 100644 --- a/service_container/factories.rst +++ b/service_container/factories.rst @@ -26,7 +26,7 @@ object by calling the static ``createNewsletterManager()`` method:: class NewsletterManagerStaticFactory { - public static function createNewsletterManager() + public static function createNewsletterManager(): NewsletterManager { $newsletterManager = new NewsletterManager(); @@ -180,7 +180,7 @@ factory service can be used as a callback:: // ... class InvokableNewsletterManagerFactory { - public function __invoke() + public function __invoke(): NewsletterManager { $newsletterManager = new NewsletterManager(); diff --git a/service_container/injection_types.rst b/service_container/injection_types.rst index 097540bd8f6..6b7b74d1d24 100644 --- a/service_container/injection_types.rst +++ b/service_container/injection_types.rst @@ -130,7 +130,7 @@ by cloning the original service, this approach allows you to make a service immu * @required * @return static */ - public function withMailer(MailerInterface $mailer) + public function withMailer(MailerInterface $mailer): self { $new = clone $this; $new->mailer = $mailer; @@ -224,7 +224,7 @@ that accepts the dependency:: // src/Mail/NewsletterManager.php namespace App\Mail; - + // ... class NewsletterManager { @@ -233,7 +233,7 @@ that accepts the dependency:: /** * @required */ - public function setMailer(MailerInterface $mailer) + public function setMailer(MailerInterface $mailer): void { $this->mailer = $mailer; } diff --git a/service_container/optional_dependencies.rst b/service_container/optional_dependencies.rst index ca702176341..b981877a942 100644 --- a/service_container/optional_dependencies.rst +++ b/service_container/optional_dependencies.rst @@ -113,7 +113,7 @@ In YAML, the special ``@?`` syntax tells the service container that the dependency is optional. The ``NewsletterManager`` must also be rewritten by adding a ``setLogger()`` method:: - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { // ... } diff --git a/service_container/parent_services.rst b/service_container/parent_services.rst index 561721a2a8a..de0d5658b15 100644 --- a/service_container/parent_services.rst +++ b/service_container/parent_services.rst @@ -26,7 +26,7 @@ you may have multiple repository classes which need the $this->objectManager = $objectManager; } - public function setLogger(LoggerInterface $logger) + public function setLogger(LoggerInterface $logger): void { $this->logger = $logger; } diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index a9579bcfcc3..2fc0ec54fb1 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -87,7 +87,7 @@ a PSR-11 ``ContainerInterface``:: $this->locator = $locator; } - public static function getSubscribedServices() + public static function getSubscribedServices(): array { return [ 'App\FooCommand' => FooHandler::class, @@ -130,7 +130,7 @@ service locator:: use Psr\Log\LoggerInterface; - public static function getSubscribedServices() + public static function getSubscribedServices(): array { return [ // ... @@ -142,7 +142,7 @@ Service types can also be keyed by a service name for internal use:: use Psr\Log\LoggerInterface; - public static function getSubscribedServices() + public static function getSubscribedServices(): array { return [ // ... @@ -159,7 +159,7 @@ typically happens when extending ``AbstractController``:: class MyController extends AbstractController { - public static function getSubscribedServices() + public static function getSubscribedServices(): array { return array_merge(parent::getSubscribedServices(), [ // ... @@ -176,7 +176,7 @@ errors if there's no matching service found in the service container:: use Psr\Log\LoggerInterface; - public static function getSubscribedServices() + public static function getSubscribedServices(): array { return [ // ... @@ -395,7 +395,7 @@ will share identical locators among all the services referencing them:: use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Reference; - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { // ... diff --git a/service_container/synthetic_services.rst b/service_container/synthetic_services.rst index 5a3ea59d276..59869d5d7f3 100644 --- a/service_container/synthetic_services.rst +++ b/service_container/synthetic_services.rst @@ -18,7 +18,7 @@ from within the ``Kernel`` class:: { // ... - protected function initializeContainer() + protected function initializeContainer(): void { // ... $this->container->set('kernel', $this); diff --git a/service_container/tags.rst b/service_container/tags.rst index bbe7df1af6b..8bddd65c795 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -126,7 +126,7 @@ In a Symfony application, call this method in your kernel class:: { // ... - protected function build(ContainerBuilder $container) + protected function build(ContainerBuilder $container): void { $container->registerForAutoconfiguration(CustomInterface::class) ->addTag('app.custom_tag') @@ -142,7 +142,7 @@ In a Symfony bundle, call this method in the ``load()`` method of the { // ... - public function load(array $configs, ContainerBuilder $container) + public function load(array $configs, ContainerBuilder $container): void { $container->registerForAutoconfiguration(CustomInterface::class) ->addTag('app.custom_tag') @@ -178,7 +178,7 @@ To begin with, define the ``TransportChain`` class:: $this->transports = []; } - public function addTransport(\Swift_Transport $transport) + public function addTransport(\Swift_Transport $transport): void { $this->transports[] = $transport; } @@ -304,7 +304,7 @@ container for any services with the ``app.mail_transport`` tag:: class MailTransportPass implements CompilerPassInterface { - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { // always first check if the primary service is defined if (!$container->has(TransportChain::class)) { @@ -341,7 +341,7 @@ or from your kernel:: { // ... - protected function build(ContainerBuilder $container) + protected function build(ContainerBuilder $container): void { $container->addCompilerPass(new MailTransportPass()); } @@ -372,16 +372,18 @@ To begin with, change the ``TransportChain`` class:: $this->transports = []; } - public function addTransport(\Swift_Transport $transport, $alias) + public function addTransport(\Swift_Transport $transport, $alias): void { $this->transports[$alias] = $transport; } - public function getTransport($alias) + public function getTransport($alias): ?\Swift_Transport { if (array_key_exists($alias, $this->transports)) { return $this->transports[$alias]; } + + return null; } } @@ -476,7 +478,7 @@ use this, update the compiler:: class TransportCompilerPass implements CompilerPassInterface { - public function process(ContainerBuilder $container) + public function process(ContainerBuilder $container): void { // ... From 68813a00f5b3b910789b06117a45fc083f251a90 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sat, 4 Apr 2020 18:06:14 +0200 Subject: [PATCH 0164/5766] [Form] Added explicit `getParent()` call in types inheritance mechanism --- form/create_custom_field_type.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/form/create_custom_field_type.rst b/form/create_custom_field_type.rst index 59816006041..f622d11c1e4 100644 --- a/form/create_custom_field_type.rst +++ b/form/create_custom_field_type.rst @@ -144,13 +144,23 @@ These are the most important methods that a form type class can define: ``configureOptions()`` It defines the options configurable when using the form type, which are also - the options that can be used in ``buildForm()`` and ``buildView()`` methods. + the options that can be used in ``buildForm()`` and ``buildView()`` + methods. Options are inherited from parent types and parent type + extensions, but you can create any custom option you need. ``finishView()`` When creating a form type that consists of many fields, this method allows to modify the "view" of any of those fields. For any other use case, it's recommended to use instead the ``buildView()`` method. +``getParent()`` + It returns a form type class name that is defined as the parent. All + the other form type methods will be called with this parent type, and + all its type extensions, before calling the ones defined in your custom + type. + By default, all classes extend the ``AbstractType`` class, which + defines the ``FormType`` as the parent type. + Defining the Form Type ~~~~~~~~~~~~~~~~~~~~~~ From 97c94d77f4096b140da3ad303f7f3e9fa0ecdcb0 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 17:38:17 +0100 Subject: [PATCH 0165/5766] Updated getParent() description with the why/when (thanks javier!) --- form/create_custom_field_type.rst | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/form/create_custom_field_type.rst b/form/create_custom_field_type.rst index f622d11c1e4..2d13673be33 100644 --- a/form/create_custom_field_type.rst +++ b/form/create_custom_field_type.rst @@ -55,13 +55,10 @@ By convention they are stored in the ``src/Form/Type/`` directory:: } } -The ``configureOptions()`` method, which is explained later in this article, -defines the options that can be configured for the form type and sets the -default value of those options. - -The ``getParent()`` method defines which is the form type used as the base of -this type. In this case, the type extends from ``ChoiceType`` to reuse all of -the logic and rendering of that field type. +The methods of the ``FormTypeInterface`` are explained in detail later in +this article. Here, ``getParent()`` method defines the base type +(``ChoiceType``) and ``configureOptions()`` overrides some of its options. +The resulting form type is a choice field with predefined choices. .. note:: @@ -154,12 +151,16 @@ These are the most important methods that a form type class can define: recommended to use instead the ``buildView()`` method. ``getParent()`` - It returns a form type class name that is defined as the parent. All - the other form type methods will be called with this parent type, and - all its type extensions, before calling the ones defined in your custom - type. - By default, all classes extend the ``AbstractType`` class, which - defines the ``FormType`` as the parent type. + If your custom type is based on another type (i.e. they share some + functionality) add this method to return the fully-qualified class name + of that original type. Do not use PHP inheritance for this. + Symfony will call all the form type methods (``buildForm()``, + ``buildView()``, etc.) of the parent type and it will call all its type + extensions before calling the ones defined in your custom type. + + By default, the ``AbstractType`` class returns the generic + :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\FormType` + type, which is the root parent for all form types in the Form component. Defining the Form Type ~~~~~~~~~~~~~~~~~~~~~~ From ad317c3e5c2e21bed3b2f5d60625d659b057fe54 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 20:42:21 +0100 Subject: [PATCH 0166/5766] [#14565] Minor formatting fixes --- mailer.rst | 17 +++++++++-------- reference/configuration/framework.rst | 22 +++++++++++++++------- 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/mailer.rst b/mailer.rst index ebf79865a72..1472d2ce2fa 100644 --- a/mailer.rst +++ b/mailer.rst @@ -70,16 +70,17 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, If you are migrating from Swiftmailer (and the Swiftmailer bundle), be warned that the DSN format is different. -Using built-in transports +Using Built-in Transports ~~~~~~~~~~~~~~~~~~~~~~~~~ -============ ==================================== =========== -DSN protocol Example Description -============ ==================================== =========== -smtp smtp://user:pass@smtp.example.com:25 Mailer uses an SMTP server to send emails -sendmail sendmail://default Mailer uses the local sendmail binary to send emails -============ ==================================== =========== - +============ ======================================== ============================== +DSN protocol Example Description +============ ======================================== ============================== +smtp ``smtp://user:pass@smtp.example.com:25`` Mailer uses an SMTP server to + send emails +sendmail ``sendmail://default`` Mailer uses the local sendmail + binary to send emails +============ ======================================== ============================== Using a 3rd Party Transport ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 255adc11fec..a1692037b12 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -2906,21 +2906,27 @@ Name of the lock you want to create. mailer ~~~~~~ +.. versionadded:: 4.3 + + The ``mailer`` settings were introduced in Symfony 4.3. + .. _mailer-dsn: dsn ... -**type**: ``string`` +**type**: ``string`` **default**: ``null`` -The DSN used by the mailer. When several DSN may be used, use `transports` (see below) instead. +The DSN used by the mailer. When several DSN may be used, use +``transports`` option (see below) instead. transports .......... **type**: ``array`` -A :ref:`list of DSN ` that can be used by the mailer. A transport name is the key and the dsn is the value. +A :ref:`list of DSN ` that can be used by the +mailer. A transport name is the key and the dsn is the value. envelope ........ @@ -2930,14 +2936,16 @@ sender **type**: ``string`` -Sender used by the ``Mailer``. Keep in mind that this setting override a sender set in the code. +Sender used by the ``Mailer``. Keep in mind that this setting override a +sender set in the code. recipients """""""""" **type**: ``array`` -Recipients used by the ``Mailer``. Keep in mind that this setting override recipients set in the code. +Recipients used by the ``Mailer``. Keep in mind that this setting override +recipients set in the code. .. configuration-block:: @@ -2963,8 +2971,8 @@ Recipients used by the ``Mailer``. Keep in mind that this setting override recip - admin@symfony.com - lead@symfony.com + admin@symfony.com + lead@symfony.com From 676403e7020add302de8df03e7f37c87211ea4d8 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 20:42:54 +0100 Subject: [PATCH 0167/5766] Removed 4.3 versionadded directive --- reference/configuration/framework.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 9086078e30f..5d3f3cf1fde 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -2797,10 +2797,6 @@ Name of the lock you want to create. mailer ~~~~~~ -.. versionadded:: 4.3 - - The ``mailer`` settings were introduced in Symfony 4.3. - .. _mailer-dsn: dsn From 34ad0b779d7a2fde362d86a0032732defb0e1539 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 20:47:25 +0100 Subject: [PATCH 0168/5766] [#14083] Revert mailer.headers option in 4.4 - 5.1 --- reference/configuration/framework.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index a1692037b12..e61e0e1365d 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -160,8 +160,6 @@ Configuration * `sender`_ * `recipients`_ - * :ref:`headers ` - * `php_errors`_ * `log`_ @@ -2996,16 +2994,6 @@ recipients set in the code. ]); }; -.. _mailer-headers: - -headers -....... - -**type**: ``array`` - -Headers to add to emails. key (``name`` attribute in xml format) -is the header name and value the header value. - workflows ~~~~~~~~~ From 1da6b0b5e30017e126228a94893ce505ccbeb270 Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Mon, 17 Aug 2020 09:10:48 +0200 Subject: [PATCH 0169/5766] Complete documentation about mailer integration --- mailer.rst | 4 +++- reference/configuration/framework.rst | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index ac768b09cde..8cab1b50659 100644 --- a/mailer.rst +++ b/mailer.rst @@ -46,6 +46,7 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, 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"> + @@ -55,6 +56,7 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, // config/packages/mailer.php use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; + return static function (ContainerConfigurator $containerConfigurator): void { $containerConfigurator->extension('framework', [ 'mailer' => [ @@ -83,7 +85,7 @@ sendmail ``sendmail://default`` Mailer uses the local se Using a 3rd Party Transport ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Instead of using your own SMTP server, you can send emails via a 3rd party +Instead of using your own SMTP server or sendmail binary, you can send emails via a 3rd party provider. Mailer supports several - install whichever you want: ================== ============================================= diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 3174485f516..8fc30e2712a 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -155,6 +155,7 @@ Configuration * :ref:`dsn ` * `transports`_ + * `message_bus`_ * `envelope`_ * `sender`_ @@ -846,6 +847,8 @@ can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM- .. _http-headers: +.. _http-headers: + headers ....... @@ -2813,6 +2816,18 @@ transports A :ref:`list of DSN ` that can be used by the mailer. A transport name is the key and the dsn is the value. +message_bus +........... + +.. versionadded:: 5.1 + + The ``message_bus`` option was introduced in Symfony 5.1. + +**type**: ``string`` **default**: ``null`` or default bus if Messenger component is installed + +Service identifier of the message bus to use when using the +:doc:`Messenger component ` (e.g. ``messenger.default_bus``). + envelope ........ @@ -2867,6 +2882,7 @@ recipients set in the code. // config/packages/mailer.php namespace Symfony\Component\DependencyInjection\Loader\Configurator; + return static function (ContainerConfigurator $containerConfigurator): void { $containerConfigurator->extension('framework', [ 'mailer' => [ From a389dfb123e3bd9b6024399e21067c40822944ff Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Mon, 17 Aug 2020 09:10:48 +0200 Subject: [PATCH 0170/5766] Complete documentation about mailer integration --- mailer.rst | 20 +++++++++++++------- reference/configuration/framework.rst | 18 ++++++++++++++++-- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/mailer.rst b/mailer.rst index 200064fbbef..60575fed9e9 100644 --- a/mailer.rst +++ b/mailer.rst @@ -73,14 +73,20 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, Using Built-in Transports ~~~~~~~~~~~~~~~~~~~~~~~~~ -============ ======================================== ============================== +.. versionadded:: 5.2 + + The native protocol was introduced in Symfony 5.2. + +============ ======================================== ============================================================== DSN protocol Example Description -============ ======================================== ============================== -smtp ``smtp://user:pass@smtp.example.com:25`` Mailer uses an SMTP server to - send emails -sendmail ``sendmail://default`` Mailer uses the local sendmail - binary to send emails -============ ======================================== ============================== +============ ======================================== ============================================================== +smtp ``smtp://user:pass@smtp.example.com:25`` Mailer uses an SMTP server to send emails +sendmail ``sendmail://default`` Mailer uses the local sendmail binary to send emails +native ``native://default`` Mailer uses the sendmail binary and options configured + in the ``sendmail_path`` setting of ``php.ini``. On Windows + hosts, Mailer fallbacks to ``smtp`` and ``smtp_port`` + ``php.ini`` settings when ``sendmail_path`` is not configured. +============ ======================================== ============================================================== Using a 3rd Party Transport ~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 38388ad21f9..fdc11499c4b 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -184,6 +184,8 @@ Configuration * `sender`_ * `recipients`_ + * :ref:`headers ` + * `php_errors`_ * `log`_ @@ -927,8 +929,6 @@ This setting is automatically set to true when one of the child settings is conf .. _http-headers: -.. _http-headers: - headers ....... @@ -3091,6 +3091,20 @@ recipients set in the code. ]); }; +.. _mailer-headers: + +headers +....... + +.. versionadded:: 5.2 + + The ``headers`` mailer option was introduced in Symfony 5.2. + +**type**: ``array`` + +Headers to add to emails. The key (``name`` attribute in xml format) is the +header name and value the header value. + workflows ~~~~~~~~~ From 6b04c5f824e178cb6b0d9575b2068a0c56839c7e Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 21:09:19 +0100 Subject: [PATCH 0171/5766] Removed duplicated line --- reference/configuration/framework.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 8fc30e2712a..0780b49b0b9 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -847,8 +847,6 @@ can be separated by colons, commas or spaces (e.g. ``'RC4-SHA:TLS13-AES-128-GCM- .. _http-headers: -.. _http-headers: - headers ....... From 034727f94ce8f1247d3ea7c18ff1bb2730522a41 Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Sat, 21 Nov 2020 18:34:04 +0100 Subject: [PATCH 0172/5766] [Form] Fixed the layout in the forms page by moving the configuration tabs outside the versionadded block. --- forms.rst | 65 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 30 deletions(-) diff --git a/forms.rst b/forms.rst index f7acdd18fe2..832a11ca075 100644 --- a/forms.rst +++ b/forms.rst @@ -560,46 +560,51 @@ To see the second approach - adding constraints to the form - and to learn more about the validation constraints, please refer to the :doc:`Symfony validation documentation `. +Form Validation Messages +~~~~~~~~~~~~~~~~~~~~~~~~ + .. versionadded:: 5.2 - In Symfony 5.2, the form validation messages have been rewritten to be more - user-friendly. Set the ``legacy_error_messages`` option to ``false`` to - enable these new messages: + The ``framework.form.legacy_error_messages`` option was introduced in Symfony 5.2 - .. configuration-block:: +The form validation messages have been rewritten to be more user-friendly. +To enable these new messages set the ``legacy_error_messages`` option in ``framework``, +``form`` to ``false``: + +.. configuration-block:: - .. code-block:: yaml + .. code-block:: yaml - # config/packages/framework.yaml - framework: - form: - legacy_error_messages: false + # config/packages/framework.yaml + framework: + form: + legacy_error_messages: false - .. code-block:: xml + .. code-block:: xml - - - + + + - - - - + + + + - .. code-block:: php + .. code-block:: php - // config/packages/framework.php - $container->loadFromExtension('framework', [ - 'form' => [ - 'legacy-error-messages' => false, - ], - ]); + // config/packages/framework.php + $container->loadFromExtension('framework', [ + 'form' => [ + 'legacy_error_messages' => false, + ], + ]); Other Common Form Features -------------------------- From c4b9fc43192dbec06c0646b18b9afa529537f664 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 23:11:15 +0100 Subject: [PATCH 0173/5766] [#14589] Reworded form error messages paragraph --- forms.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/forms.rst b/forms.rst index 832a11ca075..f6935d3d107 100644 --- a/forms.rst +++ b/forms.rst @@ -565,11 +565,11 @@ Form Validation Messages .. versionadded:: 5.2 - The ``framework.form.legacy_error_messages`` option was introduced in Symfony 5.2 + The ``legacy_error_messages`` option was introduced in Symfony 5.2 -The form validation messages have been rewritten to be more user-friendly. -To enable these new messages set the ``legacy_error_messages`` option in ``framework``, -``form`` to ``false``: +The form types have default error messages that are more clear and +user-friendly than the ones provided by the validation constraints. To enable +these new messages set the ``legacy_error_messages`` option to ``false``: .. configuration-block:: From b6777219bd16a04857f4cf3570a852fca5def089 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 21 Nov 2020 23:14:00 +0100 Subject: [PATCH 0174/5766] Fixed build --- reference/configuration/framework.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 5d9459ce97d..fdc11499c4b 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -927,6 +927,8 @@ enabled 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. +.. _http-headers: + headers ....... From 5e21b791992e8534ac28c94df453fda0e0a6c621 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 21 Nov 2020 19:45:29 +0100 Subject: [PATCH 0175/5766] Added a new troubleshooting section in the maintainer guide --- _build/maintainer_guide.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/_build/maintainer_guide.rst b/_build/maintainer_guide.rst index 7eff3143941..f5913a8e811 100644 --- a/_build/maintainer_guide.rst +++ b/_build/maintainer_guide.rst @@ -335,6 +335,23 @@ in the tree as follows: $ git push origin $ git push upstream +Merging in the wrong branch +........................... + +A Pull Request was made against ``5.x`` but it should be merged in ``5.1`` and you +forgot to merge as ``gh merge NNNNN -s 5.1`` to change the merge branch. Solution: + +.. code-block:: terminal + + $ git checkout 5.1 + $ git cherry-pick -m 1 + $ git checkout 5.x + $ git revert -m 1 + # now continue with the normal "upmerging" + $ git checkout 5.2 + $ git merge 5.1 + $ ... + .. _`symfony/symfony-docs`: https://github.com/symfony/symfony-docs .. _`Symfony Docs team`: https://github.com/orgs/symfony/teams/team-symfony-docs .. _`Symfony's respectful review comments`: https://symfony.com/doc/current/contributing/community/review-comments.html From 444072509418d6e63acee31efbc18477eb8e5d2b Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Sun, 15 Nov 2020 22:18:17 +0100 Subject: [PATCH 0176/5766] Section method only in ConsoleOutputInterface --- console.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/console.rst b/console.rst index ad9bb8c16e6..f49296cd47f 100644 --- a/console.rst +++ b/console.rst @@ -181,8 +181,18 @@ which returns an instance of { protected function execute(InputInterface $input, OutputInterface $output) { + // The section() method is only available in classes that implement ConsoleOutputInterface + if (!$output instanceof ConsoleOutputInterface) { + throw new LogicException(sprintf( + 'This command accepts only an instance of "%s", an instance of "%s" is given', + ConsoleOutputInterface::class, + \get_class($output) + )); + } + $section1 = $output->section(); $section2 = $output->section(); + $section1->writeln('Hello'); $section2->writeln('World!'); // Output displays "Hello\nWorld!\n" From 73f02f17d5e0ea2044e83f393dddd48f4d5a6711 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 22 Nov 2020 12:51:16 +0100 Subject: [PATCH 0177/5766] [#14550] Reduce nr of lines used for exception --- console.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/console.rst b/console.rst index f49296cd47f..f14765ce624 100644 --- a/console.rst +++ b/console.rst @@ -173,21 +173,19 @@ called "output sections". Create one or more of these sections when you need to clear and overwrite the output information. Sections are created with the -:method:`Symfony\\Component\\Console\\Output\\ConsoleOutput::section` method, -which returns an instance of +:method:`ConsoleOutput::section() ` +method, which returns an instance of :class:`Symfony\\Component\\Console\\Output\\ConsoleSectionOutput`:: + // ... + use Symfony\Component\Console\Output\ConsoleOutputInterface; + class MyCommand extends Command { protected function execute(InputInterface $input, OutputInterface $output) { - // The section() method is only available in classes that implement ConsoleOutputInterface if (!$output instanceof ConsoleOutputInterface) { - throw new LogicException(sprintf( - 'This command accepts only an instance of "%s", an instance of "%s" is given', - ConsoleOutputInterface::class, - \get_class($output) - )); + throw new \LogicException('This command accepts only an instance of "ConsoleOutputInterface".'); } $section1 = $output->section(); From 62c7f2b6ba2ff1a229dc62c3b8b831cdb2378dd9 Mon Sep 17 00:00:00 2001 From: Martin Hujer Date: Thu, 21 Nov 2019 22:17:29 +0100 Subject: [PATCH 0178/5766] Security: add example code which Maker Bundle generated See #11265 --- security.rst | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/security.rst b/security.rst index ebeca1b9b5b..070c18b687c 100644 --- a/security.rst +++ b/security.rst @@ -96,7 +96,59 @@ optional features, like :doc:`remember me ` and :doc:`impersonation `. Fortunately, the ``make:user`` command already configured one for you in your -``security.yaml`` file under the ``providers`` key. +``security.yaml`` file under the ``providers`` key: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/security.yaml + security: + # ... + + providers: + # used to reload user from session & other features (e.g. switch_user) + app_user_provider: + entity: + class: App\Entity\User + property: email + + .. code-block:: xml + + + + + + + + + + + + + + .. code-block:: php + + // config/packages/security.php + use App\Entity\User; + + $container->loadFromExtension('security', [ + // ... + + 'providers' => [ + // used to reload user from session & other features (e.g. switch_user) + 'app_user_provider' => [ + 'entity' => [ + 'class' => User::class, + 'property' => 'email', + ], + ], + ], + ]); If your ``User`` class is an entity, you don't need to do anything else. But if your class is *not* an entity, then ``make:user`` will also have generated a From d291a99ee339d3b4b0fb33c825f2a76b6ce867be Mon Sep 17 00:00:00 2001 From: CvekCoding <36374606+CvekCoding@users.noreply.github.com> Date: Mon, 24 Feb 2020 21:16:59 +0300 Subject: [PATCH 0179/5766] Bus restricting with Interfaces Proposed more flexible way to restrict handlers with buses - use interfaces for this. --- messenger/multiple_buses.rst | 79 +++++++++++++++++++++--------------- service_container/tags.rst | 2 + 2 files changed, 48 insertions(+), 33 deletions(-) diff --git a/messenger/multiple_buses.rst b/messenger/multiple_buses.rst index 5136553dac2..c79aeb7b2b7 100644 --- a/messenger/multiple_buses.rst +++ b/messenger/multiple_buses.rst @@ -150,30 +150,30 @@ you can restrict each handler to a specific bus using the ``messenger.message_ha This way, the ``App\MessageHandler\SomeCommandHandler`` handler will only be known by the ``command.bus`` bus. -You can also automatically add this tag to a number of classes by following -a naming convention and registering all of the handler services by name with -the correct tag: +You can also automatically add this tag to a number of classes by using +the :ref:`_instanceof service configuration `. Using this, +you can determine the message bus based on an implemented interface: .. configuration-block:: .. code-block:: yaml # config/services.yaml + services: + # ... + + _instanceof: + # all services implementing the CommandHandlerInterface + # will be registered on the command.bus bus + App\MessageHandler\CommandHandlerInterface: + tags: + - { name: messenger.message_handler, bus: command.bus } - # put this after the "App\" line that registers all your services - command_handlers: - namespace: App\MessageHandler\ - resource: '%kernel.project_dir%/src/MessageHandler/*CommandHandler.php' - autoconfigure: false - tags: - - { name: messenger.message_handler, bus: command.bus } - - query_handlers: - namespace: App\MessageHandler\ - resource: '%kernel.project_dir%/src/MessageHandler/*QueryHandler.php' - autoconfigure: false - tags: - - { name: messenger.message_handler, bus: query.bus } + # while those implementing QueryHandlerInterface will be + # registered on the query.bus bus + App\MessageHandler\QueryHandlerInterface: + tags: + - { name: messenger.message_handler, bus: query.bus } .. code-block:: xml @@ -185,32 +185,45 @@ the correct tag: https://symfony.com/schema/dic/services/services-1.0.xsd"> - - + + + + - - - + + + + - + .. code-block:: php // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; - // Command handlers - $container->services() - ->load('App\MessageHandler\\', '%kernel.project_dir%/src/MessageHandler/*CommandHandler.php') - ->autoconfigure(false) - ->tag('messenger.message_handler', ['bus' => 'command.bus']); + use App\MessageHandler\CommandHandlerInterface; + use App\MessageHandler\QueryHandlerInterface; - // Query handlers - $container->services() - ->load('App\MessageHandler\\', '%kernel.project_dir%/src/MessageHandler/*QueryHandler.php') - ->autoconfigure(false) - ->tag('messenger.message_handler', ['bus' => 'query.bus']); + return function(ContainerConfigurator $configurator) { + $services = $configurator->services(); + + // ... + + // all services implementing the CommandHandlerInterface + // will be registered on the command.bus bus + $services->instanceof(CommandHandlerInterface::class) + ->tag('messenger.message_handler', ['bus' => 'command.bus']); + + // while those implementing QueryHandlerInterface will be + // registered on the query.bus bus + $services->instanceof(QueryHandlerInterface::class) + ->tag('messenger.message_handler', ['bus' => 'query.bus']); + }; Debugging the Buses ------------------- diff --git a/service_container/tags.rst b/service_container/tags.rst index 8bddd65c795..2f60f369b97 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -60,6 +60,8 @@ and many tags require additional arguments (beyond the ``name`` parameter). **For most users, this is all you need to know**. If you want to go further and learn how to create your own custom tags, keep reading. +.. _di-instanceof: + Autoconfiguring Tags -------------------- From e059c5b1cff73ed25b0a0cba22402001b11b0959 Mon Sep 17 00:00:00 2001 From: Ben Davies Date: Mon, 10 Feb 2020 13:11:49 +0000 Subject: [PATCH 0180/5766] GitHub Actions: use docker container for CI build --- .github/workflows/ci.yaml | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 881b171ce10..8dbda8b72d8 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -14,30 +14,22 @@ jobs: runs-on: ubuntu-latest + container: python:3.7-alpine + steps: - name: "Checkout" uses: actions/checkout@v2 - - name: "Set up Python 3.7" - uses: actions/setup-python@v1 - with: - python-version: '3.7' # Semantic version range syntax or exact version of a Python version - - name: "Display Python version" run: python -c "import sys; print(sys.version)" - - name: "Install Sphinx dependencies" - run: sudo apt-get install python-dev build-essential + - name: "Install Sphinx" + run: pip install --user sphinx - - name: "Cache pip" - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('_build/.requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- + - name: "Install dependencies" + run: apk add --no-cache git make - - name: "Install Sphinx + requirements via pip" + - name: "Install custom requirements via pip" run: pip install -r _build/.requirements.txt - name: "Build documentation" From 935fa86e7b21988dd8bfc17ad9afc6d0605cdfff Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 23 Nov 2020 08:57:58 +0100 Subject: [PATCH 0181/5766] Enhancement: Streamline workflow --- .github/workflows/ci.yaml | 72 +++++++++++++++++++-------------------- 1 file changed, 36 insertions(+), 36 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8dbda8b72d8..f6cc2cff17d 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,3 +1,5 @@ +name: CI + on: push: branches-ignore: @@ -6,11 +8,9 @@ on: branches-ignore: - 'github-comments' -name: CI - jobs: - build: - name: Build + sphinx-build: + name: Build (Sphinx) runs-on: ubuntu-latest @@ -35,46 +35,46 @@ jobs: - name: "Build documentation" run: make -C _build SPHINXOPTS="-nqW -j auto" html - build-php: - name: Symfony doc builder + symfony-docs-builder-build: + name: Build (symfony/docs-builder) runs-on: ubuntu-latest continue-on-error: true steps: - - name: "Checkout" - uses: actions/checkout@v2 - - - name: "Set-up PHP" - uses: shivammathur/setup-php@v2 - with: - php-version: 7.2 - coverage: none - tools: "composer:v2" - - - name: Get composer cache directory - id: composercache - working-directory: _build - run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: ${{ steps.composercache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: ${{ runner.os }}-composer- - - - name: "Install dependencies" - working-directory: _build - run: composer install --prefer-dist --no-progress - - - name: "Build the docs" - working-directory: _build - run: php build.php -vvv + - name: "Checkout" + uses: actions/checkout@v2 + + - name: "Set-up PHP" + uses: shivammathur/setup-php@v2 + with: + php-version: 7.2 + coverage: none + tools: "composer:v2" + + - name: Get composer cache directory + id: composercache + working-directory: _build + run: echo "::set-output name=dir::$(composer config cache-files-dir)" + + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.composercache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: ${{ runner.os }}-composer- + + - name: "Install dependencies" + working-directory: _build + run: composer install --prefer-dist --no-progress + + - name: "Build the docs" + working-directory: _build + run: php build.php -vvv doctor-rst: - name: DOCtor-RST + name: Lint (DOCtor-RST) runs-on: ubuntu-latest From 17f9fbf0481b68cb8c87011fbb3c3aa5b08fd464 Mon Sep 17 00:00:00 2001 From: concilioinvest Date: Mon, 23 Nov 2020 22:22:25 +0100 Subject: [PATCH 0182/5766] Update event_dispatcher.rst It must be the `tag` method. --- event_dispatcher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/event_dispatcher.rst b/event_dispatcher.rst index 3462659efb5..2b95a637e28 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -109,7 +109,7 @@ using a special "tag": use App\EventListener\ExceptionListener; $container->register(ExceptionListener::class) - ->addTag('kernel.event_listener', ['event' => 'kernel.exception']) + ->tag('kernel.event_listener', ['event' => 'kernel.exception']) ; Symfony follows this logic to decide which method to call inside the event From 07230432e2a85a77ca575abb771e597b06b1ad28 Mon Sep 17 00:00:00 2001 From: Matthieu DANET Date: Tue, 24 Nov 2020 10:35:10 +0100 Subject: [PATCH 0183/5766] Fix wrong key name --- reference/forms/types/options/choice_attr.rst.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/forms/types/options/choice_attr.rst.inc b/reference/forms/types/options/choice_attr.rst.inc index b26f2099023..5a0add4f195 100644 --- a/reference/forms/types/options/choice_attr.rst.inc +++ b/reference/forms/types/options/choice_attr.rst.inc @@ -49,7 +49,7 @@ If an array, the keys of the ``choices`` array must be used as keys:: // ... $builder->add('choices', ChoiceType::class, [ - 'choice_label' => ChoiceList::attr($this, function (?Category $category) { + 'choice_attr' => ChoiceList::attr($this, function (?Category $category) { return $category ? ['data-uuid' => $category->getUuid()] : []; }), ]); From 322ce95fbfbcebbac88f06572518326ece0249a2 Mon Sep 17 00:00:00 2001 From: Fabien Salathe Date: Tue, 24 Nov 2020 11:58:07 +0100 Subject: [PATCH 0184/5766] Remove wrong "method" tag Method tag is not needed when the processor is invokable, here it would call `processRecord` which doesn't exist --- logging/processors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging/processors.rst b/logging/processors.rst index 9f46326ddaa..5f1e27834b5 100644 --- a/logging/processors.rst +++ b/logging/processors.rst @@ -103,7 +103,7 @@ information: $container ->register(SessionRequestProcessor::class) - ->addTag('monolog.processor', ['method' => 'processRecord']); + ->addTag('monolog.processor'); Finally, set the formatter to be used on whatever handler you want: From 691ed5fb2d94c775f08b7feece3833d1ba4f0dd7 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Tue, 24 Nov 2020 17:08:33 +0100 Subject: [PATCH 0185/5766] Update event_dispatcher.rst --- components/event_dispatcher.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/event_dispatcher.rst b/components/event_dispatcher.rst index 0344acf4e8e..ef0392e6dfc 100644 --- a/components/event_dispatcher.rst +++ b/components/event_dispatcher.rst @@ -313,7 +313,7 @@ order. Start by creating this custom event class and documenting it:: $this->order = $order; } - public function getOrder() + public function getOrder(): Order { return $this->order; } From 67eb42f6599876ae05c8b17cc7c25792350de662 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Tue, 24 Nov 2020 21:11:35 +0200 Subject: [PATCH 0186/5766] Fix package name for OvhCloud notifier --- notifier.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 9737df6395e..573ad0d942c 100644 --- a/notifier.rst +++ b/notifier.rst @@ -59,7 +59,7 @@ Service Package DSN ========== ================================ ==================================================== FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` Nexmo ``symfony/nexmo-notifier`` ``nexmo://KEY:SECRET@default?from=FROM`` -OvhCloud ``symfony/ovhcloud-notifier`` ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` +OvhCloud ``symfony/ovh-cloud-notifier`` ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` Sinch ``symfony/sinch-notifier`` ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM`` Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from=FROM`` ========== ================================ ==================================================== From 1aabce3c0d09b63ca8a6fb8c73dda47ce0a47ac9 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Sat, 21 Nov 2020 11:56:23 +0100 Subject: [PATCH 0187/5766] Add a note about exposing env vars for unrecognized Docker services --- setup/symfony_server.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index 0f4d88904d6..bd3a6718664 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -299,6 +299,9 @@ project. It understands that this is a MySQL service and creates environment variables accordingly with the service name (``database``) as a prefix: ``DATABASE_URL``, ``DATABASE_HOST``, ... +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 label to override the environment variables prefix: @@ -361,6 +364,20 @@ When Docker services are running, browse a page of your Symfony application and check the "Symfony Server" section in the web debug toolbar; you'll see that "Docker Compose" is "Up". +.. note:: + + If you don't want environment variables to be exposed for a service, set + the ``com.symfony.server.service-ignore`` label to ``true``: + + .. code-block:: yaml + + # docker-compose.yaml + services: + db: + ports: [3306] + labels: + com.symfony.server.service-ignore: true + If your Docker Compose file is not at the root of the project, use the ``COMPOSE_FILE`` and ``COMPOSE_PROJECT_NAME`` environment variables to define its location, same as for ``docker-compose``: From a18ef8d7c1aef993f69e76bca3423d245bbc932f Mon Sep 17 00:00:00 2001 From: postal Date: Wed, 25 Nov 2020 11:52:14 +0100 Subject: [PATCH 0188/5766] A method call is reversed The order of the methods is reversed. The method "advance()" must be called after the "setMessage()". --- components/console/helpers/progressbar.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/console/helpers/progressbar.rst b/components/console/helpers/progressbar.rst index 1aa4dbfc6e2..c8ef2f25a1f 100644 --- a/components/console/helpers/progressbar.rst +++ b/components/console/helpers/progressbar.rst @@ -362,8 +362,8 @@ placeholder before displaying the progress bar:: $progressBar->start(); // 0/100 -- Start - $progressBar->advance(); $progressBar->setMessage('Task is in progress...'); + $progressBar->advance(); // 1/100 -- Task is in progress... Messages can be combined with custom placeholders too. In this example, the From be63d709faaef0afde617d18a000b2b1b9fe7023 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 25 Nov 2020 15:59:25 +0100 Subject: [PATCH 0189/5766] Enhancement: Add /me to the CODEOWNERS file for GithubActions workflows --- .github/CODEOWNERS | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 51ce53a1a89..9eb5d91783b 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,3 +1,6 @@ +# GithubActions workflows +/.github/workflows* @OskarStark + # Console /console* @chalasr /components/console* @chalasr From 6b4bee4d17742e7c606f42685c7400531fca0110 Mon Sep 17 00:00:00 2001 From: Steven DUBOIS Date: Wed, 25 Nov 2020 16:41:57 +0100 Subject: [PATCH 0190/5766] Update events.rst --- doctrine/events.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doctrine/events.rst b/doctrine/events.rst index 309d10a7e12..c98be25d736 100644 --- a/doctrine/events.rst +++ b/doctrine/events.rst @@ -16,7 +16,7 @@ on other common tasks (e.g. ``loadClassMetadata``, ``onClear``). There are different ways to listen to these Doctrine events: -* **Lifecycle callbacks**, they are defined as methods on the entity classes and +* **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 methods for one or more events and they are called for all entities; @@ -46,7 +46,7 @@ to learn everything about them. Doctrine Lifecycle Callbacks ---------------------------- -Lifecycle callbacks are defined as methods inside the entity you want to modify. +Lifecycle callbacks are defined as public methods inside the entity you want to modify. For example, suppose you want to set a ``createdAt`` date column to the current date, but only when the entity is first persisted (i.e. inserted). To do so, define a callback for the ``prePersist`` Doctrine event: From def35a7da9d49d627906d69aac68e0d597ceba4a Mon Sep 17 00:00:00 2001 From: Nyholm Date: Mon, 23 Nov 2020 15:29:56 +0100 Subject: [PATCH 0191/5766] [Notifier] Add better example for Slack DSN --- notifier.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/notifier.rst b/notifier.rst index 9737df6395e..cad35611ec0 100644 --- a/notifier.rst +++ b/notifier.rst @@ -149,6 +149,8 @@ Chatters are configured using the ``chatter_transports`` setting: # .env SLACK_DSN=slack://default/ID + # If your slack webhook looks like "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" then use: + SLACK_DSN=slack://default/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX .. configuration-block:: From deec89a9352a62842553264327619c1ce32c3ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Schlu=CC=88ter?= Date: Thu, 26 Nov 2020 00:20:46 +0100 Subject: [PATCH 0192/5766] Delete duplicated words --- 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 2f60f369b97..db648334625 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -788,7 +788,7 @@ indexed by the ``key`` attribute: After compilation the ``HandlerCollection`` is able to iterate over your application handlers. To retrieve a specific service by it's ``key`` attribute -from the iterator, we can use ``iterator_to_array`` and retrieve the ``handler_two``: +from the iterator, we can use ``iterator_to_array`` to get an array and then retrieve the ``handler_two`` handler:: // src/Handler/HandlerCollection.php From cf8af6af4ab5f541b8f7bb155434cc769a1d301d Mon Sep 17 00:00:00 2001 From: Quentin Dequippe Date: Thu, 26 Nov 2020 09:54:54 +0100 Subject: [PATCH 0193/5766] Update messenger.rst --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index e9253431bd4..2f33d850cbc 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1202,7 +1202,7 @@ under the transport in ``messenger.yaml``: ====================== ====================================== =================================== ``access_key`` AWS access key ``account`` Identifier of the AWS account The owner of the credentials -``auto_setup`` Whether the table should be created ``true`` +``auto_setup`` Whether the queue should be created ``true`` automatically during send / get. ``buffer_size`` Number of messages to prefetch 9 ``endpoint`` Absolute URL to the SQS service https://sqs.eu-west-1.amazonaws.com From f1f44c4eaed18edc03e2f7b7360f7a5ad4cf6276 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 26 Nov 2020 10:55:19 +0100 Subject: [PATCH 0194/5766] Tweaks --- service_container/tags.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/service_container/tags.rst b/service_container/tags.rst index db648334625..23dd6472422 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -787,9 +787,9 @@ indexed by the ``key`` attribute: }; After compilation the ``HandlerCollection`` is able to iterate over your -application handlers. To retrieve a specific service by it's ``key`` attribute -from the iterator, we can use ``iterator_to_array`` -to get an array and then retrieve the ``handler_two`` handler:: +application handlers. To retrieve a specific service from the iterator, call the +``iterator_to_array()`` function and then use the ``key`` attribute to get the +array element. For example, to retrieve the ``handler_two`` handler:: // src/Handler/HandlerCollection.php namespace App\Handler; From dd8afa5117cf762f65c6333e09111976116c246b Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Thu, 26 Nov 2020 11:09:04 +0100 Subject: [PATCH 0195/5766] Update performance.rst --- performance.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/performance.rst b/performance.rst index de0d7883a04..8d3eb05d2c0 100644 --- a/performance.rst +++ b/performance.rst @@ -209,6 +209,8 @@ deployment process too): used in your application and prevents Composer from scanning the file system for classes that are not found in the class map. (see: `Composer's autoloader optimization`_). +You can also use the ``--classmap-authoritative`` option with the ``composer install`` command. + .. _profiling-applications: Profiling Symfony Applications From 7c9ffd764ec1d5a9071ade291543935220cd0f6e Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Fri, 27 Nov 2020 00:11:24 +0100 Subject: [PATCH 0196/5766] Fixing uppercase typo --- 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 eebfd087fb0..72bd3d17599 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -1,7 +1,7 @@ .. index:: single: Validation; Custom constraints -How to Create a custom Validation Constraint +How to Create a Custom Validation Constraint ============================================ You can create a custom constraint by extending the base constraint class, From 1ffc0f7208d11859b78257ec9a22ae56b80b5250 Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Fri, 27 Nov 2020 09:52:07 +0100 Subject: [PATCH 0197/5766] Update database.rst hello, i add missing quotes. --- testing/database.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/database.rst b/testing/database.rst index d2e0b18f24c..7e3acfd1db7 100644 --- a/testing/database.rst +++ b/testing/database.rst @@ -15,7 +15,7 @@ your project and define the new value for the ``DATABASE_URL`` env var: .. code-block:: bash # .env.test.local - DATABASE_URL=mysql://USERNAME:PASSWORD@127.0.0.1:3306/DB_NAME?serverVersion=5.7 + DATABASE_URL="mysql://USERNAME:PASSWORD@127.0.0.1:3306/DB_NAME?serverVersion=5.7" .. tip:: From 36b380cae21ef5bd0a572f49653ba904d7a71f93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Schl=C3=BCter?= Date: Fri, 27 Nov 2020 12:08:18 +0100 Subject: [PATCH 0198/5766] Fix code example In the code example is a colon instead of semicolon at the end of line --- 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 23dd6472422..bf8f6959db4 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -800,7 +800,7 @@ array element. For example, to retrieve the ``handler_two`` handler:: { $handlers = iterator_to_array($handlers); - $handlerTwo = $handlers['handler_two']: + $handlerTwo = $handlers['handler_two']; } } From 89828678a7443848962d380b31980e22d893c75b Mon Sep 17 00:00:00 2001 From: gary houbre Date: Fri, 27 Nov 2020 12:49:56 +0100 Subject: [PATCH 0199/5766] Added Invalid Constant --- console.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/console.rst b/console.rst index 34dc50003f9..246ae474d48 100644 --- a/console.rst +++ b/console.rst @@ -57,6 +57,10 @@ want a command to create a user:: // or return this if some error happened during the execution // (it's equivalent to returning int(1)) // return Command::FAILURE; + + // or return this if there was invalid value during the execution + // (it's equivalent to returning int(2)) + // return Command::INVALID } } @@ -65,6 +69,10 @@ want a command to create a user:: The ``Command::SUCCESS`` and ``Command::FAILURE`` constants were introduced in Symfony 5.1. +.. versionadded:: 5.3 + + The ``Command::INVALID`` constants was introduced in Symfony 5.3 + Configuring the Command ----------------------- From d41389ad85d4812423919a7c8c1f8163006c1f38 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 27 Nov 2020 13:34:18 +0100 Subject: [PATCH 0200/5766] Tweak --- console.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/console.rst b/console.rst index 246ae474d48..58708719974 100644 --- a/console.rst +++ b/console.rst @@ -58,8 +58,8 @@ want a command to create a user:: // (it's equivalent to returning int(1)) // return Command::FAILURE; - // or return this if there was invalid value during the execution - // (it's equivalent to returning int(2)) + // or return this to indicate incorrect command usage; e.g. invalid options + // or missing arguments (it's equivalent to returning int(2)) // return Command::INVALID } } @@ -71,7 +71,7 @@ want a command to create a user:: .. versionadded:: 5.3 - The ``Command::INVALID`` constants was introduced in Symfony 5.3 + The ``Command::INVALID`` constant was introduced in Symfony 5.3 Configuring the Command ----------------------- From b407b347fca1692a83204a6e310b56abea424ffb Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Fri, 27 Nov 2020 00:56:38 +0100 Subject: [PATCH 0201/5766] [Validator] Removing the recommended `Constraints` subdirectory --- validation/custom_constraint.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst index eebfd087fb0..26a447042ad 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -14,8 +14,8 @@ Creating the Constraint Class First you need to create a Constraint class and extend :class:`Symfony\\Component\\Validator\\Constraint`:: - // src/Validator/Constraints/ContainsAlphanumeric.php - namespace App\Validator\Constraints; + // src/Validator/ContainsAlphanumeric.php + namespace App\Validator; use Symfony\Component\Validator\Constraint; @@ -54,8 +54,8 @@ when actually performing the validation. The validator class only has one required method ``validate()``:: - // src/Validator/Constraints/ContainsAlphanumericValidator.php - namespace App\Validator\Constraints; + // src/Validator/ContainsAlphanumericValidator.php + namespace App\Validator; use Symfony\Component\Validator\Constraint; use Symfony\Component\Validator\ConstraintValidator; @@ -71,7 +71,7 @@ The validator class only has one required method ``validate()``:: } // custom constraints should ignore null and empty values to allow - // other constraints (NotBlank, NotNull, etc.) take care of that + // other constraints (NotBlank, NotNull, etc.) to take care of that if (null === $value || '' === $value) { return; } @@ -117,7 +117,7 @@ You can use custom validators like the ones provided by Symfony itself: // src/Entity/AcmeEntity.php namespace App\Entity; - use App\Validator\Constraints as AcmeAssert; + use App\Validator as AcmeAssert; use Symfony\Component\Validator\Constraints as Assert; class AcmeEntity @@ -140,7 +140,7 @@ You can use custom validators like the ones provided by Symfony itself: properties: name: - NotBlank: ~ - - App\Validator\Constraints\ContainsAlphanumeric: ~ + - App\Validator\ContainsAlphanumeric: ~ .. code-block:: xml @@ -153,7 +153,7 @@ You can use custom validators like the ones provided by Symfony itself: - + @@ -163,7 +163,7 @@ You can use custom validators like the ones provided by Symfony itself: // src/Entity/AcmeEntity.php namespace App\Entity; - use App\Validator\Constraints\ContainsAlphanumeric; + use App\Validator\ContainsAlphanumeric; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Mapping\ClassMetadata; @@ -241,13 +241,13 @@ not to the property: # config/validator/validation.yaml App\Entity\AcmeEntity: constraints: - - App\Validator\Constraints\ProtocolClass: ~ + - App\Validator\ProtocolClass: ~ .. code-block:: xml - + .. code-block:: php @@ -255,7 +255,7 @@ not to the property: // src/Entity/AcmeEntity.php namespace App\Entity; - use App\Validator\Constraints\ProtocolClass; + use App\Validator\ProtocolClass; use Symfony\Component\Validator\Mapping\ClassMetadata; class AcmeEntity From 6ba56354f37add74088b4d1a4edc058ce12c941d Mon Sep 17 00:00:00 2001 From: sebpacz <74934099+sebpacz@users.noreply.github.com> Date: Fri, 27 Nov 2020 15:09:54 +0100 Subject: [PATCH 0202/5766] Update index.rst This is a very small change. I suggest replacing "function" with "functions" because each of these helpers offer more than one function. The word "functions" seems more appropriate. --- components/console/helpers/index.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/console/helpers/index.rst b/components/console/helpers/index.rst index 87c62ca7629..5f328d47472 100644 --- a/components/console/helpers/index.rst +++ b/components/console/helpers/index.rst @@ -15,6 +15,6 @@ The Console Helpers debug_formatter The Console component comes with some useful helpers. These helpers contain -function to ease some common tasks. +functions to ease some common tasks. .. include:: map.rst.inc From 74e2a7fb64bbdf7bffcc76688f6aae7fb27b2b93 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 27 Nov 2020 17:37:01 +0100 Subject: [PATCH 0203/5766] Rewords --- performance.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/performance.rst b/performance.rst index 8d3eb05d2c0..46ed5b9c7f8 100644 --- a/performance.rst +++ b/performance.rst @@ -189,14 +189,14 @@ such as Symfony projects, should use at least these values: Optimize Composer Autoloader ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -The class loader used while developing the application is optimized to find -new and changed classes. In production servers, PHP files should never change, +The class loader used while developing the application is optimized to find new +and changed classes. In production servers, PHP files should never change, unless a new application version is deployed. That's why you can optimize -Composer's autoloader to scan the entire application once and build a "class map", -which is a big array of the locations of all the classes and it's stored -in ``vendor/composer/autoload_classmap.php``. +Composer's autoloader to scan the entire application once and build an +optimized "class map", which is a big array of the locations of all the classes +and it's stored in ``vendor/composer/autoload_classmap.php``. -Execute this command to generate the class map (and make it part of your +Execute this command to generate the new class map (and make it part of your deployment process too): .. code-block:: terminal @@ -209,8 +209,6 @@ deployment process too): used in your application and prevents Composer from scanning the file system for classes that are not found in the class map. (see: `Composer's autoloader optimization`_). -You can also use the ``--classmap-authoritative`` option with the ``composer install`` command. - .. _profiling-applications: Profiling Symfony Applications From cc151fc41aaae8e91387f7d28d3bf8c37d35a3ee Mon Sep 17 00:00:00 2001 From: Ivan Ternovtsiy Date: Tue, 1 Dec 2020 11:13:09 +0200 Subject: [PATCH 0204/5766] Remove incorrect opcache preload instructions --- performance.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/performance.rst b/performance.rst index 46ed5b9c7f8..afd5295a9e3 100644 --- a/performance.rst +++ b/performance.rst @@ -109,9 +109,7 @@ During container compilation (e.g. when running the ``cache:clear`` command), Symfony generates a file called ``preload.php`` in the ``config/`` directory with the list of classes to preload. -The only requirement is that you need to set both ``container.dumper.inline_factories`` -and ``container.dumper.inline_class_loader`` parameters to ``true``. Then, you -can configure PHP to use this preload file: +You can configure PHP to use this preload file: .. code-block:: ini From 9b1e113dbb34e3739ba298a3f476652f8375c685 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 1 Dec 2020 22:59:55 +0100 Subject: [PATCH 0205/5766] [Console] Update questionhelper.rst I noticed that the link to the ask method redirects to Symfony\Component\Console\Command\Command instead of Symfony\Component\Console\Helper\QuestionHelper. --- components/console/helpers/questionhelper.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/console/helpers/questionhelper.rst b/components/console/helpers/questionhelper.rst index de1aefd2cfa..2174550a0cd 100644 --- a/components/console/helpers/questionhelper.rst +++ b/components/console/helpers/questionhelper.rst @@ -12,7 +12,7 @@ helper set, which you can get by calling $helper = $this->getHelper('question'); The Question Helper has a single method -:method:`Symfony\\Component\\Console\\Command\\Command::ask` that needs an +:method:`Symfony\\Component\\Console\\Helper\\QuestionHelper::ask` that needs an :class:`Symfony\\Component\\Console\\Input\\InputInterface` instance as the first argument, an :class:`Symfony\\Component\\Console\\Output\\OutputInterface` instance as the second argument and a From 36b60ac475fccea62f7ef338de5e26b9f2c7ed77 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Mon, 30 Nov 2020 16:43:45 +0100 Subject: [PATCH 0206/5766] [Security] Minor typo --- security/experimental_authenticators.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index 8a1b6081d84..c86622ba84d 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -337,7 +337,7 @@ The authenticator can be enabled using the ``custom_authenticators`` setting: - App\Security\ApiKeyAuthenticator # don't forget to also configure the entry_point if the - # authenticator implements AuthenticatorEntryPointInterface + # authenticator implements AuthenticationEntryPointInterface # entry_point: App\Security\CustomFormLoginAuthenticator .. code-block:: xml @@ -409,7 +409,7 @@ well as other pieces of information, like whether a password should be checked or if "remember me" functionality should be enabled. The default -:class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Passport`. +:class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Passport` requires a user object and credentials. The following credential classes are supported by default: From 2537437a54de9de1ac2fcb8399fe34a4f6d36021 Mon Sep 17 00:00:00 2001 From: Al-Saleh KEITA <28827545+askeita@users.noreply.github.com> Date: Mon, 30 Nov 2020 18:49:48 +0100 Subject: [PATCH 0207/5766] Update http_cache.rst Replaced "two" by "three" on line 313. --- http_cache.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http_cache.rst b/http_cache.rst index 971679d5f82..0bd62b30c8e 100644 --- a/http_cache.rst +++ b/http_cache.rst @@ -315,7 +315,7 @@ Safe Methods: Only caching GET or HEAD requests ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ HTTP caching only works for "safe" HTTP methods (like GET and HEAD). This means -two things: +three things: * Don't try to cache PUT or DELETE requests. It won't work and with good reason. These methods are meant to be used when mutating the state of your application From 886a3ef480a29b92735b3ee73b083e6efafdeb9a Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Thu, 3 Dec 2020 07:44:23 +0100 Subject: [PATCH 0208/5766] Add Titouan in the core team --- contributing/code/core_team.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/contributing/code/core_team.rst b/contributing/code/core_team.rst index 47fba9c2d94..9ff45966cbb 100644 --- a/contributing/code/core_team.rst +++ b/contributing/code/core_team.rst @@ -71,7 +71,8 @@ Active Core Members * **Tobias Nyholm** (`Nyholm`_); * **Wouter De Jong** (`wouterj`_); * **Alexander M. Turek** (`derrabus`_); - * **Jérémy Derussé** (`jderusse`_). + * **Jérémy Derussé** (`jderusse`_); + * **Titouan Galopin** (`tgalopin`_). * **Security Team** (``@symfony/security`` on GitHub): @@ -207,3 +208,4 @@ discretion of the **Project Leader**. .. _`lsmith77`: https://github.com/lsmith77/ .. _`derrabus`: https://github.com/derrabus/ .. _`jderusse`: https://github.com/jderusse/ +.. _`tgalopin`: https://github.com/tgalopin/ From 3c48f6898c6bf47849306e558c55158c98755da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Malte=20Schlu=CC=88ter?= Date: Thu, 3 Dec 2020 11:24:58 +0100 Subject: [PATCH 0209/5766] [Notifier] Update information for slack on actual implementation --- notifier.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/notifier.rst b/notifier.rst index a3bb15f2232..3145bce544c 100644 --- a/notifier.rst +++ b/notifier.rst @@ -145,29 +145,26 @@ GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_T LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://TOKEN@ENDPOINT?channel=CHANNEL`` RocketChat ``symfony/rocket-chat-notifier`` ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL`` -Slack ``symfony/slack-notifier`` ``slack://default/ID`` +Slack ``symfony/slack-notifier`` ``slack://TOKEN@default?channel=CHANNEL`` Telegram ``symfony/telegram-notifier`` ``telegram://TOKEN@default?channel=CHAT_ID`` Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:APIKEY@ENDPOINT?channel=CHANNEL`` ========== ================================ =========================================================================== .. versionadded:: 5.1 - The Mattermost and RocketChat integrations were introduced in Symfony - 5.1. The Slack DSN changed in Symfony 5.1 to use Slack Incoming - Webhooks instead of legacy tokens. + The Mattermost and RocketChat integrations were introduced in Symfony 5.1. .. versionadded:: 5.2 The GoogleChat, LinkedIn, Zulip and Discord integrations were introduced in Symfony 5.2. + The Slack DSN changed in Symfony 5.2 to use Slack Web API again same as in 5.0. Chatters are configured using the ``chatter_transports`` setting: .. code-block:: bash # .env - SLACK_DSN=slack://default/ID - # If your slack webhook looks like "https://hooks.slack.com/services/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX" then use: - SLACK_DSN=slack://default/XXXXXXXXX/XXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXX + SLACK_DSN=slack://TOKEN@default?channel=CHANNEL .. configuration-block:: From a874705308eb708e6277ae30e5c539459313fc61 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Thu, 3 Dec 2020 14:13:06 +0100 Subject: [PATCH 0210/5766] Update lockable_trait.rst --- console/lockable_trait.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst index 7f751d09012..74c4c2a5870 100644 --- a/console/lockable_trait.rst +++ b/console/lockable_trait.rst @@ -38,6 +38,8 @@ that adds two convenient methods to lock and release commands:: // if not released explicitly, Symfony releases the lock // automatically when the execution of the command ends $this->release(); + + return 0; } } From 9695d7ef573a24ad440c3b291bdd291fad83f390 Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Thu, 3 Dec 2020 22:24:10 +0100 Subject: [PATCH 0211/5766] [Debug] Added option to specify the event dispatcher in debug:event-dispatcher --- event_dispatcher.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/event_dispatcher.rst b/event_dispatcher.rst index 55e99a8da34..03630c2e5f0 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -322,6 +322,18 @@ its name: $ php bin/console debug:event-dispatcher kernel.exception +For the :doc:`new experimental Security ` +an event dispatcher per firewall was added. You can get the registered listeners +for a particular event dispatcher by using the ``--dispatcher`` option: + +.. code-block:: terminal + + $ php bin/console debug:event-dispatcher --dispatcher=security.event_dispatcher.main + +.. versionadded:: 5.3 + + The ``dispatcher`` option was introduced in Symfony 5.3. + Learn more ---------- From 41418b7dad20e9f73aacdd00fe30f0a4a8e707b5 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 3 Dec 2020 11:25:15 -0500 Subject: [PATCH 0212/5766] Prefer sass over node-sass --- frontend/encore/simple-example.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index 6ddcd5bdbd8..d4f74989aa1 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -311,15 +311,15 @@ Encore. When you do, you'll see an error! .. code-block:: terminal - > Error: Install sass-loader & node-sass to use enableSassLoader() - > yarn add sass-loader@^8.0.0 node-sass --dev + > Error: Install sass-loader & sass to use enableSassLoader() + > yarn add sass-loader@^10.0.0 sass --dev Encore supports many features. But, instead of forcing all of them on you, when you need a feature, Encore will tell you what you need to install. Run: .. code-block:: terminal - $ yarn add sass-loader@^8.0.0 node-sass --dev + $ yarn add sass-loader@^10.0.0 sass --dev $ yarn encore dev --watch Your app now supports Sass. Encore also supports LESS and Stylus. See From f2a3cf57488bb80b08b519358d458e74a52a930e Mon Sep 17 00:00:00 2001 From: Laurent VOULLEMIER Date: Sat, 5 Dec 2020 18:03:19 +0100 Subject: [PATCH 0213/5766] Minor modification about the .meta file contents The explanation about the `.meta` file contents is not totally true. Only `ComposerResource` stores timestamps (for `installed.json` files). For project source and configuration files involved in the generation of a file in the cache, the `filemtime` is directly used to retrieve the resource timestamp and to compare it with the `filemtime` of the generated file. Source: https://github.com/symfony/symfony/blob/21ef411cc96459d0d87ac3e1d565aca4bba1cb21/src/Symfony/Component/Config/Resource/FileResource.php#L65 --- components/dependency_injection/compilation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/dependency_injection/compilation.rst b/components/dependency_injection/compilation.rst index 8f50b2b0d0c..55725be8da0 100644 --- a/components/dependency_injection/compilation.rst +++ b/components/dependency_injection/compilation.rst @@ -564,8 +564,8 @@ Now the cached dumped container is used regardless of whether debug mode is on or not. The difference is that the ``ConfigCache`` is set to debug mode with its second constructor argument. When the cache is not in debug mode the cached container will always be used if it exists. In debug mode, -an additional metadata file is written with the timestamps of all the resource -files. These are then checked to see if the files have changed, if they +an additional metadata file is written with all the involved resource +files. These are then checked to see if their timestamps have changed, if they have the cache will be considered stale. .. note:: From 4677e42c58bf87f72dd75150eb41f852acf7a576 Mon Sep 17 00:00:00 2001 From: Valentin Udaltsov Date: Sat, 5 Dec 2020 21:54:21 +0300 Subject: [PATCH 0214/5766] Changed iterable $forms to Traversable in the data mapper implementation example --- form/data_mappers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/form/data_mappers.rst b/form/data_mappers.rst index f10d74813b0..24ff0716f5f 100644 --- a/form/data_mappers.rst +++ b/form/data_mappers.rst @@ -98,7 +98,7 @@ in your form type:: /** * @param Color|null $viewData */ - public function mapDataToForms($viewData, iterable $forms): void + public function mapDataToForms($viewData, \Traversable $forms): void { // there is no data yet, so nothing to prepopulate if (null === $viewData) { @@ -119,7 +119,7 @@ in your form type:: $forms['blue']->setData($viewData->getBlue()); } - public function mapFormsToData(iterable $forms, &$viewData): void + public function mapFormsToData(\Traversable $forms, &$viewData): void { /** @var FormInterface[] $forms */ $forms = iterator_to_array($forms); From 4e4924e22d2a53d39be593d31e895947b1d8e892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Schl=C3=A4pfer?= Date: Sat, 5 Dec 2020 16:45:37 +0100 Subject: [PATCH 0215/5766] [Cache] Document cache encryption using SodiumMarshaller --- cache.rst | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/cache.rst b/cache.rst index 58e3cd0b816..20d9af8999e 100644 --- a/cache.rst +++ b/cache.rst @@ -714,3 +714,86 @@ Clear all caches everywhere: .. code-block:: terminal $ php bin/console cache:pool:clear cache.global_clearer + +Encrypting the Cache +-------------------- + +.. versionadded:: 5.1 + + :class:`Symfony\\Component\\Cache\\Marshaller\\SodiumMarshaller` has been + introduced in Symfony 5.1. + +To encrypt the cache using ``libsodium``, you can use the +:class:`Symfony\\Component\\Cache\\Marshaller\\SodiumMarshaller`. + +.. note:: + + This will encrypt the values of the cache items, but not the cache keys. Be + careful not the leak sensitive data in the keys. + +Generate a key: + +.. code-block:: terminal + + $ php -r 'echo base64_encode(sodium_crypto_box_keypair());' + +And add it to your :doc:`secret store ` as +``CACHE_DECRYPTION_KEY`` and enable the ``SodiumMarshaller``: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/cache.yaml + services: + Symfony\Component\Cache\Marshaller\SodiumMarshaller: + decorates: cache.default_marshaller + arguments: + - ['%env(base64:CACHE_DECRYPTION_KEY)%'] + # use multiple keys in order to rotate them + #- ['%env(base64:CACHE_DECRYPTION_KEY)%', '%env(base64:OLD_CACHE_DECRYPTION_KEY)%'] + - '@Symfony\Component\Cache\Marshaller\SodiumMarshaller.inner' + + .. code-block:: xml + + + + + + + + redis://localhost + + env(base64:CACHE_DECRYPTION_KEY) + + + + + + + + + .. code-block:: php + + // config/packages/cache.php + use Symfony\Component\Cache\Marshaller\SodiumMarshaller; + + $container->register(SodiumMarshaller::class) + ->decorate('cache.default_marshaller') + ->addArgument(['env(base64:CACHE_DECRYPTION_KEY)']) + // use multiple keys in order to rotate them + // ->addArgument(['env(base64:CACHE_DECRYPTION_KEY)', 'env(base64:OLD_CACHE_DECRYPTION_KEY)']) + ->addArgument(service('@Symfony\Component\Cache\Marshaller\SodiumMarshaller.inner')); + +To rotate your encryption keys but still be able to read existing cache entries, +add the old encryption key to the service arguments. The first key will be used +for reading and writing, and the additional key(s) will only be used for reading. + +Once all cache items encrypted with the old key have expired, you can remove +`OLD_CACHE_DECRYPTION_KEY` completely. From 54fdf7a0771a2ea5a49886bd6cda6a7595d76742 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sun, 6 Dec 2020 12:16:03 +0100 Subject: [PATCH 0216/5766] [#14658] Minor tweaks to cache encryption section --- cache.rst | 45 ++++++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/cache.rst b/cache.rst index 20d9af8999e..5f31c495e4b 100644 --- a/cache.rst +++ b/cache.rst @@ -720,31 +720,28 @@ Encrypting the Cache .. versionadded:: 5.1 - :class:`Symfony\\Component\\Cache\\Marshaller\\SodiumMarshaller` has been - introduced in Symfony 5.1. + The :class:`Symfony\\Component\\Cache\\Marshaller\\SodiumMarshaller` + class was introduced in Symfony 5.1. To encrypt the cache using ``libsodium``, you can use the :class:`Symfony\\Component\\Cache\\Marshaller\\SodiumMarshaller`. -.. note:: - - This will encrypt the values of the cache items, but not the cache keys. Be - careful not the leak sensitive data in the keys. - -Generate a key: +First, you need to generate a secure key and add it to your :doc:`secret +store ` as ``CACHE_DECRYPTION_KEY``: .. code-block:: terminal $ php -r 'echo base64_encode(sodium_crypto_box_keypair());' -And add it to your :doc:`secret store ` as -``CACHE_DECRYPTION_KEY`` and enable the ``SodiumMarshaller``: +Then, register the ``SodiumMarshaller`` service using this key: .. configuration-block:: .. code-block:: yaml # config/packages/cache.yaml + + # ... services: Symfony\Component\Cache\Marshaller\SodiumMarshaller: decorates: cache.default_marshaller @@ -766,13 +763,14 @@ And add it to your :doc:`secret store ` as http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> + + - redis://localhost env(base64:CACHE_DECRYPTION_KEY) - + @@ -783,17 +781,22 @@ And add it to your :doc:`secret store ` as // config/packages/cache.php use Symfony\Component\Cache\Marshaller\SodiumMarshaller; + use Symfony\Component\DependencyInjection\ChildDefinition; + use Symfony\Component\DependencyInjection\Reference; - $container->register(SodiumMarshaller::class) - ->decorate('cache.default_marshaller') + // ... + $container->setDefinition(SodiumMarshaller::class, new ChildDefinition('cache.default_marshaller')) ->addArgument(['env(base64:CACHE_DECRYPTION_KEY)']) // use multiple keys in order to rotate them - // ->addArgument(['env(base64:CACHE_DECRYPTION_KEY)', 'env(base64:OLD_CACHE_DECRYPTION_KEY)']) - ->addArgument(service('@Symfony\Component\Cache\Marshaller\SodiumMarshaller.inner')); + //->addArgument(['env(base64:CACHE_DECRYPTION_KEY)', 'env(base64:OLD_CACHE_DECRYPTION_KEY)']) + ->addArgument(new Reference(SodiumMarshaller::class.'.inner')); -To rotate your encryption keys but still be able to read existing cache entries, -add the old encryption key to the service arguments. The first key will be used -for reading and writing, and the additional key(s) will only be used for reading. +.. caution:: + + This will encrypt the values of the cache items, but not the cache keys. Be + careful not the leak sensitive data in the keys. -Once all cache items encrypted with the old key have expired, you can remove -`OLD_CACHE_DECRYPTION_KEY` completely. +When configuring multiple keys, the first key will be used for reading and +writing, and the additional key(s) will only be used for reading. Once all +cache items encrypted with the old key have expired, you can remove +``OLD_CACHE_DECRYPTION_KEY`` completely. From e60cd0edd2ebd14a577ab18a9d404835c79dd2d2 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 4 Dec 2020 11:51:53 +0100 Subject: [PATCH 0217/5766] Added config reference for router.default_uri --- reference/configuration/framework.rst | 9 +++++++++ routing.rst | 2 ++ 2 files changed, 11 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 0780b49b0b9..833329a8d44 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -190,6 +190,7 @@ Configuration * `router`_ + * `default_uri`_ * `http_port`_ * `https_port`_ * `resource`_ @@ -1145,6 +1146,14 @@ 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``). +default_uri +........... + +**type**: ``string`` + +The default URI used to generate URLs in a non-HTTP context (see +:ref:`Generating URLs in Commands `). + http_port ......... diff --git a/routing.rst b/routing.rst index e8f5bb91b83..ec6de557b5d 100644 --- a/routing.rst +++ b/routing.rst @@ -2055,6 +2055,8 @@ If you need to generate URLs dynamically or if you are using pure JavaScript code, this solution doesn't work. In those cases, consider using the `FOSJsRoutingBundle`_. +.. _router-generate-urls-commands: + Generating URLs in Commands ~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 2ed719f9b47fdc5e87a3253d19f7a1f853de0c15 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 7 Dec 2020 08:24:35 +0100 Subject: [PATCH 0218/5766] Added the versionadded directive --- reference/configuration/framework.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 833329a8d44..0e61184b6be 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1151,6 +1151,10 @@ default_uri **type**: ``string`` +.. versionadded:: 5.1 + + The ``default_uri`` option was introduced in Symfony 5.1. + The default URI used to generate URLs in a non-HTTP context (see :ref:`Generating URLs in Commands `). From e68926ff9c76c82081de84c515d71e85280e07d2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 7 Dec 2020 08:27:54 +0100 Subject: [PATCH 0219/5766] Reword --- event_dispatcher.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/event_dispatcher.rst b/event_dispatcher.rst index 03630c2e5f0..ed6740cc162 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -322,9 +322,9 @@ its name: $ php bin/console debug:event-dispatcher kernel.exception -For the :doc:`new experimental Security ` -an event dispatcher per firewall was added. You can get the registered listeners -for a particular event dispatcher by using the ``--dispatcher`` option: +The :doc:`new experimental Security ` +system adds an event dispatcher per firewall. Use the ``--dispatcher`` option to +get the registered listeners for a particular event dispatcher: .. code-block:: terminal From 3f0bf94b2a5a93df1950fa06588777032e4f02c3 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sat, 5 Dec 2020 17:28:42 +0100 Subject: [PATCH 0220/5766] [EventDispatcher] Show partial matching for debug:event-dispatcher --- event_dispatcher.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/event_dispatcher.rst b/event_dispatcher.rst index ed6740cc162..038a405b10b 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -322,6 +322,17 @@ its name: $ php bin/console debug:event-dispatcher kernel.exception +or can get everything which partial matches the event name: + +.. code-block:: terminal + + $ php bin/console debug:event-dispatcher kernel // matches "kernel.exception", "kernel.response" etc. + $ php bin/console debug:event-dispatcher Security // matches "Symfony\Component\Security\Http\Event\CheckPassportEvent" + +.. versionadded:: 5.3 + + The ability to match partial event names was introduced in Symfony 5.3. + The :doc:`new experimental Security ` system adds an event dispatcher per firewall. Use the ``--dispatcher`` option to get the registered listeners for a particular event dispatcher: From 955674651cd6d2d5b0a09b56971c579917914cb5 Mon Sep 17 00:00:00 2001 From: Abdouni Abdelkarim Date: Mon, 16 Nov 2020 11:22:04 +0100 Subject: [PATCH 0221/5766] Update import.rst --- service_container/import.rst | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/service_container/import.rst b/service_container/import.rst index f38c2a33525..b37c8360388 100644 --- a/service_container/import.rst +++ b/service_container/import.rst @@ -80,7 +80,8 @@ a relative or absolute path to the imported file: # config/services.yaml imports: - { resource: services/mailer.yaml } - + # If you want to import a whole directory: + - { resource: services/ } services: _defaults: autowire: true @@ -103,6 +104,8 @@ a relative or absolute path to the imported file: + + @@ -122,6 +125,8 @@ a relative or absolute path to the imported file: return function(ContainerConfigurator $configurator) { $configurator->import('services/mailer.php'); + // If you want to import a whole directory: + $configurator->import('services/'); $services = $configurator->services() ->defaults() From eef382cf8e70e69b481ee04feebe179a2de637e7 Mon Sep 17 00:00:00 2001 From: gary houbre Date: Mon, 26 Oct 2020 12:49:33 +0100 Subject: [PATCH 0222/5766] More explication for return into execute command function --- console.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/console.rst b/console.rst index ad9bb8c16e6..663fafbfd9a 100644 --- a/console.rst +++ b/console.rst @@ -45,9 +45,16 @@ want a command to create a user:: protected function execute(InputInterface $input, OutputInterface $output) { - // ... + // ... put here the code to run in your command + + // this method must return an integer number with the "exit status code" + // of the command. + // return this if there was no problem running the command return 0; + + // or return this if some error happened during the execution + // return 1; } } From 7a7cef829e307c27b48ebde8a7c135851a368329 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 11:51:31 +0100 Subject: [PATCH 0223/5766] minor. #14488 --- console.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console.rst b/console.rst index 5df984705b6..9611ce94bfd 100644 --- a/console.rst +++ b/console.rst @@ -45,7 +45,7 @@ want a command to create a user:: protected function execute(InputInterface $input, OutputInterface $output) { - // ... put here the code to run in your command + // ... put here the code to create the user // this method must return an integer number with the "exit status code" // of the command. From bd44d05db34f5c9b624cadbbdbd042e34bf23e10 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 12:03:43 +0100 Subject: [PATCH 0224/5766] minor --- notifier/chatters.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notifier/chatters.rst b/notifier/chatters.rst index 40e9cea2096..1183de984d7 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -46,9 +46,9 @@ you to send messages to chat services like Slack or Telegram:: Adding Interactions to a Slack Message -------------------------------------- -With a Slack message, you can use the -:class:`Symfony\\Component\\Notifier\\Bridge\\Slack\\SlackOptions` to add -some interactive options called `Block elements`_:: +With a Slack message, you can use the +:class:`Symfony\\Component\\Notifier\\Bridge\\Slack\\SlackOptions` class +to add some interactive options called `Block elements`_:: use Symfony\Component\Notifier\Bridge\Slack\Block\SlackActionsBlock; use Symfony\Component\Notifier\Bridge\Slack\Block\SlackDividerBlock; From f62f89a054c59166adf51375501b120691b04bf7 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 12:04:43 +0100 Subject: [PATCH 0225/5766] minor --- notifier/chatters.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notifier/chatters.rst b/notifier/chatters.rst index 50f3e5bc20f..4a10ad109d2 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -104,8 +104,8 @@ Adding Interactions to a Discord Message ---------------------------------------- With a Discord message, you can use the -:class:`Symfony\\Component\\Notifier\\Bridge\\Discord\\DiscordOptions` to add -some interactive options called `Embed elements`_:: +:class:`Symfony\\Component\\Notifier\\Bridge\\Discord\\DiscordOptions` class +to add some interactive options called `Embed elements`_:: use Symfony\Component\Notifier\Bridge\Discord\DiscordOptions; use Symfony\Component\Notifier\Bridge\Discord\Embeds\DiscordEmbed; From 25c651959497529779d3d2ec7ca0dae8744dd2c1 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 12:10:03 +0100 Subject: [PATCH 0226/5766] Use constant over int. refs #14648 --- console/lockable_trait.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst index 7745874a764..9c77073d087 100644 --- a/console/lockable_trait.rst +++ b/console/lockable_trait.rst @@ -38,8 +38,8 @@ that adds two convenient methods to lock and release commands:: // if not released explicitly, Symfony releases the lock // automatically when the execution of the command ends $this->release(); - - return 0; + + return Command:SUCCESS; } } From 33a699015263a9dac48c9ca77eb08bb426e0f9a8 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 12:11:08 +0100 Subject: [PATCH 0227/5766] remove whitespaces --- console/lockable_trait.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst index 74c4c2a5870..36cd393907c 100644 --- a/console/lockable_trait.rst +++ b/console/lockable_trait.rst @@ -38,7 +38,7 @@ that adds two convenient methods to lock and release commands:: // if not released explicitly, Symfony releases the lock // automatically when the execution of the command ends $this->release(); - + return 0; } } From 4239d4eb515786acdc698f302bc36339007a0ef5 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 7 Dec 2020 15:08:01 +0100 Subject: [PATCH 0228/5766] minor --- console.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console.rst b/console.rst index 25dd6b76924..18f39f1edd4 100644 --- a/console.rst +++ b/console.rst @@ -45,7 +45,7 @@ want a command to create a user:: protected function execute(InputInterface $input, OutputInterface $output) { - // ... put here the code to to create the user + // ... put here the code to create the user // this method must return an integer number with the "exit status code" // of the command. You can also use these constants to make code more readable From 46d1f1ae56fbb04df4ff050e6efa9673fb5165de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Renan=20Gon=C3=A7alves?= Date: Mon, 7 Dec 2020 15:34:33 +0100 Subject: [PATCH 0229/5766] Support Redis Sentinel mode when using phpredis/phpredis extension See https://github.com/symfony/symfony/pull/39363 --- components/cache/adapters/redis_adapter.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst index 64bf7ab9e4c..7846cde5200 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -95,8 +95,8 @@ Below are common examples of valid DSNs showing a combination of available value ); `Redis Sentinel`_, which provides high availability for Redis, is also supported -when using the Predis library. Use the ``redis_sentinel`` parameter to set the -name of your service group:: +when using the PHP Redis Extension v5.2+ or the Predis library. Use the ``redis_sentinel`` +parameter to set the name of your service group:: RedisAdapter::createConnection( 'redis:?host[redis1:26379]&host[redis2:26379]&host[redis3:26379]&redis_sentinel=mymaster' From fb8dea5501e50386f7ed9d7e9d83750055a75540 Mon Sep 17 00:00:00 2001 From: Florent <73140597+flovrent@users.noreply.github.com> Date: Mon, 7 Dec 2020 16:52:47 +0100 Subject: [PATCH 0230/5766] Update mercure.rst --- mercure.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mercure.rst b/mercure.rst index 8c0f52f8039..9222ddc68c5 100644 --- a/mercure.rst +++ b/mercure.rst @@ -408,7 +408,7 @@ And here is the controller:: // src/Controller/DiscoverController.php namespace App\Controller; - use Lcobucci\JWT\Builder; + use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -423,11 +423,14 @@ And here is the controller:: { $hubUrl = $this->getParameter('mercure.default_hub'); $this->addLink($request, new Link('mercure', $hubUrl)); - - $token = (new Builder()) - // set other appropriate JWT claims, such as an expiration date - ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * - ->getToken(new Sha256(), new Key($this->getParameter('mercure_secret_key'))); // don't forget to set this parameter! Test value: !ChangeMe! + + $key = Key\InMemory::plainText('mercure_secret_key'); // don't forget to set this parameter! Test value: !ChangeMe! + $configuration = Configuration::forSymmetricSigner(new Sha256(), $key); + + $token = $configuration->builder() + ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * + ->getToken($configuration->signer(), $configuration->signingKey()) + ->toString(); $response = $this->json(['@id' => '/demo/books/1', 'availability' => 'https://schema.org/InStock']); $cookie = Cookie::create('mercureAuthorization') From 8c21f36cb139d30907404fa831fe1cd8e499fccf Mon Sep 17 00:00:00 2001 From: Julien Falque Date: Wed, 29 Jul 2020 18:35:18 +0200 Subject: [PATCH 0231/5766] Document routing inline requirements and defaults for host --- routing.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/routing.rst b/routing.rst index d879feac6e3..39cb575ed8d 100644 --- a/routing.rst +++ b/routing.rst @@ -790,6 +790,11 @@ concise, but it can decrease route readability when requirements are complex: // ... }; +.. versionadded:: 5.2 + + Since Symfony 5.2, inline parameter requirements are also supported in the + host. Before Symfony 5.2, they were supported in the path only. + Optional Parameters ~~~~~~~~~~~~~~~~~~~ @@ -984,6 +989,11 @@ parameter: To give a ``null`` default value to any parameter, add nothing after the ``?`` character (e.g. ``/blog/{page?}``). +.. versionadded:: 5.2 + + Since Symfony 5.2, inline parameter default values are also supported in + the host. Before Symfony 5.2, they were supported in the path only. + Priority Parameter ~~~~~~~~~~~~~~~~~~ From 9408dd85c1f546095a539ab4188d4cb8cd441485 Mon Sep 17 00:00:00 2001 From: noniagriconomie Date: Tue, 8 Dec 2020 10:49:50 +0100 Subject: [PATCH 0232/5766] Improve README --- README.markdown | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/README.markdown b/README.markdown index b993cd45ed4..f65392efba3 100644 --- a/README.markdown +++ b/README.markdown @@ -1,7 +1,20 @@ -Symfony Documentation -===================== - -This documentation is rendered online at https://symfony.com/doc/current/ +

          + +

          + +

          + The official Symfony Documentation +

          + +

          + + Online version + + | + + Screencasts + +

          Contributing ------------ @@ -11,8 +24,8 @@ Symfony documentation, please read [Contributing to the Documentation](https://symfony.com/doc/current/contributing/documentation/overview.html) > **Note** -> All pull requests must be based off of the **4.4** branch, -> unless you're documenting a feature that was introduced *after* Symfony 4.4 +> All pull requests must be based on the ``4.4`` branch, +> unless you are documenting a feature that was introduced *after* Symfony 4.4 > (e.g. in Symfony 5.2), **not** the ``5.x`` or older branches. SymfonyCloud @@ -24,7 +37,7 @@ server where Pull Requests are built and can be reviewed by contributors. Docker ------ -You can build the doc locally with these commands: +You can build the documentation project locally with these commands: ```bash # build the image... From 5238fff27e1b9740a3c85ef47c41915656e00d2a Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Mon, 7 Dec 2020 16:00:29 +0100 Subject: [PATCH 0233/5766] [PHPUnitBridge] Document the "symfony/deprecation-contracts" --- components/phpunit_bridge.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst index d1888cd4f6e..284dae4d816 100644 --- a/components/phpunit_bridge.rst +++ b/components/phpunit_bridge.rst @@ -165,6 +165,9 @@ Deprecation notices can be triggered by using:: @trigger_error('Your deprecation message', E_USER_DEPRECATED); +You can also require the ``symfony/deprecation-contracts`` package that provides +a global ``trigger_deprecation()`` function for this usage. + Without the `@-silencing operator`_, users would need to opt-out from deprecation notices. Silencing by default swaps this behavior and allows users to opt-in when they are ready to cope with them (by adding a custom error handler like the From d232aa9f524045720b2d6d1b114440911a3470c8 Mon Sep 17 00:00:00 2001 From: Peter Bottenberg Date: Fri, 30 Oct 2020 17:55:57 +0100 Subject: [PATCH 0234/5766] [Notifier] Add documentation for telegram options --- notifier/chatters.rst | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/notifier/chatters.rst b/notifier/chatters.rst index 9d03f83987c..764f05320a8 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -98,8 +98,6 @@ some interactive options called `Block elements`_:: $chatter->send($chatMessage); -.. _`Block elements`: https://api.slack.com/reference/block-kit/block-elements - Adding Interactions to a Discord Message ---------------------------------------- @@ -151,4 +149,38 @@ some interactive options called `Embed elements`_:: $chatter->send($chatMessage); +Adding Interactions to a Telegram Message +----------------------------------------- + +With a Telegram message, you can use the +:class:`Symfony\\Component\\Notifier\\Bridge\\Telegram\\TelegramOptions` class +to add `message options`_:: + + use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\Button\InlineKeyboardButton; + use Symfony\Component\Notifier\Bridge\Telegram\Reply\Markup\InlineKeyboardMarkup; + use Symfony\Component\Notifier\Bridge\Telegram\TelegramOptions; + use Symfony\Component\Notifier\Message\ChatMessage; + + $chatMessage = new ChatMessage(''); + + // Create Telegram options + $telegramOptions = (new TelegramOptions()) + ->chatId('@symfonynotifierdev') + ->parseMode('MarkdownV2') + ->disableWebPagePreview(true) + ->disableNotification(true) + ->replyMarkup((new InlineKeyboardMarkup()) + ->inlineKeyboard([ + (new InlineKeyboardButton('Visit symfony.com')) + ->url('https://symfony.com/'), + ]) + ); + + // Add the custom options to the chat message and send the message + $chatMessage->options($telegramOptions); + + $chatter->send($chatMessage); + +.. _`Block elements`: https://api.slack.com/reference/block-kit/block-elements .. _`Embed elements`: https://discord.com/developers/docs/resources/webhook +.. _`message options`: https://core.telegram.org/bots/api From 8cf987fceb64f0974e0e289a190f9951b1d2d01c Mon Sep 17 00:00:00 2001 From: Steven DUBOIS Date: Mon, 7 Dec 2020 18:09:06 +0100 Subject: [PATCH 0235/5766] Update experimental_authenticators : add UserBadge --- security/experimental_authenticators.rst | 36 +++++++++++++----------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index 382469c4566..2870eab1830 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -295,8 +295,8 @@ method that fits most use-cases:: use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException; - use Symfony\Component\Security\Core\Exception\UsernameNotFoundException; use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator; + use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport; @@ -328,14 +328,7 @@ method that fits most use-cases:: throw new CustomUserMessageAuthenticationException('No API token provided'); } - $user = $this->entityManager->getRepository(User::class) - ->findOneBy(['apiToken' => $apiToken]) - ; - if (null === $user) { - throw new UsernameNotFoundException(); - } - - return new SelfValidatingPassport($user); + return new SelfValidatingPassport(new UserBadge($apiToken)); } public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response @@ -472,12 +465,23 @@ are supported by default: $apiToken )); -.. note:: - If you don't need any credentials to be checked (e.g. a JWT token), you - can use the - :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\SelfValidatingPassport`. - This class only requires a user and optionally `Passport Badges`_. +Self Validating Passport +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +If you don't need any credentials to be checked (e.g. a JWT token), you can use the +:class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\SelfValidatingPassport`. +This class only requires a ``UserBadge`` object and optionally `Passport Badges`_. + +You can also pass a user loader to the ``UserBadge``. This callable receives the +``$userIdentifier`` as argument and must return a ``UserInterface`` object +(otherwise a ``UsernameNotFoundException`` is thrown). If this is not set, +the default user provider will be used with ``$userIdentifier`` as username:: + + // ... + return new SelfValidatingPassport(new UserBadge($email, function ($username) { + return $this->userRepository->findOneBy(['email' => $username]); + }); + Passport Badges ~~~~~~~~~~~~~~~ @@ -547,7 +551,7 @@ authenticator, you would initialize the passport like this:: ``createAuthenticatedToken()``):: // ... - use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; class LoginAuthenticator extends AbstractAuthenticator { @@ -557,7 +561,7 @@ authenticator, you would initialize the passport like this:: { // ... process the request - $passport = new SelfValidatingPassport($username, []); + $passport = new SelfValidatingPassport(new UserBadge($username), []); // set a custom attribute (e.g. scope) $passport->setAttribute('scope', $oauthScope); From 01cb2b0937d849aeffff344ead36626aaa93d4ea Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 8 Dec 2020 15:20:20 +0100 Subject: [PATCH 0236/5766] [#14672] Updated more docs related to the UserBadge --- security/experimental_authenticators.rst | 88 ++++++++++++++++-------- 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index 2870eab1830..35aa1c9c205 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -435,23 +435,61 @@ into a security Security Passports ~~~~~~~~~~~~~~~~~~ +.. versionadded:: 5.2 + + The ``UserBadge`` was introduced in Symfony 5.2. Prior to 5.2, the user + instance was provided directly to the passport. + A passport is an object that contains the user that will be authenticated as well as other pieces of information, like whether a password should be checked or if "remember me" functionality should be enabled. The default :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Passport` -requires a user object and credentials. The following credential classes -are supported by default: +requires a user and credentials. + +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 `:: + + use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; + + // ... + $passport = new Passport(new UserBadge($email), $credentials); + +.. note:: + You can optionally pass a user loader as second argument to the + ``UserBadge``. This callable receives the ``$userIdentifier`` + and must return a ``UserInterface`` object (otherwise a + ``UsernameNotFoundException`` is thrown):: + + // ... + $passport = new Passport( + new UserBadge($email, function ($userIdentifier) { + return $this->userRepository->findOneBy(['email' => $userIdentifier]); + }), + $credentials + ); + +The following credential classes are supported by default: :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Credentials\\PasswordCredentials` This requires a plaintext ``$password``, which is validated using the - :ref:`password encoder configured for the user `. + :ref:`password encoder configured for the user `:: + + use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; + + // ... + return new Passport($user, new PasswordCredentials($plaintextPassword)); :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Credentials\\CustomCredentials` Allows a custom closure to check credentials:: + use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials; + // ... return new Passport($user, new CustomCredentials( // If this function returns anything else than `true`, the credentials @@ -467,21 +505,13 @@ are supported by default: Self Validating Passport -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If you don't need any credentials to be checked (e.g. a JWT token), you can use the -:class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\SelfValidatingPassport`. -This class only requires a ``UserBadge`` object and optionally `Passport Badges`_. - -You can also pass a user loader to the ``UserBadge``. This callable receives the -``$userIdentifier`` as argument and must return a ``UserInterface`` object -(otherwise a ``UsernameNotFoundException`` is thrown). If this is not set, -the default user provider will be used with ``$userIdentifier`` as username:: - - // ... - return new SelfValidatingPassport(new UserBadge($email, function ($username) { - return $this->userRepository->findOneBy(['email' => $username]); - }); +........................ +If you don't need any credentials to be checked (e.g. when using API +tokens), you can use the +:class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\SelfValidatingPassport`. +This class only requires a ``UserBadge`` object and optionally `Passport +Badges`_. Passport Badges ~~~~~~~~~~~~~~~ @@ -511,8 +541,13 @@ the following badges are supported: initiated). This skips the :doc:`pre-authentication user checker `. -For instance, if you want to add CSRF and password migration to your custom -authenticator, you would initialize the passport like this:: +.. versionadded:: 5.2 + + Since 5.2, the ``PasswordUpgradeBadge`` is automatically added to + the passport if the passport has ``PasswordCredentials``. + +For instance, if you want to add CSRF to your custom authenticator, you +would initialize the passport like this:: // src/Service/LoginAuthenticator.php namespace App\Service; @@ -520,7 +555,7 @@ authenticator, you would initialize the passport like this:: // ... use Symfony\Component\Security\Http\Authenticator\AbstractAuthenticator; use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge; - use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PasswordUpgradeBadge; + use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge; use Symfony\Component\Security\Http\Authenticator\Passport\Passport; use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface; @@ -532,14 +567,13 @@ authenticator, you would initialize the passport like this:: $username = $request->request->get('username'); $csrfToken = $request->request->get('csrf_token'); - // ... get the $user from the $username and validate no - // parameter is empty + // ... validate no parameter is empty - return new Passport($user, new PasswordCredentials($password), [ - // $this->userRepository must implement PasswordUpgraderInterface - new PasswordUpgradeBadge($password, $this->userRepository), - new CsrfTokenBadge('login', $csrfToken), - ]); + return new Passport( + new UserBadge($user), + new PasswordCredentials($password), + [new CsrfTokenBadge('login', $csrfToken)] + ); } } From 1ae411bfcd845af42b14bcd61295f2851009c38b Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 9 Dec 2020 11:39:05 +0100 Subject: [PATCH 0237/5766] [#14671] Added example of inline host defaults/requirements --- routing.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/routing.rst b/routing.rst index 39cb575ed8d..bcd6daec811 100644 --- a/routing.rst +++ b/routing.rst @@ -790,11 +790,6 @@ concise, but it can decrease route readability when requirements are complex: // ... }; -.. versionadded:: 5.2 - - Since Symfony 5.2, inline parameter requirements are also supported in the - host. Before Symfony 5.2, they were supported in the path only. - Optional Parameters ~~~~~~~~~~~~~~~~~~~ @@ -989,11 +984,6 @@ parameter: To give a ``null`` default value to any parameter, add nothing after the ``?`` character (e.g. ``/blog/{page?}``). -.. versionadded:: 5.2 - - Since Symfony 5.2, inline parameter default values are also supported in - the host. Before Symfony 5.2, they were supported in the path only. - Priority Parameter ~~~~~~~~~~~~~~~~~~ @@ -2046,6 +2036,16 @@ these routes. // ['HTTP_HOST' => 'm.' . $client->getContainer()->getParameter('domain')] ); +.. tip:: + + You can also use the inline defaults and requirements format in the + ``host`` option: ``{subdomain?m}.example.com`` + +.. versionadded:: 5.2 + + Inline parameter default values support in hosts were introduced in + Symfony 5.2. Prior to Symfony 5.2, they were supported in the path only. + .. _i18n-routing: Localized Routes (i18n) From fd12a43e00a94743a2047cf4e7c15b3362fbc8be Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Thu, 3 Dec 2020 08:34:50 +0100 Subject: [PATCH 0238/5766] [Console] Update table.rst The Symfony\Component\Console\Helper\TableStyle class doesn't have the setDefaultCrossingChars method, but there is the setCrossingChars method. The setCrossingChars method takes at least 9 parameters, so I think it would be difficult to present it in the example instead of the setDefaultCrossingChars method. In this commit, I removed all references to the method that doesn't exist. --- components/console/helpers/table.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/console/helpers/table.rst b/components/console/helpers/table.rst index bc680cc5ad0..0e8df0d1031 100644 --- a/components/console/helpers/table.rst +++ b/components/console/helpers/table.rst @@ -233,7 +233,7 @@ If the built-in styles do not fit your need, define your own:: // customizes the style $tableStyle - ->setDefaultCrossingChars('|') + ->setHorizontalBorderChars('|') ->setVerticalBorderChars('-') ->setDefaultCrossingChar(' ') ; @@ -244,7 +244,7 @@ If the built-in styles do not fit your need, define your own:: Here is a full list of things you can customize: * :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setPaddingChar` -* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setDefaultCrossingChars` +* :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setHorizontalBorderChars` * :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setVerticalBorderChars` * :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setCrossingChars` * :method:`Symfony\\Component\\Console\\Helper\\TableStyle::setDefaultCrossingChar` From 6fc13f253eda907f73ef2ededdbb77a3a3521e3f Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Wed, 9 Dec 2020 13:00:18 -0500 Subject: [PATCH 0239/5766] Update setup page for Symfony 5.2 - drop dev Since 5.2 is already released there is no reason to point to `next` version When merged, fixes #14663 --- setup.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.rst b/setup.rst index 8e8f7c5610e..dbcb153dac7 100644 --- a/setup.rst +++ b/setup.rst @@ -50,10 +50,10 @@ application: .. code-block:: terminal # run this if you are building a traditional web application - $ symfony new my_project_name --version=next --full + $ symfony new my_project_name --full # run this if you are building a microservice, console application or API - $ symfony new my_project_name --version=next + $ symfony new my_project_name The only difference between these two commands is the number of packages installed by default. The ``--full`` option installs all the packages that you @@ -65,10 +65,10 @@ Symfony application using Composer: .. code-block:: terminal # run this if you are building a traditional web application - $ composer create-project symfony/website-skeleton:"5.2.x@dev" my_project_name + $ composer create-project symfony/website-skeleton my_project_name # run this if you are building a microservice, console application or API - $ composer create-project symfony/skeleton:"5.2.x@dev" my_project_name + $ composer create-project symfony/skeleton my_project_name No matter which command you run to create the Symfony application. All of them will create a new ``my_project_name/`` directory, download some dependencies From a741c9ce46f60e4d57e4d648d11525164956da31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gr=C3=A9gory=20SURACI?= Date: Wed, 9 Dec 2020 15:15:47 +0100 Subject: [PATCH 0240/5766] [Service Container] Fix Service parameters typo in services.yml --- service_container.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/service_container.rst b/service_container.rst index ff80ac27a14..a33dbdfb786 100644 --- a/service_container.rst +++ b/service_container.rst @@ -340,7 +340,7 @@ you can type-hint the new ``SiteUpdateManager`` class and use it:: // src/Controller/SiteController.php namespace App\Controller; - + // ... use App\Service\SiteUpdateManager; @@ -500,13 +500,14 @@ parameter and in PHP config use the ``ref`` function: # config/services.yaml services: App\Service\MessageGenerator: - # this is not a string, but a reference to a service called 'logger' - arguments: ['@logger'] + arguments: + # this is not a string, but a reference to a service called 'logger' + - '@logger' - # if the value of a string parameter starts with '@', you need to escape - # it by adding another '@' so Symfony doesn't consider it a service - # (this will be parsed as the string '@securepassword') - mailer_password: '@@securepassword' + # if the value of a string argument starts with '@', you need to escape + # it by adding another '@' so Symfony doesn't consider it a service + # the following example would be parsed as the string '@securepassword' + # - '@@securepassword' .. code-block:: xml From 2773a4168977aa98371a578759a78df7ae15037c Mon Sep 17 00:00:00 2001 From: Alexander Frolov Date: Wed, 9 Dec 2020 13:07:12 -0500 Subject: [PATCH 0241/5766] Update setup page for Symfony 5.1 - add version Since 5.2 is now the current version it makes sense to add version to `symfony` and `composer create-project` example commands --- setup.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.rst b/setup.rst index dbcb153dac7..5ad11c5b693 100644 --- a/setup.rst +++ b/setup.rst @@ -50,10 +50,10 @@ application: .. code-block:: terminal # run this if you are building a traditional web application - $ symfony new my_project_name --full + $ symfony new my_project_name --version=5.1 --full # run this if you are building a microservice, console application or API - $ symfony new my_project_name + $ symfony new my_project_name --version=5.1 The only difference between these two commands is the number of packages installed by default. The ``--full`` option installs all the packages that you @@ -65,10 +65,10 @@ Symfony application using Composer: .. code-block:: terminal # run this if you are building a traditional web application - $ composer create-project symfony/website-skeleton my_project_name + $ composer create-project symfony/website-skeleton:"5.1.*" my_project_name # run this if you are building a microservice, console application or API - $ composer create-project symfony/skeleton my_project_name + $ composer create-project symfony/skeleton:"5.1.*" my_project_name No matter which command you run to create the Symfony application. All of them will create a new ``my_project_name/`` directory, download some dependencies From 8e39f4592c1094898a3abc50728e72c30d2509d9 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 10 Dec 2020 12:39:49 +0100 Subject: [PATCH 0242/5766] Updated Composer commands to install 5.3@dev --- setup.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.rst b/setup.rst index dbcb153dac7..0433e8af360 100644 --- a/setup.rst +++ b/setup.rst @@ -50,10 +50,10 @@ application: .. code-block:: terminal # run this if you are building a traditional web application - $ symfony new my_project_name --full + $ symfony new my_project_name --version=next --full # run this if you are building a microservice, console application or API - $ symfony new my_project_name + $ symfony new my_project_name --version=next The only difference between these two commands is the number of packages installed by default. The ``--full`` option installs all the packages that you @@ -65,10 +65,10 @@ Symfony application using Composer: .. code-block:: terminal # run this if you are building a traditional web application - $ composer create-project symfony/website-skeleton my_project_name + $ composer create-project symfony/website-skeleton:"5.3.x@dev' my_project_name # run this if you are building a microservice, console application or API - $ composer create-project symfony/skeleton my_project_name + $ composer create-project symfony/skeleton:"5.3.x@dev' my_project_name No matter which command you run to create the Symfony application. All of them will create a new ``my_project_name/`` directory, download some dependencies From 81a020857cb1ece2e70f30752fa19a1b284b5a95 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 10 Dec 2020 15:08:44 +0100 Subject: [PATCH 0243/5766] Change order in Set-up article --- setup.rst | 58 +++++++++++++++++++++++++++---------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/setup.rst b/setup.rst index 2f39564d40c..a93d157b371 100644 --- a/setup.rst +++ b/setup.rst @@ -81,6 +81,35 @@ started. In other words, your new application is ready! and ``/var/log/``) must be writable by the web server. If you have any issue, read how to :doc:`set up permissions for Symfony applications `. +.. _install-existing-app: + +Setting up an Existing Symfony Project +-------------------------------------- + +In addition to creating new Symfony projects, you will also work on projects +already created by other developers. In that case, you only need to get the +project code and install the dependencies with Composer. Assuming your team uses +Git, setup your project with the following commands: + +.. code-block:: terminal + + # clone the project to download its contents + $ cd projects/ + $ git clone ... + + # make Composer install the project's dependencies into vendor/ + $ cd my-project/ + $ composer install + +You'll probably also need to customize your :ref:`.env file ` +and do a few other project-specific tasks (e.g. creating a database). When +working on a existing Symfony application for the first time, it may be useful +to run this command which displays information about the project: + +.. code-block:: terminal + + $ php bin/console about + Running Symfony Applications ---------------------------- @@ -112,35 +141,6 @@ the server by pressing ``Ctrl+C`` from your terminal. The web server works with any PHP application, not only Symfony projects, so it's a very useful generic development tool. -.. _install-existing-app: - -Setting up an Existing Symfony Project --------------------------------------- - -In addition to creating new Symfony projects, you will also work on projects -already created by other developers. In that case, you only need to get the -project code and install the dependencies with Composer. Assuming your team uses -Git, setup your project with the following commands: - -.. code-block:: terminal - - # clone the project to download its contents - $ cd projects/ - $ git clone ... - - # make Composer install the project's dependencies into vendor/ - $ cd my-project/ - $ composer install - -You'll probably also need to customize your :ref:`.env file ` -and do a few other project-specific tasks (e.g. creating a database). When -working on a existing Symfony application for the first time, it may be useful -to run this command which displays information about the project: - -.. code-block:: terminal - - $ php bin/console about - .. _symfony-flex: Installing Packages From f7ae0fa09d5d4680b12b03cb4112912e98090133 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Fri, 11 Dec 2020 10:31:38 +0200 Subject: [PATCH 0244/5766] Fix config keys for rate limiter The `lock` and `storage` keys have been updated to `lock_factory` and `storage_service` respectively. --- rate_limiter.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index f5473607fe7..403aa9c462f 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -260,8 +260,8 @@ Rate Limiter Storage and Locking -------------------------------- Rate limiters use the default cache and locking mechanisms defined in your -Symfony application. If you prefer to change that, use the ``lock`` and -``storage`` options: +Symfony application. If you prefer to change that, use the ``lock_factory`` and +``storage_service`` options: .. code-block:: yaml @@ -274,9 +274,9 @@ Symfony application. If you prefer to change that, use the ``lock`` and cache_pool: 'app.redis_cache' # or define a service implementing StorageInterface to use a different # mechanism to store the limiter information - storage: 'App\RateLimiter\CustomRedisStorage' + storage_service: 'App\RateLimiter\CustomRedisStorage' # the value is the name of any lock defined in your application - lock: 'app.rate_limiter_lock' + lock_factory: 'app.rate_limiter_lock' .. _`token bucket algorithm`: https://en.wikipedia.org/wiki/Token_bucket .. _`PHP date relative formats`: https://www.php.net/datetime.formats.relative From 25e530fba5ce6cb43abbdd0e04aabc1392451e0e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 11 Dec 2020 16:02:44 +0100 Subject: [PATCH 0245/5766] Fixed code syntax of previous change --- mercure.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mercure.rst b/mercure.rst index 9222ddc68c5..c533c07fad7 100644 --- a/mercure.rst +++ b/mercure.rst @@ -428,9 +428,9 @@ And here is the controller:: $configuration = Configuration::forSymmetricSigner(new Sha256(), $key); $token = $configuration->builder() - ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * - ->getToken($configuration->signer(), $configuration->signingKey()) - ->toString(); + ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * + ->getToken($configuration->signer(), $configuration->signingKey()) + ->toString(); $response = $this->json(['@id' => '/demo/books/1', 'availability' => 'https://schema.org/InStock']); $cookie = Cookie::create('mercureAuthorization') From f81211422a3ba96a428bdfda062e6f22b1ed043c Mon Sep 17 00:00:00 2001 From: Youssef Benhssaien Date: Thu, 3 Dec 2020 07:25:17 +0100 Subject: [PATCH 0246/5766] Lock - replace getExpiringDate by getRemainingLifetime As the method `getExpiringDate` doesn't exist, replace it by `getRemainingLifetime` which returns the remaining time to live in seconds --- components/lock.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index 891fdc64818..55ddcf377b3 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -196,8 +196,8 @@ to reset the TTL to its original value:: $lock->refresh(600); This component also provides two useful methods related to expiring locks: -``getExpiringDate()`` (which returns ``null`` or a ``\DateTimeImmutable`` -object) and ``isExpired()`` (which returns a boolean). +``getRemainingLifetime()`` (which returns ``null`` or a ``float`` +as seconds) and ``isExpired()`` (which returns a boolean). The Owner of The Lock --------------------- From 0406cc4c0b38ceb54ec1c43eb3a46c3a227ddaa8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 11 Dec 2020 17:34:55 +0100 Subject: [PATCH 0247/5766] [Uid] Mention the Doctrine type hinting of UUID/ULID values --- components/uid.rst | 58 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/components/uid.rst b/components/uid.rst index 287789ac368..e5888c66b88 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -168,6 +168,35 @@ entity primary keys:: The UUID types and generators were introduced in Symfony 5.2. +When using built-in Doctrine repository methods (e.g. ``findOneBy()``), Doctrine +knows how to convert these UUID types to build the SQL query +(e.g. ``->findOneBy(['user' => $user->getUuid()])``). However, when using DQL +queries or building the query yourself, you'll need to set ``uuid`` as the type +of the UUID parameters:: + + // src/Repository/ProductRepository.php + + // ... + class ProductRepository extends ServiceEntityRepository + { + // ... + + public function findUserProducts(User $user): array + { + $qb = $this->createQueryBuilder('p') + // ... + // add 'uuid' as the third argument to tell Doctrine that this is an UUID + ->setParameter('user', $user->getUuid(), 'uuid') + + // alternatively, you can convert it to a value compatible with + // the type inferred by Doctrine + ->setParameter('user', $user->getUuid()->toBinary()) + ; + + // ... + } + } + ULIDs ----- @@ -283,6 +312,35 @@ entity primary keys:: The ULID types and generator were introduced in Symfony 5.2. +When using built-in Doctrine repository methods (e.g. ``findOneBy()``), Doctrine +knows how to convert these ULID types to build the SQL query +(e.g. ``->findOneBy(['user' => $user->getUlid()])``). However, when using DQL +queries or building the query yourself, you'll need to set ``ulid`` as the type +of the ULID parameters:: + + // src/Repository/ProductRepository.php + + // ... + class ProductRepository extends ServiceEntityRepository + { + // ... + + public function findUserProducts(User $user): array + { + $qb = $this->createQueryBuilder('p') + // ... + // add 'ulid' as the third argument to tell Doctrine that this is an ULID + ->setParameter('user', $user->getUlid(), 'ulid') + + // alternatively, you can convert it to a value compatible with + // the type inferred by Doctrine + ->setParameter('user', $user->getUlid()->toBinary()) + ; + + // ... + } + } + .. _`unique identifiers`: https://en.wikipedia.org/wiki/UID .. _`UUIDs`: https://en.wikipedia.org/wiki/Universally_unique_identifier .. _`ULIDs`: https://github.com/ulid/spec From 4f0ff7eaad978853b220f2956b96e6061244bf93 Mon Sep 17 00:00:00 2001 From: Adamo Crespi Date: Sat, 12 Dec 2020 13:46:23 +0100 Subject: [PATCH 0248/5766] Update normalizers.rst It was indicated a wrong class. The class `Symfony\Component\Serializer\Normalizer\NormalizableInterface` was not mentioned in the part that tells about how to normalize an object that implements the interface. --- serializer/normalizers.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/serializer/normalizers.rst b/serializer/normalizers.rst index 002cc02a433..78cc103d763 100644 --- a/serializer/normalizers.rst +++ b/serializer/normalizers.rst @@ -36,10 +36,10 @@ Symfony includes the following normalizers but you can also transform :phpclass:`SplFileInfo` objects in `Data URIs`_ * :class:`Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer` to normalize PHP object using an object that implements + :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface`; * :class:`Symfony\\Component\\Serializer\\Normalizer\\FormErrorNormalizer` for objects implementing the :class:`Symfony\\Component\\Form\\FormInterface` to - normalize form errors. - :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface`; + normalize form errors; * :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer` to normalize PHP object using the getter and setter methods of the object; * :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer` to From 586503b66bbb23c27f218d0082c6b6f4b2a81e7c Mon Sep 17 00:00:00 2001 From: Volodymyr Stelmakh Date: Sat, 12 Dec 2020 15:14:57 +0100 Subject: [PATCH 0249/5766] fix method name typo in tip --- components/semaphore.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/semaphore.rst b/components/semaphore.rst index 5f26c781164..ebae3df89e8 100644 --- a/components/semaphore.rst +++ b/components/semaphore.rst @@ -76,6 +76,6 @@ already acquired. If you don't release the semaphore explicitly, it will be released automatically on instance destruction. In some cases, it can be useful to lock a resource across several requests. To disable the automatic release - behavior, set the fifth argument of the ``createLock()`` method to ``false``. + behavior, set the fifth argument of the ``createSemaphore()`` method to ``false``. .. _`semaphores`: https://en.wikipedia.org/wiki/Semaphore_(programming) From f5ebf4229f7f24e371dc749fdd9b6c543ff68fab Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 13 Dec 2020 17:27:25 +0100 Subject: [PATCH 0250/5766] Update the Nginx example MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When I was looking through the Nginx configuration recipe for Symfony 4.x I discovered an important comment that isn’t included in the example in the Nginx section. I think this tip may be useful for those who create their environment using docker containers. In this PR I added the missing comment, which is taken from the recipe on this page: https://www.nginx.com/resources/wiki/start/topics/recipes/symfony/#secure-symfony-4-x. --- setup/web_server_configuration.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup/web_server_configuration.rst b/setup/web_server_configuration.rst index e4fef9b3d99..603a0ba3bbd 100644 --- a/setup/web_server_configuration.rst +++ b/setup/web_server_configuration.rst @@ -333,6 +333,9 @@ The **minimum configuration** to get your application running under Nginx is: # Otherwise, PHP's OPcache may not properly detect changes to # your PHP files (see https://github.com/zendtech/ZendOptimizerPlus/issues/126 # for more information). + # Caveat: When PHP-FPM is hosted on a different machine from nginx + # $realpath_root may not resolve as you expect! In this case try using + # $document_root instead. fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param DOCUMENT_ROOT $realpath_root; # Prevents URIs that include the front controller. This will 404: From 159da027be25c9013a101f723c87cbdecd50e545 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20H=C3=A9lias?= Date: Thu, 12 Nov 2020 15:32:14 +0100 Subject: [PATCH 0251/5766] Add missing options context --- components/serializer.rst | 87 +++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index 20d31fa8c0c..b2cf03b2192 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -691,7 +691,24 @@ When serializing, you can set a callback to format a specific object property:: Normalizers ----------- -There are several types of normalizers available: +Normalizers turn **object** into **array** and vice versa. They implement +::class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface` +for normalize (object to array) and +:class:`Symfony\\Component\\Serializer\\Normalizer\\DenormalizableInterface` for denormalize +(array to object). + +You can add new normalizers to a Serializer instance by using its first constructor 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 ` @@ -765,6 +782,14 @@ There are several types of normalizers available: :class:`Symfony\\Component\\Serializer\\Normalizer\\ProblemNormalizer` Normalizes errors according to the API Problem spec `RFC 7807`_. +.. note:: + + You can also create your own Normalizer to use another structure. Read more at + :doc:`/serializer/custom_normalizer`. + +All these normalizers are enabled by default when using the Serializer component +in a Symfony application. + .. _component-serializer-encoders: Encoders @@ -803,6 +828,11 @@ The Serializer component provides several built-in encoders: :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. @@ -923,18 +953,29 @@ which defines the configuration options for the XmlEncoder an associative array: These are the options available: -====================== ==================================================== ========================== -Option Description Default -====================== ==================================================== ========================== -``xml_format_output`` If set to true, formats the generated XML with line - breaks and indentation. -``xml_version`` Sets the XML version attribute ``1.1`` -``xml_encoding`` Sets the XML encoding attribute ``utf-8`` -``xml_standalone`` Adds standalone attribute in the generated XML ``true`` -``xml_root_node_name`` Sets the root node name (default: ``response``). -``remove_empty_tags`` If set to true, removes all empty tags in the ``false`` - generated XML -====================== ==================================================== ========================== +============================== ================================================= ========================== +Option Description Default +============================== ================================================= ========================== +``xml_format_output`` If set to true, formats the generated XML with + line breaks and indentation. +``xml_version`` Sets the XML version attribute ``1.1`` +``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 forgot the attribute ``true`` + type casting +``xml_root_node_name`` Sets the root node name (default: ``response``). +``as_collection`` Always returns results as a collection, even if + only one line is decoded +``decoder_ignored_node_types`` Sets nodes to be ignored in the decode ``[\XML_PI_NODE, \XML_COMMENT_NODE]`` +``encoder_ignored_node_types`` Sets nodes to be ignored in the encode ``[]`` +``load_options`` XML loading `options with libxml`_ ``\LIBXML_NONET | \LIBXML_NOBLANKS`` +``remove_empty_tags`` If set to true, removes all empty tags in the ``false`` + generated XML +============================== ================================================= ========================== + +.. versionadded:: 4.2 + + The ``decoder_ignored_node_types`` & ``encoder_ignored_node_types`` options was introduced in Symfony 4.2. The ``YamlEncoder`` ~~~~~~~~~~~~~~~~~~~ @@ -942,6 +983,25 @@ The ``YamlEncoder`` This encoder requires the :doc:`Yaml Component ` 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:: + + $xmlEncoder->encode($array, 'xml', $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 +=============== ======================================================== ========================== + Skipping ``null`` Values ------------------------ @@ -1508,6 +1568,7 @@ Learn more .. _`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 .. _JSON: http://www.json.org/ .. _XML: https://www.w3.org/XML/ .. _YAML: https://yaml.org/ From 912c86df25f7bc10f929f85b285093b010c53ca1 Mon Sep 17 00:00:00 2001 From: Christoph Wieseke Date: Tue, 15 Dec 2020 15:51:52 +0100 Subject: [PATCH 0252/5766] [PropertyAccess] fixed typos for feature enable/disable fixed typos in comments for feature enable/disable --- components/property_access.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/property_access.rst b/components/property_access.rst index d7890e13c5e..4069719cf41 100644 --- a/components/property_access.rst +++ b/components/property_access.rst @@ -519,10 +519,10 @@ configured to enable extra features. To do that you could use the $propertyAccessorBuilder->enableMagicSet(); // enables magic __set $propertyAccessorBuilder->enableMagicMethods(); // enables magic __get, __set and __call - $propertyAccessorBuilder->disableMagicCall(); // enables magic __call - $propertyAccessorBuilder->disableMagicGet(); // enables magic __get - $propertyAccessorBuilder->disableMagicSet(); // enables magic __set - $propertyAccessorBuilder->disableMagicMethods(); // enables magic __get, __set and __call + $propertyAccessorBuilder->disableMagicCall(); // disables magic __call + $propertyAccessorBuilder->disableMagicGet(); // disables magic __get + $propertyAccessorBuilder->disableMagicSet(); // disables magic __set + $propertyAccessorBuilder->disableMagicMethods(); // disables magic __get, __set and __call // checks if magic __call, __get or __set handling are enabled $propertyAccessorBuilder->isMagicCallEnabled(); // true or false From 8e2e7de46658db06b8809c6e0036c9ad1cdde104 Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Wed, 9 Dec 2020 17:33:46 +0100 Subject: [PATCH 0253/5766] Add documentation about redis cache configuration --- components/cache/adapters/redis_adapter.rst | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst index c97ab697831..e9d1fec6237 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -201,6 +201,18 @@ In order to use tag-based invalidation, you can wrap your adapter in :class:`Sym $client = RedisAdapter::createConnection('redis://localhost'); $cache = new RedisTagAwareAdapter($client); +Configuring Redis +~~~~~~~~~~~~~~~~~ + +When using Redis as cache, you should configure the `maxmemory` and `maxmemory-policy` settings. +Read more about this topic in the offical `Redis LRU Cache Documentation`_. +By setting `maxmemory`, you limit how much memory Redis is allowed to consume. If the amount is too low, Redis will drop entries that would still be useful and you benefit less from your cache. Setting the `maxmemory-policy` to +`allkeys-lru` tells Redis that it is ok to drop data when it runs out of memory, and to first drop the oldest entries (least +recently used). If you do not allow Redis to drop entries, it will return an error when you try to add data when no +memory is available. An example setting could look as follows: + + maxmemory 100mb + maxmemory-policy allkeys-lru .. _`Data Source Name (DSN)`: https://en.wikipedia.org/wiki/Data_source_name .. _`Redis server`: https://redis.io/ @@ -211,3 +223,4 @@ In order to use tag-based invalidation, you can wrap your adapter in :class:`Sym .. _`Predis Connection Parameters`: https://github.com/nrk/predis/wiki/Connection-Parameters#list-of-connection-parameters .. _`TCP-keepalive`: https://redis.io/topics/clients#tcp-keepalive .. _`Redis Sentinel`: https://redis.io/topics/sentinel +.. _`Redis LRU Cache Documentation`: https://redis.io/topics/lru-cache From ead414bfbcd3fd1212498f05aaded72c45b6c700 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 16 Dec 2020 14:43:05 +0100 Subject: [PATCH 0254/5766] minor. refs #14683 --- components/cache/adapters/redis_adapter.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst index e9d1fec6237..935afcd9f92 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -204,16 +204,21 @@ In order to use tag-based invalidation, you can wrap your adapter in :class:`Sym Configuring Redis ~~~~~~~~~~~~~~~~~ -When using Redis as cache, you should configure the `maxmemory` and `maxmemory-policy` settings. -Read more about this topic in the offical `Redis LRU Cache Documentation`_. -By setting `maxmemory`, you limit how much memory Redis is allowed to consume. If the amount is too low, Redis will drop entries that would still be useful and you benefit less from your cache. Setting the `maxmemory-policy` to -`allkeys-lru` tells Redis that it is ok to drop data when it runs out of memory, and to first drop the oldest entries (least -recently used). If you do not allow Redis to drop entries, it will return an error when you try to add data when no -memory is available. An example setting could look as follows: +When using Redis as cache, you should configure the ``maxmemory`` and ``maxmemory-policy`` +settings. By setting ``maxmemory``, you limit how much memory Redis is allowed to consume. +If the amount is too low, Redis will drop entries that would still be useful and you benefit +less from your cache. Setting the ``maxmemory-policy`` to ``allkeys-lru`` tells Redis that +it is ok to drop data when it runs out of memory, and to first drop the oldest entries (least +recently used). If you do not allow Redis to drop entries, it will return an error when you +try to add data when no memory is available. An example setting could look as follows: + +.. code-block:: ini maxmemory 100mb maxmemory-policy allkeys-lru +Read more about this topic in the offical `Redis LRU Cache Documentation`_. + .. _`Data Source Name (DSN)`: https://en.wikipedia.org/wiki/Data_source_name .. _`Redis server`: https://redis.io/ .. _`Redis`: https://github.com/phpredis/phpredis From 134df97392feb4ce78293595ea28eee35ed6348e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rathgeber=20St=C3=A9phane?= Date: Wed, 16 Dec 2020 18:53:48 +0100 Subject: [PATCH 0255/5766] Remove white 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 69883859d53..d88bb5d32ed 100644 --- a/quick_tour/the_architecture.rst +++ b/quick_tour/the_architecture.rst @@ -155,7 +155,7 @@ difference is that it's done in the constructor: { // ... - + $this->logger->info('Using the greeting: '.$greeting); + + $this->logger->info('Using the greeting: '.$greeting); return $greeting; } From 7bf71ce65e972e466826e9046318b404e3031318 Mon Sep 17 00:00:00 2001 From: MrYamous Date: Wed, 16 Dec 2020 23:26:59 +0100 Subject: [PATCH 0256/5766] Remove UuidBinary/UlidBinary usages from documentation --- components/uid.rst | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index e5888c66b88..fef72839f52 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -115,7 +115,7 @@ UUID objects created with the ``Uuid`` class can use the following methods Storing UUIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can store UUID values as any other regular string/binary values in the database. +You can store UUID values as any other regular string values in the database. However, if you :doc:`use Doctrine `, it's more convenient to use the special Doctrine types which convert to/from UUID objects automatically:: @@ -134,14 +134,13 @@ special Doctrine types which convert to/from UUID objects automatically:: */ private $someProperty; - /** - * @ORM\Column(type="uuid_binary") - */ - private $anotherProperty; - // ... } +.. versionadded:: 5.2 + + The UuidBinary type has been removed in Symfony 5.2. + There's also a Doctrine generator to help autogenerate UUID values for the entity primary keys:: @@ -260,7 +259,7 @@ ULID objects created with the ``Ulid`` class can use the following methods:: Storing ULIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can store ULID values as any other regular string/binary values in the database. +You can store ULID values as any other regular string values in the database. However, if you :doc:`use Doctrine `, it's more convenient to use the special Doctrine types which convert to/from ULID objects automatically:: @@ -279,14 +278,13 @@ special Doctrine types which convert to/from ULID objects automatically:: */ private $someProperty; - /** - * @ORM\Column(type="ulid_binary") - */ - private $anotherProperty; - // ... } +.. versionadded:: 5.2 + + The UlidBinary type has been removed in Symfony 5.2. + There's also a Doctrine generator to help autogenerate ULID values for the entity primary keys:: From 41285f0382e1056edb115c4b55c3f816aec73843 Mon Sep 17 00:00:00 2001 From: Oleksandr Barabolia Date: Mon, 16 Nov 2020 19:42:41 +0200 Subject: [PATCH 0257/5766] [Notifier] add iqsms bridge support in doc --- notifier.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/notifier.rst b/notifier.rst index b626a79ac39..9fdb9a435a8 100644 --- a/notifier.rst +++ b/notifier.rst @@ -60,6 +60,7 @@ Service Package DSN Esendex ``symfony/esendex-notifier`` ``esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM`` FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` Infobip ``symfony/infobip-notifier`` ``infobip://TOKEN@default?from=FROM`` +Iqsms ``symfony/iqsms-notifier`` ``iqsms://LOGIN:PASSWORD@default?from=FROM`` Mobyt ``symfony/mobyt-notifier`` ``mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM`` Nexmo ``symfony/nexmo-notifier`` ``nexmo://KEY:SECRET@default?from=FROM`` OvhCloud ``symfony/ovhcloud-notifier`` ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` @@ -77,6 +78,10 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= The Smsapi, Infobip, Mobyt, Esendex and Sendinblue integrations were introduced in Symfony 5.2. +.. versionadded:: 5.3 + + The Iqsms integration was introduced in Symfony 5.3. + To enable a texter, add the correct DSN in your ``.env`` file and configure the ``texter_transports``: From 1c0c7ae267a3c598ef9f5a78e12f6f1f5e40caf3 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Thu, 17 Dec 2020 21:48:23 +0100 Subject: [PATCH 0258/5766] Replace unavailable dependency in Symfony 4 --- setup/unstable_versions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup/unstable_versions.rst b/setup/unstable_versions.rst index 27036493fd4..5e11526b20e 100644 --- a/setup/unstable_versions.rst +++ b/setup/unstable_versions.rst @@ -68,7 +68,7 @@ Symfony version has deprecated some of its features. $ cd projects/my_project/ $ git checkout -b testing_new_symfony # ... update composer.json configuration - $ composer update symfony/symfony + $ composer update "symfony/*" # ... after testing the new Symfony version $ git checkout master From 2dbe568d4575e3472e0337757e134f7821c8c831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Korczewski?= Date: Fri, 18 Dec 2020 02:50:05 +0100 Subject: [PATCH 0259/5766] Fixed typo --- form/without_class.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/form/without_class.rst b/form/without_class.rst index 85838d77ce9..5f565ebfb52 100644 --- a/form/without_class.rst +++ b/form/without_class.rst @@ -79,7 +79,7 @@ you want to use. See :doc:`/validation` for more details. .. _form-option-constraints: -But if the form is not mapped to an object and you instead want to retrieve a +But if the form is not mapped to an object and you instead want to retrieve an array of your submitted data, how can you add constraints to the data of your form? From ddd13674681771b2ea316f90eb6a9134a99c990e Mon Sep 17 00:00:00 2001 From: Fouad <48414048+ltlsquare@users.noreply.github.com> Date: Fri, 18 Dec 2020 11:13:39 +0400 Subject: [PATCH 0260/5766] Update uid.rst Uuid::fromString(); should not be instantiated as "new". The Ulid section is correct the uuid section contains this error. Especially confusing when you are just starting with this newly implemented functionality. --- components/uid.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/uid.rst b/components/uid.rst index c8eee0ece94..9a097a3e675 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -71,7 +71,7 @@ Converting UUIDs Use these methods to transform the UUID object into different bases:: - $uuid = new Uuid::fromString('d9e7a184-5d5b-11ea-a62a-3499710062d0'); + $uuid = Uuid::fromString('d9e7a184-5d5b-11ea-a62a-3499710062d0'); $uuid->toBinary(); // string(16) "..." (binary contents can't be printed) $uuid->toBase32(); // string(26) "6SWYGR8QAV27NACAHMK5RG0RPG" From 1e1ff71f20d292072dd5c18f4bf0794739e2f39d Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 18 Dec 2020 11:33:45 +0100 Subject: [PATCH 0261/5766] Support JWT v4 --- mercure.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mercure.rst b/mercure.rst index 9dd6fe205b9..e4bc11d911f 100644 --- a/mercure.rst +++ b/mercure.rst @@ -408,7 +408,7 @@ And here is the controller:: // src/Controller/DiscoverController.php namespace App\Controller; - use Lcobucci\JWT\Builder; + use Lcobucci\JWT\Configuration; use Lcobucci\JWT\Signer\Hmac\Sha256; use Lcobucci\JWT\Signer\Key; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; @@ -423,10 +423,13 @@ And here is the controller:: $hubUrl = $this->getParameter('mercure.default_hub'); $this->addLink($request, new Link('mercure', $hubUrl)); - $token = (new Builder()) - // set other appropriate JWT claims, such as an expiration date + $key = Key\InMemory::plainText('mercure_secret_key'); // don't forget to set this parameter! Test value: !ChangeMe! + $configuration = Configuration::forSymmetricSigner(new Sha256(), $key); + + $token = $configuration->builder() ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * - ->getToken(new Sha256(), new Key($this->getParameter('mercure_secret_key'))); // don't forget to set this parameter! Test value: !ChangeMe! + ->getToken($configuration->signer(), $configuration->signingKey()) + ->toString(); $response = $this->json(['@id' => '/demo/books/1', 'availability' => 'https://schema.org/InStock']); $response->headers->set( From efea74512cbe0f140de4a6e9409c0221f759a838 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 18 Dec 2020 11:37:52 +0100 Subject: [PATCH 0262/5766] Update DSN --- notifier.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notifier.rst b/notifier.rst index 3145bce544c..4a587019e57 100644 --- a/notifier.rst +++ b/notifier.rst @@ -59,7 +59,7 @@ Service Package DSN ========== ================================ ==================================================== Esendex ``symfony/esendex-notifier`` ``esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM`` FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` -Infobip ``symfony/infobip-notifier`` ``infobip://TOKEN@default?from=FROM`` +Infobip ``symfony/infobip-notifier`` ``infobip://ACCESS_TOKEN@HOST?from=FROM`` Mobyt ``symfony/mobyt-notifier`` ``mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM`` Nexmo ``symfony/nexmo-notifier`` ``nexmo://KEY:SECRET@default?from=FROM`` OvhCloud ``symfony/ovh-cloud-notifier`` ``ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME`` @@ -147,7 +147,7 @@ Mattermost ``symfony/mattermost-notifier`` ``mattermost://TOKEN@ENDPOINT?chan 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`` -Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:APIKEY@ENDPOINT?channel=CHANNEL`` +Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL`` ========== ================================ =========================================================================== .. versionadded:: 5.1 From facf002bb506ca6b811d72797f03ae21498d665e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 18 Dec 2020 11:44:54 +0100 Subject: [PATCH 0263/5766] Update DSN --- notifier.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 3f7d7008de9..c5e8181c22a 100644 --- a/notifier.rst +++ b/notifier.rst @@ -131,7 +131,7 @@ integration with these chat services: ========== ================================ ============================================ Service Package DSN ========== ================================ ============================================ -Mattermost ``symfony/mattermost-notifier`` ``mattermost://TOKEN@ENDPOINT?channel=CHANNEL`` +Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` RocketChat ``symfony/rocket-chat-notifier`` ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL`` Slack ``symfony/slack-notifier`` ``slack://default/ID`` Telegram ``symfony/telegram-notifier`` ``telegram://TOKEN@default?channel=CHAT_ID`` From dc29127bf23aba45b1ec6cec5b0444fd05fe7139 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 15:16:26 +0100 Subject: [PATCH 0264/5766] Tweaks --- components/uid.rst | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index b0fd455add0..ccf372ddd96 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -115,9 +115,8 @@ UUID objects created with the ``Uuid`` class can use the following methods Storing UUIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can store UUID values as any other regular string values in the database. -However, if you :doc:`use Doctrine `, it's more convenient to use the -special Doctrine types which convert to/from UUID objects automatically:: +If you :doc:`use Doctrine `, consider using the ``uuid`` Doctrine +type, which converts to/from UUID objects automatically:: // src/Entity/Product.php namespace App\Entity; @@ -137,10 +136,6 @@ special Doctrine types which convert to/from UUID objects automatically:: // ... } -.. versionadded:: 5.2 - - The UuidBinary type has been removed in Symfony 5.2. - There's also a Doctrine generator to help autogenerate UUID values for the entity primary keys:: @@ -165,7 +160,7 @@ entity primary keys:: .. versionadded:: 5.2 - The UUID types and generators were introduced in Symfony 5.2. + The UUID type and generators were introduced in Symfony 5.2. When using built-in Doctrine repository methods (e.g. ``findOneBy()``), Doctrine knows how to convert these UUID types to build the SQL query @@ -259,9 +254,8 @@ ULID objects created with the ``Ulid`` class can use the following methods:: Storing ULIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ -You can store ULID values as any other regular string values in the database. -However, if you :doc:`use Doctrine `, it's more convenient to use the -special Doctrine types which convert to/from ULID objects automatically:: +If you :doc:`use Doctrine `, consider using the ``ulid`` Doctrine +type, which converts to/from ULID objects automatically:: // src/Entity/Product.php namespace App\Entity; @@ -281,10 +275,6 @@ special Doctrine types which convert to/from ULID objects automatically:: // ... } -.. versionadded:: 5.2 - - The UlidBinary type has been removed in Symfony 5.2. - There's also a Doctrine generator to help autogenerate ULID values for the entity primary keys:: @@ -308,7 +298,7 @@ entity primary keys:: .. versionadded:: 5.2 - The ULID types and generator were introduced in Symfony 5.2. + The ULID type and generator were introduced in Symfony 5.2. When using built-in Doctrine repository methods (e.g. ``findOneBy()``), Doctrine knows how to convert these ULID types to build the SQL query From 4629dba683293de46b4d8a1ae5ca9ec81f394f3f Mon Sep 17 00:00:00 2001 From: Dale Nash Date: Fri, 18 Dec 2020 15:10:56 +0000 Subject: [PATCH 0265/5766] Update setup.rst Fix incorrect quotation mark type --- setup.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.rst b/setup.rst index 5700c2b8878..30ef0375f20 100644 --- a/setup.rst +++ b/setup.rst @@ -65,10 +65,10 @@ Symfony application using Composer: .. code-block:: terminal # run this if you are building a traditional web application - $ composer create-project symfony/website-skeleton:"5.3.x@dev' my_project_name + $ composer create-project symfony/website-skeleton:"5.3.x@dev" my_project_name # run this if you are building a microservice, console application or API - $ composer create-project symfony/skeleton:"5.3.x@dev' my_project_name + $ composer create-project symfony/skeleton:"5.3.x@dev" my_project_name No matter which command you run to create the Symfony application. All of them will create a new ``my_project_name/`` directory, download some dependencies From 8250dc71f0cec24f3cc2b7a29431684265e10eca Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 18 Dec 2020 16:20:45 +0100 Subject: [PATCH 0266/5766] Fix build --- notifier.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 7e50df6c212..10a0a5490aa 100644 --- a/notifier.rst +++ b/notifier.rst @@ -144,7 +144,6 @@ integration with these chat services: ========== ================================ =========================================================================== Service Package DSN -<<<<<<< HEAD ========== ================================ =========================================================================== Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?threadKey=THREAD_KEY`` From d4358eb4295728074b913f98a66a021a41aeacea Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 16:58:36 +0100 Subject: [PATCH 0267/5766] Mention a possible way of reusing the same form --- forms.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/forms.rst b/forms.rst index 12013e8fbfc..1654aa3deba 100644 --- a/forms.rst +++ b/forms.rst @@ -449,6 +449,16 @@ possible paths: data is passed to it, you can :doc:`use the submit() method to handle form submissions `. +.. tip:: + + If you need to render and process the same form in different templates, + use the ``render()`` function to :ref:`embed the controller ` + that processes the form: + + .. code-block:: twig + + {{ render(controller('App\\Controller\\TaskController::new')) }} + .. _validating-forms: Validating Forms From 0e925a0993bd16ecac6f8560e4686cc63d322418 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 17:21:19 +0100 Subject: [PATCH 0268/5766] Reword the introduction about using Bootstrap and Encore --- frontend/encore/bootstrap.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/frontend/encore/bootstrap.rst b/frontend/encore/bootstrap.rst index ff281f588ac..fedb5153cac 100644 --- a/frontend/encore/bootstrap.rst +++ b/frontend/encore/bootstrap.rst @@ -1,9 +1,9 @@ Using Bootstrap CSS & JS ======================== -Want to use Bootstrap (or something similar) in your project? No problem! -First, install it. To be able to customize things further, we'll install -``bootstrap``: +This article explains how to install and integrate the `Bootstrap CSS framework`_ +in your Symfony application using :doc:`Webpack Encore `. +First, to be able to customize things further, we'll install ``bootstrap``: .. code-block:: terminal @@ -79,3 +79,5 @@ and CSS like normal: // require 2 CSS files needed require('bootstrap-star-rating/css/star-rating.css'); require('bootstrap-star-rating/themes/krajee-svg/theme.css'); + +.. _`Bootstrap CSS framework`: https://getbootstrap.com/ From 8af100d63a63d2bf22c99117f686d64e1b963ea3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 17:31:00 +0100 Subject: [PATCH 0269/5766] Mention that Symfony only loads YAML routes by default --- routing.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/routing.rst b/routing.rst index ec6de557b5d..a7d5be18fb6 100644 --- a/routing.rst +++ b/routing.rst @@ -147,6 +147,12 @@ the ``BlogController``: ; }; +.. versionadded:: 5.1 + + Starting from Symfony 5.1, by default Symfony only loads the routes defined + in YAML format. If you define routes in XML and/or PHP formats, update the + ``src/Kernel.php`` file to add support for the ``.xml`` and ``.php`` file extensions. + .. _routing-matching-http-methods: Matching HTTP Methods From 58bcabbd13cfc3f0611736f5d8cf67cc103ae8e4 Mon Sep 17 00:00:00 2001 From: Gawain Lynch Date: Sat, 19 Dec 2020 04:01:02 +0100 Subject: [PATCH 0270/5766] Correct annotation for ULID type --- components/uid.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/uid.rst b/components/uid.rst index ccf372ddd96..bdeb252bb65 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -287,7 +287,7 @@ entity primary keys:: { /** * @ORM\Id - * @ORM\Column(type="uuid", unique=true) + * @ORM\Column(type="ulid", unique=true) * @ORM\GeneratedValue(strategy="CUSTOM") * @ORM\CustomIdGenerator(class=UlidGenerator::class) */ From 63a4e504fb2e1685618690ebb0348ce8e76366b0 Mon Sep 17 00:00:00 2001 From: Gawain Lynch Date: Sat, 19 Dec 2020 04:14:46 +0100 Subject: [PATCH 0271/5766] Remove merge conflict header --- notifier.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 057545d1b71..62052eb96dc 100644 --- a/notifier.rst +++ b/notifier.rst @@ -139,7 +139,6 @@ integration with these chat services: ========== ================================ =========================================================================== Service Package DSN -<<<<<<< HEAD ========== ================================ =========================================================================== Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?threadKey=THREAD_KEY`` From b2c66b145971b0f8cae7b3c318361814c98ae2dc Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 11:12:51 +0100 Subject: [PATCH 0272/5766] [DependencyInjection] Add ServiceLocatorArgument to generate array-based locators --- .../service_subscribers_locators.rst | 92 ++++++++++++++++--- 1 file changed, 78 insertions(+), 14 deletions(-) diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index 2fc0ec54fb1..fc702a52f27 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -246,9 +246,80 @@ service type to a service. Defining a Service Locator -------------------------- -To manually define a service locator, create a new service definition and add -the ``container.service_locator`` tag to it. Use the first argument of the -service definition to pass a collection of services to the service locator: +To manually define a service locator and inject it to another service, create an +argument of type ``service_locator``: + +.. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + services: + App\CommandBus: + arguments: + !service_locator + App\FooCommand: '@app.command_handler.foo' + App\BarCommand: '@app.command_handler.bar' + + .. code-block:: xml + + + + + + + + + + + + + + + + + + .. code-block:: php + + // config/services.php + namespace Symfony\Component\DependencyInjection\Loader\Configurator; + + use App\CommandBus; + + return function(ContainerConfigurator $configurator) { + $services = $configurator->services(); + + $services->set(CommandBus::class) + ->args([service_locator([ + 'App\FooCommand' => ref('app.command_handler.foo'), + 'App\BarCommand' => ref('app.command_handler.bar'), + // if the element has no key, the ID of the original service is used + ref('app.command_handler.baz'), + ])]); + }; + +.. versionadded:: 4.2 + + The ability to add services without specifying an array key was introduced + in Symfony 4.2. + +.. versionadded:: 4.2 + + The ``service_locator`` argument type was introduced in Symfony 4.2. + +As shown in the previous sections, the constructor of the ``CommandBus`` class +must type-hint its argument with ``ContainerInterface``. Then, you can get any of +the service locator services via their ID (e.g. ``$this->locator->get('App\FooCommand')``). + +Reusing a Service Locator in Multiple Services +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If you inject the same service locator in several services, it's better to +define the service locator as a stand-alone service and then inject it in the +other services. To do so, create a new service definition using the +``ServiceLocator`` class: .. configuration-block:: @@ -334,17 +405,7 @@ service definition to pass a collection of services to the service locator: previous Symfony versions you always needed to add the ``container.service_locator`` tag explicitly. -.. versionadded:: 4.2 - - The ability to add services without specifying their id was introduced in - Symfony 4.2. - -.. note:: - - The services defined in the service locator argument must include keys, - which later become their unique identifiers inside the locator. - -Now you can use the service locator by injecting it in any other service: +Now you can inject the service locator in any other services: .. configuration-block:: @@ -386,6 +447,9 @@ Now you can use the service locator by injecting it in any other service: ->args([ref('app.command_handler_locator')]); }; +Using Service Locators in Compiler Passes +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + In :doc:`compiler passes ` it's recommended to use the :method:`Symfony\\Component\\DependencyInjection\\Compiler\\ServiceLocatorTagPass::register` method to create the service locators. This will save you some boilerplate and From d66cc136e35bd62b20cc97b0c5ed6723ad847ae1 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 18 Dec 2020 16:09:26 +0100 Subject: [PATCH 0273/5766] Added a short guide about contributing code translations --- best_practices.rst | 2 + contributing/index.rst | 1 + contributing/translations/index.rst | 103 ++++++++++++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 contributing/translations/index.rst diff --git a/best_practices.rst b/best_practices.rst index 02434a7c812..2880c1014e5 100644 --- a/best_practices.rst +++ b/best_practices.rst @@ -320,6 +320,8 @@ are two of the main tasks when handling forms. Both are too similar (most of the times, almost identical), so it's much simpler to let a single controller action handle both. +.. _best-practice-internationalization: + Internationalization -------------------- diff --git a/contributing/index.rst b/contributing/index.rst index 923a4e48ed4..d76b4a8e037 100644 --- a/contributing/index.rst +++ b/contributing/index.rst @@ -7,6 +7,7 @@ Contributing code_of_conduct/index code/index documentation/index + translations/index community/index diversity/index diff --git a/contributing/translations/index.rst b/contributing/translations/index.rst new file mode 100644 index 00000000000..d865111f0cf --- /dev/null +++ b/contributing/translations/index.rst @@ -0,0 +1,103 @@ +Contributing Translations +========================= + +Some Symfony Components include certain messages that must be translated to +different languages. For example, if a user submits a form with a wrong value in +a :doc:`TimezoneType ` field, Symfony shows the +following error message by default: "This value is not a valid timezone." + +These messages are translated into tens of languages thanks to the Symfony +community. Symfony adds new messages on a regular basis, so this is an ongoing +translation process and you can help us providing the missing translations. + +How to Contribute a Translation +------------------------------- + +Imagine that you can speak both English and Swedish and want to check if there's +some missing Swedish translations to contribute them. + +**Step 1.** Translations are contributed to the oldest maintained branch of the +Symfony repository. Visit the `Symfony Releases`_ page to find out which is the +current oldest maintained branch. + +Then, you need to either download or browse that Symfony version contents: + +* If you know Git and prefer the command console, clone the Symfony repository + and check out the oldest maintained branch (read the + :doc:`Symfony Documentation contribution guide ` + if you want to learn about this process); +* If you prefer to use a web based interface, visit + `https://github.com/symfony/symfony `_ + and switch to the oldest maintained branch. + +**Step 2.** Check out if there's some missing translation in your language by +checking these directories: + +* ``src/Symfony/Component/Form/Resources/translations/`` +* ``src/Symfony/Component/Security/Core/Resources/translations/`` +* ``src/Symfony/Component/Validator/Resources/translations/`` + +Symfony uses the :ref:`XLIFF format ` to +store translations. In this example, you are looking for missing Swedish +translations, so you should look for files called ``*.sv.xlf``. + +.. note:: + + If there's no XLIFF file for your language yet, create it yourself + duplicating the original English file (e.g. ``validators.en.xlf``). + +**Step 3.** Contribute the missing translations. To do that, compare the file +in your language to the equivalent file in English. + +Imagine that you open the ``validators.sv.xlf`` and see this at the end of the file: + +.. code-block:: xml + + + + + + This value should be either negative or zero. + Detta värde bör vara antingen negativt eller noll. + + + This value is not a valid timezone. + Detta värde är inte en giltig tidszon. + + +If you open the equivalent ``validators.en.xlf`` file, you can see that the +English file has more messages to translate: + +.. code-block:: xml + + + + + + This value should be either negative or zero. + This value should be either negative or zero. + + + This value is not a valid timezone. + This value is not a valid timezone. + + + This password has been leaked in a data breach, it must not be used. Please use another password. + This password has been leaked in a data breach, it must not be used. Please use another password. + + + This value should be between {{ min }} and {{ max }}. + This value should be between {{ min }} and {{ max }}. + + +The messages with ``id=93`` and ``id=94`` are missing in the Swedish file. +Copy and paste the messages from the English file, translate the content +inside the ```` tag and save the changes. + +**Step 4.** Make the pull request against the +`https://github.com/symfony/symfony `_ repository. +If you need help, check the other Symfony guides about +:doc:`contributing code or docs ` because the process is +the same. + +.. _`Symfony Releases`: https://symfony.com/releases From d1314646d993de107ed220142630ad99eff8bbab Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 21 Dec 2020 09:30:48 +0100 Subject: [PATCH 0274/5766] Removed unnecessary versionadded directives --- service_container/service_subscribers_locators.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/service_container/service_subscribers_locators.rst b/service_container/service_subscribers_locators.rst index 8a3f9ec3852..051a0ab592c 100644 --- a/service_container/service_subscribers_locators.rst +++ b/service_container/service_subscribers_locators.rst @@ -300,15 +300,6 @@ argument of type ``service_locator``: ])]); }; -.. versionadded:: 4.2 - - The ability to add services without specifying an array key was introduced - in Symfony 4.2. - -.. versionadded:: 4.2 - - The ``service_locator`` argument type was introduced in Symfony 4.2. - As shown in the previous sections, the constructor of the ``CommandBus`` class must type-hint its argument with ``ContainerInterface``. Then, you can get any of the service locator services via their ID (e.g. ``$this->locator->get('App\FooCommand')``). From 35eee2edc5c27824a23fcb5d2e6b1ee904b535eb Mon Sep 17 00:00:00 2001 From: Maks Rafalko Date: Mon, 21 Dec 2020 13:51:59 +0300 Subject: [PATCH 0275/5766] Add missed word --- messenger/dispatch_after_current_bus.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger/dispatch_after_current_bus.rst b/messenger/dispatch_after_current_bus.rst index e382f49eed3..7daaaebc676 100644 --- a/messenger/dispatch_after_current_bus.rst +++ b/messenger/dispatch_after_current_bus.rst @@ -40,7 +40,7 @@ DispatchAfterCurrentBusMiddleware Middleware -------------------------------------------- For many applications, the desired behavior is to *only* handle messages that -are dispatched by a handler once that handler has fully finished. This can be by +are dispatched by a handler once that handler has fully finished. This can be done by using the ``DispatchAfterCurrentBusMiddleware`` and adding a ``DispatchAfterCurrentBusStamp`` stamp to :ref:`the message Envelope `:: From 3a01e25523530fa9ebeaeb40f93cf69427acf517 Mon Sep 17 00:00:00 2001 From: Bruno Baguette <1922257+Levure@users.noreply.github.com> Date: Fri, 29 May 2020 12:33:32 +0200 Subject: [PATCH 0276/5766] Added tip for files input rendering Added a tip about files input rendering in order to enable the display of the selected file. --- form/bootstrap4.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/form/bootstrap4.rst b/form/bootstrap4.rst index e96db1afb3b..10ad6c254e3 100644 --- a/form/bootstrap4.rst +++ b/form/bootstrap4.rst @@ -94,6 +94,14 @@ Checkboxes and Radios For a checkbox/radio field, calling ``form_label()`` doesn't render anything. Due to Bootstrap internals, the label is already rendered by ``form_widget()``. +File inputs +----------- + +Files input are rendered using the Bootstrap "custom-file" class. + +Due to Bootstrap internals, the rendered field does not display the selected filename. +To fix that missing display, you can use the "`bs-custom-file-input`_" plugin (vanilla javascript), as recommended by `Bootstrap Forms documentation`_. + Accessibility ------------- @@ -126,6 +134,8 @@ Symfony Form ``RadioType`` and ``CheckboxType`` by adding some classes to the la {{ form_row(form.myCheckbox, {label_attr: {class: 'switch-custom'} }) }} .. _`WCAG 2.0 standard`: https://www.w3.org/TR/WCAG20/ +.. _`bs-custom-file-input`: https://www.npmjs.com/package/bs-custom-file-input +.. _`Bootstrap Forms documentation`: https://getbootstrap.com/docs/4.4/components/forms/#file-browser .. _`custom forms`: https://getbootstrap.com/docs/4.4/components/forms/#custom-forms .. _`custom radio`: https://getbootstrap.com/docs/4.4/components/forms/#radios .. _`custom checkbox`: https://getbootstrap.com/docs/4.4/components/forms/#checkboxes From 75194ae111a0415682d0d3f51291233940122b87 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 22 Dec 2020 15:47:32 +0100 Subject: [PATCH 0277/5766] Tweaks --- form/bootstrap4.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/form/bootstrap4.rst b/form/bootstrap4.rst index 10ad6c254e3..ccf4659738c 100644 --- a/form/bootstrap4.rst +++ b/form/bootstrap4.rst @@ -97,10 +97,9 @@ Due to Bootstrap internals, the label is already rendered by ``form_widget()``. File inputs ----------- -Files input are rendered using the Bootstrap "custom-file" class. - -Due to Bootstrap internals, the rendered field does not display the selected filename. -To fix that missing display, you can use the "`bs-custom-file-input`_" plugin (vanilla javascript), as recommended by `Bootstrap Forms documentation`_. +File inputs are rendered using the Bootstrap "custom-file" class, which hides +the name of the selected file. To fix that, use the `bs-custom-file-input`_ +JavaScript plugin, as recommended by `Bootstrap Forms documentation`_. Accessibility ------------- From b51618ff97b9aab131f0f3bb80463349d1ee3b58 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Fri, 24 Jul 2020 17:03:38 +0200 Subject: [PATCH 0278/5766] [Mailer] Update mailer.rst --- mailer.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mailer.rst b/mailer.rst index 97a3dca00d7..31039f91ec0 100644 --- a/mailer.rst +++ b/mailer.rst @@ -163,12 +163,13 @@ both strings or address objects:: :class:`Symfony\\Component\\Mailer\\Event\\MessageEvent` event to set the same ``From`` email to all messages. -Multiple addresses are defined with the ``addXXX()`` methods:: +Multiple addresses can be set with ``addTo()``, ``addCc()``, or ``addBcc()``:: $email = (new Email()) ->to('foo@example.com') ->addTo('bar@example.com') - ->addTo('baz@example.com') + ->cc('cc@example.com') + ->addCc('cc2@example.com') // ... ; @@ -178,7 +179,7 @@ Alternatively, you can pass multiple addresses to each method:: $toAddresses = ['foo@example.com', new Address('bar@example.com')]; $email = (new Email()) - ->to(...$toAddresses) + ->to(...$toAddresses) // use the splat operator if you have an array ->cc('cc1@example.com', 'cc2@example.com') // ... From fb7df00f8f50c27ac3c355f06d99f1d2af323f7c Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 22 Dec 2020 15:54:52 +0100 Subject: [PATCH 0279/5766] Tweaks --- mailer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index 2d4b2819de6..fa19d77d849 100644 --- a/mailer.rst +++ b/mailer.rst @@ -274,7 +274,7 @@ both strings or address objects:: :class:`Symfony\\Component\\Mailer\\Event\\MessageEvent` event to set the same ``From`` email to all messages. -Multiple addresses can be set with ``addTo()``, ``addCc()``, or ``addBcc()``:: +Use ``addTo()``, ``addCc()``, or ``addBcc()`` methods to add more addresses:: $email = (new Email()) ->to('foo@example.com') @@ -290,7 +290,7 @@ Alternatively, you can pass multiple addresses to each method:: $toAddresses = ['foo@example.com', new Address('bar@example.com')]; $email = (new Email()) - ->to(...$toAddresses) // use the splat operator if you have an array + ->to(...$toAddresses) ->cc('cc1@example.com', 'cc2@example.com') // ... From e9cc299e2a16df478d9e8804eed575fd9cc6d2b7 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Sat, 4 Apr 2020 11:26:06 +0200 Subject: [PATCH 0280/5766] [Form] Renaming the article --- form/form_collections.rst | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index cd1f66a7a8f..fa4210b6709 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -1,15 +1,18 @@ .. index:: single: Form; Embed collection of forms -How to Embed a Collection of Forms -================================== +Edit Related Entities in a Single Form +====================================== -In this article, you'll learn how to create a form that embeds a collection -of many other forms. This could be useful, for example, if you had a ``Task`` -class and you wanted to edit/create/remove many ``Tag`` objects related to -that Task, right inside the same form. +To edit associated entities in the same form, Symfony has the concept of +Form "Collections". Think of it as a series of sub-forms, embedded into +the main form. -Let's start by creating a ``Task`` entity:: +The example used in this article is a ``Task`` entity that relates to +a ``Tag`` entitiy. The goal is to create a single form for tasks, that +also allows to edit/create/remove many tags associated with that task. + +Here's the ``Task`` and the ``Tag`` entity:: // src/Entity/Task.php namespace App\Entity; @@ -45,12 +48,10 @@ Let's start by creating a ``Task`` entity:: .. note:: - The ``ArrayCollection`` is specific to Doctrine and is basically the - same as using an ``array`` (but it must be an ``ArrayCollection`` if - you're using Doctrine). + The `ArrayCollection`_ is specific to Doctrine and is basically the + same as using an ``array``. -Now, create a ``Tag`` class. As you saw above, a ``Task`` can have many ``Tag`` -objects:: +.. code-block:: php // src/Entity/Tag.php namespace App\Entity; @@ -688,3 +689,4 @@ the relationship between the removed ``Tag`` and ``Task`` object. .. _`JSFiddle`: http://jsfiddle.net/847Kf/4/ .. _`@a2lix/symfony-collection`: https://github.com/a2lix/symfony-collection .. _`symfony-collection`: https://github.com/ninsuo/symfony-collection +.. _`ArrayCollection`: https://www.doctrine-project.org/projects/doctrine-collections/en/1.6/index.html From ca151cec146c4d16e2e3c8168231c37d9e837356 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 22 Dec 2020 16:55:55 +0100 Subject: [PATCH 0281/5766] Tweaks --- form/form_collections.rst | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index fa4210b6709..30215b0a37d 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -1,18 +1,15 @@ .. index:: single: Form; Embed collection of forms -Edit Related Entities in a Single Form -====================================== +How to Embed a Collection of Forms +================================== -To edit associated entities in the same form, Symfony has the concept of -Form "Collections". Think of it as a series of sub-forms, embedded into -the main form. +Symfony Forms can embed a collection of many other forms, which is useful to +edit related entities in a single form. In this article, you'll create a form to +edit a ``Task`` class and, right inside the same form, you'll be able to edit, +create and remove many ``Tag`` objects related to that Task. -The example used in this article is a ``Task`` entity that relates to -a ``Tag`` entitiy. The goal is to create a single form for tasks, that -also allows to edit/create/remove many tags associated with that task. - -Here's the ``Task`` and the ``Tag`` entity:: +Let's start by creating a ``Task`` entity:: // src/Entity/Task.php namespace App\Entity; @@ -48,8 +45,11 @@ Here's the ``Task`` and the ``Tag`` entity:: .. note:: - The `ArrayCollection`_ is specific to Doctrine and is basically the - same as using an ``array``. + The `ArrayCollection`_ is specific to Doctrine and is similar to a PHP array + but provides many utility methods. + +Now, create a ``Tag`` class. As you saw above, a ``Task`` can have many ``Tag`` +objects:: .. code-block:: php From 2b1f063ea379fffb2c42e527aaceba2d3553ba67 Mon Sep 17 00:00:00 2001 From: Wim Molenberghs Date: Mon, 2 Nov 2020 08:54:22 +0100 Subject: [PATCH 0282/5766] Add DirectoryIndex to fallback for resources When DirectoryIndex is set FallbackResource disabled will do nothing because apache falls back to DirectoryIndex --- setup/web_server_configuration.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/setup/web_server_configuration.rst b/setup/web_server_configuration.rst index e4fef9b3d99..710a2f89dc6 100644 --- a/setup/web_server_configuration.rst +++ b/setup/web_server_configuration.rst @@ -127,6 +127,7 @@ and increase web server performance: # which will allow Apache to return a 404 error when files are # not found instead of passing the request to Symfony + DirectoryIndex disabled FallbackResource disabled ErrorLog /var/log/apache2/project_error.log From 84ac5b201a4209113fe32e54d16b49dcb08fc0e6 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Tue, 22 Dec 2020 17:03:51 +0100 Subject: [PATCH 0283/5766] Tweak doc around proxy manager bridge --- service_container/lazy_services.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/service_container/lazy_services.rst b/service_container/lazy_services.rst index 936316bb029..7b33bcdfcac 100644 --- a/service_container/lazy_services.rst +++ b/service_container/lazy_services.rst @@ -93,9 +93,9 @@ To check if your proxy works you can check the interface of the received object: .. note:: - If you don't install the `ProxyManager bridge`_ and the - `ocramius/proxy-manager`_, the container will skip over the ``lazy`` - flag and directly instantiate the service as it would normally do. + If you don't install the `ProxyManager bridge`_ , the container will skip + over the ``lazy`` flag and directly instantiate the service as it would + normally do. Additional Resources -------------------- @@ -106,5 +106,4 @@ in the `documentation of ProxyManager`_. .. _`ProxyManager bridge`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bridge/ProxyManager .. _`proxy`: https://en.wikipedia.org/wiki/Proxy_pattern .. _`documentation of ProxyManager`: https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md -.. _`ocramius/proxy-manager`: https://github.com/Ocramius/ProxyManager .. _`final`: https://www.php.net/manual/en/language.oop5.final.php From c8a0a723ab2565d3d24ba32f18c850f3e102aa36 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 22 Dec 2020 17:06:46 +0100 Subject: [PATCH 0284/5766] Fixed doc syntax --- form/form_collections.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index 30215b0a37d..e7502432a16 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -51,8 +51,6 @@ Let's start by creating a ``Task`` entity:: Now, create a ``Tag`` class. As you saw above, a ``Task`` can have many ``Tag`` objects:: -.. code-block:: php - // src/Entity/Tag.php namespace App\Entity; From a490d10189aad87f89a7e18a0939451276143be1 Mon Sep 17 00:00:00 2001 From: Hugo Sales Date: Sun, 21 Jun 2020 15:49:19 +0000 Subject: [PATCH 0285/5766] Add documentation for pull #37371 --- translation/message_format.rst | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/translation/message_format.rst b/translation/message_format.rst index 81bc8320975..e744ab8f757 100644 --- a/translation/message_format.rst +++ b/translation/message_format.rst @@ -165,6 +165,21 @@ you to use literal text in the select statements: #. Inside this block, ``{organizer_name}`` starts "code" mode again, allowing ``organizer_name`` to be processed as variable. +Additionally, it's possible to write the message directly in code:: + + $invitation = '{organizer_gender, select, + female {{organizer_name} has invited you for her party!} + male {{organizer_name} has invited you for his party!} + other {{organizer_name} have invited you for their party!} + }'; + // prints "Ryan has invited you for his party!" + echo $translator->trans($invitation, [ + 'organizer_name' => 'Ryan', + 'organizer_gender' => 'male', + ]); + +This can be used to create a wrapper. + .. tip:: While it might seem more logical to only put ``her``, ``his`` or ``their`` From 064bb18c88def6b3d1eab4a771076c4d3fa12366 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 22 Dec 2020 17:21:14 +0100 Subject: [PATCH 0286/5766] Tweaks --- translation/message_format.rst | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/translation/message_format.rst b/translation/message_format.rst index e744ab8f757..0a0742e16d0 100644 --- a/translation/message_format.rst +++ b/translation/message_format.rst @@ -165,21 +165,6 @@ you to use literal text in the select statements: #. Inside this block, ``{organizer_name}`` starts "code" mode again, allowing ``organizer_name`` to be processed as variable. -Additionally, it's possible to write the message directly in code:: - - $invitation = '{organizer_gender, select, - female {{organizer_name} has invited you for her party!} - male {{organizer_name} has invited you for his party!} - other {{organizer_name} have invited you for their party!} - }'; - // prints "Ryan has invited you for his party!" - echo $translator->trans($invitation, [ - 'organizer_name' => 'Ryan', - 'organizer_gender' => 'male', - ]); - -This can be used to create a wrapper. - .. tip:: While it might seem more logical to only put ``her``, ``his`` or ``their`` @@ -188,6 +173,22 @@ This can be used to create a wrapper. readable for translators and, as you can see in the ``other`` case, other parts of the sentence might be influenced by the variables. +.. tip:: + + It's possible to translate ICU MessageFormat messages directly in code, + without having to define them in any file:: + + $invitation = '{organizer_gender, select, + female {{organizer_name} has invited you for her party!} + male {{organizer_name} has invited you for his party!} + other {{organizer_name} have invited you for their party!} + }'; + + // prints "Ryan has invited you for his party!" + echo $translator->trans($invitation, [ + 'organizer_name' => 'Ryan', + 'organizer_gender' => 'male', + ]); .. _component-translation-pluralization: From dc072c4d98b3d79494e9fcb12b4314b67bde4674 Mon Sep 17 00:00:00 2001 From: Pavel Nemchenko Date: Wed, 23 Dec 2020 00:03:08 +0200 Subject: [PATCH 0287/5766] [Service Container] Fix typo in tag default index method name --- 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 bf8f6959db4..6783ef06d4e 100644 --- a/service_container/tags.rst +++ b/service_container/tags.rst @@ -807,7 +807,7 @@ array element. For example, to retrieve the ``handler_two`` handler:: .. tip:: Just like the priority, you can also implement a static - ``getDefaultIndexAttributeName()`` method in the handlers and omit the + ``getDefaultIndexName()`` method in the handlers and omit the index attribute (``key``):: // src/Handler/One.php From c521f8e54355bce0baa93a66f20a9a3ff1b8edb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 23 Dec 2020 09:59:35 +0100 Subject: [PATCH 0288/5766] Remove experimental from notifier --- notifier.rst | 3 +-- notifier/chatters.rst | 3 +-- notifier/texters.rst | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/notifier.rst b/notifier.rst index 10a0a5490aa..c7c84eb5977 100644 --- a/notifier.rst +++ b/notifier.rst @@ -6,8 +6,7 @@ Creating and Sending Notifications .. versionadded:: 5.0 - The Notifier component was introduced in Symfony 5.0 as an - :doc:`experimental feature `. + The Notifier component was introduced in Symfony 5.0. Installation ------------ diff --git a/notifier/chatters.rst b/notifier/chatters.rst index da11c8858b9..ffeb6e0dc5e 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -6,8 +6,7 @@ How to send Chat Messages .. versionadded:: 5.0 - The Notifier component was introduced in Symfony 5.0 as an - :doc:`experimental feature `. + The Notifier component was introduced in Symfony 5.0. The :class:`Symfony\\Component\\Notifier\\ChatterInterface` class allows you to send messages to chat services like Slack or Telegram:: diff --git a/notifier/texters.rst b/notifier/texters.rst index eb663b13726..4cf9b6f2de2 100644 --- a/notifier/texters.rst +++ b/notifier/texters.rst @@ -6,8 +6,7 @@ How to send SMS Messages .. versionadded:: 5.0 - The Notifier component was introduced in Symfony 5.0 as an - :doc:`experimental feature `. + The Notifier component was introduced in Symfony 5.0. The :class:`Symfony\\Component\\Notifier\\TexterInterface` class allows you to send SMS messages:: From 275b6e97ba7edd5eff2d38230d5300270a1d9868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Wed, 23 Dec 2020 11:46:38 +0100 Subject: [PATCH 0289/5766] Restore version-added in string --- components/string.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/components/string.rst b/components/string.rst index 7d2ec49a198..83d73140095 100644 --- a/components/string.rst +++ b/components/string.rst @@ -8,6 +8,10 @@ The String Component The String component provides a single object-oriented API to work with three "unit systems" of strings: bytes, code points and grapheme clusters. +.. versionadded:: 5.0 + + The String component was introduced in Symfony 5.0. + Installation ------------ From eaaceec65766e176acd0dfcc58d445fa38c08bfc Mon Sep 17 00:00:00 2001 From: Victor Bocharsky Date: Wed, 23 Dec 2020 13:13:35 +0200 Subject: [PATCH 0290/5766] Minor: Remove extra space in the config example --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index fa19d77d849..86683f365c1 100644 --- a/mailer.rst +++ b/mailer.rst @@ -962,7 +962,7 @@ you have a transport called ``async``, you can route the message there: async: "%env(MESSENGER_TRANSPORT_DSN)%" routing: - 'Symfony\Component\Mailer\Messenger\SendEmailMessage': async + 'Symfony\Component\Mailer\Messenger\SendEmailMessage': async .. code-block:: xml From 78de6f66628019b7feaee639c69ef6d907745931 Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 23 Dec 2020 12:49:07 +0100 Subject: [PATCH 0291/5766] Minor: Fix quotes style(serializer): Fix quotes --- components/serializer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/serializer.rst b/components/serializer.rst index 20d31fa8c0c..5c498cbf593 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -627,7 +627,7 @@ defines a ``Person`` entity with a ``firstName`` property: This custom mapping is used to convert property names when serializing and deserializing objects:: - $serialized = $serializer->serialize(new Person("Kévin"), 'json'); + $serialized = $serializer->serialize(new Person('Kévin'), 'json'); // {"customer_name": "Kévin"} Serializing Boolean Attributes From b885099d7b7812fa134008cdb00b786da9d775e5 Mon Sep 17 00:00:00 2001 From: Alexander Dubovskoy Date: Wed, 23 Dec 2020 17:48:32 +0300 Subject: [PATCH 0292/5766] Update lockable_trait.rst Misprint has been fixed: added ":" --- console/lockable_trait.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/console/lockable_trait.rst b/console/lockable_trait.rst index 9c77073d087..54f6e4b051d 100644 --- a/console/lockable_trait.rst +++ b/console/lockable_trait.rst @@ -39,7 +39,7 @@ that adds two convenient methods to lock and release commands:: // automatically when the execution of the command ends $this->release(); - return Command:SUCCESS; + return Command::SUCCESS; } } From ccc128974d522b6708b512112e6efa31ef453755 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 27 Dec 2020 12:36:11 +0100 Subject: [PATCH 0293/5766] [FrameworkBundle][WebLink] Config reference for the WebLink component --- reference/configuration/framework.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index e61e0e1365d..cb128f73d02 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -272,6 +272,7 @@ Configuration * `strict_email`_ * `translation_domain`_ +* `web_link`_ * `workflows`_ * :ref:`enabled ` @@ -2994,6 +2995,17 @@ recipients set in the code. ]); }; + +web_link +~~~~~~~~ + +enabled +....... + +**type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation + +Adds a Link HTTP header to the response. + workflows ~~~~~~~~~ From 6a758a514621b4c7e2c42e9068ead0ba4448443c Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 27 Dec 2020 20:46:46 +0100 Subject: [PATCH 0294/5766] Remove white space --- configuration/using_parameters_in_dic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/using_parameters_in_dic.rst b/configuration/using_parameters_in_dic.rst index 730043af714..c81fcf7fa14 100644 --- a/configuration/using_parameters_in_dic.rst +++ b/configuration/using_parameters_in_dic.rst @@ -106,7 +106,7 @@ be injected with this parameter via the extension as follows:: { private $debug; - public function __construct($debug) + public function __construct($debug) { $this->debug = (bool) $debug; } From d922ed43b736892edb4be7c7bbd11ec5a30f1501 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 26 Dec 2020 11:48:48 +0100 Subject: [PATCH 0295/5766] [Process] add docs for ExecutableFinder --- components/process.rst | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/components/process.rst b/components/process.rst index 5b1ee2ca420..b7845145ca3 100644 --- a/components/process.rst +++ b/components/process.rst @@ -483,10 +483,32 @@ Use :method:`Symfony\\Component\\Process\\Process::disableOutput` and However, it is possible to pass a callback to the ``start``, ``run`` or ``mustRun`` methods to handle process output in a streaming fashion. + +Finding an Executable +--------------------- + +The Process component provides a utility class called +:class:`Symfony\\Component\\Process\\ExecutableFinder` which finds +and returns the absolute path of an executable:: + + use Symfony\Component\Process\ExecutableFinder; + + $executableFinder = new ExecutableFinder(); + $chromedriverPath = $executableFinder->find('chromedriver'); + // $chromedriverPath = '/usr/local/bin/chromedriver' (the result will be different on your computer) + +The :method:`Symfony\\Component\\Process\\ExecutableFinder::find` method also takes extra parameters to specify a default value +to return and extra directories where to look for the executable:: + + use Symfony\Component\Process\ExecutableFinder; + + $executableFinder = new ExecutableFinder(); + $chromedriverPath = $executableFinder->find('chromedriver', '/path/to/chromedriver', ['local-bin/']); + Finding the Executable PHP Binary --------------------------------- -This component also provides a utility class called +This component also provides a special utility class called :class:`Symfony\\Component\\Process\\PhpExecutableFinder` which returns the absolute path of the executable PHP binary available on your server:: From c2500f9ebff40287335a64e03abae42f434965a3 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 27 Dec 2020 12:10:45 +0100 Subject: [PATCH 0296/5766] [FrameworkBundle] Config reference for Secrets --- reference/configuration/framework.rst | 31 +++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index e61e0e1365d..4ca47e58768 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -197,6 +197,12 @@ Configuration * `utf8`_ * `secret`_ +* `secrets`_ + + * `decryption_env_var`_ + * `local_dotenv_file`_ + * `vault_directory`_ + * `serializer`_ * :ref:`circular_reference_handler ` @@ -2483,6 +2489,31 @@ 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 From 136b2aa1056b2a7b770fe9c804c24b55263a5252 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 28 Dec 2020 11:57:43 +0100 Subject: [PATCH 0297/5766] Added redirections to specific anchors for removed Templating articles --- _build/redirection_map | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/_build/redirection_map b/_build/redirection_map index 6c49dc6bed6..4954ce471fa 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -448,15 +448,15 @@ /reference/requirements /setup /bundles/inheritance /bundles/override /templating /templates -/templating/escaping /templates -/templating/syntax /templates -/templating/debug /templates -/templating/render_without_controller /templates -/templating/app_variable /templates +/templating/escaping /templates#output-escaping +/templating/syntax /templates#linting-twig-templates +/templating/debug /templates#the-dump-twig-utilities +/templating/render_without_controller /templates#rendering-a-template-directly-from-a-route +/templating/app_variable /templates#the-app-global-variable /templating/formats /templates -/templating/namespaced_paths /templates -/templating/embedding_controllers /templates -/templating/inheritance /templates +/templating/namespaced_paths /templates#template-namespaces +/templating/embedding_controllers /templates#embedding-controllers +/templating/inheritance /templates#template-inheritance-and-layouts /testing/doctrine /testing/database /doctrine/lifecycle_callbacks /doctrine/events /doctrine/event_listeners_subscribers /doctrine/events From 5570ab83867190d892679ad5e0c5f8d3b6396ba3 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 22 Dec 2020 23:34:14 +0100 Subject: [PATCH 0298/5766] [Session] Update incorrect default value for session.handler_id --- 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 e61e0e1365d..7a7fad45029 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1251,11 +1251,11 @@ alias will be set to this service id. This class has to implement handler_id .......... -**type**: ``string`` **default**: ``null`` +**type**: ``string`` **default**: ``'session.handler.native_file'`` -The service id used for session storage. The default ``null`` value means to use -the native PHP session mechanism. Set it to ``'session.handler.native_file'`` to -let Symfony manage the sessions itself using files to store the session metadata. +The service id 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. You can also :doc:`store sessions in a database `. .. _name: From f0344be19e7c0f18b36957fd19e3fed901df215a Mon Sep 17 00:00:00 2001 From: Rhodri Pugh Date: Thu, 24 Dec 2020 11:51:20 +0000 Subject: [PATCH 0299/5766] remove mention of master branch, no longer exists --- contributing/documentation/overview.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contributing/documentation/overview.rst b/contributing/documentation/overview.rst index f7d1e4e8a03..be7d3418c6e 100644 --- a/contributing/documentation/overview.rst +++ b/contributing/documentation/overview.rst @@ -121,7 +121,7 @@ branch of the ``upstream`` remote, which is the original Symfony Docs repository Fixes should always be based on the **oldest maintained branch** which contains the error. Nowadays this is the ``4.4`` branch. If you are instead documenting a new feature, switch to the first Symfony version that included it, e.g. -``upstream/3.1``. Not sure? That's OK! Just use the ``upstream/master`` branch. +``upstream/3.1``. **Step 5.** Now make your changes in the documentation. Add, tweak, reword and even remove any content and do your best to comply with the @@ -295,12 +295,12 @@ Please be patient. It can take up to several days before your pull request can be fully reviewed. After merging the changes, it could take again several hours before your changes appear on the Symfony website. -Why Should I Use the Oldest Maintained Branch Instead of the Master Branch? +Why Should I Use the Oldest Maintained Branch Instead of the Latest Branch? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Consistent with Symfony's source code, the documentation repository is split into multiple branches, corresponding to the different versions of Symfony itself. -The ``master`` branch holds the documentation for the development branch of +The latest (e.g. ``5.x``) branch holds the documentation for the development branch of the code. Unless you're documenting a feature that was introduced after Symfony 4.4, From c39447ab9ddd33dcd0a68b43eb65f70d23188f17 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Sun, 27 Dec 2020 11:30:56 +0100 Subject: [PATCH 0300/5766] [RateLimiter] Adding config reference for policy and lock_factory --- rate_limiter.rst | 2 ++ reference/configuration/framework.rst | 36 +++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/rate_limiter.rst b/rate_limiter.rst index 403aa9c462f..63e073a1e92 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -16,6 +16,8 @@ Symfony uses these rate limiters in built-in features like "login throttling", which limits how many failed login attempts a user can make in a given period of time, but you can use them for your own features too. +.. _rate-limiter-policies: + Rate Limiting Policies ---------------------- diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 4bc44ad1f17..cc00ae83c6f 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -211,6 +211,13 @@ Configuration * :ref:`enabled ` +* `rate_limiter`_: + + * :ref:`name ` + + * `lock_factory`_ + * `policy`_ + * `request`_: * `formats`_ @@ -1220,6 +1227,35 @@ dsn The DSN where to store the profiling information. +rate_limiter +~~~~~~~~~~~~ + +.. _reference-rate-limiter-name: + +name +.... + +**type**: ``prototype`` + +Name of the rate limiter you want to create. + +lock_factory +"""""""""""" + +**type**: ``string`` **default:** ``lock.factory`` + +The service that is used to create a lock. The service has to implement the +:class:`Symfony\\Component\\Lock\\LockFactoryInterface`. + +policy +"""""" + +**type**: ``string`` **required** + +The name of the rate limiting algorithm to use. Example names are ``fixed_window``, +``sliding_window`` and ``no_limit``. See :ref:`Rate Limiter Policies `) +for more information. + request ~~~~~~~ From 95d52ea6af091519b911a655db42bcc725ebe67c Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 28 Dec 2020 15:24:00 +0100 Subject: [PATCH 0301/5766] 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 a3bbbe2d7fa..8a126514b9b 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1250,8 +1250,8 @@ lock_factory **type**: ``string`` **default:** ``lock.factory`` -The service that is used to create a lock. The service has to implement the -:class:`Symfony\\Component\\Lock\\LockFactoryInterface`. +The service that is used to create a lock. The service has to be an instance of +the :class:`Symfony\\Component\\Lock\\LockFactory` class. policy """""" From d5990bec534699ceaaeb211f3a2b0d3704036793 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 28 Dec 2020 15:42:38 +0100 Subject: [PATCH 0302/5766] Added a link to the related RFC --- reference/configuration/framework.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index fb29e6c83d3..83b1cd90abb 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -3035,7 +3035,7 @@ enabled **type**: ``boolean`` **default**: ``true`` or ``false`` depending on your installation -Adds a Link HTTP header to the response. +Adds a `Link HTTP header`_ to the response. workflows ~~~~~~~~~ @@ -3210,3 +3210,4 @@ to know their differences. .. _`session.cache-limiter`: https://www.php.net/manual/en/session.configuration.php#ini.session.cache-limiter .. _`Microsoft NTLM authentication protocol`: https://docs.microsoft.com/en-us/windows/win32/secauthn/microsoft-ntlm .. _`utf-8 modifier`: https://www.php.net/reference.pcre.pattern.modifiers +.. _`Link HTTP header`: https://tools.ietf.org/html/rfc5988 From 3a7985f90472d45a282e82d8ce30de955f3dfa24 Mon Sep 17 00:00:00 2001 From: MrYamous Date: Mon, 28 Dec 2020 02:09:18 +0100 Subject: [PATCH 0303/5766] Update rounding mode defintion integer type --- reference/forms/types/integer.rst | 45 +++++++++++++++++++------------ 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index fa5660158bc..80a946a33fd 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -55,31 +55,42 @@ Field Options ``rounding_mode`` ~~~~~~~~~~~~~~~~~ -**type**: ``integer`` **default**: ``IntegerToLocalizedStringTransformer::ROUND_DOWN`` +**type**: ``integer`` **default**: ``\NumberFormatter::ROUND_HALFUP`` -By default, if the user enters a non-integer number, it will be rounded -down. There are several other rounding methods and each is a constant -on the :class:`Symfony\\Component\\Form\\Extension\\Core\\DataTransformer\\IntegerToLocalizedStringTransformer`: +By default, if the users enters a non-integer number, it will be rounded +down. You have several configurable options for that rounding. Each option +is a constant on the :phpclass:`NumberFormatter` class: -* ``IntegerToLocalizedStringTransformer::ROUND_DOWN`` Round towards zero. +* ``\NumberFormatter::ROUND_DOWN`` Round towards zero. It + rounds ``1.4`` to ``1`` and ``-1.4`` to ``-1``. -* ``IntegerToLocalizedStringTransformer::ROUND_FLOOR`` Round towards negative - infinity. +* ``\NumberFormatter::ROUND_FLOOR`` Round towards negative + infinity. It rounds ``1.4`` to ``1`` and ``-1.4`` to ``-2``. -* ``IntegerToLocalizedStringTransformer::ROUND_UP`` Round away from zero. +* ``\NumberFormatter::ROUND_UP`` Round away from zero. It + rounds ``1.4`` to ``2`` and ``-1.4`` to ``-2``. -* ``IntegerToLocalizedStringTransformer::ROUND_CEILING`` Round towards - positive infinity. +* ``\NumberFormatter::ROUND_CEILING`` Round towards positive + infinity. It rounds ``1.4`` to ``2`` and ``-1.4`` to ``-1``. -* ``IntegerToLocalizedStringTransformer::ROUND_HALF_DOWN`` Round towards the - "nearest neighbor". If both neighbors are equidistant, round down. +* ``\NumberFormatter::ROUND_HALFDOWN`` Round towards the + "nearest neighbor". If both neighbors are equidistant, round down. It rounds + ``2.5`` and ``1.6`` to ``2``, ``1.5`` and ``1.4`` to ``1``. -* ``IntegerToLocalizedStringTransformer::ROUND_HALF_EVEN`` Round towards the - "nearest neighbor". If both neighbors are equidistant, round towards the - even neighbor. +* ``\NumberFormatter::ROUND_HALFEVEN`` Round towards the + "nearest neighbor". If both neighbors are equidistant, round towards the even + neighbor. It rounds ``2.5``, ``1.6`` and ``1.5`` to ``2`` and ``1.4`` to ``1``. + +* ``\NumberFormatter::ROUND_HALFUP`` Round towards the + "nearest neighbor". If both neighbors are equidistant, round up. It rounds + ``2.5`` to ``3``, ``1.6`` and ``1.5`` to ``2`` and ``1.4`` to ``1``. + +.. deprecated:: 5.1 + + In Symfony versions prior to 5.1, these constants were also defined as aliases + in the :class:`Symfony\\Component\\Form\\Extension\\Core\\DataTransformer\\IntegerToLocalizedStringTransformer` + class, but they are now deprecated in favor of the :phpclass:`NumberFormatter` constants. -* ``IntegerToLocalizedStringTransformer::ROUND_HALF_UP`` Round towards the - "nearest neighbor". If both neighbors are equidistant, round up. Overridden Options ------------------ From 9436d6337ca5b5d62b86059c72fa3846597046a7 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 28 Dec 2020 15:56:15 +0100 Subject: [PATCH 0304/5766] Tweaks --- reference/forms/types/integer.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index 80a946a33fd..984aa45ed89 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -57,7 +57,7 @@ Field Options **type**: ``integer`` **default**: ``\NumberFormatter::ROUND_HALFUP`` -By default, if the users enters a non-integer number, it will be rounded +By default, if the user enters a non-integer number, it will be rounded down. You have several configurable options for that rounding. Each option is a constant on the :phpclass:`NumberFormatter` class: @@ -88,10 +88,9 @@ is a constant on the :phpclass:`NumberFormatter` class: .. deprecated:: 5.1 In Symfony versions prior to 5.1, these constants were also defined as aliases - in the :class:`Symfony\\Component\\Form\\Extension\\Core\\DataTransformer\\IntegerToLocalizedStringTransformer` + in the :class:`Symfony\\Component\\Form\\Extension\\Core\\DataTransformer\\NumberToLocalizedStringTransformer` class, but they are now deprecated in favor of the :phpclass:`NumberFormatter` constants. - Overridden Options ------------------ From 11e670134ae75a228f572279e85fb3f0842b0965 Mon Sep 17 00:00:00 2001 From: MrYamous Date: Tue, 29 Dec 2020 19:03:34 +0100 Subject: [PATCH 0305/5766] Add Firebase notifier to documentation --- notifier.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index c5e8181c22a..c5415b465a8 100644 --- a/notifier.rst +++ b/notifier.rst @@ -131,6 +131,7 @@ integration with these chat services: ========== ================================ ============================================ Service Package DSN ========== ================================ ============================================ +Firebase ``symfony/firebase-notifier`` ``firebase://USERNAME:PASSWORD@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` RocketChat ``symfony/rocket-chat-notifier`` ``rocketchat://TOKEN@ENDPOINT?channel=CHANNEL`` Slack ``symfony/slack-notifier`` ``slack://default/ID`` @@ -139,7 +140,7 @@ Telegram ``symfony/telegram-notifier`` ``telegram://TOKEN@default?channel .. versionadded:: 5.1 - The Mattermost and RocketChat integrations were introduced in Symfony + The Firebase, Mattermost and RocketChat integrations were introduced in Symfony 5.1. The Slack DSN changed in Symfony 5.1 to use Slack Incoming Webhooks instead of legacy tokens. From 88130c10135ecdb2b92a5f6a530b564dffe9b41e Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 30 Dec 2020 10:04:06 +0100 Subject: [PATCH 0306/5766] Use max_colons rule for DOCtor-RST --- .doctor-rst.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 59971c508f4..949ad80f3bf 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -14,6 +14,7 @@ rules: lowercase_as_in_use_statements: ~ max_blank_lines: max: 2 + max_colons: ~ no_app_console: ~ no_blank_line_after_filepath_in_php_code_block: ~ no_blank_line_after_filepath_in_twig_code_block: ~ From 44d5818f19872d4f7fd41640ebd2e39b82959ed9 Mon Sep 17 00:00:00 2001 From: Marco Date: Tue, 29 Dec 2020 20:10:35 +0100 Subject: [PATCH 0307/5766] Minor fix to colon Mostly not worth a PR but I wanted to change it either way. Changed the display output from `::` to `:` as it is in the rest of the document. --- routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing.rst b/routing.rst index 5fd4ad30225..86defd2bafc 100644 --- a/routing.rst +++ b/routing.rst @@ -1874,7 +1874,7 @@ use the ``generateUrl()`` helper:: If you pass to the ``generateUrl()`` method some parameters that are not part of the route definition, they are included in the generated URL as a - query string::: + query string:: $this->generateUrl('blog', ['page' => 2, 'category' => 'Symfony']); // the 'blog' route only defines the 'page' parameter; the generated URL is: From 6fa2894b27067ca623fbc345f6df04da9258e8bf Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Wed, 30 Dec 2020 10:19:59 +0100 Subject: [PATCH 0308/5766] Replace link to getConfiguration method In my opinion, the link should redirect to the class where we can preview the method that must be overridden. --- bundles/configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bundles/configuration.rst b/bundles/configuration.rst index 25f8d76e76f..40eaf331d4f 100644 --- a/bundles/configuration.rst +++ b/bundles/configuration.rst @@ -334,7 +334,7 @@ As long as your bundle's configuration is located in the standard location (``YourBundle\DependencyInjection\Configuration``) and does not have a constructor it will work automatically. If you have something different, your ``Extension`` class must override the -:method:`Extension::getConfiguration() ` +:method:`Extension::getConfiguration() ` method and return an instance of your ``Configuration``. Supporting XML From f06a712d602844862cb0be976b9f31f6294b599d Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 30 Dec 2020 14:27:00 +0100 Subject: [PATCH 0309/5766] Allow to configure trusted proxies and headers using config options --- deployment/proxies.rst | 126 +++++++++++++++++++------- reference/configuration/framework.rst | 23 ++++- 2 files changed, 113 insertions(+), 36 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index cae9e285648..15725b67007 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -22,28 +22,69 @@ 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:: - - // public/index.php - - // ... - $request = Request::createFromGlobals(); - - // tell Symfony about your reverse proxy - Request::setTrustedProxies( - // the IP address (or range) of your proxy - ['192.0.0.1', '10.0.0.0/8'], - - // trust *all* "X-Forwarded-*" headers - Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO - - // or, if your proxy instead uses the "Forwarded" header - // Request::HEADER_FORWARDED - - // or, if you're using a well-known proxy - // Request::HEADER_X_FORWARDED_AWS_ELB - // Request::HEADER_X_FORWARDED_TRAEFIK - ); +and what headers your reverse proxy uses to send information: + +.. configuration-block:: + + .. config-block:: yaml + + # config/packages/framework.yaml + framework: + # ... + // the IP address (or range) of your proxy + trusted_proxies: '192.0.0.1,10.0.0.0/8' + // trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers) + trusted_headers: ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'] + // or, if your proxy instead uses the "Forwarded" header + trusted_headers: ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix'] + // or, if you're using a wellknown proxy + trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'] + trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix'] + + .. config-block:: xml + + + + + + + + 192.0.0.1,10.0.0.0/8 + + + x-forwarded-all + !x-forwarded-host + !x-forwarded-prefix + + + forwarded + !x-forwarded-host + !x-forwarded-prefix + + + + .. config-block:: php + + // config/packages/framework.php + use Symfony\Component\HttpFoundation\Request; + + $container->loadFromExtension('framework', [ + // the IP address (or range) of your proxy + 'trusted_proxies' => '192.0.0.1,10.0.0.0/8', + // trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers) + 'trusted_headers' => ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'], + // or, if your proxy instead uses the "Forwarded" header + 'trusted_headers' => ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix'], + // or, if you're using a wellknown proxy + 'trusted_headers' => [Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'], + 'trusted_headers' => [Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix'], + ]); .. deprecated:: 5.2 @@ -61,6 +102,13 @@ The Request object has several ``Request::HEADER_*`` constants that control exac *which* headers from your reverse proxy are trusted. The argument is a bit field, so you can also pass your own value (e.g. ``0b00110``). +.. versionadded:: 5.2 + + The feature to configure trusted proxies and headers with ``trusted_proxies`` + and ``trusted_headers`` options was introduced in Symfony 5.2. In earlier + Symfony versions you needed to use the ``Request::setTrustedProxies()`` + method in the ``public/index.php`` file. + But what if the IP of my Reverse Proxy Changes Constantly! ---------------------------------------------------------- @@ -74,17 +122,17 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. #. Once you've guaranteed that traffic will only come from your trusted reverse proxies, configure Symfony to *always* trust incoming request:: - // public/index.php + .. config-block:: yaml - // ... - Request::setTrustedProxies( - // trust *all* requests (the 'REMOTE_ADDR' string is replaced at - // run time by $_SERVER['REMOTE_ADDR']) - ['127.0.0.1', 'REMOTE_ADDR'], + # config/packages/framework.yaml + framework: + # ... + // trust *all* requests (the 'REMOTE_ADDR' string is replaced at + // run time by $_SERVER['REMOTE_ADDR']) + trusted_proxies: '127.0.0.1,REMOTE_ADDR' - // if you're using ELB, otherwise use a constant from above - Request::HEADER_X_FORWARDED_AWS_ELB - ); + // if you're using ELB, otherwise use another Request::HEADER-* constant + trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'] 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 @@ -100,6 +148,12 @@ other information. # .env TRUSTED_PROXIES=127.0.0.1,REMOTE_ADDR + .. config-block:: yaml + + # config/packages/framework.yaml + framework: + # ... + trusted_proxies: '%env(TRUSTED_PROXIES)%' If you are also using a reverse proxy on top of your load balancer (e.g. `CloudFront`_), calling ``$request->server->get('REMOTE_ADDR')`` won't be @@ -111,11 +165,13 @@ trusted proxies. Custom Headers When Using a Reverse Proxy ----------------------------------------- -Some reverse proxies (like `CloudFront`_ with ``CloudFront-Forwarded-Proto``) may force you to use a custom header. -For instance you have ``Custom-Forwarded-Proto`` instead of ``X-Forwarded-Proto``. +Some reverse proxies (like `CloudFront`_ with ``CloudFront-Forwarded-Proto``) +may force you to use a custom header. For instance you have +``Custom-Forwarded-Proto`` instead of ``X-Forwarded-Proto``. -In this case, you'll need to set the header ``X-Forwarded-Proto`` with the value of -``Custom-Forwarded-Proto`` early enough in your application, i.e. before handling the request:: +In this case, you'll need to set the header ``X-Forwarded-Proto`` with the value +of ``Custom-Forwarded-Proto`` early enough in your application, i.e. before +handling the request:: // public/index.php diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index df964b6d0ba..3a26887300e 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -284,6 +284,7 @@ Configuration * `logging`_ * :ref:`paths ` +* `trusted_headers`_ * `trusted_hosts`_ * `trusted_proxies`_ * `validation`_ @@ -380,12 +381,32 @@ named ``kernel.http_method_override``. $request = Request::createFromGlobals(); // ... +.. _reference-framework-trusted-headers: + +trusted_headers +~~~~~~~~~~~~~~~ + +.. versionadded:: 5.2 + + The ``trusted_headers`` option was introduced in Symfony 5.2. + +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`. + .. _reference-framework-trusted-proxies: trusted_proxies ~~~~~~~~~~~~~~~ -The ``trusted_proxies`` option was removed in Symfony 3.3. See :doc:`/deployment/proxies`. +.. versionadded:: 5.2 + + The ``trusted_headers`` option was reintroduced in Symfony 5.2 (it had been + removed in Symfony 3.3). + +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`. ide ~~~ From 853dfb082a0dadb9ee50625eb4b2350de92f1ec2 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 30 Dec 2020 14:35:32 +0100 Subject: [PATCH 0310/5766] Shortening the text and adding link to jQuery As a separate PR, as recommended by https://github.com/symfony/symfony-docs/pull/13450#issuecomment-722413038 --- form/form_collections.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index e7502432a16..9e74e0d2895 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -280,9 +280,8 @@ On the rendered page, the result will look something like this: the ``data-prototype`` attribute is automatically added to the containing ``div``, and you need to adjust the following JavaScript accordingly. -The goal of this section will be to use JavaScript to read this attribute -and dynamically add new tag forms when the user clicks the "Add a tag" button. -This example uses jQuery and assumes you have it included somewhere on your page. +Now we need some JavaScript to read this attribute and dynamically add new tag forms +when the user clicks an "Add a tag" link. This example uses `jQuery`_. Add a ``script`` tag somewhere on your page so you can start writing some JavaScript. In this script, bind to the "click" event of the "Add a tag" @@ -684,6 +683,7 @@ the relationship between the removed ``Tag`` and ``Task`` object. the `symfony-collection`_ package based on jQuery for the rest of browsers. .. _`Owning Side and Inverse Side`: https://www.doctrine-project.org/projects/doctrine-orm/en/current/reference/unitofwork-associations.html +.. _`jQuery`: http://jquery.com/ .. _`JSFiddle`: http://jsfiddle.net/847Kf/4/ .. _`@a2lix/symfony-collection`: https://github.com/a2lix/symfony-collection .. _`symfony-collection`: https://github.com/ninsuo/symfony-collection From dc794b9947f9a6139aee08a564e1d14429fa9ae3 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 30 Dec 2020 15:03:42 +0100 Subject: [PATCH 0311/5766] Shortening the text some more As a separate PR, as recommended by https://github.com/symfony/symfony-docs/pull/13450#issuecomment-722413038 * Reason for deleting "Add a script tag somewhere on your page...": Lenghthy text that didn't say much ;-) * Reason for deleting the `note`: The JavaScript code is shown in itself; not inside some HTML ;-) * --- form/form_collections.rst | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index e7502432a16..89c27960adf 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -245,7 +245,7 @@ the following ``data-prototype`` attribute to the existing ``
            `` in your temp
              -Now add a button just next to the ``
                `` to dynamically add a new tag +Now add a button just next to the ``
                  `` to dynamically add a new tag: .. code-block:: html+twig @@ -284,9 +284,7 @@ The goal of this section will be to use JavaScript to read this attribute and dynamically add new tag forms when the user clicks the "Add a tag" button. This example uses jQuery and assumes you have it included somewhere on your page. -Add a ``script`` tag somewhere on your page so you can start writing some -JavaScript. In this script, bind to the "click" event of the "Add a tag" -button so you can add a new tag form (``addFormToCollection()`` will be show next): +Now add the required functionality with JavaScript: .. code-block:: javascript @@ -344,11 +342,6 @@ one example: $collectionHolder.append($newFormLi) } -.. note:: - - It is better to separate your JavaScript in real JavaScript files than - to write it inside the HTML as is done here. - Now, each time a user clicks the ``Add a tag`` link, a new sub form will appear on the page. When the form is submitted, any new tag forms will be converted into new ``Tag`` objects and added to the ``tags`` property of the ``Task`` object. From d015c96640903093ae003b4a368c950d3b919cb0 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 30 Dec 2020 15:13:50 +0100 Subject: [PATCH 0312/5766] Rewording As a separate PR, as recommended by https://github.com/symfony/symfony-docs/pull/13450#issuecomment-722413038 Note: `addTagForm` was the wrong function name, it's now called `addFormToCollection()` --- form/form_collections.rst | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index e7502432a16..0812c2dac93 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -304,14 +304,10 @@ button so you can add a new tag form (``addFormToCollection()`` will be show nex }) }); -The ``addTagForm()`` function's job will be to use the ``data-prototype`` attribute -to dynamically add a new form when this link is clicked. The ``data-prototype`` -HTML contains the tag ``text`` input element with a name of ``task[tags][__name__][name]`` -and id of ``task_tags___name___name``. The ``__name__`` is a little "placeholder", -which you'll replace with a unique, incrementing number (e.g. ``task[tags][3][name]``). - -The actual code needed to make this all work can vary quite a bit, but here's -one example: +The ``data-prototype`` HTML contains the tag's ``text`` input element with a name of +``task[tags][__name__][name]`` and id of ``task_tags___name___name``. The ``__name__`` +part is a "placeholder", which is replaced by a unique, incrementing number +(e.g. ``task[tags][3][name]``). .. code-block:: javascript From 0bd38f6ba51e04e1a67eed30d6221206d8a37c43 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 30 Dec 2020 15:17:12 +0100 Subject: [PATCH 0313/5766] Fixing function name --- form/form_collections.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index e7502432a16..cceffb6b6b1 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -572,7 +572,7 @@ First, add a "delete this tag" link to each tag form: // ... the rest of the block from above }); - function addTagForm() { + function addFormToCollection() { // ... // add a delete link to the new form From ec51ca97c3540f7c3351451f7c63baea546404a2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 30 Dec 2020 16:26:15 +0100 Subject: [PATCH 0314/5766] Rewords and reverts --- form/form_collections.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index 9e74e0d2895..9be2b6fa6c2 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -280,8 +280,10 @@ On the rendered page, the result will look something like this: the ``data-prototype`` attribute is automatically added to the containing ``div``, and you need to adjust the following JavaScript accordingly. -Now we need some JavaScript to read this attribute and dynamically add new tag forms -when the user clicks an "Add a tag" link. This example uses `jQuery`_. +The goal of this section will be to use JavaScript to read this attribute +and dynamically add new tag forms when the user clicks the "Add a tag" link. +This example uses `jQuery`_ and assumes you have it included somewhere on your +page (e.g. using Symfony's :doc:`Webpack Encore `). Add a ``script`` tag somewhere on your page so you can start writing some JavaScript. In this script, bind to the "click" event of the "Add a tag" From 033f36473fb6b69e019c60e380a40631e86ab50f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 30 Dec 2020 16:32:29 +0100 Subject: [PATCH 0315/5766] Minor tweak --- form/form_collections.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/form/form_collections.rst b/form/form_collections.rst index c3a78e93ac0..b60e5efc47f 100644 --- a/form/form_collections.rst +++ b/form/form_collections.rst @@ -285,7 +285,8 @@ and dynamically add new tag forms when the user clicks the "Add a tag" link. This example uses `jQuery`_ and assumes you have it included somewhere on your page (e.g. using Symfony's :doc:`Webpack Encore `). -Now add the required functionality with JavaScript: +Add a `` + + See note below about the "defer" attribute --> {% endblock %} - + + + .. _encore-entrypointsjson-simple-description: @@ -135,11 +135,14 @@ If you're *not* using Symfony, you can ignore the ``entrypoints.json`` file and point to the final, built file directly. ``entrypoints.json`` is only required for some optional features. -.. versionadded:: 0.21.0 +.. versionadded:: 1.9.0 - The ``encore_entry_link_tags()`` comes from WebpackEncoreBundle and relies - on a feature in Encore that was first introduced in version 0.21.0. Previously, - the ``asset()`` function was used to point directly to the file. + The ``defer`` attribute on the ``script`` tags delays the execution of the + JavaScript until the page loads (similar to putting the ``script`` at the + bottom of the page). The ability to always add this attribute was introduced + in WebpackEncoreBundle 1.9.0 and is automatically enabled in that bundle's + recipe in the ``config/packages/webpack_encore.yaml`` file. See + `WebpackEncoreBundle Configuration`_ for more details. Requiring JavaScript Modules ---------------------------- @@ -355,3 +358,4 @@ Encore supports many more features! For a full list of what you can do, see .. _`Encore's index.js file`: https://github.com/symfony/webpack-encore/blob/master/index.js .. _`ECMAScript 6 modules`: https://hacks.mozilla.org/2015/08/es6-in-depth-modules/ +.. _`WebpackEncoreBundle Configuration`: https://github.com/symfony/webpack-encore-bundle#configuration diff --git a/introduction/from_flat_php_to_symfony.rst b/introduction/from_flat_php_to_symfony.rst index 40a421f85dd..bae9ee9a8dc 100644 --- a/introduction/from_flat_php_to_symfony.rst +++ b/introduction/from_flat_php_to_symfony.rst @@ -609,10 +609,10 @@ The ``layout.php`` file is nearly identical: {% block title %}Welcome!{% endblock %} {% block stylesheets %}{% endblock %} + {% block javascripts %}{% endblock %} {% block body %}{% endblock %} - {% block javascripts %}{% endblock %} From 2755910b95f049af2339920d5f84581b5ea23dc5 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Fri, 15 Jan 2021 21:14:17 +0100 Subject: [PATCH 0389/5766] [Lock] Use .inner instead of decorating_service_id + '.inner' --- lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lock.rst b/lock.rst index a8334a12fa8..728eb85b659 100644 --- a/lock.rst +++ b/lock.rst @@ -293,4 +293,4 @@ you can do it by :doc:`decorating the store Date: Tue, 8 Dec 2020 17:11:20 +0100 Subject: [PATCH 0390/5766] [Notifier] Add Mercure notifier documentation --- notifier.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/notifier.rst b/notifier.rst index da02d2a585d..73bdf4d86ed 100644 --- a/notifier.rst +++ b/notifier.rst @@ -153,6 +153,7 @@ Firebase ``symfony/firebase-notifier`` ``firebase://USERNAME:PASSWORD@def GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY`` LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` +Mercure ``symfony/mercure-notifier`` ``mercure://PUBLISHER_SERVICE_ID?topic=TOPIC`` 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`` @@ -170,6 +171,10 @@ Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel The GoogleChat, LinkedIn, Zulip and Discord integrations were introduced in Symfony 5.2. The Slack DSN changed in Symfony 5.2 to use Slack Web API again same as in 5.0. +.. versionadded:: 5.3 + + The Mercure integration was introduced in Symfony 5.3. + Chatters are configured using the ``chatter_transports`` setting: .. code-block:: bash From 9df0164ebdc1d62d200142b26126a19d2188b466 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 17 Jan 2021 09:45:42 +0100 Subject: [PATCH 0391/5766] deprecate the NamespacedAttributeBag class --- components/http_foundation/sessions.rst | 10 ++++++++++ session.rst | 5 +++++ 2 files changed, 15 insertions(+) diff --git a/components/http_foundation/sessions.rst b/components/http_foundation/sessions.rst index 9c9479e3e5e..5756a38fc58 100644 --- a/components/http_foundation/sessions.rst +++ b/components/http_foundation/sessions.rst @@ -169,6 +169,11 @@ and "Remember Me" login settings or other user based state information. :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag` This implementation allows for attributes to be stored in a structured namespace. + .. deprecated:: 5.3 + + The ``NamespacedAttributeBag`` class is deprecated since Symfony 5.3. + If you need this feature, you will have to implement the class yourself. + :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface` has the API @@ -237,6 +242,11 @@ So any processing of this might quickly get ugly, even adding a token to the arr $tokens['c'] = $value; $session->set('tokens', $tokens); +.. deprecated:: 5.3 + + The ``NamespacedAttributeBag`` class is deprecated since Symfony 5.3. + If you need this feature, you will have to implement the class yourself. + With structured namespacing, the key can be translated to the array structure like this using a namespace character (which defaults to ``/``):: diff --git a/session.rst b/session.rst index 47e8cc3d269..394cfece78b 100644 --- a/session.rst +++ b/session.rst @@ -167,6 +167,11 @@ By default, session attributes are key-value pairs managed with the :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBag` class. +.. deprecated:: 5.3 + + The ``NamespacedAttributeBag`` class is deprecated since Symfony 5.3. + If you need this feature, you will have to implement the class yourself. + If your application needs are complex, you may prefer to use :ref:`namespaced session attributes ` which are managed with the :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag` From 5dba6e69b3ee57a6bb3375b4ee304688269d6c4f Mon Sep 17 00:00:00 2001 From: Al-Saleh KEITA <28827545+askeita@users.noreply.github.com> Date: Fri, 15 Jan 2021 22:40:21 +0100 Subject: [PATCH 0392/5766] Update testing.rst Replaced "an" by "a" (line 66) --- testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index c3dd66c7f9c..130ed0ab2ae 100644 --- a/testing.rst +++ b/testing.rst @@ -63,7 +63,7 @@ If you want to test an entire feature of your application (e.g. registering as a user or generating an invoice), see the section about :ref:`Functional Tests `. Writing Symfony unit tests is no different from writing standard PHPUnit -unit tests. Suppose, for example, that you have an class called ``Calculator`` +unit tests. Suppose, for example, that you have a class called ``Calculator`` in the ``src/Util/`` directory of the app:: // src/Util/Calculator.php From bd610d3ac0f42d8a0255d86cc5bc2b2a70a7f092 Mon Sep 17 00:00:00 2001 From: Johnny Peck Date: Fri, 15 Jan 2021 21:49:53 -0500 Subject: [PATCH 0393/5766] Update lock.rst Small grammar change. --- components/lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lock.rst b/components/lock.rst index 55ddcf377b3..7b2c131947d 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -158,7 +158,7 @@ method, the resource will stay locked until the timeout:: .. tip:: - To avoid letting the lock in a locking state, it's recommended to wrap the + To avoid leaving the lock in a locked state, it's recommended to wrap the job in a try/catch/finally block to always try to release the expiring lock. In case of long-running tasks, it's better to start with a not too long TTL and From b11628ac41a4119918b51b38f6c8572704967507 Mon Sep 17 00:00:00 2001 From: Miky Mikolaj Date: Sun, 17 Jan 2021 17:34:39 +0100 Subject: [PATCH 0394/5766] getId(): ?Uuid missing // need test getId: ?Ulid I added all code as in example, but i had still issue with api-platform that getId() field is wrong defined... I have no experience with ULID !!! Please test my solution for This solved my issue.. and now i am able create, update or delete record without any other issues. I think that this will save lot of time for new users... because fist i thinked that must be public function getId(): ?UuidV4Generator { return $this->id; } but with this my code was still broken... now i know that there must be if you change primary identifier from Int to Uuid use Symfony\Component\Uid\Uuid; public function getId(): ?Uuid { return $this->id; } .... also i think need to done the section of Uuid and Ulid for private $someProperty; getter and setter --- components/uid.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/components/uid.rst b/components/uid.rst index bdeb252bb65..a7fb95d5d2f 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -141,6 +141,7 @@ entity primary keys:: // there are generators for UUID V1 and V6 too use Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator; + use Symfony\Component\Uid\Uuid; /** * @ORM\Entity(repositoryClass="App\Repository\ProductRepository") @@ -156,6 +157,13 @@ entity primary keys:: private $id; // ... + + public function getId(): ?Uuid + { + return $this->id; + } + + // ... } .. versionadded:: 5.2 @@ -279,6 +287,7 @@ There's also a Doctrine generator to help autogenerate ULID values for the entity primary keys:: use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; + use Symfony\Component\Uid\Ulid; /** * @ORM\Entity(repositoryClass="App\Repository\ProductRepository") @@ -294,6 +303,14 @@ entity primary keys:: private $id; // ... + + public function getId(): ?Ulid + { + return $this->id; + } + + // ... + } .. versionadded:: 5.2 From b9fe645c2f413143b434d8169b74a518e7b70c40 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Mon, 18 Jan 2021 10:05:15 +0100 Subject: [PATCH 0395/5766] expand code example to clarify usage of the UserRepository --- security/experimental_authenticators.rst | 32 +++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index c84f36ed51d..eb0ffa098e0 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -457,13 +457,33 @@ using :ref:`the user provider `:: and must return a ``UserInterface`` object (otherwise a ``UsernameNotFoundException`` is thrown):: + // src/Security/CustomAuthenticator.php + namespace App\Security; + + use App\Repository\UserRepository; // ... - $passport = new Passport( - new UserBadge($email, function ($userIdentifier) { - return $this->userRepository->findOneBy(['email' => $userIdentifier]); - }), - $credentials - ); + + class CustomAuthenticator extends AbstractAuthenticator + { + private $userRepository; + + public function __construct(UserRepository $userRepository) + { + $this->userRepository = $userRepository; + } + + public function authenticate(Request $request): PassportInterface + { + // ... + + return new Passport( + new UserBadge($email, function ($userIdentifier) { + return $this->userRepository->findOneBy(['email' => $userIdentifier]); + }), + $credentials + ); + } + } The following credential classes are supported by default: From d75a175462ff9f8ac8ee411d66ff59d7ad6e6690 Mon Sep 17 00:00:00 2001 From: Boris Sondagh Date: Mon, 18 Jan 2021 15:27:48 +0100 Subject: [PATCH 0396/5766] Update best_practices.rst --- bundles/best_practices.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index 696c9da58ff..80e13b8b10b 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -25,6 +25,7 @@ namespace short name, which must end with ``Bundle``. A namespace becomes a bundle as soon as you add a bundle class to it. The bundle class name must follow these rules: +* Extend Symfony\Component\HttpKernel\Bundle\Bundle * Use only alphanumeric characters and underscores; * Use a StudlyCaps name (i.e. camelCase with an uppercase first letter); * Use a descriptive and short name (no more than two words); @@ -41,9 +42,6 @@ Namespace Bundle Class Name ``Acme\BlogBundle`` AcmeBlogBundle ========================== ================== -By convention, the ``getName()`` method of the bundle class should return the -class name. - .. note:: If you share your bundle publicly, you must use the bundle class name as From 08a07c917f672bcf17f5e4bbfe070a7100ceacc6 Mon Sep 17 00:00:00 2001 From: YaFou <33806646+YaFou@users.noreply.github.com> Date: Mon, 18 Jan 2021 19:33:41 +0100 Subject: [PATCH 0397/5766] [Security] Clarify the DeauthenticatedEvent --- components/security/authentication.rst | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/components/security/authentication.rst b/components/security/authentication.rst index 4cb87975e08..1f75b433c6c 100644 --- a/components/security/authentication.rst +++ b/components/security/authentication.rst @@ -276,15 +276,15 @@ Authentication Events The security component provides the following authentication events: -=============================== ================================================================= ============================================================================== -Name Event Constant Argument Passed to the Listener -=============================== ================================================================= ============================================================================== -security.authentication.success ``AuthenticationEvents::AUTHENTICATION_SUCCESS`` :class:`Symfony\\Component\\Security\\Core\\Event\\AuthenticationSuccessEvent` -security.authentication.failure ``AuthenticationEvents::AUTHENTICATION_FAILURE`` :class:`Symfony\\Component\\Security\\Core\\Event\\AuthenticationFailureEvent` -security.interactive_login ``SecurityEvents::INTERACTIVE_LOGIN`` :class:`Symfony\\Component\\Security\\Http\\Event\\InteractiveLoginEvent` -security.switch_user ``SecurityEvents::SWITCH_USER`` :class:`Symfony\\Component\\Security\\Http\\Event\\SwitchUserEvent` -security.logout_on_change ``Symfony\Component\Security\Http\Event\DeauthenticatedEvent`` :class:`Symfony\\Component\\Security\\Http\\Event\\DeauthenticatedEvent` -=============================== ================================================================= ============================================================================== +=============================== ======================================================================== ============================================================================== +Name Event Constant Argument Passed to the Listener +=============================== ======================================================================== ============================================================================== +security.authentication.success ``AuthenticationEvents::AUTHENTICATION_SUCCESS`` :class:`Symfony\\Component\\Security\\Core\\Event\\AuthenticationSuccessEvent` +security.authentication.failure ``AuthenticationEvents::AUTHENTICATION_FAILURE`` :class:`Symfony\\Component\\Security\\Core\\Event\\AuthenticationFailureEvent` +security.interactive_login ``SecurityEvents::INTERACTIVE_LOGIN`` :class:`Symfony\\Component\\Security\\Http\\Event\\InteractiveLoginEvent` +security.switch_user ``SecurityEvents::SWITCH_USER`` :class:`Symfony\\Component\\Security\\Http\\Event\\SwitchUserEvent` +security.logout_on_change ``Symfony\Component\Security\Http\Event\DeauthenticatedEvent::class`` :class:`Symfony\\Component\\Security\\Http\\Event\\DeauthenticatedEvent` +=============================== ======================================================================== ============================================================================== Authentication Success and Failure Events ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -317,7 +317,7 @@ The ``security.switch_user`` event is triggered every time you activate the ``switch_user`` firewall listener. The ``Symfony\Component\Security\Http\Event\DeauthenticatedEvent`` event is triggered when a token has been deauthenticated -because of a user change, it can help you doing some clean-up task when a logout has been triggered. +because of a user change, it can help you doing some clean-up task. .. versionadded:: 4.3 From 7c0db224906e62a43283971d6eac064588159623 Mon Sep 17 00:00:00 2001 From: Christopher Date: Tue, 19 Jan 2021 11:12:38 +0000 Subject: [PATCH 0398/5766] Added missing Dotenv use --- migration.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/migration.rst b/migration.rst index 6b71a07670b..ec42dfd4a33 100644 --- a/migration.rst +++ b/migration.rst @@ -239,6 +239,7 @@ could look something like this:: use App\Kernel; use App\LegacyBridge; use Symfony\Component\Debug\Debug; + use Symfony\Component\Dotenv\Dotenv; use Symfony\Component\HttpFoundation\Request; require dirname(__DIR__).'/vendor/autoload.php'; From b2be224760b653cfb0aa6f7e0d45e62c27ee0b2f Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 19 Jan 2021 09:08:55 +0100 Subject: [PATCH 0399/5766] Use Sf4 + Sf5 instead of Sf3 for bundle best practices --- bundles/best_practices.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index 696c9da58ff..c9dab120c53 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -181,15 +181,15 @@ A bundle should at least test: * All supported major Symfony versions (e.g. both ``4.x`` and ``5.x`` if support is claimed for both). -Thus, a bundle supporting PHP 7.3, 7.4 and 8.0, and Symfony 3.4 and 4.x should +Thus, a bundle supporting PHP 7.3, 7.4 and 8.0, and Symfony 4.4 and 5.x should have at least this test matrix: =========== =============== =================== PHP version Symfony version Composer flags =========== =============== =================== -7.3 ``3.*`` ``--prefer-lowest`` -7.4 ``4.*`` -8.0 ``4.*`` +7.3 ``4.*`` ``--prefer-lowest`` +7.4 ``5.*`` +8.0 ``5.*`` =========== =============== =================== .. tip:: From 00db43a4f034ff0f8412953fc4766a01e8fba791 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Tue, 19 Jan 2021 23:16:46 +0100 Subject: [PATCH 0400/5766] Just moving this note upwards MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reasons: * It's a *general* thing, has nothing to do with "Handlers that Modify Log Entries". * Since this is uncommon in Symfony, it should be explained as early as possible. * Fits quite well after this sentence: > This defines a stack of handlers and each handler is called in the order that it’s defined. --- logging.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/logging.rst b/logging.rst index 0b3481a738f..d4ed95189ba 100644 --- a/logging.rst +++ b/logging.rst @@ -159,6 +159,13 @@ to write logs using the :phpfunction:`syslog` function: This defines a *stack* of handlers and each handler is called in the order that it's defined. +.. note:: + + If you want to override the ``monolog`` configuration via another config + file, you will need to redefine the entire ``handlers`` stack. The configuration + from the two files cannot be merged because the order matters and a merge does + not allow to control the order. + Handlers that Modify Log Entries ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,13 +270,6 @@ debugging much easier! The handler named "file_log" will not be included in the stack itself as it is used as a nested handler of the ``fingers_crossed`` handler. -.. note:: - - If you want to override the ``monolog`` configuration via another config - file, you will need to redefine the entire ``handlers`` stack. The configuration - from the two files cannot be merged because the order matters and a merge does - not allow to control the order. - All Built-in Handlers --------------------- From 26e88f7da3322a594b9eccbdce021bb6cf6fd4d4 Mon Sep 17 00:00:00 2001 From: Christin Gruber Date: Wed, 20 Jan 2021 17:26:23 +0100 Subject: [PATCH 0401/5766] Add symfony/gitter-notifier docs --- notifier.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 73bdf4d86ed..a2072e79c13 100644 --- a/notifier.rst +++ b/notifier.rst @@ -150,6 +150,7 @@ Service Package DSN ========== ================================ =========================================================================== Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` Firebase ``symfony/firebase-notifier`` ``firebase://USERNAME:PASSWORD@default`` +Gitter ``symfony/gitter-notifier`` ``GITTER_DSN=gitter://TOKEN@default?room_id=ROOM_ID`` GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY`` LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` @@ -173,7 +174,7 @@ Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel .. versionadded:: 5.3 - The Mercure integration was introduced in Symfony 5.3. + The Gitter and Mercure integrations were introduced in Symfony 5.3. Chatters are configured using the ``chatter_transports`` setting: From 748bd54c675fbe0aeb6c01f385c5e68d002d1157 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 14 Nov 2020 15:37:16 +0100 Subject: [PATCH 0402/5766] [Validator] Document constraints as php 8 Attributes --- reference/constraints/Bic.rst | 13 +++ reference/constraints/Blank.rst | 13 +++ reference/constraints/Callback.rst | 30 +++++++ reference/constraints/CardScheme.rst | 16 ++++ reference/constraints/Choice.rst | 45 ++++++++++ reference/constraints/Count.rst | 18 ++++ reference/constraints/Country.rst | 13 +++ reference/constraints/Currency.rst | 13 +++ reference/constraints/Date.rst | 13 +++ reference/constraints/DateTime.rst | 16 ++++ reference/constraints/DivisibleBy.rst | 18 ++++ reference/constraints/Email.rst | 15 ++++ reference/constraints/EqualTo.rst | 18 ++++ reference/constraints/Expression.rst | 54 ++++++++++++ .../constraints/ExpressionLanguageSyntax.rst | 18 ++++ reference/constraints/File.rst | 17 ++++ reference/constraints/GreaterThan.rst | 57 +++++++++++++ reference/constraints/GreaterThanOrEqual.rst | 57 +++++++++++++ reference/constraints/Hostname.rst | 13 +++ reference/constraints/Iban.rst | 15 ++++ reference/constraints/IdenticalTo.rst | 18 ++++ reference/constraints/Image.rst | 34 ++++++++ reference/constraints/Ip.rst | 13 +++ reference/constraints/IsFalse.rst | 18 ++++ reference/constraints/IsNull.rst | 13 +++ reference/constraints/IsTrue.rst | 18 ++++ reference/constraints/Isbn.rst | 16 ++++ reference/constraints/Isin.rst | 13 +++ reference/constraints/Issn.rst | 13 +++ reference/constraints/Json.rst | 15 ++++ reference/constraints/Language.rst | 13 +++ reference/constraints/Length.rst | 19 +++++ reference/constraints/LessThan.rst | 57 +++++++++++++ reference/constraints/LessThanOrEqual.rst | 57 +++++++++++++ reference/constraints/Locale.rst | 15 ++++ reference/constraints/Luhn.rst | 13 +++ reference/constraints/Negative.rst | 13 +++ reference/constraints/NegativeOrZero.rst | 13 +++ reference/constraints/NotBlank.rst | 13 +++ .../constraints/NotCompromisedPassword.rst | 13 +++ reference/constraints/NotEqualTo.rst | 18 ++++ reference/constraints/NotIdenticalTo.rst | 18 ++++ reference/constraints/NotNull.rst | 13 +++ reference/constraints/Positive.rst | 13 +++ reference/constraints/PositiveOrZero.rst | 13 +++ reference/constraints/Range.rst | 65 +++++++++++++++ reference/constraints/Regex.rst | 46 +++++++++++ reference/constraints/Time.rst | 16 ++++ reference/constraints/Timezone.rst | 13 +++ reference/constraints/Traverse.rst | 82 +++++++++++++++++++ reference/constraints/Type.rst | 25 ++++++ reference/constraints/Ulid.rst | 13 +++ reference/constraints/Unique.rst | 13 +++ reference/constraints/UniqueEntity.rst | 54 ++++++++++++ reference/constraints/Url.rst | 58 +++++++++++++ reference/constraints/UserPassword.rst | 15 ++++ reference/constraints/Uuid.rst | 13 +++ reference/constraints/Valid.rst | 47 +++++++++++ 58 files changed, 1404 insertions(+) diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst index 029a322e294..076cbf29b6c 100644 --- a/reference/constraints/Bic.rst +++ b/reference/constraints/Bic.rst @@ -41,6 +41,19 @@ will contain a Business Identifier Code (BIC). protected $businessIdentifierCode; } + .. code-block:: php-attributes + + // src/Entity/Transaction.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Transaction + { + #[Assert\Bic] + protected $businessIdentifierCode; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Blank.rst b/reference/constraints/Blank.rst index 8a5ba13671a..fbbd693e013 100644 --- a/reference/constraints/Blank.rst +++ b/reference/constraints/Blank.rst @@ -45,6 +45,19 @@ of an ``Author`` class were blank, you could do the following: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Blank] + protected $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst index 6985f3953e1..d15337ba9b5 100644 --- a/reference/constraints/Callback.rst +++ b/reference/constraints/Callback.rst @@ -50,6 +50,23 @@ Configuration } } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + use Symfony\Component\Validator\Context\ExecutionContextInterface; + + class Author + { + #[Assert\Callback] + public function validate(ExecutionContextInterface $context, $payload) + { + // ... + } + } + .. code-block:: yaml # config/validator/validation.yaml @@ -178,6 +195,19 @@ You can then use the following configuration to invoke this validator: { } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Acme\Validator; + use Symfony\Component\Validator\Constraints as Assert; + + #[Assert\Callback([Validator::class, 'validate'])] + class Author + { + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst index 64d6157e2c8..d93224e1a5a 100644 --- a/reference/constraints/CardScheme.rst +++ b/reference/constraints/CardScheme.rst @@ -41,6 +41,22 @@ on an object that will contain a credit card number. protected $cardNumber; } + .. code-block:: php-attributes + + // src/Entity/Transaction.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Transaction + { + #[Assert\CardScheme( + schemes: [Assert\CardScheme::VISA], + message: 'Your credit card number is invalid.', + )] + protected $cardNumber; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst index fd8481d6152..4afa6b516d9 100644 --- a/reference/constraints/Choice.rst +++ b/reference/constraints/Choice.rst @@ -58,6 +58,24 @@ If your valid choice list is simple, you can pass them in directly via the protected $genre; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + const GENRES = ['fiction', 'non-fiction']; + + #[Assert\Choice(['New York', 'Berlin', 'Tokyo'])] + protected $city; + + #[Assert\Choice(choices: Author::GENRES, message: 'Choose a valid genre.')] + protected $genre; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -160,6 +178,19 @@ constraint. protected $genre; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Choice(callback: 'getGenres')] + protected $genre; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -225,6 +256,20 @@ you can pass the class name and the method as an array. protected $genre; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use App\Entity\Genre + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Choice(callback: [Genre::class, 'getGenres'])] + protected $genre; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Count.rst b/reference/constraints/Count.rst index 4ce4691c6c9..c40294a8684 100644 --- a/reference/constraints/Count.rst +++ b/reference/constraints/Count.rst @@ -47,6 +47,24 @@ you might add the following: protected $emails = []; } + .. code-block:: php-attributes + + // src/Entity/Participant.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Participant + { + #[Assert\Count( + min: 1, + max: 5, + minMessage: 'You must specify at least one email', + maxMessage: 'You cannot specify more than {{ limit }} emails', + )] + protected $emails = []; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Country.rst b/reference/constraints/Country.rst index 744de6dd0fb..62bf38bf2ba 100644 --- a/reference/constraints/Country.rst +++ b/reference/constraints/Country.rst @@ -33,6 +33,19 @@ Basic Usage protected $country; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\Country] + protected $country; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Currency.rst b/reference/constraints/Currency.rst index 651af1b1a92..e481c0ce01d 100644 --- a/reference/constraints/Currency.rst +++ b/reference/constraints/Currency.rst @@ -35,6 +35,19 @@ a valid currency, you could do the following: protected $currency; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\Currency] + protected $currency; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Date.rst b/reference/constraints/Date.rst index 4b1e99c3ed1..7376195960a 100644 --- a/reference/constraints/Date.rst +++ b/reference/constraints/Date.rst @@ -34,6 +34,19 @@ Basic Usage protected $birthday; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Date] + protected $birthday; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/DateTime.rst b/reference/constraints/DateTime.rst index 582f93aeac8..7e5501b5515 100644 --- a/reference/constraints/DateTime.rst +++ b/reference/constraints/DateTime.rst @@ -35,6 +35,22 @@ Basic Usage protected $createdAt; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + /** + * @var string A "Y-m-d H:i:s" formatted value + */ + #[Assert\DateTime] + protected $createdAt; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/DivisibleBy.rst b/reference/constraints/DivisibleBy.rst index 4503959aa57..d08e22c241c 100644 --- a/reference/constraints/DivisibleBy.rst +++ b/reference/constraints/DivisibleBy.rst @@ -53,6 +53,24 @@ The following constraints ensure that: protected $quantity; } + .. code-block:: php-attributes + + // src/Entity/Item.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Item + { + #[Assert\DivisibleBy(0.25)] + protected $weight; + + #[Assert\DivisibleBy( + value: 5, + )] + protected $quantity; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst index 468051004a0..fd2f2576a90 100644 --- a/reference/constraints/Email.rst +++ b/reference/constraints/Email.rst @@ -37,6 +37,21 @@ Basic Usage protected $email; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Email( + message: 'The email {{ value }} is not a valid email.', + )] + protected $email; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/EqualTo.rst b/reference/constraints/EqualTo.rst index 153d13a3098..75d80043cda 100644 --- a/reference/constraints/EqualTo.rst +++ b/reference/constraints/EqualTo.rst @@ -52,6 +52,24 @@ and that the ``age`` is ``20``, you could do the following: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\EqualTo("Mary")] + protected $firstName; + + #[Assert\EqualTo( + value: 20, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Expression.rst b/reference/constraints/Expression.rst index 2ed816f3a03..264ae3b02fc 100644 --- a/reference/constraints/Expression.rst +++ b/reference/constraints/Expression.rst @@ -78,6 +78,22 @@ One way to accomplish this is with the Expression constraint: // ... } + .. code-block:: php-attributes + + // src/Model/BlogPost.php + namespace App\Model; + + use Symfony\Component\Validator\Constraints as Assert; + + #[Assert\Expression( + "this.getCategory() in ['php', 'symfony'] or !this.isTechnicalPost()", + message: 'If this is a tech post, the category should be either php or symfony!', + )] + class BlogPost + { + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -163,6 +179,26 @@ more about the expression language syntax, see // ... } + .. code-block:: php-attributes + + // src/Model/BlogPost.php + namespace App\Model; + + use Symfony\Component\Validator\Constraints as Assert; + + class BlogPost + { + // ... + + #[Assert\Expression( + "this.getCategory() in ['php', 'symfony'] or value == false", + message: 'If this is a tech post, the category should be either php or symfony!', + )] + private $isTechnicalPost; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -299,6 +335,24 @@ type (numeric, boolean, strings, null, etc.) // ... } + .. code-block:: php-attributes + + // src/Model/Analysis.php + namespace App\Model; + + use Symfony\Component\Validator\Constraints as Assert; + + class Analysis + { + #[Assert\Expression( + 'value + error_margin < threshold', + values: ['error_margin' => 0.25, 'threshold' => 1.5], + )] + private $metric; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/ExpressionLanguageSyntax.rst b/reference/constraints/ExpressionLanguageSyntax.rst index 2ca0355dfaf..218d68d4f69 100644 --- a/reference/constraints/ExpressionLanguageSyntax.rst +++ b/reference/constraints/ExpressionLanguageSyntax.rst @@ -52,6 +52,24 @@ The following constraints ensure that: protected $shippingOptions; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\ExpressionLanguageSyntax] + protected $promotion; + + #[Assert\ExpressionLanguageSyntax( + allowedVariables: ['user', 'shipping_centers'], + )] + protected $shippingOptions; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst index f1a27ac8f20..7bce9dce533 100644 --- a/reference/constraints/File.rst +++ b/reference/constraints/File.rst @@ -93,6 +93,23 @@ below a certain file size and a valid PDF, add the following: protected $bioFile; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\File( + maxSize: '1024k', + mimeTypes: ['application/pdf', 'application/x-pdf'], + mimeTypesMessage: 'Please upload a valid PDF', + )] + protected $bioFile; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/GreaterThan.rst b/reference/constraints/GreaterThan.rst index d27017fdbe5..617fc71f2a0 100644 --- a/reference/constraints/GreaterThan.rst +++ b/reference/constraints/GreaterThan.rst @@ -49,6 +49,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\GreaterThan(5)] + protected $siblings; + + #[Assert\GreaterThan( + value: 18, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -126,6 +144,19 @@ that a date must at least be the next day: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThan('today')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -185,6 +216,19 @@ dates. If you want to fix the timezone, append it to the date string: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThan('today UTC')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -245,6 +289,19 @@ current time: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThan('+5 hours')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/GreaterThanOrEqual.rst b/reference/constraints/GreaterThanOrEqual.rst index 8a054e6bbb9..c09d4e250e0 100644 --- a/reference/constraints/GreaterThanOrEqual.rst +++ b/reference/constraints/GreaterThanOrEqual.rst @@ -48,6 +48,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\GreaterThanOrEqual(5)] + protected $siblings; + + #[Assert\GreaterThanOrEqual( + value: 18, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -125,6 +143,19 @@ that a date must at least be the current day: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThanOrEqual('today')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -184,6 +215,19 @@ dates. If you want to fix the timezone, append it to the date string: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThanOrEqual('today UTC')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -244,6 +288,19 @@ current time: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\GreaterThanOrEqual('+5 hours')] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Hostname.rst b/reference/constraints/Hostname.rst index 9e67fb3c8fc..7b6cf07af21 100644 --- a/reference/constraints/Hostname.rst +++ b/reference/constraints/Hostname.rst @@ -42,6 +42,19 @@ will contain a host name. protected $name; } + .. code-block:: php-attributes + + // src/Entity/ServerSettings.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class ServerSettings + { + #[Assert\Hostname(message: 'The server name must be a valid hostname.')] + protected $name; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Iban.rst b/reference/constraints/Iban.rst index 709270f7b12..dcd60e3f408 100644 --- a/reference/constraints/Iban.rst +++ b/reference/constraints/Iban.rst @@ -40,6 +40,21 @@ will contain an International Bank Account Number. protected $bankAccountNumber; } + .. code-block:: php-attributes + + // src/Entity/Transaction.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Transaction + { + #[Assert\Iban( + message: 'This is not a valid International Bank Account Number (IBAN).', + )] + protected $bankAccountNumber; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/IdenticalTo.rst b/reference/constraints/IdenticalTo.rst index 10f1fb52342..7dc71b475f0 100644 --- a/reference/constraints/IdenticalTo.rst +++ b/reference/constraints/IdenticalTo.rst @@ -54,6 +54,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\IdenticalTo("Mary")] + protected $firstName; + + #[Assert\IdenticalTo( + value: 20, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Image.rst b/reference/constraints/Image.rst index e8b492bf4ae..5ffded599b5 100644 --- a/reference/constraints/Image.rst +++ b/reference/constraints/Image.rst @@ -100,6 +100,24 @@ that it is between a certain size, add the following: protected $headshot; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Image( + minWidth: 200, + maxWidth: 400, + minHeight: 200, + maxHeight: 400, + )] + protected $headshot; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -180,6 +198,22 @@ following code: protected $headshot; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Image( + allowLandscape: false, + allowPortrait: false, + )] + protected $headshot; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Ip.rst b/reference/constraints/Ip.rst index 9d744d54c09..3686d6bfc41 100644 --- a/reference/constraints/Ip.rst +++ b/reference/constraints/Ip.rst @@ -36,6 +36,19 @@ Basic Usage protected $ipAddress; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Ip] + protected $ipAddress; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/IsFalse.rst b/reference/constraints/IsFalse.rst index 17881aa9a75..07f25396c66 100644 --- a/reference/constraints/IsFalse.rst +++ b/reference/constraints/IsFalse.rst @@ -58,6 +58,24 @@ method returns **false**: } } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\IsFalse( + message: "You've entered an invalid state." + )] + public function isStateInvalid() + { + // ... + } + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/IsNull.rst b/reference/constraints/IsNull.rst index 252c23d934b..6fcd1e462ad 100644 --- a/reference/constraints/IsNull.rst +++ b/reference/constraints/IsNull.rst @@ -39,6 +39,19 @@ of an ``Author`` class exactly equal to ``null``, you could do the following: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\IsNull] + protected $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/IsTrue.rst b/reference/constraints/IsTrue.rst index 2698ad233e9..dea5d9c5468 100644 --- a/reference/constraints/IsTrue.rst +++ b/reference/constraints/IsTrue.rst @@ -60,6 +60,24 @@ Then you can validate this method with ``IsTrue`` as follows: } } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + protected $token; + + #[Assert\IsTrue(message: 'The token is invalid.')] + public function isTokenValid() + { + return $this->token == $this->generateToken(); + } + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Isbn.rst b/reference/constraints/Isbn.rst index e30d4e96040..fa042eb131e 100644 --- a/reference/constraints/Isbn.rst +++ b/reference/constraints/Isbn.rst @@ -43,6 +43,22 @@ on an object that will contain an ISBN. protected $isbn; } + .. code-block:: php-attributes + + // src/Entity/Book.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Book + { + #[Assert\Isbn( + type: Assert\Isbn::ISBN_10, + message: 'This value is not valid.', + )] + protected $isbn; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Isin.rst b/reference/constraints/Isin.rst index c646f33a53a..3efab915437 100644 --- a/reference/constraints/Isin.rst +++ b/reference/constraints/Isin.rst @@ -33,6 +33,19 @@ Basic Usage protected $isin; } + .. code-block:: php-attributes + + // src/Entity/UnitAccount.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class UnitAccount + { + #[Assert\Isin] + protected $isin; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Issn.rst b/reference/constraints/Issn.rst index 6cc5734aaa2..8b8d0826610 100644 --- a/reference/constraints/Issn.rst +++ b/reference/constraints/Issn.rst @@ -35,6 +35,19 @@ Basic Usage protected $issn; } + .. code-block:: php-attributes + + // src/Entity/Journal.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Journal + { + #[Assert\Issn] + protected $issn; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Json.rst b/reference/constraints/Json.rst index 6e8318077da..cd1abf69d6c 100644 --- a/reference/constraints/Json.rst +++ b/reference/constraints/Json.rst @@ -35,6 +35,21 @@ The ``Json`` constraint can be applied to a property or a "getter" method: private $chapters; } + .. code-block:: php-attributes + + // src/Entity/Book.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Book + { + #[Assert\Json( + message: "You've entered an invalid Json." + )] + private $chapters; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Language.rst b/reference/constraints/Language.rst index dac3e2819db..0d9522dc882 100644 --- a/reference/constraints/Language.rst +++ b/reference/constraints/Language.rst @@ -34,6 +34,19 @@ Basic Usage protected $preferredLanguage; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\Language] + protected $preferredLanguage; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst index 365aedfb585..13800f7daea 100644 --- a/reference/constraints/Length.rst +++ b/reference/constraints/Length.rst @@ -48,6 +48,25 @@ and "50", you might add the following: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Participant.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Participant + { + #[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', + )] + protected $firstName; + } + + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/LessThan.rst b/reference/constraints/LessThan.rst index abd0aab721c..495d3f4356a 100644 --- a/reference/constraints/LessThan.rst +++ b/reference/constraints/LessThan.rst @@ -49,6 +49,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThan(5)] + protected $siblings; + + #[Assert\LessThan( + value: 80, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -126,6 +144,19 @@ that a date must be in the past like this: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThan('today')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -185,6 +216,19 @@ dates. If you want to fix the timezone, append it to the date string: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThan('today UTC')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -244,6 +288,19 @@ can check that a person must be at least 18 years old like this: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThan('-18 years')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/LessThanOrEqual.rst b/reference/constraints/LessThanOrEqual.rst index 42ec3e939e5..47d06cfc601 100644 --- a/reference/constraints/LessThanOrEqual.rst +++ b/reference/constraints/LessThanOrEqual.rst @@ -48,6 +48,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThanOrEqual(5)] + protected $siblings; + + #[Assert\LessThanOrEqual( + value: 80, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -125,6 +143,19 @@ that a date must be today or in the past like this: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThanOrEqual('today')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -184,6 +215,19 @@ dates. If you want to fix the timezone, append it to the date string: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThanOrEqual('today UTC')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -243,6 +287,19 @@ can check that a person must be at least 18 years old like this: protected $dateOfBirth; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\LessThanOrEqual('-18 years')] + protected $dateOfBirth; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Locale.rst b/reference/constraints/Locale.rst index f5f381629e3..936cfd24089 100644 --- a/reference/constraints/Locale.rst +++ b/reference/constraints/Locale.rst @@ -43,6 +43,21 @@ Basic Usage protected $locale; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\Locale( + canonicalize: true, + )] + protected $locale; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Luhn.rst b/reference/constraints/Luhn.rst index 2bee41d5f2c..24eb9b91947 100644 --- a/reference/constraints/Luhn.rst +++ b/reference/constraints/Luhn.rst @@ -37,6 +37,19 @@ will contain a credit card number. protected $cardNumber; } + .. code-block:: php-attributes + + // src/Entity/Transaction.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Transaction + { + #[Assert\Luhn(message: 'Please check your credit card number.')] + protected $cardNumber; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Negative.rst b/reference/constraints/Negative.rst index 7468b4bfc4a..0ee0bdcf3ea 100644 --- a/reference/constraints/Negative.rst +++ b/reference/constraints/Negative.rst @@ -37,6 +37,19 @@ The following constraint ensures that the ``withdraw`` of a bank account protected $withdraw; } + .. code-block:: php-attributes + + // src/Entity/TransferItem.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class TransferItem + { + #[Assert\Negative] + protected $withdraw; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NegativeOrZero.rst b/reference/constraints/NegativeOrZero.rst index f010acda0b1..8559a57babf 100644 --- a/reference/constraints/NegativeOrZero.rst +++ b/reference/constraints/NegativeOrZero.rst @@ -36,6 +36,19 @@ is a negative number or equal to zero: protected $level; } + .. code-block:: php-attributes + + // src/Entity/TransferItem.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class UnderGroundGarage + { + #[Assert\NegativeOrZero] + protected $level; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst index f5711e001c3..2d302f5fc20 100644 --- a/reference/constraints/NotBlank.rst +++ b/reference/constraints/NotBlank.rst @@ -40,6 +40,19 @@ class were not blank, you could do the following: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotBlank] + protected $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NotCompromisedPassword.rst b/reference/constraints/NotCompromisedPassword.rst index bcd1c61b560..236dfbf5d9b 100644 --- a/reference/constraints/NotCompromisedPassword.rst +++ b/reference/constraints/NotCompromisedPassword.rst @@ -38,6 +38,19 @@ The following constraint ensures that the ``rawPassword`` property of the protected $rawPassword; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\NotCompromisedPassword] + protected $rawPassword; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NotEqualTo.rst b/reference/constraints/NotEqualTo.rst index e1436657ae8..ec5fa5000b5 100644 --- a/reference/constraints/NotEqualTo.rst +++ b/reference/constraints/NotEqualTo.rst @@ -53,6 +53,24 @@ the following: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\NotEqualTo('Mary')] + protected $firstName; + + #[Assert\NotEqualTo( + value: 15, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NotIdenticalTo.rst b/reference/constraints/NotIdenticalTo.rst index 66ccb871670..ab96bde3806 100644 --- a/reference/constraints/NotIdenticalTo.rst +++ b/reference/constraints/NotIdenticalTo.rst @@ -54,6 +54,24 @@ The following constraints ensure that: protected $age; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\NotIdenticalTo('Mary')] + protected $firstName; + + #[Assert\NotIdenticalTo( + value: 15, + )] + protected $age; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/NotNull.rst b/reference/constraints/NotNull.rst index 56d088c4cba..ccf8839434d 100644 --- a/reference/constraints/NotNull.rst +++ b/reference/constraints/NotNull.rst @@ -37,6 +37,19 @@ class were not strictly equal to ``null``, you would: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotNull] + protected $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Positive.rst b/reference/constraints/Positive.rst index af76f205e53..6e5d80c9250 100644 --- a/reference/constraints/Positive.rst +++ b/reference/constraints/Positive.rst @@ -37,6 +37,19 @@ positive number (greater than zero): protected $income; } + .. code-block:: php-attributes + + // src/Entity/Employee.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Employee + { + #[Assert\Positive] + protected $income; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/PositiveOrZero.rst b/reference/constraints/PositiveOrZero.rst index ea762e78f90..08435c2054f 100644 --- a/reference/constraints/PositiveOrZero.rst +++ b/reference/constraints/PositiveOrZero.rst @@ -36,6 +36,19 @@ is positive or zero: protected $siblings; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\PositiveOrZero] + protected $siblings; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Range.rst b/reference/constraints/Range.rst index d5b473362dd..c499187ee66 100644 --- a/reference/constraints/Range.rst +++ b/reference/constraints/Range.rst @@ -47,6 +47,23 @@ you might add the following: protected $height; } + .. code-block:: php-attributes + + // src/Entity/Participant.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Participant + { + #[Assert\Range( + min: 120, + max: 180, + notInRangeMessage: 'You must be between {{ min }}cm and {{ max }}cm tall to enter', + )] + protected $height; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -125,6 +142,22 @@ date must lie within the current year like this: protected $startDate; } + .. code-block:: php-attributes + + // src/Entity/Event.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Event + { + #[Assert\Range( + min: 'first day of January', + max: 'first day of January next year', + )] + protected $startDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -195,6 +228,22 @@ dates. If you want to fix the timezone, append it to the date string: protected $startDate; } + .. code-block:: php-attributes + + // src/Entity/Event.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Event + { + #[Assert\Range( + min: 'first day of January UTC', + max: 'first day of January next year UTC', + )] + protected $startDate; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -265,6 +314,22 @@ can check that a delivery date starts within the next five hours like this: protected $deliveryDate; } + .. code-block:: php-attributes + + // src/Entity/Order.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Order + { + #[Assert\Range( + min: 'now', + max: '+5 hours', + )] + protected $deliveryDate; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Regex.rst b/reference/constraints/Regex.rst index 642a1fc180d..a6217c892f7 100644 --- a/reference/constraints/Regex.rst +++ b/reference/constraints/Regex.rst @@ -41,6 +41,19 @@ more word characters at the beginning of your string: protected $description; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Regex('/^\w+/')] + protected $description; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -110,6 +123,23 @@ it a custom message: protected $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Regex( + pattern: '/\d/', + match: false, + message: 'Your name cannot contain a number', + )] + protected $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -203,6 +233,22 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: protected $name; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Regex( + pattern: '/^[a-z]+$/i', + match: '^[a-zA-Z]+$' + )] + protected $name; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Time.rst b/reference/constraints/Time.rst index e94613e1f6f..fb8a9b337fb 100644 --- a/reference/constraints/Time.rst +++ b/reference/constraints/Time.rst @@ -37,6 +37,22 @@ of the day when the event starts: protected $startsAt; } + .. code-block:: php-attributes + + // src/Entity/Event.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Event + { + /** + * @var string A "H:i:s" formatted value + */ + #[Assert\Time] + protected $startsAt; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Timezone.rst b/reference/constraints/Timezone.rst index 98ca73c156a..36ebdd0b86b 100644 --- a/reference/constraints/Timezone.rst +++ b/reference/constraints/Timezone.rst @@ -38,6 +38,19 @@ string which contains any of the `PHP timezone identifiers`_ (e.g. ``America/New protected $timezone; } + .. code-block:: php-attributes + + // src/Entity/UserSettings.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class UserSettings + { + #[Assert\Timezone] + protected $timezone; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Traverse.rst b/reference/constraints/Traverse.rst index fd329bd38a3..9301afc445a 100644 --- a/reference/constraints/Traverse.rst +++ b/reference/constraints/Traverse.rst @@ -89,6 +89,73 @@ that all have constraints on their properties. } } + .. code-block:: php-attributes + + // src/Entity/BookCollection.php + namespace App\Entity; + + use Doctrine\Common\Collections\ArrayCollection; + use Doctrine\Common\Collections\Collection + use Doctrine\ORM\Mapping as ORM; + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @ORM\Entity + */ + #[Assert\Traverse] + class BookCollection implements \IteratorAggregate + { + /** + * @var string + * + * @ORM\Column + */ + #[Assert\NotBlank] + protected $name = ''; + + /** + * @var Collection|Book[] + * + * @ORM\ManyToMany(targetEntity="App\Entity\Book") + */ + protected $books; + + // some other properties + + public function __construct() + { + $this->books = new ArrayCollection(); + } + + // ... setter for name, adder and remover for books + + // the name can be validated by calling the getter + public function getName(): string + { + return $this->name; + } + + /** + * @return \Generator|Book[] The books for a given author + */ + public function getBooksForAuthor(Author $author): iterable + { + foreach ($this->books as $book) { + if ($book->isAuthoredBy($author)) { + yield $book; + } + } + } + + // neither the method above nor any other specific getter + // could be used to validated all nested books; + // this object needs to be traversed to call the iterator + public function getIterator() + { + return $this->books->getIterator(); + } + } + .. code-block:: yaml # config/validator/validation.yaml @@ -168,6 +235,21 @@ disable validating: // ... } + .. code-block:: php-attributes + + // src/Entity/BookCollection.php + + // ... same as above + + /** + * ... + */ + #[Assert\Traverse(false)] + class BookCollection implements \IteratorAggregate + { + // ... + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index 1962dffa284..61189e7f989 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -59,6 +59,31 @@ This will check if ``id`` is an instance of ``Ramsey\Uuid\UuidInterface``, protected $accessCode; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Type('Ramsey\Uuid\UuidInterface')] + protected $id; + + #[Assert\Type('string')] + protected $firstName; + + #[Assert\Type( + type: 'integer', + message: 'The value {{ value }} is not a valid {{ type }}.', + )] + protected $age; + + #[Assert\Type(type: ['alpha', 'digit'])] + protected $accessCode; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Ulid.rst b/reference/constraints/Ulid.rst index 7bcae08e961..92315089350 100644 --- a/reference/constraints/Ulid.rst +++ b/reference/constraints/Ulid.rst @@ -37,6 +37,19 @@ Basic Usage protected $identifier; } + .. code-block:: php-attributes + + // src/Entity/File.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class File + { + #[Assert\Ulid] + protected $identifier; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst index 97cb6ff8602..497156ed9b4 100644 --- a/reference/constraints/Unique.rst +++ b/reference/constraints/Unique.rst @@ -50,6 +50,19 @@ strings: protected $contactEmails; } + .. code-block:: php-attributes + + // src/Entity/Person.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Person + { + #[Assert\Unique] + protected $contactEmails; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst index 2bf2533f57e..c76a31e6a4c 100644 --- a/reference/constraints/UniqueEntity.rst +++ b/reference/constraints/UniqueEntity.rst @@ -59,6 +59,31 @@ between all of the rows in your user table: protected $email; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Doctrine\ORM\Mapping as ORM; + + // DON'T forget the following use statement!!! + use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; + + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @ORM\Entity + */ + #[UniqueEntity('email')] + class User + { + /** + * @ORM\Column(name="email", type="string", length=255, unique=true) + */ + #[Assert\Email] + protected $email; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -188,6 +213,35 @@ Consider this example: public $port; } + .. code-block:: php-attributes + + // src/Entity/Service.php + namespace App\Entity; + + use Doctrine\ORM\Mapping as ORM; + use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; + + /** + * @ORM\Entity + */ + #[UniqueEntity( + fields: ['host', 'port'], + errorPath: 'port', + message: 'This port is already in use on that host.', + )] + class Service + { + /** + * @ORM\ManyToOne(targetEntity="App\Entity\Host") + */ + public $host; + + /** + * @ORM\Column(type="integer") + */ + public $port; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst index 5f4ac23245f..91714131294 100644 --- a/reference/constraints/Url.rst +++ b/reference/constraints/Url.rst @@ -35,6 +35,19 @@ Basic Usage protected $bioUrl; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Url] + protected $bioUrl; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -124,6 +137,21 @@ Parameter Description protected $bioUrl; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Url( + message: 'The url {{ value }} is not a valid url', + )] + protected $bioUrl; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -200,6 +228,21 @@ the ``ftp://`` type URLs to be valid, redefine the ``protocols`` array, listing protected $bioUrl; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Url( + protocols: ['http', 'https', 'ftp'], + )] + protected $bioUrl; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -275,6 +318,21 @@ also relative URLs that contain no protocol (e.g. ``//example.com``). protected $bioUrl; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Url( + relativeProtocol: true, + )] + protected $bioUrl; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/UserPassword.rst b/reference/constraints/UserPassword.rst index 9655380bf95..03c992e66e6 100644 --- a/reference/constraints/UserPassword.rst +++ b/reference/constraints/UserPassword.rst @@ -51,6 +51,21 @@ the user's current password: protected $oldPassword; } + .. code-block:: php-attributes + + // src/Form/Model/ChangePassword.php + namespace App\Form\Model; + + use Symfony\Component\Security\Core\Validator\Constraints as SecurityAssert; + + class ChangePassword + { + #[SecurityAssert\UserPassword( + message: 'Wrong value for your current password', + )] + protected $oldPassword; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Uuid.rst b/reference/constraints/Uuid.rst index 427a373f788..c7b2d94900b 100644 --- a/reference/constraints/Uuid.rst +++ b/reference/constraints/Uuid.rst @@ -38,6 +38,19 @@ Basic Usage protected $identifier; } + .. code-block:: php-attributes + + // src/Entity/File.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class File + { + #[Assert\Uuid] + protected $identifier; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/reference/constraints/Valid.rst b/reference/constraints/Valid.rst index 1cb992128ac..8378f34cbec 100644 --- a/reference/constraints/Valid.rst +++ b/reference/constraints/Valid.rst @@ -87,6 +87,40 @@ stores an ``Address`` instance in the ``$address`` property:: protected $address; } + .. code-block:: php-attributes + + // src/Entity/Address.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Address + { + #[Assert\NotBlank] + protected $street; + + #[Assert\NotBlank] + #[Assert\Length(max: 5)] + protected $zipCode; + } + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotBlank] + #[Assert\Length(min: 4)] + protected $firstName; + + #[Assert\NotBlank] + protected $lastName; + + protected $address; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -196,6 +230,19 @@ an invalid address. To prevent that, add the ``Valid`` constraint to the protected $address; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Valid] + protected $address; + } + .. code-block:: yaml # config/validator/validation.yaml From 8379ea8be9f200ac4415fd6a678bfc1462066d9f Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 21 Jan 2021 21:19:23 +0100 Subject: [PATCH 0403/5766] Update messenger.rst --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 2999db21334..2947f18cb68 100644 --- a/messenger.rst +++ b/messenger.rst @@ -214,7 +214,7 @@ you can configure them to be sent to a transport: routing: # async is whatever name you gave your transport above - 'App\Message\SmsNotification': async + 'App\Message\SmsNotification': async .. code-block:: xml From 465da94d215a21cdfb362c592730c89704557ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 22 Dec 2020 20:04:03 +0100 Subject: [PATCH 0404/5766] [Mercure] Update docs for v0.11 --- mercure.rst | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/mercure.rst b/mercure.rst index e4bc11d911f..527833e2f7e 100644 --- a/mercure.rst +++ b/mercure.rst @@ -68,11 +68,20 @@ clients. An official and open source (AGPL) implementation of a Hub can be downloaded as a static binary from `Mercure.rocks`_. -Run the following command to start it: +If you use `Symfony Docker`_, +a Mercure Hub is already included and you can skip straight to the next section. -.. code-block:: terminal +On Linux and Mac, run the following command to start it: + +.. rst-class:: command-linux + + $ SERVER_NAME=:3000 MERCURE_PUBLISHER_JWT_KEY="!ChangeMe!" MERCURE_SUBSCRIBER_JWT_KEY="!ChangeMe!" ./mercure run -config Caddyfile.dev + +On Windows run: + +.. rst-class: command-windows - $ ./mercure --jwt-key='!ChangeMe!' --addr='localhost:3000' --allow-anonymous --cors-allowed-origins='*' + > $env:SERVER_NAME=':3000'; $env:MERCURE_PUBLISHER_JWT_KEY='!ChangeMe!'; $env:MERCURE_SUBSCRIBER_JWT_KEY='!ChangeMe!'; .\mercure.exe run -config Caddyfile.dev .. note:: @@ -175,8 +184,8 @@ the **topic** being updated. This topic should be an `IRI`_ of the resource being dispatched. Usually, this parameter contains the original URL of the resource -transmitted to the client, but it can be any valid `IRI`_, it doesn't -have to be a URL that exists (similarly to XML namespaces). +transmitted to the client, but it can be any string or `IRI`_, +and it doesn't have to be a URL that exists (similarly to XML namespaces). The second parameter of the constructor is the content of the update. It can be anything, stored in any format. @@ -630,6 +639,7 @@ Enable the panel in your configuration, as follows: .. _`high-level implementations`: https://mercure.rocks/docs/ecosystem/awesome .. _`In this recording`: https://www.youtube.com/watch?v=UI1l0JOjLeI .. _`Mercure.rocks`: https://mercure.rocks +.. _`Symfony Docker`: https://github.com/dunglas/symfony-docker/ .. _`API Platform distribution`: https://api-platform.com/docs/distribution/ .. _`JSON Web Token`: https://tools.ietf.org/html/rfc7519 .. _`example JWT`: https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOlsiKiJdfX0.iHLdpAEjX4BqCsHJEegxRmO-Y6sMxXwNATrQyRNt3GY From 0f95e076b5529d5507444f55a130946865647d1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Marcin=20Brzuchalski?= Date: Tue, 19 Jan 2021 17:54:47 +0100 Subject: [PATCH 0405/5766] Require preprocessor env name fix used in PHP snippet --- configuration/env_var_processors.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst index 710ce3da6b6..7b134067bef 100644 --- a/configuration/env_var_processors.rst +++ b/configuration/env_var_processors.rst @@ -394,7 +394,7 @@ Symfony provides the following env var processors: // config/packages/framework.php $container->setParameter('env(PHP_FILE)', '../config/.runtime-evaluated.php'); $container->loadFromExtension('app', [ - 'auth' => '%env(require:AUTH_FILE)%', + 'auth' => '%env(require:PHP_FILE)%', ]); .. versionadded:: 4.3 From 3d560c3059e18ad7eecb4e45eeda1887cbee3e2c Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 20 Jan 2021 16:23:39 +0100 Subject: [PATCH 0406/5766] Listing possible values of storage_id --- reference/configuration/framework.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 83b1cd90abb..4515077d1d7 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1249,9 +1249,14 @@ storage_id **type**: ``string`` **default**: ``'session.storage.native'`` -The service id used for session storage. The ``session.storage`` service -alias will be set to this service id. This class has to implement +The service ID used for storing the session. The ``session.storage`` service +alias will be set to this service. The class has to implement :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface`. +To see a list of all available storages, run: + +.. code-block:: terminal + + $ php bin/console debug:container session.storage. .. _config-framework-session-handler-id: From 706222e14f34905949e077001cfd25be8dc74488 Mon Sep 17 00:00:00 2001 From: Ian Gilfillan Date: Tue, 12 Jan 2021 22:47:34 +0200 Subject: [PATCH 0407/5766] Mention MariaDB as well --- session/database.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/session/database.rst b/session/database.rst index badd1412145..6430517c647 100644 --- a/session/database.rst +++ b/session/database.rst @@ -166,11 +166,11 @@ parallel and only the first one stored the CSRF token in the session. If you use Memcached instead of Redis, follow a similar approach but replace ``RedisSessionHandler`` by :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`. -Store Sessions in a Relational Database (MySQL, PostgreSQL) +Store Sessions in a Relational Database (MariaDB, MySQL, PostgreSQL) ----------------------------------------------------------- Symfony includes a :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler` -to store sessions in relational databases like MySQL and PostgreSQL. To use it, +to store sessions in relational databases like MariaDB, MySQL and PostgreSQL. To use it, first register a new handler service with your database credentials: .. configuration-block:: @@ -379,8 +379,8 @@ file and run the migration with the following command: $ php bin/console doctrine:migrations:migrate -MySQL -..... +MariaDB/MySQL +............. .. code-block:: sql From 794de34c0063736b057c6d666569d350618f3522 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 15:12:02 +0100 Subject: [PATCH 0408/5766] Tweaks --- session/database.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/session/database.rst b/session/database.rst index 6430517c647..a0fb1b3d4a6 100644 --- a/session/database.rst +++ b/session/database.rst @@ -167,7 +167,7 @@ parallel and only the first one stored the CSRF token in the session. ``RedisSessionHandler`` by :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MemcachedSessionHandler`. Store Sessions in a Relational Database (MariaDB, MySQL, PostgreSQL) ------------------------------------------------------------ +-------------------------------------------------------------------- Symfony includes a :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler` to store sessions in relational databases like MariaDB, MySQL and PostgreSQL. To use it, @@ -379,6 +379,8 @@ file and run the migration with the following command: $ php bin/console doctrine:migrations:migrate +.. _mysql: + MariaDB/MySQL ............. From 5d8a9e25130e6d46da32084b2aa5ce64bba8cc63 Mon Sep 17 00:00:00 2001 From: CaDJoU <46056722+cadjou@users.noreply.github.com> Date: Tue, 19 Jan 2021 23:40:48 +0100 Subject: [PATCH 0409/5766] [Mailer] Update mailer.rst --- mailer.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/mailer.rst b/mailer.rst index 90472439eb5..bef7cef866e 100644 --- a/mailer.rst +++ b/mailer.rst @@ -65,6 +65,13 @@ over SMTP by configuring the DSN in your ``.env`` file (the ``user``, ]); }; +.. caution:: + + If the username, password or host 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. + .. caution:: If you are migrating from Swiftmailer (and the Swiftmailer bundle), be From 58ddc5fd32a66765980d686b00ab1b6fdd2d7105 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 15:17:24 +0100 Subject: [PATCH 0410/5766] Added missing reference link --- mailer.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/mailer.rst b/mailer.rst index bef7cef866e..58531bf85f3 100644 --- a/mailer.rst +++ b/mailer.rst @@ -1120,3 +1120,4 @@ a specific address, instead of the *real* address: .. _`S/MIME`: https://en.wikipedia.org/wiki/S/MIME .. _`OpenSSL PHP extension`: https://www.php.net/manual/en/book.openssl.php .. _`PEM encoded`: https://en.wikipedia.org/wiki/Privacy-Enhanced_Mail +.. _`RFC 3986`: https://www.ietf.org/rfc/rfc3986.txt From 6987db2dd8e984775d26058f611a321ab28693fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vincent=20Brout=C3=A9?= Date: Fri, 8 Jan 2021 18:08:31 +0100 Subject: [PATCH 0411/5766] Update configuration.rst Fix PHP configuration sample for setting default parameter bindings. --- configuration.rst | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/configuration.rst b/configuration.rst index e25e18efd5b..1b5c2eef31f 100644 --- a/configuration.rst +++ b/configuration.rst @@ -881,18 +881,15 @@ whenever a service/controller defines a ``$projectDir`` argument, use this: namespace Symfony\Component\DependencyInjection\Loader\Configurator; use App\Controller\LuckyController; - use Psr\Log\LoggerInterface; - use Symfony\Component\DependencyInjection\Reference; return static function (ContainerConfigurator $container) { - $container->services() - ->set(LuckyController::class) - ->public() - ->args([ - // pass this value to any $projectDir argument for any service - // that's created in this file (including controller arguments) - '$projectDir' => '%kernel.project_dir%', - ]); + $services = $container->services() + ->defaults() + // pass this value to any $projectDir argument for any service + // that's created in this file (including controller arguments) + ->bind('$projectDir', '%kernel.project_dir%'); + + // ... }; .. seealso:: From b72cfde11a1a6b53860b4c42e65573ac0db97d91 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 15:34:09 +0100 Subject: [PATCH 0412/5766] Tweak --- configuration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.rst b/configuration.rst index 1b5c2eef31f..ecc34b99ddc 100644 --- a/configuration.rst +++ b/configuration.rst @@ -883,7 +883,7 @@ whenever a service/controller defines a ``$projectDir`` argument, use this: use App\Controller\LuckyController; return static function (ContainerConfigurator $container) { - $services = $container->services() + $container->services() ->defaults() // pass this value to any $projectDir argument for any service // that's created in this file (including controller arguments) From b703a22e5c286c2a1f10369d97a00ede143e590b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 16:59:27 +0100 Subject: [PATCH 0413/5766] Tweaks --- components/phpunit_bridge.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst index 289346547c7..674c5d1c519 100644 --- a/components/phpunit_bridge.rst +++ b/components/phpunit_bridge.rst @@ -302,17 +302,16 @@ whenever you want to update the existing file): .. code-block:: terminal - $ SYMFONY_DEPRECATIONS_HELPER='generateBaseline=true&baselineFile=tests/allowed.json' ./vendor/bin/simple-phpunit + $ SYMFONY_DEPRECATIONS_HELPER='generateBaseline=true&baselineFile=./tests/allowed.json' ./vendor/bin/simple-phpunit This command stores all the deprecations reported while running tests in the -given file and encoded in JSON. The file path defined in ``baselineFile`` can -be absolute or relative to your project root. +given file path and encoded in JSON. Then, you can run the following command to use that file and ignore those deprecations: .. code-block:: terminal - $ SYMFONY_DEPRECATIONS_HELPER='baselineFile=tests/allowed.json' ./vendor/bin/simple-phpunit + $ SYMFONY_DEPRECATIONS_HELPER='baselineFile=./tests/allowed.json' ./vendor/bin/simple-phpunit .. versionadded:: 5.2 From 425495b63061147b8c6f3e160f747c5991bde682 Mon Sep 17 00:00:00 2001 From: Souhail Date: Fri, 22 Jan 2021 17:01:50 +0100 Subject: [PATCH 0414/5766] Update serializer.rst Update CsvEncoder's default values --- components/serializer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/serializer.rst b/components/serializer.rst index d6c19a10cd3..f554ed7cf76 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -869,7 +869,7 @@ Option Description D ``csv_delimiter`` Sets the field delimiter separating values (one ``,`` character only) ``csv_enclosure`` Sets the field enclosure (one character only) ``"`` -``csv_escape_char`` Sets the escape character (at most one character) +``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 ``.`` flattening ``csv_headers`` Sets the order of the header and data columns @@ -879,7 +879,7 @@ Option Description D ``a,b,c\n1,2,3`` ``[]``, inferred from input data's keys ``csv_escape_formulas`` Escapes fields containg formulas by prepending them ``false`` with a ``\t`` character -``as_collection`` Always returns results as a collection, even if only +``as_collection`` Always returns results as a collection, even if only ``true`` one line is decoded. ``no_headers`` Disables header in the encoded CSV ``false`` ``output_utf8_bom`` Outputs special `UTF-8 BOM`_ along with encoded data ``false`` From 78c0441a5b370c6789e0f399bbc896ef86d542c4 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 17:31:27 +0100 Subject: [PATCH 0415/5766] Tweaks --- messenger.rst | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/messenger.rst b/messenger.rst index e73498c6c84..edd43cd7881 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1309,6 +1309,16 @@ during a request:: } } +The transport has a number of options: + +``serialize`` (boolean, default: ``false``) + Whether to serialize messages or not. This is useful to test an additional + layer, especially when you use your own message serializer. + +.. versionadded:: 5.3 + + The ``serialize`` option was introduced in Symfony 5.3. + .. note:: All ``in-memory`` transports will be reset automatically after each test **in** @@ -1316,15 +1326,6 @@ during a request:: :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\KernelTestCase` or :class:`Symfony\\Bundle\\FrameworkBundle\\Test\\WebTestCase`. -.. tip:: - - Using ``in-memory://?serialize=true`` as dsn will perform message serialization as real asynchronous transport will do. - Useful to test an additional layer, especially when you use your own message serializer. - -.. versionadded:: 5.3 - - The ``in-memory://?serialize=true`` dsn was introduced in Symfony 5.3. - Amazon SQS ~~~~~~~~~~ From b40bfae8215c1e4d7615270a334c2ce0eae0f09a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 22 Jan 2021 17:41:56 +0100 Subject: [PATCH 0416/5766] [Workflow] Added initialization docs --- components/workflow.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/components/workflow.rst b/components/workflow.rst index a35602f1ac2..493b4230124 100644 --- a/components/workflow.rst +++ b/components/workflow.rst @@ -94,6 +94,20 @@ you can retrieve a workflow from it and use it as follows:: $workflow->can($blogPost, 'publish'); // True $workflow->getEnabledTransitions($blogPost); // $blogPost can perform transition "publish" or "reject" +Initialization +-------------- + +If the property of your object is ``null`` and you want to set it with the +``initial_marking`` from the configuration, you can call the ``getMarking()`` +method to initialize the object property:: + + // ... + $blogPost = new BlogPost(); + $workflow = $registry->get($blogPost); + + // initiate workflow + $workflow->getMarking($blogPost); + Learn more ---------- From 29a254533cf8ad5253fc7b68a8652bba4ba6ebba Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sat, 23 Jan 2021 14:37:04 +0100 Subject: [PATCH 0417/5766] [Validator] Use double quotes instead of single --- reference/constraints/IsFalse.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/IsFalse.rst b/reference/constraints/IsFalse.rst index 861072a1250..e476fb25387 100644 --- a/reference/constraints/IsFalse.rst +++ b/reference/constraints/IsFalse.rst @@ -97,7 +97,7 @@ method returns **false**: public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addGetterConstraint('stateInvalid', new Assert\IsFalse([ - 'message' => 'You've entered an invalid state.', + 'message' => "You've entered an invalid state.", ])); } } From 9db655a618a1421fe879ab215b9396b6324fe882 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 23 Jan 2021 11:08:47 +0100 Subject: [PATCH 0418/5766] [Validator] Use constant instead of magic string --- reference/constraints/CardScheme.rst | 2 +- reference/constraints/Isbn.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst index d93224e1a5a..1a196970525 100644 --- a/reference/constraints/CardScheme.rst +++ b/reference/constraints/CardScheme.rst @@ -101,7 +101,7 @@ on an object that will contain a credit card number. { $metadata->addPropertyConstraint('cardNumber', new Assert\CardScheme([ 'schemes' => [ - 'VISA', + Assert\CardScheme::VISA, ], 'message' => 'Your credit card number is invalid.', ])); diff --git a/reference/constraints/Isbn.rst b/reference/constraints/Isbn.rst index 2865ceffafe..9bfab789825 100644 --- a/reference/constraints/Isbn.rst +++ b/reference/constraints/Isbn.rst @@ -100,7 +100,7 @@ on an object that will contain an ISBN. public static function loadValidatorMetadata(ClassMetadata $metadata) { $metadata->addPropertyConstraint('isbn', new Assert\Isbn([ - 'type' => 'isbn10', + 'type' => Assert\Isbn::ISBN_10, 'message' => 'This value is not valid.', ])); } From 0b715dee94dab45fca4c414153427c40b5254335 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sun, 24 Jan 2021 19:08:00 +0100 Subject: [PATCH 0419/5766] [Validator] Use single quotes for string --- reference/constraints/Sequentially.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/Sequentially.rst b/reference/constraints/Sequentially.rst index 39424a6c523..21e088ba689 100644 --- a/reference/constraints/Sequentially.rst +++ b/reference/constraints/Sequentially.rst @@ -120,7 +120,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\Type('string'), new Assert\Length(['min' => 10]), new Assert\Regex(self::ADDRESS_REGEX), new AcmeAssert\Geolocalizable(), From a423947869694a15b914431373643a1b25b62b73 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sun, 24 Jan 2021 19:33:51 +0100 Subject: [PATCH 0420/5766] [Validator] Change the example to be consistent with the rest Other examples do not use key 'value'. --- reference/constraints/AtLeastOneOf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/AtLeastOneOf.rst b/reference/constraints/AtLeastOneOf.rst index b69894184d6..fb29a86f8d8 100644 --- a/reference/constraints/AtLeastOneOf.rst +++ b/reference/constraints/AtLeastOneOf.rst @@ -141,7 +141,7 @@ The following constraints ensure that: new Assert\Count(['min' => 3]), new Assert\All([ 'constraints' => [ - new Assert\GreaterThanOrEqual(['value' => 5]), + new Assert\GreaterThanOrEqual(5), ], ]), ], From a1c303bfb4dbd0586763ad4f8232673d5b042f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 23 Jan 2021 21:37:54 +0100 Subject: [PATCH 0421/5766] Add documentation about breach --- security/csrf.rst | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/security/csrf.rst b/security/csrf.rst index ac8e840c978..7058fb88478 100644 --- a/security/csrf.rst +++ b/security/csrf.rst @@ -85,7 +85,7 @@ this can be customized on a form-by-form basis:: // src/Form/TaskType.php namespace App\Form; - + // ... use App\Entity\Task; use Symfony\Component\OptionsResolver\OptionsResolver; @@ -162,4 +162,19 @@ to check its validity:: } } +CSRF Tokens and Compression Side-Channel Attacks +------------------------------------------------ + +`BREACH`_ and `CRIME`_ are security exploits against HTTPS when using HTTP +compression. Attacker can leverage information leaked by compression to recover +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. + +.. versionadded:: 5.3 + + The randomization of tokens was introduced in Symfony 5.3 + .. _`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 From 56add0114806c646c7a78b2ee85a52ae86f32eae Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 25 Jan 2021 17:38:42 +0100 Subject: [PATCH 0422/5766] [Notifier] Add clickatell Fix #14880. --- notifier.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index a2072e79c13..7231080d47e 100644 --- a/notifier.rst +++ b/notifier.rst @@ -57,6 +57,7 @@ with a couple popular SMS services: Service Package DSN ========== ================================ ==================================================== AllMySms ``symfony/allmysms-notifier`` ``allmysms://LOGIN:APIKEY@default?from=FROM`` +Clickatell ``symfony/clickatell-notifier`` ``clickatell://ACCESS_TOKEN@default?from=FROM`` Esendex ``symfony/esendex-notifier`` ``esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM`` FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` GatewayApi ``symfony/gatewayapi-notifier`` ``gatewayapi://TOKEN@default?from=FROM`` @@ -82,7 +83,8 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= .. versionadded:: 5.3 - The Iqsms, GatewayApi, Octopush and AllMySms integrations were introduced in Symfony 5.3. + The Iqsms, GatewayApi, Octopush, AllMySms and Clickatell integrations were + introduced in Symfony 5.3. To enable a texter, add the correct DSN in your ``.env`` file and From 86b2834fe361656f83972527d2082e16b398431b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Barto=C5=A1?= Date: Mon, 25 Jan 2021 23:40:14 +0100 Subject: [PATCH 0423/5766] Fix select & plural message format --- translation/message_format.rst | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/translation/message_format.rst b/translation/message_format.rst index 218d479d795..4e637a4335e 100644 --- a/translation/message_format.rst +++ b/translation/message_format.rst @@ -256,27 +256,24 @@ Usage of this string is the same as with variables and select:: .. code-block:: text {gender_of_host, select, - female { - {num_guests, plural, offset:1 + female {{num_guests, plural, offset:1 =0 {{host} does not give a party.} =1 {{host} invites {guest} to her party.} =2 {{host} invites {guest} and one other person to her party.} - other {{host} invites {guest} and # other people to her party.}} - } - male { - {num_guests, plural, offset:1 + other {{host} invites {guest} and # other people to her party.} + }} + male {{num_guests, plural, offset:1 =0 {{host} does not give a party.} =1 {{host} invites {guest} to his party.} =2 {{host} invites {guest} and one other person to his party.} - other {{host} invites {guest} and # other people to his party.}} - } - other { - {num_guests, plural, offset:1 + other {{host} invites {guest} and # other people to his party.} + }} + other {{num_guests, plural, offset:1 =0 {{host} does not give a party.} =1 {{host} invites {guest} to their party.} =2 {{host} invites {guest} and one other person to their party.} - other {{host} invites {guest} and # other people to their party.}} - } + other {{host} invites {guest} and # other people to their party.} + }} } .. sidebar:: Using Ranges in Messages From 0770446f44fc64ce450dc7780f4dd0c02d5011d1 Mon Sep 17 00:00:00 2001 From: Frankie Wittevrongel Date: Tue, 26 Jan 2021 12:44:07 +0000 Subject: [PATCH 0424/5766] Add bright colors to console. --- console/coloring.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/console/coloring.rst b/console/coloring.rst index 913805b5cea..9412511e11f 100644 --- a/console/coloring.rst +++ b/console/coloring.rst @@ -46,7 +46,9 @@ It is possible to define your own styles using the $output->writeln('foo'); Any hex color is supported for foreground and background colors. Besides that, these named colors are supported: -``black``, ``red``, ``green``, ``yellow``, ``blue``, ``magenta``, ``cyan`` and ``white``. +``black``, ``red``, ``green``, ``yellow``, ``blue``, ``magenta``, ``cyan``, ``white``, +``gray``, ``bright-red``, ``bright-green``, ``bright-yellow``, ``bright-blue``, +``bright-magenta``, ``bright-cyan`` and ``bright-white``. .. versionadded:: 5.2 From ff3b2443c29f6fe91c71bbd38b0aed269d96c5d3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 26 Jan 2021 16:52:46 +0100 Subject: [PATCH 0425/5766] Minor tweak --- security/csrf.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/csrf.rst b/security/csrf.rst index 7058fb88478..47b9396d285 100644 --- a/security/csrf.rst +++ b/security/csrf.rst @@ -166,7 +166,7 @@ CSRF Tokens and Compression Side-Channel Attacks ------------------------------------------------ `BREACH`_ and `CRIME`_ are security exploits against HTTPS when using HTTP -compression. Attacker can leverage information leaked by compression to recover +compression. Attackers can leverage information leaked by compression to recover 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. From 55c567603856bc0e353e774645b3a047d84b8177 Mon Sep 17 00:00:00 2001 From: Yoann Renard Date: Thu, 21 Jan 2021 22:15:50 +0100 Subject: [PATCH 0426/5766] [Validator] Use PHP attributes when creating custom validation constraints --- validation/custom_constraint.rst | 72 +++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 11 deletions(-) diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst index c6c588452c4..9cecde12b8a 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -12,20 +12,43 @@ alphanumeric characters. Creating the Constraint Class ----------------------------- -First you need to create a Constraint class and extend :class:`Symfony\\Component\\Validator\\Constraint`:: +First you need to create a Constraint class and extend :class:`Symfony\\Component\\Validator\\Constraint`: - // src/Validator/ContainsAlphanumeric.php - namespace App\Validator; +.. configuration-block:: - use Symfony\Component\Validator\Constraint; + .. code-block:: php-annotations - /** - * @Annotation - */ - class ContainsAlphanumeric extends Constraint - { - public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.'; - } + // src/Validator/ContainsAlphanumeric.php + namespace App\Validator; + + use Symfony\Component\Validator\Constraint; + + /** + * @Annotation + */ + class ContainsAlphanumeric extends Constraint + { + public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.'; + } + + .. code-block:: php-attributes + + // src/Validator/ContainsAlphanumeric.php + namespace App\Validator; + + use Symfony\Component\Validator\Constraint; + + #[\Attribute] + class ContainsAlphanumeric extends Constraint + { + public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.'; + } + +.. versionadded:: 5.2 + + The ability to use PHP attributes to configure constraints was introduced in + Symfony 5.2. Prior to this, Doctrine Annotations were the only way to + annotate constraints. .. note:: @@ -128,6 +151,25 @@ You can use custom validators like the ones provided by Symfony itself: // ... } + .. code-block:: php-attributes + + // src/Entity/AcmeEntity.php + namespace App\Entity; + + use App\Validator as AcmeAssert; + use Symfony\Component\Validator\Constraints as Assert; + + class AcmeEntity + { + // ... + + #[Assert\NotBlank] + #[AcmeAssert\ContainsAlphanumeric] + protected $name; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -241,6 +283,14 @@ not to the property: // ... } + .. code-block:: php-attributes + + #[AcmeAssert\ProtocolClass] + class AcmeEntity + { + // ... + } + .. code-block:: yaml # config/validator/validation.yaml From 62a317b2a52e1d11036992aeb69518ae12d107d5 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Wed, 27 Jan 2021 16:55:14 +0100 Subject: [PATCH 0427/5766] [Lock] Fix grammar issue --- components/lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lock.rst b/components/lock.rst index 7b2c131947d..16049101e10 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -676,7 +676,7 @@ can be two running containers in parallel. .. caution:: All concurrent processes must use the same machine. Before starting a - concurrent process on a new machine, check that other process are stopped + concurrent process on a new machine, check that other processes are stopped on the old one. .. caution:: From e73e9231bd9276372171857720037376849596d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Michael=20O=2E=20Hegg=C3=B8?= Date: Wed, 27 Jan 2021 22:10:28 +0100 Subject: [PATCH 0428/5766] [Messenger] More on unique Redis consumer names --- messenger.rst | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/messenger.rst b/messenger.rst index 45499c14490..733365c3800 100644 --- a/messenger.rst +++ b/messenger.rst @@ -619,7 +619,18 @@ times: process_name=%(program_name)s_%(process_num)02d Change the ``async`` argument to use the name of your transport (or transports) -and ``user`` to the Unix user on your server. Next, tell Supervisor to read your +and ``user`` to the Unix user on your server. + +If you use the Redis Transport, note that each worker needs a unique consumer name to +avoid the same message being handled by multiple workers. One way to achieve this is +to set an environment variable in the Supervisor configuration file, which you can +then refer to in `messenger.yaml` (see Redis section above): + +.. code-block:: ini + + environment=MESSENGER_CONSUMER_NAME=%(program_name)s_%(process_num)02d + +Next, tell Supervisor to read your config and start your workers: .. code-block:: terminal @@ -1209,9 +1220,13 @@ claim_interval Interval on which pending/abandoned ``60000`` (1 Minute) .. caution:: There should never be more than one ``messenger:consume`` command running with the same - config (stream, group and consumer name) to avoid having a message handled more than once. - Using the ``HOSTNAME`` as the consumer might often be a good idea. In case you are using - Kubernetes to orchestrate your containers, consider using a ``StatefulSet``. + combination of ``stream``, ``group`` and ``consumer``, or messages could end up being + handled more than once. If you run multiple queue workers, ``consumer` can be set to an + environment variable (like ``%env(MESSENGER_CONSUMER_NAME)%`)` set by Supervisor + (example below) or whatever service used to manage the worker processes. + In a container environment, the ``HOSTNAME`` can be used as the consumer name, since + there is only one worker per container/host. If using Kubernetes to orchestrate the + containers, consider using a ``StatefulSet`` to have stable names. .. tip:: From f0e6261484a12c68f8b500ac9495ccf602c13b38 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 28 Jan 2021 07:57:37 +0100 Subject: [PATCH 0429/5766] Remove experimental for UID Fix #14890 --- components/uid.rst | 15 +++++++-------- notifier.rst | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index a7fb95d5d2f..076946c7756 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -10,8 +10,7 @@ The UID Component .. versionadded:: 5.1 - The UID component was introduced in Symfony 5.1 as an - :doc:`experimental feature `. + The UID component was introduced in Symfony 5.1. Installation ------------ @@ -157,12 +156,12 @@ entity primary keys:: private $id; // ... - + public function getId(): ?Uuid { return $this->id; } - + // ... } @@ -287,7 +286,7 @@ There's also a Doctrine generator to help autogenerate ULID values for the entity primary keys:: use Symfony\Bridge\Doctrine\IdGenerator\UlidGenerator; - use Symfony\Component\Uid\Ulid; + use Symfony\Component\Uid\Ulid; /** * @ORM\Entity(repositoryClass="App\Repository\ProductRepository") @@ -303,14 +302,14 @@ entity primary keys:: private $id; // ... - + public function getId(): ?Ulid { return $this->id; } - + // ... - + } .. versionadded:: 5.2 diff --git a/notifier.rst b/notifier.rst index 7231080d47e..6845900b11b 100644 --- a/notifier.rst +++ b/notifier.rst @@ -16,7 +16,7 @@ the users (e.g. SMS, Slack messages, emails, push notifications, etc.). The Notifier component in Symfony is an abstraction on top of all these channels. It provides a dynamic way to manage how the messages are sent. Get the Notifier installed using: - +uid .. code-block:: terminal $ composer require symfony/notifier From 1c6c658627db640955982e8e2aad1265924e97b2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 28 Jan 2021 08:54:34 +0100 Subject: [PATCH 0430/5766] Removed unneeded text --- notifier.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 6845900b11b..7231080d47e 100644 --- a/notifier.rst +++ b/notifier.rst @@ -16,7 +16,7 @@ the users (e.g. SMS, Slack messages, emails, push notifications, etc.). The Notifier component in Symfony is an abstraction on top of all these channels. It provides a dynamic way to manage how the messages are sent. Get the Notifier installed using: -uid + .. code-block:: terminal $ composer require symfony/notifier From 5ff7cc7486530647a46951b6189bee23717f09f7 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 28 Jan 2021 09:06:50 +0100 Subject: [PATCH 0431/5766] Remove experimental mention in lowest branch Follows #14891 --- components/uid.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index 9a097a3e675..b0ba7259b87 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -10,8 +10,7 @@ The UID Component .. versionadded:: 5.1 - The UID component was introduced in Symfony 5.1 as an - :doc:`experimental feature `. + The UID component was introduced in Symfony 5.1. Installation ------------ From d0c1a24752df5048a3910e67985884da8a41e618 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 28 Jan 2021 09:15:02 +0100 Subject: [PATCH 0432/5766] [Uid] Document the getDateTime() method --- components/uid.rst | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index 076946c7756..adda64b8029 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -96,9 +96,9 @@ UUID objects created with the ``Uuid`` class can use the following methods $uuid = Uuid::v4(); $uuid instanceof UuidV4; // true - // getting the UUID time (it's only available in certain UUID types) + // getting the UUID datetime (it's only available in certain UUID types) $uuid = Uuid::v1(); - $uuid->getTime(); // e.g. float(1584111384.2613) + $uuid->getDateTime(); // returns a \DateTimeImmutable instance // comparing UUIDs and checking for equality $uuid1 = Uuid::v1(); @@ -111,6 +111,11 @@ 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) +.. versionadded:: 5.3 + + The ``getDateTime()`` method was introduced in Symfony 5.3. In previous + versions it was called ``getTime()``. + Storing UUIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -250,14 +255,19 @@ ULID objects created with the ``Ulid`` class can use the following methods:: // checking if a given value is valid as ULID $isValid = Ulid::isValid($ulidValue); // true or false - // getting the ULID time - $ulid1->getTime(); // e.g. float(1584111384.2613) + // getting the ULID datetime + $ulid1->getDateTime(); // returns a \DateTimeImmutable instance // comparing ULIDs and checking for equality $ulid1->equals($ulid2); // false // this method returns $ulid1 <=> $ulid2 $ulid1->compare($ulid2); // e.g. int(-1) +.. versionadded:: 5.3 + + The ``getDateTime()`` method was introduced in Symfony 5.3. In previous + versions it was called ``getTime()``. + Storing ULIDs in Databases ~~~~~~~~~~~~~~~~~~~~~~~~~~ From 1b61792e5e7ce891264f80b6c466efc3a0a7825b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 28 Jan 2021 09:20:38 +0100 Subject: [PATCH 0433/5766] [Uid] Mentioned the Uuid::NAMESPACE_* constants --- components/uid.rst | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/components/uid.rst b/components/uid.rst index 076946c7756..51f8b4021a2 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -53,11 +53,22 @@ to create each type of UUID:: $uuid = Uuid::v3($namespace, $name); // $uuid is an instance of Symfony\Component\Uid\UuidV3 $uuid = Uuid::v5($namespace, $name); // $uuid is an instance of Symfony\Component\Uid\UuidV5 + // the namespaces defined by RFC 4122 are available as constants + // (see https://tools.ietf.org/html/rfc4122#appendix-C) + $uuid = Uuid::v3(Uuid::NAMESPACE_DNS, $name); + $uuid = Uuid::v3(Uuid::NAMESPACE_URL, $name); + $uuid = Uuid::v3(Uuid::NAMESPACE_OID, $name); + $uuid = Uuid::v3(Uuid::NAMESPACE_X500, $name); + // UUID type 6 is not part of the UUID standard. It's lexicographically sortable // (like ULIDs) and contains a 60-bit timestamp and 63 extra unique bits. // It's defined in http://gh.peabody.io/uuidv6/ $uuid = Uuid::v6(); // $uuid is an instance of Symfony\Component\Uid\UuidV6 +.. versionadded:: 5.3 + + The ``Uuid::NAMESPACE_*`` constants were introduced in Symfony 5.3. + If your UUID is generated by another system, use the ``fromString()`` method to create an object and make use of the utilities available for Symfony UUIDs:: From 70fe3795c8bb33fcabe016f5a2a8c91cd158f803 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Thu, 28 Jan 2021 15:41:22 +0100 Subject: [PATCH 0434/5766] Mark semaphore exeperimental --- components/semaphore.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/components/semaphore.rst b/components/semaphore.rst index ebae3df89e8..614c38a6bd9 100644 --- a/components/semaphore.rst +++ b/components/semaphore.rst @@ -10,7 +10,8 @@ The Semaphore Component .. versionadded:: 5.2 - The Semaphore Component was introduced in Symfony 5.2. + The Semaphore Component was introduced in Symfony 5.2 as an + :doc:`experimental feature `. Installation ------------ From be512a89aa9fc34116b51d2ae8c1fce74ec88eca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Thu, 28 Jan 2021 19:20:54 +0100 Subject: [PATCH 0435/5766] Update documentation for deprecated session service --- components/http_foundation.rst | 3 +- controller.rst | 2 +- logging/processors.rst | 23 +++++++------ quick_tour/the_architecture.rst | 3 -- security/access_denied_handler.rst | 7 ++-- security/form_login_setup.rst | 10 +----- service_container.rst | 8 +---- session.rst | 55 +++++++++++++++++++++--------- session/locale_sticky_session.rst | 10 +++--- 9 files changed, 64 insertions(+), 57 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 23d8e9a6809..e00f9dabb7b 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -247,7 +247,8 @@ Accessing the Session ~~~~~~~~~~~~~~~~~~~~~ If you have a session attached to the request, you can access it via the -:method:`Symfony\\Component\\HttpFoundation\\Request::getSession` method; +:method:`Symfony\\Component\\HttpFoundation\\Request::getSession` method or the +:method:`Symfony\\Component\\HttpFoundation\\RequestStack::getSession` method; the :method:`Symfony\\Component\\HttpFoundation\\Request::hasPreviousSession` method tells you if the request contains a session which was started in one of diff --git a/controller.rst b/controller.rst index 212d0a2b509..a5017452832 100644 --- a/controller.rst +++ b/controller.rst @@ -394,7 +394,7 @@ Request object. Managing the Session -------------------- -Symfony provides a session service that you can use to store information +Symfony provides a session object that you can use to store information about the user between requests. Session is enabled by default, but will only be started if you read or write from it. diff --git a/logging/processors.rst b/logging/processors.rst index 8ba965327b2..c0a3eb33bbf 100644 --- a/logging/processors.rst +++ b/logging/processors.rst @@ -19,30 +19,33 @@ using a processor:: // src/Logger/SessionRequestProcessor.php namespace App\Logger; - use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException; + use Symfony\Component\HttpFoundation\RequestStack; class SessionRequestProcessor { - private $session; - private $sessionId; + private $requestStack; - public function __construct(SessionInterface $session) + public function __construct(RequestStack $requestStack) { - $this->session = $session; + $this->requestStack = $requestStack; } // this method is called for each log record; optimize it to not hurt performance public function __invoke(array $record) { - if (!$this->session->isStarted()) { + try { + $session = $requestStack->getSession(); + } catch (SessionNotFoundException $e) { + return; + } + if (!$session->isStarted()) { return $record; } - if (!$this->sessionId) { - $this->sessionId = substr($this->session->getId(), 0, 8) ?: '????????'; - } + $sessionId = substr($session->getId(), 0, 8) ?: '????????'; - $record['extra']['token'] = $this->sessionId.'-'.substr(uniqid('', true), -8); + $record['extra']['token'] = $sessionId.'-'.substr(uniqid('', true), -8); return $record; } diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst index d88bb5d32ed..e3b388a0bc4 100644 --- a/quick_tour/the_architecture.rst +++ b/quick_tour/the_architecture.rst @@ -72,9 +72,6 @@ What other possible classes or interfaces could you use? Find out by running: Request stack that controls the lifecycle of requests. Symfony\Component\HttpFoundation\RequestStack (request_stack) - Interface for the session. - Symfony\Component\HttpFoundation\Session\SessionInterface (session) - RouterInterface is the interface that all Router classes must implement. Symfony\Component\Routing\RouterInterface (router.default) diff --git a/security/access_denied_handler.rst b/security/access_denied_handler.rst index 42ee7fe5dd9..2a7566fafed 100644 --- a/security/access_denied_handler.rst +++ b/security/access_denied_handler.rst @@ -28,7 +28,6 @@ unauthenticated user tries to access a protected resource:: use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; - use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\Routing\Generator\UrlGeneratorInterface; use Symfony\Component\Security\Core\Exception\AuthenticationException; use Symfony\Component\Security\Http\EntryPoint\AuthenticationEntryPointInterface; @@ -36,18 +35,16 @@ unauthenticated user tries to access a protected resource:: class AuthenticationEntryPoint implements AuthenticationEntryPointInterface { private $urlGenerator; - private $session; - public function __construct(UrlGeneratorInterface $urlGenerator, SessionInterface $session) + public function __construct(UrlGeneratorInterface $urlGenerator) { $this->urlGenerator = $urlGenerator; - $this->session = $session; } public function start(Request $request, AuthenticationException $authException = null): RedirectResponse { // add a custom flash message and redirect to the login page - $this->session->getFlashBag()->add('note', 'You have to login in order to access this page.'); + $request->getSession()->getFlashBag()->add('note', 'You have to login in order to access this page.'); return new RedirectResponse($this->urlGenerator->generate('security_login')); } diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index c7ea359c459..1d269eba380 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -477,7 +477,6 @@ whenever the user browses a page:: namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; - use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpKernel\Event\RequestEvent; use Symfony\Component\HttpKernel\KernelEvents; use Symfony\Component\Security\Http\Util\TargetPathTrait; @@ -486,13 +485,6 @@ whenever the user browses a page:: { use TargetPathTrait; - private $session; - - public function __construct(SessionInterface $session) - { - $this->session = $session; - } - public function onKernelRequest(RequestEvent $event): void { $request = $event->getRequest(); @@ -504,7 +496,7 @@ whenever the user browses a page:: return; } - $this->saveTargetPath($this->session, 'main', $request->getUri()); + $this->saveTargetPath($request->getSession(), 'main', $request->getUri()); } public static function getSubscribedEvents() diff --git a/service_container.rst b/service_container.rst index e3db328033b..98fb5e61318 100644 --- a/service_container.rst +++ b/service_container.rst @@ -62,9 +62,6 @@ What other services are available? Find out by running: Request stack that controls the lifecycle of requests. Symfony\Component\HttpFoundation\RequestStack (request_stack) - Interface for the session. - Symfony\Component\HttpFoundation\Session\SessionInterface (session) - RouterInterface is the interface that all Router classes must implement. Symfony\Component\Routing\RouterInterface (router.default) @@ -80,7 +77,7 @@ in the container. .. tip:: There are actually *many* more services in the container, and each service has - a unique id in the container, like ``session`` or ``router.default``. For a full + a unique id in the container, like ``request_stack`` or ``router.default``. For a full list, you can run ``php bin/console debug:container``. But most of the time, you won't need to worry about this. See :ref:`services-wire-specific-service`. See :doc:`/service_container/debug`. @@ -283,9 +280,6 @@ type-hints by running: Request stack that controls the lifecycle of requests. Symfony\Component\HttpFoundation\RequestStack (request_stack) - Interface for the session. - Symfony\Component\HttpFoundation\Session\SessionInterface (session) - RouterInterface is the interface that all Router classes must implement. Symfony\Component\Routing\RouterInterface (router.default) diff --git a/session.rst b/session.rst index 394cfece78b..3ccf47460b6 100644 --- a/session.rst +++ b/session.rst @@ -127,25 +127,26 @@ Check out the Symfony config reference to learn more about the other available Basic Usage ----------- -Symfony provides a session service that is injected in your services and +The sessions is available througth the Request and the RequestStack. +Symfony provides a request_stack service that is injected in your services and controllers if you type-hint an argument with -:class:`Symfony\\Component\\HttpFoundation\\Session\\SessionInterface`:: +:class:`Symfony\\Component\\HttpFoundation\\RequestStack`:: - use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\HttpFoundation\RequestStack; class SomeService { - private $session; + private $requestStack; - public function __construct(SessionInterface $session) + public function __construct(RequestStack $requestStack) { - $this->session = $session; + $this->requestStack = $requestStack; } public function someMethod() { // stores an attribute in the session for later reuse - $this->session->set('attribute-name', 'attribute-value'); + $this->requestStack->getSession()->set('attribute-name', 'attribute-value'); // gets an attribute by name $foo = $this->session->get('foo'); @@ -157,10 +158,10 @@ controllers if you type-hint an argument with } } -.. tip:: +.. deprecated:: 5.3 - Every ``SessionInterface`` implementation is supported. If you have your - own implementation, type-hint this in the argument instead. + The ``SessionInterface`` and ``session`` service are deprecated since + Symfony 5.3. Inject a request stack instead. Stored attributes remain in the session for the remainder of that user's session. By default, session attributes are key-value pairs managed with the @@ -175,22 +176,44 @@ class. If your application needs are complex, you may prefer to use :ref:`namespaced session attributes ` which are managed with the :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag` -class. Before using them, override the ``session`` service definition to replace -the default ``AttributeBag`` by the ``NamespacedAttributeBag``: +class. Before using them, override the ``session_listener`` service definition to build +your ``Session`` object with the default ``AttributeBag`` by the ``NamespacedAttributeBag``: .. configuration-block:: .. code-block:: yaml # config/services.yaml - session: - public: true - class: Symfony\Component\HttpFoundation\Session\Session - arguments: ['@session.storage', '@session.namespacedattributebag'] + session_listener: + autoconfigure: true + class: App\EventListener\SessionListener + arguments: + - !service_locator + logger: '@?logger' + session_collector: '@?data_collector.request.session_collector' + session_storage: '@session.storage' + session_attributes: '@session.namespacedattributebag' + - '%kernel.debug%' session.namespacedattributebag: class: Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag +.. code-block:: php + + namespace App\EventListener; + + use Symfony\Component\HttpFoundation\Session\Session; + use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener; + + class SessionListener extends AbstractSessionListener + { + protected function getSession(): ?SessionInterface + { + return new Session($this->container->get('session_storage'), $this->container->get('session_attributes')); + } + } + .. _session-avoid-start: Avoid Starting Sessions for Anonymous Users diff --git a/session/locale_sticky_session.rst b/session/locale_sticky_session.rst index 056f2a674cb..13d620381aa 100644 --- a/session/locale_sticky_session.rst +++ b/session/locale_sticky_session.rst @@ -146,7 +146,7 @@ event:: namespace App\EventSubscriber; use Symfony\Component\EventDispatcher\EventSubscriberInterface; - use Symfony\Component\HttpFoundation\Session\SessionInterface; + use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; use Symfony\Component\Security\Http\SecurityEvents; @@ -156,11 +156,11 @@ event:: */ class UserLocaleSubscriber implements EventSubscriberInterface { - private $session; + private $requestStack; - public function __construct(SessionInterface $session) + public function __construct(RequestStack $requestStack) { - $this->session = $session; + $this->requestStack = $requestStack; } public function onInteractiveLogin(InteractiveLoginEvent $event) @@ -168,7 +168,7 @@ event:: $user = $event->getAuthenticationToken()->getUser(); if (null !== $user->getLocale()) { - $this->session->set('_locale', $user->getLocale()); + $this->requestStack->getSession()->set('_locale', $user->getLocale()); } } From 98ebace2ecae3d409ce8e229b066fd9da21f5cd9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2021 10:04:23 +0100 Subject: [PATCH 0436/5766] Tweak --- session.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/session.rst b/session.rst index 3ccf47460b6..da265d739b9 100644 --- a/session.rst +++ b/session.rst @@ -160,8 +160,9 @@ controllers if you type-hint an argument with .. deprecated:: 5.3 - The ``SessionInterface`` and ``session`` service are deprecated since - Symfony 5.3. Inject a request stack instead. + The ``SessionInterface`` and ``session`` service were deprecated in + Symfony 5.3. Instead, inject the ``RequestStack`` service to get the session + object of the current request. Stored attributes remain in the session for the remainder of that user's session. By default, session attributes are key-value pairs managed with the From 8673801703a7ca8625357234a43e645bb9c49d6b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2021 10:16:07 +0100 Subject: [PATCH 0437/5766] Added the versionadded directive --- console/coloring.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/console/coloring.rst b/console/coloring.rst index 9412511e11f..7e77a090b25 100644 --- a/console/coloring.rst +++ b/console/coloring.rst @@ -54,6 +54,10 @@ Any hex color is supported for foreground and background colors. Besides that, t True (hex) color support was introduced in Symfony 5.2 +.. versionadded:: 5.3 + + Support for bright colors was introduced in Symfony 5.3. + .. note:: If the terminal doesn't support true colors, the nearest named color is used. From 9d03c8f616eb9b9b473a51c7e8c0647e616a440f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 29 Jan 2021 10:19:15 +0100 Subject: [PATCH 0438/5766] [Semaphore] The component is no longer experimental in Symfony 5.3. --- components/semaphore.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/semaphore.rst b/components/semaphore.rst index 614c38a6bd9..ebae3df89e8 100644 --- a/components/semaphore.rst +++ b/components/semaphore.rst @@ -10,8 +10,7 @@ The Semaphore Component .. versionadded:: 5.2 - The Semaphore Component was introduced in Symfony 5.2 as an - :doc:`experimental feature `. + The Semaphore Component was introduced in Symfony 5.2. Installation ------------ From 36a5c1a2820bdcd9bd3aa65bb2774d99228c0495 Mon Sep 17 00:00:00 2001 From: Jon Green Date: Sun, 3 Jan 2021 17:22:23 +0000 Subject: [PATCH 0439/5766] [String] Feature 39178 Documentation update for [String] Feature 39178 "AsciiSlugger's symbolsMap should apply to all locales for a language". --- components/string.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/components/string.rst b/components/string.rst index 97988fc0970..48f17f0b3e9 100644 --- a/components/string.rst +++ b/components/string.rst @@ -477,6 +477,12 @@ that only includes safe ASCII characters:: $slug = $slugger->slug('10% or 5€'); // $slug = '10-percent-or-5-euro' + // if there is no symbols map for your locale (e.g. 'en_GB') then the parent locale's symbols map + // will be used instead (i.e. 'en') + $slugger = new AsciiSlugger('en_GB', ['en' => ['%' => 'percent', '€' => 'euro']]); + $slug = $slugger->slug('10% or 5€'); + // $slug = '10-percent-or-5-euro' + // for more dynamic substitutions, pass a PHP closure instead of an array $slugger = new AsciiSlugger('en', function ($string, $locale) { return str_replace('❤️', 'love', $string); @@ -490,6 +496,10 @@ that only includes safe ASCII characters:: The feature to use a PHP closure to define substitutions was introduced in Symfony 5.2. +.. versionadded:: 5.3 + + The feature to fallback to the parent locale's symbols map was introduced in Symfony 5.3. + The separator between words is a dash (``-``) by default, but you can define another separator as the second argument:: From 584396620e9a269f63493ada18e372941d123a42 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 29 Jan 2021 14:22:21 +0100 Subject: [PATCH 0440/5766] Fix Connect URL --- contributing/documentation/overview.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing/documentation/overview.rst b/contributing/documentation/overview.rst index be7d3418c6e..460f1b62589 100644 --- a/contributing/documentation/overview.rst +++ b/contributing/documentation/overview.rst @@ -338,7 +338,7 @@ definitely don't want you to waste your time! .. _`GitHub`: https://github.com/ .. _`fork the repository`: https://help.github.com/github/getting-started-with-github/fork-a-repo .. _`Symfony Documentation Contributors`: https://symfony.com/contributors/doc -.. _`SymfonyConnect`: https://connect.symfony.com/ +.. _`SymfonyConnect`: https://symfony.com/connect/login .. _`Symfony Documentation Badge`: https://connect.symfony.com/badge/36/symfony-documentation-contributor .. _`SymfonyCloud`: https://symfony.com/cloud .. _`roadmap`: https://symfony.com/releases From 1cdb6cb9079f5c0e2b709ab90294b08218b50831 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 17 Oct 2020 15:19:01 +0200 Subject: [PATCH 0441/5766] Added limiter diagrams --- _images/rate_limiter/fixed_window.svg | 84 ++++++++++++++++++ _images/rate_limiter/sliding_window.svg | 65 ++++++++++++++ _images/rate_limiter/token_bucket.svg | 83 +++++++++++++++++ _images/sources/rate_limiter/fixed_window.dia | Bin 0 -> 2356 bytes .../sources/rate_limiter/sliding_window.dia | Bin 0 -> 2190 bytes _images/sources/rate_limiter/token_bucket.dia | Bin 0 -> 2752 bytes rate_limiter.rst | 52 +++++++++-- 7 files changed, 275 insertions(+), 9 deletions(-) create mode 100644 _images/rate_limiter/fixed_window.svg create mode 100644 _images/rate_limiter/sliding_window.svg create mode 100644 _images/rate_limiter/token_bucket.svg create mode 100644 _images/sources/rate_limiter/fixed_window.dia create mode 100644 _images/sources/rate_limiter/sliding_window.dia create mode 100644 _images/sources/rate_limiter/token_bucket.dia diff --git a/_images/rate_limiter/fixed_window.svg b/_images/rate_limiter/fixed_window.svg new file mode 100644 index 00000000000..83d5f6e79ac --- /dev/null +++ b/_images/rate_limiter/fixed_window.svg @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + 10:00 + + + 10:30 + + + 11:00 + + + 11:30 + + + 12:00 + + + + + + + + 12:30 + + + 13:00 + + + + + + + + + + + + + + + + + + + + + + 1 hour window + + + 1 hour window + + + + + + 1 hour window + + + + + 13:15 + + + diff --git a/_images/rate_limiter/sliding_window.svg b/_images/rate_limiter/sliding_window.svg new file mode 100644 index 00000000000..2c565615441 --- /dev/null +++ b/_images/rate_limiter/sliding_window.svg @@ -0,0 +1,65 @@ + + + + + + + + + + 10:00 + + + 10:30 + + + 11:00 + + + 11:30 + + + 12:00 + + + + + + 12:30 + + + 13:00 + + + + + + + + + + + + + + + + + + + + + + 1 hour window + + + + + + 13:15 + + + + + + diff --git a/_images/rate_limiter/token_bucket.svg b/_images/rate_limiter/token_bucket.svg new file mode 100644 index 00000000000..29d6fc8f103 --- /dev/null +++ b/_images/rate_limiter/token_bucket.svg @@ -0,0 +1,83 @@ + + + + 10:00 + + + 10:30 + + + 11:00 + + + 11:30 + + + 12:00 + + + + + + + + 12:30 + + + 13:00 + + + + + + + + + + + + + + + + + + + + + + + + + + + 13:15 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_images/sources/rate_limiter/fixed_window.dia b/_images/sources/rate_limiter/fixed_window.dia new file mode 100644 index 0000000000000000000000000000000000000000..16282a2dcce2dc3cf58a40be13992366c2a10f48 GIT binary patch literal 2356 zcmV-43Cs2$iwFP!000021MQt#liD~I$KUfQT;#ReSQp>Y=}ygT)$BfO?WQW3=PrTO z;2C2xwrRpV>}OxuTpElG23hKuI#eYAB6KYI==VRCb>z=qe#|1{m8V&l#E%1HS_6Z} z<0J^<$>ZSn@4wx9gD+1XJ_jNDB>qfNHZ#O8;;i`eIGE=7{L^r_TrSOMm9acY%_v-$ z86Wic8q{$)<2J2Fra^oaQ zQsb3HkAsgdo7Z5tsc3jm(}~*WY{Ew=XMZ+VZi$!gUsw5@r`3vQ^CSyJk$g2jD$-C- z@%LVtO{q*2iYHGWf1w}OhqU?Pt**KQZ8Vb4SUL&gV>_aEqIFkb)592x?y!B&w_NI? zZJ%6jZlu>-q}N=k*IbxA&yzGyS(qQ293@G_S-iIT!lH~{ZzvnHNch;Pc1bkjCCu}r zqXw+M-VL`)hwdZ|gVQ7TphQD0!Akraj@6!%Wfi5qx!R{ZoJ{i*)n8ZlC`kjJo;!BSMArI+sBadA zb(xU@0M9j-f9J>jC00Z{%b&A+74fP89xrC=+Ua#w&sh*0M$1R%<4RY``Hy^XCN8Oz zY3k(iqVb?y<@&PW>hc86o5K4f&g%>n-y1I?P>xpOcvzebjPiVxtXu!|Up#u{c{pbK zY`^>njs{=tIq|H+7nL)5NZ~qcQEU>|zN03k)NB_=J6JP38uAfa+iYNencpCF$gpCF$d$tQ74 z5KrymiDktTJF2A<+or#fPHbArrBkXwAe0=WGHr)uDTxmABI@shKu*vHen=r&p8rkFmn|i^ffAVC;#jnN!PG5QY zQvA=izZNXzHJI|`?y~zDtYFUKr*J|+xiq(JEv`ZN}WH#`jlR-okP+IQIu$a6U7H` zqWyvsfyHwg;Y0vVx3_o>$tOp78s<*D-Q1~v3v;I)%$>reGh8~urL*cw=YNZHR=0bl zblMp%(|jCL^-dzf1hpTiYm&m)mDY-#w4Zq#9Bl*MqE$74kSo=6F;>R&>M_(kOyK>& z*^#rk-RxWAsNL=j-xXWFJ&1S31(BuP)v9f3D&m5hwR5vB@<7~TU}MFJAZ}r!*cr(a zZ#>n0R@12FQZ7KPrMLOrYn_7oc{5n>iia9o7IfZwoa~57fL?Q1bw4mwB7p&4NyqP%A8~p(fsGf!a}< znu-9_TDqC^jRJ}^K&>!RLQTBU0kyhDHJ1XYwe>c?n}wiCp+n{oh>tB001yD}0?^T37)1F_7-jVD+(7g%)nNdCi2eco0RL{_PrAwGB+7F+ zOZfY@0DlkQ5AcV`AK?Ekn;;SS2QT|~*44N3+NL}a&mnjBmWe%zy>jWcgNS=4Xw#Fe zMvSQ#_r@}egJcO?j_7&@bJaCrzmZ;UhD797D>|mF8dHRrUIkOWi4gGsQ-GQ$^@4JXM6iQ$^r%8s<{ra{4EjOLe_7^0`{;|}Zrn`uBa`fdM<%&_dt?%_A>h&#a5?bEq@OP0T7Qn% ail)*r;5Ny=tVAN~(zH@RP^pI)w3?7e? zAdJTky+6NwzN5X5k2fEJki8dw#wnW`;u~>Re0u0j@_hEb-(M^iX0*&$o}^|J&drSX z|7B6c`l3+3_jqF%yA=d1XT`PkRhH*zIGpF)h}o1s^oDHoeViuqIOwfPt;>y)C`pZH z7CrRdJ*{88{<@<6UQMsmK4W7(OgZ~rU%4e-zJFQeGoBt+Je?(3D2n9E*-??2dWyey z%B)LeqEI}3eD@Q1x4NbEg_pXjZnRcNK4s}RjF07r-icOSVVl&pZP6W$PkqZH9@_Lt zb8$nx;v&7`QoZ8BY%ojGJY`{iEOMA65ohsA>Jy7Hez~A*#3G?%ueD2}8BbxJCoMH# zb$L77nhxD@8V0YA+`SStwFFD?Z#Yu>Ocr5~PX<3;dnT4?JF)_n>I6K8SvZV%RU5)M zmsYDy^~-juKU9R$R=j*&Qt?)`)f%IKa)&#Y7^Cq#40v`zr}xX$)HGQa>!0fP!*Y^c z6NK3;V$0W?a9F6OE*9sZKpD$;pqQ93o89Hf-2pDDB<1P61wqO1FFwlEikc(~4Gk)! zjFLDO%@N+{-7FEKHPdV!R+kPu)l#fbGM=t)_0x-wYOHCqZoRQ?0Nc65M0=h$pLX

                  ^@POa0-qFbJ>flzQUI2+@d{l z*Y#GNfZ_14{ZA_gj zQT2p}<4N9n-NPgeczWu_EfZO*7b3oekc;fg#Dzkm)4{%>s+yDq!P9W~Vyc=6DMtUG zV(xdEGfkujXO<7Ld>QdW0X&{hSGAMNs-CeR*msqWp2vk+n)4rd?}SrwP^PYv%NgTd zxr51N&D8Q0me=|ANt{;+Dy|z(!b^^p;(l11^^Ed)l$=|A^;aG}^E@1}U9LC3gQLM$ z`An#_{~~fi_X%8yEG&>kOhSm|%E>w$k+rKCmbE)7FA*hNr*S;x)sOUL=%6#DR9fRY z*RcO$E9;EsS7CwzmIlIhek%sT&WhIBcp_QjX*0pc4|9^BK>%C>^<;RzA##ez5<9C*($>NwKKPU4v_KR0o^9JvRAWV-p58X=4)wHeCsuu=Jt>(!eHc?Xn5m z-C`30zeyjPs`L@q)JZlGX*LlZY{GkNa=OMQ@SF6pi2$3fgiVe#n>-zCa`)IoyTv9O z{3eZT@_3c0 zMxJ-;m>2Gxik@Mo_!NYrT;-m%WS5<@XKk6j>v@6;*dY{C4^gUc7aN%eduYDI=B%zw z?NV65ocXJp+Q%enBIGHIqBDdH?SSwr*g3b3Lc}V=L>u*B6wU^dBn|%&c9=!4Htrx6 zsIeG9$70u6nUHKgEaGW-@8V8so&R17F-4wg{tFrIn*Ye8o#($~mtDkvLUi(<0RMsi z!2b^LpGx!JQSbi?85{rKy#oJVvde(~z<=OB@c;6)XsK?Pr`VDVyC+%95*6 z)r5pw$Ml_h@vg9kmU2})Y*Sqk57g{DHIt6;w%uYs!&RJpB7_t&iljIy-cZ$gR?(>X zQXW9

                    3WvpyqF&=Ieo)e-_kyfLb$cbK6Oh zQVF#}!U}5QoffDawW+QMKVO*EK#l5w8a)eY6rk2j+w6AYc~nBJkg$T9c&7zwM{TMr0#G|s&7?O9 z2+{zxLP!ZU@kR&Ksv1>a3ZQnbwvl$?fRsWFZ=r@YK@FdV8V0CclnP-x?c_pZ<(bg7 z>2EWkiHW+N35_8S0`edr4+8Qa-Y^f&cH2pW#>&&6OZczTpgRqJsSdjc{s^grKd>HH z53KJ3>%Df8p0VO1wg?uOVN1nQyBadwF8jd`5;mA`k05Agp1Mo&i9%1>w&*Eo0 zt&0OV&RyZB)Wx@VmT6OBQ>SqM5yDjX&Q?dx7BMDbw`{s4b~|C_^KJ~71Cu;J!!Hr$AH4I6GgY`B2|00RI9K-vJTK1XcH)5n|D2k~c| QvgzZ^e}s1x_UWns01%r;Gynhq literal 0 HcmV?d00001 diff --git a/_images/sources/rate_limiter/token_bucket.dia b/_images/sources/rate_limiter/token_bucket.dia new file mode 100644 index 0000000000000000000000000000000000000000..16761971337dbf6890ce0d2255b6d7c75bb125ca GIT binary patch literal 2752 zcmY+Gc{r47AIE1A<20DYiENpWNjb%sv4pHKI@XjD(#RxCwqjl;jAR|tv6RWKWF0Y4 zwhWF$gpoaa_MFCGQ1%y{^Iqq@|9P(K{@u_0``(}L_qne}ngRjr4G@@}=5TlX!{Knw z%oWR4_7S?yGNyFZCca=&{t2PSw8#PETv!+z30qYc-5BiBhwwn4%Y0aWZA_`^;JksF zF(<1laDA5M7;HW<;{LQP3++Ff5Yod5Yd#@m+&uYgr&v0e$z88K7qpI-JmC0#)I`LT zG_Dr!zu0B4bDZVk$l;8RjPNdQXnp7+z>Fz>YE|#ZMox@fM^|xlg63A{q+&v~PF%NR zick8B2#EUk|Ng-BM~5_T)+o}p3fs6<(o-;eg4$L1UA#ePi^ZZBZ*LW3ZM;l>w0!QM z{1>Hzp`$`XkEk=FwS`>Ur))p1v}`UG-8||-G80_3-n4Tsb;F2K&-9(pOl z7a&$k*)fu3W;ENO+a1$`j&7J10^i^Ts{c}15O2%ENvcwhUGQ-&FQ^K>(zR72t7!Xb z&DW&q6iE}3^-6T$Ss;ImJmt1zyUxN_wklshfGy_j&g~K6pow{#dNON#Z0iTiPeN+; z6m|)VwN(;oNDb`kJZa?v>>*p> zzvy_Wipq22Z4vVxopPQfHq|2}k?;JA8wNY&(oBvXinAsAp=9~xXvz#HY$8&r@Z02> zuQHVS!uc;VwFxw(K*I-_zN zfHKL!aht^DDX#CB@0AY|I$v;$9`#Mx4KUBCdWHpheR^^xQU6{g>X0jb33?*oZMJF9 z;NvL0q!@(+KKxub%E}h+WLS$*rWcvUl>MFrnNMm}unyJKPr8U>DHbtWfQ9ZQ}?W-EXztVVwU#%Y(f8zW(o#e1M$?~fJ=CB6gw2RsbGj-A4%?z2O*FuguDn0w zkBk+I)fJj6)$xJr07?L81(3I*lX5r_h8l*#j8db4&SP&ffF-58yky`Fz>&;{z;ra2 z0QM#;l{^Bco^JTRQjIt-Oc;vrpEvIFBPXFJC$_x z+=}YQ+#qD4g|=db%)Q1X1$`IxGw$en7aQv!`o*BHD!1?X&o+HZ)kVhqs#@bstZPsk z!IwqXD_Y=CBd1Q?ZOIg$53{d)Mxo%*gMp%EQ~5>3snOL`dcNZX;mJ{J&YjiH!CAFM zvqK`v!y~;)c?K_sC=uH`Gj~o3MpnG%%UZi1dCJu5ZQkR_C{|yI@7uxcJVA`l7q{HX zId{QwtKO#nM3~uq7sGyWBj3D3583D|S&7NxnpI)cEA@?S z5D6WVe)WfJEl=5Be1umHrZ7cR2V)tZb0H}LIL&uGdC3FXRbg!}AGTp+3G*iP)B64G zT-BT#GgoUF{<}J${3*ofJ#{MfRC@DLw;~}dE}IeMX$rCH$`pL_fRQ$Tr!$2wbyl>j z-bjHkt|?pJt5je>MG%lx$yxHom&zHhF7!VY!`(#kON25Ul2?r#Fg*!Rryc0{6*>8B z+bb61;NJB)6BsE@}K(%nsYq0`XFo+C5cpZdgx~=luGX{Os4ne`MviV(vq8!LrQ-nmt@=*>(l}{x%?n(~xu3StE-+QYwe}g+@EK)!Vb*SnJc=43=C%Y9 zTPJHYkyACA9|Cpg;%axh|C2K9HneJk@hHF3QxQdV8_Fs0*34@hu5=q}y=+p` z+&c;Yk{3cQ<^@&B0&Cjew@E(B>2{NF(TbKMak_W2|&y+*;6r0ae>hR|@|-wgnALm&bbjU!7!w1LD@d(0($}!A89X^HFx4;7k>O_Vo-F$wDR;n=Ym*4I)l#2VO zl>Pu|W6g%ajIfuB;}S_Ab~yRpFqWfm$6D59fjDP}*EHW_@Yu9}d_4|h{Dy&bR3k0* zZ&V^J^)iP^pxxVQFGB!CCNIcP?+_9EQSW}Kq%(0>?M)5HJ}o;k;4&CE90zcu#TV@Z z&U%dA&%;k14Tf^Mb8!H+t{nO9PaO6Vpe5FFsTlz}m_o(n3QN3GRSgIJ4+bKWr14>d z0M$(EKT`He8M-H+?l;{!D=^SW298+4lKl|yIv?22%!QNb)6Y(7h?ac-0LZTFUF>2QFQ=|r-nO`hk=6rWS sZe+aRi%1#x{%58u2%2JfFC4w~M@EZu!`^?Rw9b|g99k(euLlJD7hTW&ssI20 literal 0 HcmV?d00001 diff --git a/rate_limiter.rst b/rate_limiter.rst index 63e073a1e92..1d54faba331 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -28,22 +28,44 @@ Fixed Window Rate Limiter ~~~~~~~~~~~~~~~~~~~~~~~~~ This is the simplest technique and it's based on setting a limit for a given -interval of time. For example: 5,000 requests per hour or 3 login attempts -every 15 minutes. +interval of time (e.g. 5,000 requests per hour or 3 login attempts every 15 +minutes). + +In the diagram below, the limit is set to "5 tokens per hour". Each window +starts at the first hit (i.e. 10:15, 11:30 and 12:30). As soon as there are +5 hits (the blue squares) in a window, all others will be rejected (red +squares). + +.. raw:: html + + Its main drawback is that resource usage is not evenly distributed in time and -it can overload the server at the window edges. In the previous example, a user -could make the 4,999 requests in the last minute of some hour and another 5,000 -requests during the first minute of the next hour, making 9,999 requests in -total in two minutes and possibly overloading the server. These periods of -excessive usage are called "bursts". +it can overload the server at the window edges. In the previous example, +there are 6 accepted requests between 11:00 and 12:00. + +This is more significant with bigger limits. For instance, with 5,000 requests +per hour, a user could make the 4,999 requests in the last minute of some +hour and another 5,000 requests during the first minute of the next hour, +making 9,999 requests in total in two minutes and possibly overloading the +server. These periods of excessive usage are called "bursts". Sliding Window Rate Limiter ~~~~~~~~~~~~~~~~~~~~~~~~~~~ The sliding window algorithm is an alternative to the fixed window algorithm -designed to reduce bursts. To do that, the rate limit is calculated based on -the current window and the previous window. +designed to reduce bursts. This is the same example as above, but then +using a 1 hour window that slides over the timeline: + +.. raw:: html + + + +As you can see, this removes the edges of the window and would prevent the +6th request at 11:45. + +To achieve this, the rate limit is approximated based on the current window and +the previous window. For example: the limit is 5,000 requests per hour; a user made 4,000 requests the previous hour and 500 requests this hour. 15 minutes in to the current hour @@ -66,6 +88,18 @@ continuously updating budget of resource usage. It roughly works like this: * If the bucket still contains tokens, the event is allowed; otherwise, it's denied; * If the bucket is at full capacity, new tokens are discarded. +The below diagram shows a token bucket of size 4 that is filled with a rate +of 1 token per 15 minutes: + +.. raw:: html + + + +This algorithm handles more complex back-off algorithm to manage bursts. +For instance, it can allow a user to try a password 5 times and then only +allow 1 every 15 minutes (unless the user waits 75 minutes and they will be +allowed 5 tries again). + Installation ------------ From dab721b1c22f3d6dbdc0bcdaed9252fa8fcfa450 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Fri, 29 Jan 2021 19:33:12 +0100 Subject: [PATCH 0442/5766] [Console] Update comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The info() method was introduced in Symfony 5.2. I updated comments that were probably copied from the success() method example. --- console/style.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/console/style.rst b/console/style.rst index a8cdad20004..66db35011b1 100644 --- a/console/style.rst +++ b/console/style.rst @@ -331,12 +331,12 @@ Result Methods It's meant to be used once to display the final result of executing the given command, without showing the result as a successful or failed one:: - // use simple strings for short success messages + // use simple strings for short info messages $io->info('Lorem ipsum dolor sit amet'); // ... - // consider using arrays when displaying long success messages + // consider using arrays when displaying long info messages $io->info([ 'Lorem ipsum dolor sit amet', 'Consectetur adipiscing elit', From 5c64519c3e3e75abfa37fed52626f6a6d2c492e9 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 30 Jan 2021 15:56:52 +0100 Subject: [PATCH 0443/5766] Fixed image path --- rate_limiter.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index 1d54faba331..4b6fc27d4ab 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -38,7 +38,7 @@ squares). .. raw:: html - + Its main drawback is that resource usage is not evenly distributed in time and it can overload the server at the window edges. In the previous example, @@ -59,7 +59,7 @@ using a 1 hour window that slides over the timeline: .. raw:: html - + As you can see, this removes the edges of the window and would prevent the 6th request at 11:45. @@ -93,7 +93,7 @@ of 1 token per 15 minutes: .. raw:: html - + This algorithm handles more complex back-off algorithm to manage bursts. For instance, it can allow a user to try a password 5 times and then only From 78e5a5dc084f50ffad3a928798923d70f2693a18 Mon Sep 17 00:00:00 2001 From: wkania <57155526+wkania@users.noreply.github.com> Date: Sun, 31 Jan 2021 13:59:10 +0100 Subject: [PATCH 0444/5766] [Validator] Use seealso instead of tip for File In other constraints when there is a suggestion to use another constraint: https://symfony.com/doc/4.4/reference/constraints/Unique.html https://symfony.com/doc/4.4/reference/constraints/UniqueEntity.html https://symfony.com/doc/4.4/reference/constraints/Collection.html --- reference/constraints/File.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst index 8c77fb008cb..a865349f913 100644 --- a/reference/constraints/File.rst +++ b/reference/constraints/File.rst @@ -11,7 +11,7 @@ Validates that a value is a valid "file", which can be one of the following: This constraint is commonly used in forms with the :doc:`FileType ` form field. -.. tip:: +.. seealso:: If the file you're validating is an image, try the :doc:`Image ` constraint. From 891f771ca9bb5356ca4aea8a4a84b69a77124fd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dan=20Michael=20O=2E=20Hegg=C3=B8?= Date: Sun, 31 Jan 2021 17:43:45 +0100 Subject: [PATCH 0445/5766] [http_client] Fix default headers --- http_client.rst | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/http_client.rst b/http_client.rst index 91122c00961..c7f31ec40f6 100644 --- a/http_client.rst +++ b/http_client.rst @@ -511,9 +511,10 @@ requests and the specific headers for each request: # config/packages/framework.yaml framework: - http_client: - headers: - 'User-Agent': 'My Fancy App' + default_options: + http_client: + headers: + 'User-Agent': 'My Fancy App' .. code-block:: xml @@ -528,7 +529,9 @@ requests and the specific headers for each request: - My Fancy App + + My Fancy App + @@ -538,8 +541,10 @@ requests and the specific headers for each request: // config/packages/framework.php $container->loadFromExtension('framework', [ 'http_client' => [ - 'headers' => [ - 'User-Agent' => 'My Fancy App', + 'default_options' => [ + 'headers' => [ + 'User-Agent' => 'My Fancy App', + ], ], ], ]); From 141a7234193c1887cec9aff680c8dce0bc455a46 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Thu, 21 Jan 2021 12:20:48 +0100 Subject: [PATCH 0446/5766] Update care team members --- contributing/code_of_conduct/care_team.rst | 27 ++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/contributing/code_of_conduct/care_team.rst b/contributing/code_of_conduct/care_team.rst index 8f32d5befd1..f0120fe7115 100644 --- a/contributing/code_of_conduct/care_team.rst +++ b/contributing/code_of_conduct/care_team.rst @@ -23,17 +23,36 @@ Here are all the members of the CARE team (in alphabetic order). You can contact any of them directly using the contact details below or you can also contact all of them at once by emailing **care@symfony.com**: -* **Emilie Lorenzo** +* **Timo Bakx** - * *E-mail*: emilie.lorenzo [at] symfony.com - * *Twitter*: `@EmilieLorenzo `_ - * *SymfonyConnect*: `emilielorenzo `_ + * *E-mail*: timobakx [at] gmail.com + * *Twitter*: `@TimoBakx `_ + * *SymfonyConnect*: `timobakx `_ + * *SymfonySlack*: `@Timo Bakx `_ + +* **Zan Baldwin** + + * *E-mail*: hello [at] zanbaldwin.com + * *Twitter*: `@ZanBaldwin `_ + * *SymfonyConnect*: `zanbaldwin `_ + +* **Valentine Boineau** + + * *E-mail*: valentine.boineau [at] gmail.com + * *Twitter*: `@BoineauV `_ + +* **Magali Milbergue** + + * *E-mail*: magali.milbergue [at] gmail.com + * *Twitter*: `@magalimilbergue `_ + * *SymfonyConnect*: `magali_milbergue `_ * **Tobias Nyholm** * *E-mail*: tobias.nyholm [at] gmail.com * *Twitter*: `@tobiasnyholm `_ * *SymfonyConnect*: `tobias `_ + * *SymfonySlack*: `@Tobias Nyholm `_ About the CARE Team ------------------- From 79a2112445af415940e317284b59572b3bad6e18 Mon Sep 17 00:00:00 2001 From: Albert Casademont Date: Mon, 1 Feb 2021 17:24:47 +0100 Subject: [PATCH 0447/5766] Docs for the new SYMFONY_PHPUNIT_REQUIRE env variable Code PR: https://github.com/symfony/symfony/pull/40059 --- components/phpunit_bridge.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/components/phpunit_bridge.rst b/components/phpunit_bridge.rst index dedb70c20d3..871b7035f9d 100644 --- a/components/phpunit_bridge.rst +++ b/components/phpunit_bridge.rst @@ -930,6 +930,18 @@ If you have installed the bridge through Composer, you can run it by calling e.g then set the ``SYMFONY_PHPUNIT_REMOVE`` env var to ``symfony/yaml``. It's also possible to set this env var in the ``phpunit.xml.dist`` file. + +.. tip:: + + It is also possible to require additional packages that will be installed along + the rest of the needed PHPUnit packages using the ``SYMFONY_PHPUNIT_REQUIRE`` + env variable. This is specially useful for installing PHPUnit plugins without + having to add them to your main ``composer.json`` file. + +.. versionadded:: 5.3 + + The ``SYMFONY_PHPUNIT_REQUIRE`` env variable was introduced in + Symfony 5.3. Code Coverage Listener ---------------------- From f1c43df622f32546b1d9f17ba97a32689438b8b0 Mon Sep 17 00:00:00 2001 From: Zan Baldwin Date: Mon, 1 Feb 2021 20:38:36 +0100 Subject: [PATCH 0448/5766] Add Slack Link to CARE Team Member --- contributing/code_of_conduct/care_team.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/contributing/code_of_conduct/care_team.rst b/contributing/code_of_conduct/care_team.rst index f0120fe7115..d740fcfbba4 100644 --- a/contributing/code_of_conduct/care_team.rst +++ b/contributing/code_of_conduct/care_team.rst @@ -35,6 +35,7 @@ of them at once by emailing **care@symfony.com**: * *E-mail*: hello [at] zanbaldwin.com * *Twitter*: `@ZanBaldwin `_ * *SymfonyConnect*: `zanbaldwin `_ + * *SymfonySlack*: `@Zan `_ * **Valentine Boineau** From 1bb5c085463299c25a10c1007e4d5a5bc443b7d6 Mon Sep 17 00:00:00 2001 From: Dale Nash Date: Tue, 2 Feb 2021 10:30:23 +0000 Subject: [PATCH 0449/5766] Update conventions page to show correct function --- contributing/code/conventions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing/code/conventions.rst b/contributing/code/conventions.rst index d2325f5fc8b..18ea420b841 100644 --- a/contributing/code/conventions.rst +++ b/contributing/code/conventions.rst @@ -167,7 +167,7 @@ A deprecation must also be triggered to help people with the migration trigger_deprecation('symfony/package-name', '5.1', 'The "%s" class is deprecated, use "%s" instead.', Deprecated::class, Replacement::class); -When deprecating a whole class the ``trigger_error()`` call should be placed +When deprecating a whole class the ``trigger_deprecation()`` call should be placed after the use declarations, like in this example from `ServiceRouterLoader`_:: namespace Symfony\Component\Routing\Loader\DependencyInjection; From c9f807259fc0f00ff6634e64bdd0eb7c859b0de2 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 2 Feb 2021 23:10:05 +0100 Subject: [PATCH 0450/5766] [Messenger] Replace comma with full stop --- components/messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/messenger.rst b/components/messenger.rst index 157d3f79d6a..0772293eab1 100644 --- a/components/messenger.rst +++ b/components/messenger.rst @@ -56,7 +56,7 @@ Concepts which means they can tweak the envelope, by adding stamps to it or even replacing it, as well as interrupt the middleware chain. Middleware are called both when a message is originally dispatched and again later when a message - is received from a transport, + is received from a transport. **Envelope**: Messenger specific concept, it gives full flexibility inside the message bus, From edb9b438bf2ae9ed91ddffff914d1be5d11706b3 Mon Sep 17 00:00:00 2001 From: James Hemery Date: Sat, 23 Jan 2021 01:47:38 +0100 Subject: [PATCH 0451/5766] [Notifier] Add SpotHit bridge --- notifier.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/notifier.rst b/notifier.rst index 7231080d47e..0e55317c31f 100644 --- a/notifier.rst +++ b/notifier.rst @@ -70,6 +70,7 @@ OvhCloud ``symfony/ovh-cloud-notifier`` ``ovhcloud://APPLICATION_KEY:APPLI Sendinblue ``symfony/sendinblue-notifier`` ``sendinblue://API_KEY@default?sender=PHONE`` Sinch ``symfony/sinch-notifier`` ``sinch://ACCOUNT_ID:AUTH_TOKEN@default?from=FROM`` Smsapi ``symfony/smsapi-notifier`` ``smsapi://TOKEN@default?from=FROM`` +SpotHit ``symfony/spothit-notifier`` ``spothit://TOKEN@default?from=FROM`` Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from=FROM`` ========== ================================ ==================================================== @@ -83,8 +84,8 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= .. versionadded:: 5.3 - The Iqsms, GatewayApi, Octopush, AllMySms and Clickatell integrations were - introduced in Symfony 5.3. + The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell and SpotHit integrations + were introduced in Symfony 5.3. To enable a texter, add the correct DSN in your ``.env`` file and From 77007c183940332c255b1a066d1058a960439994 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Wed, 3 Feb 2021 09:11:30 +0100 Subject: [PATCH 0452/5766] message consume command --queue parameter Feature introduced in https://github.com/symfony/symfony/pull/38973 --- messenger.rst | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/messenger.rst b/messenger.rst index edd43cd7881..32fab4e0a41 100644 --- a/messenger.rst +++ b/messenger.rst @@ -587,6 +587,29 @@ to handle messages in a priority order: The worker will always first look for messages waiting on ``async_priority_high``. If there are none, *then* it will consume messages from ``async_priority_low``. +.. _messenger-limit-queues: + +Limit Consuming to Specific Queues +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Some transports (notably AMQP) have the concept of exchanges and queues. A Symfony +transport is always bound to an exchange. By default, the worker consumes from all +queues attached to the exchange of the specified transport. However, there are use +cases to want a worker to only consume from specific queues. + +You can limit the worker to only process messages from specific queues: + +.. code-block:: terminal + + $ php bin/console messenger:consume my_transport --queues=fasttrack + +To allow using the ``queues`` option, the receiver must implement the +:class:`Symfony\\Component\\Messenger\\Transport\\Receiver\\QueueReceiverInterface`. + +.. versionadded:: 5.3 + + Limiting the worker to specific queues was introduced in Symfony 5.3. + .. _messenger-supervisor: Supervisor Configuration @@ -950,6 +973,11 @@ it in the ``port`` parameter of the DSN (e.g. ``amqps://localhost?cacert=/etc/ss binding keys that are needed. That can be disabled, but some functionality may not work correctly (like delayed queues). +.. note:: + + With Symfony 5.3 or newer, you can limit the consumer of an AMQP transport to only + process messages from some queues of an exchange. See :ref:`messenger-limit-queues`. + The transport has a number of other options, including ways to configure the exchange, queues binding keys and more. See the documentation on :class:`Symfony\\Component\\Messenger\\Bridge\\Amqp\\Transport\\Connection`. From 17071880c4968fba91eaff73b7c73e52a6f49c9a Mon Sep 17 00:00:00 2001 From: wickedOne Date: Thu, 4 Feb 2021 09:18:34 +0100 Subject: [PATCH 0453/5766] role_names instead of roles corrected wrong attribute name relates to symfony/symfony#40087 --- security/expressions.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/security/expressions.rst b/security/expressions.rst index 2013d6656d7..6ea9d56a5d6 100644 --- a/security/expressions.rst +++ b/security/expressions.rst @@ -42,6 +42,10 @@ Inside the expression, you have access to a number of variables: The array of roles the user has. This array includes any roles granted indirectly via the :ref:`role hierarchy ` but it does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). +``role_names`` + A string representation of the roles the user has. This array includes any roles granted + indirectly via the :ref:`role hierarchy ` but it + does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). ``object`` The object (if any) that's passed as the second argument to ``isGranted()``. ``token`` From 88a52da1bf59fc71c5ac8b7366549d5c9862f5f2 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 2 Feb 2021 17:18:40 +0100 Subject: [PATCH 0454/5766] [RateLimiter][Security] Document login throttling and clarify DoS protection --- rate_limiter.rst | 11 +++++ security.rst | 109 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) diff --git a/rate_limiter.rst b/rate_limiter.rst index 4b6fc27d4ab..99617f20d59 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -16,6 +16,14 @@ Symfony uses these rate limiters in built-in features like "login throttling", which limits how many failed login attempts a user can make in a given period of time, but you can use them for your own features too. +.. caution:: + + By definition, the Symfony rate limiters require Symfony to be booted + in a PHP process. This makes them not useful to protect against `DoS attacks`_. + Such protections must consume the least resources possible. Consider + using `Apache mod_ratelimit`_, `NGINX rate limiting`_ or proxies (like + AWS or Cloudflare) to prevent your server from being overwhelmed. + .. _rate-limiter-policies: Rate Limiting Policies @@ -314,5 +322,8 @@ Symfony application. If you prefer to change that, use the ``lock_factory`` and # the value is the name of any lock defined in your application lock_factory: 'app.rate_limiter_lock' +.. _`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/ .. _`token bucket algorithm`: https://en.wikipedia.org/wiki/Token_bucket .. _`PHP date relative formats`: https://www.php.net/datetime.formats.relative diff --git a/security.rst b/security.rst index de13f7db4f6..3b9341a07d6 100644 --- a/security.rst +++ b/security.rst @@ -469,6 +469,113 @@ here are a few common use-cases: * :doc:`/security/guard_authentication` – see this for the most detailed description of authenticators and how they work +Limiting Login Attempts +~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 5.2 + + Login throttling was introduced in Symfony 5.2. + +Symfony provides basic protection against `brute force login attacks`_ if +you're using the :doc:`experimental authenticators `. +You must enable this using the ``login_throttling`` setting: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/security.yaml + security: + enable_authenticator_manager: true + + firewalls: + # ... + + main: + # ... + + # by default, the feature allows 5 login attempts per minute + login_throttling: null + + # configure the maximum login attempts (per minute) + login_throttling: + max_attempts: 3 + + # use a custom rate limiter via its service ID + login_throttling: + limiter: app.my_login_rate_limiter + + .. code-block:: xml + + + + + + + + + + + + + + + + + + + + + + .. code-block:: php + + // config/packages/security.php + $container->loadFromExtension('security', [ + 'enable_authenticator_manager' => true, + + 'firewalls' => [ + // ... + + 'main' => [ + // by default, the feature allows 5 login attempts per minute + 'login_throttling' => null, + + // configure the maximum login attempts (per minute) + 'login_throttling' => [ + 'max_attempts' => 3, + ], + + // use a custom rate limiter via its service ID + 'login_throttling' => [ + 'limiter' => 'app.my_login_rate_limiter', + ], + ], + ], + ]); + +By default, login attempts are limited on ``max_attempts`` (default: 5) +failed requests for ``IP address + username`` and ``5 * max_attempts`` +failed requests for ``IP address``. The second limit protects against an +attacker using multiple usernames from bypassing the first limit, without +distrupting normal users on big networks (such as offices). + +If you need a more complex limiting algorithm, create a class that implements +:class:`Symfony\\Component\\HttpFoundation\\RateLimiter\\RequestRateLimiterInterface` +and set the ``limiter`` option to its service ID. + +.. tip:: + + Limiting the failed login attempts is only one basic protection against + brute force attacks. The `OWASP Brute Force Attacks`_ guidelines mention + several other protections that you should consider depending on the + level of protection required. + .. _`security-authorization`: .. _denying-access-roles-and-other-authorization: @@ -1257,5 +1364,7 @@ Authorization (Denying Access) .. _`FrameworkExtraBundle documentation`: https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html .. _`HWIOAuthBundle`: https://github.com/hwi/HWIOAuthBundle +.. _`OWASP Brute Force Attacks`: https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks +.. _`brute force login attacks`: https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks .. _`Symfony Security screencast series`: https://symfonycasts.com/screencast/symfony-security .. _`MakerBundle`: https://symfony.com/doc/current/bundles/SymfonyMakerBundle/index.html From a85f968a3d22fae4657ef89f7cabbbea4043969c Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 28 Jan 2021 11:27:20 -0500 Subject: [PATCH 0455/5766] updating Encore docs for 1.0 --- .doctor-rst.yaml | 1 + _build/redirection_map | 1 + frontend.rst | 1 - frontend/encore/advanced-config.rst | 8 +- frontend/encore/copy-files.rst | 2 +- frontend/encore/dev-server.rst | 109 ++++++++++++++-------------- frontend/encore/installation.rst | 2 +- frontend/encore/shared-entry.rst | 42 ----------- frontend/encore/simple-example.rst | 48 ++---------- frontend/encore/split-chunks.rst | 13 ++-- frontend/encore/url-loader.rst | 47 ++++-------- frontend/encore/vuejs.rst | 4 +- 12 files changed, 92 insertions(+), 186 deletions(-) delete mode 100644 frontend/encore/shared-entry.rst diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index a568b014eab..61b56614a29 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -88,6 +88,7 @@ whitelist: - '.. versionadded:: 1.3' # MakerBundle - '.. versionadded:: 1.8' # MakerBundle - '.. versionadded:: 1.6' # Flex in setup/upgrade_minor.rst + - '.. versionadded:: 1.0.0' # Encore - '0 => 123' # assertion for var_dumper - components/var_dumper.rst - '1 => "foo"' # assertion for var_dumper - components/var_dumper.rst - '123,' # assertion for var_dumper - components/var_dumper.rst diff --git a/_build/redirection_map b/_build/redirection_map index de584707346..402057bdd18 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -511,3 +511,4 @@ /messenger/message-recorder messenger/dispatch_after_current_bus /components/stopwatch https://github.com/symfony/stopwatch /service_container/3.3-di-changes https://symfony.com/doc/3.4/service_container/3.3-di-changes.html +/frontend/encore/shared-entry /frontend/encore/split-chunks diff --git a/frontend.rst b/frontend.rst index 47d3111dd33..b95f0aa216e 100644 --- a/frontend.rst +++ b/frontend.rst @@ -61,7 +61,6 @@ Optimizing * :doc:`Using a CDN ` * :doc:`/frontend/encore/code-splitting` * :doc:`/frontend/encore/split-chunks` -* :doc:`Creating a "Shared" entry for re-used modules ` * :doc:`/frontend/encore/url-loader` Guides diff --git a/frontend/encore/advanced-config.rst b/frontend/encore/advanced-config.rst index 86bdb812b94..75abf94f481 100644 --- a/frontend/encore/advanced-config.rst +++ b/frontend/encore/advanced-config.rst @@ -12,12 +12,12 @@ To do that, modify the config after fetching it from Encore: // webpack.config.js - var Encore = require('@symfony/webpack-encore'); + const Encore = require('@symfony/webpack-encore'); // ... all Encore config here // fetch the config, then modify it! - var config = Encore.getWebpackConfig(); + const config = Encore.getWebpackConfig(); // add an extension config.resolve.extensions.push('json'); @@ -208,8 +208,8 @@ The following code is equivalent: The following loaders are configurable with ``configureLoaderRule()``: - ``javascript`` (alias ``js``) - ``css`` - - ``images`` - - ``fonts`` + - ``images`` (but use ``configureImageRule()`` instead) + - ``fonts`` (but use ``configureFontRule()`` instead) - ``sass`` (alias ``scss``) - ``less`` - ``stylus`` diff --git a/frontend/encore/copy-files.rst b/frontend/encore/copy-files.rst index 7ea5a541622..28e8f26d80a 100644 --- a/frontend/encore/copy-files.rst +++ b/frontend/encore/copy-files.rst @@ -16,7 +16,7 @@ To reference an image tag from inside a JavaScript file, *require* the file: // returns the final, public path to this file // path is relative to this file - e.g. assets/images/logo.png - const logoPath = require('../images/logo.png'); + import logoPath from '../images/logo.png'; let html = `ACME logo`; diff --git a/frontend/encore/dev-server.rst b/frontend/encore/dev-server.rst index 4d0904125cb..b5683109092 100644 --- a/frontend/encore/dev-server.rst +++ b/frontend/encore/dev-server.rst @@ -8,31 +8,16 @@ While developing, instead of using ``yarn encore dev --watch``, you can use the $ yarn encore dev-server -This builds and serves the front-end assets from a new server. This server runs at -``localhost:8080`` by default, meaning your build assets are available at ``localhost:8080/build``. -This server does not actually write the files to disk; instead it servers them from memory, +This builds and serves the front-end assets from a new server. This server runs at +``localhost:8080`` by default, meaning your build assets are available at ``localhost:8080/build``. +This server does not actually write the files to disk; instead it servers them from memory, allowing for hot module reloading. -As a consequence, the ``link`` and ``script`` tags need to point to the new server. If you're using the -``encore_entry_script_tags()`` and ``encore_entry_link_tags()`` Twig shortcuts (or are -:ref:`processing your assets through entrypoints.json ` in some other way), +As a consequence, the ``link`` and ``script`` tags need to point to the new server. If you're using the +``encore_entry_script_tags()`` and ``encore_entry_link_tags()`` Twig shortcuts (or are +:ref:`processing your assets through entrypoints.json ` in some other way), you're done: the paths in your templates will automatically point to the dev server. -Enabling HTTPS using the Symfony Web Server -------------------------------------------- - -If you're using the :doc:`Symfony web server ` locally with HTTPS, -you'll need to also tell the dev-server to use HTTPS. To do this, you can reuse the Symfony web -server SSL certificate: - -.. code-block:: terminal - - # Unix-based systems - $ yarn dev-server --https --pfx=$HOME/.symfony/certs/default.p12 - - # Windows - $ encore dev-server --https --pfx=%UserProfile%\.symfony\certs\default.p12 - dev-server Options ------------------ @@ -66,53 +51,65 @@ method in your ``webpack.config.js`` file: The ``Encore.configureDevServerOptions()`` method was introduced in Encore 0.28.4. -Hot Module Replacement HMR --------------------------- +Enabling HTTPS using the Symfony Web Server +------------------------------------------- + +If you're using the :doc:`Symfony web server ` locally with HTTPS, +you'll need to also tell the dev-server to use HTTPS. To do this, you can reuse the Symfony web +server SSL certificate: + +.. code-block:: javascript -Encore *does* support `HMR`_ for :doc:`Vue.js `, but -does *not* work for styles anywhere at this time. To activate it, pass the ``--hot`` -option: + // webpack.config.js + // ... + const path = require('path'); + + Encore + // ... + + .configureDevServerOptions(options => { + options.https = { + pfx: path.join(process.env.HOME, '.symfony/certs/default.p12'), + } + }) + +Then make sure you run the ``dev-server`` with the ``--https`` option: .. code-block:: terminal - $ ./node_modules/.bin/encore dev-server --hot + $ yarn encore dev-server --https -If you want to use SSL with self-signed certificates, add the ``--https``, -``--pfx=``, and ``--allowed-hosts`` options to the ``dev-server`` command in -the ``package.json`` file: +CORS Issues +----------- -.. code-block:: diff +If you experience issues related to CORS (Cross Origin Resource Sharing), set +the ``firewall`` option: - { - ... - "scripts": { - - "dev-server": "encore dev-server", - + "dev-server": "encore dev-server --https --pfx=$HOME/.symfony/certs/default.p12 --allowed-hosts=mydomain.wip", - ... - } - } +.. code-block:: javascript -If you experience issues related to CORS (Cross Origin Resource Sharing), add -the ``--disable-host-check`` and ``--port`` options to the ``dev-server`` -command in the ``package.json`` file: + // webpack.config.js + // ... + + Encore + // ... -.. code-block:: diff + .configureDevServerOptions(options => { + options.firewall = false; + }) - { - ... - "scripts": { - - "dev-server": "encore dev-server", - + "dev-server": "encore dev-server --port 8080 --disable-host-check", - ... - } - } +Hot Module Replacement HMR +-------------------------- -.. caution:: +Hot module replacement is a superpower of the ``dev-server`` where styles and +(in some cases) JavaScript can automatically update without needing to reload +your page. HMR works automatically with CSS (as long as you're using the +``dev-server`` and Encore 1.0 or higher) but only works with some JavaScript +(like :doc:`Vue.js `). - Beware that `it's not recommended to disable host checking`_ in general, but - here it's required to solve the CORS issue. +.. versionadded:: 1.0.0 + Before Encore 1.0, you needed to pass a ``--hot`` flag at the command line + to enable HMR. You also needed to disable CSS extraction to enable HMR for + CSS. That is no longer needed. .. _`webpack-dev-server`: https://webpack.js.org/configuration/dev-server/ -.. _`HMR`: https://webpack.js.org/concepts/hot-module-replacement/ -.. _`it's not recommended to disable host checking`: https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck diff --git a/frontend/encore/installation.rst b/frontend/encore/installation.rst index bbd6469a1c3..ef77cfe71ed 100644 --- a/frontend/encore/installation.rst +++ b/frontend/encore/installation.rst @@ -54,7 +54,7 @@ is the main config file for both Webpack and Webpack Encore: .. code-block:: javascript - var Encore = require('@symfony/webpack-encore'); + const Encore = require('@symfony/webpack-encore'); // Manually configure the runtime environment if not already configured yet by the "encore" command. // It's useful when you use tools that rely on webpack.config.js file. diff --git a/frontend/encore/shared-entry.rst b/frontend/encore/shared-entry.rst deleted file mode 100644 index a2c2d08ea2a..00000000000 --- a/frontend/encore/shared-entry.rst +++ /dev/null @@ -1,42 +0,0 @@ -Creating a Shared Commons Entry -=============================== - -.. caution:: - - While this method still works, see :doc:`/frontend/encore/split-chunks` for - the preferred solution to sharing assets between multiple entry files. - -Suppose you have multiple entry files and *each* requires ``jquery``. In this -case, *each* output file will contain jQuery, slowing down your user's experience. -To solve this, you can *extract* the common libraries to a "shared" entry file -that's included on every page. - -Suppose you already have an entry called ``app`` that's included on every page. -Update your code to use ``createSharedEntry()``: - -.. code-block:: diff - - Encore - // ... - - .addEntry('app', './assets/app.js') - + .createSharedEntry('app', './assets/app.js') - .addEntry('homepage', './assets/homepage.js') - .addEntry('blog', './assets/blog.js') - .addEntry('store', './assets/store.js') - -Before making this change, if both ``app.js`` and ``store.js`` require ``jquery``, -then ``jquery`` would be packaged into *both* files, which is wasteful. By making -``app.js`` your "shared" entry, *any* code required by ``app.js`` (like jQuery) will -*no longer* be packaged into any other files. The same is true for any CSS. - -Because ``app.js`` contains all the common code that other entry files depend on, -its script (and link) tag must be on every page. - -.. tip:: - - The ``app.js`` file works best when its contents are changed *rarely* - and you're using :ref:`long-term caching `. Why? - If ``app.js`` contains application code that *frequently* changes, then - (when using versioning), its filename hash will frequently change. This means - your users won't enjoy the benefits of long-term caching for this file (which - is generally quite large). diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index dd93a31cf37..cda018f36e8 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -19,8 +19,6 @@ application: it will *require* all of the dependencies it needs (e.g. jQuery or import './styles/app.css'; - // import $ from 'jquery'; - Encore's job (via Webpack) is simple: to read and follow *all* of the ``require()`` statements and create one final ``app.js`` (and ``app.css``) that contains *everything* your app needs. Encore can do a lot more: minify files, pre-process Sass/LESS, @@ -35,7 +33,7 @@ of your project. It already holds the basic config you need: .. code-block:: javascript // webpack.config.js - var Encore = require('@symfony/webpack-encore'); + const Encore = require('@symfony/webpack-encore'); Encore // directory where compiled assets will be stored @@ -130,6 +128,8 @@ filename(s) to render. This file is *especially* useful because you can :doc:`enable versioning ` or :doc:`point assets to a CDN ` without making *any* changes to your template: the paths in ``entrypoints.json`` will always be the final, correct paths. +And if you use :doc:`splitEntryChunks() ` (where Webpack splits the output into even +more files), all the necessary ``script`` and ``link`` tags will render automatically. If you're *not* using Symfony, you can ignore the ``entrypoints.json`` file and point to the final, built file directly. ``entrypoints.json`` is only required for @@ -147,13 +147,13 @@ some optional features. Requiring JavaScript Modules ---------------------------- -Webpack is a module bundler, which means that you can ``require`` other JavaScript +Webpack is a module bundler, which means that you can ``import`` other JavaScript files. First, create a file that exports a function: .. code-block:: javascript // assets/greet.js - module.exports = function(name) { + export default function(name) { return `Yo yo ${name} - welcome to Encore!`; }; @@ -163,7 +163,7 @@ We'll use jQuery to print this message on the page. Install it via: $ yarn add jquery --dev -Great! Use ``require()`` to import ``jquery`` and ``greet.js``: +Great! Use ``import`` to import ``jquery`` and ``greet.js``: .. code-block:: diff @@ -171,11 +171,11 @@ Great! Use ``require()`` to import ``jquery`` and ``greet.js``: // ... + // loads the jquery package from node_modules - + var $ = require('jquery'); + + import jquery from 'jquery'; + // import the function from greet.js (the .js extension is optional) + // ./ (or ../) means to look for a local file - + var greet = require('./greet'); + + import greet from './greet'; + $(document).ready(function() { + $('body').prepend('

                    '+greet('jill')+'

                    '); @@ -185,37 +185,6 @@ That's it! If you previously ran ``encore dev --watch``, your final, built files have already been updated: jQuery and ``greet.js`` have been automatically added to the output file (``app.js``). Refresh to see the message! -The import and export Statements --------------------------------- - -Instead of using ``require()`` and ``module.exports`` like shown above, JavaScript -provides an alternate syntax based on the `ECMAScript 6 modules`_ that includes -the ability to use dynamic imports. - -To export values using the alternate syntax, use ``export``: - -.. code-block:: diff - - // assets/greet.js - - module.exports = function(name) { - + export default function(name) { - return `Yo yo ${name} - welcome to Encore!`; - }; - -To import values, use ``import``: - -.. code-block:: diff - - // assets/app.js - - require('../styles/app.css'); - + import './styles/app.css'; - - - var $ = require('jquery'); - + import $ from 'jquery'; - - - var greet = require('./greet'); - + import greet from './greet'; - .. _multiple-javascript-entries: Page-Specific JavaScript or CSS (Multiple Entries) @@ -357,5 +326,4 @@ Encore supports many more features! For a full list of what you can do, see `Encore's index.js file`_. Or, go back to :ref:`list of Encore articles `. .. _`Encore's index.js file`: https://github.com/symfony/webpack-encore/blob/master/index.js -.. _`ECMAScript 6 modules`: https://hacks.mozilla.org/2015/08/es6-in-depth-modules/ .. _`WebpackEncoreBundle Configuration`: https://github.com/symfony/webpack-encore-bundle#configuration diff --git a/frontend/encore/split-chunks.rst b/frontend/encore/split-chunks.rst index 0205537b7d0..5569a9731f3 100644 --- a/frontend/encore/split-chunks.rst +++ b/frontend/encore/split-chunks.rst @@ -23,9 +23,10 @@ To enable this, call ``splitEntryChunks()``: Now, each output file (e.g. ``homepage.js``) *may* be split into multiple file -(e.g. ``homepage.js``, ``vendor~homepage.js``). This means that you *may* need to -include *multiple* ``script`` tags (or ``link`` tags for CSS) in your template. -Encore creates an :ref:`entrypoints.json ` +(e.g. ``homepage.js`` & ``vendors-node_modules_jquery_dist_jquery_js.js`` - the +filename of the second will be less obvious when you build for production). This +means that you *may* need to include *multiple* ``script`` tags (or ``link`` tags +for CSS) in your template. Encore creates an :ref:`entrypoints.json ` file that lists exactly which CSS and JavaScript files are needed for each entry. If you're using the ``encore_entry_link_tags()`` and ``encore_entry_script_tags()`` @@ -37,9 +38,9 @@ tags as needed: {# May now render multiple script tags: - - - + + + #} {{ encore_entry_script_tags('homepage') }} diff --git a/frontend/encore/url-loader.rst b/frontend/encore/url-loader.rst index 976cd6974d8..9567960c99d 100644 --- a/frontend/encore/url-loader.rst +++ b/frontend/encore/url-loader.rst @@ -1,18 +1,11 @@ -Inlining files in CSS with Webpack URL Loader -============================================= +Inlining Images & Fronts in CSS +=============================== A simple technique to improve the performance of web applications is to reduce the number of HTTP requests inlining small files as base64 encoded URLs in the generated CSS files. -Webpack Encore provides this feature via Webpack's `URL Loader`_ plugin, but -it's disabled by default. First, add the URL loader to your project: - -.. code-block:: terminal - - $ yarn add url-loader --dev - -Then enable it in your ``webpack.config.js``: +You can enable this in ``webpack.config.js`` for images, fonts or both: .. code-block:: javascript @@ -21,31 +14,19 @@ Then enable it in your ``webpack.config.js``: Encore // ... - .configureUrlLoader({ - fonts: { limit: 4096 }, - images: { limit: 4096 } + .configureImageRule({ + // tell Webpack it should consider inlining + type: 'asset', + //maxSize: 4 * 1024, // 4 kb - the default is 8kb }) - ; - -The ``limit`` option defines the maximum size in bytes of the inlined files. In -the previous example, font and image files having a size below or equal to 4 KB -will be inlined and the rest of files will be processed as usual. - -You can also use all the other options supported by the `URL Loader`_. If you -want to disable this loader for either images or fonts, remove the corresponding -key from the object that is passed to the ``configureUrlLoader()`` method: - -.. code-block:: javascript - - // webpack.config.js - // ... - Encore - // ... - .configureUrlLoader({ - // 'fonts' is not defined, so only images will be inlined - images: { limit: 4096 } + .configureFontRule({ + type: 'asset', + //maxSize: 4 * 1024 }) ; -.. _`URL Loader`: https://github.com/webpack-contrib/url-loader +This leverages Webpack `Asset Modules`_. You can read more about this and the +configuration there. + +.. _`Asset Modules`: https://webpack.js.org/guides/asset-modules/ diff --git a/frontend/encore/vuejs.rst b/frontend/encore/vuejs.rst index 3d10eedcd41..eb8e2793c82 100644 --- a/frontend/encore/vuejs.rst +++ b/frontend/encore/vuejs.rst @@ -65,11 +65,11 @@ Hot Module Replacement (HMR) The ``vue-loader`` supports hot module replacement: just update your code and watch your Vue.js app update *without* a browser refresh! To activate it, use the -``dev-server`` with the ``--hot`` option: +``dev-server``: .. code-block:: terminal - $ yarn encore dev-server --hot + $ yarn encore dev-server That's it! Change one of your ``.vue`` files and watch your browser update. But note: this does *not* currently work for *style* changes in a ``.vue`` file. Seeing From 47d7639fa796d47fab5492d8a912c51f58536e35 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 4 Feb 2021 19:28:08 -0500 Subject: [PATCH 0456/5766] re-adding warning about host check --- frontend/encore/dev-server.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/encore/dev-server.rst b/frontend/encore/dev-server.rst index b5683109092..3edd2d8ef83 100644 --- a/frontend/encore/dev-server.rst +++ b/frontend/encore/dev-server.rst @@ -97,6 +97,9 @@ the ``firewall`` option: options.firewall = false; }) +Beware that `it's not recommended to disable the firewall`_ in general, but +here it's required to solve the CORS issue. + Hot Module Replacement HMR -------------------------- @@ -113,3 +116,4 @@ your page. HMR works automatically with CSS (as long as you're using the CSS. That is no longer needed. .. _`webpack-dev-server`: https://webpack.js.org/configuration/dev-server/ +.. _`it's not recommended to disable the firewall`: https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck \ No newline at end of file From bc6ca521abf3472abd70f92eb68498aa55b3f752 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Feb 2021 13:01:32 +0100 Subject: [PATCH 0457/5766] Minor tweak --- security/expressions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/security/expressions.rst b/security/expressions.rst index 6ea9d56a5d6..91454691d5f 100644 --- a/security/expressions.rst +++ b/security/expressions.rst @@ -43,8 +43,8 @@ Inside the expression, you have access to a number of variables: indirectly via the :ref:`role hierarchy ` but it does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). ``role_names`` - A string representation of the roles the user has. This array includes any roles granted - indirectly via the :ref:`role hierarchy ` but it + An array with the string representation of the roles the user has. This array + includes any roles granted indirectly via the :ref:`role hierarchy ` but it does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). ``object`` The object (if any) that's passed as the second argument to ``isGranted()``. From 77ace60dd9145a36b813aa4ce51af35f39d17097 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Feb 2021 13:02:25 +0100 Subject: [PATCH 0458/5766] Removed the "roles" variable --- security/expressions.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/security/expressions.rst b/security/expressions.rst index 0740512ed04..cfdf006466c 100644 --- a/security/expressions.rst +++ b/security/expressions.rst @@ -38,10 +38,6 @@ Inside the expression, you have access to a number of variables: ``user`` The user object (or the string ``anon`` if you're not authenticated). -``roles`` - The array of roles the user has. This array includes any roles granted - indirectly via the :ref:`role hierarchy ` but it - does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). ``role_names`` An array with the string representation of the roles the user has. This array includes any roles granted indirectly via the :ref:`role hierarchy ` but it From 451168397cdd0fa609bd1d68b7a8bbab22e66692 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Feb 2021 13:10:36 +0100 Subject: [PATCH 0459/5766] Mention the "subject" expression language variable --- security/expressions.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/expressions.rst b/security/expressions.rst index 91454691d5f..2ed16878ff2 100644 --- a/security/expressions.rst +++ b/security/expressions.rst @@ -48,6 +48,8 @@ Inside the expression, you have access to a number of variables: does not include the ``IS_AUTHENTICATED_*`` attributes (see the functions below). ``object`` The object (if any) that's passed as the second argument to ``isGranted()``. +``subject`` + It stores the same value as ``object``, so they are equivalent. ``token`` The token object. ``trust_resolver`` From 4539584ba51b3716ec7fabca591037a6341db82d Mon Sep 17 00:00:00 2001 From: Alexandre Mallet Date: Thu, 4 Feb 2021 16:03:52 +0100 Subject: [PATCH 0460/5766] Change deprecated psr 2 to psr 12 from doc PSR 2 => PSR 12 --- contributing/code/standards.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst index 586a868aae2..0371a518632 100644 --- a/contributing/code/standards.rst +++ b/contributing/code/standards.rst @@ -5,7 +5,7 @@ Symfony code is contributed by thousands of developers around the world. To make every piece of code look and feel familiar, Symfony defines some coding standards that all contributions must follow. -These Symfony coding standards are based on the `PSR-1`_, `PSR-2`_ and `PSR-4`_ +These Symfony coding standards are based on the `PSR-1`_, `PSR-12`_ and `PSR-4`_ standards, so you may already know most of them. Making your Code Follow the Coding Standards From 2c7042fe4abe6c64b94a69372a558d1dc354cba4 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Feb 2021 16:49:16 +0100 Subject: [PATCH 0461/5766] Added the missing reference --- contributing/code/standards.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst index 0371a518632..1ee3c5380ed 100644 --- a/contributing/code/standards.rst +++ b/contributing/code/standards.rst @@ -5,8 +5,8 @@ Symfony code is contributed by thousands of developers around the world. To make every piece of code look and feel familiar, Symfony defines some coding standards that all contributions must follow. -These Symfony coding standards are based on the `PSR-1`_, `PSR-12`_ and `PSR-4`_ -standards, so you may already know most of them. +These Symfony coding standards are based on the `PSR-1`_, `PSR-2`_, `PSR-4`_ +and `PSR-12`_ standards, so you may already know most of them. Making your Code Follow the Coding Standards -------------------------------------------- @@ -287,6 +287,7 @@ License .. _`PSR-1`: https://www.php-fig.org/psr/psr-1/ .. _`PSR-2`: https://www.php-fig.org/psr/psr-2/ .. _`PSR-4`: https://www.php-fig.org/psr/psr-4/ +.. _`PSR-12`: https://www.php-fig.org/psr/psr-12/ .. _`identical comparison`: https://www.php.net/manual/en/language.operators.comparison.php .. _`Yoda conditions`: https://en.wikipedia.org/wiki/Yoda_conditions .. _`camelCase`: https://en.wikipedia.org/wiki/Camel_case From a32dd60d073d24bbfb2a6934e85a66842b10d1c9 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 6 Feb 2021 12:26:54 +0100 Subject: [PATCH 0462/5766] [Validator] Use single quotes for a string --- reference/constraints/EqualTo.rst | 2 +- reference/constraints/IdenticalTo.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/constraints/EqualTo.rst b/reference/constraints/EqualTo.rst index 75d80043cda..a4721a086c3 100644 --- a/reference/constraints/EqualTo.rst +++ b/reference/constraints/EqualTo.rst @@ -61,7 +61,7 @@ and that the ``age`` is ``20``, you could do the following: class Person { - #[Assert\EqualTo("Mary")] + #[Assert\EqualTo('Mary')] protected $firstName; #[Assert\EqualTo( diff --git a/reference/constraints/IdenticalTo.rst b/reference/constraints/IdenticalTo.rst index 7dc71b475f0..27ba84e59fe 100644 --- a/reference/constraints/IdenticalTo.rst +++ b/reference/constraints/IdenticalTo.rst @@ -63,7 +63,7 @@ The following constraints ensure that: class Person { - #[Assert\IdenticalTo("Mary")] + #[Assert\IdenticalTo('Mary')] protected $firstName; #[Assert\IdenticalTo( From 648bd07c2fd9bfdaba54590da94ca3d610880ec8 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 6 Feb 2021 12:50:36 +0100 Subject: [PATCH 0463/5766] [Validator] Use correct single quotes for a string --- reference/constraints/IsFalse.rst | 2 +- reference/constraints/IsTrue.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/constraints/IsFalse.rst b/reference/constraints/IsFalse.rst index e476fb25387..5b2597d8657 100644 --- a/reference/constraints/IsFalse.rst +++ b/reference/constraints/IsFalse.rst @@ -3,7 +3,7 @@ IsFalse Validates that a value is ``false``. Specifically, this checks to see if the value is exactly ``false``, exactly the integer ``0``, or exactly the -string "``0``". +string ``'0'``. Also see :doc:`IsTrue `. diff --git a/reference/constraints/IsTrue.rst b/reference/constraints/IsTrue.rst index 2066b6d4e73..d9d53b04f82 100644 --- a/reference/constraints/IsTrue.rst +++ b/reference/constraints/IsTrue.rst @@ -2,7 +2,7 @@ IsTrue ====== Validates that a value is ``true``. Specifically, this checks if the value is -exactly ``true``, exactly the integer ``1``, or exactly the string ``"1"``. +exactly ``true``, exactly the integer ``1``, or exactly the string ``'1'``. Also see :doc:`IsFalse `. From 35467b97d09033f2d2f0fc777fe335f25340f55f Mon Sep 17 00:00:00 2001 From: wkania Date: Sat, 6 Feb 2021 13:06:50 +0100 Subject: [PATCH 0464/5766] [Validator] Add a missing dot The other two issues end with a dot. --- reference/constraints/Sequentially.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/Sequentially.rst b/reference/constraints/Sequentially.rst index 21e088ba689..da7bd16f4b2 100644 --- a/reference/constraints/Sequentially.rst +++ b/reference/constraints/Sequentially.rst @@ -35,7 +35,7 @@ In such situations, you may encounter three issues: * the ``Length`` or ``Regex`` constraints may fail hard with a :class:`Symfony\\Component\\Validator\\Exception\\UnexpectedValueException` exception if the actual value is not a string, as enforced by ``Type``. -* you may end with multiple error messages for the same property +* you may end with multiple error messages for the same property. * you may perform a useless and heavy external call to geolocalize the address, while the format isn't valid. From 7332254b3eff85db5f5aac8cce574b28eec72ac0 Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Thu, 4 Feb 2021 21:20:10 -0500 Subject: [PATCH 0465/5766] Adding notes related to the dev-server https fix in Encore --- frontend/encore/dev-server.rst | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/frontend/encore/dev-server.rst b/frontend/encore/dev-server.rst index 3edd2d8ef83..b1f72e5996b 100644 --- a/frontend/encore/dev-server.rst +++ b/frontend/encore/dev-server.rst @@ -21,12 +21,18 @@ you're done: the paths in your templates will automatically point to the dev ser dev-server Options ------------------ +.. caution:: + + Encore uses ``webpack-dev-server`` version 4, which at the time of Encore's + 1.0 release was still in beta and was not documented. See the `4.0 CHANGELOG`_ + for changes. + The ``dev-server`` command supports all the options defined by `webpack-dev-server`_. You can set these options via command line options: .. code-block:: terminal - $ yarn encore dev-server --https --port 9000 + $ yarn encore dev-server --port 9000 You can also set these options using the ``Encore.configureDevServerOptions()`` method in your ``webpack.config.js`` file: @@ -58,26 +64,27 @@ If you're using the :doc:`Symfony web server ` locally wi you'll need to also tell the dev-server to use HTTPS. To do this, you can reuse the Symfony web server SSL certificate: -.. code-block:: javascript +.. code-block:: diff // webpack.config.js // ... - const path = require('path'); + + const path = require('path'); Encore // ... - .configureDevServerOptions(options => { - options.https = { - pfx: path.join(process.env.HOME, '.symfony/certs/default.p12'), - } - }) + + .configureDevServerOptions(options => { + + options.https = { + + pfx: path.join(process.env.HOME, '.symfony/certs/default.p12'), + + } + + }) -Then make sure you run the ``dev-server`` with the ``--https`` option: -.. code-block:: terminal +.. caution:: - $ yarn encore dev-server --https + Make sure to **not** pass the ``--https`` flag at the command line when + running ``encore dev-server``. This flag was required before 1.0, but now + will cause your config to be overridden. CORS Issues ----------- @@ -116,4 +123,5 @@ your page. HMR works automatically with CSS (as long as you're using the CSS. That is no longer needed. .. _`webpack-dev-server`: https://webpack.js.org/configuration/dev-server/ -.. _`it's not recommended to disable the firewall`: https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck \ No newline at end of file +.. _`it's not recommended to disable the firewall`: https://webpack.js.org/configuration/dev-server/#devserverdisablehostcheck +.. _`4.0 CHANGELOG`: https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md#400-beta0-2020-11-27 From 91ecbdab13bcc81144dfdabfc866c9c0351a5e24 Mon Sep 17 00:00:00 2001 From: Nicolas Grekas Date: Sun, 7 Feb 2021 17:09:18 +0100 Subject: [PATCH 0466/5766] Clarify the role of http_method_override --- forms.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/forms.rst b/forms.rst index 1654aa3deba..17cd593d416 100644 --- a/forms.rst +++ b/forms.rst @@ -777,7 +777,8 @@ to the ``form()`` or the ``form_start()`` helper functions: that stores this method. The form will be submitted in a normal ``POST`` request, but :doc:`Symfony's routing ` is capable of detecting the ``_method`` parameter and will interpret it as a ``PUT``, ``PATCH`` or - ``DELETE`` request. See the :ref:`configuration-framework-http_method_override` option. + ``DELETE`` request. The :ref:`configuration-framework-http_method_override` + option must be enabled for this to work. Changing the Form Name ~~~~~~~~~~~~~~~~~~~~~~ From 6b35baff53bc705452250cee5d2d24640a915024 Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Sun, 7 Feb 2021 14:46:17 +0100 Subject: [PATCH 0467/5766] Document the way to configure emails globally --- mailer.rst | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 76 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index 9c9c1451add..89be86382a4 100644 --- a/mailer.rst +++ b/mailer.rst @@ -320,8 +320,7 @@ both strings or address objects:: .. tip:: Instead of calling ``->from()`` *every* time you create a new email, you can - create an :doc:`event subscriber ` and listen to the - :class:`Symfony\\Component\\Mailer\\Event\\MessageEvent` event to set the + :ref:`configure emails globally ` to set the same ``From`` email to all messages. .. note:: @@ -373,6 +372,12 @@ header, etc.) but most of the times you'll set text headers:: // ... ; +.. tip:: + + Instead of calling ``->addTextHeader()`` *every* time you create a new email, you can + :ref:`configure emails globally ` to set the same + headers to all sent emails. + Message Contents ~~~~~~~~~~~~~~~~ @@ -448,6 +453,75 @@ images inside the HTML contents:: ->html(' ... ...') ; +.. _mailer-configure-email-globally: + +Configuring Emails Globally +--------------------------- + +Instead of calling ``->from()`` on each Email you create, you can configure this +value globally so that it is set on all sent emails. The same is true with ``->to()`` +and headers. + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/dev/mailer.yaml + framework: + mailer: + envelope: + sender: 'fabien@example.com' + recipients: ['foo@example.com', 'bar@example.com'] + headers: + from: 'Fabien ' + bcc: 'baz@example.com' + X-Custom-Header: 'foobar' + + .. code-block:: xml + + + + + + + + + + fabien@example.com + foo@example.com + bar@example.com + + Fabien <fabien@example.com> + baz@example.com + foobar + + + + + .. code-block:: php + + // config/packages/mailer.php + $container->loadFromExtension('framework', [ + // ... + 'mailer' => [ + 'envelope' => [ + 'sender' => 'fabien@example.com', + 'recipients' => ['foo@example.com', 'bar@example.com'], + ], + 'headers' => [ + 'from' => 'Fabien ', + 'bcc' => 'baz@example.com', + 'X-Custom-Header' => 'foobar', + ], + ], + ]); + + Handling Sending Failures ------------------------- From 3b1c006d0d60fe4bb00fefff93cbbbc17cb63d4b Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 7 Feb 2021 18:36:19 +0100 Subject: [PATCH 0468/5766] [CS] Add comma after last array item in multi-line array --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 2947f18cb68..83b7d59dff4 100644 --- a/messenger.rst +++ b/messenger.rst @@ -188,7 +188,7 @@ that uses this configuration: // or expanded to configure more options 'async' => [ 'dsn' => '%env(MESSENGER_TRANSPORT_DSN)%', - 'options' => [] + 'options' => [], ], ], ], From 4c041bc7374cfa66cedc172efd6acd4857db1704 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 8 Feb 2021 09:11:38 +0100 Subject: [PATCH 0469/5766] Added the versionadded directive --- mailer.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mailer.rst b/mailer.rst index 89be86382a4..ed2e0ccf041 100644 --- a/mailer.rst +++ b/mailer.rst @@ -521,6 +521,9 @@ and headers. ], ]); +.. versionadded:: 5.2 + + The ``headers`` option was introduced in Symfony 5.2. Handling Sending Failures ------------------------- From 98d97b0a575c67dcd30e1f77117aca446d376511 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 9 Feb 2021 19:56:46 +0100 Subject: [PATCH 0470/5766] [Messenger][CS] Add missing commas in PHP configurations --- messenger.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/messenger.rst b/messenger.rst index 83b7d59dff4..7f13eb0f4b0 100644 --- a/messenger.rst +++ b/messenger.rst @@ -975,8 +975,8 @@ The transport has a number of options: 'async_priority_low' => [ 'dsn' => '%env(MESSENGER_TRANSPORT_DSN)%', 'options' => [ - 'queue_name' => 'normal_priority' - ] + 'queue_name' => 'normal_priority', + ], ], ], ], @@ -1445,8 +1445,8 @@ Then, make sure to "route" your message to *both* transports: 'image_transport' => '...', ], 'routing' => [ - 'App\Message\UploadedImage' => ['image_transport', 'async_priority_normal'] - ] + 'App\Message\UploadedImage' => ['image_transport', 'async_priority_normal'], + ], ], ]); From 336d8ae4d028b2e3b4967924d737d7b11f965cbc Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 9 Feb 2021 19:57:07 +0100 Subject: [PATCH 0471/5766] [Validator] Use single quotes for a string --- validation.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/validation.rst b/validation.rst index ab81c528462..55d0c6aaed5 100644 --- a/validation.rst +++ b/validation.rst @@ -298,7 +298,7 @@ rules). In order to validate an object, simply map one or more constraints to its class and then pass it to the ``validator`` service. Behind the scenes, a constraint is simply a PHP object that makes an assertive -statement. In real life, a constraint could be: 'The cake must not be burned'. +statement. In real life, a constraint could be: ``'The cake must not be burned'``. In Symfony, constraints are similar: they are assertions that a condition is true. Given a value, a constraint will tell you if that value adheres to the rules of the constraint. @@ -342,7 +342,7 @@ literature genre mostly associated with the author, which can be set to either { /** * @Assert\Choice( - * choices = { "fiction", "non-fiction" }, + * choices = {"fiction", "non-fiction"}, * message = "Choose a valid genre." * ) */ @@ -509,7 +509,7 @@ of the form fields:: $builder ->add('myField', TextType::class, [ 'required' => true, - 'constraints' => [new Length(['min' => 3])] + 'constraints' => [new Length(['min' => 3])], ]) ; } @@ -606,7 +606,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]) ); } } From eee0223c0de7d0c036ed9fe5872d2127888fb7d6 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 9 Feb 2021 20:01:01 +0100 Subject: [PATCH 0472/5766] [Messenger][CS] Add missing comma in PHP configuration --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index a6e64d8f94e..8a527c43c65 100644 --- a/messenger.rst +++ b/messenger.rst @@ -899,7 +899,7 @@ options. Options can be passed to the transport via a DSN string or configuratio 'dsn' => '%env(MESSENGER_TRANSPORT_DSN)%', 'options' => [ 'auto_setup' => false, - ] + ], ], ], ], From 918671aebe8e95e75de35ddb0f963c5e915ca5f7 Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 9 Feb 2021 20:02:25 +0100 Subject: [PATCH 0473/5766] [Validator] Add a comma after the last array item in a multi-line array --- validation/raw_values.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/raw_values.rst b/validation/raw_values.rst index cd25bec0653..8cee65108b8 100644 --- a/validation/raw_values.rst +++ b/validation/raw_values.rst @@ -88,7 +88,7 @@ Validation of arrays is possible using the ``Collection`` constraint:: new Assert\Collection([ 'slug' => [ new Assert\NotBlank(), - new Assert\Type(['type' => 'string']) + new Assert\Type(['type' => 'string']), ], 'label' => [ new Assert\NotBlank(), From 30f7d5f28754a7ab5d83eaec76e7bafca5c1caff Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 9 Feb 2021 20:12:31 +0100 Subject: [PATCH 0474/5766] [Validator] Add a missing namespace and use --- validation/custom_constraint.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst index 3cebc7a0c72..5ebd2f659d1 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -228,6 +228,11 @@ not to the property: .. code-block:: php-annotations + // src/Entity/AcmeEntity.php + namespace App\Entity; + + use App\Validator as AcmeAssert; + /** * @AcmeAssert\ProtocolClass */ From 5df61fdfc234a4c956e3329fd9bced53c2d2d00f Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 9 Feb 2021 20:15:55 +0100 Subject: [PATCH 0475/5766] [Validator] Add a missing namespace and use --- validation/custom_constraint.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst index 9cecde12b8a..468342ea5bd 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -285,6 +285,11 @@ not to the property: .. code-block:: php-attributes + // src/Entity/AcmeEntity.php + namespace App\Entity; + + use App\Validator as AcmeAssert; + #[AcmeAssert\ProtocolClass] class AcmeEntity { From c8ad12291ffac5f8d58e8318b3b4048c4bb14b4c Mon Sep 17 00:00:00 2001 From: Ryan Weaver Date: Wed, 10 Feb 2021 07:03:56 -0500 Subject: [PATCH 0476/5766] updating config for postcss-loader v4 --- frontend/encore/postcss.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/encore/postcss.rst b/frontend/encore/postcss.rst index 76c6e8d67e9..d2322b14032 100644 --- a/frontend/encore/postcss.rst +++ b/frontend/encore/postcss.rst @@ -43,13 +43,14 @@ You can also pass options to the `postcss-loader`_ by passing a callback: .. code-block:: diff // webpack.config.js + + const path = require('path'); Encore // ... + .enablePostCssLoader((options) => { - + options.config = { + + options.postcssOptions = { + // the directory where the postcss.config.js file is stored - + path: 'path/to/config' + + config: path.resolve(__dirname, 'sub-dir', 'custom.config.js'), + }; + }) ; From 0fcfccadc6d0a323321437af607f91bf817f4068 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Wed, 10 Feb 2021 18:56:31 +0100 Subject: [PATCH 0477/5766] [Messenger] Remove duplicated AMQP transport option The confirm_timeout option (introduced in Symfony 5.2) has been documented twice. I left the first version which is closest to the documentation available in the Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection class. --- messenger.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/messenger.rst b/messenger.rst index 625a1bfb743..49058d4d3e4 100644 --- a/messenger.rst +++ b/messenger.rst @@ -971,9 +971,6 @@ The transport has a number of options: fractional. ``connect_timeout`` Connection timeout. Note: 0 or greater seconds. May be fractional. -``confirm_timeout`` Number of seconds to wait for message sending - confirmation. If not specified, transport won't - wait for confirmation. May be fractional. ``frame_max`` The largest frame size that the server proposes for the connection, including frame header and end-byte. 0 means standard extension limit From 78a6c7764bb30d4682cc7f32854840358e6fafb3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 11 Feb 2021 09:23:49 +0100 Subject: [PATCH 0478/5766] Minor tweak --- messenger.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger.rst b/messenger.rst index 49058d4d3e4..0e69f3e11ff 100644 --- a/messenger.rst +++ b/messenger.rst @@ -965,8 +965,8 @@ The transport has a number of options: ``cert`` Path to the client certificate in PEM format. ``channel_max`` Specifies highest channel number that the server permits. 0 means standard extension limit -``confirm_timeout`` Timeout in seconds for confirmation, if none - specified transport will not wait for message +``confirm_timeout`` Timeout in seconds for confirmation; if none + specified, transport will not wait for message confirmation. Note: 0 or greater seconds. May be fractional. ``connect_timeout`` Connection timeout. Note: 0 or greater seconds. From 6c790bc5bfc91573cd166c722f51e9ec7ea5dae2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 11 Feb 2021 11:17:36 +0100 Subject: [PATCH 0479/5766] [Form] Document the new Uuid and Ulid form types --- components/uid.rst | 4 ++ reference/forms/types.rst | 3 + reference/forms/types/map.rst.inc | 6 ++ reference/forms/types/ulid.rst | 98 +++++++++++++++++++++++++++++++ reference/forms/types/uuid.rst | 98 +++++++++++++++++++++++++++++++ 5 files changed, 209 insertions(+) create mode 100644 reference/forms/types/ulid.rst create mode 100644 reference/forms/types/uuid.rst diff --git a/components/uid.rst b/components/uid.rst index e84b7296fad..49ccac839a7 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -21,6 +21,8 @@ Installation .. include:: /components/require_autoload.rst.inc +.. _uuid: + UUIDs ----- @@ -214,6 +216,8 @@ of the UUID parameters:: } } +.. _ulid: + ULIDs ----- diff --git a/reference/forms/types.rst b/reference/forms/types.rst index 49d769c8967..61ff1b5bf86 100644 --- a/reference/forms/types.rst +++ b/reference/forms/types.rst @@ -41,6 +41,9 @@ Form Types Reference types/file types/radio + types/uuid + types/ulid + types/collection types/repeated diff --git a/reference/forms/types/map.rst.inc b/reference/forms/types/map.rst.inc index 4036f2f7dce..8171c836a4d 100644 --- a/reference/forms/types/map.rst.inc +++ b/reference/forms/types/map.rst.inc @@ -43,6 +43,12 @@ Other Fields * :doc:`FileType ` * :doc:`RadioType ` +UID Fields +~~~~~~~~~~ + +* :doc:`UuidType ` +* :doc:`UlidType ` + Field Groups ~~~~~~~~~~~~ diff --git a/reference/forms/types/ulid.rst b/reference/forms/types/ulid.rst new file mode 100644 index 00000000000..26ffa1856e2 --- /dev/null +++ b/reference/forms/types/ulid.rst @@ -0,0 +1,98 @@ +.. index:: + single: Forms; Fields; UuidType + +UlidType Field +============== + +.. versionadded:: 5.3 + + The ``UlidType`` field was introduced in Symfony 5.3. + +Renders an input text field with the ULID string value and transforms it back to +a proper :ref:`Ulid object ` when submitting the form. + ++---------------------------+-----------------------------------------------------------------------+ +| Rendered as | ``input`` ``text`` field | ++---------------------------+-----------------------------------------------------------------------+ +| Options | (none) | ++---------------------------+-----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Default invalid message | Please enter a valid ULID. | ++---------------------------+-----------------------------------------------------------------------+ +| Legacy invalid message | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UlidType` | ++---------------------------+-----------------------------------------------------------------------+ + +.. include:: /reference/forms/types/options/_debug_form.rst.inc + +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/compound_type.rst.inc + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + +Inherited Options +----------------- + +These options inherit from the :doc:`FormType `: + +.. include:: /reference/forms/types/options/attr.rst.inc + +.. include:: /reference/forms/types/options/data.rst.inc + +.. include:: /reference/forms/types/options/disabled.rst.inc + +.. include:: /reference/forms/types/options/empty_data.rst.inc + :end-before: DEFAULT_PLACEHOLDER + +The default value is ``''`` (the empty string). + +.. include:: /reference/forms/types/options/empty_data.rst.inc + :start-after: DEFAULT_PLACEHOLDER + +.. include:: /reference/forms/types/options/error_bubbling.rst.inc + +.. include:: /reference/forms/types/options/error_mapping.rst.inc + +.. include:: /reference/forms/types/options/help.rst.inc + +.. include:: /reference/forms/types/options/help_attr.rst.inc + +.. include:: /reference/forms/types/options/help_html.rst.inc + +.. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc + +.. include:: /reference/forms/types/options/label.rst.inc + +.. include:: /reference/forms/types/options/label_attr.rst.inc + +.. include:: /reference/forms/types/options/label_format.rst.inc + +.. include:: /reference/forms/types/options/mapped.rst.inc + +.. include:: /reference/forms/types/options/required.rst.inc + +.. include:: /reference/forms/types/options/row_attr.rst.inc diff --git a/reference/forms/types/uuid.rst b/reference/forms/types/uuid.rst new file mode 100644 index 00000000000..dd478140ba9 --- /dev/null +++ b/reference/forms/types/uuid.rst @@ -0,0 +1,98 @@ +.. index:: + single: Forms; Fields; UuidType + +UuidType Field +============== + +.. versionadded:: 5.3 + + The ``UuidType`` field was introduced in Symfony 5.3. + +Renders an input text field with the UUID string value and transforms it back to +a proper :ref:`Uuid object ` when submitting the form. + ++---------------------------+-----------------------------------------------------------------------+ +| Rendered as | ``input`` ``text`` field | ++---------------------------+-----------------------------------------------------------------------+ +| Options | (none) | ++---------------------------+-----------------------------------------------------------------------+ +| Overridden options | - `compound`_ | +| | - `invalid_message`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Inherited options | - `attr`_ | +| | - `data`_ | +| | - `disabled`_ | +| | - `empty_data`_ | +| | - `error_bubbling`_ | +| | - `error_mapping`_ | +| | - `help`_ | +| | - `help_attr`_ | +| | - `help_html`_ | +| | - `invalid_message_parameters`_ | +| | - `label`_ | +| | - `label_attr`_ | +| | - `label_format`_ | +| | - `mapped`_ | +| | - `required`_ | +| | - `row_attr`_ | ++---------------------------+-----------------------------------------------------------------------+ +| Default invalid message | Please enter a valid UUID. | ++---------------------------+-----------------------------------------------------------------------+ +| Legacy invalid message | The value {{ value }} is not valid. | ++---------------------------+-----------------------------------------------------------------------+ +| Parent type | :doc:`FormType ` | ++---------------------------+-----------------------------------------------------------------------+ +| Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\UuidType` | ++---------------------------+-----------------------------------------------------------------------+ + +.. include:: /reference/forms/types/options/_debug_form.rst.inc + +Overridden Options +------------------ + +.. include:: /reference/forms/types/options/compound_type.rst.inc + +.. include:: /reference/forms/types/options/invalid_message.rst.inc + +Inherited Options +----------------- + +These options inherit from the :doc:`FormType `: + +.. include:: /reference/forms/types/options/attr.rst.inc + +.. include:: /reference/forms/types/options/data.rst.inc + +.. include:: /reference/forms/types/options/disabled.rst.inc + +.. include:: /reference/forms/types/options/empty_data.rst.inc + :end-before: DEFAULT_PLACEHOLDER + +The default value is ``''`` (the empty string). + +.. include:: /reference/forms/types/options/empty_data.rst.inc + :start-after: DEFAULT_PLACEHOLDER + +.. include:: /reference/forms/types/options/error_bubbling.rst.inc + +.. include:: /reference/forms/types/options/error_mapping.rst.inc + +.. include:: /reference/forms/types/options/help.rst.inc + +.. include:: /reference/forms/types/options/help_attr.rst.inc + +.. include:: /reference/forms/types/options/help_html.rst.inc + +.. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc + +.. include:: /reference/forms/types/options/label.rst.inc + +.. include:: /reference/forms/types/options/label_attr.rst.inc + +.. include:: /reference/forms/types/options/label_format.rst.inc + +.. include:: /reference/forms/types/options/mapped.rst.inc + +.. include:: /reference/forms/types/options/required.rst.inc + +.. include:: /reference/forms/types/options/row_attr.rst.inc From 37319d7f4e3b82b866d43ba2bb448a5a4f11d8e3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 11 Feb 2021 12:10:35 +0100 Subject: [PATCH 0480/5766] [Messenger] Fixed the MESSENGER_TRANSPORT_DSN example --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 0e69f3e11ff..281c31fa235 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1327,7 +1327,7 @@ The SQS transport DSN may looks like this: .. code-block:: env # .env - MESSENGER_TRANSPORT_DSN=https://AKIAIOSFODNN7EXAMPLE:j17M97ffSVoKI0briFoo9a@sqs.eu-west-3.amazonaws.com/123456789012/messages + MESSENGER_TRANSPORT_DSN=https://sqs.eu-west-3.amazonaws.com/123456789012/messages?access_key= AKIAIOSFODNN7EXAMPLE&secret_key=j17M97ffSVoKI0briFoo9a MESSENGER_TRANSPORT_DSN=sqs://localhost:9494/messages?sslmode=disable .. note:: From de411c431119a81afa63af5e804329810de16d14 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 11 Feb 2021 13:30:01 +0100 Subject: [PATCH 0481/5766] [Session] Remove some unneeded example --- session.rst | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/session.rst b/session.rst index 8d465516a58..fb9bb81cd8a 100644 --- a/session.rst +++ b/session.rst @@ -196,22 +196,6 @@ the existence of data in the session. This may hurt your application performance because all users will receive a session cookie. In order to prevent that, you must *completely* avoid accessing the session. -For example, if your templates include some code to display the -:ref:`flash messages `, sessions will start even if the user -is not logged in and even if you haven't created any flash messages. To avoid -this behavior, add a check before trying to access the flash messages: - -.. code-block:: html+twig - - {# this check prevents starting a session when there are no flash messages #} - {% if app.request.hasPreviousSession %} - {% for message in app.flashes('notice') %} -
                    - {{ message }} -
                    - {% endfor %} - {% endif %} - More about Sessions ------------------- From 243d84b030e6fbbc09bdc447bd01c6f49fc7d777 Mon Sep 17 00:00:00 2001 From: Johann Pardanaud Date: Thu, 11 Feb 2021 16:33:02 +0100 Subject: [PATCH 0482/5766] [Messenger] Document DSN format for Redis Cluster --- messenger.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/messenger.rst b/messenger.rst index c53044e588d..edcd236f2c3 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1190,6 +1190,8 @@ The Redis transport DSN may looks like this: MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages # Full DSN Example MESSENGER_TRANSPORT_DSN=redis://password@localhost:6379/messages/symfony/consumer?auto_setup=true&serializer=1&stream_max_entries=0&dbindex=0 + # Redis Cluster Example + MESSENGER_TRANSPORT_DSN=redis://host-01:6379,redis://host-02:6379,redis://host-03:6379,redis://host-04:6379 # Unix Socket Example MESSENGER_TRANSPORT_DSN=redis:///var/run/redis.sock From 5b04647263b09dc888edb0bff2ff7717ff3cc497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 11 Feb 2021 18:39:58 +0100 Subject: [PATCH 0483/5766] [Mercure] Make the command compatible with ZSH --- mercure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mercure.rst b/mercure.rst index 527833e2f7e..f32e8eee6a8 100644 --- a/mercure.rst +++ b/mercure.rst @@ -75,7 +75,7 @@ On Linux and Mac, run the following command to start it: .. rst-class:: command-linux - $ SERVER_NAME=:3000 MERCURE_PUBLISHER_JWT_KEY="!ChangeMe!" MERCURE_SUBSCRIBER_JWT_KEY="!ChangeMe!" ./mercure run -config Caddyfile.dev + $ SERVER_NAME=:3000 MERCURE_PUBLISHER_JWT_KEY='!ChangeMe!' MERCURE_SUBSCRIBER_JWT_KEY='!ChangeMe!' ./mercure run -config Caddyfile.dev On Windows run: From 036d01bdcdd847d4503ae4647833b8c02ecfb52e Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Thu, 11 Feb 2021 18:39:53 +0100 Subject: [PATCH 0484/5766] [Messenger][CS] Add missing commas I discovered two more examples where a comma is missing after the last array item in a multi-line array. --- messenger.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/messenger.rst b/messenger.rst index 7f13eb0f4b0..0ee914216ca 100644 --- a/messenger.rst +++ b/messenger.rst @@ -859,7 +859,7 @@ your Envelope:: $attributes = []; $bus->dispatch(new SmsNotification(), [ - new AmqpStamp('custom-routing-key', AMQP_NOPARAM, $attributes) + new AmqpStamp('custom-routing-key', AMQP_NOPARAM, $attributes), ]); .. caution:: @@ -1483,12 +1483,12 @@ to your message:: { $bus->dispatch(new SmsNotification('...'), [ // wait 5 seconds before processing - new DelayStamp(5000) + new DelayStamp(5000), ]); // or explicitly create an Envelope $bus->dispatch(new Envelope(new SmsNotification('...'), [ - new DelayStamp(5000) + new DelayStamp(5000), ])); // ... From 756b7734d676a1edc47611899a56d7e1a9726d1d Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Fri, 12 Feb 2021 06:49:37 +0100 Subject: [PATCH 0485/5766] [Messenger] Fix grammar issue --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 0e69f3e11ff..d4929f1659d 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1100,7 +1100,7 @@ Beanstalkd Transport The Beanstalkd transport was introduced in Symfony 5.2. -The Beanstalkd transports sends messages directly to a Beanstalkd work queue. Install +The Beanstalkd transport sends messages directly to a Beanstalkd work queue. Install it by running: .. code-block:: terminal From 5e1aaeca8f25fcdfb4c2b0fc0262450ffdc21bcc Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 12 Feb 2021 09:45:29 +0100 Subject: [PATCH 0486/5766] fix the trusted proxies configuration --- deployment/proxies.rst | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index 95d1ddfd0c9..9b6821e3f79 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -33,13 +33,13 @@ 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' - // trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers) - trusted_headers: ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'] + // trust *all* "X-Forwarded-*" headers + trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port'] // or, if your proxy instead uses the "Forwarded" header - trusted_headers: ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix'] + trusted_headers: ['forwarded'] // or, if you're using a wellknown proxy - trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'] - trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix'] + trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB] + trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_TRAEFIK] .. code-block:: xml @@ -57,15 +57,14 @@ and what headers your reverse proxy uses to send information: 192.0.0.1,10.0.0.0/8 - - x-forwarded-all - !x-forwarded-host - !x-forwarded-prefix + + x-forwarded-for + x-forwarded-host + x-forwarded-proto + x-forwarded-port forwarded - !x-forwarded-host - !x-forwarded-prefix @@ -78,12 +77,12 @@ 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', // trust *all* "X-Forwarded-*" headers (the ! prefix means to not trust those headers) - 'trusted_headers' => ['x-forwarded-all', '!x-forwarded-host', '!x-forwarded-prefix'], + 'trusted_headers' => ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port'], // or, if your proxy instead uses the "Forwarded" header - 'trusted_headers' => ['forwarded', '!x-forwarded-host', '!x-forwarded-prefix'], + 'trusted_headers' => ['forwarded'], // or, if you're using a wellknown proxy - 'trusted_headers' => [Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'], - 'trusted_headers' => [Request::HEADER_X_FORWARDED_TRAEFIK, '!x-forwarded-host', '!x-forwarded-prefix'], + 'trusted_headers' => [Request::HEADER_X_FORWARDED_AWS_ELB], + 'trusted_headers' => [Request::HEADER_X_FORWARDED_TRAEFIK], ]); .. deprecated:: 5.2 From 7a2f7df69762aa244639dd3e130cc2516277f64d Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 11 Feb 2021 10:51:03 +0100 Subject: [PATCH 0487/5766] [Uid] Removed Uuuid generator classes --- components/uid.rst | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index e84b7296fad..b63d829d03a 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -151,29 +151,32 @@ type, which converts to/from UUID objects automatically:: // ... } -There's also a Doctrine generator to help autogenerate UUID values for the -entity primary keys:: +.. versionadded:: 5.2 - // there are generators for UUID V1 and V6 too - use Symfony\Bridge\Doctrine\IdGenerator\UuidV4Generator; - use Symfony\Component\Uid\Uuid; + The UUID type was introduced in Symfony 5.2. - /** - * @ORM\Entity(repositoryClass="App\Repository\ProductRepository") - */ - class Product +There is no generator to assign UUIDs automatically as the value of your entity +primary keys, but you can use instead the following:: + + namespace App\Entity; + + use Doctrine\ORM\Mapping as ORM; + // ... + + class User implements UserInterface { /** * @ORM\Id - * @ORM\Column(type="uuid", unique=true) - * @ORM\GeneratedValue(strategy="CUSTOM") - * @ORM\CustomIdGenerator(class=UuidV4Generator::class) + * @ORM\Column(type="ulid", unique=true) */ private $id; - // ... + public function __construct() + { + $this->id = new Ulid(); + } - public function getId(): ?Uuid + public function getId(): Ulid { return $this->id; } @@ -181,10 +184,6 @@ entity primary keys:: // ... } -.. versionadded:: 5.2 - - The UUID type and generators were introduced in Symfony 5.2. - When using built-in Doctrine repository methods (e.g. ``findOneBy()``), Doctrine knows how to convert these UUID types to build the SQL query (e.g. ``->findOneBy(['user' => $user->getUuid()])``). However, when using DQL From 18393893867e6c2ad575f33775bdf0e4f102ea38 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 12 Feb 2021 15:41:40 +0100 Subject: [PATCH 0488/5766] Tweaks --- components/uid.rst | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index b63d829d03a..1bd3fcb2b56 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -156,27 +156,28 @@ type, which converts to/from UUID objects automatically:: The UUID type was introduced in Symfony 5.2. There is no generator to assign UUIDs automatically as the value of your entity -primary keys, but you can use instead the following:: +primary keys, but you can use the following:: namespace App\Entity; use Doctrine\ORM\Mapping as ORM; + use Symfony\Component\Uid\Uuid; // ... class User implements UserInterface { /** * @ORM\Id - * @ORM\Column(type="ulid", unique=true) + * @ORM\Column(type="uuid", unique=true) */ private $id; public function __construct() { - $this->id = new Ulid(); + $this->id = Uuid::v4(); } - public function getId(): Ulid + public function getId(): Uuid { return $this->id; } From 2cb0c9e53eed0730dfa2cb5e81825e9468c8a99c Mon Sep 17 00:00:00 2001 From: wkania Date: Sat, 13 Feb 2021 12:20:08 +0100 Subject: [PATCH 0489/5766] [Validator] Change Range and Legth description formatting --- reference/constraints/Length.rst | 4 ++-- reference/constraints/Range.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst index 11ae53ae6b9..7e790efeee7 100644 --- a/reference/constraints/Length.rst +++ b/reference/constraints/Length.rst @@ -23,8 +23,8 @@ Validator :class:`Symfony\\Component\\Validator\\Constraints\\LengthValidator` Basic Usage ----------- -To verify that the ``firstName`` field length of a class is between "2" -and "50", you might add the following: +To verify that the ``firstName`` field length of a class is between ``2`` +and ``50``, you might add the following: .. configuration-block:: diff --git a/reference/constraints/Range.rst b/reference/constraints/Range.rst index 5743d8d04ef..d07bc0445f4 100644 --- a/reference/constraints/Range.rst +++ b/reference/constraints/Range.rst @@ -22,7 +22,7 @@ Validator :class:`Symfony\\Component\\Validator\\Constraints\\RangeValidator` Basic Usage ----------- -To verify that the "height" field of a class is between "120" and "180", +To verify that the ``height`` field of a class is between ``120`` and ``180``, you might add the following: .. configuration-block:: From 6f212d9854638822dc016e7a540113157533e1d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 13 Feb 2021 16:17:56 +0100 Subject: [PATCH 0490/5766] Add documentation for RouterContextMiddleware --- messenger.rst | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/messenger.rst b/messenger.rst index edd43cd7881..eda3d7b16d3 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1954,6 +1954,67 @@ may want to use: ], ]); +Other Middlewares +~~~~~~~~~~~~~~~~~ + +.. versionadded:: 5.3 + + The ``router_context`` middleware were introduced in Symfony 5.3. + +When the consumer needs to build an absolute URL, for instance: rendering a +template with links, it needs the initial's request context in order to +retrieves the domain and information needed to build the URL. This can be +achieved by declaring the ``router_context`` middleware in the bus. + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/messenger.yaml + framework: + messenger: + buses: + command_bus: + middleware: + - router_context + + .. code-block:: xml + + + + + + + + + + + + + + + .. code-block:: php + + // config/packages/messenger.php + $container->loadFromExtension('framework', [ + 'messenger' => [ + 'buses' => [ + 'command_bus' => [ + 'middleware' => [ + 'router_context', + ], + ], + ], + ], + ]); + + Messenger Events ~~~~~~~~~~~~~~~~ From 6f1a420a567338648e66a788927b0ef02df8460b Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sun, 14 Feb 2021 10:09:45 +0100 Subject: [PATCH 0491/5766] [Validator] Improve Valid constraint description --- reference/constraints/Valid.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reference/constraints/Valid.rst b/reference/constraints/Valid.rst index 1cb992128ac..b052cab38b4 100644 --- a/reference/constraints/Valid.rst +++ b/reference/constraints/Valid.rst @@ -243,6 +243,13 @@ the validation of the ``Address`` fields failed. App\Entity\Author.address.zipCode: This value is too long. It should have 5 characters or less. +.. include:: /reference/constraints/_empty-values-are-valid.rst.inc + +.. note:: + + This constraint is not aware what sub-object must be associated with it, a common solution is to combine this constraint + with :doc:`Type `. + Options ------- From feb165e67b54d3f46adce3cc7915afb7a5b835cc Mon Sep 17 00:00:00 2001 From: wkania Date: Sun, 14 Feb 2021 10:18:19 +0100 Subject: [PATCH 0492/5766] [Validator] Use import instead of FQCN --- reference/constraints/Type.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index 61189e7f989..a8920e655dd 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -64,11 +64,12 @@ This will check if ``id`` is an instance of ``Ramsey\Uuid\UuidInterface``, // src/Entity/Author.php namespace App\Entity; + use Ramsey\Uuid\UuidInterface; use Symfony\Component\Validator\Constraints as Assert; class Author { - #[Assert\Type('Ramsey\Uuid\UuidInterface')] + #[Assert\Type(UuidInterface::class)] protected $id; #[Assert\Type('string')] From d9b0a1dc6f7b1bb1cd9d5ef6939b5cc17ebec660 Mon Sep 17 00:00:00 2001 From: wkania Date: Sun, 14 Feb 2021 11:06:38 +0100 Subject: [PATCH 0493/5766] [Validator] Add PHP Attributes example to Compound --- reference/constraints/Compound.rst | 90 +++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst index 6e0ab5db139..a43899e7c24 100644 --- a/reference/constraints/Compound.rst +++ b/reference/constraints/Compound.rst @@ -23,27 +23,66 @@ Basic Usage Suppose that you have different places where a user password must be validated, you can create your own named set or requirements to be reused consistently everywhere:: - // src/Validator/Constraints/PasswordRequirements.php - namespace App\Validator\Constraints; - - use Symfony\Component\Validator\Constraints\Compound; - use Symfony\Component\Validator\Constraints as Assert; - - /** - * @Annotation - */ - class PasswordRequirements extends Compound - { - protected function getConstraints(array $options): array +.. configuration-block:: + + .. code-block:: php-annotations + + // src/Validator/Constraints/PasswordRequirements.php + namespace App\Validator\Constraints; + + use Symfony\Component\Validator\Constraints\Compound; + use Symfony\Component\Validator\Constraints as Assert; + + /** + * @Annotation + */ + class PasswordRequirements extends Compound { - return [ - new Assert\NotBlank(), - new Assert\Type('string'), - new Assert\Length(['min' => 12]), - new Assert\NotCompromisedPassword(), - ]; + protected function getConstraints(array $options): array + { + return [ + new Assert\NotBlank(), + new Assert\Type('string'), + new Assert\Length(['min' => 12]), + new Assert\NotCompromisedPassword(), + ]; + } } - } + + .. code-block:: php-attributes + + // src/Validator/Constraints/PasswordRequirements.php + namespace App\Validator\Constraints; + + use Symfony\Component\Validator\Constraints\Compound; + use Symfony\Component\Validator\Constraints as Assert; + + #[\Attribute] + class PasswordRequirements extends Compound + { + protected function getConstraints(array $options): array + { + return [ + new Assert\NotBlank(), + new Assert\Type('string'), + new Assert\Length(['min' => 12]), + new Assert\NotCompromisedPassword(), + ]; + } + } + +.. versionadded:: 5.2 + + The ability to use PHP attributes to configure constraints was introduced in + Symfony 5.2. Prior to this, Doctrine Annotations were the only way to + annotate constraints. + +.. note:: + + The ``@Annotation`` or ``#[\Attribute]`` annotation is necessary for this new constraint in + order to make it available for use in classes via annotations. + Options for your constraint are represented as public properties on the + constraint class. You can now use it anywhere you need it: @@ -64,6 +103,19 @@ You can now use it anywhere you need it: public $password; } + .. code-block:: php-attributes + + // src/User/RegisterUser.php + namespace App\User; + + use App\Validator\Constraints as AcmeAssert; + + class RegisterUser + { + #[AcmeAssert\PasswordRequirements] + public $password; + } + .. code-block:: yaml # config/validator/validation.yaml From 1a71a9c7f20a18ff78293c947a877b48874f027a Mon Sep 17 00:00:00 2001 From: wkania Date: Sun, 14 Feb 2021 11:13:43 +0100 Subject: [PATCH 0494/5766] [Validator] Add PHP Attribute as an annotation option in the description --- 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 8aaca8eb96a..d0d1c27d6f4 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -52,7 +52,7 @@ First you need to create a Constraint class and extend :class:`Symfony\\Componen .. note:: - The ``@Annotation`` annotation is necessary for this new constraint in + The ``@Annotation`` or ``#[\Attribute]`` annotation is necessary for this new constraint in order to make it available for use in classes via annotations. Options for your constraint are represented as public properties on the constraint class. From 4a3a9875df8846279ff62157f0182dad4d639a7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sun, 14 Feb 2021 15:27:24 +0100 Subject: [PATCH 0495/5766] Update documentation for deprecated "session.storage" service --- reference/configuration/framework.rst | 21 ++++++++----- session.rst | 44 +++++++++++++++++++-------- session/php_bridge.rst | 10 +++--- 3 files changed, 49 insertions(+), 26 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index d3baf76260a..b13f9f870f7 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -269,7 +269,7 @@ Configuration * `save_path`_ * `sid_length`_ * `sid_bits_per_character`_ - * `storage_id`_ + * `storage_factory_id`_ * `use_cookies`_ * `test`_ @@ -1443,19 +1443,24 @@ errors. session ~~~~~~~ -storage_id -.......... +storage_factory_id +.................. -**type**: ``string`` **default**: ``'session.storage.native'`` +**type**: ``string`` **default**: ``'session.storage.factory.native'`` -The service ID used for storing the session. The ``session.storage`` service -alias will be set to this service. The class has to implement -:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageInterface`. +The service ID used for creatig the ``SessionStorageInterface`` that will store +the session. The ``session.storage.factory`` service alias will be set to this +service. The class has to implement +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\SessionStorageFactoryInterface`. To see a list of all available storages, run: .. code-block:: terminal - $ php bin/console debug:container session.storage. + $ php bin/console debug:container session.storage.factory. + +.. versionadded:: 5.3 + + The ``storage_factory_id`` option was introduced in Symfony 5.3. .. _config-framework-session-handler-id: diff --git a/session.rst b/session.rst index 2727c3d617d..5a3fb69c09b 100644 --- a/session.rst +++ b/session.rst @@ -185,33 +185,51 @@ your ``Session`` object with the default ``AttributeBag`` by the ``NamespacedAtt .. code-block:: yaml # config/services.yaml - session_listener: + session.factory: autoconfigure: true - class: App\EventListener\SessionListener + class: App\Session\SessionFactory arguments: - - !service_locator - logger: '@?logger' - session_collector: '@?data_collector.request.session_collector' - session_storage: '@session.storage' - session_attributes: '@session.namespacedattributebag' - - '%kernel.debug%' + - '@request_stack' + - '@session.storage.factory' + - ['@session_listener', 'onSessionUsage'] + - '@session.namespacedattributebag' session.namespacedattributebag: class: Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag .. code-block:: php - namespace App\EventListener; + namespace App\Session; + use Symfony\Component\HttpFoundation\RequestStack; + use Symfony\Component\HttpFoundation\Session\Attribute\NamespacedAttributeBag; use Symfony\Component\HttpFoundation\Session\Session; use Symfony\Component\HttpFoundation\Session\SessionInterface; - use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener; + use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageFactoryInterface; - class SessionListener extends AbstractSessionListener + class SessionFactory { - protected function getSession(): ?SessionInterface + private $requestStack; + private $storageFactory; + private $usageReporter; + private $sessionAttributes; + + public function __construct(RequestStack $requestStack, SessionStorageFactoryInterface $storageFactory, callable $usageReporter, NamespacedAttributeBag $sessionAttributes) + { + $this->requestStack = $requestStack; + $this->storageFactory = $storageFactory; + $this->usageReporter = $usageReporter; + $this->sessionAttributes = $sessionAttributes; + } + + public function createSession(): SessionInterface { - return new Session($this->container->get('session_storage'), $this->container->get('session_attributes')); + return new Session( + $this->storageFactory->createStorage($this->requestStack->getMasterRequest()), + $this->sessionAttributes, + null, + $this->usageReporter + ); } } diff --git a/session/php_bridge.rst b/session/php_bridge.rst index 42c8644e2a7..ba7fc53d41a 100644 --- a/session/php_bridge.rst +++ b/session/php_bridge.rst @@ -18,7 +18,7 @@ for the ``handler_id``: # config/packages/framework.yaml framework: session: - storage_id: session.storage.php_bridge + storage_factory_id: session.storage.factory.php_bridge handler_id: ~ .. code-block:: xml @@ -32,7 +32,7 @@ for the ``handler_id``: https://symfony.com/schema/dic/services/services-1.0.xsd"> - @@ -43,7 +43,7 @@ for the ``handler_id``: // config/packages/framework.php $container->loadFromExtension('framework', [ 'session' => [ - 'storage_id' => 'session.storage.php_bridge', + 'storage_factory_id' => 'session.storage.factory.php_bridge', 'handler_id' => null, ], ]); @@ -60,7 +60,7 @@ the example below: # config/packages/framework.yaml framework: session: - storage_id: session.storage.php_bridge + storage_factory_id: session.storage.factory.php_bridge handler_id: session.handler.native_file .. code-block:: xml @@ -85,7 +85,7 @@ the example below: // config/packages/framework.php $container->loadFromExtension('framework', [ 'session' => [ - 'storage_id' => 'session.storage.php_bridge', + 'storage_factory_id' => 'session.storage.factory.php_bridge', 'handler_id' => 'session.storage.native_file', ], ]); From 3ff812d799a3abdfc64f72956fe0fa0bd2c955fd Mon Sep 17 00:00:00 2001 From: Beno!t POLASZEK Date: Sun, 14 Feb 2021 10:42:34 +0100 Subject: [PATCH 0496/5766] [DependencyInjection] Negated (not:) env var processor --- configuration/env_var_processors.rst | 40 ++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst index 407b5137fbc..2b42559911f 100644 --- a/configuration/env_var_processors.rst +++ b/configuration/env_var_processors.rst @@ -136,6 +136,46 @@ Symfony provides the following env var processors: 'http_method_override' => '%env(bool:HTTP_METHOD_OVERRIDE)%', ]); +``env(not:FOO)`` + + .. versionadded:: 5.3 + + The ``not:`` env var processor was introduced in Symfony 5.3. + + Casts ``FOO`` to a bool (just as ``env(bool:...)`` does) except it returns the inverted value + (falsy values are returned as ``true``, truthy values are returned as ``false``): + + .. configuration-block:: + + .. code-block:: yaml + + # config/services.yaml + parameters: + safe_for_production: '%env(not:APP_DEBUG)%' + + .. code-block:: xml + + + + + + + %env(not:APP_DEBUG)% + + + + + .. code-block:: php + + // config/services.php + $container->setParameter('safe_for_production', '%env(not:APP_DEBUG)%'); + ``env(int:FOO)`` Casts ``FOO`` to an int. From ad5a890da80c79eefff709a62ce78362c99eaee7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Schl=C3=A4pfer?= Date: Thu, 11 Feb 2021 18:06:33 +0100 Subject: [PATCH 0497/5766] improve documentation for mailer failover and round-robin transports --- mailer.rst | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mailer.rst b/mailer.rst index 58531bf85f3..ff567eab3bc 100644 --- a/mailer.rst +++ b/mailer.rst @@ -186,9 +186,9 @@ A failover transport is configured with two or more transports and the MAILER_DSN="failover(postmark+api://ID@default sendgrid+smtp://KEY@default)" -The mailer will start using the first transport. If the sending fails, the -mailer won't retry it with the other transports, but it will switch to the next -transport automatically for the following deliveries. +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). Load Balancing ~~~~~~~~~~~~~~ @@ -203,9 +203,12 @@ A round-robin transport is configured with two or more transports and the MAILER_DSN="roundrobin(postmark+api://ID@default sendgrid+smtp://KEY@default)" -The mailer will start 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). +The round-robin transport starts with a *randomly* selected transport and +then switches to the next available transport for each subsequent email. + +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. Creating & Sending Messages --------------------------- From 7512515581be517ef92af7198eecedfea440242f Mon Sep 17 00:00:00 2001 From: Timo Bakx Date: Sun, 14 Feb 2021 17:07:14 +0100 Subject: [PATCH 0498/5766] [Security] Added debug:firewall command --- reference/configuration/security.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index d4a37758798..3c7980c153f 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -472,6 +472,26 @@ depend on the authentication mechanism, which can be any of these: http_digest: # ... +You can view actual information about the firewalls in your application with +the ``debug:firewall`` command: + +.. code-block:: terminal + + # displays a list of firewalls currently configured for your application + $ php bin/console debug:firewall + + # displays the details of a specific firewall + $ php bin/console debug:firewall main + + # displays the details of a specific firewall, including detailed information + # about the event listeners for the firewall + $ php bin/console debug:firewall main --include-listeners + +.. versionadded:: 5.3 + + The ``debug:firewall`` command was introduced in Symfony 5.3. + + .. _reference-security-firewall-form-login: ``form_login`` Authentication From 8a614ebc3df768f427f3e514488256172dc67b86 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Feb 2021 09:13:56 +0100 Subject: [PATCH 0499/5766] Minor reword --- validation/custom_constraint.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/validation/custom_constraint.rst b/validation/custom_constraint.rst index d0d1c27d6f4..5f85cb9092e 100644 --- a/validation/custom_constraint.rst +++ b/validation/custom_constraint.rst @@ -44,19 +44,16 @@ First you need to create a Constraint class and extend :class:`Symfony\\Componen public $message = 'The string "{{ string }}" contains an illegal character: it can only contain letters or numbers.'; } +Add ``@Annotation`` or ``#[\Attribute]`` to the constraint class if you want to +use it as an annotation/attribute in other classes. If the constraint has +configuration options, define them as public properties on the constraint class. + .. versionadded:: 5.2 The ability to use PHP attributes to configure constraints was introduced in Symfony 5.2. Prior to this, Doctrine Annotations were the only way to annotate constraints. -.. note:: - - The ``@Annotation`` or ``#[\Attribute]`` annotation is necessary for this new constraint in - order to make it available for use in classes via annotations. - Options for your constraint are represented as public properties on the - constraint class. - Creating the Validator itself ----------------------------- From c2a3742020fc3e683f108dcd09722bdaafb781c9 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Feb 2021 09:43:41 +0100 Subject: [PATCH 0500/5766] Tweak --- reference/configuration/framework.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index b13f9f870f7..5c0989c8afc 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1448,9 +1448,9 @@ storage_factory_id **type**: ``string`` **default**: ``'session.storage.factory.native'`` -The service ID used for creatig the ``SessionStorageInterface`` that will store -the session. The ``session.storage.factory`` service alias will be set to this -service. The class has to implement +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: From d6a73143447ae1f5446d3d24e814f3dbcc0191d8 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Mon, 15 Feb 2021 07:10:34 +0100 Subject: [PATCH 0501/5766] [Messenger] Remove duplicated Redis transport requirements The Redis transport requirements has been presented twice. I mean the following sentences: "This transport requires the Redis PHP extension (>=4.3) and a running Redis server (^5.0)." and "To use the Redis transport, you will need the Redis PHP extension (>=4.3) and a running Redis server (^5.0).". --- messenger.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/messenger.rst b/messenger.rst index c2773c0c674..19736f3df4b 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1164,9 +1164,6 @@ The Redis transport DSN may looks like this: The Unix socket DSN was introduced in Symfony 5.1. -To use the Redis transport, you will need the Redis PHP extension (>=4.3) and -a running Redis server (^5.0). - A number of options can be configured via the DSN or via the ``options`` key under the transport in ``messenger.yaml``: From d101f1ce537efcb613f019cbddba4ef5e148fd0a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Feb 2021 09:48:24 +0100 Subject: [PATCH 0502/5766] Added a previous reference --- reference/configuration/framework.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 5c0989c8afc..d9772a772cc 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1443,6 +1443,8 @@ errors. session ~~~~~~~ +.. _storage_id: + storage_factory_id .................. From 6c8bbd602c018997171fa5152e342de29d9c7770 Mon Sep 17 00:00:00 2001 From: Mohameth Date: Sat, 13 Feb 2021 21:06:29 +0100 Subject: [PATCH 0503/5766] Update lock documentation for more clarity In response to https://github.com/symfony/symfony-docs/issues/9367, I also had some understanding the meaning. --- components/lock.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index 16049101e10..7651dd19caf 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -62,9 +62,10 @@ method can be safely called repeatedly, even if the lock is already acquired. .. note:: Unlike other implementations, the Lock Component distinguishes locks - instances even when they are created for the same resource. If a lock has - to be used by several services, they should share the same ``Lock`` instance - returned by the ``LockFactory::createLock`` method. + instances even when they are created for the same resource. It means that for + a given scope and resource one lock instance can be acquired multiple times. + If a lock has to be used by several services, they should share the same ``Lock`` + instance returned by the ``LockFactory::createLock`` method. .. tip:: From ce5d6693b6715a00c461d50a5c35f827b8290f66 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Feb 2021 10:56:38 +0100 Subject: [PATCH 0504/5766] Tweak --- components/lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lock.rst b/components/lock.rst index 7651dd19caf..8e83fed5c9d 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -61,7 +61,7 @@ method can be safely called repeatedly, even if the lock is already acquired. .. note:: - Unlike other implementations, the Lock Component distinguishes locks + Unlike other implementations, the Lock Component distinguishes lock instances even when they are created for the same resource. It means that for a given scope and resource one lock instance can be acquired multiple times. If a lock has to be used by several services, they should share the same ``Lock`` From 915b0d57ae5a1fa0c7c8f8cd047824e6b2160247 Mon Sep 17 00:00:00 2001 From: Nicolas Hart Date: Mon, 15 Feb 2021 12:08:27 +0100 Subject: [PATCH 0505/5766] [Encore] fix typo fronts instead of fonts --- frontend/encore/url-loader.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/encore/url-loader.rst b/frontend/encore/url-loader.rst index 9567960c99d..ff8be75aedc 100644 --- a/frontend/encore/url-loader.rst +++ b/frontend/encore/url-loader.rst @@ -1,4 +1,4 @@ -Inlining Images & Fronts in CSS +Inlining Images & Fonts in CSS =============================== A simple technique to improve the performance of web applications is to reduce From 77744242d2ac155c265ad2bc785c31adfb5819cc Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Mon, 15 Feb 2021 12:28:58 +0100 Subject: [PATCH 0506/5766] Fix length of underline --- frontend/encore/url-loader.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/encore/url-loader.rst b/frontend/encore/url-loader.rst index ff8be75aedc..5e89234f295 100644 --- a/frontend/encore/url-loader.rst +++ b/frontend/encore/url-loader.rst @@ -1,5 +1,5 @@ Inlining Images & Fonts in CSS -=============================== +============================== A simple technique to improve the performance of web applications is to reduce the number of HTTP requests inlining small files as base64 encoded URLs in the From fa054e6fb06380a198f9301272797bb273df154b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Deruss=C3=A9?= Date: Sat, 13 Feb 2021 16:26:35 +0100 Subject: [PATCH 0507/5766] [Doctrine] Add documentation about doctrine.event_subscriber priority --- doctrine/events.rst | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/doctrine/events.rst b/doctrine/events.rst index 3eea84aff4f..16c51734411 100644 --- a/doctrine/events.rst +++ b/doctrine/events.rst @@ -166,7 +166,7 @@ with the ``doctrine.event_listener`` tag: # this is the only required option for the lifecycle listener tag event: 'postPersist' - # listeners can define their priority in case multiple listeners are associated + # listeners 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 @@ -184,7 +184,7 @@ with the ``doctrine.event_listener`` tag: @@ -213,7 +213,7 @@ with the ``doctrine.event_listener`` tag: // this is the only required option for the lifecycle listener tag 'event' => 'postPersist', - // listeners can define their priority in case multiple listeners are associated + // listeners 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, @@ -428,7 +428,14 @@ with the ``doctrine.event_subscriber`` tag: App\EventListener\DatabaseActivitySubscriber: tags: - - { name: 'doctrine.event_subscriber' } + - 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 @@ -439,8 +446,15 @@ with the ``doctrine.event_subscriber`` tag: + - + + + @@ -456,7 +470,14 @@ with the ``doctrine.event_subscriber`` tag: $services = $configurator->services(); $services->set(DatabaseActivitySubscriber::class) - ->tag('doctrine.event_subscriber') + ->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', + ]) ; }; @@ -505,6 +526,10 @@ can do it in the service configuration: ; }; +.. versionadded:: 5.3 + + Handling priority for subscribers alongside listeners has been introduced in Symfony 5.3. + .. tip:: Symfony loads (and instantiates) Doctrine subscribers whenever the From 2c082536f083677436f835f675d40f1cc898736d Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Feb 2021 13:10:56 +0100 Subject: [PATCH 0508/5766] Tweak --- doctrine/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/events.rst b/doctrine/events.rst index 16c51734411..bce3b6873e9 100644 --- a/doctrine/events.rst +++ b/doctrine/events.rst @@ -528,7 +528,7 @@ can do it in the service configuration: .. versionadded:: 5.3 - Handling priority for subscribers alongside listeners has been introduced in Symfony 5.3. + Subscriber priority was introduced in Symfony 5.3. .. tip:: From b920cfd7cd37500b2733b6754fc26e6dc94c7ce2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 16 Feb 2021 15:18:31 +0100 Subject: [PATCH 0509/5766] Tweak --- reference/constraints/Compound.rst | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst index a43899e7c24..53ce70c6df2 100644 --- a/reference/constraints/Compound.rst +++ b/reference/constraints/Compound.rst @@ -71,19 +71,16 @@ you can create your own named set or requirements to be reused consistently ever } } +Add ``@Annotation`` or ``#[\Attribute]`` to the constraint class if you want to +use it as an annotation/attribute in other classes. If the constraint has +configuration options, define them as public properties on the constraint class. + .. versionadded:: 5.2 The ability to use PHP attributes to configure constraints was introduced in Symfony 5.2. Prior to this, Doctrine Annotations were the only way to annotate constraints. -.. note:: - - The ``@Annotation`` or ``#[\Attribute]`` annotation is necessary for this new constraint in - order to make it available for use in classes via annotations. - Options for your constraint are represented as public properties on the - constraint class. - You can now use it anywhere you need it: .. configuration-block:: From 294972523d69eeb78e89ba96b579f9ce2652de1e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 16 Feb 2021 17:17:02 +0100 Subject: [PATCH 0510/5766] Reword --- messenger.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/messenger.rst b/messenger.rst index b8819c33c4a..17f894fd0e5 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1981,12 +1981,12 @@ Other Middlewares .. versionadded:: 5.3 - The ``router_context`` middleware were introduced in Symfony 5.3. + The ``router_context`` middleware was introduced in Symfony 5.3. -When the consumer needs to build an absolute URL, for instance: rendering a -template with links, it needs the initial's request context in order to -retrieves the domain and information needed to build the URL. This can be -achieved by declaring the ``router_context`` middleware in the bus. +Add the ``router_context`` middleware if you need to generate absolute URLs in +the consumer (e.g. render a template with links). This middleware stores the +original request context (i.e. the host, the HTTP port, etc.) which is needed +when building absolute URLs. .. configuration-block:: From f085b3262ec80df720768dbd30cd17de846fdd5c Mon Sep 17 00:00:00 2001 From: wkania Date: Tue, 16 Feb 2021 20:17:39 +0100 Subject: [PATCH 0511/5766] [Validator] Use single quotes for a string --- validation/groups.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/groups.rst b/validation/groups.rst index b25c82236fc..7681f583a08 100644 --- a/validation/groups.rst +++ b/validation/groups.rst @@ -123,7 +123,7 @@ user registers and when a user updates their contact information later: ])); $metadata->addPropertyConstraint('city', new Assert\Length([ - "min" => 2, + 'min' => 2, ])); } } From 462f27fcedade2bfc6b2542d70b48be6ee383517 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 17 Feb 2021 09:05:23 +0100 Subject: [PATCH 0512/5766] Minor fix --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 2cd18d823bd..f3610db7a00 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1324,7 +1324,7 @@ The SQS transport DSN may looks like this: .. code-block:: env # .env - MESSENGER_TRANSPORT_DSN=https://sqs.eu-west-3.amazonaws.com/123456789012/messages?access_key= AKIAIOSFODNN7EXAMPLE&secret_key=j17M97ffSVoKI0briFoo9a + MESSENGER_TRANSPORT_DSN=https://sqs.eu-west-3.amazonaws.com/123456789012/messages?access_key=AKIAIOSFODNN7EXAMPLE&secret_key=j17M97ffSVoKI0briFoo9a MESSENGER_TRANSPORT_DSN=sqs://localhost:9494/messages?sslmode=disable .. note:: From dca6cf4a5aee042b33929f9fc1e9a50562d34191 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 17 Feb 2021 09:52:54 +0100 Subject: [PATCH 0513/5766] [Security] bcrypt is the new default hasher for native/auto --- best_practices.rst | 2 +- security.rst | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/best_practices.rst b/best_practices.rst index 5f137d492c1..be3486e355b 100644 --- a/best_practices.rst +++ b/best_practices.rst @@ -368,7 +368,7 @@ Use the ``auto`` Password Hasher The :ref:`auto password hasher ` automatically selects the best possible encoder/hasher depending on your PHP installation. -Currently, it tries to use ``sodium`` by default and falls back to ``bcrypt``. +Starting from Symfony 5.3, the default auto hasher is ``bcrypt``. Use Voters to Implement Fine-grained Security Restrictions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/security.rst b/security.rst index 3b9341a07d6..c91db7be29a 100644 --- a/security.rst +++ b/security.rst @@ -219,9 +219,8 @@ command will pre-configure this for you: encoders: # use your user class name here App\Entity\User: - # Use native password encoder - # This value auto-selects the best possible hashing algorithm - # (i.e. Sodium when available). + # Use native password encoder, which auto-selects the best + # possible hashing algorithm (starting from Symfony 5.3 this is "bcrypt") algorithm: auto .. code-block:: xml From a74de75dde9029e83192bfe156272c71f01e4891 Mon Sep 17 00:00:00 2001 From: Thijs-jan Veldhuizen Date: Wed, 17 Feb 2021 15:53:19 +0100 Subject: [PATCH 0514/5766] Update monolog_console.rst --- logging/monolog_console.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/logging/monolog_console.rst b/logging/monolog_console.rst index 5c0263c5349..21c67d705d8 100644 --- a/logging/monolog_console.rst +++ b/logging/monolog_console.rst @@ -67,6 +67,16 @@ the console. If they are displayed, they are timestamped and colored appropriate Additionally, error logs are written to the error output (``php://stderr``). There is no need to conditionally handle the verbosity settings anymore. +=============== ======================================= ============ +LoggerInterface Verbosity Command line +=============== ======================================= ============ +->error() OutputInterface::VERBOSITY_QUIET stderr +->warning() OutputInterface::VERBOSITY_NORMAL stdout +->notice() OutputInterface::VERBOSITY_VERBOSE -v +->info() OutputInterface::VERBOSITY_VERY_VERBOSE -vv +->debug() OutputInterface::VERBOSITY_DEBUG -vvv +=============== ======================================= ============ + The Monolog console handler is enabled by default: .. configuration-block:: From 25c0716f376796104c3ecebeb839305c07672024 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 17 Feb 2021 17:21:03 +0100 Subject: [PATCH 0515/5766] Add reference to commit message conventions --- contributing/code/conventions.rst | 6 +++--- contributing/code/pull_requests.rst | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/contributing/code/conventions.rst b/contributing/code/conventions.rst index 3174ac93660..0b50de6885f 100644 --- a/contributing/code/conventions.rst +++ b/contributing/code/conventions.rst @@ -99,9 +99,9 @@ conventions: * No third level sections are allowed; -* Messages should follow the commit message conventions: should be short, - capitalize the line, do not end with a period, use an imperative verb to - start the line; +* Messages should follow the :ref:`commit message conventions `: + should be short, capitalize the line, do not end with a period, use an + imperative verb to start the line; * New entries must be added on top of the list. diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst index e69371e9d5e..1cb0da6dddc 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -224,6 +224,8 @@ in mind the following: * Never fix coding standards in some existing code as it makes the code review more difficult; +.. _commit-messages: + * Write good commit messages: Start by a short subject line (the first line), followed by a blank line and a more detailed description. From 251304e424f26a2dad7cd1d594a17ec23e333f93 Mon Sep 17 00:00:00 2001 From: wkania Date: Wed, 17 Feb 2021 19:13:44 +0100 Subject: [PATCH 0516/5766] [Validator] Use null coalescing operator instead of ternary operator --- validation/severity.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/severity.rst b/validation/severity.rst index 23b81145ee9..7a8c22298fd 100644 --- a/validation/severity.rst +++ b/validation/severity.rst @@ -137,7 +137,7 @@ method. Each constraint exposes the attached payload as a public property:: // Symfony\Component\Validator\ConstraintViolation $constraintViolation = ...; $constraint = $constraintViolation->getConstraint(); - $severity = isset($constraint->payload['severity']) ? $constraint->payload['severity'] : null; + $severity = $constraint->payload['severity'] ?? null; For example, you can leverage this to customize the ``form_errors`` block so that the severity is added as an additional HTML class: From 2de6e69f9d628cca316fa5549e4a50d51201dd84 Mon Sep 17 00:00:00 2001 From: Tamcy Date: Thu, 18 Feb 2021 13:29:18 +0800 Subject: [PATCH 0517/5766] Update the default `cookie_secure` value The default and special `cookie_secure` value should be `'auto'`, not `null`. --- 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 d3baf76260a..2636bee4a2b 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1589,10 +1589,10 @@ The possible values for this option are: cookie_secure ............. -**type**: ``boolean`` or ``null`` **default**: ``null`` +**type**: ``boolean`` or ``'auto'`` **default**: ``'auto'`` This determines whether cookies should only be sent over secure connections. In -addition to ``true`` and ``false``, there's a special ``null`` value that +addition to ``true`` and ``false``, there's a special ``'auto'`` value that means ``true`` for HTTPS requests and ``false`` for HTTP requests. cookie_httponly From 4f851e84f2a4372cdc259359bf51eded04ecde06 Mon Sep 17 00:00:00 2001 From: wkania Date: Wed, 17 Feb 2021 19:42:10 +0100 Subject: [PATCH 0518/5766] [Validator] Use import instead of FQCN --- form/dynamic_form_modification.rst | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/form/dynamic_form_modification.rst b/form/dynamic_form_modification.rst index 279b5b4118d..7c52e5f3abd 100644 --- a/form/dynamic_form_modification.rst +++ b/form/dynamic_form_modification.rst @@ -377,6 +377,8 @@ sport like this:: // src/Form/Type/SportMeetupType.php namespace App\Form\Type; + use App\Entity\Position; + use App\Entity\Sport; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; @@ -390,7 +392,7 @@ sport like this:: { $builder ->add('sport', EntityType::class, [ - 'class' => 'App\Entity\Sport', + 'class' => Sport::class, 'placeholder' => '', ]) ; @@ -407,7 +409,7 @@ sport like this:: $positions = null === $sport ? [] : $sport->getAvailablePositions(); $form->add('position', EntityType::class, [ - 'class' => 'App\Entity\Position', + 'class' => Position::class, 'placeholder' => '', 'choices' => $positions, ]); @@ -443,6 +445,7 @@ The type would now look like:: // src/Form/Type/SportMeetupType.php namespace App\Form\Type; + use App\Entity\Position; use App\Entity\Sport; use Symfony\Bridge\Doctrine\Form\Type\EntityType; use Symfony\Component\Form\FormInterface; @@ -454,7 +457,7 @@ The type would now look like:: { $builder ->add('sport', EntityType::class, [ - 'class' => 'App\Entity\Sport', + 'class' => Sport::class, 'placeholder' => '', ]) ; @@ -463,7 +466,7 @@ The type would now look like:: $positions = null === $sport ? [] : $sport->getAvailablePositions(); $form->add('position', EntityType::class, [ - 'class' => 'App\Entity\Position', + 'class' => Position::class, 'placeholder' => '', 'choices' => $positions, ]); From 7948311afca73fc192531e03575382fd9783ac5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Schl=C3=A4pfer?= Date: Wed, 17 Feb 2021 16:15:05 +0100 Subject: [PATCH 0519/5766] fix specifying http_version in YAML --- http_client.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/http_client.rst b/http_client.rst index 91122c00961..6add04b711e 100644 --- a/http_client.rst +++ b/http_client.rst @@ -750,7 +750,8 @@ the ``http_version`` option: # config/packages/framework.yaml framework: http_client: - http_version: '2.0' + default_options: + http_version: '2.0' .. code-block:: xml From cb5764ad53359ca859abec4c00972f23df69d3ad Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 18 Feb 2021 15:03:54 +0100 Subject: [PATCH 0520/5766] Updated XML and PHP configs too --- http_client.rst | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/http_client.rst b/http_client.rst index 6add04b711e..be195f2008d 100644 --- a/http_client.rst +++ b/http_client.rst @@ -765,7 +765,9 @@ the ``http_version`` option: http://symfony.com/schema/dic/symfony https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - + + + @@ -774,7 +776,9 @@ the ``http_version`` option: // config/packages/framework.php $container->loadFromExtension('framework', [ 'http_client' => [ - 'http_version' => '2.0', + 'default_options' => [ + 'http_version' => '2.0', + ], ], ]); From d44bfa826d7ea3dc438999d81cd0dd36a8f29516 Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Sun, 14 Feb 2021 22:57:48 -0500 Subject: [PATCH 0521/5766] Promoting new bundle directory structure as best practice --- bundles/best_practices.rst | 107 +++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 39 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index 696c9da58ff..bf32457cd81 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -68,30 +68,47 @@ The basic directory structure of an AcmeBlogBundle must read as follows: .. code-block:: text / - ├─ AcmeBlogBundle.php - ├─ Controller/ - ├─ README.md - ├─ LICENSE - ├─ Resources/ - │ ├─ config/ - │ ├─ doc/ - │ │ └─ index.rst - │ ├─ translations/ - │ ├─ views/ - │ └─ public/ - └─ Tests/ + ├── config/ + ├── docs/ + │ └─ index.md + ├── public/ + ├── src/ + │ ├── Controller/ + │ ├── DependencyInjection/ + │ └── AcmeBlogBundle.php + ├── templates/ + ├── tests/ + ├── translations/ + ├── LICENSE + └── README.md + +.. versionadded:: 4.4 + + This directory convention was introduced in Symfony 4.4 and can be used only when requiring + ``symfony/http-kernel`` 4.4 or superior. + + +and the bundle path must be adjusted to the root directory:: + + class AcmeBlogBundle extends Bundle + { + public function getPath(): string + { + return \dirname(__DIR__); + } + } **The following files are mandatory**, because they ensure a structure convention that automated tools can rely on: -* ``AcmeBlogBundle.php``: This is the class that transforms a plain directory +* ``src/AcmeBlogBundle.php``: This is the class that transforms a plain directory into a Symfony bundle (change this to your bundle's name); * ``README.md``: This file contains the basic description of the bundle and it usually shows some basic examples and links to its full documentation (it can use any of the markup formats supported by GitHub, such as ``README.rst``); * ``LICENSE``: The full contents of the license used by the code. Most third-party bundles are published under the MIT license, but you can `choose any license`_; -* ``Resources/doc/index.rst``: The root file for the Bundle documentation. +* ``docs/index.md``: The root file for the Bundle documentation. The depth of subdirectories should be kept to a minimum for the most used classes and files. Two levels is the maximum. @@ -107,19 +124,19 @@ and others are just conventions followed by most developers): =================================================== ======================================== Type Directory =================================================== ======================================== -Commands ``Command/`` -Controllers ``Controller/`` -Service Container Extensions ``DependencyInjection/`` -Doctrine ORM entities (when not using annotations) ``Entity/`` -Doctrine ODM documents (when not using annotations) ``Document/`` -Event Listeners ``EventListener/`` -Configuration (routes, services, etc.) ``Resources/config/`` -Web Assets (CSS, JS, images) ``Resources/public/`` -Translation files ``Resources/translations/`` -Validation (when not using annotations) ``Resources/config/validation/`` -Serialization (when not using annotations) ``Resources/config/serialization/`` -Templates ``Resources/views/`` -Unit and Functional Tests ``Tests/`` +Commands ``src/Command/`` +Controllers ``src/Controller/`` +Service Container Extensions ``src/DependencyInjection/`` +Doctrine ORM entities (when not using annotations) ``src/Entity/`` +Doctrine ODM documents (when not using annotations) ``src/Document/`` +Event Listeners ``src/EventListener/`` +Configuration (routes, services, etc.) ``config/`` +Web Assets (CSS, JS, images) ``public/`` +Translation files ``translations/`` +Validation (when not using annotations) ``config/validation/`` +Serialization (when not using annotations) ``config/serialization/`` +Templates ``templates/`` +Unit and Functional Tests ``tests/`` =================================================== ======================================== Classes @@ -127,7 +144,7 @@ Classes The bundle directory structure is used as the namespace hierarchy. For instance, a ``ContentController`` controller which is stored in -``Acme/BlogBundle/Controller/ContentController.php`` would have the fully +``src/Controller/ContentController.php`` would have the fully qualified class name of ``Acme\BlogBundle\Controller\ContentController``. All classes and files must follow the :doc:`Symfony coding standards `. @@ -153,7 +170,7 @@ Tests ----- A bundle should come with a test suite written with PHPUnit and stored under -the ``Tests/`` directory. Tests should follow the following principles: +the ``tests/`` directory. Tests should follow the following principles: * The test suite must be executable with a simple ``phpunit`` command run from a sample application; @@ -240,10 +257,10 @@ Documentation All classes and functions must come with full PHPDoc. -Extensive documentation should also be provided in the ``Resources/doc/`` +Extensive documentation should also be provided in the ``docs/`` directory. -The index file (for example ``Resources/doc/index.rst`` or -``Resources/doc/index.md``) is the only mandatory file and must be the entry +The index file (for example ``docs/index.rst`` or +``docs/index.md``) is the only mandatory file and must be the entry point for the documentation. The :doc:`reStructuredText (rST) ` is the format used to render the documentation on the Symfony website. @@ -480,10 +497,22 @@ The ``composer.json`` file should include at least the following metadata: This information is used by Symfony to load the classes of the bundle. It's recommended to use the `PSR-4`_ autoload standard: use the namespace as key, and the location of the bundle's main class (relative to ``composer.json``) - as value. For example, if the main class is located in the bundle root - directory: ``"autoload": { "psr-4": { "SomeVendor\\BlogBundle\\": "" } }``. - If the main class is located in the ``src/`` directory of the bundle: - ``"autoload": { "psr-4": { "SomeVendor\\BlogBundle\\": "src/" } }``. + as value. As the main class is located in the ``src/`` directory of the bundle: + + .. code-block:: json + + { + "autoload": { + "psr-4": { + "Acme\\BlogBundle\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Acme\\BlogBundle\\Tests\\": "tests/" + } + } + } In order to make it easier for developers to find your bundle, register it on `Packagist`_, the official repository for Composer packages. @@ -493,15 +522,15 @@ Resources If the bundle references any resources (config files, translation files, etc.), don't use physical paths (e.g. ``__DIR__/config/services.xml``) but logical -paths (e.g. ``@FooBundle/Resources/config/services.xml``). +paths (e.g. ``@AcmeBlogBundle/config/services.xml``). The logical paths are required because of the bundle overriding mechanism that lets you override any resource/file of any bundle. See :ref:`http-kernel-resource-locator` for more details about transforming physical paths into logical paths. Beware that templates use a simplified version of the logical path shown above. -For example, an ``index.html.twig`` template located in the ``Resources/views/Default/`` -directory of the FooBundle, is referenced as ``@Foo/Default/index.html.twig``. +For example, an ``index.html.twig`` template located in the ``templates/Default/`` +directory of the AcmeBlogBundle, is referenced as ``@AcmeBlog/Default/index.html.twig``. Learn more ---------- From 36421ad60206b79bf1fb5d701dac7c480ddd474e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 18 Feb 2021 15:50:36 +0100 Subject: [PATCH 0522/5766] Tweaks --- bundles/best_practices.rst | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index bf32457cd81..9c615c46db1 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -63,7 +63,7 @@ configuration options (see below for some usage examples). Directory Structure ------------------- -The basic directory structure of an AcmeBlogBundle must read as follows: +The following is the recommended directory structure of an AcmeBlogBundle: .. code-block:: text @@ -84,11 +84,11 @@ The basic directory structure of an AcmeBlogBundle must read as follows: .. versionadded:: 4.4 - This directory convention was introduced in Symfony 4.4 and can be used only when requiring - ``symfony/http-kernel`` 4.4 or superior. + This directory convention was introduced in Symfony 4.4 and can be used only + when requiring ``symfony/http-kernel`` 4.4 or superior. - -and the bundle path must be adjusted to the root directory:: +This directory structure requires to configure the bundle path to its root +directory as follows:: class AcmeBlogBundle extends Bundle { From 564378a49437963665578bd389209d803f56213c Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Thu, 18 Feb 2021 16:08:32 +0100 Subject: [PATCH 0523/5766] Removed an unnecessary versionadded directive --- bundles/best_practices.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/bundles/best_practices.rst b/bundles/best_practices.rst index 29d8008b896..bf0138ddec8 100644 --- a/bundles/best_practices.rst +++ b/bundles/best_practices.rst @@ -82,11 +82,6 @@ The following is the recommended directory structure of an AcmeBlogBundle: ├── LICENSE └── README.md -.. versionadded:: 4.4 - - This directory convention was introduced in Symfony 4.4 and can be used only - when requiring ``symfony/http-kernel`` 4.4 or superior. - This directory structure requires to configure the bundle path to its root directory as follows:: From f37c6bed41b3c755b31bc04c70cdc8baa6cab587 Mon Sep 17 00:00:00 2001 From: Nietono <8806554+nietonchique@users.noreply.github.com> Date: Fri, 29 Jan 2021 03:03:50 +0300 Subject: [PATCH 0524/5766] Update Type.rst Change Ramsey to symfony/uid --- reference/constraints/Type.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index 8aa0edd1ba2..aa48a17ca6d 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -18,7 +18,7 @@ Validator :class:`Symfony\\Component\\Validator\\Constraints\\TypeValidator` Basic Usage ----------- -This will check if ``id`` is an instance of ``Ramsey\Uuid\UuidInterface``, +This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, ``firstName`` is of type ``string`` (using :phpfunction:`is_string` PHP function), ``age`` is an ``integer`` (using :phpfunction:`is_int` PHP function) and ``accessCode`` contains either only letters or only digits (using @@ -36,7 +36,7 @@ This will check if ``id`` is an instance of ``Ramsey\Uuid\UuidInterface``, class Author { /** - * @Assert\Type("Ramsey\Uuid\UuidInterface") + * @Assert\Type("Symfony\Component\Uid\Uid") */ protected $id; From e229b93002bab30207ccba82c36091d7c65b7367 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 19 Feb 2021 17:29:09 +0100 Subject: [PATCH 0525/5766] Reworded the example --- reference/constraints/Type.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index aa48a17ca6d..103ea9fd43c 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -18,7 +18,7 @@ Validator :class:`Symfony\\Component\\Validator\\Constraints\\TypeValidator` Basic Usage ----------- -This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, +This will check if ``emailAddress`` is an instance of ``Symfony\Component\Mime\Address``, ``firstName`` is of type ``string`` (using :phpfunction:`is_string` PHP function), ``age`` is an ``integer`` (using :phpfunction:`is_int` PHP function) and ``accessCode`` contains either only letters or only digits (using @@ -36,9 +36,9 @@ This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, class Author { /** - * @Assert\Type("Symfony\Component\Uid\Uid") + * @Assert\Type("Symfony\Component\Mime\Address") */ - protected $id; + protected $emailAddress; /** * @Assert\Type("string") @@ -64,8 +64,8 @@ This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, # config/validator/validation.yaml App\Entity\Author: properties: - id: - - Type: Ramsey\Uuid\UuidInterface + emailAddress: + - Type: Symfony\Component\Mime\Address firstName: - Type: string @@ -88,9 +88,9 @@ This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, xsi:schemaLocation="http://symfony.com/schema/dic/constraint-mapping https://symfony.com/schema/dic/constraint-mapping/constraint-mapping-1.0.xsd"> - + - + @@ -120,7 +120,7 @@ This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, // src/Entity/Author.php namespace App\Entity; - use Ramsey\Uuid\UuidInterface; + use Symfony\Component\Mime\Address; use Symfony\Component\Validator\Constraints as Assert; use Symfony\Component\Validator\Mapping\ClassMetadata; @@ -128,7 +128,7 @@ This will check if ``id`` is an instance of ``Symfony\Component\Uid\Uid``, { public static function loadValidatorMetadata(ClassMetadata $metadata) { - $metadata->addPropertyConstraint('id', new Assert\Type(UuidInterface::class)); + $metadata->addPropertyConstraint('emailAddress', new Assert\Type(Address::class)); $metadata->addPropertyConstraint('firstName', new Assert\Type('string')); From fd8791b7b1e379118b5c7920dfbfa8ca7fb6dba2 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 19 Feb 2021 17:31:22 +0100 Subject: [PATCH 0526/5766] Updated the example of PHP attributes --- reference/constraints/Type.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index c557c26fe7c..ab56be81276 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -64,13 +64,13 @@ This will check if ``emailAddress`` is an instance of ``Symfony\Component\Mime\A // src/Entity/Author.php namespace App\Entity; - use Ramsey\Uuid\UuidInterface; + use Symfony\Component\Mime\Address; use Symfony\Component\Validator\Constraints as Assert; class Author { - #[Assert\Type(UuidInterface::class)] - protected $id; + #[Assert\Type(Address::class)] + protected $emailAddress; #[Assert\Type('string')] protected $firstName; From 9a8101f544cfc4e361f5d8bf0aa8a2ef188e3ee3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 19 Feb 2021 17:38:28 +0100 Subject: [PATCH 0527/5766] Tweaks --- http_client.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/http_client.rst b/http_client.rst index d541c5933b4..185e4a972cd 100644 --- a/http_client.rst +++ b/http_client.rst @@ -120,7 +120,7 @@ You can configure the global options using the ``default_options`` option: - + @@ -179,7 +179,7 @@ The HTTP client also has one configuration option called - + @@ -502,8 +502,7 @@ associative array via the ``query`` option, that will be merged with the URL:: Headers ~~~~~~~ -Use the ``headers`` option to define both the default headers added to all -requests and the specific headers for each request: +Use the ``headers`` option to define the default headers added to all requests: .. configuration-block:: @@ -511,8 +510,8 @@ requests and the specific headers for each request: # config/packages/framework.yaml framework: - default_options: - http_client: + http_client: + default_options: headers: 'User-Agent': 'My Fancy App' @@ -532,7 +531,7 @@ requests and the specific headers for each request: My Fancy App - + @@ -558,6 +557,8 @@ requests and the specific headers for each request: ], ]); +You can also set new headers or override the default ones for specific requests: + .. code-block:: php // this header is only included in this request and overrides the value @@ -772,7 +773,7 @@ the ``http_version`` option: - + From f4dbec46fff2b37f062d0221bf05efd36e20b015 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20TAMARELLE?= Date: Thu, 1 Oct 2020 01:28:00 +0200 Subject: [PATCH 0528/5766] [Framework] Add tag assets.package --- reference/dic_tags.rst | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index 0aca3c91777..2e4c7e5b339 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -12,6 +12,7 @@ application there could be more tags available provided by third-party bundles: Tag Name Usage ======================================== ======================================================================== `auto_alias`_ Define aliases based on the value of container parameters +`assets.package`_ Add an asset package `console.command`_ Add a command `container.hot_path`_ Add to list of always needed services `container.no_preload`_ Remove a class from the list of classes preloaded by PHP @@ -50,6 +51,57 @@ Tag Name Usage `validator.initializer`_ Register a service that initializes objects before validation ======================================== ======================================================================== +assets.package +-------------- + +**Purpose**: Add an asset package to the application + +This is an alternative way to declare a package in :doc:`/components/asset`. + +The name of the package is set in this order: +* first, the `package` attribute of the tag +* then, the value returned by the static method `getDefaultPackageName()` if defined +* finally, the service name + +.. configuration-block:: + + .. code-block:: yaml + + services: + App\Assets\AvatarPackage: + tags: + - { name: assets.package, package: avatars } + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + use App\Assets\AvatarPackage; + + $container + ->register(AvatarPackage::class) + ->addTag('assets.package', ['package' => 'avatars']) + ; + +Now you can use the ``avatars`` package in your templates: + +.. code-block:: html+twig + + + auto_alias ---------- From 3799eb4872da9f0730fc827386558bce3178d0ab Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 19 Feb 2021 17:44:53 +0100 Subject: [PATCH 0529/5766] Tweaks --- components/asset.rst | 2 ++ reference/dic_tags.rst | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/components/asset.rst b/components/asset.rst index 48e51754449..5044ef2dab9 100644 --- a/components/asset.rst +++ b/components/asset.rst @@ -51,6 +51,8 @@ Installation Usage ----- +.. _asset-packages: + Asset Packages ~~~~~~~~~~~~~~ diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index 2e4c7e5b339..81a9cc93704 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -56,12 +56,16 @@ assets.package **Purpose**: Add an asset package to the application -This is an alternative way to declare a package in :doc:`/components/asset`. +.. versionadded:: 5.3 + The ``assets.package`` tag was introduced in Symfony 5.3. + +This is an alternative way to declare an :ref:`asset package `. The name of the package is set in this order: -* first, the `package` attribute of the tag -* then, the value returned by the static method `getDefaultPackageName()` if defined -* finally, the service name + +* first, the ``package`` attribute of the tag; +* then, the value returned by the static method ``getDefaultPackageName()`` if defined; +* finally, the service name. .. configuration-block:: From 5c4e78061ff2ead019005ee6b56d31b7e35f3d7f Mon Sep 17 00:00:00 2001 From: wkania Date: Fri, 19 Feb 2021 18:42:57 +0100 Subject: [PATCH 0530/5766] Fix invalid file --- http_client.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/http_client.rst b/http_client.rst index 185e4a972cd..f80b2bc96ba 100644 --- a/http_client.rst +++ b/http_client.rst @@ -559,15 +559,18 @@ Use the ``headers`` option to define the default headers added to all requests: You can also set new headers or override the default ones for specific requests: -.. code-block:: php - // this header is only included in this request and overrides the value - // of the same header if defined globally by the HTTP client - $response = $client->request('POST', 'https://...', [ - 'headers' => [ - 'Content-Type' => 'text/plain', - ], - ]); +.. configuration-block:: + + .. code-block:: php + + // this header is only included in this request and overrides the value + // of the same header if defined globally by the HTTP client + $response = $client->request('POST', 'https://...', [ + 'headers' => [ + 'Content-Type' => 'text/plain', + ], + ]); Uploading Data ~~~~~~~~~~~~~~ From 4e212eedd0617acf4b16d66bb9e0189aff1bbc40 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 19 Feb 2021 19:27:06 +0100 Subject: [PATCH 0531/5766] Tweak --- http_client.rst | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/http_client.rst b/http_client.rst index f80b2bc96ba..37be3137771 100644 --- a/http_client.rst +++ b/http_client.rst @@ -557,20 +557,15 @@ Use the ``headers`` option to define the default headers added to all requests: ], ]); -You can also set new headers or override the default ones for specific requests: +You can also set new headers or override the default ones for specific requests:: - -.. configuration-block:: - - .. code-block:: php - - // this header is only included in this request and overrides the value - // of the same header if defined globally by the HTTP client - $response = $client->request('POST', 'https://...', [ - 'headers' => [ - 'Content-Type' => 'text/plain', - ], - ]); + // this header is only included in this request and overrides the value + // of the same header if defined globally by the HTTP client + $response = $client->request('POST', 'https://...', [ + 'headers' => [ + 'Content-Type' => 'text/plain', + ], + ]); Uploading Data ~~~~~~~~~~~~~~ From 6280192b77dab7650921154c3d583d68b8a68fab Mon Sep 17 00:00:00 2001 From: wkania Date: Thu, 18 Feb 2021 21:17:26 +0100 Subject: [PATCH 0532/5766] [Form] Add PHP Attributes example to forms --- forms.rst | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/forms.rst b/forms.rst index 42bdedc9658..e80ad65da71 100644 --- a/forms.rst +++ b/forms.rst @@ -507,6 +507,23 @@ object. protected $dueDate; } + .. code-block:: php-attributes + + // src/Entity/Task.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Task + { + #[Assert\NotBlank] + public $task; + + #[Assert\NotBlank] + #[Assert\Type(\DateTime::class)] + protected $dueDate; + } + .. code-block:: yaml # config/validator/validation.yaml From 2abb9aac37ef9db5ed95bfb112bbcfa960ac95ef Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 20 Feb 2021 18:02:11 +0100 Subject: [PATCH 0533/5766] [Security] Add PHP Attribute example to controller --- security.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/security.rst b/security.rst index 3b9341a07d6..18d0344f42e 100644 --- a/security.rst +++ b/security.rst @@ -1089,6 +1089,24 @@ Next, you'll need to create a route for this URL (but not a controller): } } + .. code-block:: php-attributes + + // src/Controller/SecurityController.php + namespace App\Controller; + + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\Routing\Annotation\Route; + + class SecurityController extends AbstractController + { + #[Route('/logout', name: 'app_logout', methods: ['GET'])] + public function logout() + { + // controller can be blank: it will never be executed! + throw new \Exception('Don\'t forget to activate logout in security.yaml'); + } + } + .. code-block:: yaml # config/routes.yaml From 832436bfc788fbb809a3d6c669dbbd9eec94a4ba Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 20 Feb 2021 18:41:02 +0100 Subject: [PATCH 0534/5766] [Routing] Add PHP Attribute route example to the controller --- controller/service.rst | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/controller/service.rst b/controller/service.rst index f8048e09def..2c592518608 100644 --- a/controller/service.rst +++ b/controller/service.rst @@ -41,6 +41,22 @@ a service like: ``App\Controller\HelloController::index``: } } + .. code-block:: php-attributes + + // src/Controller/HelloController.php + namespace App\Controller; + + use Symfony\Component\Routing\Annotation\Route; + + class HelloController + { + #[Route('/hello', name: 'hello', methods: ['GET'])] + public function index() + { + // ... + } + } + .. code-block:: yaml # config/routes.yaml @@ -105,6 +121,23 @@ which is a common practice when following the `ADR pattern`_ } } + .. code-block:: php-attributes + + // src/Controller/Hello.php + namespace App\Controller; + + use Symfony\Component\HttpFoundation\Response; + use Symfony\Component\Routing\Annotation\Route; + + #[Route('/hello/{name}', name: 'hello')] + class Hello + { + public function __invoke($name = 'World') + { + return new Response(sprintf('Hello %s!', $name)); + } + } + .. code-block:: yaml # config/routes.yaml From fd02abef74ebdcbc2a94f6212dda8e9908ad554c Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Sun, 21 Feb 2021 18:24:01 +0100 Subject: [PATCH 0535/5766] remove unsupported trusted header config values --- deployment/proxies.rst | 9 --------- 1 file changed, 9 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index 9b6821e3f79..5f24a69a418 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -37,9 +37,6 @@ and what headers your reverse proxy uses to send information: trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port'] // or, if your proxy instead uses the "Forwarded" header trusted_headers: ['forwarded'] - // or, if you're using a wellknown proxy - trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB] - trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_TRAEFIK] .. code-block:: xml @@ -80,9 +77,6 @@ and what headers your reverse proxy uses to send information: 'trusted_headers' => ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port'], // or, if your proxy instead uses the "Forwarded" header 'trusted_headers' => ['forwarded'], - // or, if you're using a wellknown proxy - 'trusted_headers' => [Request::HEADER_X_FORWARDED_AWS_ELB], - 'trusted_headers' => [Request::HEADER_X_FORWARDED_TRAEFIK], ]); .. deprecated:: 5.2 @@ -135,9 +129,6 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. // run time by $_SERVER['REMOTE_ADDR']) trusted_proxies: '127.0.0.1,REMOTE_ADDR' - // if you're using ELB, otherwise use another Request::HEADER-* constant - trusted_headers: [!php/const Symfony\\Component\\HttpFoundation\\Request::HEADER_X_FORWARDED_AWS_ELB, '!x-forwarded-host', '!x-forwarded-prefix'] - 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 a757019a71115250ec82c61aee4f98eab9d134f1 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sun, 21 Feb 2021 20:28:44 +0100 Subject: [PATCH 0536/5766] [Validator] Mention doctrine-bridge in the UniqueEntity constraint --- reference/constraints/UniqueEntity.rst | 5 +++++ reference/constraints/UserPassword.rst | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst index e6e449d949b..ca0a0be28c6 100644 --- a/reference/constraints/UniqueEntity.rst +++ b/reference/constraints/UniqueEntity.rst @@ -10,6 +10,11 @@ using an email address that already exists in the system. If you want to validate that all the elements of the collection are unique use the :doc:`Unique constraint `. +.. note:: + + In order to use this constraint, you should have installed the + symfony/doctrine-bridge with Composer. + ========== =================================================================== Applies to :ref:`class ` Options - `em`_ diff --git a/reference/constraints/UserPassword.rst b/reference/constraints/UserPassword.rst index 91017168a82..208281df216 100644 --- a/reference/constraints/UserPassword.rst +++ b/reference/constraints/UserPassword.rst @@ -12,7 +12,7 @@ password, but needs to enter their old password for security. .. note:: - In order to use this constraints, you should have installed the + In order to use this constraint, you should have installed the symfony/security-core component with Composer. ========== =================================================================== From f5fb27dac8fb5c3709130ca1f25c4d095553ddb6 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 21 Feb 2021 21:59:37 +0100 Subject: [PATCH 0537/5766] [Twig] Add missing space --- performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/performance.rst b/performance.rst index afd5295a9e3..80e36849cc9 100644 --- a/performance.rst +++ b/performance.rst @@ -275,7 +275,7 @@ You can also profile your template code with the :ref:`stopwatch Twig tag Date: Sun, 21 Feb 2021 11:03:54 +0100 Subject: [PATCH 0538/5766] Minor change to use DateTimeImmutable instead of DateTime Using DateTimeImmutable instead of DateTime when no mutation is needed improves performances. --- doctrine/events.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/events.rst b/doctrine/events.rst index c98be25d736..30b48856c13 100644 --- a/doctrine/events.rst +++ b/doctrine/events.rst @@ -76,7 +76,7 @@ define a callback for the ``prePersist`` Doctrine event: */ public function setCreatedAtValue(): void { - $this->createdAt = new \DateTime(); + $this->createdAt = new \DateTimeImmutable(); } } From 8ddf8ec5b8a3544cb1db3ee0356d863cf5d9f489 Mon Sep 17 00:00:00 2001 From: Pierre Boissinot Date: Mon, 22 Feb 2021 12:25:05 +0100 Subject: [PATCH 0539/5766] fix file path in comment following namespace --- security/impersonating_user.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/impersonating_user.rst b/security/impersonating_user.rst index 5f44a7fad23..ca4c1e3947f 100644 --- a/security/impersonating_user.rst +++ b/security/impersonating_user.rst @@ -259,7 +259,7 @@ be called): Then, create a voter class that responds to this role and includes whatever custom logic you want:: - // src/Service/Voter/SwitchToCustomerVoter.php + // src/Security/Voter/SwitchToCustomerVoter.php namespace App\Security\Voter; use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; From 6f8ff2502089924952031b58307335dc77bda687 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Mon, 22 Feb 2021 20:30:14 +0100 Subject: [PATCH 0540/5766] [Validator] Add PHP Attributes to severity and translation examples --- validation/severity.rst | 19 +++++++++++++++++++ validation/translations.rst | 13 +++++++++++++ 2 files changed, 32 insertions(+) diff --git a/validation/severity.rst b/validation/severity.rst index 7a8c22298fd..7df7746c7f2 100644 --- a/validation/severity.rst +++ b/validation/severity.rst @@ -50,6 +50,25 @@ Use the ``payload`` option to configure the error level for each constraint: protected $bankAccountNumber; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\NotBlank(payload: ['severity' => 'error'])] + protected $username; + + #[Assert\NotBlank(payload: ['severity' => 'error'])] + protected $password; + + #[Assert\Iban(payload: ['severity' => 'warning'])] + protected $bankAccountNumber; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/validation/translations.rst b/validation/translations.rst index 5c22f9362c3..c251c986b3b 100644 --- a/validation/translations.rst +++ b/validation/translations.rst @@ -40,6 +40,19 @@ property is not empty, add the following: public $name; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotBlank(message: 'author.name.not_blank')] + public $name; + } + .. code-block:: yaml # config/validator/validation.yaml From c4a398e55598cef9f2bc4557cfa1e0a12ff98e1d Mon Sep 17 00:00:00 2001 From: wkania Date: Mon, 22 Feb 2021 21:46:34 +0100 Subject: [PATCH 0541/5766] [Validator][Translation] Mention symfony/translation --- validation/translations.rst | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/validation/translations.rst b/validation/translations.rst index 5c22f9362c3..3edc15dab5e 100644 --- a/validation/translations.rst +++ b/validation/translations.rst @@ -8,6 +8,11 @@ If you're using validation constraints with the Form component, you can translat the error messages by creating a translation resource for the ``validators`` :ref:`domain `. +.. note:: + + In order to translate the error message, you should have installed the + symfony/translation component with Composer. + To start, suppose you've created a plain-old-PHP object that you need to use somewhere in your application:: @@ -93,7 +98,7 @@ Now, create a ``validators`` catalog file in the ``translations/`` directory: .. code-block:: xml - + @@ -108,12 +113,12 @@ Now, create a ``validators`` catalog file in the ``translations/`` directory: .. code-block:: yaml - # translations/validators.en.yaml + # translations/validators/validators.en.yaml author.name.not_blank: Please enter an author name. .. code-block:: php - // translations/validators.en.php + // translations/validators/validators.en.php return [ 'author.name.not_blank' => 'Please enter an author name.', ]; From 2d2f3b7cbdbea6b805212c8dc21bdd02966aebcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20Isaert?= Date: Mon, 21 Dec 2020 19:43:42 +0100 Subject: [PATCH 0542/5766] [Cache] Add TLS scheme for Redis connection See https://github.com/symfony/symfony/pull/39599 --- components/cache/adapters/redis_adapter.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst index 935afcd9f92..f1d00b248c2 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -62,7 +62,8 @@ helper method allows creating and configuring the Redis client class instance us ); 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. +password and a database index. To enable TLS for connections, the scheme ``redis`` must be +replaced by ``rediss``. .. note:: @@ -70,7 +71,7 @@ password and a database index. .. code-block:: text - redis://[pass@][ip|host|socket[:port]][/db-index] + redis[s]://[pass@][ip|host|socket[:port]][/db-index] Below are common examples of valid DSNs showing a combination of available values:: From efd9cd0758127350e7a67c28fc9100e936d68ae4 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Tue, 23 Feb 2021 19:49:10 +0100 Subject: [PATCH 0543/5766] Use null coalescing operator instead of ternary operator --- components/property_access.rst | 8 ++------ create_framework/http_foundation.rst | 4 ++-- frontend/custom_version_strategy.rst | 2 +- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/components/property_access.rst b/components/property_access.rst index 7b9053b835f..5cd5095908a 100644 --- a/components/property_access.rst +++ b/components/property_access.rst @@ -237,9 +237,7 @@ enable this feature by using :class:`Symfony\\Component\\PropertyAccess\\Propert { $property = lcfirst(substr($name, 3)); if ('get' === substr($name, 0, 3)) { - return isset($this->children[$property]) - ? $this->children[$property] - : null; + return $this->children[$property] ?? null; } elseif ('set' === substr($name, 0, 3)) { $value = 1 == count($args) ? $args[0] : null; $this->children[$property] = $value; @@ -334,9 +332,7 @@ see `Enable other Features`_:: { $property = lcfirst(substr($name, 3)); if ('get' === substr($name, 0, 3)) { - return isset($this->children[$property]) - ? $this->children[$property] - : null; + return $this->children[$property] ?? null; } elseif ('set' === substr($name, 0, 3)) { $value = 1 == count($args) ? $args[0] : null; $this->children[$property] = $value; diff --git a/create_framework/http_foundation.rst b/create_framework/http_foundation.rst index 99dff5c1faf..3c84dd25e57 100644 --- a/create_framework/http_foundation.rst +++ b/create_framework/http_foundation.rst @@ -25,7 +25,7 @@ First, if the ``name`` query parameter is not defined in the URL query string, you will get a PHP warning; so let's fix it:: // framework/index.php - $name = isset($_GET['name']) ? $_GET['name'] : 'World'; + $name = $_GET['name'] ?? 'World'; printf('Hello %s', $name); @@ -33,7 +33,7 @@ Then, this *application is not secure*. Can you believe it? Even this simple snippet of PHP code is vulnerable to one of the most widespread Internet security issue, XSS (Cross-Site Scripting). Here is a more secure version:: - $name = isset($_GET['name']) ? $_GET['name'] : 'World'; + $name = $_GET['name'] ?? 'World'; header('Content-Type: text/html; charset=utf-8'); diff --git a/frontend/custom_version_strategy.rst b/frontend/custom_version_strategy.rst index 6361ba632c0..d6280637b7f 100644 --- a/frontend/custom_version_strategy.rst +++ b/frontend/custom_version_strategy.rst @@ -83,7 +83,7 @@ version string:: $this->hashes = $this->loadManifest(); } - return isset($this->hashes[$path]) ? $this->hashes[$path] : ''; + return $this->hashes[$path] ?? ''; } public function applyVersion($path) From dde96698a2fc6307c6eb02557476d3d8713049ba Mon Sep 17 00:00:00 2001 From: Kolja Zuelsdorf Date: Tue, 23 Feb 2021 21:59:11 +0100 Subject: [PATCH 0544/5766] Fixed small typo --- testing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index 8fd666c8f96..8cc56e61b20 100644 --- a/testing.rst +++ b/testing.rst @@ -607,7 +607,7 @@ submitting a login form - make a test very slow. For this reason, Symfony provides a ``loginUser()`` method to simulate logging in in your functional tests. -Instead of login in with real users, it's recommended to create a user only for +Instead of logging in with real users, it's recommended to create a user only for tests. You can do that with Doctrine :ref:`data fixtures `, to load the testing users only in the test database. From c335d0e232a55b90911bd2db818de05b9261a00e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 23 Feb 2021 09:21:01 +0100 Subject: [PATCH 0545/5766] [Internal] Set the specific version of the doc-builder --- _build/composer.json | 6 +- _build/composer.lock | 267 ++++++++++++++++++------------------------- 2 files changed, 117 insertions(+), 156 deletions(-) diff --git a/_build/composer.json b/_build/composer.json index ea0ef4eee25..45f492f2f06 100644 --- a/_build/composer.json +++ b/_build/composer.json @@ -15,8 +15,8 @@ }, "require": { "php": ">=7.2.9", - "symfony/console": "^4.1", - "symfony/docs-builder": "dev-master", - "symfony/process": "9999999-dev" + "symfony/console": "^4.4", + "symfony/docs-builder": "^0.12.0", + "symfony/process": "^4.4" } } diff --git a/_build/composer.lock b/_build/composer.lock index 8a5ab63dcb7..b1815909808 100644 --- a/_build/composer.lock +++ b/_build/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e580f6d54e3fe0b71ca6103550882138", + "content-hash": "f237cd997543c606037f2517b2ffad9f", "packages": [ { "name": "doctrine/event-manager", @@ -571,16 +571,16 @@ }, { "name": "scrivo/highlight.php", - "version": "v9.18.1.3", + "version": "v9.18.1.6", "source": { "type": "git", "url": "https://github.com/scrivo/highlight.php.git", - "reference": "6a1699707b099081f20a488ac1f92d682181018c" + "reference": "44a3d4136edb5ad8551590bf90f437db80b2d466" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/6a1699707b099081f20a488ac1f92d682181018c", - "reference": "6a1699707b099081f20a488ac1f92d682181018c", + "url": "https://api.github.com/repos/scrivo/highlight.php/zipball/44a3d4136edb5ad8551590bf90f437db80b2d466", + "reference": "44a3d4136edb5ad8551590bf90f437db80b2d466", "shasum": "" }, "require": { @@ -594,9 +594,6 @@ "symfony/finder": "^2.8|^3.4", "symfony/var-dumper": "^2.8|^3.4" }, - "suggest": { - "ext-dom": "Needed to make use of the features in the utilities namespace" - }, "type": "library", "autoload": { "psr-0": { @@ -646,20 +643,20 @@ "type": "github" } ], - "time": "2020-10-16T07:43:22+00:00" + "time": "2020-12-22T19:20:29+00:00" }, { "name": "symfony/console", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124" + "reference": "24026c44fc37099fa145707fecd43672831b837a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/90933b39c7b312fc3ceaa1ddeac7eb48cb953124", - "reference": "90933b39c7b312fc3ceaa1ddeac7eb48cb953124", + "url": "https://api.github.com/repos/symfony/console/zipball/24026c44fc37099fa145707fecd43672831b837a", + "reference": "24026c44fc37099fa145707fecd43672831b837a", "shasum": "" }, "require": { @@ -694,11 +691,6 @@ "symfony/process": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" @@ -721,10 +713,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/console/tree/v4.4.15" + "source": "https://github.com/symfony/console/tree/v4.4.19" }, "funding": [ { @@ -740,31 +732,26 @@ "type": "tidelift" } ], - "time": "2020-09-15T07:58:55+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/css-selector", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc" + "reference": "f907d3e53ecb2a5fad8609eb2f30525287a734c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/bf17dc9f6ce144e41f786c32435feea4d8e11dcc", - "reference": "bf17dc9f6ce144e41f786c32435feea4d8e11dcc", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/f907d3e53ecb2a5fad8609eb2f30525287a734c8", + "reference": "f907d3e53ecb2a5fad8609eb2f30525287a734c8", "shasum": "" }, "require": { "php": ">=7.1.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" @@ -791,10 +778,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony CssSelector Component", + "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v4.4.15" + "source": "https://github.com/symfony/css-selector/tree/v4.4.19" }, "funding": [ { @@ -810,11 +797,11 @@ "type": "tidelift" } ], - "time": "2020-07-05T09:39:30+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/docs-builder", - "version": "dev-master", + "version": "v0.12.0", "source": { "type": "git", "url": "https://github.com/weaverryan/docs-builder", @@ -839,7 +826,6 @@ "symfony/phpunit-bridge": "^4.1", "symfony/process": "^4.2" }, - "default-branch": true, "type": "project", "autoload": { "psr-4": { @@ -854,16 +840,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b" + "reference": "21032c566558255e551d23f4a516434c9e3a9a78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/bdcb7633a501770a0daefbf81d2e6b28c3864f2b", - "reference": "bdcb7633a501770a0daefbf81d2e6b28c3864f2b", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/21032c566558255e551d23f4a516434c9e3a9a78", + "reference": "21032c566558255e551d23f4a516434c9e3a9a78", "shasum": "" }, "require": { @@ -882,11 +868,6 @@ "symfony/css-selector": "" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\DomCrawler\\": "" @@ -909,10 +890,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony DomCrawler Component", + "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v4.4.15" + "source": "https://github.com/symfony/dom-crawler/tree/v4.4.19" }, "funding": [ { @@ -928,20 +909,20 @@ "type": "tidelift" } ], - "time": "2020-10-02T07:34:48+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/filesystem", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db" + "reference": "83a6feed14846d2d9f3916adbaf838819e4e3380" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/ebc51494739d3b081ea543ed7c462fa73a4f74db", - "reference": "ebc51494739d3b081ea543ed7c462fa73a4f74db", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/83a6feed14846d2d9f3916adbaf838819e4e3380", + "reference": "83a6feed14846d2d9f3916adbaf838819e4e3380", "shasum": "" }, "require": { @@ -949,11 +930,6 @@ "symfony/polyfill-ctype": "~1.8" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" @@ -976,10 +952,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Filesystem Component", + "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v4.4.15" + "source": "https://github.com/symfony/filesystem/tree/v4.4.19" }, "funding": [ { @@ -995,31 +971,26 @@ "type": "tidelift" } ], - "time": "2020-09-27T13:54:16+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/finder", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "60d08560f9aa72997c44077c40d47aa28a963230" + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/60d08560f9aa72997c44077c40d47aa28a963230", - "reference": "60d08560f9aa72997c44077c40d47aa28a963230", + "url": "https://api.github.com/repos/symfony/finder/zipball/25d79cfccfc12e84e7a63a248c3f0720fdd92db6", + "reference": "25d79cfccfc12e84e7a63a248c3f0720fdd92db6", "shasum": "" }, "require": { "php": ">=7.1.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" @@ -1042,10 +1013,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Finder Component", + "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v4.4.15" + "source": "https://github.com/symfony/finder/tree/v4.4.19" }, "funding": [ { @@ -1061,20 +1032,20 @@ "type": "tidelift" } ], - "time": "2020-10-02T07:34:48+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/http-client", - "version": "v4.4.15", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "b1cb966898aaf8df37280fde537a27b6724b3bc4" + "reference": "d8df50fe9229576b254c6822eb5cfff36c02c967" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/b1cb966898aaf8df37280fde537a27b6724b3bc4", - "reference": "b1cb966898aaf8df37280fde537a27b6724b3bc4", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d8df50fe9229576b254c6822eb5cfff36c02c967", + "reference": "d8df50fe9229576b254c6822eb5cfff36c02c967", "shasum": "" }, "require": { @@ -1091,7 +1062,7 @@ "symfony/http-client-implementation": "1.1" }, "require-dev": { - "guzzlehttp/promises": "^1.3.1", + "guzzlehttp/promises": "^1.4", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", "psr/http-client": "^1.0", @@ -1100,11 +1071,6 @@ "symfony/process": "^4.2|^5.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.4-dev" - } - }, "autoload": { "psr-4": { "Symfony\\Component\\HttpClient\\": "" @@ -1127,10 +1093,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpClient component", + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-client/tree/v4.4.15" + "source": "https://github.com/symfony/http-client/tree/v4.4.19" }, "funding": [ { @@ -1146,7 +1112,7 @@ "type": "tidelift" } ], - "time": "2020-10-02T13:41:48+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/http-client-contracts", @@ -1229,16 +1195,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41" + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/f4ba089a5b6366e453971d3aad5fe8e897b37f41", - "reference": "f4ba089a5b6366e453971d3aad5fe8e897b37f41", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", + "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", "shasum": "" }, "require": { @@ -1250,7 +1216,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1288,7 +1254,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" }, "funding": [ { @@ -1304,20 +1270,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-intl-idn", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117" + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3b75acd829741c768bc8b1f84eb33265e7cc5117", - "reference": "3b75acd829741c768bc8b1f84eb33265e7cc5117", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/2d63434d922daf7da8dd863e7907e67ee3031483", + "reference": "2d63434d922daf7da8dd863e7907e67ee3031483", "shasum": "" }, "require": { @@ -1331,7 +1297,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1375,7 +1341,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.22.1" }, "funding": [ { @@ -1391,20 +1357,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "727d1096295d807c309fb01a851577302394c897" + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", - "reference": "727d1096295d807c309fb01a851577302394c897", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", + "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", "shasum": "" }, "require": { @@ -1416,7 +1382,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1459,7 +1425,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1" }, "funding": [ { @@ -1475,20 +1441,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", + "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", "shasum": "" }, "require": { @@ -1500,7 +1466,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1539,7 +1505,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" }, "funding": [ { @@ -1555,20 +1521,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-22T09:19:47+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930" + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cede45fcdfabdd6043b3592e83678e42ec69e930", - "reference": "cede45fcdfabdd6043b3592e83678e42ec69e930", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", "shasum": "" }, "require": { @@ -1577,7 +1543,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1615,7 +1581,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1" }, "funding": [ { @@ -1631,20 +1597,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", - "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", "shasum": "" }, "require": { @@ -1653,7 +1619,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1694,7 +1660,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1" }, "funding": [ { @@ -1710,20 +1676,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.20.0", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", - "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", + "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", "shasum": "" }, "require": { @@ -1732,7 +1698,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.22-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1777,7 +1743,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.20.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1" }, "funding": [ { @@ -1793,27 +1759,25 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-01-07T16:49:33+00:00" }, { "name": "symfony/process", - "version": "5.x-dev", + "version": "v4.4.19", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "88d47196a2fe06db8f90f0c2a986651e91ee3660" + "reference": "7e950b6366d4da90292c2e7fa820b3c1842b965a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/88d47196a2fe06db8f90f0c2a986651e91ee3660", - "reference": "88d47196a2fe06db8f90f0c2a986651e91ee3660", + "url": "https://api.github.com/repos/symfony/process/zipball/7e950b6366d4da90292c2e7fa820b3c1842b965a", + "reference": "7e950b6366d4da90292c2e7fa820b3c1842b965a", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" + "php": ">=7.1.3" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -1837,10 +1801,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Process Component", + "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/5.x" + "source": "https://github.com/symfony/process/tree/v4.4.19" }, "funding": [ { @@ -1856,7 +1820,7 @@ "type": "tidelift" } ], - "time": "2020-10-24T12:08:07+00:00" + "time": "2021-01-27T09:09:26+00:00" }, { "name": "symfony/service-contracts", @@ -1939,16 +1903,16 @@ }, { "name": "twig/twig", - "version": "v2.14.0", + "version": "v2.14.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "d495243dade48c39b6a5261c26cdbd8c5703f6a0" + "reference": "8bc568d460d88b25c00c046256ec14a787ea60d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/d495243dade48c39b6a5261c26cdbd8c5703f6a0", - "reference": "d495243dade48c39b6a5261c26cdbd8c5703f6a0", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/8bc568d460d88b25c00c046256ec14a787ea60d9", + "reference": "8bc568d460d88b25c00c046256ec14a787ea60d9", "shasum": "" }, "require": { @@ -2002,7 +1966,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v2.14.0" + "source": "https://github.com/twigphp/Twig/tree/v2.14.3" }, "funding": [ { @@ -2014,16 +1978,13 @@ "type": "tidelift" } ], - "time": "2020-10-21T12:35:06+00:00" + "time": "2021-01-05T15:34:33+00:00" } ], "packages-dev": [], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "symfony/docs-builder": 20, - "symfony/process": 20 - }, + "stability-flags": [], "prefer-stable": true, "prefer-lowest": false, "platform": { From f68b17f307b6c614d39917e4fc9f5a17c803ae03 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 24 Feb 2021 15:23:59 +0100 Subject: [PATCH 0546/5766] Remove comment about PR draft status --- contributing/code/pull_requests.rst | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst index 1cb0da6dddc..58a6004ca14 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -370,8 +370,7 @@ because you want early feedback on your work, add an item to todo-list: - [ ] gather feedback for my changes As long as you have items in the todo-list, please prefix the pull request -title with "[WIP]". If you do not yet want to trigger the automated tests, -you can also set the PR to `draft status`_. +title with "[WIP]". In the pull request description, give as much detail as possible about your changes (don't hesitate to give code examples to illustrate your points). If @@ -436,4 +435,3 @@ before merging. .. _`searching on GitHub`: https://github.com/symfony/symfony/issues?q=+is%3Aopen+ .. _`Symfony Slack`: https://symfony.com/slack-invite .. _`Travis-CI`: https://travis-ci.org/symfony/symfony -.. _`draft status`: https://help.github.com/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests From 33794481aea1a41001d514c33ca1f24f9e214d81 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 24 Feb 2021 17:52:43 +0100 Subject: [PATCH 0547/5766] Show example how to set xdebug.file_link_format --- reference/configuration/framework.rst | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 4515077d1d7..246726e820c 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -415,7 +415,13 @@ Since every developer uses a different IDE, the recommended way to enable this feature is to configure it on a system level. This can be done by setting 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. +need to escape the percent signs (``%``) by doubling them:: + + // example for PhpStorm + xdebug.file_link_format="phpstorm://open?file=%f&line=%l" + + // example for Sublime + xdebug.file_link_format="subl://open?url=file://%f&line=%l" .. note:: From 1859757418b7731cecc099fa9518e32008623370 Mon Sep 17 00:00:00 2001 From: Pierre Boissinot Date: Wed, 24 Feb 2021 21:45:59 +0100 Subject: [PATCH 0548/5766] doc(mailer): add Sendinblue to transports supporting tags and metadata --- mailer.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/mailer.rst b/mailer.rst index ea83e0a4f46..08a10c59e03 100644 --- a/mailer.rst +++ b/mailer.rst @@ -1209,6 +1209,7 @@ The following transports currently support tags and metadata: * Postmark * Mailgun * MailChimp +* Sendinblue Development & Debugging ----------------------- From 69f9db34df0fa0c54aea8f6a3d72a1490ab4cb75 Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Wed, 24 Feb 2021 21:39:22 +0100 Subject: [PATCH 0549/5766] [Validator] Mention IsNull in Basic Constraints --- reference/constraints/IsFalse.rst | 2 ++ reference/constraints/IsTrue.rst | 2 ++ reference/constraints/Type.rst | 2 ++ reference/constraints/_null-values-are-valid.rst.inc | 6 ++++++ 4 files changed, 12 insertions(+) create mode 100644 reference/constraints/_null-values-are-valid.rst.inc diff --git a/reference/constraints/IsFalse.rst b/reference/constraints/IsFalse.rst index 5b2597d8657..63f1364024c 100644 --- a/reference/constraints/IsFalse.rst +++ b/reference/constraints/IsFalse.rst @@ -107,6 +107,8 @@ method returns **false**: // ... } +.. include:: /reference/constraints/_null-values-are-valid.rst.inc + Options ------- diff --git a/reference/constraints/IsTrue.rst b/reference/constraints/IsTrue.rst index d9d53b04f82..aa172153e9f 100644 --- a/reference/constraints/IsTrue.rst +++ b/reference/constraints/IsTrue.rst @@ -111,6 +111,8 @@ Then you can validate this method with ``IsTrue`` as follows: If the ``isTokenValid()`` returns false, the validation will fail. +.. include:: /reference/constraints/_null-values-are-valid.rst.inc + Options ------- diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index 103ea9fd43c..307b7565749 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -148,6 +148,8 @@ This will check if ``emailAddress`` is an instance of ``Symfony\Component\Mime\A The feature to define multiple types in the ``type`` option was introduced in Symfony 4.4. +.. include:: /reference/constraints/_null-values-are-valid.rst.inc + Options ------- diff --git a/reference/constraints/_null-values-are-valid.rst.inc b/reference/constraints/_null-values-are-valid.rst.inc new file mode 100644 index 00000000000..49b6a54faad --- /dev/null +++ b/reference/constraints/_null-values-are-valid.rst.inc @@ -0,0 +1,6 @@ +.. note:: + + As with most of the other constraints, ``null`` is + considered a valid value. This is to allow the use of optional values. + If the value is mandatory, a common solution is to combine this constraint + with :doc:`NotNull `. From 795dcb7172dbc716df7029abc0651a9581dc66c9 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 24 Feb 2021 15:43:10 +0100 Subject: [PATCH 0550/5766] Updated contribution guide with "Automated Feedback" --- contributing/code/pull_requests.rst | 32 +++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/contributing/code/pull_requests.rst b/contributing/code/pull_requests.rst index 58a6004ca14..d1f06f8db76 100644 --- a/contributing/code/pull_requests.rst +++ b/contributing/code/pull_requests.rst @@ -399,6 +399,36 @@ The :doc:`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. +Automated Feedback +~~~~~~~~~~~~~~~~~~ + +There are many automated scripts that will provide feedback on a pull request. + +fabbot +"""""" + +`fabbot`_ will review code style, check for common typos and make sure the git +history looks good. If there are any issues, fabbot will often suggest what changes +that should be done. Most of the time you get a command to run to automatically +fix the changes. + +It is rare, but fabbot could be wrong. One should verify if the suggested changes +make sense and that they are related to the pull request. + +Psalm +""""" + +`Psalm`_ will make a comment on a pull request if it discovers any potential +type errors. The Psalm errors are not always correct, but each should be reviewed +and discussed. A pull request should not update the Psalm baseline nor add ``@psalm-`` +annotations. + +After the `Psalm phar is installed`_, the analysis can be run locally with: + +.. code-block:: terminal + + $ psalm.phar src/Symfony/Component/Workflow + .. _rework-your-patch: Rework your Pull Request @@ -430,8 +460,10 @@ before merging. .. _Symfony repository: https://github.com/symfony/symfony .. _`documentation repository`: https://github.com/symfony/symfony-docs .. _`fabbot`: https://fabbot.io +.. _`Psalm`: https://psalm.dev/ .. _`PSR-1`: https://www.php-fig.org/psr/psr-1/ .. _`PSR-2`: https://www.php-fig.org/psr/psr-2/ .. _`searching on GitHub`: https://github.com/symfony/symfony/issues?q=+is%3Aopen+ .. _`Symfony Slack`: https://symfony.com/slack-invite .. _`Travis-CI`: https://travis-ci.org/symfony/symfony +.. _`Psalm phar is installed`: https://psalm.dev/docs/running_psalm/installation/ From 79661cca1f63b7a0092fc44cf5863fd1d4147e75 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 26 Feb 2021 10:37:34 +0100 Subject: [PATCH 0551/5766] Make the doc clearer --- setup/symfony_server.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index bd3a6718664..b9e1ef9d2ef 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -64,8 +64,8 @@ Enabling PHP-FPM PHP-FPM must be installed locally for the Symfony server to utilize. -When the server starts it will check for common patterns like ``web/app.php``, -``web/app_dev.php`` or ``public/index.php``. If a file like this is found the +When the server starts, it checks for ``web/index_dev.php``, ``web/index.php``, +``public/app_dev.php``, ``public/app.php`` in that order. If one is found, the server will automatically start with PHP-FPM enabled. Otherwise the server will start without PHP-FPM and will show a ``Page not found`` page when trying to access a ``.php`` file in the browser. From 962e0875f7e8a5422580899e5952bd010e896d09 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 26 Feb 2021 11:12:46 +0100 Subject: [PATCH 0552/5766] Make the explanation about how Docker services are detected (hopefully) clearer --- setup/symfony_server.rst | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index bd3a6718664..9784bd57e24 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -282,8 +282,11 @@ The local Symfony server provides full `Docker`_ integration for projects that use it. When the web server detects that Docker Compose is running for the project, it -automatically exposes environment variables according to the exposed port and -the name of the ``docker-compose`` services. +automatically exposes some environment variables. + +Via the ``docker-compose`` API, it looks for exposed ports used for common +services. When it detects one it knows about, it uses the service name to +expose environment variables. Consider the following configuration: From 00fbbdcbb31cbddd0e5a57ff586a6df29cd6469a Mon Sep 17 00:00:00 2001 From: "Alexander M. Turek" Date: Fri, 26 Feb 2021 21:25:49 +0100 Subject: [PATCH 0553/5766] Unique validator: Better description for the value placeholder --- reference/constraints/Unique.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst index 97cb6ff8602..e6acb08ea71 100644 --- a/reference/constraints/Unique.rst +++ b/reference/constraints/Unique.rst @@ -107,7 +107,7 @@ You can use the following parameters in this message: ============================= ================================================ Parameter Description ============================= ================================================ -``{{ value }}`` The repeated value +``{{ value }}`` The current (invalid) value ============================= ================================================ .. include:: /reference/constraints/_payload-option.rst.inc From e3328a46d4f8b03f9a4a9f6fbbf9b2ba33554518 Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Sun, 28 Feb 2021 21:51:40 +0100 Subject: [PATCH 0554/5766] [Encore] Deploying to a CDN subdirectory --- frontend/encore/cdn.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/frontend/encore/cdn.rst b/frontend/encore/cdn.rst index a7a2884c13a..17df7ffce21 100644 --- a/frontend/encore/cdn.rst +++ b/frontend/encore/cdn.rst @@ -39,6 +39,10 @@ pages also use the CDN. Fortunately, the :ref:`entrypoints.json ` paths are updated to include the full URL to the CDN. +When deploying to a subdirectory of your CDN, you must add the path at the end of your URL - +e.g. ``Encore.setPublicPath('https://my-cool-app.com.global.prod.fastly.net/awesome-website')`` +will generate assets URLs like ``https://my-cool-app.com.global.prod.fastly.net/awesome-website/dashboard.js`` + If you are using ``Encore.enableIntegrityHashes()`` and your CDN and your domain are not the `same-origin`_, you may need to set the ``crossorigin`` option in your webpack_encore.yaml configuration to ``anonymous`` or ``use-credentials`` From 52ce42f0dd0003b993c52766ccd750c01ccc648b Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 2 Mar 2021 11:21:11 +0100 Subject: [PATCH 0555/5766] Add part about resolving parameter values to prepend extension --- bundles/prepend_extension.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst index 2b6f9dbfe3f..d0c6522e4ec 100644 --- a/bundles/prepend_extension.rst +++ b/bundles/prepend_extension.rst @@ -82,6 +82,9 @@ in case a specific other bundle is not registered:: // process the configuration of AcmeHelloExtension $configs = $container->getExtensionConfig($this->getAlias()); + // resolve config parameters e.g. %kernel.debug% to boolean value + $resolvingBag = $container->getParameterBag(); + $configs = $resolvingBag->resolveValue($configs); // use the Configuration class to generate a config array with // the settings "acme_hello" $config = $this->processConfiguration(new Configuration(), $configs); From 8132571a84ee69102c743368c2b3aa78416defee Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Sat, 20 Feb 2021 20:22:27 +0100 Subject: [PATCH 0556/5766] [#15009] Fix inconsistent diff examples --- frontend/encore/legacy-applications.rst | 3 +++ frontend/encore/split-chunks.rst | 2 ++ frontend/encore/typescript.rst | 3 ++- frontend/encore/versioning.rst | 2 +- quick_tour/flex_recipes.rst | 6 +++--- setup/flex.rst | 6 +++--- 6 files changed, 14 insertions(+), 8 deletions(-) diff --git a/frontend/encore/legacy-applications.rst b/frontend/encore/legacy-applications.rst index 4f1193d7e06..f76bc35adcb 100644 --- a/frontend/encore/legacy-applications.rst +++ b/frontend/encore/legacy-applications.rst @@ -32,6 +32,7 @@ jQuery plugins often expect that jQuery is already available via the ``$`` or .. code-block:: diff + // webpack.config.js Encore // ... + .autoProvidejQuery() @@ -74,6 +75,8 @@ page, add: .. code-block:: diff + // webpack.config.js + // require jQuery normally const $ = require('jquery'); diff --git a/frontend/encore/split-chunks.rst b/frontend/encore/split-chunks.rst index ebaa4ee48ce..b03952a3153 100644 --- a/frontend/encore/split-chunks.rst +++ b/frontend/encore/split-chunks.rst @@ -10,6 +10,7 @@ To enable this, call ``splitEntryChunks()``: .. code-block:: diff + // webpack.config.js Encore // ... @@ -52,6 +53,7 @@ this plugin with the ``configureSplitChunks()`` function: .. code-block:: diff + // webpack.config.js Encore // ... diff --git a/frontend/encore/typescript.rst b/frontend/encore/typescript.rst index b1af45d9c04..0ca51f7a13f 100644 --- a/frontend/encore/typescript.rst +++ b/frontend/encore/typescript.rst @@ -6,8 +6,8 @@ Want to use `TypeScript`_? No problem! First, enable it: .. code-block:: diff // webpack.config.js - // ... + // ... Encore // ... + .addEntry('main', './assets/main.ts') @@ -30,6 +30,7 @@ method. .. code-block:: diff + // webpack.config.js Encore // ... .addEntry('main', './assets/main.ts') diff --git a/frontend/encore/versioning.rst b/frontend/encore/versioning.rst index 1f3d0cdd39e..27177d2d554 100644 --- a/frontend/encore/versioning.rst +++ b/frontend/encore/versioning.rst @@ -13,8 +13,8 @@ ignoring any existing cache: .. code-block:: diff // webpack.config.js - // ... + // ... Encore .setOutputPath('public/build/') // ... diff --git a/quick_tour/flex_recipes.rst b/quick_tour/flex_recipes.rst index 435b4f07351..16724e3ee90 100644 --- a/quick_tour/flex_recipes.rst +++ b/quick_tour/flex_recipes.rst @@ -83,9 +83,9 @@ Thanks to Flex, after one command, you can start using Twig immediately: - use Symfony\Component\HttpFoundation\Response; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - -class DefaultController - +class DefaultController extends AbstractController - { + - class DefaultController + + class DefaultController extends AbstractController + { /** * @Route("/hello/{name}") */ diff --git a/setup/flex.rst b/setup/flex.rst index eaba102d073..31f034db862 100644 --- a/setup/flex.rst +++ b/setup/flex.rst @@ -61,9 +61,9 @@ manual steps: { "require": { "symfony/flex": "^1.0", - + }, - + "conflict": { - + "symfony/symfony": "*" + + }, + + "conflict": { + + "symfony/symfony": "*" } } From 4865b3bfa9ae03cb9a8dfda0793c4a9225c92fd7 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Tue, 23 Feb 2021 19:09:49 +0100 Subject: [PATCH 0557/5766] [#15009] Fix indentation of all diff code blocks MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jérémy Derussé --- configuration/dot-env-changes.rst | 8 ++-- controller.rst | 10 ++--- doctrine.rst | 14 +++---- frontend/encore/cdn.rst | 18 ++++----- frontend/encore/copy-files.rst | 8 ++-- frontend/encore/custom-loaders-plugins.rst | 8 ++-- frontend/encore/dev-server.rst | 24 ++++++------ frontend/encore/faq.rst | 10 ++--- frontend/encore/legacy-applications.rst | 14 +++---- frontend/encore/postcss.rst | 24 ++++++------ frontend/encore/reactjs.rst | 10 ++--- frontend/encore/shared-entry.rst | 10 ++--- frontend/encore/simple-example.rst | 36 +++++++++--------- frontend/encore/split-chunks.rst | 24 ++++++------ frontend/encore/typescript.rst | 28 +++++++------- frontend/encore/versioning.rst | 10 ++--- frontend/encore/virtual-machine.rst | 36 +++++++++--------- frontend/encore/vuejs.rst | 24 ++++++------ http_cache.rst | 12 +++--- page_creation.rst | 28 +++++++------- quick_tour/flex_recipes.rst | 24 ++++++------ quick_tour/the_architecture.rst | 30 +++++++-------- quick_tour/the_big_picture.rst | 44 +++++++++++----------- security.rst | 40 ++++++++++---------- security/form_login_setup.rst | 12 +++--- security/guard_authentication.rst | 32 ++++++++-------- security/securing_services.rst | 24 ++++++------ service_container.rst | 36 +++++++++--------- setup/flex.rst | 10 ++--- setup/unstable_versions.rst | 10 ++--- setup/upgrade_major.rst | 34 ++++++++--------- setup/upgrade_minor.rst | 34 ++++++++--------- 32 files changed, 343 insertions(+), 343 deletions(-) diff --git a/configuration/dot-env-changes.rst b/configuration/dot-env-changes.rst index df418e6ea75..316bfa01aba 100644 --- a/configuration/dot-env-changes.rst +++ b/configuration/dot-env-changes.rst @@ -60,16 +60,16 @@ changes can be made to any Symfony 3.4 or higher app: .. code-block:: diff - # .gitignore - # ... + # .gitignore + # ... - ###> symfony/framework-bundle ### + ###> symfony/framework-bundle ### - /.env + /.env.local + /.env.local.php + /.env.*.local - # ... + # ... #. Rename ``.env`` to ``.env.local`` and ``.env.dist`` to ``.env``: diff --git a/controller.rst b/controller.rst index 212d0a2b509..ef3c3987a96 100644 --- a/controller.rst +++ b/controller.rst @@ -98,16 +98,16 @@ Add the ``use`` statement atop your controller class and then modify .. code-block:: diff - // src/Controller/LuckyController.php - namespace App\Controller; + // src/Controller/LuckyController.php + namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - class LuckyController + class LuckyController extends AbstractController - { - // ... - } + { + // ... + } That's it! You now have access to methods like :ref:`$this->render() ` and many others that you'll learn about next. diff --git a/doctrine.rst b/doctrine.rst index 8226bf22700..e1ee1785c00 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -280,20 +280,20 @@ methods: .. code-block:: diff - // src/Entity/Product.php - // ... + // src/Entity/Product.php + // ... - class Product - { - // ... + class Product + { + // ... + /** + * @ORM\Column(type="text") + */ + private $description; - // getDescription() & setDescription() were also added - } + // getDescription() & setDescription() were also added + } The new property is mapped, but it doesn't exist yet in the ``product`` table. No problem! Generate a new migration: diff --git a/frontend/encore/cdn.rst b/frontend/encore/cdn.rst index a7a2884c13a..267e3e2f88f 100644 --- a/frontend/encore/cdn.rst +++ b/frontend/encore/cdn.rst @@ -6,15 +6,15 @@ built files are uploaded to the CDN, configure it in Encore: .. code-block:: diff - // webpack.config.js - // ... - - Encore - .setOutputPath('public/build/') - // in dev mode, don't use the CDN - .setPublicPath('/build'); - // ... - ; + // webpack.config.js + // ... + + Encore + .setOutputPath('public/build/') + // in dev mode, don't use the CDN + .setPublicPath('/build'); + // ... + ; + if (Encore.isProduction()) { + Encore.setPublicPath('https://my-cool-app.com.global.prod.fastly.net'); diff --git a/frontend/encore/copy-files.rst b/frontend/encore/copy-files.rst index bc263ef056a..dc97fb0d434 100644 --- a/frontend/encore/copy-files.rst +++ b/frontend/encore/copy-files.rst @@ -32,11 +32,11 @@ files into your final output directory. .. code-block:: diff - // webpack.config.js + // webpack.config.js - Encore - // ... - .setOutputPath('public/build/') + Encore + // ... + .setOutputPath('public/build/') + .copyFiles({ + from: './assets/images', diff --git a/frontend/encore/custom-loaders-plugins.rst b/frontend/encore/custom-loaders-plugins.rst index 66ce1f7c5cc..31c688ffc75 100644 --- a/frontend/encore/custom-loaders-plugins.rst +++ b/frontend/encore/custom-loaders-plugins.rst @@ -50,14 +50,14 @@ to use the `IgnorePlugin`_ (see `moment/moment#2373`_): .. code-block:: diff - // webpack.config.js + // webpack.config.js + var webpack = require('webpack'); - Encore - // ... + Encore + // ... + .addPlugin(new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)) - ; + ; .. _`handlebars-loader`: https://github.com/pcardune/handlebars-loader .. _`plugins`: https://webpack.js.org/plugins/ diff --git a/frontend/encore/dev-server.rst b/frontend/encore/dev-server.rst index 3a602f89b19..76047ddc2a7 100644 --- a/frontend/encore/dev-server.rst +++ b/frontend/encore/dev-server.rst @@ -65,14 +65,14 @@ the ``package.json`` file: .. code-block:: diff - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server", + "dev-server": "encore dev-server --https --pfx=$HOME/.symfony/certs/default.p12 --allowed-hosts=mydomain.wip", - ... - } - } + ... + } + } If you experience issues related to CORS (Cross Origin Resource Sharing), add the ``--disable-host-check`` and ``--port`` options to the ``dev-server`` @@ -80,14 +80,14 @@ command in the ``package.json`` file: .. code-block:: diff - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server", + "dev-server": "encore dev-server --port 8080 --disable-host-check", - ... - } - } + ... + } + } .. caution:: diff --git a/frontend/encore/faq.rst b/frontend/encore/faq.rst index 3c621c3b8d0..f349cf350cf 100644 --- a/frontend/encore/faq.rst +++ b/frontend/encore/faq.rst @@ -63,11 +63,11 @@ like ``/myAppSubdir``), you will need to configure that when calling ``Encore.se .. code-block:: diff - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... - .setOutputPath('public/build/') + .setOutputPath('public/build/') - .setPublicPath('/build') + // this is your *true* public path @@ -76,7 +76,7 @@ like ``/myAppSubdir``), you will need to configure that when calling ``Encore.se + // this is now needed so that your manifest.json keys are still `build/foo.js` + // (which is a file that's used by Symfony's `asset()` function) + .setManifestKeyPrefix('build') - ; + ; If you're using the ``encore_entry_script_tags()`` and ``encore_entry_link_tags()`` Twig shortcuts (or are :ref:`processing your assets through entrypoints.json ` diff --git a/frontend/encore/legacy-applications.rst b/frontend/encore/legacy-applications.rst index f76bc35adcb..36087b88978 100644 --- a/frontend/encore/legacy-applications.rst +++ b/frontend/encore/legacy-applications.rst @@ -32,11 +32,11 @@ jQuery plugins often expect that jQuery is already available via the ``$`` or .. code-block:: diff - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... + .autoProvidejQuery() - ; + ; After restarting Encore, Webpack will look for all uninitialized ``$`` and ``jQuery`` variables and automatically require ``jquery`` and set those variables for you. @@ -75,10 +75,10 @@ page, add: .. code-block:: diff - // webpack.config.js + // webpack.config.js - // require jQuery normally - const $ = require('jquery'); + // require jQuery normally + const $ = require('jquery'); + // create global $ and jQuery variables + global.$ = global.jQuery = $; diff --git a/frontend/encore/postcss.rst b/frontend/encore/postcss.rst index 76c6e8d67e9..e30af2ae6ca 100644 --- a/frontend/encore/postcss.rst +++ b/frontend/encore/postcss.rst @@ -28,12 +28,12 @@ Then, enable the loader in Encore! .. code-block:: diff - // webpack.config.js + // webpack.config.js - Encore - // ... + Encore + // ... + .enablePostCssLoader() - ; + ; Because you just modified ``webpack.config.js``, stop and restart Encore. @@ -42,17 +42,17 @@ You can also pass options to the `postcss-loader`_ by passing a callback: .. code-block:: diff - // webpack.config.js + // webpack.config.js - Encore - // ... + Encore + // ... + .enablePostCssLoader((options) => { + options.config = { + // the directory where the postcss.config.js file is stored + path: 'path/to/config' + }; + }) - ; + ; .. _browserslist_package_config: @@ -65,25 +65,25 @@ support. The best-practice is to configure this directly in your ``package.json` .. code-block:: diff - { + { + "browserslist": [ + "defaults" + ] - } + } The ``defaults`` option is recommended for most users and would be equivalent to the following browserslist: .. code-block:: diff - { + { + "browserslist": [ + "> 0.5%", + "last 2 versions", + "Firefox ESR", + "not dead" + ] - } + } See `browserslist`_ for more details on the syntax. diff --git a/frontend/encore/reactjs.rst b/frontend/encore/reactjs.rst index ca3b017f13b..f7e206e15e8 100644 --- a/frontend/encore/reactjs.rst +++ b/frontend/encore/reactjs.rst @@ -17,13 +17,13 @@ Enable react in your ``webpack.config.js``: .. code-block:: diff - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... + Encore + // ... + .enableReactPreset() - ; + ; Then restart Encore. When you do, it will give you a command you can run to diff --git a/frontend/encore/shared-entry.rst b/frontend/encore/shared-entry.rst index 6693b649d8d..f71868eee2f 100644 --- a/frontend/encore/shared-entry.rst +++ b/frontend/encore/shared-entry.rst @@ -16,13 +16,13 @@ Update your code to use ``createSharedEntry()``: .. code-block:: diff - Encore - // ... + Encore + // ... - .addEntry('app', './assets/js/app.js') + .createSharedEntry('app', './assets/js/app.js') - .addEntry('homepage', './assets/js/homepage.js') - .addEntry('blog', './assets/js/blog.js') - .addEntry('store', './assets/js/store.js') + .addEntry('homepage', './assets/js/homepage.js') + .addEntry('blog', './assets/js/blog.js') + .addEntry('store', './assets/js/store.js') Before making this change, if both ``app.js`` and ``store.js`` require ``jquery``, then ``jquery`` would be packaged into *both* files, which is wasteful. By making diff --git a/frontend/encore/simple-example.rst b/frontend/encore/simple-example.rst index 4373f9c3b66..2e9153e26db 100644 --- a/frontend/encore/simple-example.rst +++ b/frontend/encore/simple-example.rst @@ -167,8 +167,8 @@ Great! Use ``require()`` to import ``jquery`` and ``greet.js``: .. code-block:: diff - // assets/js/app.js - // ... + // assets/js/app.js + // ... + // loads the jquery package from node_modules + var $ = require('jquery'); @@ -196,17 +196,17 @@ To export values using the alternate syntax, use ``export``: .. code-block:: diff - // assets/js/greet.js + // assets/js/greet.js - module.exports = function(name) { + export default function(name) { - return `Yo yo ${name} - welcome to Encore!`; - }; + return `Yo yo ${name} - welcome to Encore!`; + }; To import values, use ``import``: .. code-block:: diff - // assets/js/app.js + // assets/js/app.js - require('../css/app.css'); + import '../css/app.css'; @@ -240,13 +240,13 @@ Next, use ``addEntry()`` to tell Webpack to read these two new files when it bui .. code-block:: diff - // webpack.config.js - Encore - // ... - .addEntry('app', './assets/js/app.js') + // webpack.config.js + Encore + // ... + .addEntry('app', './assets/js/app.js') + .addEntry('checkout', './assets/js/checkout.js') + .addEntry('account', './assets/js/account.js') - // ... + // ... And because you just changed the ``webpack.config.js`` file, make sure to stop and restart Encore: @@ -264,8 +264,8 @@ you need them: .. code-block:: diff - {# templates/.../checkout.html.twig #} - {% extends 'base.html.twig' %} + {# templates/.../checkout.html.twig #} + {% extends 'base.html.twig' %} + {% block stylesheets %} + {{ parent() }} @@ -294,7 +294,7 @@ file to ``app.scss`` and update the ``import`` statement: .. code-block:: diff - // assets/js/app.js + // assets/js/app.js - import '../css/app.css'; + import '../css/app.scss'; @@ -302,12 +302,12 @@ Then, tell Encore to enable the Sass pre-processor: .. code-block:: diff - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... + .enableSassLoader() - ; + ; Because you just changed your ``webpack.config.js`` file, you'll need to restart Encore. When you do, you'll see an error! diff --git a/frontend/encore/split-chunks.rst b/frontend/encore/split-chunks.rst index b03952a3153..f25c876704d 100644 --- a/frontend/encore/split-chunks.rst +++ b/frontend/encore/split-chunks.rst @@ -10,15 +10,15 @@ To enable this, call ``splitEntryChunks()``: .. code-block:: diff - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... - // multiple entry files, which probably import the same code - .addEntry('app', './assets/js/app.js') - .addEntry('homepage', './assets/js/homepage.js') - .addEntry('blog', './assets/js/blog.js') - .addEntry('store', './assets/js/store.js') + // multiple entry files, which probably import the same code + .addEntry('app', './assets/js/app.js') + .addEntry('homepage', './assets/js/homepage.js') + .addEntry('blog', './assets/js/blog.js') + .addEntry('store', './assets/js/store.js') + .splitEntryChunks() @@ -53,11 +53,11 @@ this plugin with the ``configureSplitChunks()`` function: .. code-block:: diff - // webpack.config.js - Encore - // ... + // webpack.config.js + Encore + // ... - .splitEntryChunks() + .splitEntryChunks() + .configureSplitChunks(function(splitChunks) { + // change the configuration + splitChunks.minSize = 0; diff --git a/frontend/encore/typescript.rst b/frontend/encore/typescript.rst index 0ca51f7a13f..fbd0b616c86 100644 --- a/frontend/encore/typescript.rst +++ b/frontend/encore/typescript.rst @@ -5,20 +5,20 @@ Want to use `TypeScript`_? No problem! First, enable it: .. code-block:: diff - // webpack.config.js + // webpack.config.js - // ... - Encore - // ... + // ... + Encore + // ... + .addEntry('main', './assets/main.ts') + .enableTypeScriptLoader() - // optionally enable forked type script for faster builds - // https://www.npmjs.com/package/fork-ts-checker-webpack-plugin - // requires that you have a tsconfig.json file that is setup correctly. + // optionally enable forked type script for faster builds + // https://www.npmjs.com/package/fork-ts-checker-webpack-plugin + // requires that you have a tsconfig.json file that is setup correctly. + //.enableForkedTypeScriptTypesChecking() - ; + ; Then restart Encore. When you do, it will give you a command you can run to install any missing dependencies. After running that command and restarting @@ -30,10 +30,10 @@ method. .. code-block:: diff - // webpack.config.js - Encore - // ... - .addEntry('main', './assets/main.ts') + // webpack.config.js + Encore + // ... + .addEntry('main', './assets/main.ts') - .enableTypeScriptLoader() + .enableTypeScriptLoader(function(tsConfig) { @@ -43,8 +43,8 @@ method. + // tsConfig.silent = false + }) - // ... - ; + // ... + ; See the `Encore's index.js file`_ for detailed documentation and check out the `tsconfig.json reference`_ and the `Webpack guide about Typescript`_. diff --git a/frontend/encore/versioning.rst b/frontend/encore/versioning.rst index 27177d2d554..0911f8d8cc3 100644 --- a/frontend/encore/versioning.rst +++ b/frontend/encore/versioning.rst @@ -12,12 +12,12 @@ ignoring any existing cache: .. code-block:: diff - // webpack.config.js + // webpack.config.js - // ... - Encore - .setOutputPath('public/build/') - // ... + // ... + Encore + .setOutputPath('public/build/') + // ... + .enableVersioning() To link to these assets, Encore creates two files ``entrypoints.json`` and diff --git a/frontend/encore/virtual-machine.rst b/frontend/encore/virtual-machine.rst index 068d5c8451f..40b7ec2d386 100644 --- a/frontend/encore/virtual-machine.rst +++ b/frontend/encore/virtual-machine.rst @@ -49,14 +49,14 @@ If your Symfony application is running on a custom domain (e.g. .. code-block:: diff - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server", + "dev-server": "encore dev-server --public http://app.vm:8080", - ... - } - } + ... + } + } After restarting Encore and reloading your web page, you will probably see different issues in the web console: @@ -78,14 +78,14 @@ connections: .. code-block:: diff - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server --public http://app.vm:8080", + "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0", - ... - } - } + ... + } + } .. caution:: @@ -100,14 +100,14 @@ the dev-server. To fix this, add the argument ``--disable-host-check``: .. code-block:: diff - { - ... - "scripts": { + { + ... + "scripts": { - "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0", + "dev-server": "encore dev-server --public http://app.vm:8080 --host 0.0.0.0 --disable-host-check", - ... - } - } + ... + } + } .. caution:: diff --git a/frontend/encore/vuejs.rst b/frontend/encore/vuejs.rst index dd1227c9447..2af99c075fb 100644 --- a/frontend/encore/vuejs.rst +++ b/frontend/encore/vuejs.rst @@ -10,15 +10,15 @@ Want to use `Vue.js`_? No problem! First enable it in ``webpack.config.js``: .. code-block:: diff - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... - .addEntry('main', './assets/main.js') + Encore + // ... + .addEntry('main', './assets/main.js') + .enableVueLoader() - ; + ; Then restart Encore. When you do, it will give you a command you can run to install any missing dependencies. After running that command and restarting @@ -53,18 +53,18 @@ You can enable `JSX with Vue.js`_ by configuring the second parameter of the .. code-block:: diff - // webpack.config.js - // ... + // webpack.config.js + // ... - Encore - // ... - .addEntry('main', './assets/main.js') + Encore + // ... + .addEntry('main', './assets/main.js') - .enableVueLoader() + .enableVueLoader(() => {}, { + useJsx: true + }) - ; + ; Next, run or restart Encore. When you do, you will see an error message helping you install any missing dependencies. After running that command and restarting diff --git a/http_cache.rst b/http_cache.rst index 0bd62b30c8e..6061ed128cc 100644 --- a/http_cache.rst +++ b/http_cache.rst @@ -93,20 +93,20 @@ caching kernel: .. code-block:: diff - // public/index.php + // public/index.php + use App\CacheKernel; - use App\Kernel; + use App\Kernel; - // ... - $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); + // ... + $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']); + // Wrap the default Kernel with the CacheKernel one in 'prod' environment + if ('prod' === $kernel->getEnvironment()) { + $kernel = new CacheKernel($kernel); + } - $request = Request::createFromGlobals(); - // ... + $request = Request::createFromGlobals(); + // ... The caching kernel will immediately act as a reverse proxy: caching responses from your application and returning them to the client. diff --git a/page_creation.rst b/page_creation.rst index 90096beb4d4..817c59fc6ff 100644 --- a/page_creation.rst +++ b/page_creation.rst @@ -105,21 +105,21 @@ You can now add your route directly *above* the controller: .. code-block:: diff - // src/Controller/LuckyController.php + // src/Controller/LuckyController.php - // ... + // ... + use Symfony\Component\Routing\Annotation\Route; - class LuckyController - { + class LuckyController + { + /** + * @Route("/lucky/number") + */ - public function number() - { - // this looks exactly the same - } - } + public function number() + { + // this looks exactly the same + } + } That's it! The page - http://localhost:8000/lucky/number will work exactly like before! Annotations are the recommended way to configure routes. @@ -209,16 +209,16 @@ Make sure that ``LuckyController`` extends Symfony's base .. code-block:: diff - // src/Controller/LuckyController.php + // src/Controller/LuckyController.php - // ... + // ... + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; - class LuckyController + class LuckyController extends AbstractController - { - // ... - } + { + // ... + } Now, use the handy ``render()`` function to render a template. Pass it a ``number`` variable so you can use it in Twig:: diff --git a/quick_tour/flex_recipes.rst b/quick_tour/flex_recipes.rst index 16724e3ee90..1b929667b92 100644 --- a/quick_tour/flex_recipes.rst +++ b/quick_tour/flex_recipes.rst @@ -75,28 +75,28 @@ Thanks to Flex, after one command, you can start using Twig immediately: .. code-block:: diff - render('default/index.html.twig', [ + 'name' => $name, + ]); - } - } + } + } By extending ``AbstractController``, you now have access to a number of shortcut methods and tools, like ``render()``. Create the new template: diff --git a/quick_tour/the_architecture.rst b/quick_tour/the_architecture.rst index d88bb5d32ed..0d640d1746d 100644 --- a/quick_tour/the_architecture.rst +++ b/quick_tour/the_architecture.rst @@ -138,12 +138,12 @@ difference is that it's done in the constructor: .. code-block:: diff - logger = $logger; + } - public function getRandomGreeting() - { - // ... + public function getRandomGreeting() + { + // ... + $this->logger->info('Using the greeting: '.$greeting); - return $greeting; - } - } + return $greeting; + } + } Yes! This works too: no configuration, no time wasted. Keep coding! @@ -279,7 +279,7 @@ from ``dev`` to ``prod``: .. code-block:: diff - # .env + # .env - APP_ENV=dev + APP_ENV=prod @@ -321,10 +321,10 @@ Thanks to a new recipe installed by Flex, look at the ``.env`` file again: .. code-block:: diff - ###> symfony/framework-bundle ### - APP_ENV=dev - APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10 - ###< symfony/framework-bundle ### + ###> symfony/framework-bundle ### + APP_ENV=dev + APP_SECRET=cc86c7ca937636d5ddf1b754beb22a10 + ###< symfony/framework-bundle ### + ###> doctrine/doctrine-bundle ### + # ... diff --git a/quick_tour/the_big_picture.rst b/quick_tour/the_big_picture.rst index 4fae7ef5991..b6ad8eaafdd 100644 --- a/quick_tour/the_big_picture.rst +++ b/quick_tour/the_big_picture.rst @@ -105,32 +105,32 @@ But the routing system is *much* more powerful. So let's make the route more int .. code-block:: diff - # config/routes.yaml - index: + # config/routes.yaml + index: - path: / + path: /hello/{name} - controller: 'App\Controller\DefaultController::index' + controller: 'App\Controller\DefaultController::index' The URL to this page has changed: it is *now* ``/hello/*``: the ``{name}`` acts like a wildcard that matches anything. And it gets better! Update the controller too: .. code-block:: diff - passwordEncoder = $passwordEncoder; + } - public function load(ObjectManager $manager) - { - $user = new User(); - // ... + public function load(ObjectManager $manager) + { + $user = new User(); + // ... + $user->setPassword($this->passwordEncoder->encodePassword( + $user, + 'the_new_password' + )); - // ... - } - } + // ... + } + } You can manually encode a password by running: @@ -671,8 +671,8 @@ using annotations: .. code-block:: diff - // src/Controller/AdminController.php - // ... + // src/Controller/AdminController.php + // ... + use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted; @@ -681,18 +681,18 @@ using annotations: + * + * @IsGranted("ROLE_ADMIN") + */ - class AdminController extends AbstractController - { + class AdminController extends AbstractController + { + /** + * Require ROLE_ADMIN for only this controller method. + * + * @IsGranted("ROLE_ADMIN") + */ - public function adminDashboard() - { - // ... - } - } + public function adminDashboard() + { + // ... + } + } For more information, see the `FrameworkExtraBundle documentation`_. diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index 768ce725a72..d78a415ff34 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -377,17 +377,17 @@ be redirected after success: .. code-block:: diff - // src/Security/LoginFormAuthenticator.php + // src/Security/LoginFormAuthenticator.php - // ... - public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) - { - // ... + // ... + public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) + { + // ... - throw new \Exception('TODO: provide a valid redirect inside '.__FILE__); + // redirect to some "app_homepage" route - of wherever you want + return new RedirectResponse($this->urlGenerator->generate('app_homepage')); - } + } Unless you have any other TODOs in that file, that's it! If you're loading users from the database, make sure you've loaded some :ref:`dummy users `. diff --git a/security/guard_authentication.rst b/security/guard_authentication.rst index 7a6a25b9618..7f0ff8b7f0b 100644 --- a/security/guard_authentication.rst +++ b/security/guard_authentication.rst @@ -27,22 +27,22 @@ your ``User`` class (the ``make:entity`` command is a good way to do this): .. code-block:: diff - // src/Entity/User.php - namespace App\Entity; + // src/Entity/User.php + namespace App\Entity; - // ... + // ... - class User implements UserInterface - { - // ... + class User implements UserInterface + { + // ... + /** + * @ORM\Column(type="string", unique=true, nullable=true) + */ + private $apiToken; - // the getter and setter methods - } + // the getter and setter methods + } Don't forget to generate and run the migration: @@ -518,13 +518,13 @@ are two possible fixes: .. code-block:: diff - // src/Security/MyIpAuthenticator.php - // ... + // src/Security/MyIpAuthenticator.php + // ... + use Symfony\Component\Security\Core\Security; - class MyIpAuthenticator - { + class MyIpAuthenticator + { + private $security; + public function __construct(Security $security) @@ -532,8 +532,8 @@ are two possible fixes: + $this->security = $security; + } - public function supports(Request $request) - { + public function supports(Request $request) + { + // if there is already an authenticated user (likely due to the session) + // then return false and skip authentication: there is no need. + if ($this->security->getUser()) { @@ -542,8 +542,8 @@ are two possible fixes: + // the user is not logged in, so the authenticator should continue + return true; - } - } + } + } If you use autowiring, the ``Security`` service will automatically be passed to your authenticator. diff --git a/security/securing_services.rst b/security/securing_services.rst index 67b37dd792e..015d2a76400 100644 --- a/security/securing_services.rst +++ b/security/securing_services.rst @@ -14,14 +14,14 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro .. code-block:: diff - // src/Newsletter/NewsletterManager.php + // src/Newsletter/NewsletterManager.php - // ... - use Symfony\Component\Security\Core\Exception\AccessDeniedException; + // ... + use Symfony\Component\Security\Core\Exception\AccessDeniedException; + use Symfony\Component\Security\Core\Security; - class SalesReportManager - { + class SalesReportManager + { + private $security; + public function __construct(Security $security) @@ -29,19 +29,19 @@ want to include extra details only for users that have a ``ROLE_SALES_ADMIN`` ro + $this->security = $security; + } - public function sendNewsletter() - { - $salesData = []; + public function sendNewsletter() + { + $salesData = []; + if ($this->security->isGranted('ROLE_SALES_ADMIN')) { + $salesData['top_secret_numbers'] = rand(); + } - // ... - } + // ... + } - // ... - } + // ... + } If you're using the :ref:`default services.yaml configuration `, Symfony will automatically pass the ``security.helper`` to your service diff --git a/service_container.rst b/service_container.rst index 9c4892712ea..fec082a377c 100644 --- a/service_container.rst +++ b/service_container.rst @@ -369,34 +369,34 @@ example, suppose you want to make the admin email configurable: .. code-block:: diff - // src/Service/SiteUpdateManager.php - // ... + // src/Service/SiteUpdateManager.php + // ... - class SiteUpdateManager - { - // ... + class SiteUpdateManager + { + // ... + private $adminEmail; - public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer) + public function __construct(MessageGenerator $messageGenerator, MailerInterface $mailer, string $adminEmail) - { - // ... + { + // ... + $this->adminEmail = $adminEmail; - } + } - public function notifyOfSiteUpdate(): bool - { - // ... + public function notifyOfSiteUpdate(): bool + { + // ... - $email = (new Email()) - // ... + $email = (new Email()) + // ... - ->to('manager@example.com') + ->to($this->adminEmail) - // ... - ; - // ... - } - } + // ... + ; + // ... + } + } If you make this change and refresh, you'll see an error: diff --git a/setup/flex.rst b/setup/flex.rst index 31f034db862..21c470a1073 100644 --- a/setup/flex.rst +++ b/setup/flex.rst @@ -58,14 +58,14 @@ manual steps: .. code-block:: diff - { - "require": { - "symfony/flex": "^1.0", + { + "require": { + "symfony/flex": "^1.0", + }, + "conflict": { + "symfony/symfony": "*" - } - } + } + } Now you must add in ``composer.json`` all the Symfony dependencies required by your project. A quick way to do that is to add all the components that diff --git a/setup/unstable_versions.rst b/setup/unstable_versions.rst index 5e11526b20e..5e6e138ff8d 100644 --- a/setup/unstable_versions.rst +++ b/setup/unstable_versions.rst @@ -33,14 +33,14 @@ new version and change your ``minimum-stability`` to ``beta``: .. code-block:: diff - { - "require": { + { + "require": { + "symfony/framework-bundle": "^4.0", + "symfony/finder": "^4.0", - "...": "..." - }, + "...": "..." + }, + "minimum-stability": "beta" - } + } You can also use set ``minimum-stability`` to ``dev``, or omit this line entirely, and opt into your stability on each package by using constraints diff --git a/setup/upgrade_major.rst b/setup/upgrade_major.rst index 89f80ae109f..1562be9442b 100644 --- a/setup/upgrade_major.rst +++ b/setup/upgrade_major.rst @@ -131,26 +131,26 @@ starting with ``symfony/`` to the new major version: .. code-block:: diff - { - "...": "...", + { + "...": "...", - "require": { + "require": { - "symfony/cache": "4.4.*", + "symfony/cache": "5.0.*", - "symfony/config": "4.4.*", + "symfony/config": "5.0.*", - "symfony/console": "4.4.*", + "symfony/console": "5.0.*", - "...": "...", + "...": "...", - "...": "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", - }, - "...": "...", - } + "...": "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", + }, + "...": "...", + } 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 @@ -158,13 +158,13 @@ this one. For instance, update it to ``5.0.*`` to upgrade to Symfony 5.0: .. code-block:: diff - "extra": { - "symfony": { - "allow-contrib": false, + "extra": { + "symfony": { + "allow-contrib": false, - "require": "4.4.*" + "require": "5.0.*" - } - } + } + } Next, use Composer to download new versions of the libraries: diff --git a/setup/upgrade_minor.rst b/setup/upgrade_minor.rst index 09a88124fa8..66e261a6726 100644 --- a/setup/upgrade_minor.rst +++ b/setup/upgrade_minor.rst @@ -28,39 +28,39 @@ probably need to update the version constraint next to each library starting .. code-block:: diff - { - "...": "...", + { + "...": "...", - "require": { + "require": { - "symfony/cache": "4.3.*", + "symfony/cache": "4.4.*", - "symfony/config": "4.3.*", + "symfony/config": "4.4.*", - "symfony/console": "4.3.*", + "symfony/console": "4.4.*", - "...": "...", + "...": "...", - "...": "A few libraries starting with - symfony/ follow their versioning scheme. You - do not need to update these versions: you can - upgrade them independently whenever you want", - "symfony/monolog-bundle": "^3.5", - }, - "...": "...", - } + "...": "A few libraries starting with + symfony/ follow their versioning scheme. You + do not need to update these versions: you can + upgrade them independently whenever you want", + "symfony/monolog-bundle": "^3.5", + }, + "...": "...", + } Your ``composer.json`` file should also have an ``extra`` block that you will *also* need to update: .. code-block:: diff - "extra": { - "symfony": { - "...": "...", + "extra": { + "symfony": { + "...": "...", - "require": "4.3.*" + "require": "4.4.*" - } - } + } + } Next, use Composer to download new versions of the libraries: From c55c2a2745ce464fc90f0cb8c8d3d173205904ec Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 2 Mar 2021 21:23:44 +0100 Subject: [PATCH 0558/5766] [Messenger] Added note about timezone --- messenger.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/messenger.rst b/messenger.rst index 0ee914216ca..1f4b116595e 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1001,6 +1001,12 @@ auto_setup Whether the table should be created automatically during send / get. true ================== ===================================== ====================== +.. caution:: + + Messages are stored in the database will have a datetime property which is created + with the timezone of the current system. This may cause issues if multiple machines + with different timezone configuration is using the same storage. + Redis Transport ~~~~~~~~~~~~~~~ From e98f953d7bda83018ed723ad37f48b1656862f21 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Wed, 3 Mar 2021 21:12:36 +0100 Subject: [PATCH 0559/5766] [Translation] Update translation.rst The trans() in the translator service is a method, not a function. --- translation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translation.rst b/translation.rst index 20025b8b5cd..4a0137b94d8 100644 --- a/translation.rst +++ b/translation.rst @@ -352,7 +352,7 @@ The ``translation:update`` command looks for missing translations in: defined in the :ref:`twig.default_path ` and :ref:`twig.paths ` config options); * Any PHP file/class that injects or :doc:`autowires ` - the ``translator`` service and makes calls to the ``trans()`` function. + the ``translator`` service and makes calls to the ``trans()`` method. .. versionadded:: 4.3 From 3d5dadda9986dd58c5e9df44bb3fd6ce6c1cf438 Mon Sep 17 00:00:00 2001 From: Roland Franssen Date: Fri, 5 Mar 2021 09:10:22 +0100 Subject: [PATCH 0560/5766] Update env_var_processors.rst --- configuration/env_var_processors.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration/env_var_processors.rst b/configuration/env_var_processors.rst index 7b134067bef..a1c28de0c4f 100644 --- a/configuration/env_var_processors.rst +++ b/configuration/env_var_processors.rst @@ -285,7 +285,7 @@ Symfony provides the following env var processors: # config/packages/framework.yaml parameters: - env(TRUSTED_HOSTS): "10.0.0.1, 10.0.0.2" + env(TRUSTED_HOSTS): "10.0.0.1,10.0.0.2" framework: trusted_hosts: '%env(csv:TRUSTED_HOSTS)%' @@ -302,7 +302,7 @@ Symfony provides the following env var processors: https://symfony.com/schema/dic/symfony/symfony-1.0.xsd"> - ["10.0.0.1", "10.0.0.2"] + 10.0.0.1,10.0.0.2 @@ -311,7 +311,7 @@ Symfony provides the following env var processors: .. code-block:: php // config/packages/framework.php - $container->setParameter('env(TRUSTED_HOSTS)', '["10.0.0.1", "10.0.0.2"]'); + $container->setParameter('env(TRUSTED_HOSTS)', '10.0.0.1,10.0.0.2'); $container->loadFromExtension('framework', [ 'trusted_hosts' => '%env(csv:TRUSTED_HOSTS)%', ]); From e40b5d5ddefe1e61a14736d2a5f80521c3478d72 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Mar 2021 10:37:44 +0100 Subject: [PATCH 0561/5766] Reword --- messenger.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/messenger.rst b/messenger.rst index 1f4b116595e..52f125a3b61 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1003,9 +1003,9 @@ auto_setup Whether the table should be created .. caution:: - Messages are stored in the database will have a datetime property which is created - with the timezone of the current system. This may cause issues if multiple machines - with different timezone configuration is using the same storage. + 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. Redis Transport ~~~~~~~~~~~~~~~ From b11322cc7f511054f9601e2bbaf55fe846633e2b Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 2 Mar 2021 15:32:52 +0100 Subject: [PATCH 0562/5766] [Cache] Remove `compression` option from Redis and Memcache --- components/cache/adapters/memcached_adapter.rst | 12 ------------ components/cache/adapters/redis_adapter.rst | 5 ----- 2 files changed, 17 deletions(-) diff --git a/components/cache/adapters/memcached_adapter.rst b/components/cache/adapters/memcached_adapter.rst index 9cd8c8cdd25..1b8103433e1 100644 --- a/components/cache/adapters/memcached_adapter.rst +++ b/components/cache/adapters/memcached_adapter.rst @@ -124,7 +124,6 @@ option names and their respective values:: // associative array of configuration options [ - 'compression' => true, 'libketama_compatible' => true, 'serializer' => 'igbinary', ] @@ -143,17 +142,6 @@ Available Options server(s). Any action that retrieves data, quits the connection, or closes down the connection will cause the buffer to be committed. -``compression`` (type: ``bool``, default: ``true``) - Enables or disables payload compression, where item values longer than 100 - bytes are compressed during storage and decompressed during retrieval. - -``compression_type`` (type: ``string``) - Specifies the compression method used on value payloads. when the - **compression** option is enabled. - - Valid option values include ``fastlz`` and ``zlib``, with a default value - that *varies based on flags used at compilation*. - ``connect_timeout`` (type: ``int``, default: ``1000``) Specifies the timeout (in milliseconds) of socket connection operations when the ``no_block`` option is enabled. diff --git a/components/cache/adapters/redis_adapter.rst b/components/cache/adapters/redis_adapter.rst index 935afcd9f92..ef40de623e9 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -131,7 +131,6 @@ array of ``key => value`` pairs representing option names and their respective v // associative array of configuration options [ - 'compression' => true, 'lazy' => false, 'persistent' => 0, 'persistent_id' => null, @@ -151,10 +150,6 @@ Available Options If none is specified, it will return ``\Redis`` if the ``redis`` extension is available, and ``\Predis\Client`` otherwise. -``compression`` (type: ``bool``, default: ``true``) - Enables or disables compression of items. This requires phpredis v4 or higher with - LZF support enabled. - ``lazy`` (type: ``bool``, default: ``false``) Enables or disables lazy connections to the backend. It's ``false`` by default when using this as a stand-alone component and ``true`` by default From e98cef46e8a9469049446c97e49fc8b6817de372 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Farys?= Date: Thu, 4 Mar 2021 18:00:32 +0100 Subject: [PATCH 0563/5766] Fixed typo for YamlEncoder section Minor typo fix for YamlEncoder section --- components/serializer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/serializer.rst b/components/serializer.rst index f554ed7cf76..f2c3285a33b 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -994,7 +994,7 @@ The ``YamlEncoder`` Context Options The ``encode()`` method, like other encoder, uses ``context`` to set configuration options for the YamlEncoder an associative array:: - $xmlEncoder->encode($array, 'xml', $context); + $yamlEncoder->encode($array, 'yaml', $context); These are the options available: From 84ce746d39ce93e7c24a161763258794123be877 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 2 Mar 2021 14:00:25 +0100 Subject: [PATCH 0564/5766] [Lock] Added paragraph about auto release --- components/lock.rst | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/components/lock.rst b/components/lock.rst index 7b2c131947d..c1d3983aa46 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -199,6 +199,38 @@ This component also provides two useful methods related to expiring locks: ``getRemainingLifetime()`` (which returns ``null`` or a ``float`` as seconds) and ``isExpired()`` (which returns a boolean). +Automatically Releasing The Lock +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +A Lock will be automatically released when the Lock object is destructed. This is +an implementation detail that will be important when Locks are shared between processes. +In the example below, the ``pcntl_fork()`` will create two processes and the Lock +will be released automatically as soon as one process finishes:: + + // ... + $lock = $factory->createLock('report-generation', 3600); + if (!$lock->acquire()) { + return; + } + + $pid = pcntl_fork(); + if ($pid == -1) { + // Could not fork + exit(1); + } elseif ($pid) { + // Parent process + sleep(30); + } else { + // Child process + echo 'The lock will be released now.' + exit(0); + } + // ... + +To disable this behavior, one needs to set the 3rd argument to the ``LockFactory::createLock()`` +to false. That will make the Lock acquired for 3600 seconds or until ``Lock::release()`` +is called. + The Owner of The Lock --------------------- From 4ed8ef05f5c2638305fa0e70f76e2f66a043ded0 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Mar 2021 11:00:58 +0100 Subject: [PATCH 0565/5766] Tweaks --- components/lock.rst | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/components/lock.rst b/components/lock.rst index e92603aec5e..e0baecd9560 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -203,10 +203,10 @@ as seconds) and ``isExpired()`` (which returns a boolean). Automatically Releasing The Lock ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -A Lock will be automatically released when the Lock object is destructed. This is -an implementation detail that will be important when Locks are shared between processes. -In the example below, the ``pcntl_fork()`` will create two processes and the Lock -will be released automatically as soon as one process finishes:: +Lock are automatically released when their Lock objects are destructed. This is +an implementation detail that will be important when sharing Locks between +processes. In the example below, ``pcntl_fork()`` creates two processes and the +Lock will be released automatically as soon as one process finishes:: // ... $lock = $factory->createLock('report-generation', 3600); @@ -215,7 +215,7 @@ will be released automatically as soon as one process finishes:: } $pid = pcntl_fork(); - if ($pid == -1) { + if (-1 === $pid) { // Could not fork exit(1); } elseif ($pid) { @@ -228,9 +228,9 @@ will be released automatically as soon as one process finishes:: } // ... -To disable this behavior, one needs to set the 3rd argument to the ``LockFactory::createLock()`` -to false. That will make the Lock acquired for 3600 seconds or until ``Lock::release()`` -is called. +To disable this behavior, set to ``false`` the third argument of +``LockFactory::createLock()``. That will make the lock acquired for 3600 seconds +or until ``Lock::release()`` is called. The Owner of The Lock --------------------- From 685cb2c6a684aca654b8be4baee4d81536da0a71 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Mar 2021 12:19:52 +0100 Subject: [PATCH 0566/5766] Tweak --- bundles/prepend_extension.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bundles/prepend_extension.rst b/bundles/prepend_extension.rst index d0c6522e4ec..a332d45141f 100644 --- a/bundles/prepend_extension.rst +++ b/bundles/prepend_extension.rst @@ -82,9 +82,11 @@ in case a specific other bundle is not registered:: // process the configuration of AcmeHelloExtension $configs = $container->getExtensionConfig($this->getAlias()); - // resolve config parameters e.g. %kernel.debug% to boolean value + + // resolve config parameters e.g. %kernel.debug% to its boolean value $resolvingBag = $container->getParameterBag(); $configs = $resolvingBag->resolveValue($configs); + // use the Configuration class to generate a config array with // the settings "acme_hello" $config = $this->processConfiguration(new Configuration(), $configs); From 126cf24a33a440396f8e7d7ffb961131272add0b Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 2 Mar 2021 20:05:19 +0100 Subject: [PATCH 0567/5766] [Cache] Adding about marshallers --- components/cache.rst | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/components/cache.rst b/components/cache.rst index a620206682f..35002831be8 100644 --- a/components/cache.rst +++ b/components/cache.rst @@ -192,6 +192,25 @@ Now you can create, retrieve, update and delete items using this cache pool:: For a list of all of the supported adapters, see :doc:`/components/cache/cache_pools`. +Serializing Data +---------------- + +When an item is stored in the cache, it is serialised to a string. It is a class +implementing :class:`Symfony\\Component\\Cache\\Marshaller\\MarshallerInterface` +that is responsible for serializing and unserializing. Or to be technically correct: +to ``marshall()`` and to ``unmarshall()``. + +The :class:`Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller` is using PHP's +``serialize()`` or ``igbinary_serialize()`` if the Igbinary extension is installed. +There are other marshallers that will encrypt or compress the data before storing it:: + + use Symfony\Component\Cache\Adapter\RedisAdapter; + use Symfony\Component\Cache\DefaultMarshaller; + use Symfony\Component\Cache\DeflateMarshaller; + + $marshaller = new DeflateMarshaller(new DefaultMarshaller()); + $cache = new RedisAdapter(new \Redis(), 'namespace', 0, $marshaller); + Advanced Usage -------------- From 90ce1b2040cd92c02bade2adf1a8edbaf923e3d3 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 5 Mar 2021 13:09:24 +0100 Subject: [PATCH 0568/5766] Updates --- components/cache.rst | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/components/cache.rst b/components/cache.rst index 35002831be8..16c1f8a7691 100644 --- a/components/cache.rst +++ b/components/cache.rst @@ -192,17 +192,26 @@ Now you can create, retrieve, update and delete items using this cache pool:: For a list of all of the supported adapters, see :doc:`/components/cache/cache_pools`. -Serializing Data ----------------- +Marshalling (Serializing) Data +------------------------------ -When an item is stored in the cache, it is serialised to a string. It is a class -implementing :class:`Symfony\\Component\\Cache\\Marshaller\\MarshallerInterface` -that is responsible for serializing and unserializing. Or to be technically correct: -to ``marshall()`` and to ``unmarshall()``. +.. note:: + + `Marshalling`_ and `serializing`_ are similar concepts. Serializing is the + process of translating an object state into a format that can be stored + (e.g. in a file). Marshalling is the process of translating both the object + state and its codebase into a format that can be stored or transmitted. + + Unmarshalling an object produces a copy of the original object, possibly by + automatically loading the class definitions of the object. + +Symfony uses *marshallers* (classes which implement +:class:`Symfony\\Component\\Cache\\Marshaller\\MarshallerInterface`) to process +the cache items before storing them. -The :class:`Symfony\\Component\\Cache\\Marshaller\\DefaultMarshaller` is using PHP's -``serialize()`` or ``igbinary_serialize()`` if the Igbinary extension is installed. -There are other marshallers that will encrypt or compress the data before storing it:: +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:: use Symfony\Component\Cache\Adapter\RedisAdapter; use Symfony\Component\Cache\DefaultMarshaller; @@ -224,3 +233,6 @@ Advanced Usage .. _`Cache Contracts`: https://github.com/symfony/contracts/blob/master/Cache/CacheInterface.php .. _`Stampede prevention`: https://en.wikipedia.org/wiki/Cache_stampede .. _Probabilistic early expiration: https://en.wikipedia.org/wiki/Cache_stampede#Probabilistic_early_expiration +.. _`Marshalling`: https://en.wikipedia.org/wiki/Marshalling_(computer_science) +.. _`serializing`: https://en.wikipedia.org/wiki/Serialization +.. _`Igbinary extension`: https://github.com/igbinary/igbinary From 8a2e8d77bc4442e02dad895e1b63226968f586cf Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 6 Mar 2021 09:47:47 +0100 Subject: [PATCH 0569/5766] [Validator] Add PHP Attributes to validation groups --- validation/groups.rst | 21 +++++++++++ validation/sequence_provider.rst | 65 +++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 2 deletions(-) diff --git a/validation/groups.rst b/validation/groups.rst index 7681f583a08..70dcc975655 100644 --- a/validation/groups.rst +++ b/validation/groups.rst @@ -42,6 +42,27 @@ user registers and when a user updates their contact information later: private $city; } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Security\Core\User\UserInterface; + use Symfony\Component\Validator\Constraints as Assert; + + class User implements UserInterface + { + #[Assert\Email(groups: ['registration'])] + private $email; + + #[Assert\NotBlank(groups: ['registration'])] + #[Assert\Length(min: 7, groups: ['registration'])] + private $password; + + #[Assert\Length(min: 2)] + private $city; + } + .. code-block:: yaml # config/validator/validation.yaml diff --git a/validation/sequence_provider.rst b/validation/sequence_provider.rst index 503c50f67e5..699711b661d 100644 --- a/validation/sequence_provider.rst +++ b/validation/sequence_provider.rst @@ -47,6 +47,33 @@ username and the password are different only if all other validation passes } } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Security\Core\User\UserInterface; + use Symfony\Component\Validator\Constraints as Assert; + + #[Assert\GroupSequence(['User', 'Strict'])] + class User implements UserInterface + { + #[Assert\NotBlank] + private $username; + + #[Assert\NotBlank] + private $password; + + #[Assert\IsTrue( + message: 'The password cannot match your username', + groups: ['Strict'], + )] + public function isPasswordSafe() + { + return ($this->username !== $this->password); + } + } + .. code-block:: yaml # config/validator/validation.yaml @@ -151,7 +178,7 @@ You can also define a group sequence in the ``validation_groups`` form option:: // src/Form/MyType.php namespace App\Form; - + use Symfony\Component\Form\AbstractType; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\GroupSequence; @@ -204,6 +231,27 @@ entity and a new constraint group called ``Premium``: // ... } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + use Symfony\Component\Validator\Constraints as Assert; + + class User + { + #[Assert\NotBlank] + private $name; + + #[Assert\CardScheme( + schemes: [Assert\CardScheme::VISA], + groups: ['Premium'], + )] + private $creditCard; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -263,7 +311,7 @@ entity and a new constraint group called ``Premium``: { $metadata->addPropertyConstraint('name', new Assert\NotBlank()); $metadata->addPropertyConstraint('creditCard', new Assert\CardScheme([ - 'schemes' => ['VISA'], + 'schemes' => [Assert\CardScheme::VISA], 'groups' => ['Premium'], ])); } @@ -319,6 +367,19 @@ provides a sequence of groups to be validated: // ... } + .. code-block:: php-attributes + + // src/Entity/User.php + namespace App\Entity; + + // ... + + #[Assert\GroupSequenceProvider] + class User implements GroupSequenceProviderInterface + { + // ... + } + .. code-block:: yaml # config/validator/validation.yaml From 72fcddd507da0b2f21cfa384182273ccdcef152e Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sat, 6 Mar 2021 14:15:39 +0100 Subject: [PATCH 0570/5766] [Validator] Add PHP Attributes to validation page --- validation.rst | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/validation.rst b/validation.rst index b0b74525734..0ad5a3108ec 100644 --- a/validation.rst +++ b/validation.rst @@ -68,6 +68,20 @@ following: private $name; } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + // ... + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotBlank] + private $name; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -351,6 +365,25 @@ literature genre mostly associated with the author, which can be set to either // ... } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + // ... + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\Choice( + choices: ['fiction', 'non-fiction'], + message: 'Choose a valid genre.', + )] + private $genre; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -437,6 +470,22 @@ options can be specified in this way. // ... } + .. 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 $genre; + + // ... + } + .. code-block:: yaml # config/validator/validation.yaml @@ -559,6 +608,20 @@ class to have at least 3 characters. private $firstName; } + .. code-block:: php-attributes + + // src/Entity/Author.php + + // ... + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\NotBlank] + #[Assert\Length(min: 3)] + private $firstName; + } + .. code-block:: yaml # config/validator/validation.yaml @@ -655,6 +718,23 @@ this method must return ``true``: } } + .. code-block:: php-attributes + + // src/Entity/Author.php + namespace App\Entity; + + // ... + use Symfony\Component\Validator\Constraints as Assert; + + class Author + { + #[Assert\IsTrue(message: 'The password cannot match your first name')] + public function isPasswordSafe() + { + // ... return true or false + } + } + .. code-block:: yaml # config/validator/validation.yaml From d1190fcfafecb4ee29f8a59fa77210a0b9822799 Mon Sep 17 00:00:00 2001 From: William Pinaud Date: Sat, 6 Mar 2021 15:51:38 +0100 Subject: [PATCH 0571/5766] Added doc and defaults for missing 'ttl' option in config Hi, this might need validation, but I stumbled upon a difference between what the doc says (4.4+) and what's in https://github.com/symfony/http-foundation/blob/5.x/Session/Storage/Handler/RedisSessionHandler.php. I think the 'ttl' option is unexplained and undocumented since it was added in 2019: https://github.com/symfony/http-foundation/commit/0c5217a9050712a1e66f851d04962abf8f2c6fc4 --- session/database.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/session/database.rst b/session/database.rst index a0fb1b3d4a6..f7a5b002dbb 100644 --- a/session/database.rst +++ b/session/database.rst @@ -89,9 +89,10 @@ and ``RedisProxy``: Symfony\Component\HttpFoundation\Session\Storage\Handler\RedisSessionHandler: arguments: - '@Redis' - # you can optionally pass an array of options. The only option is 'prefix', - # which defines the prefix to use for the keys to avoid collision on the Redis server - # - { prefix: 'my_prefix' } + # you can optionally pass an array of options. The only options are 'prefix' and 'ttl', + # which define the prefix to use for the keys to avoid collision on the Redis server + # and the expiration time for any given entry (in seconds), defaults are 'sf_s' and null: + # - { 'prefix' => 'my_prefix', 'ttl' => 600 } .. code-block:: xml @@ -99,8 +100,9 @@ and ``RedisProxy``: - @@ -116,9 +118,10 @@ and ``RedisProxy``: ->register(RedisSessionHandler::class) ->addArgument( new Reference('Redis'), - // you can optionally pass an array of options. The only option is 'prefix', - // which defines the prefix to use for the keys to avoid collision on the Redis server: - // ['prefix' => 'my_prefix'], + // you can optionally pass an array of options. The only options are 'prefix' and 'ttl', + // which define the prefix to use for the keys to avoid collision on the Redis server + // and the expiration time for any given entry (in seconds), defaults are 'sf_s' and null: + // ['prefix' => 'my_prefix', 'ttl' => 600], ); Next, use the :ref:`handler_id ` From b5adc53d63bc0104ae25466c38aa4ea2be77ac3e Mon Sep 17 00:00:00 2001 From: Samuel NELA Date: Sat, 6 Mar 2021 23:40:02 +0100 Subject: [PATCH 0572/5766] [Uid] Fix typos --- components/uid.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index 366ad1bcec6..6a73666f511 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -186,7 +186,7 @@ of the UUID parameters:: { $qb = $this->createQueryBuilder('p') // ... - // add 'uuid' as the third argument to tell Doctrine that this is an UUID + // add 'uuid' as the third argument to tell Doctrine that this is a UUID ->setParameter('user', $user->getUuid(), 'uuid') // alternatively, you can convert it to a value compatible with @@ -333,7 +333,7 @@ of the ULID parameters:: { $qb = $this->createQueryBuilder('p') // ... - // add 'ulid' as the third argument to tell Doctrine that this is an ULID + // add 'ulid' as the third argument to tell Doctrine that this is a ULID ->setParameter('user', $user->getUlid(), 'ulid') // alternatively, you can convert it to a value compatible with From 070c9bb8781d956ba645442e1b71781a79e51044 Mon Sep 17 00:00:00 2001 From: Massimiliano Arione Date: Sun, 7 Mar 2021 11:20:51 +0100 Subject: [PATCH 0573/5766] add a warning about object as extra parameter in route --- routing.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/routing.rst b/routing.rst index 86defd2bafc..7c852af98da 100644 --- a/routing.rst +++ b/routing.rst @@ -1880,6 +1880,14 @@ use the ``generateUrl()`` helper:: // the 'blog' route only defines the 'page' parameter; the generated URL is: // /blog/2?category=Symfony +.. caution:: + + 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) + as value of an extra parameter, you need to explictly convert it to a string:: + + $this->generateUrl('blog', ['uuid' => (string) $entity->getUuid())] + If your controller does not extend from ``AbstractController``, you'll need to :ref:`fetch services in your controller ` and follow the instructions of the next section. From db79f2a9e6f0ce0d4c485fe21df43fdc68470990 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 7 Mar 2021 11:23:33 +0100 Subject: [PATCH 0574/5766] [Framework] Fix reference to default_path --- 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 246726e820c..ada92f8f25e 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -2223,7 +2223,7 @@ paths 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 -`default_path ` have more priority than +:ref:`default_path ` have more priority than translations from all these paths. .. _reference-translator-default_path: From a4063c413d398f48e88356c3fd7f27d338b02f9b Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 7 Mar 2021 11:39:39 +0100 Subject: [PATCH 0575/5766] [Translation] Fix link to Translatable Extension documentation The site http://atlantic18.github.io/DoctrineExtensions/ returns 404. --- translation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translation.rst b/translation.rst index 4a0137b94d8..0e1601cc536 100644 --- a/translation.rst +++ b/translation.rst @@ -610,5 +610,5 @@ Learn more .. _`ICU MessageFormat`: https://unicode-org.github.io/icu/userguide/format_parse/messages/ .. _`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`: http://atlantic18.github.io/DoctrineExtensions/doc/translatable.html +.. _`Translatable Extension`: https://github.com/doctrine-extensions/DoctrineExtensions/blob/main/doc/translatable.md .. _`Translatable Behavior`: https://github.com/KnpLabs/DoctrineBehaviors From eba011912bd32de759dc4a6569bacdbe53701f39 Mon Sep 17 00:00:00 2001 From: Chris Maiden Date: Sun, 7 Mar 2021 13:54:03 +0000 Subject: [PATCH 0576/5766] Fix typo --- configuration/secrets.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration/secrets.rst b/configuration/secrets.rst index bb89c67258f..15f4d194f5b 100644 --- a/configuration/secrets.rst +++ b/configuration/secrets.rst @@ -212,9 +212,9 @@ Listing the secrets will now also display the local variable: DATABASE_PASSWORD "dev value" "root" ------------------- ------------- ------------- -Symfony also provides the ``secrets:decrypt-to-local`` command to decrypts -all secrets and stores them in the local vault and ``secrets:encrypt-from-local`` -to encrypt all local secrets to the vault. +Symfony also provides the ``secrets:decrypt-to-local`` command which decrypts +all secrets and stores them in the local vault and the ``secrets:encrypt-from-local`` +command to encrypt all local secrets to the vault. Secrets in the test Environment ------------------------------- From 5f26782afe95e6ef9912b57899222142a5ddc658 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 9 Mar 2021 11:05:00 +0100 Subject: [PATCH 0577/5766] [PropertyAccess] fix the component name --- reference/forms/types/entity.rst | 2 +- serializer/normalizers.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst index 21183ad4e57..cf245c2c275 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -182,7 +182,7 @@ more details, see the main :ref:`choice_label ` doc When passing a string, the ``choice_label`` option is a property path. So you can use anything supported by the - :doc:`PropertyAccessor component ` + :doc:`PropertyAccess component ` For example, if the translations property is actually an associative array of objects, each with a ``name`` property, then you could do this:: diff --git a/serializer/normalizers.rst b/serializer/normalizers.rst index 5aef4568dc6..af30532e48a 100644 --- a/serializer/normalizers.rst +++ b/serializer/normalizers.rst @@ -25,7 +25,7 @@ Symfony includes the following normalizers but you can also :doc:`create your own normalizer `: * :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer` to - normalize PHP object using the :doc:`PropertyAccessor component `; + normalize PHP object using the :doc:`PropertyAccess component `; * :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer` for :phpclass:`DateTimeZone` objects * :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer` for From c5101c7d2b0ec56444bd35dd76c3019ab674fc5d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 9 Mar 2021 11:09:09 +0100 Subject: [PATCH 0578/5766] [PropertyAccess] use bitwise instead of boolean flags --- components/property_access.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/property_access.rst b/components/property_access.rst index a1ae83ab406..fdb678c1c3e 100644 --- a/components/property_access.rst +++ b/components/property_access.rst @@ -435,7 +435,7 @@ Sometimes, adder and remover methods don't use the standard ``add`` or ``remove` $list = new PeopleList(); $reflectionExtractor = new ReflectionExtractor(null, null, ['join', 'leave']); - $propertyAccessor = new PropertyAccessor(false, false, null, true, $reflectionExtractor, $reflectionExtractor); + $propertyAccessor = new PropertyAccessor(PropertyAccessor::DISALLOW_MAGIC_METHODS, false, null, true, $reflectionExtractor, $reflectionExtractor); $propertyAccessor->setValue($person, 'peoples', ['kevin', 'wouter']); var_dump($person->getPeoples()); // ['kevin', 'wouter'] From 97a164daa87d81ede8e5f954a32d1af52f0c2408 Mon Sep 17 00:00:00 2001 From: mostefamed Date: Tue, 9 Mar 2021 11:17:02 +0100 Subject: [PATCH 0579/5766] Fix the matched path value During the test of the example, I didn't get the expected result when calling /blog --- routing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routing.rst b/routing.rst index 86defd2bafc..3fc50a8f5d7 100644 --- a/routing.rst +++ b/routing.rst @@ -1264,7 +1264,7 @@ the common configuration using options when importing the routes. was introduced in Symfony 4.4. In this example, the route of the ``index()`` action will be called ``blog_index`` -and its URL will be ``/blog/``. The route of the ``show()`` action will be called +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 will also validate that the ``_locale`` parameter matches the regular expression defined in the class annotation. From a9cb63d242d7047c226cf2431ed1a407fbf84d0a Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Tue, 9 Mar 2021 11:03:50 +0100 Subject: [PATCH 0580/5766] =?UTF-8?q?[PropertyAccess]=C2=A0do=20not=20pass?= =?UTF-8?q?=20boolean=20constructor=20flags?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/property_access.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/property_access.rst b/components/property_access.rst index fdb678c1c3e..9d3f4e355fc 100644 --- a/components/property_access.rst +++ b/components/property_access.rst @@ -435,7 +435,7 @@ Sometimes, adder and remover methods don't use the standard ``add`` or ``remove` $list = new PeopleList(); $reflectionExtractor = new ReflectionExtractor(null, null, ['join', 'leave']); - $propertyAccessor = new PropertyAccessor(PropertyAccessor::DISALLOW_MAGIC_METHODS, false, null, true, $reflectionExtractor, $reflectionExtractor); + $propertyAccessor = new PropertyAccessor(PropertyAccessor::DISALLOW_MAGIC_METHODS, PropertyAccessor::THROW_ON_INVALID_PROPERTY_PATH, null, $reflectionExtractor, $reflectionExtractor); $propertyAccessor->setValue($person, 'peoples', ['kevin', 'wouter']); var_dump($person->getPeoples()); // ['kevin', 'wouter'] From 607eb2599d09cb3f34f98af79dbcc08ee000e3c1 Mon Sep 17 00:00:00 2001 From: Rob Meijer Date: Tue, 9 Mar 2021 19:44:35 +0000 Subject: [PATCH 0581/5766] [Rate Limiter] Typo in Rate Limiter Status example --- rate_limiter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index 99617f20d59..6982f88cae4 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -293,7 +293,7 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the // ... - $reponse = new Response('...'); + $response = new Response('...'); $response->headers->add($headers); return $response; From ad8330b010dd87a6b869cb2a219f68b58a43a22c Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Wed, 10 Mar 2021 15:32:53 +0100 Subject: [PATCH 0582/5766] [Workflow] fix PHP config --- workflow/dumping-workflows.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow/dumping-workflows.rst b/workflow/dumping-workflows.rst index d1749603155..1611082c6f4 100644 --- a/workflow/dumping-workflows.rst +++ b/workflow/dumping-workflows.rst @@ -241,8 +241,8 @@ Below is the configuration for the pull request state machine with styling added 'pull_request' => [ 'type' => 'state_machine', 'marking_store' => [ - type: 'method', - property: 'currentPlace', + 'type' => 'method', + 'property' => 'currentPlace', ], 'supports' => ['App\Entity\PullRequest'], 'initial_marking' => 'start', From 95ca723c985cb5db4e52a6b394aa7e0b818b1836 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 11 Mar 2021 13:12:02 +0100 Subject: [PATCH 0583/5766] Minor: Sort alphabetically --- mailer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index 08a10c59e03..7cef0ee2668 100644 --- a/mailer.rst +++ b/mailer.rst @@ -1206,9 +1206,9 @@ If your transport does not support tags and metadata, they will be added as cust The following transports currently support tags and metadata: -* Postmark -* Mailgun * MailChimp +* Mailgun +* Postmark * Sendinblue Development & Debugging From 2d924e8363900bf0a2b0f6be2604696472e6db9f Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Sun, 28 Feb 2021 23:25:47 +0100 Subject: [PATCH 0584/5766] [Mailer] Configuration of the message_bus to use --- mailer.rst | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/mailer.rst b/mailer.rst index 9c9c1451add..39f2cb42081 100644 --- a/mailer.rst +++ b/mailer.rst @@ -1094,6 +1094,52 @@ you have a transport called ``async``, you can route the message there: Thanks to this, instead of being delivered immediately, messages will be sent to the transport to be handled later (see :ref:`messenger-worker`). +You can configure which bus is used to dispatch the message using the ``message_bus`` option. +You can also set this to ``false`` to call the Mailer transport directly and +disable asynchronous delivery. + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/mailer.yaml + framework: + mailer: + message_bus: app.another_bus + + .. code-block:: xml + + + + + + + + + + + + .. code-block:: php + + // config/packages/mailer.php + $container->loadFromExtension('framework', [ + 'mailer' => [ + 'message_bus' => 'app.another_bus', + ], + ]); + +.. versionadded:: 5.1 + + The `message_bus` option was introduced in Symfony 5.1. + Adding Tags and Metadata to Emails ---------------------------------- From 1b476a17e54a229bda2ade9732471aa2d1e78978 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 11 Mar 2021 14:06:48 +0100 Subject: [PATCH 0585/5766] minor --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index c25a4246eb1..8f98d9b766f 100644 --- a/mailer.rst +++ b/mailer.rst @@ -1218,7 +1218,7 @@ disable asynchronous delivery. .. versionadded:: 5.1 - The `message_bus` option was introduced in Symfony 5.1. + The ``message_bus`` option was introduced in Symfony 5.1. Adding Tags and Metadata to Emails ---------------------------------- From d59c1c8fdcdff10bc2b2cbd99a73d04261e79d93 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Fri, 12 Mar 2021 00:00:46 +0100 Subject: [PATCH 0586/5766] Update debug.rst --- reference/configuration/debug.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/reference/configuration/debug.rst b/reference/configuration/debug.rst index 86aed3b7ba6..33a6c656537 100644 --- a/reference/configuration/debug.rst +++ b/reference/configuration/debug.rst @@ -67,9 +67,10 @@ dump_destination Configures the output destination of the dumps. -By default, the dumps are shown in the toolbar. Since this is not always -possible (e.g. when working on a JSON API), you can have an alternate output -destination for dumps. Typically, you would set this to ``php://stderr``: +By default, dumps are shown in the WebDebugToolbar when returning HTML. +Since this is not always possible (e.g. when working on a JSON API), +you can have an alternate output destination for dumps. +Typically, you would set this to ``php://stderr``: .. configuration-block:: From ce6cdbe33c5f01b36a2486fdfb649bc8e6bf48e2 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Fri, 12 Mar 2021 00:06:40 +0100 Subject: [PATCH 0587/5766] Update kernel.rst --- reference/configuration/kernel.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/configuration/kernel.rst b/reference/configuration/kernel.rst index 6b0ac4279ad..5cb1f8ea781 100644 --- a/reference/configuration/kernel.rst +++ b/reference/configuration/kernel.rst @@ -5,7 +5,7 @@ Configuring in the Kernel ========================= Some configuration can be done on the kernel class itself (located by default at -``src/Kernel.php``). You can do this by overriding specific methods in +``src/Kernel.php``). You can do this by overriding specific methods of the parent :class:`Symfony\\Component\\HttpKernel\\Kernel` class. Configuration From 1ad9effde7927b35af83c1fb3b6981c65308fee9 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Fri, 12 Mar 2021 00:15:50 +0100 Subject: [PATCH 0588/5766] Update events.rst --- reference/events.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/reference/events.rst b/reference/events.rst index 900d40eb12c..c55bfdcc824 100644 --- a/reference/events.rst +++ b/reference/events.rst @@ -1,10 +1,11 @@ Built-in Symfony Events ======================= -During the handling of an HTTP request, the Symfony framework (or any +The Symfony framework is an HTTP Request-Response one. +During the handling of an HTTP request, the framework (or any application using the :doc:`HttpKernel component `) dispatches some :doc:`events ` which you can use to modify -how the request is handled. +how the request is handled and how the response is returned. Kernel Events ------------- From ad6075bf1770d43a8dd71b38bdce5b57bdcf05bf Mon Sep 17 00:00:00 2001 From: mostefamed Date: Sat, 13 Mar 2021 20:23:19 +0100 Subject: [PATCH 0589/5766] Update definitions.rst Rename the returned variable from setArgument method and the assigned variable to addArgument method --- service_container/definitions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/service_container/definitions.rst b/service_container/definitions.rst index f90a185e1c5..1107413cf99 100644 --- a/service_container/definitions.rst +++ b/service_container/definitions.rst @@ -92,10 +92,10 @@ fetched from the container:: // adds a new argument with the name of the argument // $argumentName = the name of the argument in the constructor - $argument = $definition->setArgument('$argumentName', $argumentValue); + $definition = $definition->setArgument('$argumentName', $argumentValue); // adds a new argument - $definition->addArgument($argument); + $definition->addArgument($argumentValue); // replaces argument on a specific index (0 = first argument) $definition->replaceArgument($index, $argument); From 068b20e5bb83ebd9f5c15cca2004ebe60db8c4bb Mon Sep 17 00:00:00 2001 From: Wojciech Kania Date: Sun, 14 Mar 2021 11:06:51 +0100 Subject: [PATCH 0590/5766] [Serializer] Add PHP Attributes to serializer examples --- components/serializer.rst | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/components/serializer.rst b/components/serializer.rst index c484a9ed170..5f32da7c468 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -315,6 +315,26 @@ Then, create your groups definition: // ... } + .. code-block:: php-attributes + + namespace Acme; + + use Symfony\Component\Serializer\Annotation\Groups; + + class MyObj + { + #[Groups(['group1', 'group2'])] + public $foo; + + #[Groups(['group3'])] + public function getBar() // is* methods are also supported + { + return $this->bar; + } + + // ... + } + .. code-block:: yaml Acme\MyObj: @@ -437,6 +457,20 @@ Option 1: Using ``@Ignore`` Annotation public $bar; } + .. code-block:: php-attributes + + namespace App\Model; + + use Symfony\Component\Serializer\Annotation\Ignore; + + class MyClass + { + public $foo; + + #[Ignore] + public $bar; + } + .. code-block:: yaml App\Model\MyClass: @@ -658,6 +692,25 @@ defines a ``Person`` entity with a ``firstName`` property: // ... } + .. code-block:: php-attributes + + namespace App\Entity; + + use Symfony\Component\Serializer\Annotation\SerializedName; + + class Person + { + #[SerializedName('customer_name')] + private $firstName; + + public function __construct($firstName) + { + $this->firstName = $firstName; + } + + // ... + } + .. code-block:: yaml App\Entity\Person: @@ -1214,6 +1267,20 @@ Here, we set it to 2 for the ``$child`` property: // ... } + .. code-block:: php-attributes + + namespace Acme; + + use Symfony\Component\Serializer\Annotation\MaxDepth; + + class MyObj + { + #[MaxDepth(2)] + public $child; + + // ... + } + .. code-block:: yaml Acme\MyObj: @@ -1524,6 +1591,23 @@ and ``BitBucketCodeRepository`` classes: // ... } + .. 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, + ])] + interface CodeRepository + { + // ... + } + .. code-block:: yaml App\CodeRepository: From 8c0f61ce423e02bd0f0cec10fdbf5fc8474f049b Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 14 Mar 2021 13:01:51 +0100 Subject: [PATCH 0591/5766] [Validator] Fixed a minor RST syntax issue --- reference/constraints/Compound.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/reference/constraints/Compound.rst b/reference/constraints/Compound.rst index 53ce70c6df2..95d9ba10789 100644 --- a/reference/constraints/Compound.rst +++ b/reference/constraints/Compound.rst @@ -21,7 +21,7 @@ Basic Usage ----------- Suppose that you have different places where a user password must be validated, -you can create your own named set or requirements to be reused consistently everywhere:: +you can create your own named set or requirements to be reused consistently everywhere: .. configuration-block:: From 2f3d95778ff70da9288ae87b4ce38309681435b2 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 14 Mar 2021 19:11:11 +0100 Subject: [PATCH 0592/5766] [Session] Add missing semicolon --- session/locale_sticky_session.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/session/locale_sticky_session.rst b/session/locale_sticky_session.rst index f8caef23370..265298f864b 100644 --- a/session/locale_sticky_session.rst +++ b/session/locale_sticky_session.rst @@ -109,7 +109,8 @@ via some "Change Locale" route & controller), or create a route with the :ref:`_ $container->register(LocaleSubscriber::class) ->addArgument('%kernel.default_locale%') // uncomment the next line if you are not using autoconfigure - // ->addTag('kernel.event_subscriber'); + // ->addTag('kernel.event_subscriber') + ; That's it! Now celebrate by changing the user's locale and seeing that it's sticky throughout the request. From 74d2938580c363c38df6979700103483ec0b1d69 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 14 Mar 2021 19:38:47 +0100 Subject: [PATCH 0593/5766] [Intl] Fix typos --- components/intl.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/intl.rst b/components/intl.rst index 6417489b14e..dafe45800d0 100644 --- a/components/intl.rst +++ b/components/intl.rst @@ -110,7 +110,7 @@ to catching the exception, you can also check if a given language code is valid: $isValidLanguage = Languages::exists($languageCode); -Or if you have a alpha3 language code you want to check:: +Or if you have an alpha3 language code you want to check:: $isValidLanguage = Languages::alpha3CodeExists($alpha3Code); @@ -209,7 +209,7 @@ to catching the exception, you can also check if a given country code is valid:: $isValidCountry = Countries::exists($alpha2Code); -Or if you have a alpha3 country code you want to check:: +Or if you have an alpha3 country code you want to check:: $isValidCountry = Countries::alpha3CodeExists($alpha3Code); From ac44f85bd9596c5eff147f1b6ce93d8e7cf31817 Mon Sep 17 00:00:00 2001 From: Peter Date: Sun, 7 Mar 2021 21:03:35 +0100 Subject: [PATCH 0594/5766] Update description for Access decision strategies Updated the description to reflect the current behavior of the builtin AccessDecisionManager. --- security/voters.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/security/voters.rst b/security/voters.rst index 98ba54519af..869df508d50 100644 --- a/security/voters.rst +++ b/security/voters.rst @@ -278,12 +278,16 @@ There are three strategies available: This grants access as soon as there is *one* voter granting access; ``consensus`` - This grants access if there are more voters granting access than denying; + This grants access if there are more voters granting access than + denying. If case of a tie the decision is based on the + ``allow_if_equal_granted_denied`` config option (defaulting to ``true``); ``unanimous`` - This only grants access if there is no voter denying access. If all voters - abstained from voting, the decision is based on the ``allow_if_all_abstain`` - config option (which defaults to ``false``). + This only grants access if there is no voter denying access. + +Regardless the chosen strategy, if all voters abstained from voting, the +decision is based on the ``allow_if_all_abstain`` config option (which +defaults to ``false``). In the above scenario, both voters should grant access in order to grant access to the user to read the post. In this case, the default strategy is no longer From d24d45c3bfdc68e9b6040e939fc9d21ee7588be6 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Fri, 12 Mar 2021 17:16:49 +0100 Subject: [PATCH 0595/5766] [Translation] Move the "templates" section into the main guide --- _build/redirection_map | 1 + translation.rst | 121 +++++++++++++++++++++++++++++++++++-- translation/templates.rst | 123 -------------------------------------- 3 files changed, 116 insertions(+), 129 deletions(-) delete mode 100644 translation/templates.rst diff --git a/_build/redirection_map b/_build/redirection_map index 4954ce471fa..fe432c55aa1 100644 --- a/_build/redirection_map +++ b/_build/redirection_map @@ -458,6 +458,7 @@ /templating/embedding_controllers /templates#embedding-controllers /templating/inheritance /templates#template-inheritance-and-layouts /testing/doctrine /testing/database +/translation/templates /translation#translation-in-templates /doctrine/lifecycle_callbacks /doctrine/events /doctrine/event_listeners_subscribers /doctrine/events /doctrine/common_extensions /doctrine diff --git a/translation.rst b/translation.rst index 0e1601cc536..bb822614451 100644 --- a/translation.rst +++ b/translation.rst @@ -304,14 +304,124 @@ Translations in Templates ------------------------- Most of the time, translation occurs in templates. Symfony provides native -support for both Twig and PHP templates: +support for both Twig and PHP templates. -.. code-block:: html+twig +Using Twig Tags +~~~~~~~~~~~~~~~ -

                    {% trans %}Symfony is great!{% endtrans %}

                    +Symfony provides specialized Twig tags (``trans`` and ``transchoice``) to +help with message translation of *static blocks of text*: + +.. code-block:: twig + + {% trans %}Hello %name%{% endtrans %} + + {% transchoice count %} + {0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples + {% endtranschoice %} + +The ``transchoice`` tag automatically gets the ``%count%`` variable from +the current context and passes it to the translator. This mechanism only +works when you use a placeholder following the ``%var%`` pattern. + +.. deprecated:: 4.2 + + The ``transchoice`` tag is deprecated since Symfony 4.2 and will be + removed in 5.0. Use the :doc:`ICU MessageFormat ` with + the ``trans`` tag instead. + +.. caution:: + + The ``%var%`` notation of placeholders is required when translating in + Twig templates using the tag. + +.. tip:: + + If you need to use the percent character (``%``) in a string, escape it by + doubling it: ``{% trans %}Percent: %percent%%%{% endtrans %}`` + +You can also specify the message domain and pass some additional variables: + +.. code-block:: twig + + {% trans with {'%name%': 'Fabien'} from 'app' %}Hello %name%{% endtrans %} + + {% trans with {'%name%': 'Fabien'} from 'app' into 'fr' %}Hello %name%{% endtrans %} + + {% transchoice count with {'%name%': 'Fabien'} from 'app' %} + {0} %name%, there are no apples|{1} %name%, there is one apple|]1,Inf[ %name%, there are %count% apples + {% endtranschoice %} + +.. _translation-filters: + +Using Twig Filters +~~~~~~~~~~~~~~~~~~ + +The ``trans`` and ``transchoice`` filters can be used to translate *variable +texts* and complex expressions: + +.. code-block:: twig + + {{ message|trans }} + + {{ message|transchoice(5) }} + + {{ message|trans({'%name%': 'Fabien'}, 'app') }} + + {{ message|transchoice(5, {'%name%': 'Fabien'}, 'app') }} + +.. deprecated:: 4.2 + + The ``transchoice`` filter is deprecated since Symfony 4.2 and will be + removed in 5.0. Use the :doc:`ICU MessageFormat ` with + the ``trans`` filter instead. + +.. tip:: + + Using the translation tags or filters have the same effect, but with + one subtle difference: automatic output escaping is only applied to + translations using a filter. In other words, if you need to be sure + that your translated message is *not* output escaped, you must apply + the ``raw`` filter after the translation filter: + + .. code-block:: html+twig + + {# text translated between tags is never escaped #} + {% trans %} +

                    foo

                    + {% endtrans %} + + {% set message = '

                    foo

                    ' %} + + {# strings and variables translated via a filter are escaped by default #} + {{ message|trans|raw }} + {{ '

                    bar

                    '|trans|raw }} + +.. tip:: + + You can set the translation domain for an entire Twig template with a single tag: + + .. code-block:: twig + + {% trans_default_domain 'app' %} + + Note that this only influences the current template, not any "included" + template (in order to avoid side effects). + +PHP Templates +~~~~~~~~~~~~~ + +The translator service is accessible in PHP templates through the +``translator`` helper:: + + trans('Symfony is great') ?> + + transChoice( + '{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples', + 10, + ['%count%' => 10] + ) ?> -Read :doc:`/translation/templates` for more information about the Twig tags and -filters for translation. Forcing the Translator Locale ----------------------------- @@ -600,7 +710,6 @@ Learn more :maxdepth: 1 translation/message_format - translation/templates translation/locale translation/debug translation/lint diff --git a/translation/templates.rst b/translation/templates.rst deleted file mode 100644 index 903f1934d92..00000000000 --- a/translation/templates.rst +++ /dev/null @@ -1,123 +0,0 @@ -Using Translation in Templates -============================== - -Twig Templates --------------- - -.. _translation-tags: - -Using Twig Tags -~~~~~~~~~~~~~~~ - -Symfony provides specialized Twig tags (``trans`` and ``transchoice``) to -help with message translation of *static blocks of text*: - -.. code-block:: twig - - {% trans %}Hello %name%{% endtrans %} - - {% transchoice count %} - {0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples - {% endtranschoice %} - -The ``transchoice`` tag automatically gets the ``%count%`` variable from -the current context and passes it to the translator. This mechanism only -works when you use a placeholder following the ``%var%`` pattern. - -.. deprecated:: 4.2 - - The ``transchoice`` tag is deprecated since Symfony 4.2 and will be - removed in 5.0. Use the :doc:`ICU MessageFormat ` with - the ``trans`` tag instead. - -.. caution:: - - The ``%var%`` notation of placeholders is required when translating in - Twig templates using the tag. - -.. tip:: - - If you need to use the percent character (``%``) in a string, escape it by - doubling it: ``{% trans %}Percent: %percent%%%{% endtrans %}`` - -You can also specify the message domain and pass some additional variables: - -.. code-block:: twig - - {% trans with {'%name%': 'Fabien'} from 'app' %}Hello %name%{% endtrans %} - - {% trans with {'%name%': 'Fabien'} from 'app' into 'fr' %}Hello %name%{% endtrans %} - - {% transchoice count with {'%name%': 'Fabien'} from 'app' %} - {0} %name%, there are no apples|{1} %name%, there is one apple|]1,Inf[ %name%, there are %count% apples - {% endtranschoice %} - -.. _translation-filters: - -Using Twig Filters -~~~~~~~~~~~~~~~~~~ - -The ``trans`` and ``transchoice`` filters can be used to translate *variable -texts* and complex expressions: - -.. code-block:: twig - - {{ message|trans }} - - {{ message|transchoice(5) }} - - {{ message|trans({'%name%': 'Fabien'}, 'app') }} - - {{ message|transchoice(5, {'%name%': 'Fabien'}, 'app') }} - -.. deprecated:: 4.2 - - The ``transchoice`` filter is deprecated since Symfony 4.2 and will be - removed in 5.0. Use the :doc:`ICU MessageFormat ` with - the ``trans`` filter instead. - -.. tip:: - - Using the translation tags or filters have the same effect, but with - one subtle difference: automatic output escaping is only applied to - translations using a filter. In other words, if you need to be sure - that your translated message is *not* output escaped, you must apply - the ``raw`` filter after the translation filter: - - .. code-block:: html+twig - - {# text translated between tags is never escaped #} - {% trans %} -

                    foo

                    - {% endtrans %} - - {% set message = '

                    foo

                    ' %} - - {# strings and variables translated via a filter are escaped by default #} - {{ message|trans|raw }} - {{ '

                    bar

                    '|trans|raw }} - -.. tip:: - - You can set the translation domain for an entire Twig template with a single tag: - - .. code-block:: twig - - {% trans_default_domain 'app' %} - - Note that this only influences the current template, not any "included" - template (in order to avoid side effects). - -PHP Templates -------------- - -The translator service is accessible in PHP templates through the -``translator`` helper:: - - trans('Symfony is great') ?> - - transChoice( - '{0} There are no apples|{1} There is one apple|]1,Inf[ There are %count% apples', - 10, - ['%count%' => 10] - ) ?> From 271f8f6d64d9bb25893e88ae150c2507a6d3d64a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 15 Mar 2021 20:13:00 +0100 Subject: [PATCH 0596/5766] Readded a missing reference --- translation.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/translation.rst b/translation.rst index bb822614451..ac14dd8c318 100644 --- a/translation.rst +++ b/translation.rst @@ -306,6 +306,8 @@ Translations in Templates Most of the time, translation occurs in templates. Symfony provides native support for both Twig and PHP templates. +.. _translation-tags: + Using Twig Tags ~~~~~~~~~~~~~~~ From 518926f33835067cc67a57c887e3490fe86d6961 Mon Sep 17 00:00:00 2001 From: Massimiliano Arione Date: Tue, 16 Mar 2021 08:53:19 +0100 Subject: [PATCH 0597/5766] add a warning about Amazon SES signature --- mailer.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mailer.rst b/mailer.rst index ff567eab3bc..0a44eace54c 100644 --- a/mailer.rst +++ b/mailer.rst @@ -160,6 +160,11 @@ party provider: For example, the DSN ``ses+smtp://ABC1234:abc+12/345@default`` should be configured as ``ses+smtp://ABC1234:abc%2B12%2F345@default`` +.. caution:: + + Symfony 4.4 only suppports Amazon SES Signature Version 3, that has been deprecated. + You need to use symfony/amazon-mailer 5.1 or newer. + .. tip:: If you want to override the default host for a provider (to debug an issue using From 5cabc722845f9f08d4636d378636f56e07a70c03 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 16 Mar 2021 09:25:52 +0100 Subject: [PATCH 0598/5766] Typo --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index 0a44eace54c..e236b27c1a5 100644 --- a/mailer.rst +++ b/mailer.rst @@ -162,7 +162,7 @@ party provider: .. caution:: - Symfony 4.4 only suppports Amazon SES Signature Version 3, that has been deprecated. + Symfony 4.4 only supports Amazon SES Signature Version 3, that has been deprecated. You need to use symfony/amazon-mailer 5.1 or newer. .. tip:: From dd280ea98bcb48529038852d7b3b653d8c72be3c Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 16 Mar 2021 09:27:04 +0100 Subject: [PATCH 0599/5766] minor --- mailer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index e236b27c1a5..dd0c14956c3 100644 --- a/mailer.rst +++ b/mailer.rst @@ -162,8 +162,8 @@ party provider: .. caution:: - Symfony 4.4 only supports Amazon SES Signature Version 3, that has been deprecated. - You need to use symfony/amazon-mailer 5.1 or newer. + Symfony 4.4 only supports Amazon SES signature version 3 which has been + deprecated. You need to use ``symfony/amazon-mailer`` 5.1 or newer. .. tip:: From c9cff9fa76541ca82a240048f3aae48e4c2d25fa Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 16 Mar 2021 09:27:56 +0100 Subject: [PATCH 0600/5766] Remove caution. refs #15106 --- mailer.rst | 5 ----- 1 file changed, 5 deletions(-) diff --git a/mailer.rst b/mailer.rst index bbb7ab9305c..8f98d9b766f 100644 --- a/mailer.rst +++ b/mailer.rst @@ -174,11 +174,6 @@ party provider: For example, the DSN ``ses+smtp://ABC1234:abc+12/345@default`` should be configured as ``ses+smtp://ABC1234:abc%2B12%2F345@default`` -.. caution:: - - Symfony 4.4 only supports Amazon SES signature version 3 which has been - deprecated. You need to use ``symfony/amazon-mailer`` 5.1 or newer. - .. note:: When using SMTP, the default timeout for sending a message before throwing an From e37983a7cc8316fc409a0c9b6a5fc85b95309d22 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Tue, 16 Mar 2021 16:34:14 +0100 Subject: [PATCH 0601/5766] Update logging.rst --- logging.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/logging.rst b/logging.rst index d4ed95189ba..ae9ddd10a73 100644 --- a/logging.rst +++ b/logging.rst @@ -23,7 +23,7 @@ To do so, :ref:`override the "logger" service definition `. Logging a Message ----------------- -To log a message, inject the default logger in your controller:: +To log a message, inject the default logger in your controller or service:: use Psr\Log\LoggerInterface; From 61dc76568fe769311e98b76df8682b190df34e41 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 17 Mar 2021 10:18:54 +0100 Subject: [PATCH 0602/5766] Use UserBadge in all passports --- security/experimental_authenticators.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/security/experimental_authenticators.rst b/security/experimental_authenticators.rst index eb0ffa098e0..269aefe01a0 100644 --- a/security/experimental_authenticators.rst +++ b/security/experimental_authenticators.rst @@ -494,7 +494,7 @@ The following credential classes are supported by default: use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials; // ... - return new Passport($user, new PasswordCredentials($plaintextPassword)); + return new Passport(new UserBadge($email), new PasswordCredentials($plaintextPassword)); :class:`Symfony\\Component\\Security\\Http\\Authenticator\\Passport\\Credentials\\CustomCredentials` Allows a custom closure to check credentials:: @@ -502,7 +502,7 @@ The following credential classes are supported by default: use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\CustomCredentials; // ... - return new Passport($user, new CustomCredentials( + return new Passport(new UserBadge($email), new CustomCredentials( // If this function returns anything else than `true`, the credentials // are marked as invalid. // The $credentials parameter is equal to the next argument of this class @@ -581,7 +581,7 @@ would initialize the passport like this:: // ... validate no parameter is empty return new Passport( - new UserBadge($user), + new UserBadge($email), new PasswordCredentials($password), [new CsrfTokenBadge('login', $csrfToken)] ); From 316da38f2444913392161afa202e95e5be3edca3 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 17 Mar 2021 11:33:49 +0100 Subject: [PATCH 0603/5766] Fix DSN --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index 8f98d9b766f..15c3d48ddcf 100644 --- a/mailer.rst +++ b/mailer.rst @@ -165,7 +165,7 @@ party provider: Mailjet mailjet+smtp://ACCESS_KEY:SECRET_KEY@default n/a mailjet+api://ACCESS_KEY:SECRET_KEY@default Postmark postmark+smtp://ID:ID@default n/a postmark+api://KEY@default Sendgrid sendgrid+smtp://apikey:KEY@default n/a sendgrid+api://KEY@default - Sendinblue sendinblue+smtp://apikey:USERNAME:PASSWORD@default n/a sendinblue+api://KEY@default + Sendinblue sendinblue+smtp://USERNAME:PASSWORD@default n/a sendinblue+api://KEY@default ==================== ==================================================== =========================================== ======================================== .. caution:: From 89a9964dea89a754283a00d966ede0636c6fcf34 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 17 Mar 2021 11:35:22 +0100 Subject: [PATCH 0604/5766] Fix DSNs --- mailer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index dd0c14956c3..dda2efc5898 100644 --- a/mailer.rst +++ b/mailer.rst @@ -150,8 +150,8 @@ party provider: Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default - Postmark postmark+smtp://ID:ID@default n/a postmark+api://KEY@default - Sendgrid sendgrid+smtp://apikey:KEY@default n/a sendgrid+api://KEY@default + Postmark postmark+smtp://ID@default n/a postmark+api://KEY@default + Sendgrid sendgrid+smtp://KEY@default n/a sendgrid+api://KEY@default ==================== ========================================== =========================================== ======================================== .. caution:: From f019d537fa82e5f93929f3c1b4c9f2a469219141 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 17 Mar 2021 11:37:17 +0100 Subject: [PATCH 0605/5766] Use correct domain --- mailer.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mailer.rst b/mailer.rst index dd0c14956c3..0f57ba46164 100644 --- a/mailer.rst +++ b/mailer.rst @@ -173,8 +173,8 @@ party provider: .. code-block:: env # .env - MAILER_DSN=mailgun+https://KEY:DOMAIN@example.com - MAILER_DSN=mailgun+https://KEY:DOMAIN@example.com:99 + MAILER_DSN=mailgun+https://KEY:DOMAIN@requestbin.com + MAILER_DSN=mailgun+https://KEY:DOMAIN@requestbin.com:99 Note that the protocol is *always* HTTPs and cannot be changed. From b66dd5f27581c0cf7df1e66966b28c502f29eb51 Mon Sep 17 00:00:00 2001 From: cedric lombardot Date: Wed, 17 Mar 2021 16:51:14 +0100 Subject: [PATCH 0606/5766] Fix to use yaml syntax --- deployment/proxies.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index 5f24a69a418..a51aa1c8889 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -31,11 +31,11 @@ and what headers your reverse proxy uses to send information: # config/packages/framework.yaml framework: # ... - // the IP address (or range) of your proxy + # the IP address (or range) of your proxy trusted_proxies: '192.0.0.1,10.0.0.0/8' - // trust *all* "X-Forwarded-*" headers + # trust *all* "X-Forwarded-*" headers trusted_headers: ['x-forwarded-for', 'x-forwarded-host', 'x-forwarded-proto', 'x-forwarded-port'] - // or, if your proxy instead uses the "Forwarded" header + # or, if your proxy instead uses the "Forwarded" header trusted_headers: ['forwarded'] .. code-block:: xml From 97614c0f05bc84e035c0a21ed0c019d27e2e5024 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 17 Mar 2021 17:30:31 +0100 Subject: [PATCH 0607/5766] Remove Jakub from the core team --- contributing/code/core_team.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contributing/code/core_team.rst b/contributing/code/core_team.rst index 4c719ff4330..136edb28dbb 100644 --- a/contributing/code/core_team.rst +++ b/contributing/code/core_team.rst @@ -60,7 +60,6 @@ Active Core Members * **Christian Flothmann** (`xabbuh`_); * **Tobias Schultze** (`Tobion`_); * **Kévin Dunglas** (`dunglas`_); - * **Jakub Zalas** (`jakzal`_); * **Javier Eguiluz** (`javiereguiluz`_); * **Grégoire Pineau** (`lyrixx`_); * **Ryan Weaver** (`weaverryan`_); @@ -106,7 +105,8 @@ Symfony contributions: * **Romain Neutron** (`romainneutron`_); * **Jordi Boggiano** (`Seldaek`_); * **Lukas Kahwe Smith** (`lsmith77`_); -* **Jules Pietri** (`HeahDude`_). +* **Jules Pietri** (`HeahDude`_); +* **Jakub Zalas** (`jakzal`_). Core Membership Application ~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 3a10fff91326c84f1c3956d19a60d89f513501ab Mon Sep 17 00:00:00 2001 From: Nicolas Hart Date: Wed, 17 Mar 2021 22:23:20 +0100 Subject: [PATCH 0608/5766] [Testing] Fix typo in assertEmailAttachmentCount --- testing/functional_tests_assertions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/functional_tests_assertions.rst b/testing/functional_tests_assertions.rst index edf1a6bb679..29e4b1e5e3a 100644 --- a/testing/functional_tests_assertions.rst +++ b/testing/functional_tests_assertions.rst @@ -84,7 +84,7 @@ Mailer - ``assertQueuedEmailCount()`` - ``assertEmailIsQueued()`` - ``assertEmailIsNotQueued()`` -- ``assertEmailAttachementCount()`` +- ``assertEmailAttachmentCount()`` - ``assertEmailTextBodyContains()`` - ``assertEmailTextBodyNotContains()`` - ``assertEmailHtmlBodyContains()`` From 07dea78ee4fe513abd4d6abf0622d1a8315a7aab Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Fri, 19 Mar 2021 09:04:52 +0100 Subject: [PATCH 0609/5766] Update workflow.rst --- workflow.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/workflow.rst b/workflow.rst index 7f7acffaa3a..fa489c63cf7 100644 --- a/workflow.rst +++ b/workflow.rst @@ -238,7 +238,8 @@ Accessing the Workflow in a Class You can use the workflow inside a class by using :doc:`service autowiring ` and using -``camelCased workflow name + Workflow`` as parameter name:: +``camelCased workflow name + Workflow`` as parameter name. If it is a state machine type +you can use ``camelCased workflow name + StateMachine``:: use App\Entity\BlogPost; use Symfony\Component\Workflow\WorkflowInterface; From 455edf4f2a7a764ae16ab06b5878600f38149dfd Mon Sep 17 00:00:00 2001 From: Hossein Vakili Date: Thu, 18 Mar 2021 13:01:45 +0100 Subject: [PATCH 0610/5766] Add Oracle DATABASE_URL instruction --- doctrine.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doctrine.rst b/doctrine.rst index e1ee1785c00..9d98f26b7ca 100644 --- a/doctrine.rst +++ b/doctrine.rst @@ -54,6 +54,9 @@ The database connection information is stored as an environment variable called # to use postgresql: # DATABASE_URL="postgresql://db_user:db_password@127.0.0.1:5432/db_name?serverVersion=11&charset=utf8" + + # to use oracle: + # DATABASE_URL="oci8://db_user:db_password@127.0.0.1:1521/db_name" .. caution:: From b3f014dff10f9331102fa1cb6fe56c000fff32b9 Mon Sep 17 00:00:00 2001 From: rodmar35 Date: Thu, 18 Mar 2021 09:56:35 +0100 Subject: [PATCH 0611/5766] Update reverse_engineering.rst --- doctrine/reverse_engineering.rst | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doctrine/reverse_engineering.rst b/doctrine/reverse_engineering.rst index 087e41db955..320e424ea0a 100644 --- a/doctrine/reverse_engineering.rst +++ b/doctrine/reverse_engineering.rst @@ -99,9 +99,12 @@ run: .. code-block:: terminal - // generates getter/setter methods + // generates getter/setter methods for all Entities $ php bin/console make:entity --regenerate App + // generates getter/setter methods for one specific Entity + $ php bin/console make:entity --regenerate App\\Entity\\Country + .. note:: If you want to have a OneToMany relationship, you will need to add From 019a8c82fa800777a7ea85dafe26cfccfdd9d9a7 Mon Sep 17 00:00:00 2001 From: cedric lombardot Date: Sat, 20 Mar 2021 11:42:29 +0100 Subject: [PATCH 0612/5766] Fix yaml syntax --- deployment/proxies.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deployment/proxies.rst b/deployment/proxies.rst index a51aa1c8889..49aa04c8361 100644 --- a/deployment/proxies.rst +++ b/deployment/proxies.rst @@ -125,8 +125,8 @@ In this case, you'll need to - *very carefully* - trust *all* proxies. # config/packages/framework.yaml framework: # ... - // trust *all* requests (the 'REMOTE_ADDR' string is replaced at - // run time by $_SERVER['REMOTE_ADDR']) + # trust *all* requests (the 'REMOTE_ADDR' string is replaced at + # run time by $_SERVER['REMOTE_ADDR']) trusted_proxies: '127.0.0.1,REMOTE_ADDR' That's it! It's critical that you prevent traffic from all non-trusted sources. From 6e3a415ad1d256e630aa34c5a2507f9f46f793b2 Mon Sep 17 00:00:00 2001 From: Antoine Makdessi Date: Sat, 20 Mar 2021 19:07:46 +0100 Subject: [PATCH 0613/5766] Update bc.rst --- contributing/code/bc.rst | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/contributing/code/bc.rst b/contributing/code/bc.rst index 15f1f03674d..371c1a35b95 100644 --- a/contributing/code/bc.rst +++ b/contributing/code/bc.rst @@ -4,10 +4,13 @@ Our Backward Compatibility Promise Ensuring smooth upgrades of your projects is our first priority. That's why we promise you backward compatibility (BC) for all minor Symfony releases. You probably recognize this strategy as `Semantic Versioning`_. In short, -Semantic Versioning means that only major releases (such as 2.0, 3.0 etc.) are -allowed to break backward compatibility. Minor releases (such as 2.5, 2.6 etc.) +Semantic Versioning means that only major releases (such as 5.0, 6.0 etc.) are +allowed to break backward compatibility. Minor releases (such as 5.1, 5.2 etc.) may introduce new features, but must do so without breaking the existing API of -that release branch (2.x in the previous example). +that release branch (5.x in the previous example). + +We also provide deprecation message triggered in the code base to help you with +the migration process across major release. .. caution:: From 0e04632a01caee166f8dff10d5de2101e851627b Mon Sep 17 00:00:00 2001 From: Yonel Ceruto Date: Sat, 20 Mar 2021 16:51:09 -0400 Subject: [PATCH 0614/5766] Remove extra slash in template path --- configuration/override_dir_structure.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/override_dir_structure.rst b/configuration/override_dir_structure.rst index e0bd417886d..ece722f6f27 100644 --- a/configuration/override_dir_structure.rst +++ b/configuration/override_dir_structure.rst @@ -109,7 +109,7 @@ for multiple directories): # config/packages/twig.yaml twig: # ... - default_path: "%kernel.project_dir%//resources/views" + default_path: "%kernel.project_dir%/resources/views" .. code-block:: xml From 7bbfe94d3a8a6e1d7743491fd7dd3fa97b04b979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Sch=C3=A4dlich?= <1880467+jschaedl@users.noreply.github.com> Date: Sun, 21 Mar 2021 14:09:17 +0100 Subject: [PATCH 0615/5766] Remove SentMessage paragraph The Notifier's `send` method does not return a `SentMessage` object: https://github.com/symfony/symfony/blob/5.2/src/Symfony/Component/Notifier/NotifierInterface.php#L26 Only the Chatter and Texter classes `send` methods returns a `SendMessage`. --- notifier.rst | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/notifier.rst b/notifier.rst index d328084c0b8..0c8309aec71 100644 --- a/notifier.rst +++ b/notifier.rst @@ -380,7 +380,7 @@ To send a notification, autowire the ); // Send the notification to the recipient - $sentMessage = $notifier->send($notification, $recipient); + $notifier->send($notification, $recipient); // ... } @@ -391,14 +391,6 @@ channels. The channels specify which channel (or transport) should be used to send the notification. For instance, ``['email', 'sms']`` will send both an email and sms notification to the user. -The ``send()`` method used to send the notification returns a variable of type -:class:`Symfony\\Component\\Notifier\\Message\\SentMessage` which provides -information such as the message ID and the original message contents. - -.. versionadded:: 5.2 - - The ``SentMessage`` class was introduced in Symfony 5.2. - The default notification also has a ``content()`` and ``emoji()`` method to set the notification content and icon. From 7803935f38f770401db5a477d8accdac20f83809 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 21 Mar 2021 22:57:06 +0100 Subject: [PATCH 0616/5766] [Intl] Remove duplicated parentheses --- components/intl.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/intl.rst b/components/intl.rst index dafe45800d0..dae70440cf5 100644 --- a/components/intl.rst +++ b/components/intl.rst @@ -381,8 +381,8 @@ arguments to get the offset at any given point in time:: The string representation of the GMT offset can vary depending on the locale, so you can pass the locale as the third optional argument:: - $offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'ar')); // $offset = 'غرينتش+01:00' - $offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'dz')); // $offset = 'ཇི་ཨེམ་ཏི་+01:00' + $offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'ar'); // $offset = 'غرينتش+01:00' + $offset = Timezones::getGmtOffset('Europe/Madrid', strtotime('October 28, 2019'), 'dz'); // $offset = 'ཇི་ཨེམ་ཏི་+01:00' If the given timezone ID doesn't exist, the methods trigger a :class:`Symfony\\Component\\Intl\\Exception\\MissingResourceException`. In addition From e28f5a1172ed0f520b9d218b81a956b6f6a2a790 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 21 Mar 2021 23:01:14 +0100 Subject: [PATCH 0617/5766] [Filesystem] Fix typo --- components/filesystem.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/filesystem.rst b/components/filesystem.rst index c0cad3dc9b9..4b09bc4cd7e 100644 --- a/components/filesystem.rst +++ b/components/filesystem.rst @@ -162,7 +162,7 @@ permissions of a file. The fourth argument is a boolean recursive option:: // sets the mode of the video to 0600 $filesystem->chmod('video.ogg', 0600); - // changes the mod of the src directory recursively + // changes the mode of the src directory recursively $filesystem->chmod('src', 0700, 0000, true); .. note:: From bc8997112a103b12493c4869c5f6592c85ca8367 Mon Sep 17 00:00:00 2001 From: Farhad Safarov Date: Tue, 23 Mar 2021 10:07:30 +0300 Subject: [PATCH 0618/5766] [Mailer] fix ses+smtp credentials format --- mailer.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index e7ca76dbb7f..42ec190574a 100644 --- a/mailer.rst +++ b/mailer.rst @@ -146,7 +146,7 @@ party provider: ==================== ========================================== =========================================== ======================================== Provider SMTP HTTP API ==================== ========================================== =========================================== ======================================== - Amazon SES ses+smtp://ACCESS_KEY:SECRET_KEY@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default + Amazon SES ses+smtp://USERNAME:PASSWORD@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default From e1ca15247611f9dfa2b88c4f00ab2a2cb41c8b80 Mon Sep 17 00:00:00 2001 From: Al-Saleh KEITA <28827545+askeita@users.noreply.github.com> Date: Mon, 22 Mar 2021 13:57:04 +0100 Subject: [PATCH 0619/5766] Typo with backticks. Removed extra backticks. --- http_cache/validation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/http_cache/validation.rst b/http_cache/validation.rst index 3a1dabf902e..599d0883b52 100644 --- a/http_cache/validation.rst +++ b/http_cache/validation.rst @@ -106,7 +106,7 @@ doing so much work. .. tip:: - Symfony also supports weak ``ETag``s by passing ``true`` as the second + Symfony also supports weak ``ETag`` s by passing ``true`` as the second argument to the :method:`Symfony\\Component\\HttpFoundation\\Response::setEtag` method. From 40bdc02b644f722430b6178ab1c0315cf4edf9fb Mon Sep 17 00:00:00 2001 From: Ilya Antipenko Date: Tue, 23 Mar 2021 18:19:11 +0100 Subject: [PATCH 0620/5766] Fix markdown in multiple_entity_managers.rst --- doctrine/multiple_entity_managers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/multiple_entity_managers.rst b/doctrine/multiple_entity_managers.rst index ba3475dbfbc..57b2879f868 100644 --- a/doctrine/multiple_entity_managers.rst +++ b/doctrine/multiple_entity_managers.rst @@ -313,6 +313,6 @@ The same applies to repository calls:: // ... } - You should now always fetch this repository using ``ManagerRegistry::getRepository()``. +You should now always fetch this repository using ``ManagerRegistry::getRepository()``. .. _`several alternatives`: https://stackoverflow.com/a/11494543 From 85c9813c7adb18bba646492b792e54bb9fc94427 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 24 Mar 2021 11:34:54 +0100 Subject: [PATCH 0621/5766] Minor tweak --- doctrine/multiple_entity_managers.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doctrine/multiple_entity_managers.rst b/doctrine/multiple_entity_managers.rst index 57b2879f868..32e5a979cdb 100644 --- a/doctrine/multiple_entity_managers.rst +++ b/doctrine/multiple_entity_managers.rst @@ -313,6 +313,6 @@ The same applies to repository calls:: // ... } -You should now always fetch this repository using ``ManagerRegistry::getRepository()``. + You should now always fetch this repository using ``ManagerRegistry::getRepository()``. .. _`several alternatives`: https://stackoverflow.com/a/11494543 From 3938dbdc9b63f80d9900396f903e1f8d8b446fc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20W=C3=B3js?= Date: Mon, 22 Mar 2021 10:22:09 +0100 Subject: [PATCH 0622/5766] Fixed invalid alias definition in "Deprecating Service Aliases" YAML example Fixed invalid alias definition in "Deprecating Service Aliases" YAML example. Current version is ```yaml app.mailer: alias: '@App\Mail\PhpMailer' # .... ``` Correct version is ```yaml app.mailer: alias: 'App\Mail\PhpMailer' # .... ``` (without `@` prefix in service id) --- service_container/alias_private.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service_container/alias_private.rst b/service_container/alias_private.rst index bac0b8fdc5f..f202ce8d277 100644 --- a/service_container/alias_private.rst +++ b/service_container/alias_private.rst @@ -166,7 +166,7 @@ or you decided not to maintain it anymore), you can deprecate its definition: .. code-block:: yaml app.mailer: - alias: '@App\Mail\PhpMailer' + alias: 'App\Mail\PhpMailer' # this will display a generic deprecation message... deprecated: true From 53fab68e61f0eccc1a0d51b74d4ee97ddbbf6cfb Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 24 Mar 2021 12:27:28 +0100 Subject: [PATCH 0623/5766] Tweak --- workflow.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/workflow.rst b/workflow.rst index fa489c63cf7..74d986ed868 100644 --- a/workflow.rst +++ b/workflow.rst @@ -238,8 +238,8 @@ Accessing the Workflow in a Class You can use the workflow inside a class by using :doc:`service autowiring ` and using -``camelCased workflow name + Workflow`` as parameter name. If it is a state machine type -you can use ``camelCased workflow name + StateMachine``:: +``camelCased workflow name + Workflow`` as parameter name. If it is a state +machine type, use ``camelCased workflow name + StateMachine``:: use App\Entity\BlogPost; use Symfony\Component\Workflow\WorkflowInterface; From 485637c22d154f26a2ad3d3f5605e5e244c9ec64 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 24 Mar 2021 12:31:06 +0100 Subject: [PATCH 0624/5766] Minor tweak --- mailer.rst | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/mailer.rst b/mailer.rst index cda5c1fb646..b632449c4b5 100644 --- a/mailer.rst +++ b/mailer.rst @@ -155,11 +155,10 @@ transport, but you can force to use one: This table shows the full list of available DSN formats for each third party provider: -<<<<<<< HEAD ==================== ==================================================== =========================================== ======================================== Provider SMTP HTTP API ==================== ==================================================== =========================================== ======================================== - Amazon SES ses+smtp://ACCESS_KEY:SECRET_KEY@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default + Amazon SES ses+smtp://USERNAME:PASSWORD@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default @@ -168,18 +167,7 @@ party provider: Sendgrid sendgrid+smtp://KEY@default n/a sendgrid+api://KEY@default Sendinblue sendinblue+smtp://USERNAME:PASSWORD@default n/a sendinblue+api://KEY@default ==================== ==================================================== =========================================== ======================================== -======= -==================== ========================================== =========================================== ======================================== - Provider SMTP HTTP API -==================== ========================================== =========================================== ======================================== - Amazon SES ses+smtp://USERNAME:PASSWORD@default ses+https://ACCESS_KEY:SECRET_KEY@default ses+api://ACCESS_KEY:SECRET_KEY@default - Google Gmail gmail+smtp://USERNAME:PASSWORD@default n/a n/a - Mailchimp Mandrill mandrill+smtp://USERNAME:PASSWORD@default mandrill+https://KEY@default mandrill+api://KEY@default - Mailgun mailgun+smtp://USERNAME:PASSWORD@default mailgun+https://KEY:DOMAIN@default mailgun+api://KEY:DOMAIN@default - Postmark postmark+smtp://ID@default n/a postmark+api://KEY@default - Sendgrid sendgrid+smtp://KEY@default n/a sendgrid+api://KEY@default -==================== ========================================== =========================================== ======================================== ->>>>>>> 4.4 + .. caution:: From 8aaf4776218a914da649cff13f4ffc712e445236 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 24 Mar 2021 12:31:15 +0100 Subject: [PATCH 0625/5766] Revert minor tweak --- mailer.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/mailer.rst b/mailer.rst index b632449c4b5..721e2144654 100644 --- a/mailer.rst +++ b/mailer.rst @@ -168,7 +168,6 @@ party provider: Sendinblue sendinblue+smtp://USERNAME:PASSWORD@default n/a sendinblue+api://KEY@default ==================== ==================================================== =========================================== ======================================== - .. caution:: If your credentials contain special characters, you must URL-encode them. From f749e254733b9ccfbe342646fad1d38b5e196ada Mon Sep 17 00:00:00 2001 From: KalleV Date: Thu, 25 Mar 2021 11:59:45 -0400 Subject: [PATCH 0626/5766] docs(http-client): fix default retry_failed configuration example The framework bundle configuration validation requires the top-level http client retry_failed configuration to be nested under default_options or scoped_clients. See: https://github.com/symfony/framework-bundle/blob/1f977bb1b790f915b22462e511b039fb761280b3/DependencyInjection/Configuration.php#L1414 --- reference/configuration/framework.rst | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 6458d77328a..5ea8a8cee0a 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -831,17 +831,18 @@ will automatically retry failed HTTP requests. # ... http_client: # ... - 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 + 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: From 1cc3689e8a8e896e4959807302b8f6f28911c61a Mon Sep 17 00:00:00 2001 From: Ivan Gantsev Date: Fri, 26 Mar 2021 10:57:52 +0300 Subject: [PATCH 0627/5766] Update rate_limiter.rst Inject HttpFoundation $request in action of controller --- rate_limiter.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rate_limiter.rst b/rate_limiter.rst index 6982f88cae4..22e78fa6c39 100644 --- a/rate_limiter.rst +++ b/rate_limiter.rst @@ -167,6 +167,7 @@ the number of requests to the API:: namespace App\Controller; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; + use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException; use Symfony\Component\RateLimiter\RateLimiterFactory; @@ -174,7 +175,7 @@ the number of requests to the API:: { // if you're using service autowiring, the variable name must be: // "rate limiter name" (in camelCase) + "Limiter" suffix - public function index(RateLimiterFactory $anonymousApiLimiter) + public function index(Request $request, RateLimiterFactory $anonymousApiLimiter) { // 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.) @@ -272,12 +273,13 @@ the :class:`Symfony\\Component\\RateLimiter\\Reservation` object returned by the 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 ApiController extends AbstractController { - public function index(RateLimiterFactory $anonymousApiLimiter) + public function index(Request $request, RateLimiterFactory $anonymousApiLimiter) { $limiter = $anonymousApiLimiter->create($request->getClientIp()); $limit = $limiter->consume(); From c4dd584759b514f9158c115e8da988285d910406 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 26 Mar 2021 09:10:21 +0100 Subject: [PATCH 0628/5766] [#15074] fix typo --- security/voters.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/voters.rst b/security/voters.rst index 869df508d50..c8daae7ba38 100644 --- a/security/voters.rst +++ b/security/voters.rst @@ -279,7 +279,7 @@ There are three strategies available: ``consensus`` This grants access if there are more voters granting access than - denying. If case of a tie the decision is based on the + denying. In case of a tie the decision is based on the ``allow_if_equal_granted_denied`` config option (defaulting to ``true``); ``unanimous`` From cf8f937743d5f9afaaae7911796d90e68adb3e66 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Sun, 5 Apr 2020 04:19:52 +0200 Subject: [PATCH 0629/5766] [Validator] Added grouped constraints in `Collection` reference --- reference/constraints/Collection.rst | 34 ++++++++++++++++++++++++++++ validation/raw_values.rst | 7 ++++++ 2 files changed, 41 insertions(+) diff --git a/reference/constraints/Collection.rst b/reference/constraints/Collection.rst index 2f3dfd52035..c60679aa90b 100644 --- a/reference/constraints/Collection.rst +++ b/reference/constraints/Collection.rst @@ -289,6 +289,40 @@ However, if the ``personal_email`` field does not exist in the array, the ``NotBlank`` constraint will still be applied (since it is wrapped in ``Required``) and you will receive a constraint violation. +When you define groups in nested constraints they are automatically added to +the ``Collection`` constraint itself so it can be traversed for all nested +groups. Take the following example:: + + use Symfony\Component\Validator\Constraints as Assert; + + $constraint = new Assert\Collection([ + 'fields' => [ + 'name' => new Assert\NotBlank(['groups' => 'basic']), + 'email' => new Assert\NotBlank(['groups' => 'contact']), + ], + ]); + +This will result in the following configuration:: + + $constraint = new Assert\Collection([ + 'fields' => [ + 'name' => new Assert\Required([ + 'constraints' => new Assert\NotBlank(['groups' => 'basic']), + 'groups' => ['basic', 'strict'], + ]), + 'email' => new Assert\Required([ + "constraints" => new Assert\NotBlank(['groups' => 'contact']), + 'groups' => ['basic', 'strict'], + ]), + ], + 'groups' => ['basic', 'strict'], + ]); + +The default ``allowMissingFields`` option requires the fields in all groups. +So when validating in ``contact`` group, ``$name`` can be empty but the key is +still required. If this is not the intended behavior, use the ``Optional`` +constraint explicitly instead of ``Required``. + Options ------- diff --git a/validation/raw_values.rst b/validation/raw_values.rst index 8cee65108b8..2014d37644b 100644 --- a/validation/raw_values.rst +++ b/validation/raw_values.rst @@ -105,3 +105,10 @@ The ``validate()`` method returns a :class:`Symfony\\Component\\Validator\\Const object, which acts like an array of errors. Each error in the collection is a :class:`Symfony\\Component\\Validator\\ConstraintViolation` object, which holds the error message on its ``getMessage()`` method. + +.. note:: + + When using groups with the + :doc:`Collection` constraint, be sure to + use the ``Optional`` constraint when appropriate as explained in its + reference documentation. From 64eb995d1df235b7d048bea89e4d522f0f9a7e57 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 26 Mar 2021 13:23:18 +0100 Subject: [PATCH 0630/5766] [#13492] satisfy the linter --- validation/raw_values.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/validation/raw_values.rst b/validation/raw_values.rst index 2014d37644b..9699e5353cc 100644 --- a/validation/raw_values.rst +++ b/validation/raw_values.rst @@ -109,6 +109,6 @@ which holds the error message on its ``getMessage()`` method. .. note:: When using groups with the - :doc:`Collection` constraint, be sure to + :doc:`Collection ` constraint, be sure to use the ``Optional`` constraint when appropriate as explained in its reference documentation. From 20436fc6026621885009e6b951e14b9b43027e9d Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 26 Mar 2021 14:07:27 +0100 Subject: [PATCH 0631/5766] rename master request to main request --- components/http_kernel.rst | 12 ++++++------ create_framework/http_kernel_httpkernelinterface.rst | 4 ++-- event_dispatcher.rst | 8 ++++---- http_cache.rst | 2 +- http_cache/esi.rst | 2 +- reference/configuration/framework.rst | 8 ++++---- reference/events.rst | 6 +++--- security/form_login_setup.rst | 2 +- session.rst | 2 +- 9 files changed, 23 insertions(+), 23 deletions(-) diff --git a/components/http_kernel.rst b/components/http_kernel.rst index c0da0fd6cfa..4dcf0ff6aa3 100644 --- a/components/http_kernel.rst +++ b/components/http_kernel.rst @@ -65,7 +65,7 @@ that system:: */ public function handle( Request $request, - int $type = self::MASTER_REQUEST, + int $type = self::MAIN_REQUEST, bool $catch = true ); } @@ -701,12 +701,12 @@ argument as follows:: This creates another full request-response cycle where this new ``Request`` is transformed into a ``Response``. The only difference internally is that some -listeners (e.g. security) may only act upon the master request. Each listener +listeners (e.g. security) may only act upon the main request. Each listener is passed some sub-class of :class:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent`, -whose :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::isMasterRequest` -can be used to check if the current request is a "master" or "sub" request. +whose :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::isMainRequest` +can be used to check if the current request is a "main" or "sub" request. -For example, a listener that only needs to act on the master request may +For example, a listener that only needs to act on the main request may look like this:: use Symfony\Component\HttpKernel\Event\RequestEvent; @@ -714,7 +714,7 @@ look like this:: public function onKernelRequest(RequestEvent $event) { - if (!$event->isMasterRequest()) { + if (!$event->isMainRequest()) { return; } diff --git a/create_framework/http_kernel_httpkernelinterface.rst b/create_framework/http_kernel_httpkernelinterface.rst index a5c46c8daaa..29ddcc9c124 100644 --- a/create_framework/http_kernel_httpkernelinterface.rst +++ b/create_framework/http_kernel_httpkernelinterface.rst @@ -16,7 +16,7 @@ goal by making our framework implement ``HttpKernelInterface``:: */ public function handle( Request $request, - $type = self::MASTER_REQUEST, + $type = self::MAIN_REQUEST, $catch = true ); } @@ -39,7 +39,7 @@ Update your framework so that it implements this interface:: public function handle( Request $request, - $type = HttpKernelInterface::MASTER_REQUEST, + $type = HttpKernelInterface::MAIN_REQUEST, $catch = true ) { // ... diff --git a/event_dispatcher.rst b/event_dispatcher.rst index 038a405b10b..450f23cf698 100644 --- a/event_dispatcher.rst +++ b/event_dispatcher.rst @@ -206,10 +206,10 @@ the ``EventSubscriber`` directory. Symfony takes care of the rest. Request Events, Checking Types ------------------------------ -A single page can make several requests (one master request, and then multiple +A single page can make several requests (one main request, and then multiple sub-requests - typically when :ref:`embedding controllers in templates `). For the core Symfony events, you might need to check to see if the event is for -a "master" request or a "sub request":: +a "main" request or a "sub request":: // src/EventListener/RequestListener.php namespace App\EventListener; @@ -220,8 +220,8 @@ a "master" request or a "sub request":: { public function onKernelRequest(RequestEvent $event) { - if (!$event->isMasterRequest()) { - // don't do anything if it's not the master request + if (!$event->isMainRequest()) { + // don't do anything if it's not the main request return; } diff --git a/http_cache.rst b/http_cache.rst index 9a9c7e414d3..35620d1cd76 100644 --- a/http_cache.rst +++ b/http_cache.rst @@ -155,7 +155,7 @@ header to the response. You can also use the ``trace_level`` config option and set it to either ``none``, ``short`` or ``full`` to add this information. -``short`` will add the information for the master request only. +``short`` will add the information for the main request only. It's written in a concise way that makes it easy to record the information in your server log files. For example, in Apache you can use ``%{X-Symfony-Cache}o`` in ``LogFormat`` format statements. diff --git a/http_cache/esi.rst b/http_cache/esi.rst index b23b19eda36..6108df41f49 100644 --- a/http_cache/esi.rst +++ b/http_cache/esi.rst @@ -161,7 +161,7 @@ used ``render()``. contains the ``ESI/1.0`` string anywhere. The embedded action can now specify its own caching rules entirely independently -of the master page:: +of the main page:: // src/Controller/NewsController.php namespace App\Controller; diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 9e03d3d05bd..15180619b77 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -197,7 +197,7 @@ Configuration * :ref:`dsn ` * :ref:`enabled ` * `only_exceptions`_ - * `only_master_requests`_ + * `only_main_requests`_ * `property_access`_ @@ -1244,12 +1244,12 @@ only_exceptions When this is set to ``true``, the profiler will only be enabled when an exception is thrown during the handling of the request. -only_master_requests -.................... +only_main_requests +.................. **type**: ``boolean`` **default**: ``false`` -When this is set to ``true``, the profiler will only be enabled on the master +When this is set to ``true``, the profiler will only be enabled on the main requests (and not on the subrequests). .. _profiler-dsn: diff --git a/reference/events.rst b/reference/events.rst index c55bfdcc824..75694ab1097 100644 --- a/reference/events.rst +++ b/reference/events.rst @@ -15,7 +15,7 @@ Each event dispatched by the HttpKernel component is a subclass of following information: :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::getRequestType` - Returns the *type* of the request (``HttpKernelInterface::MASTER_REQUEST`` + Returns the *type* of the request (``HttpKernelInterface::MAIN_REQUEST`` or ``HttpKernelInterface::SUB_REQUEST``). :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::getKernel` @@ -24,8 +24,8 @@ following information: :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::getRequest` Returns the current ``Request`` being handled. -:method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::isMasterRequest` - Checks if this is a master request. +:method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::isMainRequest` + Checks if this is a main request. .. _kernel-core-request: diff --git a/security/form_login_setup.rst b/security/form_login_setup.rst index 3aa01ef0972..3bc9cb94d10 100644 --- a/security/form_login_setup.rst +++ b/security/form_login_setup.rst @@ -489,7 +489,7 @@ whenever the user browses a page:: { $request = $event->getRequest(); if ( - !$event->isMasterRequest() + !$event->isMainRequest() || $request->isXmlHttpRequest() || 'app_login' === $request->attributes->get('_route') ) { diff --git a/session.rst b/session.rst index 5a3fb69c09b..0caba75894f 100644 --- a/session.rst +++ b/session.rst @@ -225,7 +225,7 @@ your ``Session`` object with the default ``AttributeBag`` by the ``NamespacedAtt public function createSession(): SessionInterface { return new Session( - $this->storageFactory->createStorage($this->requestStack->getMasterRequest()), + $this->storageFactory->createStorage($this->requestStack->getMainRequest()), $this->sessionAttributes, null, $this->usageReporter From dcb14d2989024578b2414761c5c9df15e798b3c3 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Fri, 26 Mar 2021 15:14:38 +0100 Subject: [PATCH 0632/5766] rename User to InMemoryUser --- components/security/authentication.rst | 6 +++--- security/user_provider.rst | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/components/security/authentication.rst b/components/security/authentication.rst index 8761e87915a..0b0e2d97f95 100644 --- a/components/security/authentication.rst +++ b/components/security/authentication.rst @@ -175,14 +175,14 @@ receives an array of encoders:: use Acme\Entity\LegacyUser; use Symfony\Component\Security\Core\Encoder\EncoderFactory; use Symfony\Component\Security\Core\Encoder\MessageDigestPasswordEncoder; - use Symfony\Component\Security\Core\User\User; + use Symfony\Component\Security\Core\User\InMemoryUser; $defaultEncoder = new MessageDigestPasswordEncoder('sha512', true, 5000); $weakEncoder = new MessageDigestPasswordEncoder('md5', true, 1); $encoders = [ - User::class => $defaultEncoder, - LegacyUser::class => $weakEncoder, + InMemoryUser::class => $defaultEncoder, + LegacyUser::class => $weakEncoder, // ... ]; $encoderFactory = new EncoderFactory($encoders); diff --git a/security/user_provider.rst b/security/user_provider.rst index 00e7c5a58d8..491eb57e256 100644 --- a/security/user_provider.rst +++ b/security/user_provider.rst @@ -138,7 +138,7 @@ interface only requires one method: ``loadUserByUsername($username)``:: public function loadUserByUsername(string $usernameOrEmail) { $entityManager = $this->getEntityManager(); - + return $entityManager->createQuery( 'SELECT u FROM App\Entity\User u @@ -231,7 +231,7 @@ users will encode their passwords: # ... encoders: # this internal class is used by Symfony to represent in-memory users - Symfony\Component\Security\Core\User\User: 'auto' + Symfony\Component\Security\Core\User\InMemoryUser: 'auto' .. code-block:: xml @@ -249,7 +249,7 @@ users will encode their passwords: - @@ -260,7 +260,7 @@ users will encode their passwords: // config/packages/security.php // this internal class is used by Symfony to represent in-memory users - use Symfony\Component\Security\Core\User\User; + use Symfony\Component\Security\Core\User\InMemoryUser; $container->loadFromExtension('security', [ // ... @@ -417,7 +417,7 @@ command will generate a nice skeleton to get you started:: { return User::class === $class || is_subclass_of($class, User::class); } - + /** * Upgrades the encoded password of a user, typically for using a better hash algorithm. */ From 1e6d1304681e4942adf30faf9987dc1051236948 Mon Sep 17 00:00:00 2001 From: Andrii Popov Date: Sat, 27 Mar 2021 09:27:39 +0200 Subject: [PATCH 0633/5766] [Validator] Add missing backticks for constraint option names --- reference/constraints/Bic.rst | 16 +-- reference/constraints/CardScheme.rst | 8 +- reference/constraints/Choice.rst | 36 +++--- reference/constraints/Count.rst | 20 ++-- reference/constraints/DateTime.rst | 4 +- reference/constraints/DivisibleBy.rst | 4 +- reference/constraints/Email.rst | 16 +-- reference/constraints/Expression.rst | 4 +- reference/constraints/File.rst | 64 +++++------ reference/constraints/Image.rst | 108 +++++++++--------- reference/constraints/Ip.rst | 8 +- reference/constraints/Isbn.rst | 20 ++-- reference/constraints/Issn.rst | 12 +- reference/constraints/Json.rst | 4 +- reference/constraints/Length.rst | 28 ++--- reference/constraints/Locale.rst | 4 +- reference/constraints/Negative.rst | 4 +- reference/constraints/NegativeOrZero.rst | 4 +- reference/constraints/NotBlank.rst | 4 +- .../constraints/NotCompromisedPassword.rst | 12 +- reference/constraints/Positive.rst | 4 +- reference/constraints/PositiveOrZero.rst | 4 +- reference/constraints/Range.rst | 32 +++--- reference/constraints/Regex.rst | 16 +-- reference/constraints/Timezone.rst | 16 +-- reference/constraints/Type.rst | 8 +- reference/constraints/Unique.rst | 4 +- reference/constraints/UniqueEntity.rst | 24 ++-- reference/constraints/Url.rst | 20 ++-- reference/constraints/Valid.rst | 4 +- .../constraints/_normalizer-option.rst.inc | 4 +- 31 files changed, 258 insertions(+), 258 deletions(-) diff --git a/reference/constraints/Bic.rst b/reference/constraints/Bic.rst index 6496ae63d54..0d00fca6297 100644 --- a/reference/constraints/Bic.rst +++ b/reference/constraints/Bic.rst @@ -87,8 +87,8 @@ Available Options .. include:: /reference/constraints/_groups-option.rst.inc -iban -~~~~ +``iban`` +~~~~~~~~ **type**: ``string`` **default**: ``null`` @@ -98,8 +98,8 @@ iban An IBAN value to validate that its country code is the same as the BIC's one. -ibanMessage -~~~~~~~~~~~ +``ibanMessage`` +~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``This Business Identifier Code (BIC) is not associated with IBAN {{ iban }}.`` @@ -109,8 +109,8 @@ ibanMessage The default message supplied when the value does not pass the combined BIC/IBAN check. -ibanPropertyPath -~~~~~~~~~~~~~~~~ +``ibanPropertyPath`` +~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``null`` @@ -124,8 +124,8 @@ For example, if you want to compare the ``$bic`` property of some object with regard to the ``$iban`` property of the same object, use ``ibanPropertyPath="iban"`` in the comparison constraint of ``$bic``. -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This is not a valid Business Identifier Code (BIC).`` diff --git a/reference/constraints/CardScheme.rst b/reference/constraints/CardScheme.rst index 6362d9932ee..e8e2b744987 100644 --- a/reference/constraints/CardScheme.rst +++ b/reference/constraints/CardScheme.rst @@ -99,8 +99,8 @@ Available Options .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``Unsupported card type or invalid card number.`` @@ -116,8 +116,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -schemes -~~~~~~~ +``schemes`` +~~~~~~~~~~~ **type**: ``mixed`` [:ref:`default option `] diff --git a/reference/constraints/Choice.rst b/reference/constraints/Choice.rst index b1407c8add0..0e099053775 100644 --- a/reference/constraints/Choice.rst +++ b/reference/constraints/Choice.rst @@ -275,8 +275,8 @@ you can pass the class name and the method as an array. Available Options ----------------- -callback -~~~~~~~~ +``callback`` +~~~~~~~~~~~~ **type**: ``string|array|Closure`` @@ -284,8 +284,8 @@ This is a callback method that can be used instead of the `choices`_ option to return the choices array. See `Supplying the Choices with a Callback Function`_ for details on its usage. -choices -~~~~~~~ +``choices`` +~~~~~~~~~~~ **type**: ``array`` [:ref:`default option `] @@ -295,8 +295,8 @@ will be matched against this array. .. include:: /reference/constraints/_groups-option.rst.inc -max -~~~ +``max`` +~~~~~~~ **type**: ``integer`` @@ -305,8 +305,8 @@ to force no more than XX number of values to be selected. For example, if ``max`` is 3, but the input array contains 4 valid items, the validation will fail. -maxMessage -~~~~~~~~~~ +``maxMessage`` +~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``You must select at most {{ limit }} choices.`` @@ -326,8 +326,8 @@ Parameter Description The ``{{ choices }}`` parameter was introduced in Symfony 4.3. -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``The value you selected is not a valid choice.`` @@ -344,8 +344,8 @@ Parameter Description ``{{ value }}`` The current (invalid) value ================= ============================================================ -min -~~~ +``min`` +~~~~~~~ **type**: ``integer`` @@ -354,8 +354,8 @@ to force at least XX number of values to be selected. For example, if ``min`` is 3, but the input array only contains 2 valid items, the validation will fail. -minMessage -~~~~~~~~~~ +``minMessage`` +~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``You must select at least {{ limit }} choices.`` @@ -375,8 +375,8 @@ Parameter Description The ``{{ choices }}`` parameter was introduced in Symfony 4.3. -multiple -~~~~~~~~ +``multiple`` +~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` @@ -385,8 +385,8 @@ of a single, scalar value. The constraint will check that each value of the input array can be found in the array of valid choices. If even one of the input values cannot be found, the validation will fail. -multipleMessage -~~~~~~~~~~~~~~~ +``multipleMessage`` +~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``One or more of the given values is invalid.`` diff --git a/reference/constraints/Count.rst b/reference/constraints/Count.rst index 2ff99b5adbb..dbbe94b480a 100644 --- a/reference/constraints/Count.rst +++ b/reference/constraints/Count.rst @@ -101,8 +101,8 @@ you might add the following: Options ------- -exactMessage -~~~~~~~~~~~~ +``exactMessage`` +~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``This collection should contain exactly {{ limit }} elements.`` @@ -120,8 +120,8 @@ Parameter Description .. include:: /reference/constraints/_groups-option.rst.inc -max -~~~ +``max`` +~~~~~~~ **type**: ``integer`` @@ -130,8 +130,8 @@ collection elements count is **greater** than this max value. This option is required when the ``min`` option is not defined. -maxMessage -~~~~~~~~~~ +``maxMessage`` +~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``This collection should contain {{ limit }} elements or less.`` @@ -147,8 +147,8 @@ Parameter Description ``{{ limit }}`` The upper limit =============== ============================================================== -min -~~~ +``min`` +~~~~~~~ **type**: ``integer`` @@ -157,8 +157,8 @@ collection elements count is **less** than this min value. This option is required when the ``max`` option is not defined. -minMessage -~~~~~~~~~~ +``minMessage`` +~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``This collection should contain {{ limit }} elements or more.`` diff --git a/reference/constraints/DateTime.rst b/reference/constraints/DateTime.rst index 41b4db2acc0..c3a9c328932 100644 --- a/reference/constraints/DateTime.rst +++ b/reference/constraints/DateTime.rst @@ -84,8 +84,8 @@ Basic Usage Options ------- -format -~~~~~~ +``format`` +~~~~~~~~~~ **type**: ``string`` **default**: ``Y-m-d H:i:s`` diff --git a/reference/constraints/DivisibleBy.rst b/reference/constraints/DivisibleBy.rst index f4ae78ab0f8..73b0a9c88b6 100644 --- a/reference/constraints/DivisibleBy.rst +++ b/reference/constraints/DivisibleBy.rst @@ -104,8 +104,8 @@ Options .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value should be a multiple of {{ compared_value }}.`` diff --git a/reference/constraints/Email.rst b/reference/constraints/Email.rst index 5b149f0bf5f..5cbeaeb4523 100644 --- a/reference/constraints/Email.rst +++ b/reference/constraints/Email.rst @@ -92,8 +92,8 @@ Basic Usage Options ------- -checkHost -~~~~~~~~~ +``checkHost`` +~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` @@ -105,8 +105,8 @@ If true, then the :phpfunction:`checkdnsrr` PHP function will be used to check the validity of the MX *or* the A *or* the AAAA record of the host of the given email. -checkMX -~~~~~~~ +``checkMX`` +~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` @@ -124,8 +124,8 @@ check the validity of the MX record of the host of the given email. .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is not a valid email address.`` @@ -139,8 +139,8 @@ Parameter Description ``{{ value }}`` The current (invalid) value =============== ============================================================== -mode -~~~~ +``mode`` +~~~~~~~~ **type**: ``string`` **default**: ``loose`` diff --git a/reference/constraints/Expression.rst b/reference/constraints/Expression.rst index f3af00f1d3a..fbcbfc9c2b2 100644 --- a/reference/constraints/Expression.rst +++ b/reference/constraints/Expression.rst @@ -264,8 +264,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -values -~~~~~~ +``values`` +~~~~~~~~~~ **type**: ``array`` **default**: ``[]`` diff --git a/reference/constraints/File.rst b/reference/constraints/File.rst index a865349f913..bc93caf83d1 100644 --- a/reference/constraints/File.rst +++ b/reference/constraints/File.rst @@ -158,8 +158,8 @@ have been specified. Options ------- -binaryFormat -~~~~~~~~~~~~ +``binaryFormat`` +~~~~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``null`` @@ -171,8 +171,8 @@ the value defined in the ``maxSize`` option. For more information about the difference between binary and SI prefixes, see `Wikipedia: Binary prefix`_. -disallowEmptyMessage -~~~~~~~~~~~~~~~~~~~~ +``disallowEmptyMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``An empty file is not allowed.`` @@ -190,8 +190,8 @@ Parameter Description .. include:: /reference/constraints/_groups-option.rst.inc -maxSize -~~~~~~~ +``maxSize`` +~~~~~~~~~~~ **type**: ``mixed`` @@ -212,8 +212,8 @@ Suffix Unit Name Value Example For more information about the difference between binary and SI prefixes, see `Wikipedia: Binary prefix`_. -maxSizeMessage -~~~~~~~~~~~~~~ +``maxSizeMessage`` +~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file is too large ({{ size }} {{ suffix }}). Allowed maximum size is {{ limit }} {{ suffix }}.`` @@ -231,8 +231,8 @@ Parameter Description ``{{ suffix }}`` Suffix for the used file size unit (see above) ================ ============================================================= -mimeTypes -~~~~~~~~~ +``mimeTypes`` +~~~~~~~~~~~~~ **type**: ``array`` or ``string`` @@ -256,8 +256,8 @@ You can find a list of existing mime types on the `IANA website`_. This feature was introduced in Symfony 4.4. -mimeTypesMessage -~~~~~~~~~~~~~~~~ +``mimeTypesMessage`` +~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The mime type of the file is invalid ({{ type }}). Allowed mime types are {{ types }}.`` @@ -275,8 +275,8 @@ Parameter Description ``{{ types }}`` The list of allowed MIME types =============== ============================================================== -notFoundMessage -~~~~~~~~~~~~~~~ +``notFoundMessage`` +~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file could not be found.`` @@ -292,8 +292,8 @@ Parameter Description ``{{ file }}`` Absolute file path =============== ============================================================== -notReadableMessage -~~~~~~~~~~~~~~~~~~ +``notReadableMessage`` +~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file is not readable.`` @@ -310,8 +310,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -uploadCantWriteErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadCantWriteErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``Cannot write temporary file to disk.`` @@ -320,8 +320,8 @@ temporary folder. This message has no parameters. -uploadErrorMessage -~~~~~~~~~~~~~~~~~~ +``uploadErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file could not be uploaded.`` @@ -330,8 +330,8 @@ for some unknown reason. This message has no parameters. -uploadExtensionErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadExtensionErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``A PHP extension caused the upload to fail.`` @@ -340,8 +340,8 @@ fail. This message has no parameters. -uploadFormSizeErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadFormSizeErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file is too large.`` @@ -350,8 +350,8 @@ by the HTML file input field. This message has no parameters. -uploadIniSizeErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadIniSizeErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file is too large. Allowed maximum size is {{ limit }} {{ suffix }}.`` @@ -367,8 +367,8 @@ Parameter Description ``{{ suffix }}`` Suffix for the used file size unit (see above) ================ ============================================================= -uploadNoFileErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadNoFileErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``No file was uploaded.`` @@ -376,8 +376,8 @@ The message that is displayed if no file was uploaded. This message has no parameters. -uploadNoTmpDirErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadNoTmpDirErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``No temporary folder was configured in php.ini.`` @@ -386,8 +386,8 @@ missing. This message has no parameters. -uploadPartialErrorMessage -~~~~~~~~~~~~~~~~~~~~~~~~~ +``uploadPartialErrorMessage`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The file was only partially uploaded.`` diff --git a/reference/constraints/Image.rst b/reference/constraints/Image.rst index e8b492bf4ae..8ab714db79b 100644 --- a/reference/constraints/Image.rst +++ b/reference/constraints/Image.rst @@ -230,15 +230,15 @@ This constraint shares all of its options with the :doc:`File `] diff --git a/reference/constraints/Timezone.rst b/reference/constraints/Timezone.rst index c5f27e1cbfb..3725038f0d8 100644 --- a/reference/constraints/Timezone.rst +++ b/reference/constraints/Timezone.rst @@ -86,8 +86,8 @@ string which contains any of the `PHP timezone identifiers`_ (e.g. ``America/New Options ------- -countryCode -~~~~~~~~~~~ +``countryCode`` +~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``null`` @@ -100,8 +100,8 @@ The value of this option must be a valid `ISO 3166-1 alpha-2`_ country code .. include:: /reference/constraints/_groups-option.rst.inc -intlCompatible -~~~~~~~~~~~~~~ +``intlCompatible`` +~~~~~~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` @@ -114,8 +114,8 @@ timezones provided by PHP's Intl extension (because they use different ICU versions). If this option is set to ``true``, this constraint only considers valid the values compatible with the PHP ``\IntlTimeZone::createTimeZone()`` method. -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is not a valid timezone.`` @@ -131,8 +131,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -zone -~~~~ +``zone`` +~~~~~~~~ **type**: ``string`` **default**: ``\DateTimeZone::ALL`` diff --git a/reference/constraints/Type.rst b/reference/constraints/Type.rst index 307b7565749..17ee98fec78 100644 --- a/reference/constraints/Type.rst +++ b/reference/constraints/Type.rst @@ -155,8 +155,8 @@ Options .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value should be of type {{ type }}.`` @@ -175,8 +175,8 @@ Parameter Description .. _reference-constraint-type-type: -type -~~~~ +``type`` +~~~~~~~~ **type**: ``string`` or ``array`` [:ref:`default option `] diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst index e6acb08ea71..9d9cc0ffed2 100644 --- a/reference/constraints/Unique.rst +++ b/reference/constraints/Unique.rst @@ -94,8 +94,8 @@ Options .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This collection should contain only unique elements.`` diff --git a/reference/constraints/UniqueEntity.rst b/reference/constraints/UniqueEntity.rst index ca0a0be28c6..f96d6d91b47 100644 --- a/reference/constraints/UniqueEntity.rst +++ b/reference/constraints/UniqueEntity.rst @@ -140,8 +140,8 @@ the uniqueness. If it's left blank, the correct entity manager will be determined for this class. For that reason, this option should probably not need to be used. -entityClass -~~~~~~~~~~~ +``entityClass`` +~~~~~~~~~~~~~~~ **type**: ``string`` @@ -151,8 +151,8 @@ inheritance mapping, you need to execute the query in a different repository. Use this option to define the fully-qualified class name (FQCN) of the Doctrine entity associated with the repository you want to use. -errorPath -~~~~~~~~~ +``errorPath`` +~~~~~~~~~~~~~ **type**: ``string`` **default**: The name of the first field in `fields`_ @@ -249,8 +249,8 @@ Consider this example: Now, the message would be bound to the ``port`` field with this configuration. -fields -~~~~~~ +``fields`` +~~~~~~~~~~ **type**: ``array`` | ``string`` [:ref:`default option `] @@ -266,8 +266,8 @@ each with a single field. .. include:: /reference/constraints/_groups-option.rst.inc -ignoreNull -~~~~~~~~~~ +``ignoreNull`` +~~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``true`` @@ -276,8 +276,8 @@ entities to have a ``null`` value for a field without failing validation. If set to ``false``, only one ``null`` value is allowed - if a second entity also has a ``null`` value, validation would fail. -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is already used.`` @@ -300,8 +300,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -repositoryMethod -~~~~~~~~~~~~~~~~ +``repositoryMethod`` +~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``findBy`` diff --git a/reference/constraints/Url.rst b/reference/constraints/Url.rst index 4c9885d0147..ac230890a9a 100644 --- a/reference/constraints/Url.rst +++ b/reference/constraints/Url.rst @@ -81,8 +81,8 @@ Basic Usage Options ------- -checkDNS -~~~~~~~~ +``checkDNS`` +~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` @@ -163,8 +163,8 @@ option to the value of any of the ``CHECK_DNS_TYPE_*`` constants in the This option uses the :phpfunction:`checkdnsrr` PHP function to check the validity of the DNS record corresponding to the host associated with the given URL. -dnsMessage -~~~~~~~~~~ +``dnsMessage`` +~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``The host could not be resolved.`` @@ -242,8 +242,8 @@ DNS check failed. .. include:: /reference/constraints/_groups-option.rst.inc -message -~~~~~~~ +``message`` +~~~~~~~~~~~ **type**: ``string`` **default**: ``This value is not a valid URL.`` @@ -324,8 +324,8 @@ Parameter Description .. include:: /reference/constraints/_payload-option.rst.inc -protocols -~~~~~~~~~ +``protocols`` +~~~~~~~~~~~~~ **type**: ``array`` **default**: ``['http', 'https']`` @@ -399,8 +399,8 @@ the ``ftp://`` type URLs to be valid, redefine the ``protocols`` array, listing } } -relativeProtocol -~~~~~~~~~~~~~~~~ +``relativeProtocol`` +~~~~~~~~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` diff --git a/reference/constraints/Valid.rst b/reference/constraints/Valid.rst index 1cb992128ac..edd282fa53b 100644 --- a/reference/constraints/Valid.rst +++ b/reference/constraints/Valid.rst @@ -250,8 +250,8 @@ Options .. include:: /reference/constraints/_payload-option.rst.inc -traverse -~~~~~~~~ +``traverse`` +~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``true`` diff --git a/reference/constraints/_normalizer-option.rst.inc b/reference/constraints/_normalizer-option.rst.inc index 784f915ff95..dcbba1c2da8 100644 --- a/reference/constraints/_normalizer-option.rst.inc +++ b/reference/constraints/_normalizer-option.rst.inc @@ -1,5 +1,5 @@ -normalizer -~~~~~~~~~~ +``normalizer`` +~~~~~~~~~~~~~~ **type**: a `PHP callable`_ **default**: ``null`` From c610653de3785f1e7578bf06c5b32cd234742147 Mon Sep 17 00:00:00 2001 From: Chris Maiden Date: Thu, 25 Mar 2021 11:14:31 +0000 Subject: [PATCH 0634/5766] Fix typo --- frontend/encore/versioning.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/encore/versioning.rst b/frontend/encore/versioning.rst index 0911f8d8cc3..ecea440ec75 100644 --- a/frontend/encore/versioning.rst +++ b/frontend/encore/versioning.rst @@ -7,7 +7,7 @@ Tired of deploying and having browser's cache the old version of your assets? By calling ``enableVersioning()``, each filename will now include a hash that changes whenever the *contents* of that file change (e.g. ``app.123abc.js`` instead of ``app.js``). This allows you to use aggressive caching strategies -(e.g. a far future ``Expires``) because, whenever a file change, its hash will change, +(e.g. a far future ``Expires``) because, whenever a file changes, its hash will change, ignoring any existing cache: .. code-block:: diff From 04b203118081c7714687031f3f5e9f70142a0b69 Mon Sep 17 00:00:00 2001 From: Chris Maiden Date: Thu, 25 Mar 2021 14:11:06 +0000 Subject: [PATCH 0635/5766] [CssSelector] Grammatical fix --- components/css_selector.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/css_selector.rst b/components/css_selector.rst index c8100793ab4..be68d1801ed 100644 --- a/components/css_selector.rst +++ b/components/css_selector.rst @@ -25,8 +25,8 @@ Usage component in any PHP application. Read the :ref:`Symfony Functional Tests ` article to learn about how to use it when creating Symfony tests. -Why to Use CSS selectors? -~~~~~~~~~~~~~~~~~~~~~~~~~ +Why Use CSS selectors? +~~~~~~~~~~~~~~~~~~~~~~ When you're parsing an HTML or an XML document, by far the most powerful method is `XPath`_. From 92072d936ca519203685c3eb1ace602adff68ad6 Mon Sep 17 00:00:00 2001 From: Andrii Popov Date: Fri, 19 Mar 2021 09:03:37 +0200 Subject: [PATCH 0636/5766] [Validator] Add normalizer option to Unique constraint --- reference/constraints/Unique.rst | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst index eb7b4727491..f673d2d817b 100644 --- a/reference/constraints/Unique.rst +++ b/reference/constraints/Unique.rst @@ -2,8 +2,9 @@ Unique ====== Validates that all the elements of the given collection are unique (none of them -is present more than once). Elements are compared strictly, so ``'7'`` and ``7`` -are considered different elements (a string and an integer, respectively). +is present more than once). By default elements are compared strictly, +so ``'7'`` and ``7`` are considered different elements (a string and an integer, respectively). +If you want any other comparison logic to be applied, use the `normalizer`_ option. .. seealso:: @@ -21,6 +22,7 @@ are considered different elements (a string and an integer, respectively). Applies to :ref:`property or method ` Options - `groups`_ - `message`_ + - `normalizer`_ - `payload`_ Class :class:`Symfony\\Component\\Validator\\Constraints\\Unique` Validator :class:`Symfony\\Component\\Validator\\Constraints\\UniqueValidator` @@ -123,4 +125,22 @@ Parameter Description ``{{ value }}`` The current (invalid) value ============================= ================================================ +``normalizer`` +~~~~~~~~~~~~~~ + +**type**: a `PHP callable`_ **default**: ``null`` + +.. versionadded:: 5.3 + + The ``normalizer`` option was introduced in Symfony 5.3. + +This option allows to define the PHP callable applied to each element of the given collection before +checking if the collection is valid. + +For example, you may want to pass the ``'trim'`` string to apply the +:phpfunction:`trim` PHP function to each element of the collection in order to ignore leading and trailing +whitespace during validation. + .. include:: /reference/constraints/_payload-option.rst.inc + +.. _`PHP callable`: https://www.php.net/callable From 3862669e610854ea302c5859f8755f563741dedf Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sat, 27 Mar 2021 20:03:16 +0100 Subject: [PATCH 0637/5766] Minor tweaks --- reference/constraints/Unique.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/reference/constraints/Unique.rst b/reference/constraints/Unique.rst index 3be82ed5da5..6b6d363acf1 100644 --- a/reference/constraints/Unique.rst +++ b/reference/constraints/Unique.rst @@ -4,7 +4,7 @@ Unique Validates that all the elements of the given collection are unique (none of them is present more than once). By default elements are compared strictly, so ``'7'`` and ``7`` are considered different elements (a string and an integer, respectively). -If you want any other comparison logic to be applied, use the `normalizer`_ option. +If you want to apply any other comparison logic, use the `normalizer`_ option. .. seealso:: @@ -134,12 +134,12 @@ Parameter Description The ``normalizer`` option was introduced in Symfony 5.3. -This option allows to define the PHP callable applied to each element of the given collection before -checking if the collection is valid. +This option defined the PHP callable applied to each element of the given +collection before checking if the collection is valid. -For example, you may want to pass the ``'trim'`` string to apply the -:phpfunction:`trim` PHP function to each element of the collection in order to ignore leading and trailing -whitespace during validation. +For example, you can pass the ``'trim'`` string to apply the :phpfunction:`trim` +PHP function to each element of the collection in order to ignore leading and +trailing whitespace during validation. .. include:: /reference/constraints/_payload-option.rst.inc From a6874e68d8710a01239b99e3499d3c127fed290a Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 28 Mar 2021 11:37:53 +0200 Subject: [PATCH 0638/5766] [Finder] Fix typo --- components/finder.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/finder.rst b/components/finder.rst index f799208558e..6952685b64f 100644 --- a/components/finder.rst +++ b/components/finder.rst @@ -214,7 +214,7 @@ Use the forward slash (i.e. ``/``) as the directory separator on all platforms, including Windows. The component makes the necessary conversion internally. The ``path()`` method accepts a string, a regular expression or an array of -strings or regulars expressions:: +strings or regular expressions:: $finder->path('foo/bar'); $finder->path('/^foo\/bar/'); From 337e25169c2a369e2a102144c3d5d11a02f3259b Mon Sep 17 00:00:00 2001 From: James Hemery Date: Sat, 23 Jan 2021 02:35:30 +0100 Subject: [PATCH 0639/5766] [Notifier] [FakeSms] Add the bridge --- notifier.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/notifier.rst b/notifier.rst index 023361051c2..72afd815ac3 100644 --- a/notifier.rst +++ b/notifier.rst @@ -59,6 +59,7 @@ Service Package DSN AllMySms ``symfony/allmysms-notifier`` ``allmysms://LOGIN:APIKEY@default?from=FROM`` Clickatell ``symfony/clickatell-notifier`` ``clickatell://ACCESS_TOKEN@default?from=FROM`` Esendex ``symfony/esendex-notifier`` ``esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM`` +FakeSms ``symfony/fake-sms-notifier`` ``fakesms+email://MAILER_SERVICE_ID?to=TO&from=FROM`` FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` GatewayApi ``symfony/gatewayapi-notifier`` ``gatewayapi://TOKEN@default?from=FROM`` Infobip ``symfony/infobip-notifier`` ``infobip://AUTH_TOKEN@HOST?from=FROM`` @@ -84,9 +85,8 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= .. versionadded:: 5.3 - The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell and SpotHit integrations - were introduced in Symfony 5.3. - + The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell, SpotHit and FakeSms + integrations were introduced in Symfony 5.3. To enable a texter, add the correct DSN in your ``.env`` file and configure the ``texter_transports``: From 687199ee2bb22b4decbec8e8c1f7f4b4730d9de3 Mon Sep 17 00:00:00 2001 From: Guillaume Sarramegna <13528732+sarramegnag@users.noreply.github.com> Date: Tue, 30 Mar 2021 19:06:41 +0200 Subject: [PATCH 0640/5766] Standardize built-in normalizers lists --- components/serializer.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/serializer.rst b/components/serializer.rst index f2c3285a33b..84c8ecb8a36 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -782,6 +782,9 @@ The Serializer component provides several built-in normalizers: :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`. + .. note:: You can also create your own Normalizer to use another structure. Read more at From 3f33c81da2b1d3330d353c86af52aba5789bb205 Mon Sep 17 00:00:00 2001 From: Guilliam Xavier Date: Wed, 31 Mar 2021 11:36:34 +0200 Subject: [PATCH 0641/5766] [Validator] Fix Regex htmlPattern examples --- reference/constraints/Regex.rst | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/reference/constraints/Regex.rst b/reference/constraints/Regex.rst index 02a5ea8f407..c3b9a9bd5c6 100644 --- a/reference/constraints/Regex.rst +++ b/reference/constraints/Regex.rst @@ -175,12 +175,12 @@ Options This option specifies the pattern to use in the HTML5 ``pattern`` attribute. You usually don't need to specify this option because by default, the constraint will convert the pattern given in the `pattern`_ option into an HTML5 compatible -pattern. This means that the delimiters are removed (e.g. ``/[a-z]+/`` becomes -``[a-z]+``). +pattern. Notably, the delimiters are removed and the anchors are implicit (e.g. +``/^[a-z]+$/`` becomes ``[a-z]+``, and ``/[a-z]+/`` becomes ``.*[a-z]+.*``). However, there are some other incompatibilities between both patterns which cannot be fixed by the constraint. For instance, the HTML5 ``pattern`` attribute -does not support flags. If you have a pattern like ``/[a-z]+/i``, you +does not support flags. If you have a pattern like ``/^[a-z]+$/i``, you need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: .. configuration-block:: @@ -197,7 +197,7 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: /** * @Assert\Regex( * pattern = "/^[a-z]+$/i", - * htmlPattern = "^[a-zA-Z]+$" + * htmlPattern = "[a-zA-Z]+" * ) */ protected $name; @@ -211,7 +211,7 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: name: - Regex: pattern: '/^[a-z]+$/i' - htmlPattern: '^[a-zA-Z]+$' + htmlPattern: '[a-zA-Z]+' .. code-block:: xml @@ -225,7 +225,7 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: - +
                    @@ -245,7 +245,7 @@ need to specify the HTML5 compatible pattern in the ``htmlPattern`` option: { $metadata->addPropertyConstraint('name', new Assert\Regex([ 'pattern' => '/^[a-z]+$/i', - 'htmlPattern' => '^[a-zA-Z]+$', + 'htmlPattern' => '[a-zA-Z]+', ])); } } From ebddb78293a7901799d6aeba24d80f42301c13fa Mon Sep 17 00:00:00 2001 From: Nyholm Date: Wed, 31 Mar 2021 09:24:36 +0200 Subject: [PATCH 0642/5766] [Validator] Add warning about closure not being cachable --- reference/constraints/Callback.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst index 6985f3953e1..65a63235a73 100644 --- a/reference/constraints/Callback.rst +++ b/reference/constraints/Callback.rst @@ -251,6 +251,13 @@ constructor of the Callback constraint:: } } +.. warning:: + + Using a ``Closure`` together with annotation configuration will disable the + annotation cache for that class/property/methods because ``Closure``s cannot + be cached. For best performance, it is recommended to use a static callback + method. + Options ------- From f57055d5e95f79ee49c604ed3bd273070f773e91 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Wed, 31 Mar 2021 13:17:07 +0200 Subject: [PATCH 0643/5766] Minor tweak --- reference/constraints/Callback.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/reference/constraints/Callback.rst b/reference/constraints/Callback.rst index 65a63235a73..c917bf93412 100644 --- a/reference/constraints/Callback.rst +++ b/reference/constraints/Callback.rst @@ -254,9 +254,8 @@ constructor of the Callback constraint:: .. warning:: Using a ``Closure`` together with annotation configuration will disable the - annotation cache for that class/property/methods because ``Closure``s cannot - be cached. For best performance, it is recommended to use a static callback - method. + annotation cache for that class/property/method because ``Closure`` cannot + be cached. For best performance, it's recommended to use a static callback method. Options ------- From bf9e574c1ad2a0507639eee8a6285bf5f1776b15 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Wed, 31 Mar 2021 18:18:21 +0200 Subject: [PATCH 0644/5766] Rewording Priority Parameter Important part: Explaining how to do it in YAML and XML, to make clear that `priority` is not *limited* to annotations/attributes - but simply not necessary in YAML/XML :-) Closes https://github.com/symfony/symfony-docs/issues/13367 --- routing.rst | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/routing.rst b/routing.rst index bf971924311..97df5e57787 100644 --- a/routing.rst +++ b/routing.rst @@ -997,11 +997,10 @@ Priority Parameter The ``priority`` parameter was introduced in Symfony 5.1 -When defining a greedy pattern that matches many routes, this may be at the -beginning of your routing collection and prevents any route defined after to be -matched. -A ``priority`` optional parameter is available in order to let you choose the -order of your routes, and it is only available when using annotations. +Symfony evaluates routes in the order they are defined. So a routing pattern +that matches many routes might prevent subsequent routes to be matched. In YAML +and XML you can control the order by moving the routes up or down inside the file. +For annotations and attributes, there is an optional ``priority`` parameter: .. configuration-block:: From af96b342256b1683aed3fcd0c648bb05110dba5c Mon Sep 17 00:00:00 2001 From: Mathias Arlaud Date: Thu, 1 Apr 2021 16:27:39 +0200 Subject: [PATCH 0645/5766] Update doc for mercure 0.5 --- notifier.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 72afd815ac3..45507e1784a 100644 --- a/notifier.rst +++ b/notifier.rst @@ -157,7 +157,7 @@ Gitter ``symfony/gitter-notifier`` ``GITTER_DSN=gitter://TOKEN@defaul GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY`` LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` -Mercure ``symfony/mercure-notifier`` ``mercure://PUBLISHER_SERVICE_ID?topic=TOPIC`` +Mercure ``symfony/mercure-notifier`` ``mercure://HUB_ID?topic=TOPIC`` 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`` From 7eb064ca248c04d46d69dc168a62d0f84393c5c4 Mon Sep 17 00:00:00 2001 From: Maxime Steinhausser Date: Fri, 2 Apr 2021 14:56:31 +0200 Subject: [PATCH 0646/5766] [Lock] Remove tip about the RetryTillSaveStore --- reference/configuration/framework.rst | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 6458d77328a..d107cf804df 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -3090,18 +3090,6 @@ name Name of the lock you want to create. -.. tip:: - - If you want to use the `RetryTillSaveStore` for :ref:`non-blocking locks `, - you can do it by :doc:`decorating the store ` service: - - .. code-block:: yaml - - lock.invoice.retry_till_save.store: - class: Symfony\Component\Lock\Store\RetryTillSaveStore - decorates: lock.invoice.store - arguments: ['@.inner', 100, 50] - mailer ~~~~~~ From 9e9796bd7a04c18269531e64dae8367bd00634ad Mon Sep 17 00:00:00 2001 From: Felipy Amorim Date: Sun, 4 Apr 2021 21:41:28 -0300 Subject: [PATCH 0647/5766] remove namespace unused --- security/user_checkers.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/security/user_checkers.rst b/security/user_checkers.rst index b215191e680..a1662298276 100644 --- a/security/user_checkers.rst +++ b/security/user_checkers.rst @@ -24,7 +24,6 @@ displayed to the user:: namespace App\Security; use App\Entity\User as AppUser; - use App\Exception\AccountDeletedException; use Symfony\Component\Security\Core\Exception\AccountExpiredException; use Symfony\Component\Security\Core\Exception\CustomUserMessageAccountStatusException; use Symfony\Component\Security\Core\User\UserCheckerInterface; From 3fe341f6c733e4d3c40d1dd44d802c5d300c8c80 Mon Sep 17 00:00:00 2001 From: Vasilij Dusko | CREATION Date: Thu, 1 Apr 2021 16:36:38 +0300 Subject: [PATCH 0648/5766] [Notifier] [LightSMS] add docs --- notifier.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index 72afd815ac3..e23c85aeefa 100644 --- a/notifier.rst +++ b/notifier.rst @@ -64,6 +64,7 @@ FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@defa GatewayApi ``symfony/gatewayapi-notifier`` ``gatewayapi://TOKEN@default?from=FROM`` Infobip ``symfony/infobip-notifier`` ``infobip://AUTH_TOKEN@HOST?from=FROM`` Iqsms ``symfony/iqsms-notifier`` ``iqsms://LOGIN:PASSWORD@default?from=FROM`` +LightSMS ``symfony/lightsms-notifier`` ``lightsms://LOGIN:TOKEN@default?from=PHONE`` Mobyt ``symfony/mobyt-notifier`` ``mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM`` Nexmo ``symfony/nexmo-notifier`` ``nexmo://KEY:SECRET@default?from=FROM`` Octopush ``symfony/octopush-notifier`` ``octopush://USERLOGIN:APIKEY@default?from=FROM&type=TYPE`` @@ -85,7 +86,7 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= .. versionadded:: 5.3 - The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell, SpotHit and FakeSms + The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell, SpotHit, FakeSms and LightSMS integrations were introduced in Symfony 5.3. To enable a texter, add the correct DSN in your ``.env`` file and From 018d50ba322d5e58990918b226f0363dd0fcf541 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 31 Mar 2021 09:17:13 +0200 Subject: [PATCH 0649/5766] [Notifier][FakeChat] add docs --- notifier.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index e23c85aeefa..459f7d406b7 100644 --- a/notifier.rst +++ b/notifier.rst @@ -153,6 +153,7 @@ integration with these chat services: Service Package DSN ========== ================================ =========================================================================== Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` +FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://MAILER_SERVICE_ID?to=TO&from=FROM`` Firebase ``symfony/firebase-notifier`` ``firebase://USERNAME:PASSWORD@default`` Gitter ``symfony/gitter-notifier`` ``GITTER_DSN=gitter://TOKEN@default?room_id=ROOM_ID`` GoogleChat ``symfony/google-chat-notifier`` ``googlechat://ACCESS_KEY:ACCESS_TOKEN@default/SPACE?thread_key=THREAD_KEY`` @@ -178,7 +179,7 @@ Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel .. versionadded:: 5.3 - The Gitter and Mercure integrations were introduced in Symfony 5.3. + The Gitter, Mercure and FakeChat integrations were introduced in Symfony 5.3. Chatters are configured using the ``chatter_transports`` setting: From 8e5d9bcaaee6bf5bb55b927331f470a66352f04e Mon Sep 17 00:00:00 2001 From: ferror Date: Mon, 5 Apr 2021 16:46:16 +0200 Subject: [PATCH 0650/5766] Every custom header in testing client must have HTTP prefix --- testing.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/testing.rst b/testing.rst index 130ed0ab2ae..d6fa9774a1b 100644 --- a/testing.rst +++ b/testing.rst @@ -1029,6 +1029,10 @@ You can also override HTTP headers on a per request basis:: 'HTTP_USER_AGENT' => 'MySuperBrowser/1.0', ]); +.. caution:: + + Every custom header must have `HTTP_` prefix. + .. tip:: The test client is available as a service in the container in the ``test`` From cc0337ca95bcdf1ecec0c3db32cfedb81e2911cd Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 6 Apr 2021 13:36:11 +0200 Subject: [PATCH 0651/5766] Added more details to the explanation --- testing.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/testing.rst b/testing.rst index d6fa9774a1b..12bd6c74524 100644 --- a/testing.rst +++ b/testing.rst @@ -1031,7 +1031,10 @@ You can also override HTTP headers on a per request basis:: .. caution:: - Every custom header must have `HTTP_` prefix. + 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 + uppercase and prefix the result with ``HTTP_``. For example, if your + header name is ``X-Session-Token``, pass ``HTTP_X_SESSION_TOKEN``. .. tip:: @@ -1128,3 +1131,4 @@ Learn more .. _`$_SERVER`: https://www.php.net/manual/en/reserved.variables.server.php .. _`data providers`: https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers .. _`code coverage analysis`: https://phpunit.readthedocs.io/en/9.1/code-coverage-analysis.html +.. _`section 4.1.18 of RFC 3875`: https://tools.ietf.org/html/rfc3875#section-4.1.18 From 0e53eb0a675ccd1f64948fd0b000016bc409be26 Mon Sep 17 00:00:00 2001 From: azjezz Date: Wed, 24 Mar 2021 12:19:38 +0100 Subject: [PATCH 0652/5766] update mercure documentation --- mercure.rst | 169 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 55 deletions(-) diff --git a/mercure.rst b/mercure.rst index f32e8eee6a8..d67609f659a 100644 --- a/mercure.rst +++ b/mercure.rst @@ -159,20 +159,19 @@ service, including controllers:: namespace App\Controller; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\Mercure\PublisherInterface; + use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Mercure\Update; class PublishController { - public function __invoke(PublisherInterface $publisher): Response + public function __invoke(HubInterface $hub): Response { $update = new Update( 'http://example.com/books/1', json_encode(['status' => 'OutOfStock']) ); - // The Publisher service is an invokable object - $publisher($update); + $hub->publish($update); return new Response('published!'); } @@ -297,17 +296,14 @@ by using the ``AbstractController::addLink`` helper method:: use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\Request; - use Symfony\Component\WebLink\Link; + use Symfony\Component\Mercure\Discovery; class DiscoverController extends AbstractController { - public function __invoke(Request $request): JsonResponse + public function __invoke(Request $request, Discovery $discovery): JsonResponse { - // This parameter is automatically created by the MercureBundle - $hubUrl = $this->getParameter('mercure.default_hub'); - // Link: ; rel="mercure" - $this->addLink($request, new Link('mercure', $hubUrl)); + $discovery->addLink($request); return $this->json([ '@id' => '/books/1', @@ -346,13 +342,13 @@ of the ``Update`` constructor to ``true``:: // src/Controller/Publish.php namespace App\Controller; + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\Mercure\PublisherInterface; use Symfony\Component\Mercure\Update; - class PublishController + class PublishController extends AbstractController { - public function __invoke(PublisherInterface $publisher): Response + public function __invoke(HubInterface $hub): Response { $update = new Update( 'http://example.com/books/1', @@ -362,7 +358,7 @@ of the ``Update`` constructor to ``true``:: // Publisher's JWT must contain this topic, a URI template it matches or * in mercure.publish or you'll get a 401 // Subscriber's JWT must contain this topic, a URI template it matches or * in mercure.subscribe to receive the update - $publisher($update); + $hub->publish($update); return new Response('private update published!'); } @@ -406,44 +402,71 @@ This cookie will be automatically sent by the web browser when connecting to the Then, the Hub will verify the validity of the provided JWT, and extract the topic selectors from it. -To generate the JWT, we'll use the ``lcobucci/jwt`` library. Install it: +add your JWT secret to the configuration as follow :: -.. code-block:: terminal +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/mercure.yaml + mercure: + hubs: + default: + url: https://mercure-hub.example.com/.well-known/mercure + jwt: + secret: '!ChangeMe!' + + .. code-block:: xml + + + + + + + + + + .. code-block:: php - $ composer require lcobucci/jwt + // config/packages/mercure.php + $container->loadFromExtension('mercure', [ + 'hubs' => [ + 'default' => [ + 'url' => 'https://mercure-hub.example.com/.well-known/mercure', + 'jwt' => [ + 'secret' => '!ChangeMe!', + ] + ], + ], + ]); And here is the controller:: // src/Controller/DiscoverController.php namespace App\Controller; - use Lcobucci\JWT\Configuration; - use Lcobucci\JWT\Signer\Hmac\Sha256; - use Lcobucci\JWT\Signer\Key; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\WebLink\Link; + use Symfony\Component\Mercure\Authorization; + use Symfony\Component\Mercure\Discovery; class DiscoverController extends AbstractController { - public function __invoke(Request $request): Response + public function __invoke(Request $request, Discovery $discovery, Authorization $authorization): Response { - $hubUrl = $this->getParameter('mercure.default_hub'); - $this->addLink($request, new Link('mercure', $hubUrl)); - - $key = Key\InMemory::plainText('mercure_secret_key'); // don't forget to set this parameter! Test value: !ChangeMe! - $configuration = Configuration::forSymmetricSigner(new Sha256(), $key); + $discovery->addLink($request); - $token = $configuration->builder() - ->withClaim('mercure', ['subscribe' => ["http://example.com/books/1"]]) // can also be a URI template, or * - ->getToken($configuration->signer(), $configuration->signingKey()) - ->toString(); + $response = new JsonResponse([ + '@id' => '/demo/books/1', + 'availability' => 'https://schema.org/InStock' + ]); - $response = $this->json(['@id' => '/demo/books/1', 'availability' => 'https://schema.org/InStock']); - $response->headers->set( - 'set-cookie', - sprintf('mercureAuthorization=%s; path=/.well-known/mercure; secure; httponly; SameSite=strict', $token) + $response->headers->setCookie( + $authorization->createCookie($request, ["http://example.com/books/1"]) ); return $response; @@ -459,15 +482,17 @@ Programmatically Generating The JWT Used to Publish --------------------------------------------------- Instead of directly storing a JWT in the configuration, -you can create a service that will return the token used by -the ``Publisher`` object:: +you can create a token provider that will return the token used by +the ``HubInterface`` object:: - // src/Mercure/MyJwtProvider.php + // src/Mercure/MyTokenProvider.php namespace App\Mercure; - final class MyJwtProvider + use Symfony\Component\Mercure\JWT\TokenProviderInterface; + + final class MyTokenProvider implements TokenProviderInterface { - public function __invoke(): string + public function getToken(): string { return 'the-JWT'; } @@ -484,7 +509,8 @@ Then, reference this service in the bundle configuration: hubs: default: url: https://mercure-hub.example.com/.well-known/mercure - jwt_provider: App\Mercure\MyJwtProvider + jwt: + provider: App\Mercure\MyTokenProvider .. code-block:: xml @@ -494,8 +520,9 @@ Then, reference this service in the bundle configuration: + > + + .. code-block:: php @@ -507,7 +534,9 @@ Then, reference this service in the bundle configuration: 'hubs' => [ 'default' => [ 'url' => 'https://mercure-hub.example.com/.well-known/mercure', - 'jwt_provider' => MyJwtProvider::class, + 'jwt' => [ + 'provider' => MyJwtProvider::class, + ] ], ], ]); @@ -568,29 +597,59 @@ its Mercure support. Testing -------- -During functional testing there is no need to send updates to Mercure. They will -be handled by a stub publisher:: +During unit testing there is not need to send updates to Mercure. + +You can instead make use of the `MockHub`:: + + // tests/Functional/.php + namespace App\Tests\Unit\Controller; - // tests/Functional/Fixtures/PublisherStub.php + use App\Controller\MessageController; + use Symfony\Component\Mercure\HubInterface; + use Symfony\Component\Mercure\JWT\StaticTokenProvider; + use Symfony\Component\Mercure\MockHub; + use Symfony\Component\Mercure\Update; + + class MessageControllerTest extends TestCase + { + public function testPublishing() + { + $hub = new MockHub('default', 'https://internal/.well-known/mercure', new StaticTokenProvider('foo'), function(Update $update): string { + // $this->assertTrue($update->isPrivate()); + + return 'id'; + }); + + $controller = new MessageController($hub); + + ... + } + } + +During functional testing you can instead decorate the Hub:: + + // tests/Functional/Fixtures/HubStub.php namespace App\Tests\Functional\Fixtures; - use Symfony\Component\Mercure\PublisherInterface; + use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Mercure\Update; - class PublisherStub implements PublisherInterface + class HubStub implements HubInterface { - public function __invoke(Update $update): string + public function publish(Update $update): string { - return ''; + return 'id'; } + + // implement rest of HubInterface methods here } -PublisherStub decorates the default publisher service so no updates are actually -sent. Here is the PublisherStub implementation:: +HubStub decorates the default hub service so no updates are actually +sent. Here is the HubStub implementation:: # config/services_test.yaml - App\Tests\Functional\Fixtures\PublisherStub: - decorates: mercure.hub.default.publisher + App\Tests\Functional\Fixtures\HubStub: + decorates: mercure.hub.default Debugging From 09b1c98830c5712052824df30375788a2eb37881 Mon Sep 17 00:00:00 2001 From: Guillaume Sarramegna <13528732+sarramegnag@users.noreply.github.com> Date: Tue, 30 Mar 2021 19:14:37 +0200 Subject: [PATCH 0653/5766] Standardize built-in normalizers lists --- serializer/normalizers.rst | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/serializer/normalizers.rst b/serializer/normalizers.rst index 50352e29c85..224fb809bcc 100644 --- a/serializer/normalizers.rst +++ b/serializer/normalizers.rst @@ -27,13 +27,13 @@ Symfony includes the following normalizers but you can also * :class:`Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer` to normalize PHP object using the :doc:`PropertyAccess component `; * :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeZoneNormalizer` - for :phpclass:`DateTimeZone` objects + for :phpclass:`DateTimeZone` objects; * :class:`Symfony\\Component\\Serializer\\Normalizer\\DateTimeNormalizer` for - objects implementing the :phpclass:`DateTimeInterface` interface + objects implementing the :phpclass:`DateTimeInterface` interface; * :class:`Symfony\\Component\\Serializer\\Normalizer\\DateIntervalNormalizer` - for :phpclass:`DateInterval` objects + for :phpclass:`DateInterval` objects; * :class:`Symfony\\Component\\Serializer\\Normalizer\\DataUriNormalizer` to - transform :phpclass:`SplFileInfo` objects in `Data URIs`_ + transform :phpclass:`SplFileInfo` objects in `Data URIs`_; * :class:`Symfony\\Component\\Serializer\\Normalizer\\CustomNormalizer` to normalize PHP object using an object that implements :class:`Symfony\\Component\\Serializer\\Normalizer\\NormalizableInterface`; @@ -43,11 +43,13 @@ Symfony includes the following normalizers but you can also * :class:`Symfony\\Component\\Serializer\\Normalizer\\GetSetMethodNormalizer` to normalize PHP object using the getter and setter methods of the object; * :class:`Symfony\\Component\\Serializer\\Normalizer\\PropertyNormalizer` to - normalize PHP object using `PHP reflection`_. -* :class:`Symfony\\Component\\Serializer\\Normalizer\\ConstraintViolationListNormalizer` for objects implementing the :class:`Symfony\\Component\\Validator\\ConstraintViolationListInterface` interface + normalize PHP object using `PHP reflection`_; +* :class:`Symfony\\Component\\Serializer\\Normalizer\\ConstraintViolationListNormalizer` for objects implementing the :class:`Symfony\\Component\\Validator\\ConstraintViolationListInterface` interface; * :class:`Symfony\\Component\\Serializer\\Normalizer\\ProblemNormalizer` for :class:`Symfony\\Component\\ErrorHandler\\Exception\\FlattenException` objects * :class:`Symfony\\Component\\Serializer\\Normalizer\\JsonSerializableNormalizer` - to deal with objects implementing the :phpclass:`JsonSerializable` interface + to deal with objects implementing the :phpclass:`JsonSerializable` interface; +* :class:`Symfony\\Component\\Serializer\\Normalizer\\UidNormalizer` converts objects that implement :class:`Symfony\\Component\\Uid\\AbstractUid` into strings and denormalizes uuid or ulid strings to :class:`Symfony\\Component\\Uid\\Uuid` or :class:`Symfony\\Component\\Uid\\Ulid`. + .. _`Data URIs`: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs .. _`PHP reflection`: https://php.net/manual/en/book.reflection.php From 6c728236ebf666002fb73fe9b5c53e6b65d3aeb9 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 6 Apr 2021 22:15:12 +0200 Subject: [PATCH 0654/5766] [HttpFoundation] Remove extra space --- components/http_foundation.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 980eb597c3b..0fa78dc6439 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -633,7 +633,7 @@ handling, switching to chunked encoding instead:: use Symfony\Component\HttpFoundation\BinaryFileResponse; use Symfony\Component\HttpFoundation\File\Stream; - $stream = new Stream('path/to/stream'); + $stream = new Stream('path/to/stream'); $response = new BinaryFileResponse($stream); .. note:: From 7388cc941f0c6bf084ecfe4de2cfb025fc00047b Mon Sep 17 00:00:00 2001 From: Nyholm Date: Tue, 9 Mar 2021 18:34:08 +0100 Subject: [PATCH 0655/5766] Init Runtime docs --- components/runtime.rst | 417 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 components/runtime.rst diff --git a/components/runtime.rst b/components/runtime.rst new file mode 100644 index 00000000000..760b10397a4 --- /dev/null +++ b/components/runtime.rst @@ -0,0 +1,417 @@ +.. index:: + single: Runtime + single: Components; Runtime + +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-FPM, ReactPHP, + Swoole etc without any changes. + +Installation +------------ + +.. code-block:: terminal + + $ composer require symfony/runtime + +.. include:: /components/require_autoload.rst.inc + +Usage +----- + +The Runtime component allows you to write front-controllers in a generic way +and with use of configuration you may change the behavior. Let's consider the +``public/index.php`` as an example. It will return a callable which will create +and return the application:: + + handle(Request::createFromGlobals())->send()``. + +To make a console application, the same bootstrap code would look like:: + + #!/usr/bin/env php + setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('Hello World'); + }); + + return $command; + }; + +``:class:`Symfony\\Component\\Console\\Application``` + Useful with console applications with more than one command. This will use the + :class:`Symfony\\Component\\Runtime\\Runner\\Symfony\\ConsoleApplicationRunner``.:: + + setCode(function (InputInterface $input, OutputInterface $output) { + $output->write('Hello World'); + }); + + $app = new Application(); + $app->add($command); + $app->setDefaultCommand('hello', true); + + return $app; + }; + +``:class:`Symfony\\Component\\Runtime\\RunnerInterface``` + The ``RuntimeInterface`` is a way to use a custom application with the + generic Runtime.:: + + '/var/task', + ]; + + require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; + + // ... + +The second way to pass an option to ``SymfonyRuntime::__construct()`` is to use +``extra.runtime.options`` in ``composer.json``. + +.. code-block:: json + + { + "require": { + "...": "..." + }, + "extra": { + "runtime": { + "options": { + "project_dir": "/var/task" + } + } + } + } + +.. note:: + + The environment variable ``APP_DEBUG`` has special support to easily + turn on and off debugging. + +Creating Your Own Runtime +------------------------- + +This is an advanced topic that describes the internals of the Runtime component. + +Using the runtime component will benefit maintainers because the bootstrap logic +could be versioned as a part of a normal package. If the application author decides +to use this component, the package maintainer of the Runtime class will have more +control and can fix bugs and add features. + +-- note:: + + Before Symfony 5.3, the boostrap logic was part of a Flex recipe. Since recipes + are rarely updated by users, bug patches would rarely be installed. + +The Runtime component is designed to be totally generic and able to run any application +outside of the global state in 6 steps: + + 1. The main entry point returns a callable (A) that wraps the application + 2. Callable (A) is passed to ``RuntimeInterface::getResolver()``, which returns a + ``ResolverInterface``. This resolver returns an array with the callable (A) + (or something that decorates the callable (A)) at index 0, and all its resolved + arguments at index 1. + 3. The callable A is invoked with its arguments, it will return an object that + represents the application (B). + 4. That object (B) is passed to ``RuntimeInterface::getRunner()``, which returns a + ``RunnerInterface``: an instance that knows how to "run" the object (B). + 5. The ``RunnerInterface::run($objectB)`` is executed and it returns the exit status + code as `int`. + 6. The PHP engine is exited with this status code. + +When creating a new runtime, there are two things to consider: First, what arguments +will the end user use? Second, what will the user's application look like? + +To create a runtime for ReactPHP, we see that no special arguments are typically +required. We will use the standard arguments provided by :class:`Symfony\\Component\\Runtime\\GenericRuntime` +by extending tha class. But a ReactPHP application will need some special logic +to run. That logic is added in a new class implementing :class:`Symfony\\Component\\Runtime\\RunnerInterface`:: + + use Psr\Http\Message\ServerRequestInterface; + use Symfony\Component\Runtime\RunnerInterface; + + class ReactPHPRunner implements RunnerInterface + { + private $application; + private $port; + + public function __construct(RequestHandlerInterface $application, int $port) + { + $this->application = $application; + $this->port = $port; + } + + public function run(): int + { + $application = $this->application; + $loop = \React\EventLoop\Factory::create(); + + $server = new \React\Http\Server($loop, function (ServerRequestInterface $request) use ($application) { + return $application->handle($request); + }); + + $socket = new \React\Socket\Server($this->port, $loop); + $server->listen($socket); + + $loop->run(); + + return 0; + } + } + +Now we should create a new :class:`Symfony\\Component\\Runtime\\RuntimeInterface` +that is using our ``ReactPHPRunner``:: + + use Symfony\Component\Runtime\GenericRuntime; + use Symfony\Component\Runtime\RunnerInterface; + + class ReactPHPRuntime extends GenericRuntime + { + private $port; + + public function __construct(array $options) + { + $this->port = $options['port'] ?? 8080; + parent::__construct($options); + } + + public function getRunner(?object $application): RunnerInterface + { + if ($application instanceof RequestHandlerInterface) { + return new ReactPHPRunner($application, $this->port); + } + + return parent::getRunner($application); + } + } + +The end user will now be able to create front controller like:: + + require_once dirname(__DIR__).'/vendor/autoload_runtime.php'; + + return function (array $context) { + return new Psr15Application(); + }; + + From 06414b72271a50303eaf138a8bc7c50b4ab0fdc2 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Fri, 12 Mar 2021 11:47:32 +0100 Subject: [PATCH 0656/5766] Apply suggestions from code review Co-authored-by: Oskar Stark --- components/runtime.rst | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/components/runtime.rst b/components/runtime.rst index 760b10397a4..86e3814ee0c 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -65,7 +65,7 @@ Selecting Runtimes The default Runtime is :class:`Symfony\\Component\\Runtime\\SymfonyRuntime`, it works excellent on most applications running with a webserver like Nginx and Apache, and PHP-FPM. You may change Runtime to :class:`Symfony\\Component\\Runtime\\GenericRuntime` -or a custom Runtime for Swoole or Aws Lambda. This can be done by specifying the +or a custom Runtime for Swoole or AWS Lambda. This can be done by specifying the Runtime class in the ``APP_RUNTIME`` environment variable or to specify the ``extra.runtime.class`` in ``composer.json``. @@ -82,8 +82,8 @@ Runtime class in the ``APP_RUNTIME`` environment variable or to specify the } } -Using SymfonyRuntime --------------------- +Using the SymfonyRuntime +------------------------ The :class:`Symfony\\Component\\Runtime\\RuntimeInterface` has two methods. One to get an instance of :class:`Symfony\\Component\\Runtime\\ResolverInterface` @@ -309,8 +309,8 @@ The second way to pass an option to ``SymfonyRuntime::__construct()`` is to use The environment variable ``APP_DEBUG`` has special support to easily turn on and off debugging. -Creating Your Own Runtime -------------------------- +Create Your Own Runtime +----------------------- This is an advanced topic that describes the internals of the Runtime component. @@ -319,7 +319,7 @@ could be versioned as a part of a normal package. If the application author deci to use this component, the package maintainer of the Runtime class will have more control and can fix bugs and add features. --- note:: +.. note:: Before Symfony 5.3, the boostrap logic was part of a Flex recipe. Since recipes are rarely updated by users, bug patches would rarely be installed. @@ -413,5 +413,3 @@ The end user will now be able to create front controller like:: return function (array $context) { return new Psr15Application(); }; - - From e7bacf17fae9eee8223b24a302bd1695ffefe913 Mon Sep 17 00:00:00 2001 From: Tobias Nyholm Date: Tue, 16 Mar 2021 08:57:48 +0100 Subject: [PATCH 0657/5766] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ondřej Frei <37588173+freiondrej@users.noreply.github.com> --- components/runtime.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/runtime.rst b/components/runtime.rst index 86e3814ee0c..9c868bdc05b 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -41,7 +41,7 @@ the autoload files since the component includes a composer plugin. The ``autoloa will instantiate a :class:`Symfony\\Component\\Runtime\\RuntimeInterface`, its job is to take the callable and resolve the arguments (``array $context``). Then it calls the callable to get the application ``App\Kernel``. At last it will run the application, -ie calling ``$kernel->handle(Request::createFromGlobals())->send()``. +i.e. calling ``$kernel->handle(Request::createFromGlobals())->send()``. To make a console application, the same bootstrap code would look like:: From 76de97372b3fde4f2472b836542649bdef30a1fe Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Mon, 5 Apr 2021 14:22:59 +0200 Subject: [PATCH 0658/5766] [#15081] Finish the new Runtime docs --- .doctor-rst.yaml | 1 + components/runtime.rst | 287 ++++++++++++++++++++++++++--------------- 2 files changed, 182 insertions(+), 106 deletions(-) diff --git a/.doctor-rst.yaml b/.doctor-rst.yaml index 61b56614a29..388147a8281 100644 --- a/.doctor-rst.yaml +++ b/.doctor-rst.yaml @@ -101,3 +101,4 @@ whitelist: - 'provides a ``loginUser()`` method to simulate logging in in your functional' - '.. code-block:: twig' - '.. versionadded:: 3.6' # MonologBundle + - '// bin/console' diff --git a/components/runtime.rst b/components/runtime.rst index 9c868bdc05b..ae962dd18cb 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -7,7 +7,11 @@ 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-FPM, ReactPHP, - Swoole etc without any changes. + Swoole, etc. without any changes. + +.. versionadded:: 5.3 + + The Runtime component was introduced in Symfony 5.3. Installation ------------ @@ -21,10 +25,10 @@ Installation Usage ----- -The Runtime component allows you to write front-controllers in a generic way -and with use of configuration you may change the behavior. Let's consider the -``public/index.php`` as an example. It will return a callable which will create -and return the application:: +The Runtime component abstracts most bootstrapping logic as so-called +*runtimes*, allowing you to write front-controllers in a generic way. +For instance, the Runtime component allows Symfony's ``public/index.php`` +to look like this:: handle(Request::createFromGlobals())->send()``. +So how does this front-controller work? At first, the special +``autoload_runtime.php`` is automatically created by the Composer plugin in +the component. This file runs the following logic: + +#. It instantiates a :class:`Symfony\\Component\\Runtime\\RuntimeInterface`; +#. The callable (returned in the file) is passed to the Runtime, whose job + is to resolve the arguments (in this example: ``array $content``); +#. Then, this callable is called to get the application (``App\Kernel``); +#. At last, the Runtime is used to run the application (i.e. calling + ``$kernel->handle(Request::createFromGlobals())->send()``). -To make a console application, the same bootstrap code would look like:: +To make a console application, the bootstrap code would look like:: #!/usr/bin/env php application; - $loop = \React\EventLoop\Factory::create(); + $loop = ReactFactory::create(); - $server = new \React\Http\Server($loop, function (ServerRequestInterface $request) use ($application) { - return $application->handle($request); - }); + // configure ReactPHP to correctly handle the PSR-15 application + $server = new ReactHttpServer( + $loop, + function (ServerRequestInterface $request) use ($application) { + return $application->handle($request); + } + ); - $socket = new \React\Socket\Server($this->port, $loop); + // start the ReactPHP server + $socket = new ReactSocketServer($this->port, $loop); $server->listen($socket); $loop->run(); @@ -380,8 +448,8 @@ to run. That logic is added in a new class implementing :class:`Symfony\\Compone } } -Now we should create a new :class:`Symfony\\Component\\Runtime\\RuntimeInterface` -that is using our ``ReactPHPRunner``:: +By extending the ``GenericRuntime``, you make sure that the application is +always using this ``ReactPHPRunner``:: use Symfony\Component\Runtime\GenericRuntime; use Symfony\Component\Runtime\RunnerInterface; @@ -402,14 +470,21 @@ that is using our ``ReactPHPRunner``:: return new ReactPHPRunner($application, $this->port); } + // if it's not a PSR-15 application, use the GenericRuntime to + // run the application (see "Resolvable Applications" above) return parent::getRunner($application); } } The end user will now be able to create front controller like:: + Date: Mon, 5 Apr 2021 18:55:04 +0200 Subject: [PATCH 0659/5766] Apply suggestions from code review Co-authored-by: Denis Brumann --- components/runtime.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/runtime.rst b/components/runtime.rst index ae962dd18cb..dc745adb5c6 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -45,7 +45,7 @@ So how does this front-controller work? At first, the special the component. This file runs the following logic: #. It instantiates a :class:`Symfony\\Component\\Runtime\\RuntimeInterface`; -#. The callable (returned in the file) is passed to the Runtime, whose job +#. The callable (returned by ``public/index.php``) is passed to the Runtime, whose job is to resolve the arguments (in this example: ``array $content``); #. Then, this callable is called to get the application (``App\Kernel``); #. At last, the Runtime is used to run the application (i.e. calling @@ -107,7 +107,7 @@ Use the ``APP_RUNTIME`` environment variable or by specifying the Using the Runtime ----------------- -A Runtime is resposible for passing arguments into the closure and run the +A Runtime is responsible for passing arguments into the closure and run the application returned by the closure. The :class:`Symfony\\Component\\Runtime\\SymfonyRuntime` and :class:`Symfony\\Component\\Runtime\\GenericRuntime` supports a number of arguments and different applications that you can use in your @@ -245,7 +245,7 @@ The ``GenericRuntime`` and ``SymfonyRuntime`` also support these generic applications: :class:`Symfony\\Component\\Runtime\\RunnerInterface` - The ``RuntimeInterface`` is a way to use a custom application with the + The ``RunnerInterface`` is a way to use a custom application with the generic Runtime:: Date: Wed, 7 Apr 2021 15:03:44 +0200 Subject: [PATCH 0660/5766] Fixed invalid configuration-block --- components/runtime.rst | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/components/runtime.rst b/components/runtime.rst index dc745adb5c6..75c84b0fe17 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -85,24 +85,18 @@ integrate with Swoole or AWS Lambda). Use the ``APP_RUNTIME`` environment variable or by specifying the ``extra.runtime.class`` in ``composer.json`` to change the Runtime class: -.. configuration-block:: - - .. code-block:: json +.. code-block:: json - { - "require": { - "...": "..." - }, - "extra": { - "runtime": { - "class": "Symfony\\Component\\Runtime\\GenericRuntime" - } + { + "require": { + "...": "..." + }, + "extra": { + "runtime": { + "class": "Symfony\\Component\\Runtime\\GenericRuntime" } } - - .. code-block:: env - - APP_RUNTIME="Symfony\\Component\\Runtime\\GenericRuntime" + } Using the Runtime ----------------- From f5ee47256a00b3f1544215bbd3b2633d2454baf1 Mon Sep 17 00:00:00 2001 From: Sylvain Fabre Date: Fri, 16 Oct 2020 13:17:42 +0200 Subject: [PATCH 0661/5766] [Messenger] Routing & Inheritance --- messenger.rst | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/messenger.rst b/messenger.rst index 52f125a3b61..8b977fcd283 100644 --- a/messenger.rst +++ b/messenger.rst @@ -314,6 +314,13 @@ to multiple transports: ], ]); +.. note:: + + If you configure routing for both a child and parent class, but rules + are used. E.g. if you have an ``SmsNotification`` object that extends + from ``Notification``, both the routing for ``Notification`` and + ``SmsNotification`` will be used. + Doctrine Entities in Messages ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ From 5c20fe3a94072394baec216a5d48947f010b66e1 Mon Sep 17 00:00:00 2001 From: Christian Flothmann Date: Wed, 7 Apr 2021 16:14:13 +0200 Subject: [PATCH 0662/5766] [Messenger] fix typo --- messenger.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messenger.rst b/messenger.rst index 8b977fcd283..70944b9a2d0 100644 --- a/messenger.rst +++ b/messenger.rst @@ -316,7 +316,7 @@ to multiple transports: .. note:: - If you configure routing for both a child and parent class, but rules + If you configure routing for both a child and parent class, both rules are used. E.g. if you have an ``SmsNotification`` object that extends from ``Notification``, both the routing for ``Notification`` and ``SmsNotification`` will be used. From 5a8ce041c96a52be437f4333cf36c9b0c2c716ef Mon Sep 17 00:00:00 2001 From: Carlos Pereira De Amorim Date: Thu, 9 Jul 2020 12:50:34 +0200 Subject: [PATCH 0663/5766] Added explaination on context in events and initial marking --- workflow.rst | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/workflow.rst b/workflow.rst index 048ea2c003a..bd36eb49014 100644 --- a/workflow.rst +++ b/workflow.rst @@ -381,11 +381,36 @@ order: * ``workflow.[workflow name].announce`` * ``workflow.[workflow name].announce.[transition name]`` + You can avoid triggering those events by using the context:: + + $workflow->apply($subject, $transitionName, [Workflow::DISABLE_ANNOUNCE_EVENT => true]); + + .. versionadded:: 5.1 + + The ``Workflow::DISABLE_ANNOUNCE_EVENT`` constant was introduced in Symfony 5.1. + + .. versionadded:: 5.2 + + In Symfony 5.2, the context is accessible in all events:: + + // $context must be an array + $context = ['context_key' => 'context_value']; + $workflow->apply($subject, $transitionName, $context); + + // in an event listener + $context = $event->getContext(); // returns ['context'] + .. note:: The leaving and entering events are triggered even for transitions that stay in same place. +.. note:: + + If you initialize the marking by calling ``$workflow->getMarking($object);``, + then the ``workflow.[workflow_name].entered.[initial_place_name]`` event will + be called with the default context (``Workflow::DEFAULT_INITIAL_CONTEXT``). + Here is an example of how to enable logging for every time a "blog_publishing" workflow leaves a place:: From 61c6a2efe64af747ffcb825e26fdc45d281c37e5 Mon Sep 17 00:00:00 2001 From: Andrius Date: Mon, 14 Dec 2020 00:18:28 +0200 Subject: [PATCH 0664/5766] Update login_link.rst --- security/login_link.rst | 82 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/security/login_link.rst b/security/login_link.rst index b92dd694178..e43edbd7a22 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -654,3 +654,85 @@ user create this POST request (e.g. by clicking a button):: {% endblock %} + +Customizing the Success Handler +............................... + +To customize, how the success handler behaves, create your own ``AuthenticationSuccessHandler``:: + + // src/Security/Authentication/AuthenticationSuccessHandler.php + namespace App\Security\Authentication; + + use Symfony\Component\HttpFoundation\JsonResponse; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\Security\Core\Authentication\Token\TokenInterface; + use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface; + + class AuthenticationSuccessHandler implements AuthenticationSuccessHandlerInterface + { + public function onAuthenticationSuccess(Request $request, TokenInterface $token): JsonResponse + { + // Example use case: Create API token for Guard Authentication. + $user = $token->getUser(); // Returns string|\Stringable|UserInterface - depends on your implementation. + + $userApiToken = $user->getApiToken(); + + return new JsonResponse(['apiToken' => 'userApiToken']); + } + } + +Modify the configuration and use your handler for the ``success_handler`` key: + +.. configuration-block:: + + .. code-block:: yaml + + # config/packages/security.yaml + security: + firewalls: + main: + login_link: + check_route: login_check + lifetime: 600 + max_uses: 1 + success_handler: App\Security\Authentication\AuthenticationSuccessHandler + + .. code-block:: xml + + + + + + + + + + + + + .. code-block:: php + + // config/packages/security.php + $container->loadFromExtension('security', [ + 'firewalls' => [ + 'main' => [ + 'login_link' => [ + 'check_route' => 'login_check', + 'lifetime' => 600, + 'max_uses' => 1, + 'success_handler' => 'App\Security\Authentication\AuthenticationSuccessHandler', + ], + ], + ], + ]); From 8680b94bd703f414735f25c18b3515a3915bcf8b Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 7 Apr 2021 16:56:32 +0200 Subject: [PATCH 0665/5766] [#14700] Minor rewording --- security/login_link.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/security/login_link.rst b/security/login_link.rst index e43edbd7a22..d3c7b0e4c23 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -656,9 +656,12 @@ user create this POST request (e.g. by clicking a button):: {% endblock %} Customizing the Success Handler -............................... +------------------------------- -To customize, how the success handler behaves, create your own ``AuthenticationSuccessHandler``:: +Sometimes, the default success handling does not fit your use-case (e.g. +when you need to generate and return an API key). To customize how the +success handler behaves, create your own +:class:`Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface`:: // src/Security/Authentication/AuthenticationSuccessHandler.php namespace App\Security\Authentication; @@ -672,16 +675,14 @@ To customize, how the success handler behaves, create your own ``AuthenticationS { public function onAuthenticationSuccess(Request $request, TokenInterface $token): JsonResponse { - // Example use case: Create API token for Guard Authentication. - $user = $token->getUser(); // Returns string|\Stringable|UserInterface - depends on your implementation. - + $user = $token->getUser(); $userApiToken = $user->getApiToken(); return new JsonResponse(['apiToken' => 'userApiToken']); } } -Modify the configuration and use your handler for the ``success_handler`` key: +Then, configure this service ID as the ``success_handler``: .. configuration-block:: @@ -715,7 +716,7 @@ Modify the configuration and use your handler for the ``success_handler`` key: check-post-only="true" max-uses="1" lifetime="600" - success_handler="App\Security\Authentication\AuthenticationSuccessHandler" + success-handler="App\Security\Authentication\AuthenticationSuccessHandler" /> @@ -724,6 +725,8 @@ Modify the configuration and use your handler for the ``success_handler`` key: .. code-block:: php // config/packages/security.php + use App\Security\Authentication\AuthenticationSuccessHandler; + $container->loadFromExtension('security', [ 'firewalls' => [ 'main' => [ @@ -731,7 +734,7 @@ Modify the configuration and use your handler for the ``success_handler`` key: 'check_route' => 'login_check', 'lifetime' => 600, 'max_uses' => 1, - 'success_handler' => 'App\Security\Authentication\AuthenticationSuccessHandler', + 'success_handler' => AuthenticationSuccessHandler::class, ], ], ], From e16bc4ea4180381e515095f898163faeeba04397 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 7 Apr 2021 17:02:08 +0200 Subject: [PATCH 0666/5766] [#14728] Be explicit about the double 's' --- 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 bed064679e4..0845b3bcb96 100644 --- a/components/cache/adapters/redis_adapter.rst +++ b/components/cache/adapters/redis_adapter.rst @@ -63,7 +63,7 @@ helper method allows creating and configuring the Redis client class instance us 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``. +replaced by ``rediss`` (the second ``s`` means "secure"). .. note:: From 1834da9e971aa71870ba2fc66417d0f4ae05fc24 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Tue, 23 Feb 2021 18:57:23 +0100 Subject: [PATCH 0667/5766] Update data_collector.rst I removed the DataCollector class import because it has been replaced with the AbstractDataCollector class. --- profiler/data_collector.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/profiler/data_collector.rst b/profiler/data_collector.rst index 6e53fd5203d..ef377c47974 100644 --- a/profiler/data_collector.rst +++ b/profiler/data_collector.rst @@ -31,7 +31,6 @@ request:: use Symfony\Bundle\FrameworkBundle\DataCollector\AbstractDataCollector; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; - use Symfony\Component\HttpKernel\DataCollector\DataCollector; class RequestCollector extends AbstractDataCollector { From 55edd4857e5023321ba0143bb7b1dcc27ad8870c Mon Sep 17 00:00:00 2001 From: Thibault RICHARD Date: Sun, 28 Feb 2021 18:27:21 +0100 Subject: [PATCH 0668/5766] [Messenger] Add options for PostgreSQL LISTEN/NOTIFY support --- messenger.rst | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/messenger.rst b/messenger.rst index abf45612374..ee98b1f2e84 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1074,6 +1074,12 @@ a table named ``messenger_messages``. Or, to create the table yourself, set the ``auto_setup`` option to ``false`` and :ref:`generate a migration `. +.. 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: ================== ===================================== ====================== @@ -1093,11 +1099,28 @@ auto_setup Whether the table should be created automatically during send / get. true ================== ===================================== ====================== -.. caution:: +.. versionadded:: 5.1 - 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 ability to leverage PostgreSQL's LISTEN/NOTIFY was introduced + in Symfony 5.1. + +When using PostgreSQL, you have access to the following options to leverage +the `LISTEN/NOTIFY`_ feature. This allow for a more performant approach +than the default polling behavior of the Doctrine transport because +PostgreSQL will directly notify the workers when a new message is inserted +in the table. + +======================= ===================================== ====================== +Option Description Default +======================= ===================================== ====================== +use_notify Whether to use LISTEN/NOTIFY. true +check_delayed_interval The interval to check for delayed 1000 + messages, in milliseconds. + Set to 0 to disable checks. +get_notify_timeout The length of time to wait for a 0 + response when calling + ``PDO::pgsqlGetNotify```, in milliseconds. +======================= ========================================== ====================== Beanstalkd Transport ~~~~~~~~~~~~~~~~~~~~ @@ -1971,3 +1994,4 @@ Learn more .. _`Long polling`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-short-and-long-polling.html .. _`Visibility Timeout`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-visibility-timeout.html .. _`FIFO queue`: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html +.. _`LISTEN/NOTIFY`: https://www.postgresql.org/docs/current/sql-notify.html From bd0073371144f4664597be836ecd523529edd5cb Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 7 Apr 2021 17:23:37 +0200 Subject: [PATCH 0669/5766] Fixed table markup --- messenger.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/messenger.rst b/messenger.rst index ee98b1f2e84..c97efd5210f 100644 --- a/messenger.rst +++ b/messenger.rst @@ -1110,9 +1110,9 @@ than the default polling behavior of the Doctrine transport because PostgreSQL will directly notify the workers when a new message is inserted in the table. -======================= ===================================== ====================== +======================= ========================================== ====================== Option Description Default -======================= ===================================== ====================== +======================= ========================================== ====================== use_notify Whether to use LISTEN/NOTIFY. true check_delayed_interval The interval to check for delayed 1000 messages, in milliseconds. From 91096d5fbb61cb3209e97524732191062bc11a9e Mon Sep 17 00:00:00 2001 From: Jesse Rushlow Date: Fri, 26 Feb 2021 19:05:50 -0500 Subject: [PATCH 0670/5766] Add serialize reference --- reference/twig_reference.rst | 23 +++++++++++++++++++++++ serializer.rst | 13 +++++++++++++ 2 files changed, 36 insertions(+) diff --git a/reference/twig_reference.rst b/reference/twig_reference.rst index 270c9c678c8..e4991845096 100644 --- a/reference/twig_reference.rst +++ b/reference/twig_reference.rst @@ -558,6 +558,29 @@ project's root directory: If the given file path is out of the project directory, a ``null`` value will be returned. +serialize +~~~~~~~~~ + +.. code-block:: twig + + {{ object|serialize(format = 'json', context = []) }} + +``object`` + **type**: ``mixed`` + +``format`` *(optional)* + **type**: ``string`` + +``context`` *(optional)* + **type**: ``array`` + +.. versionadded:: 5.3 + + The ``serialize`` filter was introduced in Symfony 5.3. + +Accepts any data that can be serialized by the :doc:`Serializer component ` +and returns a serialized string in the specified ``format``. + .. _reference-twig-tags: Tags diff --git a/serializer.rst b/serializer.rst index b4dd7e03d52..7d526ae46bc 100644 --- a/serializer.rst +++ b/serializer.rst @@ -41,6 +41,19 @@ you need it or it can be used in a controller:: } } +Or you can use the ``serialize`` Twig filter in a template: + +.. code-block:: twig + + {{ object|serialize(format = 'json') }} + +See the :doc:`twig reference ` for +more information. + +.. versionadded:: 5.3 + + A ``serialize`` filter was introduced in Symfony 5.3 that uses the Serializer component. + Adding Normalizers and Encoders ------------------------------- From 367efdb0ea5ef8648d857660623a7d59701ce36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20G=C3=B6kalp?= Date: Sat, 30 Jan 2021 18:31:32 +0300 Subject: [PATCH 0671/5766] JsonResponse content updated --- components/http_foundation.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 0fa78dc6439..449d29ea0f0 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -668,9 +668,11 @@ class, which can make this even easier:: // if you know the data to send when creating the response $response = new JsonResponse(['data' => 123]); - // if you don't know the data to send when creating the response + // if you don't know the data to send or if you want to customize the encoding options $response = new JsonResponse(); // ... + // configure any custom encoding options (if needed, it must be called before "setData()") + //$response->setEncodingOptions(JsonResponse::DEFAULT_ENCODING_OPTIONS | \JSON_PRESERVE_ZERO_FRACTION); $response->setData(['data' => 123]); // if the data to send is already encoded in JSON From 77089fa264786081748cd1d90c331784c2882b50 Mon Sep 17 00:00:00 2001 From: Nate Wiebe Date: Fri, 5 Mar 2021 15:35:03 -0500 Subject: [PATCH 0672/5766] Update docs relating to translation extraction --- translation.rst | 5 +++++ translation/debug.rst | 7 ++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/translation.rst b/translation.rst index 8153d000531..b8e61251893 100644 --- a/translation.rst +++ b/translation.rst @@ -292,6 +292,8 @@ To manage these situations, Symfony follows the `ICU MessageFormat`_ syntax by using PHP's :phpclass:`MessageFormatter` class. Read more about this in :doc:`/translation/message_format`. +.. _translatable-objects: + Translatable Objects -------------------- @@ -386,6 +388,9 @@ The ``translation:update`` command looks for missing translations in: :ref:`twig.paths ` config options); * Any PHP file/class that injects or :doc:`autowires ` the ``translator`` service and makes calls to the ``trans()`` method. +* Any PHP file/class stored in the ``src/`` directory that creates + :ref:`translatable-objects` using the constructor or the ``t()`` method or calls + the ``trans()`` method. .. _translation-resource-locations: diff --git a/translation/debug.rst b/translation/debug.rst index 74e52783245..c511d7c9777 100644 --- a/translation/debug.rst +++ b/translation/debug.rst @@ -19,9 +19,10 @@ command helps you to find these missing or unused translation messages templates .. caution:: - The extractors can't find messages translated outside templates, like form - labels or controllers. Dynamic translations using variables or expressions - in templates are not detected either: + The extractors can't find messages translated outside templates (like form + labels or controllers) unless using :ref:`translatable-objects` or calling + the ``trans()`` method on a translator. Dynamic translations using variables + or expressions in templates are not detected either: .. code-block:: twig From dc9e6134441517ba520d30c060aeb70ed17e4a85 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Wed, 7 Apr 2021 17:50:50 +0200 Subject: [PATCH 0673/5766] [#15063] Added versionaddeds --- translation.rst | 5 +++++ translation/debug.rst | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/translation.rst b/translation.rst index b1e1cb619c0..4330e171c0a 100644 --- a/translation.rst +++ b/translation.rst @@ -468,6 +468,11 @@ The ``translation:update`` command looks for missing translations in: :ref:`translatable-objects` using the constructor or the ``t()`` method or calls the ``trans()`` method. +.. versionadded:: 5.3 + + Support for extracting Translatable objects has been introduced in + Symfony 5.3. + .. _translation-resource-locations: Translation Resource/File Names and Locations diff --git a/translation/debug.rst b/translation/debug.rst index c511d7c9777..cc14945dc9d 100644 --- a/translation/debug.rst +++ b/translation/debug.rst @@ -21,8 +21,9 @@ command helps you to find these missing or unused translation messages templates The extractors can't find messages translated outside templates (like form labels or controllers) unless using :ref:`translatable-objects` or calling - the ``trans()`` method on a translator. Dynamic translations using variables - or expressions in templates are not detected either: + the ``trans()`` method on a translator (since Symfony 5.3). Dynamic + translations using variables or expressions in templates are not + detected either: .. code-block:: twig From 90e6580276ba5e07a002b453c069f093daac6731 Mon Sep 17 00:00:00 2001 From: AntoineRoue <64271860+AntoineRoue@users.noreply.github.com> Date: Tue, 6 Apr 2021 20:57:34 +0200 Subject: [PATCH 0674/5766] Update framework.rst This value was not changed with https://github.com/symfony/symfony/pull/30390 --- 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 ada92f8f25e..63e0ca7ad20 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1221,7 +1221,7 @@ The value can be one of: ``true`` Throw an exception when the requirements are not met; ``false`` - Disable exceptions when the requirements are not met and return ``null`` + Disable exceptions when the requirements are not met and return ``''`` instead; ``null`` Disable checking the requirements (thus, match the route even when the From bdb8a80215972b4b85cbb957fb70241e9391f3e8 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 8 Apr 2021 11:48:23 +0200 Subject: [PATCH 0675/5766] Rename LightSms package Follows https://github.com/symfony/symfony/pull/40736 --- notifier.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notifier.rst b/notifier.rst index b5c9d8eda80..488ed973a5a 100644 --- a/notifier.rst +++ b/notifier.rst @@ -64,7 +64,7 @@ FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@defa GatewayApi ``symfony/gatewayapi-notifier`` ``gatewayapi://TOKEN@default?from=FROM`` Infobip ``symfony/infobip-notifier`` ``infobip://AUTH_TOKEN@HOST?from=FROM`` Iqsms ``symfony/iqsms-notifier`` ``iqsms://LOGIN:PASSWORD@default?from=FROM`` -LightSMS ``symfony/lightsms-notifier`` ``lightsms://LOGIN:TOKEN@default?from=PHONE`` +LightSms ``symfony/light-sms-notifier`` ``lightsms://LOGIN:TOKEN@default?from=PHONE`` Mobyt ``symfony/mobyt-notifier`` ``mobyt://USER_KEY:ACCESS_TOKEN@default?from=FROM`` Nexmo ``symfony/nexmo-notifier`` ``nexmo://KEY:SECRET@default?from=FROM`` Octopush ``symfony/octopush-notifier`` ``octopush://USERLOGIN:APIKEY@default?from=FROM&type=TYPE`` @@ -86,7 +86,7 @@ Twilio ``symfony/twilio-notifier`` ``twilio://SID:TOKEN@default?from= .. versionadded:: 5.3 - The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell, SpotHit, FakeSms and LightSMS + The Iqsms, GatewayApi, Octopush, AllMySms, Clickatell, SpotHit, FakeSms and LightSms integrations were introduced in Symfony 5.3. To enable a texter, add the correct DSN in your ``.env`` file and From 2204e13626a8a06c78654de002601355b616f134 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 8 Apr 2021 12:34:13 +0200 Subject: [PATCH 0676/5766] Remove variable --- notifier.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/notifier.rst b/notifier.rst index b5c9d8eda80..987afd08f8a 100644 --- a/notifier.rst +++ b/notifier.rst @@ -155,7 +155,7 @@ Service Package DSN Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://MAILER_SERVICE_ID?to=TO&from=FROM`` Firebase ``symfony/firebase-notifier`` ``firebase://USERNAME:PASSWORD@default`` -Gitter ``symfony/gitter-notifier`` ``GITTER_DSN=gitter://TOKEN@default?room_id=ROOM_ID`` +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`` LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` From 9e1e0a906038a705bfe377706b95656873120df7 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Tue, 6 Apr 2021 14:23:37 +0200 Subject: [PATCH 0677/5766] [Notifier] Add MicrosoftTeams --- notifier.rst | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/notifier.rst b/notifier.rst index e07794be445..b260b58b58a 100644 --- a/notifier.rst +++ b/notifier.rst @@ -149,22 +149,23 @@ 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 -========== ================================ =========================================================================== -Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` -FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://MAILER_SERVICE_ID?to=TO&from=FROM`` -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`` -LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` -Mattermost ``symfony/mattermost-notifier`` ``mattermost://ACCESS_TOKEN@HOST/PATH?channel=CHANNEL`` -Mercure ``symfony/mercure-notifier`` ``mercure://HUB_ID?topic=TOPIC`` -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`` -Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL`` -========== ================================ =========================================================================== +============== ==================================== =========================================================================== +Service Package DSN +============== ==================================== =========================================================================== +Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` +FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://MAILER_SERVICE_ID?to=TO&from=FROM`` +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`` +LinkedIn ``symfony/linked-in-notifier`` ``linkedin://TOKEN:USER_ID@default`` +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`` +Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel=CHANNEL`` +============== ==================================== =========================================================================== .. versionadded:: 5.1 @@ -179,7 +180,7 @@ Zulip ``symfony/zulip-notifier`` ``zulip://EMAIL:TOKEN@HOST?channel .. versionadded:: 5.3 - The Gitter, Mercure and FakeChat integrations were introduced in Symfony 5.3. + The Gitter, Mercure, FakeChat and Microsoft Teams integrations were introduced in Symfony 5.3. Chatters are configured using the ``chatter_transports`` setting: From 0c57c73506ccc7663f618cfe69766cdd3f724fa4 Mon Sep 17 00:00:00 2001 From: Wouter de Jong Date: Thu, 8 Apr 2021 13:16:41 +0200 Subject: [PATCH 0678/5766] Add troubleshooting for parallel merges to maintainer guide --- _build/maintainer_guide.rst | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/_build/maintainer_guide.rst b/_build/maintainer_guide.rst index f5913a8e811..8485bc3191d 100644 --- a/_build/maintainer_guide.rst +++ b/_build/maintainer_guide.rst @@ -352,6 +352,26 @@ forgot to merge as ``gh merge NNNNN -s 5.1`` to change the merge branch. Solutio $ git merge 5.1 $ ... +Merging while the target branch changed +....................................... + +Sometimes, someone else merges a PR in ``5.x`` at the same time as you are +doing it. In these cases, ``gh merge ...`` failes to push. Solve this by +resetting your local branch and restarting the merge: + +.. code-block:: terminal + + $ gh merge ... + # this failed + + # fetch the updated 5.x branch from GitHub + $ git fetch upstream + $ git checkout 5.x + $ git reset --hard upstream/5.x + + # restart the merge + $ gh merge ... + .. _`symfony/symfony-docs`: https://github.com/symfony/symfony-docs .. _`Symfony Docs team`: https://github.com/orgs/symfony/teams/team-symfony-docs .. _`Symfony's respectful review comments`: https://symfony.com/doc/current/contributing/community/review-comments.html From f68ec043011cc63df61541f5758dd70b198117e5 Mon Sep 17 00:00:00 2001 From: Matthew Setter Date: Thu, 8 Apr 2021 09:54:26 +0200 Subject: [PATCH 0679/5766] Corrected minor grammar mistake in the routing docs --- routing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routing.rst b/routing.rst index bf971924311..bd3697451a4 100644 --- a/routing.rst +++ b/routing.rst @@ -2216,8 +2216,8 @@ Stateless Routes The ``stateless`` option was introduced in Symfony 5.1. Sometimes, when an HTTP response should be cached, it is important to ensure -that can happen. However, whenever session is started during a request, Symfony -turns the response into a private non-cacheable response. +that can happen. However, whenever a session is started during a request, +Symfony turns the response into a private non-cacheable response. For details, see :doc:`/http_cache`. From c8deb3d013d486e99016d0918cd125180dcac555 Mon Sep 17 00:00:00 2001 From: Cristoforo Cervino Date: Tue, 16 Mar 2021 14:19:06 +0100 Subject: [PATCH 0680/5766] add form_attr option doc --- reference/forms/types/form.rst | 3 +++ .../forms/types/options/form_attr.rst.inc | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 reference/forms/types/options/form_attr.rst.inc diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index 9e1a5d47227..43a5a398bdf 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -19,6 +19,7 @@ on all types for which ``FormType`` is the parent. | | - `error_bubbling`_ | | | - `error_mapping`_ | | | - `extra_fields_message`_ | +| | - `form_attr`_ | | | - `help`_ | | | - `help_attr`_ | | | - `help_html`_ | @@ -116,6 +117,8 @@ The actual default value of this option depends on other field options: .. include:: /reference/forms/types/options/extra_fields_message.rst.inc +.. include:: /reference/forms/types/options/form_attr.rst.inc + .. include:: /reference/forms/types/options/help.rst.inc .. include:: /reference/forms/types/options/help_attr.rst.inc diff --git a/reference/forms/types/options/form_attr.rst.inc b/reference/forms/types/options/form_attr.rst.inc new file mode 100644 index 00000000000..bb6cb1ca4fd --- /dev/null +++ b/reference/forms/types/options/form_attr.rst.inc @@ -0,0 +1,20 @@ +``form_attr`` +~~~~~~~~~~~~~ + +**type**: ``boolean`` or ``string`` **default**: ``false`` + +When ``true`` and used on a form element, it adds a `"form" attribute`_ to its HTML field representation with +its HTML form id. By doing this, a form element can be rendered outside the HTML form while still working as expected:: + + $builder->add('body', TextareaType::class, [ + 'form_attr' => true, + ]); + +This can be useful when you need to solve nested form problems. +You can also set this to ``true`` on a root form to automatically set the "form" attribute on all its children. + +.. note:: + + When the root form has no ID, ``form_attr`` is required to be a string identifier to be used as the form ID. + +.. _`"form" attribute`: https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#attr-fae-form From d0d10f6f8b7faf5c1a19aa6dc2da0a671fcce427 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Sat, 3 Apr 2021 19:04:59 +0200 Subject: [PATCH 0681/5766] Adding typehint ...from https://symfony.com/doc/current/security/guard_authentication.html#the-guard-authenticator-methods --- security/guard_authentication.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/guard_authentication.rst b/security/guard_authentication.rst index 6949d008d8d..4a406239aed 100644 --- a/security/guard_authentication.rst +++ b/security/guard_authentication.rst @@ -187,7 +187,7 @@ This requires you to implement several methods:: return true; } - public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey) + public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $providerKey) { // on success, let the request continue return null; From 5cdeedc73d7b32d48fce220b5bea5f57395658bc Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Fri, 9 Apr 2021 08:55:04 +0200 Subject: [PATCH 0682/5766] Fix: Build --- security/login_link.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/login_link.rst b/security/login_link.rst index d3c7b0e4c23..456cfc706c6 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -661,7 +661,7 @@ Customizing the Success Handler Sometimes, the default success handling does not fit your use-case (e.g. when you need to generate and return an API key). To customize how the success handler behaves, create your own -:class:`Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface`:: +:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationSuccessHandlerInterface`:: // src/Security/Authentication/AuthenticationSuccessHandler.php namespace App\Security\Authentication; From 3833bbac0e74d4a948e4bcd0cc80b0a42ddc65c3 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Thu, 8 Apr 2021 14:40:46 +0200 Subject: [PATCH 0683/5766] [Notifier] [FakeSms] [FakeChat] Update DSN --- notifier.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/notifier.rst b/notifier.rst index b260b58b58a..305c433f53d 100644 --- a/notifier.rst +++ b/notifier.rst @@ -59,7 +59,7 @@ Service Package DSN AllMySms ``symfony/allmysms-notifier`` ``allmysms://LOGIN:APIKEY@default?from=FROM`` Clickatell ``symfony/clickatell-notifier`` ``clickatell://ACCESS_TOKEN@default?from=FROM`` Esendex ``symfony/esendex-notifier`` ``esendex://USER_NAME:PASSWORD@default?accountreference=ACCOUNT_REFERENCE&from=FROM`` -FakeSms ``symfony/fake-sms-notifier`` ``fakesms+email://MAILER_SERVICE_ID?to=TO&from=FROM`` +FakeSms ``symfony/fake-sms-notifier`` ``fakesms+email://default?to=TO&from=FROM`` FreeMobile ``symfony/free-mobile-notifier`` ``freemobile://LOGIN:PASSWORD@default?phone=PHONE`` GatewayApi ``symfony/gatewayapi-notifier`` ``gatewayapi://TOKEN@default?from=FROM`` Infobip ``symfony/infobip-notifier`` ``infobip://AUTH_TOKEN@HOST?from=FROM`` @@ -153,7 +153,7 @@ integration with these chat services: Service Package DSN ============== ==================================== =========================================================================== Discord ``symfony/discord-notifier`` ``discord://TOKEN@default?webhook_id=ID`` -FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://MAILER_SERVICE_ID?to=TO&from=FROM`` +FakeChat ``symfony/fake-chat-notifier`` ``fakechat+email://default?to=TO&from=FROM`` 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`` From 9a69cac3322dc410d4bbfb2a5f53d33f332de1d7 Mon Sep 17 00:00:00 2001 From: Nyholm Date: Thu, 25 Feb 2021 09:01:54 +0100 Subject: [PATCH 0684/5766] [Intl] Remove documentation about deprecated code --- components/intl.rst | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/components/intl.rst b/components/intl.rst index cb120034615..5331097be01 100644 --- a/components/intl.rst +++ b/components/intl.rst @@ -6,12 +6,11 @@ The Intl Component ================== This component provides access to the localization data of the `ICU library`_. - It also provides a PHP replacement layer for the C `intl extension`_. .. caution:: The replacement layer is limited to the ``en`` locale. If you want to use - other locales, you should `install the intl extension`_. There is no conflict + other locales, you should `install the intl extension`_. There is no conflict between the two because, even if you use the extension, this package can still be useful to access the ICU data. @@ -30,30 +29,6 @@ Installation .. include:: /components/require_autoload.rst.inc -If you install the component via Composer, the following classes and functions -of the intl extension will be automatically provided if the intl extension is -not loaded: - -* :phpclass:`Collator` -* :phpclass:`IntlDateFormatter` -* :phpclass:`Locale` -* :phpclass:`NumberFormatter` -* :phpfunction:`intl_error_name` -* :phpfunction:`intl_is_failure` -* :phpfunction:`intl_get_error_code` -* :phpfunction:`intl_get_error_message` - -When the intl extension is not available, the following classes are used to -replace the intl classes: - -* :class:`Symfony\\Component\\Intl\\Collator\\Collator` -* :class:`Symfony\\Component\\Intl\\DateFormatter\\IntlDateFormatter` -* :class:`Symfony\\Component\\Intl\\Locale\\Locale` -* :class:`Symfony\\Component\\Intl\\NumberFormatter\\NumberFormatter` -* :class:`Symfony\\Component\\Intl\\Globals\\IntlGlobals` - -Composer automatically exposes these classes in the global namespace. - Accessing ICU Data ------------------ @@ -211,9 +186,9 @@ Locales ~~~~~~~ A locale is the combination of a language, a region and some parameters that -define the interface preferences of the user. For example, "Chinese" is the -language and ``zh_Hans_MO`` is the locale for "Chinese" (language) + "Simplified" -(script) + "Macau SAR China" (region). The ``Locales`` class provides access to +define the interface preferences of the user. For example, "Chinese" is the +language and ``zh_Hans_MO`` is the locale for "Chinese" (language) + "Simplified" +(script) + "Macau SAR China" (region). The ``Locales`` class provides access to the name of all locales:: use Symfony\Component\Intl\Locales; @@ -375,7 +350,6 @@ Learn more /reference/forms/types/locale /reference/forms/types/timezone -.. _intl extension: https://www.php.net/manual/en/book.intl.php .. _install the intl extension: https://www.php.net/manual/en/intl.setup.php .. _ICU library: http://site.icu-project.org/ .. _`Unicode ISO 15924 Registry`: https://www.unicode.org/iso15924/iso15924-codes.html From f9c37de16ef72f750eac88ec93feb9c1a6f893ca Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 9 Apr 2021 10:38:39 +0200 Subject: [PATCH 0685/5766] [Serializer] Document the csv_end_of_line option --- components/serializer.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/serializer.rst b/components/serializer.rst index 580f55aa613..6eac8eebd51 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -984,6 +984,8 @@ Option Description D ``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`` Sets the escape character (at most one character) empty string ``csv_key_separator`` Sets the separator for array's keys during its ``.`` flattening @@ -1000,6 +1002,10 @@ Option Description D ``output_utf8_bom`` Outputs special `UTF-8 BOM`_ along with encoded data ``false`` ======================= ===================================================== ========================== +.. versionadded:: 5.3 + + The ``csv_end_of_line`` option was introduced in Symfony 5.3. + The ``XmlEncoder`` ~~~~~~~~~~~~~~~~~~ From 60d3a1b335040c55dbaa7e2db485e15515ef8766 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 11 Apr 2021 13:12:35 +0200 Subject: [PATCH 0686/5766] [HttpFoundation] Fix IpUtils example This PR fixes a small bug in the IpUtils class name. --- components/http_foundation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 449d29ea0f0..cbb1742dad1 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -331,11 +331,11 @@ analysis purposes. Use the ``anonymize()`` method from the use Symfony\Component\HttpFoundation\IpUtils; $ipv4 = '123.234.235.236'; - $anonymousIpv4 = IPUtils::anonymize($ipv4); + $anonymousIpv4 = IpUtils::anonymize($ipv4); // $anonymousIpv4 = '123.234.235.0' $ipv6 = '2a01:198:603:10:396e:4789:8e99:890f'; - $anonymousIpv6 = IPUtils::anonymize($ipv6); + $anonymousIpv6 = IpUtils::anonymize($ipv6); // $anonymousIpv6 = '2a01:198:603:10::' Accessing other Data From 2a39702c83eb46fc496f487bb1955639a737a119 Mon Sep 17 00:00:00 2001 From: Sebastian Paczkowski <74934099+sebpacz@users.noreply.github.com> Date: Sun, 11 Apr 2021 13:23:04 +0200 Subject: [PATCH 0687/5766] [HttpFoundation] Minor fixes --- components/http_foundation.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/http_foundation.rst b/components/http_foundation.rst index 3699eb17258..410fcd2272a 100644 --- a/components/http_foundation.rst +++ b/components/http_foundation.rst @@ -190,7 +190,7 @@ Finally, the raw data sent with the request body can be accessed using $content = $request->getContent(); -For instance, this may be useful to process a XML string sent to the +For instance, this may be useful to process an XML string sent to the application by a remote service using the HTTP POST method. If the request body is a JSON string, it can be accessed using @@ -519,7 +519,7 @@ call:: 's_maxage' => 600, 'immutable' => true, 'last_modified' => new \DateTime(), - 'etag' => 'abcdef' + 'etag' => 'abcdef', ]); .. versionadded:: 5.1 From cc800ddfb486ff60d8ea2a8cf603f9657821f5ea Mon Sep 17 00:00:00 2001 From: Martin Bens Date: Mon, 12 Apr 2021 01:18:39 +0200 Subject: [PATCH 0688/5766] Tip added to explain how to use HttpClient options in BrowserKit requests. --- components/browser_kit.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/components/browser_kit.rst b/components/browser_kit.rst index 76c0e33d5e1..764e42e0e2b 100644 --- a/components/browser_kit.rst +++ b/components/browser_kit.rst @@ -317,6 +317,12 @@ dedicated web crawler or scraper such as `Goutte`_:: '.table-list-header-toggle a:nth-child(1)' )->text()); +.. tip:: + + You can also use HTTP client options like 'ciphers', 'auth_basic' and 'query'. + They have to be passed as the default options argument to the client, + which is used by the HTTP browser. + .. versionadded:: 4.3 The feature to make external HTTP requests was introduced in Symfony 4.3. From a9890170c674d9be585c043ab628913eac1cbd28 Mon Sep 17 00:00:00 2001 From: Anatoly Pashin Date: Mon, 12 Apr 2021 16:48:28 +1000 Subject: [PATCH 0689/5766] [Runtime] Fix typo --- components/runtime.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/runtime.rst b/components/runtime.rst index 75c84b0fe17..2bdad2e38f5 100644 --- a/components/runtime.rst +++ b/components/runtime.rst @@ -142,7 +142,7 @@ The following arguments are supported by the ``SymfonyRuntime``: ``Command::setCode()``). And these arguments are supported by both the ``SymfonyRuntime`` and -``GenerGenericRuntime`` (both type and variable name are important): +``GenericRuntime`` (both type and variable name are important): ``array $context`` This is the same as ``$_SERVER`` + ``$_ENV``. From 24c07cc105ebc887db74e92b654057a3b165a56f Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 9 Apr 2021 10:57:10 +0200 Subject: [PATCH 0690/5766] [Security] Document the login_throttling.interval option --- security.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/security.rst b/security.rst index 3b1c81f8b20..13153307ad1 100644 --- a/security.rst +++ b/security.rst @@ -500,6 +500,11 @@ You must enable this using the ``login_throttling`` setting: login_throttling: max_attempts: 3 + # configure the maximum login attempts in a custom period of time + login_throttling: + max_attempts: 3 + interval: '15 minutes' + # use a custom rate limiter via its service ID login_throttling: limiter: app.my_login_rate_limiter @@ -526,6 +531,9 @@ You must enable this using the ``login_throttling`` setting: + + + @@ -550,6 +558,12 @@ You must enable this using the ``login_throttling`` setting: 'max_attempts' => 3, ], + // configure the maximum login attempts in a custom period of time + 'login_throttling' => [ + 'max_attempts' => 3, + 'interval' => '15 minutes', + ], + // use a custom rate limiter via its service ID 'login_throttling' => [ 'limiter' => 'app.my_login_rate_limiter', @@ -558,6 +572,10 @@ You must enable this using the ``login_throttling`` setting: ], ]); +.. versionadded:: 5.3 + + The ``login_throttling.interval`` option was introduced in Symfony 5.3. + By default, login attempts are limited on ``max_attempts`` (default: 5) failed requests for ``IP address + username`` and ``5 * max_attempts`` failed requests for ``IP address``. The second limit protects against an From 98b620676a23275b4bb12823398bab2fa1a8b9a4 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 9 Apr 2021 13:05:33 +0200 Subject: [PATCH 0691/5766] [Uid] Document the ::from() methods for UUIDs and ULIDs --- components/uid.rst | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/components/uid.rst b/components/uid.rst index 1bf66021fe1..b262768195a 100644 --- a/components/uid.rst +++ b/components/uid.rst @@ -71,12 +71,20 @@ to create each type of UUID:: The ``Uuid::NAMESPACE_*`` constants were introduced in Symfony 5.3. -If your UUID is generated by another system, use the ``fromString()`` method to -create an object and make use of the utilities available for Symfony UUIDs:: +If your UUID value is already generated in another format, use any of the +following methods to create a ``Uuid`` object from it:: - // this value is generated somewhere else (can also be in binary format) - $uuidValue = 'd9e7a184-5d5b-11ea-a62a-3499710062d0'; - $uuid = Uuid::fromString($uuidValue); + // all the following examples would generate the same Uuid object + $uuid = Uuid::fromString('d9e7a184-5d5b-11ea-a62a-3499710062d0'); + $uuid = Uuid::fromBinary("\xd9\xe7\xa1\x84\x5d\x5b\x11\xea\xa6\x2a\x34\x99\x71\x00\x62\xd0"); + $uuid = Uuid::fromBase32('6SWYGR8QAV27NACAHMK5RG0RPG'); + $uuid = Uuid::fromBase58('TuetYWNHhmuSQ3xPoVLv9M'); + $uuid = Uuid::fromRfc4122('d9e7a184-5d5b-11ea-a62a-3499710062d0'); + +.. versionadded:: 5.3 + + The ``fromBinary()``, ``fromBase32()``, ``fromBase58()`` and ``fromRfc4122()`` + methods were introduced in Symfony 5.3. Converting UUIDs ~~~~~~~~~~~~~~~~ @@ -85,7 +93,7 @@ Use these methods to transform the UUID object into different bases:: $uuid = Uuid::fromString('d9e7a184-5d5b-11ea-a62a-3499710062d0'); - $uuid->toBinary(); // string(16) "..." (binary contents can't be printed) + $uuid->toBinary(); // string(16) "\xd9\xe7\xa1\x84\x5d\x5b\x11\xea\xa6\x2a\x34\x99\x71\x00\x62\xd0" $uuid->toBase32(); // string(26) "6SWYGR8QAV27NACAHMK5RG0RPG" $uuid->toBase58(); // string(22) "TuetYWNHhmuSQ3xPoVLv9M" $uuid->toRfc4122(); // string(36) "d9e7a184-5d5b-11ea-a62a-3499710062d0" @@ -238,12 +246,20 @@ Instantiate the ``Ulid`` class to generate a random ULID value:: $ulid = new Ulid(); // e.g. 01AN4Z07BY79KA1307SR9X4MV3 -If your ULID is generated by another system, use the ``fromString()`` method to -create an object and make use of the utilities available for Symfony ULIDs:: +If your ULID value is already generated in another format, use any of the +following methods to create a ``Ulid`` object from it:: + + // all the following examples would generate the same Ulid object + $ulid = Ulid::fromString('01E439TP9XJZ9RPFH3T1PYBCR8'); + $ulid = Ulid::fromBinary("\x01\x71\x06\x9d\x59\x3d\x97\xd3\x8b\x3e\x23\xd0\x6d\xe5\xb3\x08"); + $ulid = Ulid::fromBase32('01E439TP9XJZ9RPFH3T1PYBCR8'); + $ulid = Ulid::fromBase58('1BKocMc5BnrVcuq2ti4Eqm'); + $ulid = Ulid::fromRfc4122('0171069d-593d-97d3-8b3e-23d06de5b308'); + +.. versionadded:: 5.3 - // this value is generated somewhere else (can also be in binary format) - $ulidValue = '01E439TP9XJZ9RPFH3T1PYBCR8'; - $ulid = Ulid::fromString($ulidValue); + The ``fromBinary()``, ``fromBase32()``, ``fromBase58()`` and ``fromRfc4122()`` + methods were introduced in Symfony 5.3. Converting ULIDs ~~~~~~~~~~~~~~~~ @@ -252,7 +268,7 @@ Use these methods to transform the ULID object into different bases:: $ulid = Ulid::fromString('01E439TP9XJZ9RPFH3T1PYBCR8'); - $ulid->toBinary(); // string(16) "..." (binary contents can't be printed) + $ulid->toBinary(); // string(16) "\x01\x71\x06\x9d\x59\x3d\x97\xd3\x8b\x3e\x23\xd0\x6d\xe5\xb3\x08" $ulid->toBase32(); // string(26) "01E439TP9XJZ9RPFH3T1PYBCR8" $ulid->toBase58(); // string(22) "1BKocMc5BnrVcuq2ti4Eqm" $ulid->toRfc4122(); // string(36) "0171069d-593d-97d3-8b3e-23d06de5b308" From 8daccd39555d4db035625b0c4e25f55059efb929 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 9 Apr 2021 16:52:54 +0200 Subject: [PATCH 0692/5766] [HttpFoundation] Document the unix_socket and charset options for MySQL PdoSessionHandler --- session/database.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/session/database.rst b/session/database.rst index 01c663911e1..dffed5562e7 100644 --- a/session/database.rst +++ b/session/database.rst @@ -234,6 +234,16 @@ first register a new handler service with your database credentials: ; }; +.. tip:: + + When using MySQL as the database, the DSN defined in ``DATABASE_URL`` can + contain the ``charset`` and ``unix_socket`` options as query string parameters. + + .. versionadded:: 5.3 + + The support for ``charset`` and ``unix_socket`` options was introduced + in Symfony 5.3. + Next, use the :ref:`handler_id ` configuration option to tell Symfony to use this service as the session handler: From 12b0cfc4d6f9e3d47fa4a7046f4b8941107954ff Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Fri, 9 Apr 2021 11:13:06 +0200 Subject: [PATCH 0693/5766] [DomCrawler] Clarify the ways to add contents --- components/dom_crawler.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/components/dom_crawler.rst b/components/dom_crawler.rst index 1363d977a3a..b1dda3d42f7 100644 --- a/components/dom_crawler.rst +++ b/components/dom_crawler.rst @@ -292,7 +292,9 @@ context of the crawler:: Adding the Content ~~~~~~~~~~~~~~~~~~ -The crawler supports multiple ways of adding the content:: +The crawler supports multiple ways of adding the content, but they are mutually +exclusive, so you can only use one of them to add content (e.g. if you pass the +content to the ``Crawler`` constructor, you can't call ``addContent()`` later):: $crawler = new Crawler(''); From 0354465e71fd3b72c649f68d2a3f40b8ad0bc162 Mon Sep 17 00:00:00 2001 From: Linus Karlsson Date: Mon, 12 Apr 2021 10:59:28 +0200 Subject: [PATCH 0694/5766] Update table in lock component --- components/lock.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/lock.rst b/components/lock.rst index 4200adcd817..dfb3962464c 100644 --- a/components/lock.rst +++ b/components/lock.rst @@ -357,7 +357,7 @@ Store Scope Blocking Expiring Sharing :ref:`MemcachedStore ` remote no yes no :ref:`MongoDbStore ` remote no yes no :ref:`PdoStore ` remote no yes no -:ref:`PostgreSqlStore ` remote yes yes yes +:ref:`PostgreSqlStore ` remote yes no yes :ref:`RedisStore ` remote no yes yes :ref:`SemaphoreStore ` local yes no no :ref:`ZookeeperStore ` remote no no no From a7cf4b344ddf31729e6b310848317d4cd8d15685 Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Mon, 12 Apr 2021 13:20:30 +0200 Subject: [PATCH 0695/5766] Updated link to v5.2 version --- configuration/dot-env-changes.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration/dot-env-changes.rst b/configuration/dot-env-changes.rst index bed01ea766a..6679600e908 100644 --- a/configuration/dot-env-changes.rst +++ b/configuration/dot-env-changes.rst @@ -85,7 +85,7 @@ changes can be made to any Symfony 3.4 or higher app: and update your `phpunit.xml.dist file`_ so it loads the ``tests/bootstrap.php`` file. -.. _`public/index.php`: https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.1/public/index.php +.. _`public/index.php`: https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.2/public/index.php .. _`bin/console`: https://github.com/symfony/recipes/blob/master/symfony/console/5.1/bin/console .. _`comment on the top of .env`: https://github.com/symfony/recipes/blob/master/symfony/flex/1.0/.env .. _`create a new .env.test`: https://github.com/symfony/recipes/blob/master/symfony/phpunit-bridge/3.3/.env.test From f0853efdf4a695e53e924aada965b5879b5c72c8 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Mon, 12 Apr 2021 13:43:33 +0200 Subject: [PATCH 0696/5766] Fixed RST syntax issue --- security/login_link.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/login_link.rst b/security/login_link.rst index d3c7b0e4c23..456cfc706c6 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -661,7 +661,7 @@ Customizing the Success Handler Sometimes, the default success handling does not fit your use-case (e.g. when you need to generate and return an API key). To customize how the success handler behaves, create your own -:class:`Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface`:: +:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationSuccessHandlerInterface`:: // src/Security/Authentication/AuthenticationSuccessHandler.php namespace App\Security\Authentication; From d39b47767c9f8085e3e199f8d88f87d104fe7ad0 Mon Sep 17 00:00:00 2001 From: Oskar Stark Date: Wed, 7 Apr 2021 15:18:01 +0200 Subject: [PATCH 0697/5766] Docs for Slack options field() method Closes #13398 --- _images/notifier/slack/field-method.png | Bin 0 -> 17302 bytes notifier/chatters.rst | 38 ++++++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 _images/notifier/slack/field-method.png diff --git a/_images/notifier/slack/field-method.png b/_images/notifier/slack/field-method.png new file mode 100644 index 0000000000000000000000000000000000000000..d77a60e6a2e920910686cfd06702d68360050bf6 GIT binary patch literal 17302 zcmeIZWmFwY8zl_nkl^m_?gV#Ba0qU}-Q6Wfa0~7Pf(CbY4KBe6?(Qzr-1ojozHip7 zHUH+vOx8Kj>F%nos;;VMKYMRNI$KfkC7J$B|I4fuCsuvv^=& zFjHnCBJvUseOy1aQvv(f$yLZM8oPh~W5j$6XcAH>65>8?e zfe}^X>g|N~=IAwB5ATh-?|xT>%nk-7w`Ff64Aws#oc?7LmBg+;3yMebMjyHp66*d; zRExi}1WImnWCVM?4@#5tNdb(?Fd*5?CzSd@>fx=jCxdFiT1aazBq3FTR8@W0)9AO` z<(Tx`q#?Z!x=L{joCs64jR$L!t$-r67SSHxWrCb35%M`XdmTk23%R}T+QuaPHu<>o}&Uajya z6xj?UXoCx$dx8~oQm0NqfSLAV*9dG;8{VR_U(CLG6)cE9=F7kYVcd>0`^sbmq1jge zN_a0ER6zti^oExRVovZih99{uIo0c2UD8x}0QyyICRF2&Ra-h7wPKcZ)?|C;HzLams68fM=YzK24OwLGk1znrIBX4csfv6hf0yld6b z&Y6=?i!3s1unT>?b{%0wcC~c%wJqT(Su^tzHetA2uhdD=$>z=DP3(=uP5uqC-|G&) z6|rEl6X-A~TqqA{s{q;n@J^^NlGP-4NCqL;-SOQp`lP3Lr~Ie%A)+kgZZTWY-8twv zFcZWRkP3vmsOqtnQpT~0{V-?lXZ-d&w+OfNpM@)OZWLpv-Qq6e+y}4+LqQ!xKlO<%(`uRf1kjcBnv@x(i9i(`?ZJ3nt0F)O}jufyQ4upF`BaB;8$u_WQ^a5I=a&2p?ZY~u8)dv7_uRyt zIs{_)_w?&4F^#YUO2bJD%b-y-$u!EmlP-~7msU+?Pv&PLO<^9M7_LonN`g^V!0k3{eLKK8w1ua&K5ew2HrvG*)>pQ*WzAokUBZPu2V49n5V(K?&*V}~*4U|Y4# zv9%NPz}xT*>{MgNk(;fZt)$KRnbVBeJjJ9*ntb+rj*;3C-ffy~Tn4m6-Na3X5{9ym zhgy)OJRfbE#utqnO6>M+@Ar;Y860dJ2``wg#V-r4c8n&HKMXky!De8Mf{kuw^zjL} zHF#{g;a}Z#EiCa&dbC|vC9AMPvR;oITr*#;-W^rUR7b|i67U*R^~XSV=)cph9?ged4TI3F}UT;ed(RLD`7)Ec+x$2p8D z@+wUdAu>vPhYf$KqJqT&oo(H1(c!|BbFz7AcL_%mIC^8Dp{Jzl3h)YC{o@|>KI%2@ zwW)Q*wf%JgG7v=^ITfl28G}r7T23OFthr1tc^~Br1>z`tN|V!(V5p{~-9U+($~nx| z$FwpI0gI;)$UWG4*vK4x1yqIWeDBqF_7?SBW@*)X)x-p;brIKo$D_-gglIQV10cCc zuZh8lOlYrw)X)AT0v{T7a+Byw(b`6!hG*kXiCI}3bhb=YgjE#T`FYsxlSF~V$CYXj zrx-m+S`&*Q72lxUpy?1~xLT>fMV3ivGyIM8l|o{t#%X#s<1$AZ&GUNa&FA+p1&}d* zrDC;V(+ut!SXwue`WO03Ymwv>QYs9)ngbe*9@y1%R_cBBRhwdiZ&U(`3p6FPk{izI zlp~7WkF@d8llViJw%=xp3=jM<+=JnTh-mt zQGrmO<`y197l#NVnOlN`j0ZlstKQ?ohmc!EuM%x5v%?v$7_WiGoyMw5g3HT$_$wRJ zPq=9C{%;fzwD_=G%WKA4?ObA=6?chk#qD-(M+*g(x$(T~*P+hE*BLR|ln8V2>CFOD zFxe1mf;HkwBue=DIwPH`-Rkfkr&edY`eY(i)5o|gR>@8c$A63~e$EeE$US6~gO$5> zq1&la%`x>^{w zzCPNbB~aBUbJw=oPo8r)OIfa&oOxB2+1Aluce{0v%2&5${p(0(S9xh`+1r_Ne`LSu z*5&jJg#jcbkaM0*!$vL9ew3wWC_quT`!OTU|4rqY6$mlAcu52bpri$RxWWaN2#q$8ZGpvlNV|gYZ*DMFGxuLca@5 zWj0de<(u-bF!M*Lja`Nj)CzI>ep3a0?mLWRTsw9!&qI8Cd^2qPM~yHv56onPCApz< z0~9^PPmLi4bhNb`F6%HS9LY(S&p+3f*|3V*(H}lOqo&hfN`%T*lL9zb#Yj!USVjhn z1~`TS0}nC-0|7_iz!wMjf`Pq?2?Tos{6+!3qF*8Ydle$>>#P4BgGIjFD5NMNAp!hW zG_W@^vUV`FakPv1+6z=QZKkB=s3s%LZD3=?pl4{KZ^YngW&2VDjMtSLIJ7cy)FX1W zvb1*KcI6}a=MHY*_~kSs3DG~dI9l+LsL99^iP+d15wSBcF))$v!w?Y>@!A_2b1R6x z`?omoKRyyuM@L(3Mn)GG7X}wr1{-@5MrJN9E=DF6Miv%&;0}5RH)}^dS9)s)(*IQQ z-+Dxi91QHuY#q&PtchOg)zi0ea^xc+d3n(9fB$Kxk*nFCCs{lE+by7jj4xLhnHiWE zf7cBZ<$XEJEpO&(WT`G{W(5on@C<(Dw=BH>-2Xpa`SZlTN~--S$4^~+WQfO4@Xs|z@02E)_te*_2G#JkcKJ^k6e3@Fpd9vh*E!C=N`gUBw!I<~ zg!ui*lKkYys&rau_xA%~WWC?~RWV379t_f?V9jX#cQN1qE$so}|I>CFaF`MKp21#; zKTQHrao*zp)e{sbWuRPEXktX{U%i&MJ>&VSNn}XhfpQ|~jJTA4^(R;mM20jCtwx8@ z;Pc$d>+_^lZgq^t@97$X$(SJ;fitxvQ^ohY6aMX(HmjbuXPcBQbv$Owr_W ztfE)FUB-9T_Wa1GG;-Pcu1L9r!elf9{^X>1u8Qn^Bpx^ctZZIXRFr5il8`R?gA%kK zQ}tv%=X+C~R}24k-M3tlNC~uUA!5p(QuX18evZM0fEU^Ay!ZMJehQnxTRP~AWZQSGiwZ#I`yC?#_7)V$Q@d-nTo?pLy9c_#H|7vnd{Mh6y5sF5g zV>wqD!=%?K&ovr^<8^mY$m{*U*-lcX-2%fTz?nRlNS`=eqB*$3{4Ljf>U&2a4vi7> z5CXU*?SWpQ=UMm72sX9xP!hM&k)h|YE_sW~amJRx4p7GpO&XiO&F_hlCE0%DcivOe zWM8sxc*^hcQ9CR)0MX=T5&PA3YlaJk+he=p(a=0m#y(>I^K145Q?7}*ONb~uetq;* zRPS^mqk*_D27Qq~CIk{CC-YEzIixmIyUSb!uFPh zFESLL?3KY4nGg82=YMO{_Lv9JF$ePvQrgX~#LFAE@9ejR%=or^UQHjgcw9@CXw*DhtdC`hn9udO zEcU5AJBeNo#SsZX;NK0W^VD4&&Zz2l2NOr& zvL#5O)BgBbs5q=||8QehsFC|!>A9jYR1uGm*R@>EmYSXV^;TVT}^a z*@kk2%yq5u0zE2RjJG+fT|pL_vq8#sXB$5hzPZB-rN0(niyls8*Bs?BTO%t}Xb81b zYZG#JJSHAl=CSw~i~;4}eiurV@(G2`9hvmq#knxSgL+>CZvG>^N_A4T*{^pDI<1yg zYwfDr$i zH{kA$vI-Vf`!pC&Px`JfutBDd#4&SL6Pb|S?cB^?){=JS(l6vS)r~VaU8Z@h*Rbqm^Z~{`Z$(;D++p~d6 zqd_Il)-o@qbQZTz7Usb;9uL{xC|pKt7USq2HEE}4S5 z^LbL3j6XUdVP83xecB|v9Mhrr?^dD&61Ki#@i0$fvWZHf96jb`Nn;Zu>5HKM(Kwy3 z^Vwd!-nO+7gJfWT7P4W^CXlzyTUDF)GDfp&TjKlaVGniMhaU*knpc)I)kLM{(*@L! zFc{G==rrQFlJRe0xTL1(XyAzO_I?(Uej$CIu=Mv ze6@s5xgWdbtUOUYQ34K|IoXG7QRWA&bR{rhQ|pCR8Hjz_Jy2W*zXuJliB%9tCeS4# zoIWc(Q`Ue9yPEVz3neh>Flg3U#}8|=7ug2x^zuo@QGHo#@lYk&%i#4QdAz$+ge9i) z7rzPk`uQur*H$$ipS{wVSE^i;P(U&Sl+!ZS5!$SP-CBS~GBFsd$w;x)v;5N=^gXkQ zoN@N|;aFM4e7$a_nuPBDMu_}{KVm6W^;C1jkvB~=DHU?W{Stj#AZ&ZR-j?;%js(@( zEHzW3_R2*EM&JwtuaZ8X@i}aTD}C3JXr;YK-}2zULQ`9S#bh|hPitT`xP!A}IG~fl zU}UZ`9892BsMS*ckvN)2j!>*wCwsO%YC~^ey`uL9QAptF=9}e0>r=nDVUA0z49QXy;P zN<(^B=p>-7l5#rz9s9%i8h39sBCE+5fyDlCgZGerhx1bw+;Aa}*1wv}nAJ##n{|8M zqIPctM&KGA>v%xwqw0IyhHjb{?#-7JVc>Eb7HBLDaqqI`B>D#-3>@(_)$pmcIUmgy zinIzH7R_Ps6NBk7ztt&^6ROv($A)n48^N!1oKrAc%&8!1H{S|Rj$t- z3IZN4(W^J`KPeLFKjwL9G??eIh#7A)q+jB+JzjN*^v<_0aA={@4J+o$#ADEF_OA%} zD_aWd3TcU4P{^jK(fjK@W`Ssd9g$<%^IJCRH3}k4Eg}1ZB6^@5c!+5i{#s?ym-bO|a+UTa)u)3LG|zD7_atjmp?0QM751 z-l~5ti|Ub&F`Gds zp<4G)9F-o)rBJ{!aW_4RC@Msh-@IxSy=QMEz9tMBm9Cdi03omKm`0BAaLS%Zqy8<- zusiYQC%$vXohTIy{?>`I4G;1vzy&mVCoQ6%u+K;>75jxiz+%L`5tBfP~LBknrnk9=G z<6H1Ek#A7ybys{r(?&ObcXDjz)6qRr82cjVt@%YW#R=c1zTYwSdi}f6LODS=<0|;r zEtWH3g9{^fzK>24vk$9FtP98Cl7xiwF8HF`k<4lm>G}M49n-9<(tt|s*X(wy;VG;0 zp=3{UfPW@j7kS3L^v-;$GQL=?LU<&Tr!2w%3Rguy?P17`+vjeV@;>dxind&qSm+_? zhx5XALsar($7s~9#nr)_(a0i~_dK7|UEGmDXu(=f*gaPQtttb)u+2n$h{n^HTwIll zA14cHE2VgHm7xl_>DGEv47CA;14p}DuvD;wn)H`aoi>Idm6DiHblN>{palstGGU71#8I`2hh}(U*-7g9nzXre(%9f;J@%PDd&DXTB^B%N2K}=gc zcm(KB757X3i$zWfp=ZTxTbbP-?{1~m^Cu;iu-Fx)T^z@ez~wSrao#`Svvl`#M8S1s znMua6;PJtOpG{~kxwf?*Ea)eFmnRd2774>&rbL>dCh(aN5>I5kS4mI2rgs{)l zWCba$!)Dtq*fR5YcU{HTZS~*SZwNXd;bdkwM&qmG#2#QxJ9WRj327fNq=3RzEM7sK zu2Nm%M;R%%Ze@t<@SNqWl6Yb*{IX3i4zPshW2|u zsnOHA0^zIP1?jXps^>lND|=BtUc>4``O*aUzH3L$BOi#RjJo^L>G!a*`ijeIulm^> z{Kz2Y0e`_|$L&NA?D}&$kIUW(=L6Sr-<#=XA^+F6W~dG&Brs1R&?-7wCZ^;!og~pa zK`;UZo9ItnH>K;JgNX2gYAQtf5WE|~_C5M!@gFycgWfMGU9jR5{?HS36J;8X7g$x!XZe1MHP~}&!3zau?PdBrsk>htU>Bdy zek-dV*=5ZuBF9YNym%vw*j0YQ2Bb{6vR@IH*H>4w+@Ac+kuE@C6njEy!p-{DlK{S= zF#(wp(=>^XllW@u9F;j(oFIr|WzVkGK?!Xvbv)u%+)}Hs!R&Fpi^3_Hey>GD7qsOl z-zIY_^O-!4yOZvfYsW-n02raPB3fL4AnTAen83m(6jAQ2?YH!U#@IIpohe5Gu26l* zX#qZAzt?L66esrd`!<6m!nxS|d$}Jq(*_a5PGJF2*dHfk4oS+^#8hdqylt7a_AD-; zDMf-1z5pQhj&v05!dy)cO7RUb%YqLMzhym4k^Sc258xWE&_P=o-<933a$B!rot&0? z805&WWEXwYWoSB(8(rL1`!;5SU`}@QSXVVNNi;Bs7~t^W3kk5MxV{puoF~h9>KKoH zMu;L4&UcL|GW(R>6eIX!*WGd*QHvdqZ#Xok3Fpv?zWgWu|0IG^p1RV#7^|uog*@v2 z?xKcy*CXzkJOQm`Pbw~LcO#zpa!j^M73IS^5}ewq;lXSLx91&KK}S@D;1dLmA0~qa zRY&sDw&L~7m%F>dxf9RdnP;RBktZSP+_$1~Yq7!Gc-~*8(&`2v@Rlo2im2%)@`U>g zlp$H(hs`}-@a8WrL(QmgsuD^92Kh4yHp2iH@l?4yZXul!PIXVT09Khn!f zRN_^$-_!_R_@`fVX))-V@QsR8=$i;Sxn|9OX2!kX@=^}JBxe53U>CYk z9x8*^cfnImRjS?cjy~OCdt{2r1jIuWgV*X99PsY#W#7A>wJsJm&Yv@X*9RQveG)9E zPlGzS0lMeJVg?r`m&WWD@y9eF z4eTw|-XojFQOIZ%S`~Xmx)D{hzEznPYCUbko9^2oX9pWb@Mw~J#SPt5aqIq~|TwX-nCuMGiTxpH8<9M{saNfr^UY6+8q|pr$mGR+n&1>gWmA*vvS*|Rxc@T=L4$s z-iTNhqXDe(gCfX%ujM8e)p821z=h=BGafj=3loe6ZEp@HI+^ifj5~-**xT*GCxr3Nr$|PTBAK>P@#nTAxRvM!=`u#w~KGggE!hy*cNIg+F~4 zgm5N9%K1usqaciyGA)_5{6kGar$e!jzR}9d!5Gzv)@Q z9b~AO&#ba(oHiaSWLVlkpm59LFGtmv< z)ph-9?QCcKoBiehI(iCHdfv)V67x3-Rsl5&l|rpB|w>61K(zaT1ie?@z{#el=|Z=`Tv%+4b3|FYB4% z%(8jmTMCw#f@B48KZ?!GO5z>a3|_N~X$c|~9+x9JAd`2?zdkv4ba9!{CBq9S@1_v} z$SzbyM#i}Y2TFT3wf^VOcgJtH7{3X2K-i!6%Dix$;RNe04THq~LH*auK4r+K1%drH z-j8<@r)xcI%a$-*_drx(qxfz^SE!iJUUgZev+O-lt*)qEV;+w;>mwM7&X^ZF#i&^; zJ&i?6t#@{pCzC3fQf*dzsq6N!T-SF*Cxuz$o!QU&FWsT&Qc(gPSJHVh=@gW*Y0=#h zC{htPY;lkXoik3S**$AkAeD~cuhzdB2SAV7^}1OH3w3gyaIp5D32DR&CvuCoyXG&e zOorJ#b&n;s=#t4zM$+8j5W$k<3HRqkT-S+7#0JnN3OkxpU~@}iAEdWVKE%SR_viU4| z0`x?2f@X07Xf+%(u2!f|-cm~wU({csS*Jv#@2yC7Q+%{oqez1@DUd7uMS(&lE$4Q} zhHu6_hS=aWwPs#19*?{9LTAU-;k<=_{nh~W?nK@sJFt!ATq0R2*GMW$q%xG$Pdmgr zn2buG8hp<8e}nLy{I>HJR-sYJtmSARo)$OiwX8yKZg_kHdnd=gco(4f%in;DpuMI} z=W^&>TT|%OhZ6Uyu~}ZS-`kJ~BgU&~B~GL3MQX?u3&Tjz?+G=-7U@?Dj}KllBQ)~3 zIxyND{}$APrBH{Jz-@sY$B`#e8AtU&c%eO?xUsm;zfup1S!#c}q{eh#rG$R!yYi$} zS|3tv0>Tl#W1Dq)V?wLf{a!8c7#(#?e)+*%OP@xq>6h#T9m1v z#1rX!D;`J{?|Qnn+j<-5H2DSruR!D+i($FVr>)%t6+@aX)(s$Z4Y+f+ReWUO=nb%L z4HN-(r3Wdp()y4)o%Z7A55>l(rspeNF?ywf=!erj!k9Ke@5AK?T#g*$l9Z<~jqBl6 zTf=skG^P*2AsF;21VN+J6xDsU?8Rx6a%oD}5Or79({~ve8TLmHTxtlgP_6JoOQ2Gj_D8LOdNtBxW^e(N1c=XVMVk>~qd~kP?J&h9OG`^A zZ01VL1X$HJSbOjNa0LhAsC#M!5*a_%+Rq4klKvhZa2_P6%9ZX0q5z_T-YCK{i!>1} z;kY@9u3*#RL;{_lK3EJoQxEYvX3vjb1;M!-ccMdy;aa+EPP?IR{8GN`$8e)m-S`zq`haQWt_3MZUctu&8`)6nvK%_>2O8G;aFV4txtCr>UG}fclrnf zylQvX$BeATBV*2R7Qj_zVK4JG$>(??tbvOTI@Q)Rx{tL=X>Bel&x#-u>}iD%Jg!P- z=*FQYT={V{a0-AO=o`f9 zaNEv1V?rfqc2d9Xr{X*`|mpLOEE>`Zrw0O|SMX`~%^0T*{Up_KUgr zVy%*+epwsWlZNB-s6Z~&Eql{mA1%cuR~ehH$TyZvn4QQ01i6xJS1uR{de<@(PN%%v zlBb*UtUv1PuQnf@)HUXF zlCAegJYK7)d3OIuxvAw#Op?;oi4ip(-kMCUW&BOx2i$$HD%y244nVuB`qg)362VZj# z%8!X$DWjw228HiR)Ywe6pF%C5|MwJhSV z!_}U*_Sn3pJVFp6Qt*@CB=Ql;z4#w}96=g5=W9dI zB>U&w|GE2C!Zf8G0g5rQJ>BcCbR&p38VKP?m+?TSpa^OI*49DqK8fu4BCq|e@B1Pl z1NH%Aew9A~3LFJ09MJf616=>M6cCBN2=M_?@qbJD5Tt;u0E?L5Z*d+98PNWbRt=2) z-~l4vb|`t<*YAS+{w^#m3fK)qZ`6|iOiXbiCcqQ$e`gc3m|PzK{JwU0i2vH7m*Gzi z+};EtX-?g|;Q|(XB5VGrc+qr8jz*0+xc1o7<9)8wHUkQ=FbD`oA3qrh$IRu+5zf^* zrLrS4XmLs;F=ctiKhc^2fiOoVmAzj^05D732YZwJYH)ZTia|{SaLIAN;+Fz4OaDa- zSYWLL$UyvRbdCk^=gqFxK6}aL{c+oMtjUp9qpJjr`zM5)8jgy=?W2mZ+(`0tt-?F+dqNZ1KMK)fMa<24!_uKU*R8$IO=6l(-RQ>}`Se+tPFsR%nf8w`OvVkM_tT!% zfXjrF0{nqbqt-Ina46{m3pq~!_Q-wkW@{(QV zX^}ugLIwcm#e|?zzMjV^#$?oKy-;LOuQaT5n31iqdeYM+xT#p<;v@F&SoObs1F@UHXswVmxk${d|Dn1SntlrGOhJCTkwC7Wt^uUaW ze<6_oQX!?qDW?)zXcRK}+HxcWTz2W8ob|pa#v22hJRnK#2Yd_^`LY=(Kg%>qzAKez zC_j?(I3469^!WO}mTY!C{nAzi%DJVcYc)KG|f_^T87bF zs@0k;VsQ9ten0xY7arFL5RNshmzv$qW^{bi_jO6#&NkMzjwo#5KNY-diKkT=0C32Q z+5j>5K7mfXdZfx^)DXyxjQ|OG-UhCPTsm4lTQq{C#$x7blEDSw1^DTGt4u~D0gUHQ z#@^D>JQcGG(4_j42WE%dHAaAo;EpJr(uROF^&gT7$r#G>i^$$rSUn)`G^xRR5%JM) z01kEIq2YX@*o`%WfUlA586XT5z8g}jx0u&-hY`woeVeai6nyse8I9eIUw0gu9D|kT9twVAODl%%Y(Tp@T=9ki2b{< z;2^UF0DIE-mfcKQs9IGu$h?FTy}))%i&fAnkpGLfdfplWYSKi39cj%&1Oc1ID_0y2 zYdQ;+vWlhP8|bw`z^Fm)6?j3z#Q3q1>~lKoU}f%L4q$Ow+uNhrpDtDOku)(e!Dev{ z_B2YWMdWg{h%*#WIaQ>Z2vFV0}iKJ8QWBl_zEi$mHgLFp*?`Y+3#??U8%bYL9J8T zY&lylq>wASng4!Eq<~A`fS{Yn9k5ZAAQl?)3%tY%qGF^Qefl&C-5aqEMEi~4FDwqd z(hY9sc?cYDHfZBXO%P5`Prn>4)C~e@Up2JoXVMN;^PAvR6jl{!-%V5?nQ-;JmEybK zPS!vnW+$dgd}!!4NB+F|7H})rpLUAXD5P}V*NPmupAj|d1><{(0#i2Do8R?BkmOx> zK`A6uq+c+<&r`F85EApKC(lP{Yk9ljR&_NaY4EhifP&jUh z`c9sSMW3LKulFAT2nrU|Y6?pUW^mJ}RH#s?-ve`L6Hulk=p7aebv#{?O84kcc;}HP zo-BME1-W!%gPKPaibb5g64iuFZB5{@Yy#-QKZP|K6pXk4-R|9Y4%1n|FhYROWX4?qEewnz)q}^1)6LL4`n^es?3= zIT0KHb@e`q;794NCd0`s8S~8(Rb>|u8bOnxBw}X$?lCu>C;}cDTGbLXC@nx#_bq=9 zhFF!91#!gpq?pEO=a|!d@rEPHfY3M0c21Avp9YGr2oQ7XLGS!(s(WkxQ=Hxl{1=oO z=NG18ua$Q2-NnMHO#LF2(uuFcfQAe4JPH_A`m;oW4CkxOya!rrC;?e(~b zKluRDOMn+tBR$DPO8XS4cd+E;UgY2{$N}y%Hkl(q z+V*f3_OtNg`&VI-i3}xTry^tD-Xls_74Lv&1%j5xxH{R713>o~75Ay7yOEegrtKy8t8)NjY|xicLHz>z${E2ay9iHpD8=q;4{b}pA-jzL zDcg}?M9vQUq)8YIYzxHZ@BNU8sYt9x1ur1mArmZLrc>4`ox&>tEU9l(6?Y1?#dD6G zJEy39>(?QkrD)2O?tj)^?cr}mwVYiGgHAJx3^ngWqCf~ za#)LFC$j8yg;K|?$iXCnKgiQ-H233-6Ab*)J^zjJpY;H&`Rtn-Ma(^P7(~pa_F;8W zqsW>5BlE6+?QOH@fAOpDD1iIVS(m{wGX5adR!4{q7np~MkdwQ=3GoBKLOWT?IfwN( zPwN9b=PATC^G|8<_EG>%ABM(8{DFC3&^MHV9lM!O*MEcL|7C^jq8S1{r533RhM$vV ziiQ1@Lz4b9qUS{kGLreah18)&6B%{x%20B=&YLUr`(j?^`leK( z(OP#14L{&X#mQkG%M8b68CYuZDA^n*gpya&eNiP^c_D5zl`4eA)Z4sUbh+jcbN@wy zj@{o5N3F=+LO1Sgn*c0`sJzbn@^WvAL9OB)W+?w+!Jfq$?-wc-fsotsSKm8e!W!<^ zmQ)(_AxHq0wM>JKU%OLPi9;Ezn$Ab_)BxB?0DKkw;n=KxKZj1&`7+B^nAogTKUmF4vW>8U(rxmJ>N4Xmo008rvecYITcq zbLv||$)qmFi&NPE8}0K_cq`d?ol@}Bgv~nDlY(7&+4=5nh zZ+3az&XeZ;6PlPrR>Ep*h1Hyo7S)4(^gXdm!{B8f{f!R^aTjW>Vu2*bECT>>FUVr= zXX!V7<~0HLB#wJoFe)rTb1v1SN)1haWvW0*508z~22kAHI?6bp}k-+Zm`= zxyyXzAOYkI7Ly~q5F}zhIGnfQ6i?hAYAxqT0Ppf~36EhvQV23>VEYWr8roxldR1P6 z%~WH&(tSnBOV)G^3>B@^v(|T`g=({JDsmur$DP>@a|u4LyXrU^^}Y0SHXynJ)}fqR zbnk+f7yn_LzyZCr?-ozyGRRwOc2it2C8XDQTh;$Y0LZYu>!W@K z^u`<`!o}+v;np$|Pj=!Pq8FD>|4%bTNRbC|BrgE0Cjz9;k3Hq0&5&)>;l6SWTSY)2 zDOP4NdaASe5ks!n;jz{Y?S$PP%|mi*r~Ts9>mvsPpjjJpEi_`hTqeKrxLNAxf3O+t zKiG_D`$z11fcMK48M7UcOJ>P^eHO6sTCMx6W3N2Gcqs0JWCB&;lM3#%O>|7Ir&krb z%@Q47kFj#4&5z7DJ&Mf^0j#8M?*&5`fneJJI}p5%YC6 zW!^c;MM_iDsenFhdWkI7WQ=4J?6!(tpSHIr7spH5r#pZV^LRnTr}Vbj1!YMSnE;}&#aHTPV2M%;tP4^ zJ1PTU42NZ3dCq6xoq;fZ&f4iqJw4nyWylV#VsqIWsyA8|$|9n}A2_@z9FFs6nS%s`Ulf%XUB~Nw7bk4X-18a+@K3Z;#8$Gm(wrD8$^; R>dW5(N{GpdmI~|o{SO+qaeM#( literal 0 HcmV?d00001 diff --git a/notifier/chatters.rst b/notifier/chatters.rst index da11c8858b9..318ed8c74d7 100644 --- a/notifier/chatters.rst +++ b/notifier/chatters.rst @@ -98,6 +98,44 @@ to add some interactive options called `Block elements`_:: $chatter->send($chatMessage); +Adding Fields and Values to a Slack Message +------------------------------------------- + +To add fields and values to your message you can use the +:method:`SlackSectionBlock::field() ` method:: + + use Symfony\Component\Notifier\Bridge\Slack\Block\SlackDividerBlock; + use Symfony\Component\Notifier\Bridge\Slack\Block\SlackSectionBlock; + use Symfony\Component\Notifier\Bridge\Slack\SlackOptions; + use Symfony\Component\Notifier\Message\ChatMessage; + + $chatMessage = new ChatMessage('Symfony Feature'); + + $options = (new SlackOptions()) + ->block((new SlackSectionBlock())->text('My message')) + ->block(new SlackDividerBlock()) + ->block( + (new SlackSectionBlock()) + ->field('*Max Rating*') + ->field('5.0') + ->field('*Min Rating*') + ->field('1.0') + ); + + // Add the custom options to the chat message and send the message + $chatMessage->options($options); + + $chatter->send($chatMessage); + +The result will be something like: + +.. image:: /_images/notifier/slack/field-method.png + :align: center + +.. versionadded:: 5.1 + + The `field()` method was introduced in Symfony 5.1. + Adding Interactions to a Discord Message ---------------------------------------- From 6b105893cfe25b8b34cddd504a230d3c38e5220a Mon Sep 17 00:00:00 2001 From: Hugo Alliaume Date: Mon, 12 Apr 2021 23:21:43 +0200 Subject: [PATCH 0698/5766] [Symfony CLI] Document about `APP_ENV=test` behavior Running the Symfony CLI with `APP_ENV=test` has an interesting but undocumented behaviour, it updates `DATABASE_*` environment variables for a test environment. --- setup/symfony_server.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index f0723c20ea1..580af42bfba 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -322,6 +322,22 @@ prefixed with ``DB_``, but as the ``com.symfony.server.service-prefix`` is set to ``DATABASE``, the web server creates environment variables starting with ``DATABASE_`` instead as expected by the default Symfony configuration. +You don't need to create two containers for a main database and a test database. +Using `APP_ENV=test symfony` will automatically adjust `DATABASE_*` environment variables +for a test environment. + +.. code-block:: terminal + + $ symfony var:export --multiline + export DATABASE_DATABASE=app + export DATABASE_NAME=app + export DATABASE_URL=postgres://app:app@127.0.0.1:49160/app?sslmode=disable&charset=utf8 + + $ APP_ENV=test symfony var:export --multiline + export DATABASE_DATABASE=app_test + export DATABASE_NAME=app_test + export DATABASE_URL=postgres://app:app@127.0.0.1:49160/app_test?sslmode=disable&charset=utf8 + Here is the list of supported services with their ports and default Symfony prefixes: From 2e77005d76dff81a99055f7eca8286bec44f850e Mon Sep 17 00:00:00 2001 From: Jason Aller Date: Thu, 8 Apr 2021 13:29:05 -0700 Subject: [PATCH 0699/5766] [Ldap] Update ldap.rst --- components/ldap.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/components/ldap.rst b/components/ldap.rst index d7cb6ed17cd..60c4629fec9 100644 --- a/components/ldap.rst +++ b/components/ldap.rst @@ -115,6 +115,11 @@ to the ``LDAP_SCOPE_BASE`` scope of :phpfunction:`ldap_read`) and ``SCOPE_ONE`` $query = $ldap->query('dc=symfony,dc=com', '...', ['scope' => QueryInterface::SCOPE_ONE]); +To retrieve only specific attributes you can specify which attributes you want returned using +the ``filter`` option:: + + $query = $ldap->query('dc=symfony,dc=com', '...', ['filter' => ['cn, mail']); + Creating or Updating Entries ---------------------------- From 4586d288f27709970e2c60f6c51ccd66d5e4667e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 13 Apr 2021 08:57:23 +0200 Subject: [PATCH 0700/5766] Minor reword --- components/ldap.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/components/ldap.rst b/components/ldap.rst index 60c4629fec9..5b16a3ffb97 100644 --- a/components/ldap.rst +++ b/components/ldap.rst @@ -115,8 +115,7 @@ to the ``LDAP_SCOPE_BASE`` scope of :phpfunction:`ldap_read`) and ``SCOPE_ONE`` $query = $ldap->query('dc=symfony,dc=com', '...', ['scope' => QueryInterface::SCOPE_ONE]); -To retrieve only specific attributes you can specify which attributes you want returned using -the ``filter`` option:: +Use the ``filter`` option to only retrieve some specific attributes: $query = $ldap->query('dc=symfony,dc=com', '...', ['filter' => ['cn, mail']); From 5529b12eb11e8557c6f94fc663bee2beb42c0490 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 13 Apr 2021 12:00:38 +0200 Subject: [PATCH 0701/5766] Minor tweak --- setup/symfony_server.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/setup/symfony_server.rst b/setup/symfony_server.rst index 580af42bfba..7420a822ab6 100644 --- a/setup/symfony_server.rst +++ b/setup/symfony_server.rst @@ -322,9 +322,9 @@ prefixed with ``DB_``, but as the ``com.symfony.server.service-prefix`` is set to ``DATABASE``, the web server creates environment variables starting with ``DATABASE_`` instead as expected by the default Symfony configuration. -You don't need to create two containers for a main database and a test database. -Using `APP_ENV=test symfony` will automatically adjust `DATABASE_*` environment variables -for a test environment. +You don't need to create two containers for the main database and the test +database. Using ``APP_ENV=test symfony`` will automatically adjust +``DATABASE_*`` environment variables for the ``test`` environment: .. code-block:: terminal From 3780af231b78da570d6d1bf757b9206c29e1cc7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl?= <50833583+Mis0u@users.noreply.github.com> Date: Tue, 13 Apr 2021 14:08:16 +0200 Subject: [PATCH 0702/5766] Update login_link.rst I propose this change to manage the case of the link is invalid --- security/login_link.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/security/login_link.rst b/security/login_link.rst index 456cfc706c6..f7f5e36751e 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -739,3 +739,5 @@ Then, configure this service ID as the ``success_handler``: ], ], ]); + +If you want to manage the failure for example the link is expires, use 'failure_handler' and implements "AuthenticationFailureHandlerInterface" instand of "AuthenticationSuccessHandlerInterface" From b7340c7e7633177d37230bda2923bf3b1cb1d01d Mon Sep 17 00:00:00 2001 From: Stefan Graupner Date: Sun, 14 Mar 2021 15:38:24 +0100 Subject: [PATCH 0703/5766] [Workflow] Add info about MermaidDumper [Workflow] rst syntax fixes --- .../components/workflow/blogpost_mermaid.png | Bin 0 -> 24123 bytes workflow/dumping-workflows.rst | 20 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 _images/components/workflow/blogpost_mermaid.png diff --git a/_images/components/workflow/blogpost_mermaid.png b/_images/components/workflow/blogpost_mermaid.png new file mode 100644 index 0000000000000000000000000000000000000000..b0ffbc984c9dc40ef086aa3cc2f0029ca974a284 GIT binary patch literal 24123 zcmZ^LbyU>f7cF3*v>;s~B_JT(prmwnDc#*E(o#w{0@B?vbV_%3cXti%j^E#V|2-Fr zHH**8XYS|Td(Pcw?|lrGlMzEjB0z$JgF_YnEUW+rhoBB#U%z+`elJmB+bOG%?!R?2u@F}GI{Q~I_vXQ##MmJ(n@t$sMUW2|MiQedvZmifSBrDI* z)Ji>8&rRD_S7E*d^_j>kVW;?K@n5~XZL*}4Vtu~e@RCN5?Ai=oc?^CSXxMUZ+PZTr z)hJT&!w`Hy<|oZH3xOj8uY(dl3&z6!B>e2>PfFNDd3Xwgm#|Apa4*$i@5R9W`2TrJ zhQfGt0$0o>!$;WLCUl+Z6Z*$JP!f#J)s4<)aLyBOz>ClsfA7f?C&4sB(Y3pRx^L3kfhyL*nf*-Z`UEI3M%-;`>&xgK})hd%RHwGt07bS*D7#eiRDH`o$`$EQ*d!@jUL z%s<}P7GaKzS^jSp3$^s&Aye5lTwR|7y>zah?b(#B(c90M-gFQTZQhSa)uWzfD64YZ zVJjm1_X*o41=yE`k{jz#so9H*x3xmV?r{#jTE707bBf}127l(>SPRaYA80F-{kJ|D ze^-ij_8-Y(s?&8U_Yc1w*;&!?(5Ge2Dg0$o+ve&(Zl*E=cX;yOEG(aLkrU!lV~!W2 z9o)J2_%_nf)Lyn>Dcloo?%tb)B)|PPkRXl2?QoRAv=76UCVX1s6VAPU>&T)` zkBNVeIi3tplszi_{@?p7`c4fBIY(`O*EC9&1@kJx6XJA?9hKFynx&VS)Bo>HW)sG7 zFD>>&qb`;27#hoi)NK7*HqE#%Dwb-Q{|!x;J}Mz{=u~!X=j@NbB9zS-KgpZBo()?v zHNl5`cV^@Ie>bAo$q0UAsOxPUdiL8PUo>;B@7Tr!?WND=NN75Jp(&9?toSbuY%8u5M`_>ozr|%6j!`3L60_evXC!rxQ=nWBp!$Yg!Kl2=^nb4h zbc#E;|88pR%PpU8NI5~Cw6oFI@Fy1f-w=s{|NfSzQ&pPXg-qKUns`P~|C$?P+EVS0 zPXBK{35=F*U(a6T;Un{_Ryuh$Ojod13C_m;H@Y`>(9fC5=(0pvSOvm~iwA=@Yh2qb z1MJqCu@kQZg9zR;4GN!9Mu9Jn2hSN$i0SUDxd_p?WG=#kwmZa7o zcntrl%@rNI(}#s%5WzCo$K2;}I)&w@$dk*3Dv@}`mFh|Vd;B+M)>K}t8t!rOMRjgm z_R!izql5pJFTbvjNwk45SMHtp6~gew25AN*gT{Xu5K7H15uqD&t``$mkb{MWhW1B$ zphDdJzgwCyFmMMx$1JyKi)~c@-=E&IG2v!Kk!v_pgDD}uer{fiVVT4u3wtb(Fx9jw zNggp$z%(*>5af$P5<`0AAh@?>4SNe}7B*v4MVXxs`w2-x!ot2zSvF(z*B}b2jOzz5n zES^=+U>GEMIxi+{p*Nlz7!(mf=hkmlRc&za6XDkI&l^fO{)*RzoDR_Vs_eB zyT8A;x~=2y3x$--qQ%67$Hk$KZ;PIY(W=8!fB1ewfUEbNyDqdBDmVx z++5w}Qt0$F9vbm%$b?yz;~pBT9c0H(qQ{p81+|tyjpQ-%uftm zR+-*~1>ew62e?>9-Hx0zuaF2?zQGip_W3%NmnbLjdu#VkZK+{D!^bSTnT@vgz^junS!5qV?`G$vg_Jx+ z<4h&mo1L6z*Vp6CWCjPbRWTQP-Yd{MQd&0)=>3ey5YNW~m4oZ!_Ms6o>(tk5e0){g zju+Q!L!N-p*cAm&Cq(3Z!E?c!4VPqe}8^$IBrVvSnpB%(<3iUqDO*79TKNSXJejG&;#eCbj*skcauj5e1i z_YYMa{GMWMO_PxfRFKlt8m`UVE_R2mPoiubi`p*_2ow0+36{JC;-+-ddcpf%qU%bV zY=6}8bVQ}wTWZjAkC~Pkat_;;7nO#6IN8!k0j+YjzBTrCcC{`iZ}}wabl1B4 z^)nh8JX}tDwt|AL8F`#67?l6o+1oQB@ie+!P}A2{Qd-`-FPf-;vk;7UVq=gv>$M-UQUBkUe0l4kiD%_qPaSCecR~Q(6 z8bvFAfBC}QU(VUViH727I=n119gC&p7kHOU*JshsIKlr&K_>Zvj8@*ui$Bft62CyD zsBLH{!n*k(c5@&pu3!LiSihIu?Z8b8mOrO%=%-y3sz0d<*y{08hH1%VViElJ&^rlC zEG&u2Mv!`s8qQu;7|ZIfb{OxBZjeyPc;L#)mgv=7oxk5FX2FwadM&XvsO@sqCq%ip zNU}MUHuU`&2V!eDF%K-4XG}u$|FUP=(#>_(1qM>XsTOO|+K1`rELK`Aq~_*ka?H!S z@W}FW1^D?%-rt`^_yv}1Zp1BRTQ9j=*EQBSYlG|u*W!=71sBg{-zz;=S6d6`zgBnu z@WhG-?O3LKY@oJ2);dEKhB)QLBO@c@SxqsG2b0rPOLRQ0R{~9{G?GZx+-lucgQ;yC z9SwC|Xg46s@Hw(#@be$u&6v?I+ZQ#Pjkx#Arus)P2XP<1ZH>NEQQ%ifHS2<2FUASoSwSO|t$c|P5`vFThX@tRG z@}quNsI#q&%{zI?w9*3W!)re_cvz^m$T*|@aMAOC3D7@jQa5=i!{4yZP&mvREa}uZMQy)i)Vv{ zfA{)F26|O(ZG47h@zsZU8H05%ID{v@K5Zm{=2MYYkcb(Ju8E1TkxX5^mTwOqdsa+)!M!g&GZ4g zX0g&+y!lPMUBAh0bP1z`8vuhD2nhp5O}D#ru?*T0AP(bsoEeHVYnsl&vpyL0$7iI{ zX@WEw)~UBLp0{Q(Eywx6P0n$zpvmV}Iq zKIjK`@9u=8$Ez#}b_~kvAhLkG}MTuK~TGMC>*7=9Zp8;&L8OE{rhMPO_ zZ~=05(oLE?0OSJ8j{`~VV1Us8pH)~dg=cK36;1vg ztHWs&ZD`y(ZADDO_Ro8cir})FXIrS#=;wL&)?}_)f23)OaUpNQY;|qzdONd5u7C{% z4?`4e0;}oGBPc&&90Y<0vLUhk<~=DP`+ZjcYIC}Z`3uwsTvyk+cQF$6&gdIiaf^B@ zZH(6sS1}-SM~H?IJXzjWD_=I~XUcS>*Ojs>jlFEE2h|J@x6LwK6t%2q$<$dJGUM_2 znCx6ucpH;?c;&X!R+-$?7DFQQhT?2ZGhs;Q_aw~}O{=t+81?-jMa2^NoN&bO@Nh6^ z;ME;Hbv|o?R87i9Rsn&uhK6~)EnV6OWcistU4(eoN{u|$TK*yjeH3Ku5s<@+y0vNn zC}%{Pm&V^8*hzBlUW4G*P%xVfcIZGEZI7}@!8^ocD&O6~pT z9Q3ffoO#5|vGaLBkfhE&vJuzg+QU`b3#p!!UMgVK!S88-)| zm5%b(>8}a1jk}{}XuF$T4>H!jF0w|;8d2+i)4tewNa1-#b!z%Ru>U6Z4m+>)j~vl3L<{gf07^~CLT84 z((h%rXKM}J34IADHI1#$n^hj)HB4VxPcb$;IPpOXKkcK)Nz-ag4&WmT!zHcrLwin zjnJexmH~*{&os@CZR&hX-RJwa2LuaBSd*l1JLV6s zy|m>4Q*>3&pan7L$Vq>2b29(oSK;=3Zh8|r30A%iXmeQ`Si8{5m_6eox$GP$xPS85 zy0fSAR||Xb(`wt!pN5;$m#@*R2Yz>dVMItYwQws;PA1BhN@xT1is@W6J&W;R$K2he z;_Dak_+XZ6?FQeF^*t|69vgc+;Thsl!GzHV>`}4t-G`1e>jXuWs26RJPa91u=JU~j z_2J)9wdbm&j1kft-C>$ea)YPTth{uRN#h^*BOX=jc0oJDfA@Z^JA(1-=?}qa4LLe` z@Aonp+G(RhFDapsMAjXBQ_pa#EEygo0be!Ukta|Q6vm7>K1kgBW$yA#Osp6muA9K2 z*r^D4V71{g>AK+E;-R6{(N>zb(dGV3?u6OqU<#;~v@O(%FgCW-ml6;{V)oBHwD|G| z7iuO3V(g!P*O)nckQ6mVBI~uhI-=3yH2kyo)6EH8&0DqRS7Nd6-Y>U_{z>efti>f0 z*3-=-Yi9i}6pc!g)*sk(6kmdA3mj{>wL*KVo$)6$R=N1->!+I8wTbs&ZMYLqzTB63&uaWy?Ifaz&-7Q{hacBLdMskMlz$<=wn2b=?YW5U#=9RPq1pJ{TeDx~ zZ7k&nlS)R78bWi91SuGbyuWIG%u+5;>5pgfy}j6*%Tt*9%ZBsQI5IVCm6MAnV|20s znOnfa#fM+^I@2+(Or6rv!kxC*k*Lo7n)fyZo&#hcibpy59px(lJ z6#o$Z*a!0O2@LOP)!O*1v49Ot9OO9ts6yFI4qkhM9*eQnX0xTs%46Ct7+&NU0f{@&EETfGHj>K7WD z-{OcI?s0l7@bnI>FYhq&m3! z(({jAGp7WIx%tV2_L*8&o;97C`@KhHWdaULD49n1L1f(@;el24p@hN5Q-h;K3NSH- z>j_BHRouSUYm4`8`yzpk~p z1T?>rqxnZR*JfcsSO7nqVOwxBhW{>w$YgTH*Eeb1_wzXKLOX9yL!zXh)B%Zmt^EY{ zEw2WyYDBNAER5x<&GOt+G}T0QD=Ri1n~M@k8hckd4Z$R{us+7q4Yz0t;AdG{%$gQi z-+WCFko(d?-L;RVC-g`#NRN0f!H2)w$B13)R}(jr-F znXB9JZQIyK2LpQ~udo!;nL4|i-@gD55H8aTUtiwPbzk%=DVY1*zT?Xbr!y`Uj)Zq< z_5>|}+MbMdZgE5D$3ip3>gJBx4m>i9C;IWVzwBp1WQ4Qtu0VymX`LIlkMENm)w6x= z9~jt1*Mz9z!5lUg?)iXp{;=smx3Z-5N1B6!8~wae5*0S396%ge!_BC2#&=r7Eu>_q zcS6U&VOwfW%@-p^7jr6X&^uDFV4!U6NaQL*Nm&+KW50A~{5MD97J$OlATDR^5Fy;x z4#2=JRun+zzHl@?h{OHMG7*}$GDJGCdR_gx%X`$1TSvyJNCZ&Ht5mqMyC>Ef?n1G$ z-x4eTXxW9atqF+*&6$pCwP%*Fe_8t;k}RO$*-gGl@Lu>pijsPwBNK~o8bSn<;#Nsl zWp-Z{e+u~+r@ZE5rNv9xsGi|8JRyI&KmO)?$JNi<^VhW^*Cj(c-hGyTpgl>SG9T4-LTu`Qe3r2k`00{ii|XGjet@ye2al7b zUJs0*sLmD&WbpH2EjeE+aFk#!Nu+(K6`W2=io?1JE0jH@#B!g^vNI#CJXi}ee#mFZ z>Z|)J6>ce;B^|-t@PTf6abrGGN|aWZp2ZvL0g6a`9;f$SUS1pz_ss%SD_DOr`G2pnn58&YlmF_AL9@atMeCj#I@A63jpt{OiNU$MbU91cXCI zd(ubu{x-yl35KR#M{!+q$dB;#BO5DEkX#r%mJ|pEN#K%@$hf$0e*OBD!=K)>+8<84 zhXI#_w>EHnUHGsrM*!k%O-Z(bnV$ZbVLFDRR-^)m-_ATmY8yK{DvCePQh2UfT3dap z%vD#`*ZV!MQ0dL+I5^@Q_q?({`HFsvSzo7sLqbCOAsE|Zptm(Rpw)mE0%(eZ*#+(K zK5UXE0%K#`=V(M)<3>v3@*bXq%NrZ0-v9`_T2dV?RHp-{r2U+|;?8Tl3PVp~G6Htx zv*|wp$pXLH>oU2Bw7jv?p3~lcue$a(8L3m9C-wjem=;$KHJNC{Xpc`)Rk3iL(Y}?IihW2LkV?AbMnv0h`g+Hp zeYo;)_1L~MCU3EDi)cCL)V9=21_v(cwSMPnxY=YyBbk>5H-NjnLKn(YvIErdBlOAz ztQ{zg@WT9kN5vw%g1@$>u1uE+?a$Zw1FG96P;8~cH_aRRs?i)G`M8BXZ1h{vP+nt(suO(OsQ0Y_|Hd}laLWyp8g#yv21q31}B{wUa z4rr?_=U@bRIbh!{=Bj-FtBTx`Ep0Aezy_--y&ev`0hO=ot*zn^3gZttI-c_1AKQa6 zLqcH`+h`!MH$y~sG*e9X_Pj1Gg{Q`52df+T|9SzITNn--ui!zs{>j6GXm7G;wX9oo zb$z{KFeM4zWTC#Dct|`;`OBzgsYYx1X-Vh{`7E{<@?&p=2l#{<#ijd!Ts2fDFec7v z+>&f9a*!{ashBZJBexTs%Nm}m6_d*h13bN&J~=zmHRqQw?I4_JB9_q zxzexXwvG?xvw^6DlW;(t5M$7Kx4&Wrn32h1Z4sb7JV$v!PVt9pWkuku11nQpy0I(G z`*0&Kr)y=^?reG1e5%;)`q)dO#wwzqfY5j-^(j)j0!*?<4$cOm1Dw;*VsGOWf6MJf zGu+Q#zXqE;dA32p4*1~TiaEu#buktr=1Wur;4u<0b@;I}*iTO#Tl=m`9~ta-6>%73HRM{j0+f0sG(w>O4Pz21Qa zA0NNcY~sh&qI-l+qgzbD!p+%M1t`FhNRFn<$N{0Xv3+E$I+M}B?Kdpyw_HFMYC+YngdU!5gnV4VD+tC)qpy~Zk?4dy zSXWrH{f!-O5=S75UI$D~>9%gB?;a>Z!^hu&vBSZGJsNQ0WzS!#2}Vb@^}us5QqS-6 z&bcYSfh`eW1u8sl>;Qc(s-l8(Fjuoxx0RX+CKcPRVQ*!(7;=d4#^{bRlxtJLzpz=6 z7I{gcBk*NLX3`mRX+dbKt+7oA)F1@||E9MC~TQYnPxMfbqbTzM@1+iiM4^FI4HRZNMT*G0raz~LJ5S};1L!S{u{ z$ol&F@tCYY85kb;w++-90G_jfcm{^%9Z;~xS{x4cqFk4FREz|rbW-*D{!COyM{0TH-9)zL=}F{4!rV^`r66i{WZZ>Txqvz$E(xpmlWT zkQ^SS)SDKfLuZUCVdv9^T%%a@OZg`T#>QtCQ@SiB!*5_k!rkS; z4Ir;>Zud$+?ZIX~8R~krd2&#*wD`IduF^3Y&%W1Lb-{k95v3)X21~u%fPZi5v6s*~ zbghq3pzbT=?$90MUBkQ!ga#Y%vo5zgCwO7cbzC>_!OrglR2PfcxR8i5nc&wJ$kig^ zx3<1ta56G7yw}TEaDD;Mf{rZ^$!6<#ugHWqewCOCPKz5EQ3*h=$zdeA3F~N%ENNF5 zp_q+L=b#P|0fF0G+TJ`ElLWg!w6D;~(%5VjBn0G2bo;GAgPqZ~6Wzr{$DQHyGt{}8 z8@At)ajEBre8;hty3Mbzr}fF@-@W#De9!^~+{=%0a>vq*8dvjUX@Hgl8@+hD%;!m9 zsb1%m!|r&I@YXZ`IOHnFb$W#t@=nZa5R91je0(XSUe`Vo1*%a=NqsFoPw-icP<(uR zE*Vh2VYxHc#hPSmlQJe%#>K=03#NZ8p!a%yv%mj-+)R2zt(b@A-Mcq@e5k6bHF{I5 zl^R6`hK34&k3x+wHu$r4cqqSGpLz8seT36S^)d2@+z-Q>T6fGZmm)7O4-EOLP`%=L z#SA!47rM7cGEJvTfiesEv=G1`d^A+8?(Uq(uyUj*5bc+lsXu~p*a?{MTADBLSx9Pd zQ>$SPB-`rwo_-jsM*uF$w<;(os8yQ00#r01Fz=8F1$;0Yf44hTVtq9FLz(fTKN%gV ze)uy-`jn>MEf$nqi^A>Mz)SNMkT)4b?&-wm zzs-$_^@}I^&J%4hI+(a=7n%x=Aon;xwQqvYe$^Kj7k{r-`t4$GY7J!cP9S9Ro>lL3WvTjx(}{#9_Kpy-|c4D_=luRD4|4lCgzl`}y7osBEXuIy@* zyC&pEiqfAC(>JWwinnuzmt4`95=w3sgS0l8{zcefXrT;PvpjTK-;?G%XR zIZB-!t4C_9V%s&x#Oo~DAU?e?(7#{l0pm!l)h3#`KE05?nDJm%$XpcEicX!zan~A;5yA%Yp@zn)gYdQYmU>%r!b^j_!gAC~!GT zMHEa8U~&8?FH`FWU@p41StWtPU{kRq9odtVaV^7Jc{t`w^s-nsb0`XW$&jV652gGy zsl8w_TJ3bP_>zn^V8E?hp=2Es|5t0L;&TGl3C!VM)aEbrHENET3LAg6>~|c{+$XbF zwqHoknwc)$ZT29Umx~r@na*V1&M&ACcarqI-OKL*o|b4`EVe-gG>TM?Wf|sE)&kHdJgPi8Wa7Dl)+o5 zoDk0CsXv#f)W9m3%&gmgXRk=mePuB6K&FeJsoKn;Qzi2$uGH;mRZ;sYI>S%%-0Lzu zK_%5kw|aiWDQf+q^v9(A2m0VUv7R`3GC#{08Ux~`7!jxJnA8ZRM~*CDw>x*QhnLLO zr4XoDJ@R;+QSY{26=0!-XAR6oR(%n1_`F@{S&9cu$m%b?x@V!OyH90BdQe6S3xg$V@k@qIBQ)y<(Z0dr>*o{UG$2}H3Y5t9 z&eJVM75g2wby>E4);T)}#Xjb2dMe_!sR(j!AD=pIt}n8}mfOKPXuaK;f!9xyzzRBG6Q)3U*WDq7Jb)VLx=>Kd6K14Gr5=NaR~ zdnHmLR&cetAQ-fpE=*>AbgMKQFq!Og=)Ag9Ah@>K0m_C;29Y4zqM_3Iar5Q=%QVb= z?Ox&oos=LNj+kf7&3^%_xUU_Kk%3dI|F_;_^4nm00ylq^`2r+6Wg&Pr&G3lXFZXoz zvQVhzQ|di84~}QR45;2HrsO_ePvM$OjfHvhk+cCVz8^463B0c5jgnY`<2KGH>RXxT z+l-jgVj!4u~N4Sg`~=t%LgT^vxZny34bazfC3JV zf@C02fml>Iwa(bwael&8M(!`bK@nwMISrwBZ$u}?o@4WYHyBa(n7UMXCD9M)SO#r= zFD(`u62Rd;Qztu(7T{wWyMg^z#OTV6ArSb7y$W7yPzEvF}6HSr<)oxH)MGXxkkRbIodXEmYC5kpOoD7C@Z=d?*Uh6|e z!Yw5`&2mh)GMutb_V(3wZ|U&4ThTdWa|pfo-Of#(qY`wq`6ItXN3W6n1-xoU)nt1b zf(#%-v082Dh}8=c33%asL+8H^wO!N6)bD11yFYH{*q^P+nm^#MSdkbNQLLNGLxEw? z;dCK((>|3UUBlDU)32bQ;C;ML0&_EIKGPYt#cvTBSVK;ileV^=S}B37nS*Xnx*KJm zJMqCw6l-?Tevc<3M=C)OCWEkB68!r0D@O4*MutkArCYDWK(`*vBSha|9Ug$fjw2b30$@2qsVFbC28{&>X8U)&*X#D6nonqoPE*!?ghhVUaNW+5-b? zXPa%-zjI_#-q6uS0WVOg^%7dKw&YuK@)S@d!w&2n-~Y zR3H`9KrkU1xCe@vtL$^O7}?na{{DS1Ffzixz~}(>DzPlun~ik=sG2Wur$C{oz{G&i z$R7ywO-x{DiHwSxuCYc`EumTk{-_$O#*@opNuVqPl#TWJwG^<1gv?5OuI&KTgvop@ zO&p^xTuY~j$iuCd$QorBIf_!x1mqaF(Pj0Xxdm77KQJAe#aa zkAC*CKfwgpw^n@+N$AGT)RP>y*FFXElk97z^>+E=j?{9kkY;o?=iyWhvg^*Y(KMyVppdGVJ{Oi`?~MLiJ`Pkn{x#N~O5A;0t)?7wWg~ z?duj%id5)yJ=uJZk0;;&%mtN@S35hH*e{3k2^O=JvGMU^aIi|8-BP35IL%Y7a-pP| zp?zv9tSPydNKqG>nE)1AwEdv(q1VdtinfS%C)}#*)Y)gyVynw1s1C z8|SO#1Y;^7mU#iOOau;KbD+wXG$po%;x7%?J0b#h_<2i&K(SD|9Nh7ob)PyA%*V0^ zzJdpUb(b@jx=@~s9&n|Qcn6L*9vY%`X@zVAnL@Z$Y)f8 z1(14<44@B;7Xg-OAfe4(IFOgd-~=i#2;{01z)AspCcURvR8n7dMzdU8CsKLx{4uci zs$cfTYs;;2G_Qh4i~)-PijMUO)tui7d200z@RG6p&8C{Ztu4+=MXhrX1^^Bl8h8~H zOGYxqNOz~MjAzRI3$^OvgMuEJO@`Y&pf`G({Wk*a7S~}wWR*K_<*{9bP*7;C&Q?+2 zFhU#qtDe-FypBh~f!?3VVY0#MC?zk#YRmVO;nZM3$Qpd<|?dB8;HJEw4Ub;Uz*GaB?j_kM(1^mKmy=~HVm zuWPdNqHD0MfM;5ku11}H`?^D5HCf=ZjA;r{sAo6ldr6a$6n|?!UUY2 zWiBUE=erYWCu`IIiUuCcaWK1IvNk<>F#v%*=G(V7FpdQ1`?d}a?{Aq)J?})HqkBc4 zpR+>m?HStx_!L*|u{!N-zKPPa0>?PK$LDa4SA>Sk{XVRi`eE_sIOD|i&|>R2+&EX-T1cst$)|gSApj`0j$vny^a^D-cVN@Mx9U% zZK#t!#%eWLACk#Jid9XI<-`B;FNx;?8%w7ZkHOy$_YZ_n<#>f2EZI;hkmjjnNf_(< z1%&*6fm zBz8I2?I2}8mB_*bPKV2bM@o?4nmmulIi@-QYsSgVJ(?jx2n>HV2eZn6B-01V|8%(_ z-@)9{07yaL5JDlobt&tfuD?Kst9LpOv9rSjF07|dp90?ir``G+xF^s3%1lP$07n*< zl*9wPl!#vj5;y$(`PzVq3}$Gkv5-xy&8ml|-F<%Vm;k&+`&=9biA)BX!^R2lh^)nC zti?#Ij?pFy(VVev;&+k2IcWewvf+GG5{NdzjLrAu+aXC9g3%L}Lb1M2*8gn9)tvy7 z1Ta7S=xUgk>5DzEx~^&cy|wh1+A>o?4S#%v4%cFkKfhr$%AlF>(Agd1)?bb%;N?*k z;k-8)b~qpu@}O=CjARJI86tBT-O&=1fH_>fK4}Lw-qqDrg^X%oRPl=%(_MMEb;$>m zSrz2$B!7`)3ld(xD3fpzHIi>a6Ih0rGVtD zKa#-+%l+Mto^H(-lVTpHJv>A_PC-SQQ^0o<_wy$XB{!qI6B^p@f=pr6ZZD1*hn-P> z8pZ4nj=M_0$=8KQ>hYyU!w-Y4-EwK9vKWb3;jGv3TV>_z_c(phOGuAgaL}|z=t`h9 zCor*MQ8!60HC?64y~AV8rHko_*Z)+c80(5r$LH_w&-9<2c=}Nc98E+T*$UV?{5^wB zwng>89R+9O#BgI!_2@xgTl@ObqyY>Sa)Nh;9%oYi_U5!m@6K>-eoLE8)Na3JjfcYu0FXUbX+bs8PgmyAth zWaPEejlTC3Tn~C9zwUJ97yJneBrhU+8{m&XsNBvi>UvE}r-1SrhbD@$Fl7KwLUg z&ek{|!FP0bms!p|2OM=f@NqqTEyHBPXR{yyKmq*qW>TBJs3^%h#fJbXmL{JGeR&H_ zzkf0z!EBPlXy6PjtO*Ufx|Dtw+f&!Y>C?i^lD_0KY(%HUz?H^Myk(Tgu>U z(*{^r2J|CP-_?(u)TavtKKbBsoLNJhd_OECo1tP3JHudZAk7+R>-moL*=h*+hor~b z)!{~WQaG3eHdEC9Q#oMY0FMl!9$VUm&MXdH;Ql8XG57JJ`;qNx$4mD(a=+YcE5dT# zJ)WqPR9PpDnJz=eBN7ePH@83{I9-c4%T?^oJZ=g9@%W&w)+WG6#&`NxvC`Zbm&K@| z+x@6f@Z(2)63=r}X6Dflx31!vlcB|6oyOs$u@)=#IrbfocRK z)Z$ffG2P*fB5jPv{fVl>{UuLUGV;rL@x~9(-&=q+ z2i{}Fn~Nz!KflTry}Gika^oQ{;7dDfeoQAMX@(NiLb>e#T&Ngo$^^T@V)~en#aLzq zeDEn^%^Sv}lDeUWhK8N-Jac)MC&MO{Cmx_Z4e$v2ZrnYiXoHX-|!%1F~>0| zAEI)AX13N=x4=Co(08@`TW+|aKr8`WuS!E)Riu~}L`CK#@!t=!oeRE|^%b z;msTg^7R$UqtXcDixrtv#(D^tqCer!Fp~s=c}LJIP9B~LpjFQ=So8TdU-_C?hf-?ZZHa zLrw1sbwNQD>1yL4;I>WvTw}Em&te=tZ%gacvSMfaO6s zsct_2$yy2?_up22E-}Bg;O)Yf;WTl-SXhfSbNwtYcPaN$ivU|Ny1$RHS<1xZo&9G2 zSHRO=GKjs9?~LIz*qM)UfGkB3(_tPq*s?huME(k)F0VDt1)XTG1eHDk%a>Fde+n=q zu(+NYBnU~qu+^j_xQ055RU7}rh?A^A++A>8Gwb+MQ|h%S(&aTj4TS7u6ps=j=Htf8 zzrDSyJ2`1oEG$umeX%Qhd*(-x5*Bm42B-FY{5=kiQ{FDxuVp6OHAv(=qumDL(LCpE zOU##-ZwDQ*;Dg;24slK;KfDW;iI!edT9=fpGb~96c zc}XVGIW-jr7MU5;kvd*ChJeKW78M1$v1oq<&}-S+<#~Qu8}0%wgiqtlhN=5mhPWJp zq$fsOKb{T}eXcQ-j(N*R6Gu#k^;ewjWV>UR__aUAuv6ADyIm_2VDb|(tNB1ri5wIeaw25Hw7bLH((!=Tj^(#7fDlHar3 zWFye(|NWkcz*?*WgIct-P#0zG0xL(8aV_&BW?B&)9TLU{IZpO$V50&`fUk?Y>SBX2 z&`nw=RDe^nKbb2E)C_097*%dE@)j8Mt&V_z;iN>Pd!fx5UTcy}wP_RCYuvD@gy=250JLw0s{Zo1hd1Zs8shpz}+T!1JNfAN(X zvs^fA43IE-q|GGNZ{NP9t$Qm!$7(VCld>kxA+&zEZWIQ=1Y1s$ z$uPGO$A!a7`B$@*rtRlDV_bIYFOC|oQXBhT2~PX?y_a8mJr$LukarDY&jomi_T_%% z7Tuojw1+S@{RR5c4VaC8G*sk7?8tCN><-Z208IeLYBKx{OrtHZrfKR(yw1o7CE|*# zt>wg_*AQ+GKm~1370%*T1ma{C7Qji6l<(JL3X2+GgBbJ&9M6nNtD$~ekoLq?>`D(Re%|z;-irxoJEJC zLL=^qXO9A^9UxMHpJXkfky@I(rOzV17;L~4$yulL7-EU0qHZBM{_)kTSJ$_7y$B<~ zG9J(WVA&O#@RvLyv{XC^C?CKo_k}qDU|0v1y+>xcSmP!1!dIk=%B>srq71@2!C{k` za-7ScUm9>1xYA#96{7X3;&}DpfyM_qnYFl6gaoC~_)(Qut%@jftEy*ZC>Y2j#|h?Y ztha!J^UL;ddc)lz1Z3@TL7?J<;xQqFbhZIp3dF_o8zz92WP#6Ott*V~a@4>upm2U( z>n-`!Sn-0k32Su%#*76!i;0|STN}v=tdN~(!YuDSvJ3Uueo)s6nq1o`X=79i@eaaC z2|N&z0~V{7uvYGK;Efxu%%mfBgJjy|^T**}14=5z>U zilAA^%#mSGJ_CdK0O%e8-Gc2sJ=LT#f#{@0p#4BtSh&<`fqQ;_-UJx@bp@6pWzHB# zD0dA32ljQUxX8tQYGb*T4=^uifOG;#Tfa(!%jOF%j9()5L;;6>v$qft5z^d3vo~&c z1ZmrsVf`w>MmO(;i=^b_4$uQQQ)iD1`cvBa`nIw$oIvND)4?puD$O7q9Puvf{{?6R zbz#rn&zV-*y2&XiFtQ{N?Vz)#Cm75X=#JPMgW&&1l7U9@uliYVR3v6L*=2&HT&f7xs@~MH|-fLE%lN|m_#@(p^}UjmyOL; zK0P~g1;_!`%>>lvv9T zshGNzPnJB!fas6^`EwJ9x6hXcIC6mZ`D3=Ud&(0;r=?QQIEJfZ=-ne|LOBL4r{#bR zfP-PsRQE$eI5g75p*id37vKIh>%o1{@8YPm_T~UZy;K^M-Tg}Rw~G0&nd6^76k`CR zF1l`EiH5la`T1Qxro;*8=~0*;U{>cs#fkhQ?mCFvI5())JdRrt8&0|i`xDth zY8Gi12&*uvKbQ`r4rLHU64HvVsZEtOT!dvT|{nc#lPiz&Svk&5wM zB|8}{4PBnd6#cBx?5s@%CuT*(lhJ-z9%!|IYPUZW}~-f^vM@v8b#U0 zL;OViL_-q=aWmx`h;XSMc7hu(($dllvoGmrX|IhoBqaKza7;^z5fBjKLGjw!+8Q=% zEtJBm){=^ z7sznF*0xZ$Idyng4lH}V1H}lEbP9J2I6XBg2NJW9eR_RIYu@L2`>Y%-m7HEtMZvlu z;TAp4vdpexuuO zE)@j@3@igj0ru_H(GWO#5*^C0Av**CZAhu{iy}Mk99Mr&*({kjpH@hyLx=2nFUxUB zye=iW^C?7PO{&0mN{5qxHcX}0fV2O3p`Ia9FR%5mv~*;DVYRmTiz#gLwmTp&5Led| zThVg7uv(rKuITbMa7oj8;OpO?fd$%(bP%22hKAaW`q`W1qm=L71%aMq+D?^^AK^gR zOGZH)P5;-9=ryb`E_qWmnjnBEq+<#Y${(|FD5v$bGD2msAw`Of?3iX>d zq*~cMMIuWOWbC53MgxOC_J>+_F;j~gN(=GX77QSo00&DW8TKz;MtIxRV9Yt4*mLR1INR|!=QbO zg@{P(_K+gRkl2QUmYSLxO2U`e(((~F?bOTko&jrjEd;W5aImoLI;!v^=;m$8N|dLq zsrA(MgQl-42XURMBxfaGNGe%xxJl3FSd$CTEsoD-_8Nd&qopQKiSAdc#h}7fw^)}b zYJ$G9-NOOhxX)f;V~2_A_vI`1{huXEv&e`%_Q)2Q z4J0RfWOmAkvUkQoBr80}ULnWKcI^4RKRw^yU%%JOUtZ^P&U@aU>%On+zU~)K9d{fT zIzL`oh%+v*nfp$|EWWHejo+nXKjw#a_zxykZxi%GNJz(9^Nk3&#kAq#pE7dCTa&{h z_Ib-?Vu44OSFu$R<^kJM908)K@$vH4Hjl+WynFW_5HNj<<l!p9~KVzw48_S6dl$>TJ^!Y1NxG1g%`J?iD5^CIZ%biPji1-X-U|($+dS zNbPr+!YFKOYx}-WYG6Mp|3jU&0mv_)_`{_Z$@X3wBd3`x-13QYY0>u1SLd1zbMAxj z{W+U!e9d3q7a023gbLdZienq>6|YQvJIIfXrTd_b;a@5X&gHb77ayR=_n40zDZ%qV zdFoH1re==39cdF2lkxG zE*tgX=#G(^X+5++G12&qm~HVK$x&=M->y zOabUwB`}cR1uJ%r@lB<=nu9oWO&ZnvOQ9JBR5Nkw-&kD);Rn$C)_Z{`Dwm#=%rf4W z*gKH1ShG@V5*Ue?sJdXJI6i~)i2^HSGux5CcEd+!QBqM<1GpP2{I?&V(0Lq6O=T#p zRp#kfBKBxhlv^_iI-C6*>*N8Dwzaj%RMuJ>k&-m6Da`lQXw@u;3@5-9?8ZRxzd_H6 z+zoA1X7dw|Zw4UHRpEFCFZ2+VLeIk^E1j-C+w=tID#2({Sy>5)Z2gGPW5`ztt(+au zcW8vIIp8jmSe{H#F`@ChQTxjQo5STdMXn8Pe(DNZ`0M9lPR|5?4#8q&aX1_kB`Ne1 z;oe!^3Z`v}b-rMNX1Lze-5nVgMg~Yk>TgTS+qZ7z-Y9}9n*1E(C6Og-U2iG{~D>3p$lK-D{Qq zG>-I{0rpHNI^KN1{fwqlzmG*mEd5Z1VDdd(`(p7QuywgD@QdBiD5d+bE09{=la2&g zMUAf0om6qEOx*ohV^vjBpdbp5JdP@zd}-WOxG;M}o;2=1$K6Omss}OR@l~c_V@a}p z;+HO6LV893AR+@&zF1OHA{KZIhp{)7BJw0rsYszPA}!y3N#<+BvAm5DmIHqNGgZ2l zny05IK(0EVNxJ5Aj8V#+-UQ?P6sY*M=I>7n9*5S5{rzd~y}paAVV_1@&0VK~Kv9E7 z55gGU!FXX`XxZ7jhRlPI9;En45SRd~NXNu65wq0e}T(8(hwvM2a;P*F#73JqHIoblyNn@PbYQ`dh+=3bNJy~_9+}a zg^_8IJ*Z=+^JWj&@_Sz*5989LJm5m-BnerPE)5l_6%E1d4h$j zYdQ+TcSJ0jUFp0y z%f;Ml9)gecy?^P*t)^RDSkf|;EuS&F&NZ)2{%CB>s4n1MNdC;l472*<9TU03Wf4e; zeV{!sAreGv1OA66XD|6Q(PJH#q~&r@kt^SuveQ!<-zQGyR$Po^{L{@FIeCz=-~a52 z;?YXe`MvWo9@T$<9`dXK`x8&E8UNUgZVBNC^yxZ9l6&k1&d~9 zjMNbzgzSS9&GE**85xR2-$4&$CVcO{%Y<+&mvUbwqF`y>k6} zYqX&aPJDJUn3e%p|3;+X2tx!h++7%AMuPB#c#EPk`}lf@kC4R4i>aGa>E6BjHS0DW z6nfU_t5rkxf-|YtQxsr5u32r)v~Mj9MF9rsek+^j$%azqv-&Q9pX!%h!nh=K011?2v1 zZMQVJ<9cI)X$!)tvz~8mQaDva5O9|+ZlA{lRMJ(9x*xBMZkq$w8`;}ShpsR(q}F1g zAY7A)<+5d@uuy=v7XAf|+!Qn;&SG~b@W)WgmyU($!O-3ETdxdi%ePGZ8l@Hx;DC8X ze9>w9?A9|i-J8f~D2%`le)I0e=4SLWl5>595B!MS-Ai9Z99NXG%QrZK9|6(Tt5?CO zXBOJqhet{xEODOvsNIE*{li;#?m!>>B=K;4fQT?QIu>V$1UtiM4RRA#j)~|~?MY}y;+Bf?` zAfj7XKq%BqlZ;8=Geig@&^07LT(CP!xo^X^<#l@Byk?8u)O0j9)h|H0t0nt7J$D^2 zO>CzG`6A+}si|AKF)=;zn9lKPG&va=w}eEhKz)+oNH?_7zZ-B6O6{uKHM_jA;g`2X z&vHPdtBZqIB_a*aH#%=xmlTfHFbPMad9MnCDTzxaZrFYLt1gkaiy8XG3(nnfd}L7( z#~T4#$Td3wN*dan@!4n@0)HTKqUGTYdN>4U-aV+@@ju>X-1a?PPInSC_Nmc<1C;-J zhd^_KJ*7MkBh{|$3GNhNs?H@_&nL)?3VG^AS`vX z$2Ev}%q@M#aI^rGj{Ik5g*^X$Nwn8e{YNLq=FodzTi2|ozZx=&%-O4JXzcBb35-C} zBjfFifB#Yyx_=L0Zg7)DEi9CXKrTg#_1jg;!~vmv@q~ck^51CjPT;g9!UTxFgnZ*< zyQqgra7s>CL|_A_wpRLgiz2Wu3IMTTf=xq1Q6L;n^ILTTzVVL_+CkObYauVGhYS&R0xSu%0HSHEO&k+T21vic1WlZ2gp=>uBfCoE zx#H_m@M!R>L7wV-#~f{mWeqYuH*asSd{MSzH<0xy@!?7JEQ){9Fek=DQy#L5I9r%D|L zu0o6iiP!Io9OB+T_E5Or89<=G!|vLp>I3Ler-k2TLvkNxX7$3{Q`aOcChl+sb}O za^>n3CBvSWMwysJMO6NB#gJJh_>t5>^MYxO=WW1hVGQc?`R{Y5RtGQa?|YFv94dU2 zd-sz=gF`0HZeijF2F?p4CIfrY92hMkXwNC=2pjG?n~AYwbfGgLh+By{(znxj#(}Wep}hwk!pQrqAyC%M%?)ysno;d2MKZT4 zrwRw^qa+moAmbk{eJZ!<8UkVQJ?4_l_4R3xl3nKh7L(>r2O{sHhLg6V{W2y|J0@SO z$1E0*_hsHiCh%+_E-*lYK}^HZCg(ZoqtN!d%EqHAiPsO~`*PyQsMv!I9HT}|J8+pV zhbtUev$L~7-12&#kh$>B7gm?G$OTU=pkI82Mfyt0`eM`kDS}SxVX$=cG_;IWFE=;c z5r?f-j#D&bgS{X18E?o2AgALcO{>SowA6PS5%6Ss79ZcYcerca`1F~#zdXPB6~%&2 z@8TL}sfVF75T-f>O=3`RykBNR1@s^#OaHnT3E0G>W_|YeKTiKuj#^9+Gsn-)Hcx#C z`goM0p8eNlE83Bfp|FS_Urvr|p-DtC;NTD8hmAL(5O8-QHHoPef`%c35xcZcZ?=Xv z+>9_ZnoCYD5!@9Hw*Sn4TQzl%;S-_STpv&?=`UGdx&kE3Pw>-1qxoiMks@{k*3aAh zSO40Ljjse4x=P+aspHUNq{jpn3fxOBky3u9fnA5?0oK{$XwM=xHWJR?9~>O=dU_|w z#XUo!w6+&$sxF@4VSpcKc~89N-*xw*L{uL+D&GNI(7+)i5$+m@hjb9sX`JMR$vVHT zBQt(uWv!;5w^t8Ji>_|=CisQJPJt*MF|iO#V0h7ES$TOHR#sL|=^U1^!rWY_=$wNz zNv!gbaI#=>xLx13><&@uCr^NR7+KivPS8hJb#!%oX}=vb#>3#~?z(hQdZ)NmzJI@4 zVkicQTIW@im0f4r&Szv~fSBzZq{fiOE0+I<%IL_9)x>1X0o{fU4+sAiL8!)Z!zhZ2 zQDO|YC8B%=l(Y44l?9FkLn|vQB~?XcS3V8=VqvH>oSp97sT^{&6i%}KSxeiMTu^Ww z5(y$@Rn@@*$#PmnQDr~#>-*c|-`>jsp}sdSpHt%eLn1hY>gV>*WTmlrL_zL5O2eoW zwN@5&1dt`?j*Qj)B)iV6thZ7S+n z^tEh+9K;qLKx_-Mae<;bSk6VR)gML%9PaS4tC8UpKYN!0NOCCQZ8otNWs&w={|ZCA zy28gLJ92Y=BGK>DIw^v6+frTXe;Zy%d2qiG7z(@_LaW%XmSZNJ7im+W%xoLsxmo4^ z^9lqp3Y=phSH`0Jtfr_U( zh=Ae&Dcj9GULJn-V9dWa&bp(RUs#WF&&WcS;Z_Wna-1O0Fa7}mPv+CTfp+PBnFEYq z7ZC3IkP1GTiBUs;&@jE?z3|$GL^u!!b&$34fc8IQq&wA7@7K$ zCSJ~0weHME@o90sB9_mR%^PmxLvpnYR@7jVQ{Ew~`CX(3843_=cV{p7LZWCR$}$2( z1uQ1STe<{w6_^Ah#n$UnV7|AV8a!Go$bPC&Sib93tT#Q!<4mxw+40J1CBoi2jDeuZ z?Eq!>-<}66E^a(}7N^D^T5l>MJ|TxU;Im`I6L9 z=AF7XXZys>s|~|nO}ZyHXzf<`nwN6Jm;QpLE*^gVNEI~0c{Vo9wFxW&KZ}c-niMOY zf2eC}Qu6ZhBIT7v5*lzBVS-oIwaxgFml%>2>`I%aSnro2>vXAMTHB}@5xcv1HmB>H zu>TgMFP?4STlEbL5Cs%&sX(UudaxZEyrEFs+@au&qGM|Mx~fV7+_)^Z7I2?yjBRC} zT`bdkGQ(xQ>?Lks-ykJ%(FFEpe&d->#qj(%csIQLi`E};m}k6)mmlPu}>7ZhTUb3d-&<|YJ0kw|iK zG9($HG#uR!br;8~iZZGrm%F)^!jn&$M|o2+g$knNI(l0J~wDc8iR24`6 z1y*yxb|IAkanEWo^z42WN>>2AoM&2)P_Fa(YnwBzl!OG8)%&uoRcv-GJ9*&_bo0$TiC zYvglrhh^Y}8WFms1wC4prmxrLHtRuw{aHs?J~2-ILV z{0ZtDWiA>Fj9SbKGUe>-$LaBrf84CDer{P?`q{PgX>pA67Nwhkv|a(!tl;y?1r((k zBfFLiBX2aweTvyv)8qaAUQ>1w=h>YXbPZ-De(~T!r|$oTG96j?fziX&Pu#FCd}H}j zb6zbydww0drd>z%fSF{mJtRJ*V{y1I<{!0`R%4-mw}y6GC)$!*>|?Y?E0tAN%KEPl z@ECQGvot!5D#2oL Date: Tue, 13 Apr 2021 19:10:06 +0200 Subject: [PATCH 0704/5766] Fix typo in handler success customization part. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Backslashes were missing. Reading was difficult, especially at the end of that very complete page 😅 . --- security/login_link.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/security/login_link.rst b/security/login_link.rst index 456cfc706c6..34705d28983 100644 --- a/security/login_link.rst +++ b/security/login_link.rst @@ -660,8 +660,10 @@ Customizing the Success Handler Sometimes, the default success handling does not fit your use-case (e.g. when you need to generate and return an API key). To customize how the -success handler behaves, create your own -:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationSuccessHandlerInterface`:: +success handler behaves, create your own that must implement +:class:`Symfony\\Component\\Security\\Http\\Authentication\\AuthenticationSuccessHandlerInterface`. + +.. code-block:: php // src/Security/Authentication/AuthenticationSuccessHandler.php namespace App\Security\Authentication; From 369e959d0edc411a1d006781e25da4c732f7245d Mon Sep 17 00:00:00 2001 From: Thomas Landauer Date: Tue, 13 Apr 2021 21:09:00 +0200 Subject: [PATCH 0705/5766] Fixing typo "by" was misssing. --- forms.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/forms.rst b/forms.rst index 17cd593d416..6f244fd7d1c 100644 --- a/forms.rst +++ b/forms.rst @@ -695,8 +695,7 @@ Set the ``label`` option on fields to define their labels explicitly:: .. tip:: By default, ``