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

GroupBuilder::middleware()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

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