From 7fc9fe850b7745f33bb83e506cd306eeb73f7994 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Wed, 6 Apr 2016 16:43:37 +0200 Subject: [PATCH 01/17] Added docs about ArgumentValueResolvers --- .../controller/argument_value_resolver.rst | 157 ++++++++++++++++++ cookbook/controller/index.rst | 1 + cookbook/map.rst.inc | 1 + 3 files changed, 159 insertions(+) create mode 100644 cookbook/controller/argument_value_resolver.rst diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst new file mode 100644 index 00000000000..afd6c703296 --- /dev/null +++ b/cookbook/controller/argument_value_resolver.rst @@ -0,0 +1,157 @@ +.. index:: + single: Controller; Argument Value Resolvers + +Extending Action Argument Resolving +=================================== + +.. versionadded:: 3.1 + The ``ArgumentResolver`` and value resolvers are added in Symfony 3.1. + +In the book, you've learned that you can add the :class:`Symfony\\Component\\HttpFoundation\\Request` +as action argument and it will be injected into the method. This is done via the +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. The ``ArgumentResolver`` uses +several value resolvers which allow you to extend the functionality. + + +Functionality Shipped With The HttpKernel +----------------------------------------- + +Symfony ships with four value resolvers in the HttpKernel: + - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` + attempts to find a request attribute that matches the name of the argument. + + - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` + injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. + + - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` + will set the default value of the argument if present and the argument is optional. + + - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` + verifies in the request if your data is an array and will add all of them to the argument list. + When the action is called, the last (variadic) argument will contain all the values of this array. + +.. note:: + In older versions of Symfony this logic was all resolved within the ``ControllerResolver``. The + old functionality is moved to the ``LegacyArgumentResolver``, which contains the previously + used resolving logic. + +Adding a New Value Resolver +--------------------------- + +Adding a new value resolver requires one class and one service defintion. In our next example, we +will be creating a shortcut to inject the ``User`` object from our security. Given we write the following +action:: + + namespace AppBundle\Controller; + + class UserController + { + public function indexAction(User $user) + { + return new Response('Hello '.$user->getUsername().'!'); + } + } + +Somehow we will have to get the ``User`` object and inject it into our action. This can be done +by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. +This interface specifies that we have to implement two methods:: + + interface ArgumentValueResolverInterface + { + public function supports(Request $request, ArgumentMetadata $argument); + public function resolve(Request $request, ArgumentMetadata $argument); + } + + - The ``supports()`` method is used to check whether the resolver supports the given argument. It will + only continue if it returns ``true``. + + - The ``resolve()`` method will be used to resolve the actual value just acknowledged by + ``supports()``. Once a value is resolved you can ``yield`` the value to the ``ArgumentResolver``. + + - The ``Request`` object is the current ``Request`` which would also be injected into your + action in the forementioned functionality. + + - The :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`` represents + information retrieved from the method signature for the current argument it's trying to resolve. + +.. note:: + The ``ArgumentMetadata`` is a simple data container created by the + :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory``. This + factory will work on every supported php version but might give different results. E.g. the + ``isVariadic()`` will never return true on php 5.5 and only on php 7.0 and higher it will give + you basic types when calling ``getType()``. + +Now that we know what to do, we can implement this interface. In order to get the current ``User``, +we will have to get it from the ``TokenInterface`` which is in the ``TokenStorageInterface``:: + + namespace AppBundle\ArgumentValueResolver; + + use AppBundle\User; + use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; + use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; + + class UserValueResolver implements ArgumentValueResolverInterface + { + private $tokenStorage; + + public function __construct(TokenStorageInterface $tokenStorage) + { + $this->tokenStorage = $tokenStorage; + } + + public function supports(Request $request, ArgumentMetadata $argument) + { + return ($token = $this->tokenStorage->getToken()) && $token->getUser() instanceof User; + } + + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield $this->tokenStorage->getToken()->getUser(); + } + } + +This was pretty simple, now all we have to do is add the configuration for the service container. This +can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. + +.. note:: + While adding a priority is optional, it's recommended to add one to make sure the expected + value is injected. The ``ArgumentFromAttributeResolver`` has a priority of 100. As this + one is responsible for fetching attributes from the ``Request``, it's also recommended to + trigger your custom value resolver with a lower priority. This makes sure the argument + resolvers are not triggered in (e.g.) subrequests if you pass your user along: + ``{{ render(controller('AppBundle:User:index', {'user', app.user})) }}``. + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + services: + app.value_resolver.user: + class: AppBundle\ArgumentValueResolver\UserValueResolver + arguments: + - '@security.token_storage' + tags: + - { name: kernel.argument_resolver, priority: 50 } + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; + + $defintion = new Definition( + 'AppBundle\ArgumentValueResolver\UserValueResolver', + array(new Reference('security.token_storage')) + ); + $definition->addTag('kernel.argument_resolver', array('priority' => 50)); + $container->setDefinition('app.value_resolver.user', $definition); diff --git a/cookbook/controller/index.rst b/cookbook/controller/index.rst index 9ee8ca56a17..91972c92c26 100644 --- a/cookbook/controller/index.rst +++ b/cookbook/controller/index.rst @@ -7,3 +7,4 @@ Controller error_pages service upload_file + argument_value_resolver diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index dac8ec5c77d..06a2b3d0f67 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -56,6 +56,7 @@ * :doc:`/cookbook/controller/error_pages` * :doc:`/cookbook/controller/service` * :doc:`/cookbook/controller/upload_file` + * :doc:`/cookbook/controller/argument_value_resolver` * **Debugging** From 7ddf5d67a5dce3253e4b308b19dcd3ff145f41b3 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Wed, 6 Apr 2016 17:07:08 +0200 Subject: [PATCH 02/17] we>you, php>PHP, fixed directive start & list style --- .../controller/argument_value_resolver.rst | 37 ++++++++++--------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index afd6c703296..cb918fcd41b 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -17,20 +17,21 @@ Functionality Shipped With The HttpKernel ----------------------------------------- Symfony ships with four value resolvers in the HttpKernel: - - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` + * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` attempts to find a request attribute that matches the name of the argument. - - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` + * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. - - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` + * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` will set the default value of the argument if present and the argument is optional. - - The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` + * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` verifies in the request if your data is an array and will add all of them to the argument list. When the action is called, the last (variadic) argument will contain all the values of this array. .. note:: + In older versions of Symfony this logic was all resolved within the ``ControllerResolver``. The old functionality is moved to the ``LegacyArgumentResolver``, which contains the previously used resolving logic. @@ -39,7 +40,7 @@ Adding a New Value Resolver --------------------------- Adding a new value resolver requires one class and one service defintion. In our next example, we -will be creating a shortcut to inject the ``User`` object from our security. Given we write the following +will be creating a shortcut to inject the ``User`` object from our security. Given you write the following action:: namespace AppBundle\Controller; @@ -52,9 +53,9 @@ action:: } } -Somehow we will have to get the ``User`` object and inject it into our action. This can be done +Somehow you will have to get the ``User`` object and inject it into our action. This can be done by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. -This interface specifies that we have to implement two methods:: +This interface specifies that you have to implement two methods:: interface ArgumentValueResolverInterface { @@ -62,27 +63,28 @@ This interface specifies that we have to implement two methods:: public function resolve(Request $request, ArgumentMetadata $argument); } - - The ``supports()`` method is used to check whether the resolver supports the given argument. It will + * The ``supports()`` method is used to check whether the resolver supports the given argument. It will only continue if it returns ``true``. - - The ``resolve()`` method will be used to resolve the actual value just acknowledged by + * The ``resolve()`` method will be used to resolve the actual value just acknowledged by ``supports()``. Once a value is resolved you can ``yield`` the value to the ``ArgumentResolver``. - - The ``Request`` object is the current ``Request`` which would also be injected into your + * The ``Request`` object is the current ``Request`` which would also be injected into your action in the forementioned functionality. - - The :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`` represents + * The :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`` represents information retrieved from the method signature for the current argument it's trying to resolve. .. note:: + The ``ArgumentMetadata`` is a simple data container created by the :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory``. This - factory will work on every supported php version but might give different results. E.g. the - ``isVariadic()`` will never return true on php 5.5 and only on php 7.0 and higher it will give + factory will work on every supported PHP version but might give different results. E.g. the + ``isVariadic()`` will never return true on PHP 5.5 and only on PHP 7.0 and higher it will give you basic types when calling ``getType()``. -Now that we know what to do, we can implement this interface. In order to get the current ``User``, -we will have to get it from the ``TokenInterface`` which is in the ``TokenStorageInterface``:: +Now that you know what to do, you can implement this interface. In order to get the current ``User``, +you will have to get it from the ``TokenInterface`` which is in the ``TokenStorageInterface``:: namespace AppBundle\ArgumentValueResolver; @@ -110,16 +112,17 @@ we will have to get it from the ``TokenInterface`` which is in the ``TokenStorag } } -This was pretty simple, now all we have to do is add the configuration for the service container. This +This was pretty simple, now all you have to do is add the configuration for the service container. This can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. .. note:: + While adding a priority is optional, it's recommended to add one to make sure the expected value is injected. The ``ArgumentFromAttributeResolver`` has a priority of 100. As this one is responsible for fetching attributes from the ``Request``, it's also recommended to trigger your custom value resolver with a lower priority. This makes sure the argument resolvers are not triggered in (e.g.) subrequests if you pass your user along: - ``{{ render(controller('AppBundle:User:index', {'user', app.user})) }}``. + ``{{ render(controller('AppBundle:User:index', {'user', app.user})) }}``. .. configuration-block:: From 1a19d2e6e738bcbb993c29a0fb5fea47cca7f550 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Wed, 6 Apr 2016 17:14:57 +0200 Subject: [PATCH 03/17] Fixed the list indents --- .../controller/argument_value_resolver.rst | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index cb918fcd41b..abbcf4e63d1 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -18,17 +18,17 @@ Functionality Shipped With The HttpKernel Symfony ships with four value resolvers in the HttpKernel: * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` - attempts to find a request attribute that matches the name of the argument. + attempts to find a request attribute that matches the name of the argument. * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` - injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. + injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` - will set the default value of the argument if present and the argument is optional. + will set the default value of the argument if present and the argument is optional. * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` - verifies in the request if your data is an array and will add all of them to the argument list. - When the action is called, the last (variadic) argument will contain all the values of this array. + verifies in the request if your data is an array and will add all of them to the argument list. + When the action is called, the last (variadic) argument will contain all the values of this array. .. note:: @@ -64,16 +64,16 @@ This interface specifies that you have to implement two methods:: } * The ``supports()`` method is used to check whether the resolver supports the given argument. It will - only continue if it returns ``true``. + only continue if it returns ``true``. * The ``resolve()`` method will be used to resolve the actual value just acknowledged by - ``supports()``. Once a value is resolved you can ``yield`` the value to the ``ArgumentResolver``. + ``supports()``. Once a value is resolved you can ``yield`` the value to the ``ArgumentResolver``. * The ``Request`` object is the current ``Request`` which would also be injected into your - action in the forementioned functionality. + action in the forementioned functionality. * The :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`` represents - information retrieved from the method signature for the current argument it's trying to resolve. + information retrieved from the method signature for the current argument it's trying to resolve. .. note:: From f491199c2ae8946ca83232fb12ec71a67b79b178 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Wed, 6 Apr 2016 17:22:28 +0200 Subject: [PATCH 04/17] Added missing use statements to example --- cookbook/controller/argument_value_resolver.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index abbcf4e63d1..28bd7d90115 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -45,6 +45,9 @@ action:: namespace AppBundle\Controller; + use AppBundle\User; + use Symfony\Component\HttpFoundation\Response; + class UserController { public function indexAction(User $user) From a07fcc350aa7301aac6f0741d721a6c08cf7c8a8 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Thu, 7 Apr 2016 08:22:27 +0200 Subject: [PATCH 05/17] Processed feedback from @wouterj --- .../controller/argument_value_resolver.rst | 101 ++++++++++-------- 1 file changed, 58 insertions(+), 43 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 28bd7d90115..50dd7ae0f40 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -7,45 +7,46 @@ Extending Action Argument Resolving .. versionadded:: 3.1 The ``ArgumentResolver`` and value resolvers are added in Symfony 3.1. -In the book, you've learned that you can add the :class:`Symfony\\Component\\HttpFoundation\\Request` -as action argument and it will be injected into the method. This is done via the -:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. The ``ArgumentResolver`` uses -several value resolvers which allow you to extend the functionality. +In the book, you've learned that you can get the :class:`Symfony\\Component\\HttpFoundation\\Request` +object by adding a ``Request`` argument to your controller. This is done via the +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By creating and registering custom +argument value resolvers, you can extend this functionality. Functionality Shipped With The HttpKernel ----------------------------------------- Symfony ships with four value resolvers in the HttpKernel: - * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` - attempts to find a request attribute that matches the name of the argument. - * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` - injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` + Attempts to find a request attribute that matches the name of the argument. - * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` - will set the default value of the argument if present and the argument is optional. +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` + Injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. - * The :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` - verifies in the request if your data is an array and will add all of them to the argument list. +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` + Will set the default value of the argument if present and the argument is optional. + +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` + Verifies in the request if your data is an array and will add all of them to the argument list. When the action is called, the last (variadic) argument will contain all the values of this array. .. note:: - In older versions of Symfony this logic was all resolved within the ``ControllerResolver``. The - old functionality is moved to the ``LegacyArgumentResolver``, which contains the previously + Prior to Symfony 3.1, this logic was resolved within the ``ControllerResolver``. The old + functionality is moved to the ``LegacyArgumentResolver``, which contains the previously used resolving logic. -Adding a New Value Resolver ---------------------------- +Adding a Custom Value Resolver +------------------------------ -Adding a new value resolver requires one class and one service defintion. In our next example, we -will be creating a shortcut to inject the ``User`` object from our security. Given you write the following -action:: +Adding a new value resolver requires one class and one service defintion. In the next example, +you'll create a value resolver to inject the ``User`` object from the security system.. Given +you write the following action:: namespace AppBundle\Controller; - use AppBundle\User; + use AppBundle\Entity\User; use Symfony\Component\HttpFoundation\Response; class UserController @@ -56,7 +57,7 @@ action:: } } -Somehow you will have to get the ``User`` object and inject it into our action. This can be done +Somehow you will have to get the ``User`` object and inject it into the controller. This can be done by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. This interface specifies that you have to implement two methods:: @@ -66,32 +67,32 @@ This interface specifies that you have to implement two methods:: public function resolve(Request $request, ArgumentMetadata $argument); } - * The ``supports()`` method is used to check whether the resolver supports the given argument. It will - only continue if it returns ``true``. - - * The ``resolve()`` method will be used to resolve the actual value just acknowledged by - ``supports()``. Once a value is resolved you can ``yield`` the value to the ``ArgumentResolver``. +``supports()`` + This method is used to check whether the value resolver supports the + given argument. ``resolve()`` will only be executed when this returns ``true``. +``resolve()`` + This method will resolve the actual value for the argument. Once the value + is resolved, you should `yield`_ the value to the ``ArgumentResolver``. - * The ``Request`` object is the current ``Request`` which would also be injected into your - action in the forementioned functionality. - - * The :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`` represents - information retrieved from the method signature for the current argument it's trying to resolve. +Both methods get the ``Request`` object, which is the current request, and an +:class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`. +This object contains all informations retrieved from the method signature for the +current argument. .. note:: The ``ArgumentMetadata`` is a simple data container created by the - :class:``Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory``. This + :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory`. This factory will work on every supported PHP version but might give different results. E.g. the ``isVariadic()`` will never return true on PHP 5.5 and only on PHP 7.0 and higher it will give you basic types when calling ``getType()``. -Now that you know what to do, you can implement this interface. In order to get the current ``User``, -you will have to get it from the ``TokenInterface`` which is in the ``TokenStorageInterface``:: +Now that you know what to do, you can implement this interface. To get the current ``User``, you need +the current security token. This token can be retrieved from the token storage.:: namespace AppBundle\ArgumentValueResolver; - use AppBundle\User; + use AppBundle\Entity\User; use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; @@ -106,7 +107,12 @@ you will have to get it from the ``TokenInterface`` which is in the ``TokenStora public function supports(Request $request, ArgumentMetadata $argument) { - return ($token = $this->tokenStorage->getToken()) && $token->getUser() instanceof User; + if (User::class !== $argument->getType()) { + return false; + } + + $token = $this->tokenStorage->getToken() + return $token->getUser() instanceof User; } public function resolve(Request $request, ArgumentMetadata $argument) @@ -115,7 +121,7 @@ you will have to get it from the ``TokenInterface`` which is in the ``TokenStora } } -This was pretty simple, now all you have to do is add the configuration for the service container. This +That's it! Now all you have to do is add the configuration for the service container. This can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. .. note:: @@ -143,12 +149,19 @@ can be done by tagging the service with ``kernel.argument_resolver`` and adding .. code-block:: xml - - - - - - + + + + + + + + + + + .. code-block:: php @@ -161,3 +174,5 @@ can be done by tagging the service with ``kernel.argument_resolver`` and adding ); $definition->addTag('kernel.argument_resolver', array('priority' => 50)); $container->setDefinition('app.value_resolver.user', $definition); + +.. _`yield`: http://php.net/manual/en/language.generators.syntax.php From 2e41c0752440a6f088267bde21c2ac68b89aad91 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 11 Apr 2016 08:46:27 +0200 Subject: [PATCH 06/17] Added some extra info about the DefaultValueResolver --- .../controller/argument_value_resolver.rst | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 50dd7ae0f40..00fdee701d6 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -12,7 +12,6 @@ object by adding a ``Request`` argument to your controller. This is done via the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By creating and registering custom argument value resolvers, you can extend this functionality. - Functionality Shipped With The HttpKernel ----------------------------------------- @@ -34,14 +33,13 @@ Symfony ships with four value resolvers in the HttpKernel: .. note:: Prior to Symfony 3.1, this logic was resolved within the ``ControllerResolver``. The old - functionality is moved to the ``LegacyArgumentResolver``, which contains the previously - used resolving logic. + functionality is rewritten to the aforementioned value resolvers. Adding a Custom Value Resolver ------------------------------ Adding a new value resolver requires one class and one service defintion. In the next example, -you'll create a value resolver to inject the ``User`` object from the security system.. Given +you'll create a value resolver to inject the ``User`` object from the security system. Given you write the following action:: namespace AppBundle\Controller; @@ -76,7 +74,7 @@ This interface specifies that you have to implement two methods:: Both methods get the ``Request`` object, which is the current request, and an :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`. -This object contains all informations retrieved from the method signature for the +This object contains all information retrieved from the method signature for the current argument. .. note:: @@ -121,6 +119,23 @@ the current security token. This token can be retrieved from the token storage.: } } +In order to get the actual ``User`` object in your argument, the given value should fulfill the +following requirements: + +* The argument type (of the method signature) must be typehinted as ``User``; +* The security token must be present; +* The value should be an instance of the ``User``. + +When all those requirements are met and true is returned, the ``ArgumentResolver`` calls +``resolve()`` with the same values as it called ``supports()``. + +.. tip:: + + You can leverage the ``DefaultValueResolver`` by making your resolver accept only mandatory + arguments. Given your signature is `User $user = null`, the above example will not hit ``resolve()`` + as one of the conditions does not match. Eventually when the ``DefaultValueResolver`` is asked to + resolve this, it will simply add the default value from the method signature, which results in ``null``. + That's it! Now all you have to do is add the configuration for the service container. This can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. From 7cdc96b09849d1431658785136ae78f17c11e25a Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 11 Apr 2016 14:52:22 +0200 Subject: [PATCH 07/17] Fixed a typo in code example --- cookbook/controller/argument_value_resolver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 00fdee701d6..7c09b1632d8 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -109,7 +109,7 @@ the current security token. This token can be retrieved from the token storage.: return false; } - $token = $this->tokenStorage->getToken() + $token = $this->tokenStorage->getToken(); return $token->getUser() instanceof User; } From 7d00d8ced8a0d80bc2418e6244c541f23fa56865 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 12 Apr 2016 08:08:25 +0200 Subject: [PATCH 08/17] Fixed a wrong tag name --- cookbook/controller/argument_value_resolver.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 7c09b1632d8..473afb99cd3 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -159,7 +159,7 @@ can be done by tagging the service with ``kernel.argument_resolver`` and adding arguments: - '@security.token_storage' tags: - - { name: kernel.argument_resolver, priority: 50 } + - { name: controller_argument.value_resolver, priority: 50 } .. code-block:: xml @@ -172,7 +172,7 @@ can be done by tagging the service with ``kernel.argument_resolver`` and adding - + @@ -187,7 +187,7 @@ can be done by tagging the service with ``kernel.argument_resolver`` and adding 'AppBundle\ArgumentValueResolver\UserValueResolver', array(new Reference('security.token_storage')) ); - $definition->addTag('kernel.argument_resolver', array('priority' => 50)); + $definition->addTag('controller_argument.value_resolver', array('priority' => 50)); $container->setDefinition('app.value_resolver.user', $definition); .. _`yield`: http://php.net/manual/en/language.generators.syntax.php From f9cbe717a50d20f9abc4f720219cab59b490a1b6 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 12 Apr 2016 09:09:16 +0200 Subject: [PATCH 09/17] Added instanceof check in example --- cookbook/controller/argument_value_resolver.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 473afb99cd3..0e4290a9a3b 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -110,6 +110,11 @@ the current security token. This token can be retrieved from the token storage.: } $token = $this->tokenStorage->getToken(); + + if (!$token instanceof TokenInterface) { + return false; + } + return $token->getUser() instanceof User; } From 4c6ed2abfbea3aa5a2f1acb15a54336ee2b9fd0a Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 12 Apr 2016 12:04:28 +0200 Subject: [PATCH 10/17] Respecting the line length --- .../controller/argument_value_resolver.rst | 84 +++++++++++-------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 0e4290a9a3b..8495340c2a6 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -8,9 +8,10 @@ Extending Action Argument Resolving The ``ArgumentResolver`` and value resolvers are added in Symfony 3.1. In the book, you've learned that you can get the :class:`Symfony\\Component\\HttpFoundation\\Request` -object by adding a ``Request`` argument to your controller. This is done via the -:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By creating and registering custom -argument value resolvers, you can extend this functionality. +object by adding a ``Request`` argument to your controller. This is done +via the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. +By creating and registering custom argument value resolvers, you can extend +this functionality. Functionality Shipped With The HttpKernel ----------------------------------------- @@ -21,26 +22,29 @@ Symfony ships with four value resolvers in the HttpKernel: Attempts to find a request attribute that matches the name of the argument. :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver` - Injects the current ``Request`` if type-hinted with ``Request``, or a sub-class thereof. + Injects the current ``Request`` if type-hinted with ``Request``, or a + sub-class thereof. :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver` - Will set the default value of the argument if present and the argument is optional. + Will set the default value of the argument if present and the argument + is optional. :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver` - Verifies in the request if your data is an array and will add all of them to the argument list. - When the action is called, the last (variadic) argument will contain all the values of this array. + Verifies in the request if your data is an array and will add all of + them to the argument list. When the action is called, the last (variadic) + argument will contain all the values of this array. .. note:: - Prior to Symfony 3.1, this logic was resolved within the ``ControllerResolver``. The old - functionality is rewritten to the aforementioned value resolvers. + Prior to Symfony 3.1, this logic was resolved within the ``ControllerResolver``. + The old functionality is rewritten to the aforementioned value resolvers. Adding a Custom Value Resolver ------------------------------ -Adding a new value resolver requires one class and one service defintion. In the next example, -you'll create a value resolver to inject the ``User`` object from the security system. Given -you write the following action:: +Adding a new value resolver requires one class and one service defintion. +In the next example, you'll create a value resolver to inject the ``User`` +object from the security system. Given you write the following action:: namespace AppBundle\Controller; @@ -55,8 +59,8 @@ you write the following action:: } } -Somehow you will have to get the ``User`` object and inject it into the controller. This can be done -by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. +Somehow you will have to get the ``User`` object and inject it into the controller. +This can be done by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. This interface specifies that you have to implement two methods:: interface ArgumentValueResolverInterface @@ -74,19 +78,21 @@ This interface specifies that you have to implement two methods:: Both methods get the ``Request`` object, which is the current request, and an :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`. -This object contains all information retrieved from the method signature for the -current argument. +This object contains all information retrieved from the method signature for +the current argument. .. note:: The ``ArgumentMetadata`` is a simple data container created by the - :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory`. This - factory will work on every supported PHP version but might give different results. E.g. the - ``isVariadic()`` will never return true on PHP 5.5 and only on PHP 7.0 and higher it will give - you basic types when calling ``getType()``. + :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory`. + This factory will work on every supported PHP version but might give + different results. E.g. the ``isVariadic()`` will never return true on + PHP 5.5 and only on PHP 7.0 and higher it will give you basic types when + calling ``getType()``. -Now that you know what to do, you can implement this interface. To get the current ``User``, you need -the current security token. This token can be retrieved from the token storage.:: +Now that you know what to do, you can implement this interface. To get the +current ``User``, you need the current security token. This token can be +retrieved from the token storage:: namespace AppBundle\ArgumentValueResolver; @@ -124,33 +130,37 @@ the current security token. This token can be retrieved from the token storage.: } } -In order to get the actual ``User`` object in your argument, the given value should fulfill the -following requirements: +In order to get the actual ``User`` object in your argument, the given value +should fulfill the following requirements: * The argument type (of the method signature) must be typehinted as ``User``; * The security token must be present; * The value should be an instance of the ``User``. -When all those requirements are met and true is returned, the ``ArgumentResolver`` calls -``resolve()`` with the same values as it called ``supports()``. +When all those requirements are met and true is returned, the ``ArgumentResolver`` +calls ``resolve()`` with the same values as it called ``supports()``. .. tip:: - You can leverage the ``DefaultValueResolver`` by making your resolver accept only mandatory - arguments. Given your signature is `User $user = null`, the above example will not hit ``resolve()`` - as one of the conditions does not match. Eventually when the ``DefaultValueResolver`` is asked to - resolve this, it will simply add the default value from the method signature, which results in ``null``. + You can leverage the ``DefaultValueResolver`` by making your resolver + accept only mandatory arguments. Given your signature is `User $user = null`, + the above example will not hit ``resolve()`` as one of the conditions + does not match. Eventually when the ``DefaultValueResolver`` is asked + to resolve this, it will simply add the default value from the method + signature, which results in ``null``. -That's it! Now all you have to do is add the configuration for the service container. This -can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. +That's it! Now all you have to do is add the configuration for the service +container. This can be done by tagging the service with ``kernel.argument_resolver`` +and adding a priority. .. note:: - While adding a priority is optional, it's recommended to add one to make sure the expected - value is injected. The ``ArgumentFromAttributeResolver`` has a priority of 100. As this - one is responsible for fetching attributes from the ``Request``, it's also recommended to - trigger your custom value resolver with a lower priority. This makes sure the argument - resolvers are not triggered in (e.g.) subrequests if you pass your user along: + While adding a priority is optional, it's recommended to add one to + make sure the expected value is injected. The ``ArgumentFromAttributeResolver`` + has a priority of 100. As this one is responsible for fetching attributes + from the ``Request``, it's also recommended to trigger your custom value + resolver with a lower priority. This makes sure the argument resolvers + are not triggered in (e.g.) subrequests if you pass your user along: ``{{ render(controller('AppBundle:User:index', {'user', app.user})) }}``. .. configuration-block:: From 9784406850e1a35d6aca3b189292830f7c10e8dc Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Thu, 14 Apr 2016 13:28:27 +0200 Subject: [PATCH 11/17] Fixed the tag name --- cookbook/controller/argument_value_resolver.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 8495340c2a6..8f4fec43826 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -174,7 +174,7 @@ and adding a priority. arguments: - '@security.token_storage' tags: - - { name: controller_argument.value_resolver, priority: 50 } + - { name: controller.argument_value_resolver, priority: 50 } .. code-block:: xml @@ -187,7 +187,7 @@ and adding a priority. - + @@ -202,7 +202,7 @@ and adding a priority. 'AppBundle\ArgumentValueResolver\UserValueResolver', array(new Reference('security.token_storage')) ); - $definition->addTag('controller_argument.value_resolver', array('priority' => 50)); + $definition->addTag('controller.argument_value_resolver', array('priority' => 50)); $container->setDefinition('app.value_resolver.user', $definition); .. _`yield`: http://php.net/manual/en/language.generators.syntax.php From e3d1b48acf7dde3d167f6d1627f1264b1dca2224 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Mon, 18 Apr 2016 10:26:32 +0200 Subject: [PATCH 12/17] Tried to make the default value resolving more clear --- .../controller/argument_value_resolver.rst | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 8f4fec43826..ce1462ec56a 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -5,12 +5,13 @@ Extending Action Argument Resolving =================================== .. versionadded:: 3.1 - The ``ArgumentResolver`` and value resolvers are added in Symfony 3.1. + The ``ArgumentResolver`` and value resolvers were introduced in Symfony 3.1. In the book, you've learned that you can get the :class:`Symfony\\Component\\HttpFoundation\\Request` -object by adding a ``Request`` argument to your controller. This is done -via the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. -By creating and registering custom argument value resolvers, you can extend +object via an argument in your controller. This argument has to be typehinted +by the ``Request`` class in order to be recognized. This is done via the +:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By +creating and registering custom argument value resolvers, you can extend this functionality. Functionality Shipped With The HttpKernel @@ -74,7 +75,7 @@ This interface specifies that you have to implement two methods:: given argument. ``resolve()`` will only be executed when this returns ``true``. ``resolve()`` This method will resolve the actual value for the argument. Once the value - is resolved, you should `yield`_ the value to the ``ArgumentResolver``. + is resolved, you must `yield`_ the value to the ``ArgumentResolver``. Both methods get the ``Request`` object, which is the current request, and an :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`. @@ -131,24 +132,15 @@ retrieved from the token storage:: } In order to get the actual ``User`` object in your argument, the given value -should fulfill the following requirements: +must fulfill the following requirements: -* The argument type (of the method signature) must be typehinted as ``User``; -* The security token must be present; -* The value should be an instance of the ``User``. +* An argument must be typehinted as ``User`` in your action method signature; +* A security token must be present; +* The value must be an instance of the ``User``. When all those requirements are met and true is returned, the ``ArgumentResolver`` calls ``resolve()`` with the same values as it called ``supports()``. -.. tip:: - - You can leverage the ``DefaultValueResolver`` by making your resolver - accept only mandatory arguments. Given your signature is `User $user = null`, - the above example will not hit ``resolve()`` as one of the conditions - does not match. Eventually when the ``DefaultValueResolver`` is asked - to resolve this, it will simply add the default value from the method - signature, which results in ``null``. - That's it! Now all you have to do is add the configuration for the service container. This can be done by tagging the service with ``kernel.argument_resolver`` and adding a priority. @@ -206,3 +198,33 @@ and adding a priority. $container->setDefinition('app.value_resolver.user', $definition); .. _`yield`: http://php.net/manual/en/language.generators.syntax.php + +Creating an Optional User Resolver +---------------------------------- + +When you want your user to be optional, e.g. when your page is behind a +firewall that also allows anonymous authentication, you might not always +have a security user. To get this to work, you only have to change your +method signature to `UserInterface $user = null`. + +When you take the ``UserValueResolver`` from the previous example, you can +see there is no logic in case of failure to comply to the requirements. Default +values in are defined in the signature and are available in the ``ArgumentMetadata``. +When a default value is available and there are no resolvers that support +the given value, the ``DefaultValueResolver`` is triggered. This Resolver +takes the default value of your argument and yields it to the argument list:: + + namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + + final class DefaultValueResolver implements ArgumentValueResolverInterface + { + public function supports(Request $request, ArgumentMetadata $argument) + { + return $argument->hasDefaultValue(); + } + + public function resolve(Request $request, ArgumentMetadata $argument) + { + yield $argument->getDefaultValue(); + } + } From 55a87b50dcbc5ede77436bca3d9fa90165afd2a2 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Fri, 29 Apr 2016 15:50:58 +0200 Subject: [PATCH 13/17] Minor fixes --- cookbook/controller/argument_value_resolver.rst | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index ce1462ec56a..ca900ab7264 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -149,7 +149,7 @@ and adding a priority. While adding a priority is optional, it's recommended to add one to make sure the expected value is injected. The ``ArgumentFromAttributeResolver`` - has a priority of 100. As this one is responsible for fetching attributes + has a priority of 100. As this one is responsible for fetching attributes from the ``Request``, it's also recommended to trigger your custom value resolver with a lower priority. This makes sure the argument resolvers are not triggered in (e.g.) subrequests if you pass your user along: @@ -197,8 +197,6 @@ and adding a priority. $definition->addTag('controller.argument_value_resolver', array('priority' => 50)); $container->setDefinition('app.value_resolver.user', $definition); -.. _`yield`: http://php.net/manual/en/language.generators.syntax.php - Creating an Optional User Resolver ---------------------------------- @@ -209,13 +207,17 @@ method signature to `UserInterface $user = null`. When you take the ``UserValueResolver`` from the previous example, you can see there is no logic in case of failure to comply to the requirements. Default -values in are defined in the signature and are available in the ``ArgumentMetadata``. +values are defined in the signature and are available in the ``ArgumentMetadata``. When a default value is available and there are no resolvers that support the given value, the ``DefaultValueResolver`` is triggered. This Resolver takes the default value of your argument and yields it to the argument list:: namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver; + use Symfony\Component\HttpFoundation\Request; + use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface; + use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata; + final class DefaultValueResolver implements ArgumentValueResolverInterface { public function supports(Request $request, ArgumentMetadata $argument) @@ -228,3 +230,5 @@ takes the default value of your argument and yields it to the argument list:: yield $argument->getDefaultValue(); } } + +.. _`yield`: http://php.net/manual/en/language.generators.syntax.php From 8d30575b43d1aeafa38ce8537c73ac621778daf3 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Fri, 6 May 2016 07:56:25 +0200 Subject: [PATCH 14/17] Added instance --- cookbook/controller/argument_value_resolver.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index ca900ab7264..51dcffa2e3a 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -78,9 +78,9 @@ This interface specifies that you have to implement two methods:: is resolved, you must `yield`_ the value to the ``ArgumentResolver``. Both methods get the ``Request`` object, which is the current request, and an -:class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`. -This object contains all information retrieved from the method signature for -the current argument. +:class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata` +instance. This object contains all information retrieved from the method signature +for the current argument. .. note:: From dd225e8cbbaccdfaebeceb774ffd8a06c31e30fe Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 17 May 2016 08:16:47 +0200 Subject: [PATCH 15/17] Feedback from PR --- .../controller/argument_value_resolver.rst | 23 ++++--------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 51dcffa2e3a..7cdf791764a 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -17,7 +17,7 @@ this functionality. Functionality Shipped With The HttpKernel ----------------------------------------- -Symfony ships with four value resolvers in the HttpKernel: +Symfony ships with four value resolvers in the HttpKernel component: :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver` Attempts to find a request attribute that matches the name of the argument. @@ -62,13 +62,7 @@ object from the security system. Given you write the following action:: Somehow you will have to get the ``User`` object and inject it into the controller. This can be done by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`. -This interface specifies that you have to implement two methods:: - - interface ArgumentValueResolverInterface - { - public function supports(Request $request, ArgumentMetadata $argument); - public function resolve(Request $request, ArgumentMetadata $argument); - } +This interface specifies that you have to implement two methods: ``supports()`` This method is used to check whether the value resolver supports the @@ -82,15 +76,6 @@ Both methods get the ``Request`` object, which is the current request, and an instance. This object contains all information retrieved from the method signature for the current argument. -.. note:: - - The ``ArgumentMetadata`` is a simple data container created by the - :class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory`. - This factory will work on every supported PHP version but might give - different results. E.g. the ``isVariadic()`` will never return true on - PHP 5.5 and only on PHP 7.0 and higher it will give you basic types when - calling ``getType()``. - Now that you know what to do, you can implement this interface. To get the current ``User``, you need the current security token. This token can be retrieved from the token storage:: @@ -134,7 +119,7 @@ retrieved from the token storage:: In order to get the actual ``User`` object in your argument, the given value must fulfill the following requirements: -* An argument must be typehinted as ``User`` in your action method signature; +* An argument must be type-hinted as ``User`` in your action method signature; * A security token must be present; * The value must be an instance of the ``User``. @@ -142,7 +127,7 @@ When all those requirements are met and true is returned, the ``ArgumentResolver calls ``resolve()`` with the same values as it called ``supports()``. That's it! Now all you have to do is add the configuration for the service -container. This can be done by tagging the service with ``kernel.argument_resolver`` +container. This can be done by tagging the service with ``controller.argument_resolver`` and adding a priority. .. note:: From ca014a637345d0898a789759ab0db103e6bfaf30 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 17 May 2016 09:29:31 +0200 Subject: [PATCH 16/17] Fixed sub-title case --- cookbook/controller/argument_value_resolver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 7cdf791764a..470e9b3ac37 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -14,7 +14,7 @@ by the ``Request`` class in order to be recognized. This is done via the creating and registering custom argument value resolvers, you can extend this functionality. -Functionality Shipped With The HttpKernel +Functionality Shipped with the HttpKernel ----------------------------------------- Symfony ships with four value resolvers in the HttpKernel component: From 14d77e13147cd740ef41e9a6854f057261f40e10 Mon Sep 17 00:00:00 2001 From: Iltar van der Berg Date: Tue, 17 May 2016 09:30:45 +0200 Subject: [PATCH 17/17] typehinted > type-hinted --- cookbook/controller/argument_value_resolver.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cookbook/controller/argument_value_resolver.rst b/cookbook/controller/argument_value_resolver.rst index 470e9b3ac37..6f495504d1f 100644 --- a/cookbook/controller/argument_value_resolver.rst +++ b/cookbook/controller/argument_value_resolver.rst @@ -8,7 +8,7 @@ Extending Action Argument Resolving The ``ArgumentResolver`` and value resolvers were introduced in Symfony 3.1. In the book, you've learned that you can get the :class:`Symfony\\Component\\HttpFoundation\\Request` -object via an argument in your controller. This argument has to be typehinted +object via an argument in your controller. This argument has to be type-hinted by the ``Request`` class in order to be recognized. This is done via the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By creating and registering custom argument value resolvers, you can extend