Passed
Pull Request — master (#115)
by Rustam
02:24
created

Group::routes()   B

Complexity

Conditions 11
Paths 7

Size

Total Lines 34
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 13.4538

Importance

Changes 0
Metric Value
cc 11
eloc 22
c 0
b 0
f 0
nc 7
nop 1
dl 0
loc 34
ccs 16
cts 22
cp 0.7272
crap 13.4538
rs 7.3166

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
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
use InvalidArgumentException;
8
use RuntimeException;
9
use Yiisoft\Middleware\Dispatcher\MiddlewareDispatcher;
10
11
use function get_class;
12
use function in_array;
13
use function is_array;
14
use function is_callable;
15
use function is_object;
16
17
final class Group implements GroupInterface
18
{
19
    /**
20
     * @var Group[]|Route[]
21
     */
22
    private array $items = [];
23
    private ?string $prefix;
24
    private array $middlewareDefinitions = [];
25
    private ?string $host = null;
26
    private ?string $namePrefix = null;
27
    private bool $routesAdded = false;
28
    private bool $middlewareAdded = false;
29
    private array $disabledMiddlewareDefinitions = [];
30
    private ?MiddlewareDispatcher $dispatcher;
31
32 14
    private function __construct(?string $prefix = null, MiddlewareDispatcher $dispatcher = null)
33
    {
34 14
        $this->dispatcher = $dispatcher;
35 14
        $this->prefix = $prefix;
36 14
    }
37
38
    /**
39
     * Create a new group instance.
40
     *
41
     * @param string|null $prefix URL prefix to prepend to all routes of the group.
42
     * @param MiddlewareDispatcher|null $dispatcher Middleware dispatcher to use for the group.
43
     *
44
     * @return GroupInterface
45
     */
46 14
    public static function create(
47
        ?string $prefix = null,
48
        MiddlewareDispatcher $dispatcher = null
49
    ): GroupInterface {
50 14
        return new self($prefix, $dispatcher);
51
    }
52
53 11
    public function routes(...$routes): GroupInterface
54
    {
55 11
        if ($this->middlewareAdded) {
56
            throw new RuntimeException('routes() can not be used after prependMiddleware().');
57
        }
58 11
        if (is_callable($routes)) {
59
            $callback = $routes;
60 11
        } elseif (is_array($routes)) {
0 ignored issues
show
introduced by
The condition is_array($routes) is always true.
Loading history...
61 11
            $callback = static function (self $group) use (&$routes) {
62 11
                foreach ($routes as $route) {
63 11
                    if ($route instanceof Route || $route instanceof self) {
64 11
                        if (!$route->hasDispatcher() && $group->hasDispatcher()) {
65 4
                            $route = $route->withDispatcher($group->dispatcher);
66
                        }
67 11
                        $group->items[] = $route;
68
                    } else {
69
                        $type = is_object($route) ? get_class($route) : gettype($route);
70
                        throw new InvalidArgumentException(
71
                            sprintf('Route should be either an instance of Route or Group, %s given.', $type)
72
                        );
73
                    }
74
                }
75 11
            };
76
        } else {
77
            $callback = null;
78
        }
79
80 11
        $new = clone $this;
81 11
        if ($callback !== null) {
0 ignored issues
show
introduced by
The condition $callback !== null is always true.
Loading history...
82 11
            $callback($new);
83
        }
84 11
        $new->routesAdded = true;
85
86 11
        return $new;
87
    }
88
89 2
    public function withDispatcher(MiddlewareDispatcher $dispatcher): GroupInterface
90
    {
91 2
        $group = clone $this;
92 2
        $group->dispatcher = $dispatcher;
93 2
        foreach ($group->items as $index => $route) {
94 2
            if (!$route->hasDispatcher()) {
95 2
                $route = $route->withDispatcher($dispatcher);
96 2
                $group->items[$index] = $route;
97
            }
98
        }
99
100 2
        return $group;
101
    }
102
103 11
    public function hasDispatcher(): bool
104
    {
105 11
        return $this->dispatcher !== null;
106
    }
107
108
    /**
109
     * Appends a handler middleware definition that should be invoked for a matched route.
110
     * First added handler will be executed first.
111
     *
112
     * @param mixed $middlewareDefinition
113
     *
114
     * @return self
115
     */
116 6
    public function middleware($middlewareDefinition): GroupInterface
117
    {
118 6
        if ($this->routesAdded) {
119
            throw new RuntimeException('middleware() can not be used after routes().');
120
        }
121 6
        $new = clone $this;
122 6
        array_unshift($new->middlewareDefinitions, $middlewareDefinition);
123 6
        return $new;
124
    }
125
126
    /**
127
     * Prepends a handler middleware definition that should be invoked for a matched route.
128
     * First added handler will be executed last.
129
     *
130
     * @param mixed $middlewareDefinition
131
     *
132
     * @return self
133
     */
134 1
    public function prependMiddleware($middlewareDefinition): GroupInterface
135
    {
136 1
        $new = clone $this;
137 1
        $new->middlewareDefinitions[] = $middlewareDefinition;
138 1
        $new->middlewareAdded = true;
139 1
        return $new;
140
    }
141
142 2
    public function namePrefix(string $namePrefix): GroupInterface
143
    {
144 2
        $new = clone $this;
145 2
        $new->namePrefix = $namePrefix;
146 2
        return $new;
147
    }
148
149 2
    public function host(string $host): GroupInterface
150
    {
151 2
        $new = clone $this;
152 2
        $new->host = rtrim($host, '/');
153 2
        return $new;
154
    }
155
156
    /**
157
     * Excludes middleware from being invoked when action is handled.
158
     * It is useful to avoid invoking one of the parent group middleware for
159
     * a certain route.
160
     *
161
     * @param mixed $middlewareDefinition
162
     *
163
     * @return self
164
     */
165
    public function disableMiddleware($middlewareDefinition): GroupInterface
166
    {
167
        $new = clone $this;
168
        $new->disabledMiddlewareDefinitions[] = $middlewareDefinition;
169
        return $new;
170
    }
171
172
    /**
173
     * @return Group[]|Route[]
174
     */
175 10
    public function getItems(): array
176
    {
177 10
        return $this->items;
178
    }
179
180 9
    public function getPrefix(): ?string
181
    {
182 9
        return $this->prefix;
183
    }
184
185 9
    public function getNamePrefix(): ?string
186
    {
187 9
        return $this->namePrefix;
188
    }
189
190 9
    public function getHost(): ?string
191
    {
192 9
        return $this->host;
193
    }
194
195 8
    public function getMiddlewareDefinitions(): array
196
    {
197 8
        foreach ($this->middlewareDefinitions as $index => $definition) {
198 6
            if (in_array($definition, $this->disabledMiddlewareDefinitions, true)) {
199
                unset($this->middlewareDefinitions[$index]);
200
            }
201
        }
202
203 8
        return $this->middlewareDefinitions;
204
    }
205
}
206