Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.10% covered (warning)
87.10%
54 / 62
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApieRouteLoader
87.10% covered (warning)
87.10%
54 / 62
50.00% covered (danger)
50.00%
1 / 2
15.48
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 loadRoutes
86.89% covered (warning)
86.89%
53 / 61
0.00% covered (danger)
0.00%
0 / 1
14.44
1<?php
2namespace Apie\LaravelApie\Wrappers\Routing;
3
4use Apie\Common\Enums\UrlPrefix;
5use Apie\Common\Interfaces\GlobalRouteDefinitionProviderInterface;
6use Apie\Common\Interfaces\HasRouteDefinition;
7use Apie\Common\Interfaces\RouteDefinitionProviderInterface;
8use Apie\Common\RouteDefinitions\PossibleRoutePrefixProvider;
9use Apie\Core\BoundedContext\BoundedContextHashmap;
10use Apie\Core\Context\ApieContext;
11use Apie\Core\Enums\RequestMethod;
12use Apie\Core\ValueObjects\Utils;
13use Apie\LaravelApie\Wrappers\Security\VerifyApieUser;
14use Illuminate\Routing\RouteRegistrar;
15use Illuminate\Session\Middleware\StartSession;
16
17class ApieRouteLoader
18{
19    private bool $loaded = false;
20
21    public function __construct(
22        private readonly RouteDefinitionProviderInterface $routeProvider,
23        private readonly BoundedContextHashmap $boundedContextHashmap,
24        private readonly PossibleRoutePrefixProvider $routePrefixProvider
25    ) {
26    }
27
28    public function loadRoutes(RouteRegistrar $routeRegistrar): void
29    {
30        if ($this->loaded === true) {
31            throw new \RuntimeException('Do not load the "ApieRouteLoader" twice!');
32        }
33        $this->loaded = true;
34        $apieContext = new ApieContext([]);
35        $cmsMiddleware = Utils::toArray(config('apie.cms.laravel_middleware') ?? []);
36        $apiMiddleware = Utils::toArray(config('apie.rest_api.laravel_middleware') ?? []);
37        
38        if ($this->routeProvider instanceof GlobalRouteDefinitionProviderInterface) {
39            foreach ($this->routeProvider->getGlobalRoutes() as $routeDefinition) {
40                /** @var HasRouteDefinition $routeDefinition */
41                $url = $routeDefinition->getUrl();
42                $placeholders = $url->getPlaceholders();
43                $path = ltrim($url->toNative(), '/');
44                $method = $routeDefinition->getMethod();
45                $defaults = $routeDefinition->getRouteAttributes()
46                    + [
47                        '_is_apie' => true,
48                        'uses' => $routeDefinition->getController(),
49                    ];
50                /** @var \Illuminate\Routing\Route $route */
51                if ($method === RequestMethod::ANY) {
52                    $route = $routeRegistrar->match(
53                        array_map(fn ($s) => $s->value, RequestMethod::cases()),
54                        $path,
55                        $routeDefinition->getController()
56                    );
57                } else {
58                    // @phpstan-ignore-next-line method.notFound
59                    $route = $routeRegistrar->{strtolower($method->value)}($path, $routeDefinition->getController());
60                }
61                $route->defaults += $defaults;
62                $route->name('apie.global.' . $routeDefinition->getOperationId());
63                $route->middleware([StartSession::class, VerifyApieUser::class, ...$cmsMiddleware]);
64                if (in_array('properties', $placeholders)) {
65                    $route->where('properties', '[a-zA-Z0-9]+(/[a-zA-Z0-9]+)*');
66                }
67                if (in_array('path', $placeholders)) {
68                    $route->where('path', '.*');
69                }
70            }
71        }
72        
73        foreach ($this->boundedContextHashmap as $boundedContextId => $boundedContext) {
74            foreach ($this->routeProvider->getActionsForBoundedContext($boundedContext, $apieContext) as $routeDefinition) {
75                /** @var HasRouteDefinition $routeDefinition */
76                $prefix = $this->routePrefixProvider->getPossiblePrefixes($routeDefinition);
77                $url = $routeDefinition->getUrl();
78                $placeholders = $url->getPlaceholders();
79                $path = $prefix . $boundedContextId . '/' . ltrim($url->toNative(), '/');
80
81                $method = $routeDefinition->getMethod();
82                $defaults = $routeDefinition->getRouteAttributes()
83                    + [
84                        '_is_apie' => true,
85                        'uses' => $routeDefinition->getController(),
86                    ];
87                /** @var \Illuminate\Routing\Route $route */
88                if ($method === RequestMethod::ANY) {
89                    $route = $routeRegistrar->match(
90                        array_map(fn ($s) => $s->value, RequestMethod::cases()),
91                        $path,
92                        $routeDefinition->getController()
93                    );
94                } else {
95                    // @phpstan-ignore-next-line method.notFound
96                    $route = $routeRegistrar->{strtolower($method->value)}($path, $routeDefinition->getController());
97                }
98                $route->defaults += $defaults;
99                $route->name('apie.' . $boundedContextId . '.' . $routeDefinition->getOperationId());
100                foreach ($routeDefinition->getUrlPrefixes() as $urlPrefix) {
101                    if ($urlPrefix === UrlPrefix::CMS) {
102                        $route->middleware([StartSession::class, VerifyApieUser::class, ...$cmsMiddleware]);
103                    } else {
104                        $route->middleware([StartSession::class, VerifyApieUser::class, ...$apiMiddleware]);
105                    }
106                }
107                $route->wheres = $prefix->getRouteRequirements();
108                if (in_array('properties', $placeholders)) {
109                    $route->where('properties', '[a-zA-Z0-9]+(/[a-zA-Z0-9]+)*');
110                }
111                if (in_array('path', $placeholders)) {
112                    $route->where('path', '.*');
113                }
114            }
115        }
116    }
117}