Passed
Branch v0.2 (3b8de8)
by Freddie
05:06
created

ModuleDefinitionLoader   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 83
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 83
rs 10
c 0
b 0
f 0
wmc 14

6 Methods

Rating   Name   Duplication   Size   Complexity  
A addModuleToContainer() 0 6 1
A loadModuleDefinitions() 0 17 3
A getModuleDefinitionsDirectory() 0 11 3
A __construct() 0 3 1
A getModules() 0 17 4
A load() 0 7 2
1
<?php declare(strict_types=1);
2
3
namespace Simplex\DefinitionLoader;
4
5
use DI\ContainerBuilder;
6
use Simplex\ContainerKeys;
7
use Simplex\Module;
8
use Symfony\Component\Finder\Finder;
9
10
class ModuleDefinitionLoader implements DefinitionLoader
11
{
12
    const MODULES_FILENAME = 'modules.php';
13
14
    /** @var \SplFileInfo */
15
    private $configDirectory;
16
17
    public function __construct(\SplFileInfo $configDirectory)
18
    {
19
        $this->configDirectory = $configDirectory;
20
    }
21
22
    public function load(ContainerBuilder $containerBuilder): void
23
    {
24
        $modules = $this->getModules();
25
26
        foreach ($modules as $module) {
27
            $this->addModuleToContainer($module, $containerBuilder);
28
            $this->loadModuleDefinitions($module, $containerBuilder);
29
        }
30
    }
31
32
    /** @return Module[] */
33
    private function getModules(): array
34
    {
35
        $modulesFile = new \SplFileInfo(
36
            $this->configDirectory->getPathname() . DIRECTORY_SEPARATOR . self::MODULES_FILENAME
37
        );
38
39
        if (!$modulesFile->isFile() || !$modulesFile->isReadable()) {
40
            throw new \RuntimeException('Could not read modules file ' . $modulesFile->getRealPath());
41
        }
42
43
        $modules = include $modulesFile;
44
45
        if (!is_array($modules)) {
46
            throw new \LogicException('Expected ' . $modulesFile->getPathname() . ' to return an array');
47
        }
48
49
        return $modules;
50
    }
51
52
    private function addModuleToContainer(Module $module, ContainerBuilder $containerBuilder): void
53
    {
54
        $containerBuilder->addDefinitions([
55
            get_class($module) => \DI\create(get_class($module)),
56
            ContainerKeys::MODULES => \DI\add([
57
                \DI\get(get_class($module)),
58
            ]),
59
        ]);
60
    }
61
62
    private function loadModuleDefinitions(Module $module, ContainerBuilder $containerBuilder): void
63
    {
64
        $definitionsDirectoryPath = $module->getServiceDefinitionsDirectory();
65
66
        if (null === $definitionsDirectoryPath) {
67
            return;
68
        }
69
70
        $definitionsDirectory = $this->getModuleDefinitionsDirectory(
71
            rtrim($definitionsDirectoryPath, DIRECTORY_SEPARATOR)
72
        );
73
74
        $finder = new Finder();
75
        $finder->files()->depth(0)->in($definitionsDirectory->getPathname());
76
77
        foreach ($finder as $file) {
78
            $containerBuilder->addDefinitions($file->getPathname());
79
        }
80
    }
81
82
    private function getModuleDefinitionsDirectory(string $definitionsDirectoryPath): \SplFileInfo
83
    {
84
        $definitionsDirectory = new \SplFileInfo(rtrim($definitionsDirectoryPath, DIRECTORY_SEPARATOR));
85
86
        if (!$definitionsDirectory->isDir() || !$definitionsDirectory->isReadable()) {
87
            throw new \RuntimeException(
88
                'Invalid module definitions directory path ' . $definitionsDirectory->getRealPath()
89
            );
90
        }
91
92
        return $definitionsDirectory;
93
    }
94
}
95