Passed
Pull Request — master (#831)
by Maxim
15:41
created

RouterBootloader   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 7
eloc 35
dl 0
loc 79
ccs 20
cts 22
cp 0.9091
rs 10
c 2
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A initRegistry() 0 4 1
A boot() 0 15 2
A route() 0 8 2
A router() 0 12 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Spiral\Bootloader\Http;
6
7
use Psr\Container\ContainerInterface;
8
use Psr\EventDispatcher\EventDispatcherInterface;
9
use Psr\Http\Message\ServerRequestInterface;
10
use Psr\Http\Server\RequestHandlerInterface;
11
use Spiral\Boot\AbstractKernel;
12
use Spiral\Boot\Bootloader\Bootloader;
13
use Spiral\Config\ConfiguratorInterface;
14
use Spiral\Core\Core;
15
use Spiral\Core\CoreInterface;
16
use Spiral\Core\Exception\ScopeException;
17
use Spiral\Framework\Kernel;
18
use Spiral\Http\Config\HttpConfig;
19
use Spiral\Router\GroupRegistry;
20
use Spiral\Router\Loader\Configurator\RoutingConfigurator;
21
use Spiral\Router\Loader\DelegatingLoader;
22
use Spiral\Router\Loader\LoaderInterface;
23
use Spiral\Router\Loader\LoaderRegistry;
24
use Spiral\Router\Loader\LoaderRegistryInterface;
25
use Spiral\Router\Loader\PhpFileLoader;
26
use Spiral\Router\RouteInterface;
27
use Spiral\Router\Router;
28
use Spiral\Router\RouterInterface;
29
use Spiral\Router\UriHandler;
30
use Spiral\Telemetry\Bootloader\TelemetryBootloader;
31
use Spiral\Telemetry\TracerInterface;
32
33
final class RouterBootloader extends Bootloader
34
{
35
    protected const DEPENDENCIES = [
36
        HttpBootloader::class,
37
        TelemetryBootloader::class,
38
    ];
39
40
    protected const SINGLETONS = [
41
        CoreInterface::class => Core::class,
42
        RouterInterface::class => [self::class, 'router'],
43
        RouteInterface::class => [self::class, 'route'],
44
        RequestHandlerInterface::class => RouterInterface::class,
45
        LoaderInterface::class => DelegatingLoader::class,
46
        LoaderRegistryInterface::class => [self::class, 'initRegistry'],
47
        GroupRegistry::class => GroupRegistry::class,
48
        RoutingConfigurator::class => RoutingConfigurator::class,
49
    ];
50
51 273
    public function __construct(
52
        private readonly ConfiguratorInterface $config
53
    ) {
54
    }
55
56 273
    public function boot(AbstractKernel $kernel): void
57
    {
58 273
        $configuratorCallback = static function (RouterInterface $router, RoutingConfigurator $routes): void {
59 273
            $router->import($routes);
60
        };
61 273
        $groupsCallback = static function (RouterInterface $router, GroupRegistry $groups): void {
62 273
            $groups->registerRoutes($router);
63
        };
64
65 273
        if ($kernel instanceof Kernel) {
66 273
            $kernel->appBooted($configuratorCallback);
67 273
            $kernel->appBooted($groupsCallback);
68
        } else {
69
            $kernel->booted($configuratorCallback);
70
            $kernel->booted($groupsCallback);
71
        }
72
    }
73
74
    /**
75
     * @noRector RemoveUnusedPrivateMethodRector
76
     */
77 273
    private function router(
78
        UriHandler $uriHandler,
79
        ContainerInterface $container,
80
        TracerInterface $tracer,
81
        ?EventDispatcherInterface $dispatcher = null
82
    ): RouterInterface {
83 273
        return new Router(
84 273
            $this->config->getConfig(HttpConfig::CONFIG)['basePath'],
85
            $uriHandler,
86
            $container,
87
            $dispatcher,
88
            $tracer,
89
        );
90
    }
91
92
    /**
93
     * @noRector RemoveUnusedPrivateMethodRector
94
     */
95 3
    private function route(ServerRequestInterface $request): RouteInterface
96
    {
97 3
        $route = $request->getAttribute(Router::ROUTE_ATTRIBUTE, null);
98 3
        if ($route === null) {
99 1
            throw new ScopeException('Unable to resolve Route, invalid request scope');
100
        }
101
102 2
        return $route;
103
    }
104
105
    /**
106
     * @noRector RemoveUnusedPrivateMethodRector
107
     */
108 273
    private function initRegistry(ContainerInterface $container): LoaderRegistryInterface
109
    {
110 273
        return new LoaderRegistry([
111 273
            $container->get(PhpFileLoader::class),
112
        ]);
113
    }
114
}
115