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                    $route = $routeRegistrar->{strtolower($method->value)}($path, $routeDefinition->getController());
59                }
60                $route->defaults += $defaults;
61                $route->name('apie.global.' . $routeDefinition->getOperationId());
62                $route->middleware([StartSession::class, VerifyApieUser::class, ...$cmsMiddleware]);
63                if (in_array('properties', $placeholders)) {
64                    $route->where('properties', '[a-zA-Z0-9]+(/[a-zA-Z0-9]+)*');
65                }
66                if (in_array('path', $placeholders)) {
67                    $route->where('path', '.*');
68                }
69            }
70        }
71        
72        foreach ($this->boundedContextHashmap as $boundedContextId => $boundedContext) {
73            foreach ($this->routeProvider->getActionsForBoundedContext($boundedContext, $apieContext) as $routeDefinition) {
74                /** @var HasRouteDefinition $routeDefinition */
75                $prefix = $this->routePrefixProvider->getPossiblePrefixes($routeDefinition);
76                $url = $routeDefinition->getUrl();
77                $placeholders = $url->getPlaceholders();
78                $path = $prefix . $boundedContextId . '/' . ltrim($url->toNative(), '/');
79
80                $method = $routeDefinition->getMethod();
81                $defaults = $routeDefinition->getRouteAttributes()
82                    + [
83                        '_is_apie' => true,
84                        'uses' => $routeDefinition->getController(),
85                    ];
86                /** @var \Illuminate\Routing\Route $route */
87                if ($method === RequestMethod::ANY) {
88                    $route = $routeRegistrar->match(
89                        array_map(fn ($s) => $s->value, RequestMethod::cases()),
90                        $path,
91                        $routeDefinition->getController()
92                    );
93                } else {
94                    $route = $routeRegistrar->{strtolower($method->value)}($path, $routeDefinition->getController());
95                }
96                $route->defaults += $defaults;
97                $route->name('apie.' . $boundedContextId . '.' . $routeDefinition->getOperationId());
98                foreach ($routeDefinition->getUrlPrefixes() as $urlPrefix) {
99                    if ($urlPrefix === UrlPrefix::CMS) {
100                        $route->middleware([StartSession::class, VerifyApieUser::class, ...$cmsMiddleware]);
101                    } else {
102                        $route->middleware([StartSession::class, VerifyApieUser::class, ...$apiMiddleware]);
103                    }
104                }
105                $route->wheres = $prefix->getRouteRequirements();
106                if (in_array('properties', $placeholders)) {
107                    $route->where('properties', '[a-zA-Z0-9]+(/[a-zA-Z0-9]+)*');
108                }
109                if (in_array('path', $placeholders)) {
110                    $route->where('path', '.*');
111                }
112            }
113        }
114    }
115}