Passed
Pull Request — master (#9)
by Pavel
12:36
created

ControllerListener::onKernelController()   C

Complexity

Conditions 11
Paths 46

Size

Total Lines 47
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 16.8164

Importance

Changes 0
Metric Value
dl 0
loc 47
c 0
b 0
f 0
ccs 21
cts 33
cp 0.6364
rs 5.2653
cc 11
eloc 30
nc 46
nop 1
crap 16.8164

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/*
4
 * Copyright (c) 2010-2017 Fabien Potencier
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is furnished
11
 * to do so, subject to t * *he following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in all
14
 * copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 *
24
 */
25
26
namespace Bankiru\Api\Rpc\Listener;
27
28
use Bankiru\Api\Rpc\Event\FilterControllerEvent;
29
use Bankiru\Api\Rpc\RpcEvents;
30
use Doctrine\Common\Annotations\Reader;
31
use Doctrine\Common\Util\ClassUtils;
32
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ConfigurationInterface;
33
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
34
35
/**
36
 * Adopted SensioFrameworkExtraBundle Controller listener
37
 *
38
 * The ControllerListener class parses annotation blocks located in
39
 * controller classes.
40
 *
41
 * @author Pavel Batanov <[email protected]>
42
 */
43
final class ControllerListener implements EventSubscriberInterface
44
{
45
    /**
46
     * @var Reader
47
     */
48
    private $reader;
49
50
    /**
51
     * Constructor.
52
     *
53
     * @param Reader $reader An Reader instance
54
     */
55 8
    public function __construct(Reader $reader)
56
    {
57 8
        $this->reader = $reader;
58 8
    }
59
60
    /**
61
     * Modifies the Request object to apply configuration information found in
62
     * controllers annotations like the template to render or HTTP caching
63
     * configuration.
64
     *
65
     * @param FilterControllerEvent $event A FilterControllerEvent instance
66
     */
67 8
    public function onKernelController(FilterControllerEvent $event)
68
    {
69 8
        $controller = $event->getController();
70
71 8
        if (!is_array($controller) && method_exists($controller, '__invoke')) {
72
            $controller = [$controller, '__invoke'];
73
        }
74
75 8
        if (!is_array($controller)) {
76
            return;
77
        }
78
79
        $className =
80 8
            class_exists('Doctrine\Common\Util\ClassUtils') ? ClassUtils::getClass($controller[0]) :
81 8
                get_class($controller[0]);
82 8
        $object    = new \ReflectionClass($className);
83 8
        $method    = $object->getMethod($controller[1]);
84
85 8
        $classConfigurations  = $this->getConfigurations($this->reader->getClassAnnotations($object));
86 8
        $methodConfigurations = $this->getConfigurations($this->reader->getMethodAnnotations($method));
87
88 8
        $configurations = [];
89 8
        foreach (array_merge(array_keys($classConfigurations), array_keys($methodConfigurations)) as $key) {
90 2
            if (!array_key_exists($key, $classConfigurations)) {
91 2
                $configurations[$key] = $methodConfigurations[$key];
92 2
            } elseif (!array_key_exists($key, $methodConfigurations)) {
93
                $configurations[$key] = $classConfigurations[$key];
94
            } else {
95
                if (is_array($classConfigurations[$key])) {
96
                    if (!is_array($methodConfigurations[$key])) {
97
                        throw new \UnexpectedValueException(
98
                            'Configurations should both be an array or both not be an array'
99
                        );
100
                    }
101
                    $configurations[$key] = array_merge($classConfigurations[$key], $methodConfigurations[$key]);
102
                } else {
103
                    // method configuration overrides class configuration
104
                    $configurations[$key] = $methodConfigurations[$key];
105
                }
106
            }
107 8
        }
108
109 8
        $request = $event->getRequest();
110 8
        foreach ($configurations as $key => $attributes) {
111 2
            $request->getAttributes()->set($key, $attributes);
112 8
        }
113 8
    }
114
115 1
    public static function getSubscribedEvents()
116
    {
117
        return [
118 1
            RpcEvents::CONTROLLER => ['onKernelController', 255],
119 1
        ];
120
    }
121
122 8
    protected function getConfigurations(array $annotations)
123
    {
124 8
        $configurations = [];
125 8
        foreach ($annotations as $configuration) {
126 8
            if ($configuration instanceof ConfigurationInterface) {
127 2
                $index = '_' . $configuration->getAliasName();
128 2
                if ($configuration->allowArray()) {
129
                    $configurations[$index][] = $configuration;
130 2
                } elseif (!isset($configurations[$index])) {
131 2
                    $configurations[$index] = $configuration;
132 2
                } else {
133
                    throw new \LogicException(
134
                        sprintf('Multiple "%s" annotations are not allowed.', $configuration->getAliasName())
135
                    );
136
                }
137 2
            }
138 8
        }
139
140 8
        return $configurations;
141
    }
142
}
143