Passed
Pull Request — master (#225)
by Rustam
02:46
created

Group::assertMiddlewares()   A

Complexity

Conditions 5
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 5
nc 3
nop 1
dl 0
loc 10
ccs 6
cts 6
cp 1
crap 5
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router;
6
7
use Yiisoft\Router\Internal\MiddlewareFilter;
8
9
final class Group
10
{
11
    /**
12
     * @var Group[]|RoutableInterface[]|Route[]
13
     */
14
    private array $routes = [];
15
16
    /**
17
     * @var array[]|callable[]|string[]
18
     * @psalm-var list<array|callable|string>
19
     */
20
    private array $middlewares = [];
21
22
    /**
23
     * @var string[]
24
     */
25
    private array $hosts = [];
26
27
    /**
28
     * @psalm-var list<array|callable|string>|null
29
     */
30
    private ?array $enabledMiddlewaresCache = null;
31
32
    /**
33
     * @var array|callable|string|null Middleware definition for CORS requests.
34
     */
35
    private $corsMiddleware = null;
36
37
    /**
38
     * @param array $disabledMiddlewares Excludes middleware from being invoked when action is handled.
39
     * It is useful to avoid invoking one of the parent group middleware for
40
     * a certain route.
41
     */
42 40
    public function __construct(
43
        private ?string $prefix = null,
44
        private ?string $namePrefix = null,
45
        array $routes = [],
46
        array $middlewares = [],
47
        array $hosts = [],
48
        private array $disabledMiddlewares = [],
49
        array|callable|string|null $corsMiddleware = null
50
    ) {
51 40
        $this->setRoutes($routes);
52 40
        $this->setMiddlewares($middlewares);
53 39
        $this->setHosts($hosts);
54 38
        $this->corsMiddleware = $corsMiddleware;
55
    }
56
57
    /**
58
     * @return Group[]|RoutableInterface[]|Route[]
59
     */
60 23
    public function getRoutes(): array
61
    {
62 23
        return $this->routes;
63
    }
64
65 23
    public function getMiddlewares(): array
66
    {
67 23
        return $this->middlewares;
68
    }
69
70 26
    public function getHosts(): array
71
    {
72 26
        return $this->hosts;
73
    }
74
75 23
    public function getCorsMiddleware(): callable|array|string|null
76
    {
77 23
        return $this->corsMiddleware;
78
    }
79
80 24
    public function getPrefix(): ?string
81
    {
82 24
        return $this->prefix;
83
    }
84
85 24
    public function getNamePrefix(): ?string
86
    {
87 24
        return $this->namePrefix;
88
    }
89
90 1
    public function getDisabledMiddlewares(): array
91
    {
92 1
        return $this->disabledMiddlewares;
93
    }
94
95 40
    public function setRoutes(array $routes): self
96
    {
97 40
        $this->assertRoutes($routes);
98 40
        $this->routes = $routes;
99 40
        return $this;
100
    }
101
102 40
    public function setMiddlewares(array $middlewares): self
103
    {
104 40
        $this->assertMiddlewares($middlewares);
105 39
        $this->middlewares = $middlewares;
106 39
        $this->enabledMiddlewaresCache = null;
107 39
        return $this;
108
    }
109
110 39
    public function setHosts(array $hosts): self
111
    {
112 39
        $this->assertHosts($hosts);
113 38
        foreach ($hosts as $host) {
114 5
            $host = rtrim($host, '/');
115
116 5
            if ($host !== '' && !in_array($host, $this->hosts, true)) {
117 5
                $this->hosts[] = $host;
118
            }
119
        }
120
121 38
        return $this;
122
    }
123
124 3
    public function setCorsMiddleware(callable|array|string|null $corsMiddleware): self
125
    {
126 3
        $this->corsMiddleware = $corsMiddleware;
127 3
        return $this;
128
    }
129
130 1
    public function setPrefix(?string $prefix): self
131
    {
132 1
        $this->prefix = $prefix;
133 1
        return $this;
134
    }
135
136 1
    public function setNamePrefix(?string $namePrefix): self
137
    {
138 1
        $this->namePrefix = $namePrefix;
139 1
        return $this;
140
    }
141
142 4
    public function setDisabledMiddlewares(array $disabledMiddlewares): self
143
    {
144 4
        $this->disabledMiddlewares = $disabledMiddlewares;
145 4
        $this->enabledMiddlewaresCache = null;
146 4
        return $this;
147
    }
148
149
    /**
150
     * @return array[]|callable[]|string[]
151
     * @psalm-return list<array|callable|string>
152
     */
153 24
    public function getEnabledMiddlewares(): array
154
    {
155 24
        if ($this->enabledMiddlewaresCache !== null) {
156 13
            return $this->enabledMiddlewaresCache;
157
        }
158
159 24
        $this->enabledMiddlewaresCache = MiddlewareFilter::filter($this->middlewares, $this->disabledMiddlewares);
160
161 24
        return $this->enabledMiddlewaresCache;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->enabledMiddlewaresCache returns the type null which is incompatible with the type-hinted return array.
Loading history...
162
    }
163
164
    /**
165
     * @psalm-assert array<string> $hosts
166
     */
167 39
    private function assertHosts(array $hosts): void
168
    {
169 39
        foreach ($hosts as $host) {
170 6
            if (!is_string($host)) {
171 1
                throw new \InvalidArgumentException('Invalid $hosts provided, list of string expected.');
172
            }
173
        }
174
    }
175
176
    /**
177
     * @psalm-assert list<array|callable|string> $middlewares
178
     */
179 40
    private function assertMiddlewares(array $middlewares): void
180
    {
181
        /** @var mixed $middleware */
182 40
        foreach ($middlewares as $middleware) {
183 15
            if (is_string($middleware) || is_callable($middleware) || is_array($middleware)) {
184 15
                continue;
185
            }
186
187 1
            throw new \InvalidArgumentException(
188 1
                'Invalid $middlewares provided, list of string or array or callable expected.'
189 1
            );
190
        }
191
    }
192
193
    /**
194
     * @psalm-assert array<Route|Group|RoutableInterface> $routes
195
     */
196 40
    private function assertRoutes(array $routes): void
197
    {
198
        /** @var Group|RoutableInterface|Route $route */
199 40
        foreach ($routes as $route) {
200 23
            if ($route instanceof Route || $route instanceof self || $route instanceof RoutableInterface) {
201 23
                continue;
202
            }
203
204
            throw new \InvalidArgumentException(
205
                'Invalid $routes provided, array of `Route` or `Group` or `RoutableInterface` instance expected.'
206
            );
207
        }
208
    }
209
}
210