Passed
Pull Request — master (#225)
by Rustam
11:11 queued 08:15
created

GroupBuilder::routes()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 6
nc 2
nop 1
dl 0
loc 11
ccs 7
cts 7
cp 1
crap 2
rs 10
c 1
b 0
f 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Router\Builder;
6
7
use RuntimeException;
8
use Yiisoft\Router\Group;
9
use Yiisoft\Router\RoutableInterface;
10
use Yiisoft\Router\Route;
11
12
/**
13
 * GroupBuilder allows you to build group of routes using a flexible syntax.
14
 */
15
final class GroupBuilder implements RoutableInterface
16
{
17
    /**
18
     * @var Group[]|RoutableInterface[]|Route[]
19
     */
20
    private array $routes = [];
21
22
    /**
23
     * @var array[]|callable[]|string[]
24
     * @psalm-var list<array|callable|string>
25
     */
26
    private array $middlewares = [];
27
28
    private array $disabledMiddlewares = [];
29
30
    /**
31
     * @var string[]
32
     */
33
    private array $hosts = [];
34
    private bool $routesAdded = false;
35
    private bool $middlewareAdded = false;
36
37
    /**
38
     * @var array|callable|string|null Middleware definition for CORS requests.
39
     */
40
    private $corsMiddleware = null;
41
42 36
    private function __construct(
43
        private ?string $prefix = null,
44
        private ?string $namePrefix = null,
45
    ) {
46 36
    }
47
48
    /**
49
     * Create a new group instance.
50
     *
51
     * @param string|null $prefix URL prefix to prepend to all routes of the group.
52
     */
53 36
    public static function create(?string $prefix = null, ?string $namePrefix = null): self
54
    {
55 36
        return new self($prefix, $namePrefix);
56
    }
57
58 29
    public function routes(Group|Route|RoutableInterface ...$routes): self
59
    {
60 29
        if ($this->middlewareAdded) {
61 1
            throw new RuntimeException('routes() can not be used after prependMiddleware().');
62
        }
63
64 28
        $new = clone $this;
65 28
        $new->routes = $routes;
66 28
        $new->routesAdded = true;
67
68 28
        return $new;
69
    }
70
71
    /**
72
     * Adds a middleware definition that handles CORS requests.
73
     * If set, routes for {@see Method::OPTIONS} request will be added automatically.
74
     *
75
     * @param array|callable|string|null $middlewareDefinition Middleware definition for CORS requests.
76
     */
77 8
    public function withCors(array|callable|string|null $middlewareDefinition): self
78
    {
79 8
        $group = clone $this;
80 8
        $group->corsMiddleware = $middlewareDefinition;
81
82 8
        return $group;
83
    }
84
85
    /**
86
     * Appends a handler middleware definition that should be invoked for a matched route.
87
     * First added handler will be executed first.
88
     */
89 11
    public function middleware(array|callable|string ...$definition): self
90
    {
91 11
        if ($this->routesAdded) {
92 1
            throw new RuntimeException('middleware() can not be used after routes().');
93
        }
94
95 10
        $new = clone $this;
96 10
        array_push(
97 10
            $new->middlewares,
98 10
            ...array_values($definition)
99 10
        );
100
101 10
        return $new;
102
    }
103
104
    /**
105
     * Prepends a handler middleware definition that should be invoked for a matched route.
106
     * First added handler will be executed last.
107
     */
108 4
    public function prependMiddleware(array|callable|string ...$definition): self
109
    {
110 4
        $new = clone $this;
111 4
        array_unshift(
112 4
            $new->middlewares,
113 4
            ...array_values($definition)
114 4
        );
115
116 4
        $new->middlewareAdded = true;
117
118 4
        return $new;
119
    }
120
121 4
    public function namePrefix(string $namePrefix): self
122
    {
123 4
        $new = clone $this;
124 4
        $new->namePrefix = $namePrefix;
125 4
        return $new;
126
    }
127
128 2
    public function host(string $host): self
129
    {
130 2
        return $this->hosts($host);
131
    }
132
133 5
    public function hosts(string ...$hosts): self
134
    {
135 5
        $new = clone $this;
136 5
        $new->hosts = array_values($hosts);
137
138 5
        return $new;
139
    }
140
141
    /**
142
     * Excludes middleware from being invoked when action is handled.
143
     * It is useful to avoid invoking one of the parent group middleware for
144
     * a certain route.
145
     */
146 3
    public function disableMiddleware(mixed ...$definition): self
147
    {
148 3
        $new = clone $this;
149 3
        array_push(
150 3
            $new->disabledMiddlewares,
151 3
            ...array_values($definition),
152 3
        );
153
154 3
        return $new;
155
    }
156
157 30
    public function toRoute(): Group|Route
158
    {
159 30
        return new Group(
160 30
            prefix: $this->prefix,
161 30
            namePrefix: $this->namePrefix,
162 30
            routes: $this->routes,
163 30
            middlewares: $this->middlewares,
164 30
            hosts: $this->hosts,
165 30
            disabledMiddlewares: $this->disabledMiddlewares,
166 30
            corsMiddleware: $this->corsMiddleware
167 30
        );
168
    }
169
}
170