Test Failed
Pull Request — master (#134)
by Rustam
02:12
created

Group   A

Complexity

Total Complexity 33

Size/Duplication

Total Lines 180
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 8
Bugs 1 Features 0
Metric Value
eloc 77
c 8
b 1
f 0
dl 0
loc 180
ccs 60
cts 66
cp 0.9091
rs 9.76
wmc 33

16 Methods

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