1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Component\HttpKernel\DependencyInjection;
13
14use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
15use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
16use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
17use Symfony\Component\DependencyInjection\ContainerBuilder;
18use Symfony\Component\DependencyInjection\Reference;
19use Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver;
20use Symfony\Component\Stopwatch\Stopwatch;
21
22/**
23 * Gathers and configures the argument value resolvers.
24 *
25 * @author Iltar van der Berg <kjarli@gmail.com>
26 */
27class ControllerArgumentValueResolverPass implements CompilerPassInterface
28{
29    use PriorityTaggedServiceTrait;
30
31    private $argumentResolverService;
32    private $argumentValueResolverTag;
33    private $traceableResolverStopwatch;
34
35    public function __construct(string $argumentResolverService = 'argument_resolver', string $argumentValueResolverTag = 'controller.argument_value_resolver', string $traceableResolverStopwatch = 'debug.stopwatch')
36    {
37        $this->argumentResolverService = $argumentResolverService;
38        $this->argumentValueResolverTag = $argumentValueResolverTag;
39        $this->traceableResolverStopwatch = $traceableResolverStopwatch;
40    }
41
42    public function process(ContainerBuilder $container)
43    {
44        if (!$container->hasDefinition($this->argumentResolverService)) {
45            return;
46        }
47
48        $resolvers = $this->findAndSortTaggedServices($this->argumentValueResolverTag, $container);
49
50        if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has($this->traceableResolverStopwatch)) {
51            foreach ($resolvers as $resolverReference) {
52                $id = (string) $resolverReference;
53                $container->register("debug.$id", TraceableValueResolver::class)
54                    ->setDecoratedService($id)
55                    ->setArguments([new Reference("debug.$id.inner"), new Reference($this->traceableResolverStopwatch)]);
56            }
57        }
58
59        $container
60            ->getDefinition($this->argumentResolverService)
61            ->replaceArgument(1, new IteratorArgument($resolvers))
62        ;
63    }
64}
65