Passed
Pull Request — master (#115)
by Alexander
04:23 queued 02:16
created

Group::getMiddlewareDefinitions()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3.072

Importance

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