Passed
Push — main ( 94bc2d...615377 )
by Chema
03:24 queued 56s
created

Routes::__call()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 6
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router\Configure;
6
7
use Gacela\Router\Controllers\RedirectController;
8
use Gacela\Router\Entities\Request;
9
use Gacela\Router\Entities\Route;
10
use Gacela\Router\Exceptions\UnsupportedHttpMethodException;
11
12
use function in_array;
13
use function is_array;
14
15
/**
16
 * @method head(string $path, object|string $controller, string $action = '__invoke')
17
 * @method connect(string $path, object|string $controller, string $action = '__invoke')
18
 * @method get(string $path, object|string $controller, string $action = '__invoke')
19
 * @method post(string $path, object|string $controller, string $action = '__invoke')
20
 * @method put(string $path, object|string $controller, string $action = '__invoke')
21
 * @method patch(string $path, object|string $controller, string $action = '__invoke')
22
 * @method delete(string $path, object|string $controller, string $action = '__invoke')
23
 * @method options(string $path, object|string $controller, string $action = '__invoke')
24
 * @method trace(string $path, object|string $controller, string $action = '__invoke')
25
 * @method any(string $path, object|string $controller, string $action = '__invoke')
26
 */
27
final class Routes
28
{
29
    /** @var list<Route> */
30
    private array $routes = [];
31
32
    /**
33
     * @psalm-suppress MixedArgument
34
     */
35 71
    public function __call(string $method, array $arguments): void
36
    {
37 71
        if ($method === 'any') {
38 9
            $this->addRoute(Request::ALL_METHODS, ...$arguments);
39
        } else {
40 62
            $this->addRoute($method, ...$arguments);
41
        }
42
    }
43
44
    /**
45
     * @psalm-suppress MixedArgument
46
     *
47
     * @param string[] $methods
48
     * @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...
49
     */
50 8
    public function match(array $methods, string $path, object|string $controller, string $action = '__invoke'): void
51
    {
52 8
        $this->addRoute($methods, $path, $controller, $action);
53
    }
54
55 15
    public function redirect(
56
        string $uri,
57
        string $destination,
58
        int $status = 302,
59
        string $method = null,
60
    ): void {
61 15
        if ($method === null) {
62 10
            $this->addRoute(Request::ALL_METHODS, $uri, new RedirectController($destination, $status));
63
        } else {
64 5
            $this->addRoute([$method], $uri, new RedirectController($destination, $status));
65
        }
66
    }
67
68
    /**
69
     * @return list<Route>
70
     */
71 95
    public function getAllRoutes(): array
72
    {
73 95
        return $this->routes;
74
    }
75
76
    /**
77
     * @param string[]|string $methods
78
     * @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...
79
     */
80 94
    private function addRoute(
81
        array|string $methods,
82
        string $path,
83
        object|string $controller,
84
        string $action = '__invoke',
85
    ): void {
86 94
        if (!is_array($methods)) {
0 ignored issues
show
introduced by
The condition is_array($methods) is always true.
Loading history...
87 62
            $methods = [$methods];
88
        }
89
90 94
        $methods = array_map(static fn ($method) => strtoupper($method), $methods);
91
92 94
        foreach ($methods as $method) {
93 94
            if (!in_array($method, Request::ALL_METHODS, true)) {
94 1
                throw UnsupportedHttpMethodException::withName($method);
95
            }
96 93
            $path = ($path === '/') ? '' : $path;
97
98 93
            $this->routes[] = new Route($method, $path, $controller, $action);
99
        }
100
    }
101
}
102