Passed
Push — master ( 57e6a4...af6527 )
by Melech
05:41 queued 01:55
created

Route   A

Complexity

Total Complexity 38

Size/Duplication

Total Lines 421
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 85
c 4
b 0
f 0
dl 0
loc 421
rs 9.36
wmc 38

31 Methods

Rating   Name   Duplication   Size   Complexity  
A setRegex() 0 5 1
A getCode() 0 3 1
A withPath() 0 7 1
A setPath() 0 5 1
A setCode() 0 5 1
A getMethods() 0 3 1
A setMethods() 0 10 2
A getRegex() 0 3 1
A withName() 0 13 3
A getTo() 0 3 1
A getPath() 0 3 1
A setMiddleware() 0 5 1
A __setMessages() 0 7 2
A isRedirect() 0 3 1
A withMessages() 0 7 1
A getMessages() 0 3 1
A getMiddleware() 0 3 1
A setMessages() 0 5 1
A setParameters() 0 16 4
A addParameter() 0 16 1
A setTo() 0 7 1
A setRedirect() 0 5 1
A withMiddleware() 0 7 1
A withMessage() 0 3 1
A setDynamic() 0 5 1
A isDynamic() 0 3 1
A setSecure() 0 5 1
A __setParameters() 0 3 1
A setParameter() 0 7 1
A isSecure() 0 3 1
A getParameters() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Valkyrja Framework package.
7
 *
8
 * (c) Melech Mizrachi <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Valkyrja\Routing\Models;
15
16
use InvalidArgumentException;
17
use Valkyrja\Dispatcher\Models\Dispatch;
18
use Valkyrja\Http\Constants\RequestMethod;
19
use Valkyrja\Model\Data\Cast;
20
use Valkyrja\Routing\Constants\Regex;
21
use Valkyrja\Routing\Message;
22
use Valkyrja\Routing\Route as Contract;
23
24
use function assert;
25
use function is_array;
26
27
/**
28
 * Class Route.
29
 *
30
 * @author Melech Mizrachi
31
 */
32
class Route extends Dispatch implements Contract
33
{
34
    /**
35
     * The path for this route.
36
     *
37
     * @var string
38
     */
39
    protected string $path = '';
40
41
    /**
42
     * The redirect path for this route.
43
     *
44
     * @var string|null
45
     */
46
    protected string|null $to;
47
48
    /**
49
     * The redirect status code for this route.
50
     *
51
     * @var int|null
52
     */
53
    protected int|null $code;
54
55
    /**
56
     * The request methods for this route.
57
     *
58
     * @var array
59
     */
60
    protected array $methods = [
61
        RequestMethod::GET,
62
        RequestMethod::HEAD,
63
    ];
64
65
    /**
66
     * The regex for dynamic routes.
67
     *
68
     * @var string|null
69
     */
70
    protected string|null $regex;
71
72
    /**
73
     * The dynamic parameters.
74
     *
75
     * @var array<int, Parameter>
76
     */
77
    protected array $parameters;
78
79
    /**
80
     * The middleware for this route.
81
     *
82
     * @var array|null
83
     */
84
    protected array|null $middleware;
85
86
    /**
87
     * The messages for this route.
88
     *
89
     * @var class-string<Message>[]|null
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message>[]|null at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>[]|null.
Loading history...
90
     */
91
    protected array|null $messages;
92
93
    /**
94
     * Whether the route is dynamic.
95
     *
96
     * @var bool
97
     */
98
    protected bool $dynamic = false;
99
100
    /**
101
     * Whether the route is secure.
102
     *
103
     * @var bool
104
     */
105
    protected bool $secure = false;
106
107
    /**
108
     * Whether the route is a redirect.
109
     *
110
     * @var bool
111
     */
112
    protected bool $redirect = false;
113
114
    /**
115
     * @inheritDoc
116
     */
117
    public function getPath(): string
118
    {
119
        return $this->path;
120
    }
121
122
    /**
123
     * @inheritDoc
124
     */
125
    public function setPath(string $path): static
126
    {
127
        $this->path = $path;
128
129
        return $this;
130
    }
131
132
    /**
133
     * @inheritDoc
134
     */
135
    public function withPath(string $path): static
136
    {
137
        $route = clone $this;
138
139
        $route->path .= $path;
140
141
        return $route;
142
    }
143
144
    /**
145
     * @inheritDoc
146
     */
147
    public function withName(string $name): static
148
    {
149
        $route = clone $this;
150
151
        $currentName = $this->name ?? '';
152
153
        if ($name) {
154
            $route->name = $currentName
155
                ? "$currentName.$name"
156
                : $name;
157
        }
158
159
        return $route;
160
    }
161
162
    /**
163
     * @inheritDoc
164
     */
165
    public function getTo(): string|null
166
    {
167
        return $this->to ?? null;
168
    }
169
170
    /**
171
     * @inheritDoc
172
     */
173
    public function setTo(string|null $to = null): static
174
    {
175
        $this->redirect = $to !== null;
176
177
        $this->to = $to;
178
179
        return $this;
180
    }
181
182
    /**
183
     * @inheritDoc
184
     */
185
    public function getCode(): int|null
186
    {
187
        return $this->code ?? null;
188
    }
189
190
    /**
191
     * @inheritDoc
192
     */
193
    public function setCode(int|null $code = null): static
194
    {
195
        $this->code = $code;
196
197
        return $this;
198
    }
199
200
    /**
201
     * @inheritDoc
202
     */
203
    public function getMethods(): array
204
    {
205
        return $this->methods;
206
    }
207
208
    /**
209
     * @inheritDoc
210
     */
211
    public function setMethods(array $methods): static
212
    {
213
        // TODO: Change to use Method enum
214
        if (array_diff($methods, RequestMethod::ANY)) {
215
            throw new InvalidArgumentException('Invalid request methods set');
216
        }
217
218
        $this->methods = $methods;
219
220
        return $this;
221
    }
222
223
    /**
224
     * @inheritDoc
225
     */
226
    public function getRegex(): string|null
227
    {
228
        return $this->regex ?? null;
229
    }
230
231
    /**
232
     * @inheritDoc
233
     */
234
    public function setRegex(string|null $regex = null): static
235
    {
236
        $this->regex = $regex;
237
238
        return $this;
239
    }
240
241
    /**
242
     * @inheritDoc
243
     */
244
    public function getParameters(): array
245
    {
246
        return $this->parameters ?? [];
247
    }
248
249
    /**
250
     * @inheritDoc
251
     */
252
    public function setParameters(array $parameters): static
253
    {
254
        // If this is an array of arrays vs an array of Parameter models
255
        if (is_array($parameters[0] ?? null)) {
256
            foreach ($parameters as $key => $parameter) {
257
                if (is_array($parameter)) {
258
                    // Convert each array to a Parameter model
259
                    $parameters[$key] = Parameter::fromArray($parameter);
260
                }
261
            }
262
        }
263
264
        /** @var Parameter[] $parameters */
265
        $this->__setParameters(...$parameters);
266
267
        return $this;
268
    }
269
270
    /**
271
     * @inheritDoc
272
     */
273
    public function setParameter(Parameter $parameter): static
274
    {
275
        $this->parameters ??= [];
276
277
        $this->parameters[] = $parameter;
278
279
        return $this;
280
    }
281
282
    /**
283
     * @inheritDoc
284
     */
285
    public function addParameter(
286
        string $name,
287
        string|null $regex = null,
288
        Cast|null $cast = null,
289
        bool $isOptional = false,
290
        bool $shouldCapture = true,
291
        mixed $default = null
292
    ): static {
293
        return $this->setParameter(
294
            new Parameter(
295
                name: $name,
296
                regex: $regex ?? Regex::ANY,
297
                cast: $cast,
298
                isOptional: $isOptional,
299
                shouldCapture: $shouldCapture,
300
                default: $default
301
            )
302
        );
303
    }
304
305
    /**
306
     * @inheritDoc
307
     */
308
    public function getMiddleware(): array|null
309
    {
310
        return $this->middleware ?? null;
311
    }
312
313
    /**
314
     * @inheritDoc
315
     */
316
    public function setMiddleware(array|null $middleware = null): static
317
    {
318
        $this->middleware = $middleware;
319
320
        return $this;
321
    }
322
323
    /**
324
     * @inheritDoc
325
     */
326
    public function withMiddleware(array $middleware): static
327
    {
328
        $route = clone $this;
329
330
        $route->middleware = array_merge($this->middleware ?? [], $middleware);
331
332
        return $route;
333
    }
334
335
    /**
336
     * @inheritDoc
337
     */
338
    public function getMessages(): array|null
339
    {
340
        return $this->messages ?? null;
341
    }
342
343
    /**
344
     * @inheritDoc
345
     */
346
    public function setMessages(array|null $messages = null): static
347
    {
348
        $this->__setMessages(...$messages);
349
350
        return $this;
351
    }
352
353
    /**
354
     * @inheritDoc
355
     */
356
    public function withMessages(array $messages): static
357
    {
358
        $route = clone $this;
359
360
        $route->__setMessages(...array_merge($this->messages ?? [], $messages));
361
362
        return $route;
363
    }
364
365
    /**
366
     * @inheritDoc
367
     */
368
    public function withMessage(string $message): static
369
    {
370
        return $this->withMessages([$message]);
371
    }
372
373
    /**
374
     * @inheritDoc
375
     */
376
    public function isDynamic(): bool
377
    {
378
        return $this->dynamic;
379
    }
380
381
    /**
382
     * @inheritDoc
383
     */
384
    public function setDynamic(bool $dynamic = true): static
385
    {
386
        $this->dynamic = $dynamic;
387
388
        return $this;
389
    }
390
391
    /**
392
     * @inheritDoc
393
     */
394
    public function isSecure(): bool
395
    {
396
        return $this->secure;
397
    }
398
399
    /**
400
     * @inheritDoc
401
     */
402
    public function setSecure(bool $secure = true): static
403
    {
404
        $this->secure = $secure;
405
406
        return $this;
407
    }
408
409
    /**
410
     * @inheritDoc
411
     */
412
    public function isRedirect(): bool
413
    {
414
        return $this->redirect;
415
    }
416
417
    /**
418
     * @inheritDoc
419
     */
420
    public function setRedirect(bool $redirect): static
421
    {
422
        $this->redirect = $redirect;
423
424
        return $this;
425
    }
426
427
    /**
428
     * Set the parameters.
429
     *
430
     * @param array<int, Parameter> $parameters The parameters
431
     *
432
     * @return void
433
     */
434
    protected function __setParameters(Parameter ...$parameters): void
435
    {
436
        $this->parameters = $parameters;
437
    }
438
439
    /**
440
     * Set the messages.
441
     *
442
     * @param class-string<Message>[] $messages The messages
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<Message>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<Message>[].
Loading history...
443
     *
444
     * @return void
445
     */
446
    protected function __setMessages(string ...$messages): void
447
    {
448
        foreach ($messages as $message) {
449
            assert(is_a($message, Message::class, true));
450
        }
451
452
        $this->messages = $messages;
453
    }
454
}
455