Skip to content

Commit 86f68cf

Browse files
author
Iltar van der Berg
committed
Added an ArgumentResolver with clean extension point
1 parent bcdcfcb commit 86f68cf

File tree

4 files changed

+91
-1
lines changed

4 files changed

+91
-1
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
13+
14+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
15+
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Reference;
17+
18+
/**
19+
* Gathers and configures the argument value resolvers.
20+
*
21+
* @author Iltar van der Berg <[email protected]>
22+
*/
23+
class ControllerArgumentValueResolverPass implements CompilerPassInterface
24+
{
25+
public function process(ContainerBuilder $container)
26+
{
27+
if (!$container->hasDefinition('argument_resolver')) {
28+
return;
29+
}
30+
31+
$definition = $container->getDefinition('argument_resolver');
32+
$argumentResolvers = $this->findAndSortTaggedServices('controller_argument.value_resolver', $container);
33+
$definition->replaceArgument(1, $argumentResolvers);
34+
}
35+
36+
/**
37+
* Finds all services with the given tag name and order them by their priority.
38+
*
39+
* @param string $tagName
40+
* @param ContainerBuilder $container
41+
*
42+
* @return array
43+
*/
44+
private function findAndSortTaggedServices($tagName, ContainerBuilder $container)
45+
{
46+
$services = $container->findTaggedServiceIds($tagName);
47+
48+
$sortedServices = array();
49+
foreach ($services as $serviceId => $tags) {
50+
foreach ($tags as $attributes) {
51+
$priority = isset($attributes['priority']) ? $attributes['priority'] : 0;
52+
$sortedServices[$priority][] = new Reference($serviceId);
53+
}
54+
}
55+
56+
if (empty($sortedServices)) {
57+
return array();
58+
}
59+
60+
krsort($sortedServices);
61+
62+
// Flatten the array
63+
return call_user_func_array('array_merge', $sortedServices);
64+
}
65+
}

DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,8 @@ public function load(array $configs, ContainerBuilder $container)
171171
'Symfony\\Component\\HttpKernel\\EventListener\\RouterListener',
172172
'Symfony\\Component\\HttpKernel\\Controller\\ControllerResolver',
173173
'Symfony\\Component\\HttpKernel\\Controller\\ArgumentResolver',
174+
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadata',
175+
'Symfony\\Component\\HttpKernel\\ControllerMetadata\\ArgumentMetadataFactory',
174176
'Symfony\\Component\\HttpKernel\\Event\\KernelEvent',
175177
'Symfony\\Component\\HttpKernel\\Event\\FilterControllerEvent',
176178
'Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent',

FrameworkBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConstraintValidatorsPass;
1515
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddValidatorInitializersPass;
1616
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass;
17+
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\ControllerArgumentValueResolverPass;
1718
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\FormPass;
1819
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\PropertyInfoPass;
1920
use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TemplatingPass;
@@ -87,6 +88,7 @@ public function build(ContainerBuilder $container)
8788
$container->addCompilerPass(new FragmentRendererPass(), PassConfig::TYPE_AFTER_REMOVING);
8889
$container->addCompilerPass(new SerializerPass());
8990
$container->addCompilerPass(new PropertyInfoPass());
91+
$container->addCompilerPass(new ControllerArgumentValueResolverPass());
9092

9193
if ($container->getParameter('kernel.debug')) {
9294
$container->addCompilerPass(new UnusedTagsPass(), PassConfig::TYPE_AFTER_REMOVING);

Resources/config/web.xml

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,28 @@
1717
<argument type="service" id="logger" on-invalid="ignore" />
1818
</service>
1919

20-
<service id="argument_resolver" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver" public="false" />
20+
<service id="argument_resolver" class="Symfony\Component\HttpKernel\Controller\ArgumentResolver" public="false">
21+
<argument type="service" id="argument_metadata_factory" />
22+
<argument type="collection" />
23+
</service>
24+
25+
<service id="argument_metadata_factory" class="Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory" public="false" />
26+
27+
<service id="argument_value_resolver.argument_from_attribute" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\ArgumentFromAttributeResolver" public="false">
28+
<tag name="controller_argument.value_resolver" priority="100" />
29+
</service>
30+
31+
<service id="argument_value_resolver.argument_is_request" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\RequestResolver" public="false">
32+
<tag name="controller_argument.value_resolver" priority="50" />
33+
</service>
34+
35+
<service id="argument_value_resolver.default_argument_value" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\DefaultArgumentValueResolver" public="false">
36+
<tag name="controller_argument.value_resolver" priority="-100" />
37+
</service>
38+
39+
<service id="argument_value_resolver.variadic_argument_from_attribute" class="Symfony\Component\HttpKernel\Controller\ArgumentValueResolver\VariadicArgumentValueResolver" public="false">
40+
<tag name="controller_argument.value_resolver" priority="-150" />
41+
</service>
2142

2243
<service id="response_listener" class="Symfony\Component\HttpKernel\EventListener\ResponseListener">
2344
<tag name="kernel.event_subscriber" />

0 commit comments

Comments
 (0)