Route::withRequestMethod()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 4
dl 0
loc 8
rs 10
c 1
b 0
f 0
cc 1
nc 1
nop 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\Http\Routing\Data;
15
16
use Override;
0 ignored issues
show
Bug introduced by
The type Override was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Valkyrja\Dispatcher\Data\Contract\MethodDispatch;
18
use Valkyrja\Http\Message\Enum\RequestMethod;
0 ignored issues
show
Bug introduced by
The type Valkyrja\Http\Message\Enum\RequestMethod was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
19
use Valkyrja\Http\Middleware\Contract\RouteDispatchedMiddleware;
20
use Valkyrja\Http\Middleware\Contract\RouteMatchedMiddleware;
21
use Valkyrja\Http\Middleware\Contract\SendingResponseMiddleware;
22
use Valkyrja\Http\Middleware\Contract\TerminatedMiddleware;
23
use Valkyrja\Http\Middleware\Contract\ThrowableCaughtMiddleware;
24
use Valkyrja\Http\Routing\Data\Contract\Parameter;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Valkyrja\Http\Routing\Data\Parameter. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
25
use Valkyrja\Http\Routing\Data\Contract\Route as Contract;
26
use Valkyrja\Http\Struct\Request\Contract\RequestStruct;
27
use Valkyrja\Http\Struct\Response\Contract\ResponseStruct;
28
29
use function in_array;
30
31
/**
32
 * Class Route.
33
 *
34
 * @author Melech Mizrachi
35
 */
36
class Route implements Contract
37
{
38
    /**
39
     * @param non-empty-string                          $path                      The path
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
40
     * @param non-empty-string                          $name                      The name
41
     * @param non-empty-string|null                     $regex                     The regex
42
     * @param RequestMethod[]                           $requestMethods            The request methods
43
     * @param Parameter[]                               $parameters                The parameters
44
     * @param class-string<RouteMatchedMiddleware>[]    $routeMatchedMiddleware    The route matched middleware
45
     * @param class-string<RouteDispatchedMiddleware>[] $routeDispatchedMiddleware The route dispatched middleware
46
     * @param class-string<ThrowableCaughtMiddleware>[] $throwableCaughtMiddleware The throwable caught middleware
47
     * @param class-string<SendingResponseMiddleware>[] $sendingResponseMiddleware The sending response middleware
48
     * @param class-string<TerminatedMiddleware>[]      $terminatedMiddleware      The terminated middleware
49
     * @param class-string<RequestStruct>|null          $requestStruct             The request struct
50
     * @param class-string<ResponseStruct>|null         $responseStruct            The response struct
51
     */
52
    public function __construct(
53
        protected string $path,
54
        protected string $name,
55
        protected MethodDispatch $dispatch = new \Valkyrja\Dispatcher\Data\MethodDispatch(self::class, 'getPath'),
56
        protected array $requestMethods = [RequestMethod::HEAD, RequestMethod::GET],
57
        protected string|null $regex = null,
58
        protected array $parameters = [],
59
        protected array $routeMatchedMiddleware = [],
60
        protected array $routeDispatchedMiddleware = [],
61
        protected array $throwableCaughtMiddleware = [],
62
        protected array $sendingResponseMiddleware = [],
63
        protected array $terminatedMiddleware = [],
64
        protected string|null $requestStruct = null,
65
        protected string|null $responseStruct = null,
66
    ) {
67
    }
68
69
    /**
70
     * @inheritDoc
71
     */
72
    #[Override]
73
    public function getPath(): string
74
    {
75
        return $this->path;
76
    }
77
78
    /**
79
     * @inheritDoc
80
     */
81
    #[Override]
82
    public function withPath(string $path): static
83
    {
84
        $new = clone $this;
85
86
        $new->path = $path;
87
88
        return $new;
89
    }
90
91
    /**
92
     * @inheritDoc
93
     */
94
    #[Override]
95
    public function withAddedPath(string $path): static
96
    {
97
        $new = clone $this;
98
99
        $filteredExistingPath = $this->getFilteredPath($this->path);
100
        $filteredPath         = $this->getFilteredPath($path);
101
102
        $new->path = $this->getFilteredPath($filteredExistingPath . $filteredPath);
103
104
        return $new;
105
    }
106
107
    /**
108
     * @inheritDoc
109
     */
110
    #[Override]
111
    public function getName(): string
112
    {
113
        return $this->name;
114
    }
115
116
    /**
117
     * @inheritDoc
118
     */
119
    #[Override]
120
    public function withName(string $name): static
121
    {
122
        $new = clone $this;
123
124
        $new->name = $name;
125
126
        return $new;
127
    }
128
129
    /**
130
     * @inheritDoc
131
     */
132
    #[Override]
133
    public function withAddedName(string $name): static
134
    {
135
        $new = clone $this;
136
137
        $new->name = $this->name . $name;
138
139
        return $new;
140
    }
141
142
    /**
143
     * @inheritDoc
144
     */
145
    #[Override]
146
    public function getDispatch(): MethodDispatch
147
    {
148
        return $this->dispatch;
149
    }
150
151
    /**
152
     * @inheritDoc
153
     */
154
    #[Override]
155
    public function withDispatch(MethodDispatch $dispatch): static
156
    {
157
        $new = clone $this;
158
159
        $new->dispatch = $dispatch;
160
161
        return $new;
162
    }
163
164
    /**
165
     * @inheritDoc
166
     *
167
     * @return RequestMethod[]
168
     */
169
    #[Override]
170
    public function getRequestMethods(): array
171
    {
172
        return $this->requestMethods;
173
    }
174
175
    /**
176
     * @inheritDoc
177
     */
178
    #[Override]
179
    public function hasRequestMethod(RequestMethod $requestMethod): bool
180
    {
181
        return in_array($requestMethod, $this->requestMethods, true);
182
    }
183
184
    /**
185
     * @inheritDoc
186
     */
187
    #[Override]
188
    public function withRequestMethod(RequestMethod $requestMethod): static
189
    {
190
        $new = clone $this;
191
192
        $new->requestMethods = [$requestMethod];
193
194
        return $new;
195
    }
196
197
    /**
198
     * @inheritDoc
199
     */
200
    #[Override]
201
    public function withRequestMethods(RequestMethod ...$requestMethods): static
202
    {
203
        $new = clone $this;
204
205
        $new->requestMethods = $requestMethods;
206
207
        return $new;
208
    }
209
210
    /**
211
     * @inheritDoc
212
     */
213
    #[Override]
214
    public function withAddedRequestMethod(RequestMethod $requestMethod): static
215
    {
216
        $new = clone $this;
217
218
        if (! in_array($requestMethod, $this->requestMethods, true)) {
219
            $new->requestMethods[] = $requestMethod;
220
        }
221
222
        return $new;
223
    }
224
225
    /**
226
     * @inheritDoc
227
     */
228
    #[Override]
229
    public function withAddedRequestMethods(RequestMethod ...$requestMethods): static
230
    {
231
        $new = clone $this;
232
233
        foreach ($requestMethods as $requestMethod) {
234
            if (! in_array($requestMethod, $this->requestMethods, true)) {
235
                $new->requestMethods[] = $requestMethod;
236
            }
237
        }
238
239
        return $new;
240
    }
241
242
    /**
243
     * @inheritDoc
244
     */
245
    #[Override]
246
    public function getRegex(): string|null
247
    {
248
        return $this->regex;
249
    }
250
251
    /**
252
     * @inheritDoc
253
     */
254
    #[Override]
255
    public function withRegex(string|null $regex = null): static
256
    {
257
        $new = clone $this;
258
259
        $new->regex = $regex;
260
261
        return $new;
262
    }
263
264
    /**
265
     * @inheritDoc
266
     *
267
     * @return array<array-key, Parameter>
0 ignored issues
show
Documentation Bug introduced by
The doc comment array<array-key, Parameter> at position 2 could not be parsed: Unknown type name 'array-key' at position 2 in array<array-key, Parameter>.
Loading history...
268
     */
269
    #[Override]
270
    public function getParameters(): array
271
    {
272
        return $this->parameters;
273
    }
274
275
    /**
276
     * @inheritDoc
277
     */
278
    #[Override]
279
    public function withParameter(Parameter $parameter): static
280
    {
281
        $new = clone $this;
282
283
        $new->parameters = [$parameter];
284
285
        return $new;
286
    }
287
288
    /**
289
     * @inheritDoc
290
     */
291
    #[Override]
292
    public function withParameters(Parameter ...$parameters): static
293
    {
294
        $new = clone $this;
295
296
        $new->parameters = $parameters;
297
298
        return $new;
299
    }
300
301
    /**
302
     * @inheritDoc
303
     */
304
    #[Override]
305
    public function withAddedParameter(Parameter $parameter): static
306
    {
307
        $new = clone $this;
308
309
        $new->parameters[] = $parameter;
310
311
        return $new;
312
    }
313
314
    /**
315
     * @inheritDoc
316
     */
317
    #[Override]
318
    public function withAddedParameters(Parameter ...$parameters): static
319
    {
320
        $new = clone $this;
321
322
        $new->parameters = array_merge($this->parameters, $parameters);
323
324
        return $new;
325
    }
326
327
    /**
328
     * @inheritDoc
329
     *
330
     * @return class-string<RouteMatchedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteMatchedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteMatchedMiddleware>[].
Loading history...
331
     */
332
    #[Override]
333
    public function getRouteMatchedMiddleware(): array
334
    {
335
        return $this->routeMatchedMiddleware;
336
    }
337
338
    /**
339
     * @inheritDoc
340
     *
341
     * @param class-string<RouteMatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteMatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteMatchedMiddleware>.
Loading history...
342
     */
343
    #[Override]
344
    public function withRouteMatchedMiddleware(string ...$middleware): static
345
    {
346
        $new = clone $this;
347
348
        $new->routeMatchedMiddleware = $middleware;
349
350
        return $new;
351
    }
352
353
    /**
354
     * @inheritDoc
355
     *
356
     * @param class-string<RouteMatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteMatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteMatchedMiddleware>.
Loading history...
357
     */
358
    #[Override]
359
    public function withAddedRouteMatchedMiddleware(string ...$middleware): static
360
    {
361
        $new = clone $this;
362
363
        $new->routeMatchedMiddleware = array_merge($this->routeMatchedMiddleware, $middleware);
364
365
        return $new;
366
    }
367
368
    /**
369
     * @inheritDoc
370
     *
371
     * @return class-string<RouteDispatchedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteDispatchedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteDispatchedMiddleware>[].
Loading history...
372
     */
373
    #[Override]
374
    public function getRouteDispatchedMiddleware(): array
375
    {
376
        return $this->routeDispatchedMiddleware;
377
    }
378
379
    /**
380
     * @inheritDoc
381
     *
382
     * @param class-string<RouteDispatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteDispatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteDispatchedMiddleware>.
Loading history...
383
     */
384
    #[Override]
385
    public function withRouteDispatchedMiddleware(string ...$middleware): static
386
    {
387
        $new = clone $this;
388
389
        $new->routeDispatchedMiddleware = $middleware;
390
391
        return $new;
392
    }
393
394
    /**
395
     * @inheritDoc
396
     *
397
     * @param class-string<RouteDispatchedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<RouteDispatchedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<RouteDispatchedMiddleware>.
Loading history...
398
     */
399
    #[Override]
400
    public function withAddedRouteDispatchedMiddleware(string ...$middleware): static
401
    {
402
        $new = clone $this;
403
404
        $new->routeDispatchedMiddleware = array_merge($this->routeDispatchedMiddleware, $middleware);
405
406
        return $new;
407
    }
408
409
    /**
410
     * @inheritDoc
411
     *
412
     * @return class-string<ThrowableCaughtMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>[].
Loading history...
413
     */
414
    #[Override]
415
    public function getThrowableCaughtMiddleware(): array
416
    {
417
        return $this->throwableCaughtMiddleware;
418
    }
419
420
    /**
421
     * @inheritDoc
422
     *
423
     * @param class-string<ThrowableCaughtMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>.
Loading history...
424
     */
425
    #[Override]
426
    public function withThrowableCaughtMiddleware(string ...$middleware): static
427
    {
428
        $new = clone $this;
429
430
        $new->throwableCaughtMiddleware = $middleware;
431
432
        return $new;
433
    }
434
435
    /**
436
     * @inheritDoc
437
     *
438
     * @param class-string<ThrowableCaughtMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<ThrowableCaughtMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<ThrowableCaughtMiddleware>.
Loading history...
439
     */
440
    #[Override]
441
    public function withAddedThrowableCaughtMiddleware(string ...$middleware): static
442
    {
443
        $new = clone $this;
444
445
        $new->throwableCaughtMiddleware = array_merge($this->throwableCaughtMiddleware, $middleware);
446
447
        return $new;
448
    }
449
450
    /**
451
     * @inheritDoc
452
     *
453
     * @return class-string<SendingResponseMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<SendingResponseMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<SendingResponseMiddleware>[].
Loading history...
454
     */
455
    #[Override]
456
    public function getSendingResponseMiddleware(): array
457
    {
458
        return $this->sendingResponseMiddleware;
459
    }
460
461
    /**
462
     * @inheritDoc
463
     *
464
     * @param class-string<SendingResponseMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<SendingResponseMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<SendingResponseMiddleware>.
Loading history...
465
     */
466
    #[Override]
467
    public function withSendingResponseMiddleware(string ...$middleware): static
468
    {
469
        $new = clone $this;
470
471
        $new->sendingResponseMiddleware = $middleware;
472
473
        return $new;
474
    }
475
476
    /**
477
     * @inheritDoc
478
     *
479
     * @param class-string<SendingResponseMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<SendingResponseMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<SendingResponseMiddleware>.
Loading history...
480
     */
481
    #[Override]
482
    public function withAddedSendingResponseMiddleware(string ...$middleware): static
483
    {
484
        $new = clone $this;
485
486
        $new->sendingResponseMiddleware = array_merge($this->sendingResponseMiddleware, $middleware);
487
488
        return $new;
489
    }
490
491
    /**
492
     * @inheritDoc
493
     *
494
     * @return class-string<TerminatedMiddleware>[]
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TerminatedMiddleware>[] at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TerminatedMiddleware>[].
Loading history...
495
     */
496
    #[Override]
497
    public function getTerminatedMiddleware(): array
498
    {
499
        return $this->terminatedMiddleware;
500
    }
501
502
    /**
503
     * @inheritDoc
504
     *
505
     * @param class-string<TerminatedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TerminatedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TerminatedMiddleware>.
Loading history...
506
     */
507
    #[Override]
508
    public function withTerminatedMiddleware(string ...$middleware): static
509
    {
510
        $new = clone $this;
511
512
        $new->terminatedMiddleware = $middleware;
513
514
        return $new;
515
    }
516
517
    /**
518
     * @inheritDoc
519
     *
520
     * @param class-string<TerminatedMiddleware> ...$middleware The middleware
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string<TerminatedMiddleware> at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string<TerminatedMiddleware>.
Loading history...
521
     */
522
    #[Override]
523
    public function withAddedTerminatedMiddleware(string ...$middleware): static
524
    {
525
        $new = clone $this;
526
527
        $new->terminatedMiddleware = array_merge($this->terminatedMiddleware, $middleware);
528
529
        return $new;
530
    }
531
532
    /**
533
     * @inheritDoc
534
     */
535
    #[Override]
536
    public function getRequestStruct(): string|null
537
    {
538
        return $this->requestStruct;
539
    }
540
541
    /**
542
     * @inheritDoc
543
     */
544
    #[Override]
545
    public function withRequestStruct(string|null $requestStruct = null): static
546
    {
547
        $new = clone $this;
548
549
        $new->requestStruct = $requestStruct;
550
551
        return $new;
552
    }
553
554
    /**
555
     * @inheritDoc
556
     */
557
    #[Override]
558
    public function getResponseStruct(): string|null
559
    {
560
        return $this->responseStruct;
561
    }
562
563
    /**
564
     * @inheritDoc
565
     */
566
    #[Override]
567
    public function withResponseStruct(string|null $responseStruct = null): static
568
    {
569
        $new = clone $this;
570
571
        $new->responseStruct = $responseStruct;
572
573
        return $new;
574
    }
575
576
    /**
577
     * Validate a path.
578
     *
579
     * @param non-empty-string $path The path
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
580
     *
581
     * @return non-empty-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment non-empty-string at position 0 could not be parsed: Unknown type name 'non-empty-string' at position 0 in non-empty-string.
Loading history...
582
     */
583
    protected function getFilteredPath(string $path): string
584
    {
585
        // Trim slashes from the beginning and end of the path
586
        if (! $path = trim($path, '/')) {
587
            // If the path only had a slash return as just slash
588
            return '/';
589
        }
590
591
        // Prepend a slash
592
        return '/' . $path;
593
    }
594
}
595