Passed
Push — main ( 13bcd8...97d8ea )
by Chema
54s queued 14s
created

Router   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 63
Duplicated Lines 0 %

Test Coverage

Coverage 96.77%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 28
dl 0
loc 63
ccs 30
cts 31
cp 0.9677
rs 10
c 2
b 0
f 0
wmc 9

4 Methods

Rating   Name   Duplication   Size   Complexity  
A findHandler() 0 4 1
A handleException() 0 15 3
A configure() 0 20 2
A findRoute() 0 9 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Gacela\Router;
6
7
use Closure;
8
use Exception;
9
use Gacela\Resolver\InstanceCreator;
10
use Gacela\Router\Entities\Route;
11
use Gacela\Router\Exceptions\NotFound404Exception;
12
use ReflectionException;
13
use ReflectionFunction;
14
15
use function get_class;
16
use function is_callable;
17
18
final class Router
19
{
20
    /**
21
     * @throws ReflectionException
22
     */
23 82
    public static function configure(Closure $fn): void
24
    {
25 82
        $routes = new Routes();
26 82
        $bindings = new Bindings();
27 82
        $handlers = new Handlers();
28
29 82
        $params = array_map(static fn ($param) => match ((string)$param->getType()) {
30 82
            Routes::class => $routes,
31 82
            Bindings::class => $bindings,
32 82
            Handlers::class => $handlers,
33 82
            default => null,
34 82
        }, (new ReflectionFunction($fn))->getParameters());
35
36 82
        $fn(...$params);
37
38
        try {
39 81
            echo self::findRoute($routes)
40 81
                ->run($bindings);
41 11
        } catch (Exception $exception) {
42 11
            echo self::handleException($handlers, $exception);
43
        }
44
    }
45
46 81
    private static function findRoute(Routes $routes): Route
47
    {
48 81
        foreach ($routes->getAllRoutes() as $route) {
49 79
            if ($route->requestMatches()) {
50 74
                return $route;
51
            }
52
        }
53
54 7
        throw new NotFound404Exception();
55
    }
56
57 11
    private static function handleException(Handlers $handlers, Exception $exception): string
58
    {
59 11
        $handler = self::findHandler($handlers, $exception);
60
61 11
        if (is_callable($handler)) {
62 4
            return $handler($exception);
63
        }
64
65 7
        $instance = (new InstanceCreator())->createByClassName($handler);
0 ignored issues
show
Bug introduced by
It seems like $handler can also be of type callable; however, parameter $className of Gacela\Resolver\Instance...or::createByClassName() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

65
        $instance = (new InstanceCreator())->createByClassName(/** @scrutinizer ignore-type */ $handler);
Loading history...
66
67 7
        if (is_callable($instance)) {
68 7
            return $instance($exception);
69
        }
70
71
        return '';
72
    }
73
74
    /**
75
     * @return callable|class-string
0 ignored issues
show
Documentation Bug introduced by
The doc comment callable|class-string at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in callable|class-string.
Loading history...
76
     */
77 11
    private static function findHandler(Handlers $handlers, Exception $exception): string|callable
78
    {
79 11
        return $handlers->getAllHandlers()[get_class($exception)]
80 11
            ?? $handlers->getAllHandlers()[Exception::class];
81
    }
82
}
83