@@ -5,12 +5,13 @@ Extending Action Argument Resolving
55===================================
66
77..versionadded ::3.1
8- The ``ArgumentResolver `` and value resolversare added in Symfony 3.1.
8+ The ``ArgumentResolver `` and value resolverswere introduced in Symfony 3.1.
99
1010In 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
1415this functionality.
1516
1617Functionality 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, youshould `yield `_ the value to the ``ArgumentResolver ``.
78+ is resolved, youmust `yield `_ the value to the ``ArgumentResolver ``.
7879
7980Both 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
133134In 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 argumenttype (of the method signature) must be typehinted as ``User ``;
137- *The security token must be present;
138- * The valueshould 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 valuemust be an instance of the ``User ``.
139140
140141When all those requirements are met and true is returned, the ``ArgumentResolver ``
141142calls ``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-
152144That's it! Now all you have to do is add the configuration for the service
153145container. This can be done by tagging the service with ``kernel.argument_resolver ``
154146and 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+ }