ParamConverterEventSubscriber::onKernelController()   A
last analyzed

Complexity

Conditions 5
Paths 4

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
dl 0
loc 19
ccs 11
cts 11
cp 1
rs 9.3222
c 0
b 0
f 0
cc 5
nc 4
nop 1
crap 5
1
<?php
2
3
namespace Drupal\controller_annotations\EventSubscriber;
4
5
use Drupal\controller_annotations\Configuration\ParamConverter;
6
use Drupal\controller_annotations\Request\ParamConverter\ParamConverterManager;
7
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
8
use Symfony\Component\HttpFoundation\Request;
9
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
10
use Symfony\Component\HttpKernel\KernelEvents;
11
12
class ParamConverterEventSubscriber implements EventSubscriberInterface
13
{
14
    /**
15
     * @var ParamConverterManager
16
     */
17
    protected $manager;
18
19
    /**
20
     * @var bool
21
     */
22
    protected $autoConvert;
23
24
    /**
25
     * @var bool
26
     */
27
    private $isParameterTypeSupported;
28
29
    /**
30
     * @param ParamConverterManager $manager A ParamConverterManager instance
31
     * @param bool $autoConvert Auto convert non-configured objects
32
     */
33 17
    public function __construct(ParamConverterManager $manager, $autoConvert = true)
34
    {
35 17
        $this->manager = $manager;
36 17
        $this->autoConvert = $autoConvert;
37 17
        $this->isParameterTypeSupported = method_exists('ReflectionParameter', 'getType');
38 17
    }
39
40
    /**
41
     * Modifies the ParamConverterManager instance.
42
     *
43
     * @param FilterControllerEvent $event A FilterControllerEvent instance
44
     */
45 17
    public function onKernelController(FilterControllerEvent $event)
46
    {
47 17
        $controller = $event->getController();
48 17
        $request = $event->getRequest();
49 17
        $configurations = [];
50
51 17
        if ($configuration = $request->attributes->get('_converters')) {
52 2
            foreach (is_array($configuration) ? $configuration : [$configuration] as $configuration) {
53 2
                $configurations[$configuration->getName()] = $configuration;
54
            }
55
        }
56
57
        // automatically apply conversion for non-configured objects
58 17
        if ($this->autoConvert) {
59 14
            $configurations = $this->autoConfigure($this->resolveMethod($controller), $request, $configurations);
60
        }
61
62 17
        $this->manager->apply($request, $configurations);
63 17
    }
64
65
    /**
66
     * @param $controller
67
     *
68
     * @return \ReflectionFunction|\ReflectionMethod
69
     */
70 14
    protected function resolveMethod($controller)
71
    {
72 14
        if (is_array($controller)) {
73 12
            return new \ReflectionMethod($controller[0], $controller[1]);
74
        }
75 2
        if (is_object($controller) && is_callable($controller, '__invoke')) {
76 2
            return new \ReflectionMethod($controller, '__invoke');
77
        }
78
79
        return new \ReflectionFunction($controller);
80
    }
81
82
    /**
83
     * @param \ReflectionFunctionAbstract $r
84
     * @param \Symfony\Component\HttpFoundation\Request $request
85
     * @param array $configurations
86
     *
87
     * @return array
88
     */
89 14
    private function autoConfigure(\ReflectionFunctionAbstract $r, Request $request, $configurations)
90
    {
91 14
        foreach ($r->getParameters() as $param) {
92 9
            if ($param->getClass() && $param->getClass()->isInstance($request)) {
93 2
                continue;
94
            }
95
96 7
            $name = $param->getName();
0 ignored issues
show
Bug introduced by
Consider using $param->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
97 7
            $class = $param->getClass();
98 7
            $hasType = $this->isParameterTypeSupported && $param->hasType();
99
100 7
            if ($class || $hasType) {
101 6
                if (!isset($configurations[$name])) {
102 6
                    $configuration = new ParamConverter([]);
103 6
                    $configuration->setName($name);
104
105 6
                    $configurations[$name] = $configuration;
106
                }
107
108 6
                if ($class && null === $configurations[$name]->getClass()) {
109 6
                    $configurations[$name]->setClass($class->getName());
110
                }
111
            }
112
113 7
            if (isset($configurations[$name])) {
114 6
                $configurations[$name]->setIsOptional(
115 6
                    $param->isOptional()
116 5
                    || $param->isDefaultValueAvailable()
117 7
                    || $hasType && $param->getType()->allowsNull()
118
                );
119
            }
120
        }
121
122 14
        return $configurations;
123
    }
124
125
    /**
126
     * @return array
127
     */
128 7
    public static function getSubscribedEvents()
129
    {
130
        return [
131 7
            KernelEvents::CONTROLLER => [
132
                ['onKernelController', 100],
133
            ],
134
        ];
135
    }
136
}
137