Skip to content

Commit fdce9c6

Browse files
author
Iltar van der Berg
committed
Tried to make the default value resolving more clear
1 parent c35b56f commit fdce9c6

File tree

1 file changed

+40
-18
lines changed

1 file changed

+40
-18
lines changed

cookbook/controller/argument_value_resolver.rst

+40-18
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ Extending Action Argument Resolving
55
===================================
66

77
.. versionadded:: 3.1
8-
The ``ArgumentResolver`` and value resolvers are added in Symfony 3.1.
8+
The ``ArgumentResolver`` and value resolvers were introduced in Symfony 3.1.
99

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

1617
Functionality Shipped With The HttpKernel
@@ -74,7 +75,7 @@ This interface specifies that you have to implement two methods::
7475
given argument. ``resolve()`` will only be executed when this returns ``true``.
7576
``resolve()``
7677
This method will resolve the actual value for the argument. Once the value
77-
is resolved, you should `yield`_ the value to the ``ArgumentResolver``.
78+
is resolved, you must `yield`_ the value to the ``ArgumentResolver``.
7879

7980
Both methods get the ``Request`` object, which is the current request, and an
8081
:class:`Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata`.
@@ -131,24 +132,15 @@ retrieved from the token storage::
131132
}
132133

133134
In order to get the actual ``User`` object in your argument, the given value
134-
should fulfill the following requirements:
135+
must fulfill the following requirements:
135136

136-
* The argument type (of the method signature) must be typehinted as ``User``;
137-
* The security token must be present;
138-
* The value should be an instance of the ``User``.
137+
* An argument must be typehinted as ``User`` in your action method signature;
138+
* A security token must be present;
139+
* The value must be an instance of the ``User``.
139140

140141
When all those requirements are met and true is returned, the ``ArgumentResolver``
141142
calls ``resolve()`` with the same values as it called ``supports()``.
142143

143-
.. tip::
144-
145-
You can leverage the ``DefaultValueResolver`` by making your resolver
146-
accept only mandatory arguments. Given your signature is `User $user = null`,
147-
the above example will not hit ``resolve()`` as one of the conditions
148-
does not match. Eventually when the ``DefaultValueResolver`` is asked
149-
to resolve this, it will simply add the default value from the method
150-
signature, which results in ``null``.
151-
152144
That's it! Now all you have to do is add the configuration for the service
153145
container. This can be done by tagging the service with ``kernel.argument_resolver``
154146
and adding a priority.
@@ -206,3 +198,33 @@ and adding a priority.
206198
$container->setDefinition('app.value_resolver.user', $definition);
207199
208200
.. _`yield`: http://php.net/manual/en/language.generators.syntax.php
201+
202+
Creating an Optional User Resolver
203+
----------------------------------
204+
205+
When you want your user to be optional, e.g. when your page is behind a
206+
firewall that also allows anonymous authentication, you might not always
207+
have a security user. To get this to work, you only have to change your
208+
method signature to `UserInterface $user = null`.
209+
210+
When you take the ``UserValueResolver`` from the previous example, you can
211+
see there is no logic in case of failure to comply to the requirements. Default
212+
values in are defined in the signature and are available in the ``ArgumentMetadata``.
213+
When a default value is available and there are no resolvers that support
214+
the given value, the ``DefaultValueResolver`` is triggered. This Resolver
215+
takes the default value of your argument and yields it to the argument list::
216+
217+
namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
218+
219+
final class DefaultValueResolver implements ArgumentValueResolverInterface
220+
{
221+
public function supports(Request $request, ArgumentMetadata $argument)
222+
{
223+
return $argument->hasDefaultValue();
224+
}
225+
226+
public function resolve(Request $request, ArgumentMetadata $argument)
227+
{
228+
yield $argument->getDefaultValue();
229+
}
230+
}

0 commit comments

Comments
 (0)