Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 66ce882

Browse filesBrowse files
committed
[#6438] Fix class names and shorten article after merging
1 parent ae73303 commit 66ce882
Copy full SHA for 66ce882

File tree

Expand file treeCollapse file tree

1 file changed

+47
-65
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+47
-65
lines changed

‎cookbook/controller/argument_value_resolver.rst

Copy file name to clipboardExpand all lines: cookbook/controller/argument_value_resolver.rst
+47-65Lines changed: 47 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,34 @@ Extending Action Argument Resolving
77
.. versionadded:: 3.1
88
The ``ArgumentResolver`` and value resolvers were introduced in Symfony 3.1.
99

10-
In the book, you've learned that you can get the :class:`Symfony\\Component\\HttpFoundation\\Request`
11-
object via an argument in your controller. This argument has to be type-hinted
12-
by the ``Request`` class in order to be recognized. This is done via the
10+
In the book, you've learned that you can get the
11+
:class:`Symfony\\Component\\HttpFoundation\\Request` object via an argument in
12+
your controller. This argument has to be type-hinted by the ``Request`` class
13+
in order to be recognized. This is done via the
1314
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver`. By
14-
creating and registering custom argument value resolvers, you can extend
15-
this functionality.
15+
creating and registering custom argument value resolvers, you can extend this
16+
functionality.
1617

1718
Functionality Shipped with the HttpKernel
1819
-----------------------------------------
1920

2021
Symfony ships with four value resolvers in the HttpKernel component:
2122

22-
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\ArgumentFromAttributeResolver`
23+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestAttributeValueResolver`
2324
Attempts to find a request attribute that matches the name of the argument.
2425

25-
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\RequestValueResolver`
26-
Injects the current ``Request`` if type-hinted with ``Request``, or a
27-
sub-class thereof.
26+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\RequestValueResolver`
27+
Injects the current ``Request`` if type-hinted with ``Request`` or a class
28+
extending ``Request``.
2829

29-
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\DefaultValueResolver`
30+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\DefaultValueResolver`
3031
Will set the default value of the argument if present and the argument
3132
is optional.
3233

33-
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolver\\VariadicValueResolver`
34-
Verifies in the request if your data is an array and will add all of
35-
them to the argument list. When the action is called, the last (variadic)
36-
argument will contain all the values of this array.
34+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver\\VariadicValueResolver`
35+
Verifies if the request data is an array and will add all of them to the
36+
argument list. When the action is called, the last (variadic) argument will
37+
contain all the values of this array.
3738

3839
.. note::
3940

@@ -43,9 +44,10 @@ Symfony ships with four value resolvers in the HttpKernel component:
4344
Adding a Custom Value Resolver
4445
------------------------------
4546

46-
Adding a new value resolver requires one class and one service defintion.
47-
In the next example, you'll create a value resolver to inject the ``User``
48-
object from the security system. Given you write the following action::
47+
Adding a new value resolver requires creatign one class and one service
48+
definition. In the next example, you'll create a value resolver to inject the
49+
``User`` object from the security system. Given you write the following
50+
controller::
4951

5052
namespace AppBundle\Controller;
5153

@@ -56,12 +58,13 @@ object from the security system. Given you write the following action::
5658
{
5759
public function indexAction(User $user)
5860
{
59-
return new Response('<html><body>Hello '.$user->getUsername().'!</body></html>');
61+
return new Response('Hello '.$user->getUsername().'!');
6062
}
6163
}
6264

6365
Somehow you will have to get the ``User`` object and inject it into the controller.
64-
This can be done by implementing the :class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`.
66+
This can be done by implementing the
67+
:class:`Symfony\\Component\\HttpKernel\\Controller\\ArgumentValueResolverInterface`.
6568
This interface specifies that you have to implement two methods:
6669

6770
``supports()``
@@ -80,7 +83,8 @@ Now that you know what to do, you can implement this interface. To get the
8083
current ``User``, you need the current security token. This token can be
8184
retrieved from the token storage::
8285

83-
namespace AppBundle\ArgumentValueResolver;
86+
// src/AppBundle/ArgumentResolver/UserValueResolver.php
87+
namespace AppBundle\ArgumentResolver;
8488

8589
use AppBundle\Entity\User;
8690
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
@@ -123,31 +127,22 @@ must fulfill the following requirements:
123127
* A security token must be present;
124128
* The value must be an instance of the ``User``.
125129

126-
When all those requirements are met and true is returned, the ``ArgumentResolver``
127-
calls ``resolve()`` with the same values as it called ``supports()``.
130+
When all those requirements are met and ``true`` is returned, the
131+
``ArgumentResolver`` calls ``resolve()`` with the same values as it called
132+
``supports()``.
128133

129134
That's it! Now all you have to do is add the configuration for the service
130135
container. This can be done by tagging the service with ``controller.argument_resolver``
131136
and adding a priority.
132137

133-
.. note::
134-
135-
While adding a priority is optional, it's recommended to add one to
136-
make sure the expected value is injected. The ``ArgumentFromAttributeResolver``
137-
has a priority of 100. As this one is responsible for fetching attributes
138-
from the ``Request``, it's also recommended to trigger your custom value
139-
resolver with a lower priority. This makes sure the argument resolvers
140-
are not triggered in (e.g.) subrequests if you pass your user along:
141-
``{{ render(controller('AppBundle:User:index', {'user', app.user})) }}``.
142-
143138
.. configuration-block::
144139

145140
.. code-block:: yaml
146141
147142
# app/config/services.yml
148143
services:
149144
app.value_resolver.user:
150-
class: AppBundle\ArgumentValueResolver\UserValueResolver
145+
class: AppBundle\ArgumentResolver\UserValueResolver
151146
arguments:
152147
- '@security.token_storage'
153148
tags:
@@ -162,7 +157,9 @@ and adding a priority.
162157
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
163158
164159
<services>
165-
<service id="app.value_resolver.user" class="AppBundle\ArgumentValueResolver\UserValueResolver">
160+
<service id="app.value_resolver.user"
161+
class="AppBundle\ArgumentResolver\UserValueResolver"
162+
>
166163
<argument type="service" id="security.token_storage">
167164
<tag name="controller.argument_value_resolver" priority="50" />
168165
</service>
@@ -176,44 +173,29 @@ and adding a priority.
176173
use Symfony\Component\DependencyInjection\Definition;
177174
178175
$defintion = new Definition(
179-
'AppBundle\ArgumentValueResolver\UserValueResolver',
176+
'AppBundle\ArgumentResolver\UserValueResolver',
180177
array(new Reference('security.token_storage'))
181178
);
182179
$definition->addTag('controller.argument_value_resolver', array('priority' => 50));
183180
$container->setDefinition('app.value_resolver.user', $definition);
184181
185-
Creating an Optional User Resolver
186-
----------------------------------
187-
188-
When you want your user to be optional, e.g. when your page is behind a
189-
firewall that also allows anonymous authentication, you might not always
190-
have a security user. To get this to work, you only have to change your
191-
method signature to `UserInterface $user = null`.
182+
While adding a priority is optional, it's recommended to add one to make sure
183+
the expected value is injected. The ``RequestAttributeValueResolver`` has a
184+
priority of 100. As this one is responsible for fetching attributes from the
185+
``Request``, it's recommended to trigger your custom value resolver with a
186+
lower priority. This makes sure the argument resolvers are not triggered when
187+
the attribute is present. For instance, when passing the user along a
188+
subrequests.
192189

193-
When you take the ``UserValueResolver`` from the previous example, you can
194-
see there is no logic in case of failure to comply to the requirements. Default
195-
values are defined in the signature and are available in the ``ArgumentMetadata``.
196-
When a default value is available and there are no resolvers that support
197-
the given value, the ``DefaultValueResolver`` is triggered. This Resolver
198-
takes the default value of your argument and yields it to the argument list::
190+
.. tip::
199191

200-
namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
192+
As you see in the ``UserValueResolver::supports()`` method, the user may
193+
not be available (e.g. when the controller is not behind a firewall). In
194+
these cases, the resolver will not be executed. If no argument value is
195+
resolved, an exception will be throwed.
201196

202-
use Symfony\Component\HttpFoundation\Request;
203-
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
204-
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
205-
206-
final class DefaultValueResolver implements ArgumentValueResolverInterface
207-
{
208-
public function supports(Request $request, ArgumentMetadata $argument)
209-
{
210-
return $argument->hasDefaultValue();
211-
}
212-
213-
public function resolve(Request $request, ArgumentMetadata $argument)
214-
{
215-
yield $argument->getDefaultValue();
216-
}
217-
}
197+
To prevent this, you can add a default value in the controller (e.g. ``User
198+
$user = null``). The ``DefaultValueResolver`` is executed as last resolver
199+
and will use the default value if no value is resolved already.
218200

219201
.. _`yield`: http://php.net/manual/en/language.generators.syntax.php

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.