Passed
Push — master ( d0f9e3...c3e906 )
by Divine Niiquaye
08:38
created

Listener::addRouteGroup()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 25
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 17
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 15
nc 5
nop 2
dl 0
loc 25
ccs 17
cts 17
cp 1
crap 4
rs 9.7666
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Flight Routing.
7
 *
8
 * PHP version 7.1 and above required
9
 *
10
 * @author    Divine Niiquaye Ibok <[email protected]>
11
 * @copyright 2019 Biurad Group (https://biurad.com/)
12
 * @license   https://opensource.org/licenses/BSD-3-Clause License
13
 *
14
 * For the full copyright and license information, please view the LICENSE
15
 * file that was distributed with this source code.
16
 */
17
18
namespace Flight\Routing\Annotation;
19
20
use Biurad\Annotations\ListenerInterface;
21
use Flight\Routing\Interfaces\RouteCollectorInterface;
22
use ReflectionClass;
23
24
class Listener implements ListenerInterface
25
{
26
    /** @var RouteCollectorInterface */
27
    private $collector;
28
29
    /** @var int */
30
    private $defaultRouteIndex = 0;
31
32 15
    public function __construct(RouteCollectorInterface $collector)
33
    {
34 15
        $this->collector = $collector;
35 15
    }
36
37
    /**
38
     * {@inheritdoc}
39
     */
40 4
    public function onAnnotation(array $annotations)
41
    {
42 4
        foreach ($annotations as $class => $collection) {
43 4
            if (isset($collection['method'])) {
44 4
                $this->addRouteGroup($collection['class'] ?? null, $collection['method']);
45
46 4
                continue;
47
            }
48
49 3
            $this->defaultRouteIndex = 0;
50 3
            $this->addRoute($this->collector, $collection['class'], $class);
51
        }
52
53 4
        return $this->collector->getCollection();
54
    }
55
56
    /**
57
     * {@inheritdoc}
58
     */
59 4
    public function getArguments(): array
60
    {
61 4
        return [];
62
    }
63
64
    /**
65
     * {@inheritdoc}
66
     */
67 14
    public function getAnnotation(): string
68
    {
69 14
        return 'Flight\Routing\Annotation\Route';
70
    }
71
72
    /**
73
     * Add a route from annotation
74
     *
75
     * @param RouteCollectorInterface $collector
76
     * @param Route                   $annotation
77
     * @param string|string[]         $handler
78
     */
79 4
    protected function addRoute(RouteCollectorInterface $collector, Route $annotation, $handler): void
80
    {
81 4
        $routeName    = $annotation->getName() ?? $this->getDefaultRouteName($handler);
82 4
        $routeMethods = $annotation->getMethods();
83
84
        // Incase of API Resource
85 4
        if (str_ends_with($routeName, '__restful')) {
86
            $routeMethods = $collector::HTTP_METHODS_STANDARD;
87
        }
88
89 4
        $route = $collector->map($routeName, $routeMethods, $annotation->getPath(), $handler)
90 4
        ->setScheme(...$annotation->getSchemes())
91 4
        ->setPatterns($annotation->getPatterns())
92 4
        ->setDefaults($annotation->getDefaults())
93 4
        ->addMiddleware(...$annotation->getMiddlewares());
94
95 4
        if (null !== $annotation->getDomain()) {
96 3
            $route->setDomain($annotation->getDomain());
97
        }
98 4
    }
99
100
    /**
101
     * Add a routes from annotation into group
102
     *
103
     * @param nullRoute $grouping
0 ignored issues
show
Bug introduced by
The type Flight\Routing\Annotation\nullRoute was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
104
     * @param array     $methods
105
     */
106 4
    protected function addRouteGroup(?Route $grouping, array $methods): void
107
    {
108 4
        if (null === $grouping) {
109 3
            $this->mergeAnnotations($this->collector, $methods);
110
111 3
            return;
112
        }
113
114 4
        $group = $this->collector->group(
115 4
            function (RouteCollectorInterface $group) use ($methods): void {
116 4
                $this->mergeAnnotations($group, $methods);
117 4
            }
118
        )
119 4
        ->addMethod(...$grouping->getMethods())
120 4
        ->addPrefix($grouping->getPath())
121 4
        ->addScheme(...$grouping->getSchemes())
122 4
        ->addMiddleware(...$grouping->getMiddlewares())
123 4
        ->setDefaults($grouping->getDefaults());
124
125 4
        if (null !== $grouping->getName()) {
126 4
            $group->setName($grouping->getName());
127
        }
128
129 4
        if (null !== $grouping->getDomain()) {
130 3
            $group->addDomain($grouping->getDomain());
131
        }
132 4
    }
133
134
    /**
135
     * @param RouteCollectorInterface $route
136
     * @param mixed[]                 $methods
137
     */
138 4
    protected function mergeAnnotations(RouteCollectorInterface $route, array $methods): void
139
    {
140 4
        $this->defaultRouteIndex = 0;
141
142 4
        foreach ($methods as [$method, $annotation]) {
143 4
            $this->addRoute($route, $annotation, [$method->class, $method->getName()]);
144
        }
145 4
    }
146
147
    /**
148
     * Gets the default route name for a class method.
149
     *
150
     * @param string|string[] $handler
151
     *
152
     * @return string
153
     */
154 4
    private function getDefaultRouteName($handler): string
155
    {
156 4
        $classReflection = new ReflectionClass(\is_string($handler) ? $handler : $handler[0]);
157 4
        $name            = \str_replace('\\', '_', $classReflection->name);
158
159 4
        if (\is_array($handler) || $classReflection->hasMethod('__invoke')) {
160 4
            $name .= '_' . $handler[1] ?? '__invoke';
161
        }
162
163 4
        if ($this->defaultRouteIndex > 0) {
164 3
            $name .= '_' . $this->defaultRouteIndex;
165
        }
166 4
        ++$this->defaultRouteIndex;
167
168 4
        return \strtolower($name);
169
    }
170
}
171