Passed
Pull Request — master (#2)
by ANTHONIUS
06:08 queued 02:34
created

ModuleLoader   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 66
Duplicated Lines 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
eloc 26
dl 0
loc 66
rs 10
c 1
b 1
f 0
wmc 7

4 Methods

Rating   Name   Duplication   Size   Complexity  
A load() 0 20 3
A __construct() 0 11 1
A supports() 0 3 1
A loadRoute() 0 6 2
1
<?php
2
3
/*
4
 * This file is part of the ModularBundle project.
5
 *
6
 * (c) Anthonius Munthi <https://itstoni.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Doyo\Bundle\Modular\Routing;
15
16
use Doyo\Bundle\Modular\Application\ModuleInterface;
17
use Symfony\Component\Config\Loader\Loader;
18
use Symfony\Component\HttpKernel\KernelInterface;
19
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
20
use Symfony\Component\Routing\Loader\ContainerLoader;
21
use Symfony\Component\Routing\Loader\PhpFileLoader as RoutingPhpFileLoader;
22
use Symfony\Component\Routing\RouteCollection;
23
24
class ModuleLoader extends Loader
25
{
26
    private bool $loaded = false;
27
    private KernelInterface $kernel;
28
29
    /**
30
     * @var iterable<array-key,ModuleInterface>|ModuleInterface[]
31
     */
32
    private iterable $modules;
33
    private ContainerLoader $loader;
34
35
    /**
36
     * @param iterable<array-key,ModuleInterface> $modules
37
     */
38
    public function __construct(
39
        string $env,
40
        KernelInterface $kernel,
41
        ContainerLoader $loader,
42
        iterable $modules
43
    ) {
44
        parent::__construct($env);
45
46
        $this->kernel  = $kernel;
47
        $this->loader  = $loader;
48
        $this->modules = $modules;
49
    }
50
51
    /**
52
     * @psalm-suppress PossiblyFalseArgument
53
     * @psalm-suppress ArgumentTypeCoercion
54
     * @psalm-suppress UndefinedInterfaceMethod
55
     * @psalm-suppress PossiblyFalseReference
56
     */
57
    public function load($resource, string $type = null): RouteCollection
58
    {
59
        if (true === $this->loaded) {
60
            throw new \RuntimeException('Do not add the "extra" loader twice');
61
        }
62
63
        $loader = $this->loader;
64
        $file   = (new \ReflectionObject($this->kernel))->getFileName();
65
        /** @psalm-var RoutingPhpFileLoader $kernelLoader */
66
        $kernelLoader = $loader->getResolver()->resolve($file, 'php');
67
        \assert($kernelLoader instanceof RoutingPhpFileLoader);
68
        $kernelLoader->setCurrentDir(\dirname($file));
69
        $collection   = new RouteCollection();
70
        $configurator = new RoutingConfigurator($collection, $kernelLoader, $file, $file, $this->env);
71
72
        foreach ($this->modules as $module) {
73
            $this->loadRoute($configurator, $module);
74
        }
75
76
        return $collection;
77
    }
78
79
    public function supports($resource, string $type = null): bool
80
    {
81
        return 'modular' === $type;
82
    }
83
84
    private function loadRoute(RoutingConfigurator $configurator, ModuleInterface $module): void
85
    {
86
        $routePath = $module->getBasePath().'/Resources/routes';
87
        if (is_dir($routePath)) {
88
            $configurator->import($routePath.'/*.yaml');
89
            $configurator->import($routePath.'/*.xml');
90
        }
91
    }
92
}
93