@@ -5,12 +5,13 @@ Extending Action Argument Resolving
5
5
===================================
6
6
7
7
.. 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.
9
9
10
10
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
14
15
this functionality.
15
16
16
17
Functionality Shipped With The HttpKernel
@@ -74,7 +75,7 @@ This interface specifies that you have to implement two methods::
74
75
given argument. ``resolve() `` will only be executed when this returns ``true ``.
75
76
``resolve() ``
76
77
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 ``.
78
79
79
80
Both methods get the ``Request `` object, which is the current request, and an
80
81
:class: `Symfony\\ Component\\ HttpKernel\\ ControllerMetadata\\ ArgumentMetadata `.
@@ -131,24 +132,15 @@ retrieved from the token storage::
131
132
}
132
133
133
134
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:
135
136
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 ``.
139
140
140
141
When all those requirements are met and true is returned, the ``ArgumentResolver ``
141
142
calls ``resolve() `` with the same values as it called ``supports() ``.
142
143
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
-
152
144
That's it! Now all you have to do is add the configuration for the service
153
145
container. This can be done by tagging the service with ``kernel.argument_resolver ``
154
146
and adding a priority.
@@ -206,3 +198,33 @@ and adding a priority.
206
198
$container->setDefinition('app.value_resolver.user', $definition);
207
199
208
200
.. _`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