Completed
Push — 8.x-1.x ( 2c0805...e1bdd0 )
by
unknown
26:50
created

ParamConverterEventSubscriber::onKernelController()   C

Complexity

Conditions 8
Paths 12

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 8.0155

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 27
ccs 15
cts 16
cp 0.9375
rs 5.3846
cc 8
eloc 16
nc 12
nop 1
crap 8.0155
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 14
    public function __construct(ParamConverterManager $manager, $autoConvert = true)
34
    {
35 14
        $this->manager = $manager;
36 14
        $this->autoConvert = $autoConvert;
37 14
        $this->isParameterTypeSupported = method_exists('ReflectionParameter', 'getType');
38 14
    }
39
40
    /**
41
     * Modifies the ParamConverterManager instance.
42
     *
43
     * @param FilterControllerEvent $event A FilterControllerEvent instance
44
     */
45 14
    public function onKernelController(FilterControllerEvent $event)
46
    {
47 14
        $controller = $event->getController();
48 14
        $request = $event->getRequest();
49 14
        $configurations = array();
50
51 14
        if ($configuration = $request->attributes->get('_converters')) {
52 2
            foreach (is_array($configuration) ? $configuration : array($configuration) as $configuration) {
53 2
                $configurations[$configuration->getName()] = $configuration;
54
            }
55
        }
56
57 14
        if (is_array($controller)) {
58 10
            $r = new \ReflectionMethod($controller[0], $controller[1]);
59 4
        } elseif (is_object($controller) && is_callable($controller, '__invoke')) {
60 4
            $r = new \ReflectionMethod($controller, '__invoke');
61
        } else {
62
            $r = new \ReflectionFunction($controller);
63
        }
64
65
        // automatically apply conversion for non-configured objects
66 14
        if ($this->autoConvert) {
67 11
            $configurations = $this->autoConfigure($r, $request, $configurations);
68
        }
69
70 14
        $this->manager->apply($request, $configurations);
71 14
    }
72
73
    /**
74
     * @param \ReflectionFunctionAbstract $r
75
     * @param \Symfony\Component\HttpFoundation\Request $request
76
     * @param array $configurations
77
     *
78
     * @return array
79
     */
80 11
    private function autoConfigure(\ReflectionFunctionAbstract $r, Request $request, $configurations)
81
    {
82 11
        foreach ($r->getParameters() as $param) {
83 6
            if ($param->getClass() && $param->getClass()->isInstance($request)) {
84 2
                continue;
85
            }
86
87 4
            $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...
88 4
            $class = $param->getClass();
89 4
            $hasType = $this->isParameterTypeSupported && $param->hasType();
90
91 4
            if ($class || $hasType) {
92 3
                if (!isset($configurations[$name])) {
93 3
                    $configuration = new ParamConverter([]);
94 3
                    $configuration->setName($name);
95
96 3
                    $configurations[$name] = $configuration;
97
                }
98
99 3
                if ($class && null === $configurations[$name]->getClass()) {
100 3
                    $configurations[$name]->setClass($class->getName());
101
                }
102
            }
103
104 4
            if (isset($configurations[$name])) {
105 4
                $configurations[$name]->setIsOptional($param->isOptional() || $param->isDefaultValueAvailable() || $hasType && $param->getType()->allowsNull());
106
            }
107
        }
108
109 11
        return $configurations;
110
    }
111
112
    /**
113
     * @return array
114
     */
115 7
    public static function getSubscribedEvents()
116
    {
117
        return [
118
            KernelEvents::CONTROLLER => [
119
                ['onKernelController', 100],
120 7
            ],
121
        ];
122
    }
123
}
124