Passed
Pull Request — main (#37)
by Jesús
11:23 queued 08:20
created

Route::calculateDefaultPathPattern()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 12
c 0
b 0
f 0
nc 5
nop 0
dl 0
loc 19
ccs 12
cts 12
cp 1
crap 5
rs 9.5555
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router\Entities;
6
7
use Gacela\Container\Container;
8
use Gacela\Router\Configure\Bindings;
9
use Gacela\Router\Exceptions\UnsupportedResponseTypeException;
10
use Gacela\Router\Validators\PathPatternGenerator;
11
use Stringable;
12
13
use function is_object;
14
use function is_string;
15
16
final class Route
17
{
18
    /**
19
     * @param object|class-string $controller
0 ignored issues
show
Documentation Bug introduced by
The doc comment object|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in object|class-string.
Loading history...
20 102
     */
21
    public function __construct(
22
        private string $method,
23
        private string $path,
24
        private object|string $controller,
25
        private string $action = '__invoke',
26
        private ?string $pathPattern = null,
27 102
    ) {
28
    }
29
30
    /**
31
     * @psalm-suppress MixedMethodCall
32 97
     */
33
    public function run(Bindings $bindings): string|Stringable
34 97
    {
35
        $params = (new RouteParams($this))->getAll();
36 95
37 70
        if (!is_object($this->controller)) {
38
            $creator = new Container($bindings->getAllBindings());
39 70
            /** @var object $controller */
40 70
            $controller = $creator->get($this->controller);
41
            $response = $controller->{$this->action}(...$params);
42
        } else {
43 25
            /** @var string|Stringable $response */
44
            $response = $this->controller->{$this->action}(...$params);
45
        }
46 90
47 4
        if (!is_string($response) && !($response instanceof Stringable)) {
48
            throw UnsupportedResponseTypeException::fromType($response);
49
        }
50 86
51
        return $response;
52
    }
53 97
54
    public function path(): string
55 97
    {
56
        return $this->path;
57
    }
58
59
    /**
60
     * @return object|class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment object|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in object|class-string.
Loading history...
61 97
     */
62
    public function controller(): object|string
63 97
    {
64
        return $this->controller;
65
    }
66 97
67
    public function action(): string
68 97
    {
69
        return $this->action;
70
    }
71 97
72
    public function getPathPattern(): string
73 97
    {
74 97
        if ($this->pathPattern === null) {
75
            $this->pathPattern = PathPatternGenerator::generate($this->path);
76
        }
77 97
78
        return $this->pathPattern;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->pathPattern could return the type null which is incompatible with the type-hinted return string. Consider adding an additional type-check to rule them out.
Loading history...
79
    }
80 102
81
    public function requestMatches(): bool
82 102
    {
83
        return $this->methodMatches() && $this->pathMatches();
84
    }
85 102
86
    private function methodMatches(): bool
87 102
    {
88
        return Request::fromGlobals()->isMethod($this->method);
89
    }
90 97
91
    private function pathMatches(): bool
92 97
    {
93
        $path = Request::fromGlobals()->path();
94 97
95
        return (bool)preg_match($this->getPathPattern(), $path);
96
    }
97
}
98