ModuleLoader   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 194
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 27
dl 0
loc 194
ccs 68
cts 68
cp 1
rs 10
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getModules() 0 3 1
A getCurrentModule() 0 3 1
A loadModuleDependencies() 0 5 2
A loadModules() 0 5 2
A getMenuItems() 0 6 2
A addModuleMenuItems() 0 11 4
A getCurrentModuleNameFromRoute() 0 8 3
A __construct() 0 5 1
A addModuleServiceProviders() 0 4 1
A getModuleFromConfigPair() 0 8 3
A loadModuleIgnoreDuplicates() 0 7 2
A getServiceProviders() 0 3 1
A loadModulesIgnoreDuplicates() 0 5 2
A loadModule() 0 9 2
1
<?php
2
3
namespace Modulatr\Loader;
4
5
use Modulatr\Loader\Exceptions\ModuleLoadedException;
6
use Modulatr\Loader\Exceptions\UnknownMenuTypeException;
7
8
/**
9
 * Class ModuleLoader
10
 *
11
 * @package Modulatr\Loader
12
 */
13
class ModuleLoader
14
{
15
    /**
16
     * @var ModuleContract[]
17
     */
18
    private $modules = [];
19
20
    /**
21
     * @var array
22
     */
23
    private $serviceProviders = [];
24
25
    /**
26
     * @var ModuleContract
27
     */
28
    private $currentModule;
29
30
    /**
31
     * @var array
32
     */
33
    private $prefixes;
34
35
    /**
36
     * @var array
37
     */
38
    private $menuTypes = [];
39
40
    /**
41
     * @var array
42
     */
43
    private $menuItems = [];
44
45
    /**
46
     * ModuleManager constructor.
47
     *
48
     * @param array $routeParts
49
     * @param array $config
50
     */
51 13
    public function __construct(array $routeParts, array $config)
52
    {
53 13
        $this->prefixes = $config['prefixes'] ?? [];
54 13
        $this->loadModules($config['modules'] ?? []);
55 12
        $this->currentModule = $this->getCurrentModuleNameFromRoute($routeParts);
56 12
    }
57
58
    /**
59
     * @param ModuleContract[] $modules
60
     */
61 13
    private function loadModules(array $modules): void
62
    {
63 13
        foreach ($modules as $key => $value) {
64 12
            $module = $this->getModuleFromConfigPair($value, $key);
65 12
            $this->loadModule($module);
66
        }
67 12
    }
68
69
    /**
70
     * @param $value
71
     * @param $key
72
     * @return ModuleContract
73
     */
74 12
    private function getModuleFromConfigPair($value, $key): ModuleContract
75
    {
76 12
        if (is_array($value) && is_string($key)) {
77 1
            $module = new $key($value);
78
        } else {
79 11
            $module = new $value();
80
        }
81 12
        return $module;
82
    }
83
84
    /**
85
     * @param ModuleContract $module
86
     */
87 12
    private function loadModule(ModuleContract $module): void
88
    {
89 12
        if (array_key_exists($module->getId(), $this->modules)) {
90 1
            throw new ModuleLoadedException();
91
        }
92 12
        $this->modules[$module->getId()] = $module;
93 12
        $this->loadModuleDependencies($module);
94 12
        $this->addModuleServiceProviders($module);
95 12
        $this->addModuleMenuItems($module);
96 12
    }
97
98
    /**
99
     * @param ModuleContract $module
100
     */
101 12
    private function loadModuleDependencies(ModuleContract $module)
102
    {
103 12
        $dependencies = $module->getDependencies();
104 12
        if (!empty($dependencies)) {
105 1
            $this->loadModulesIgnoreDuplicates($dependencies);
106
        }
107 12
    }
108
109
    /**
110
     * @param Module[] $modules
111
     */
112 1
    private function loadModulesIgnoreDuplicates(array $modules): void
113
    {
114 1
        foreach ($modules as $key => $value) {
115 1
            $module = $this->getModuleFromConfigPair($value, $key);
116 1
            $this->loadModuleIgnoreDuplicates($module);
117
        }
118 1
    }
119
120
    /**
121
     * @param ModuleContract $module
122
     */
123 1
    private function loadModuleIgnoreDuplicates(ModuleContract $module): void
124
    {
125 1
        if (!array_key_exists($module->getId(), $this->modules)) {
126 1
            $this->modules[$module->getId()] = $module;
127 1
            $this->loadModuleDependencies($module);
128 1
            $this->addModuleServiceProviders($module);
129 1
            $this->addModuleMenuItems($module);
130
        }
131 1
    }
132
133
    /**
134
     * @param ModuleContract $module
135
     */
136 12
    private function addModuleServiceProviders(ModuleContract $module): void
137
    {
138 12
        $providers = $this->serviceProviders + $module->getServiceProviders();
139 12
        $this->serviceProviders = array_unique($providers);
140 12
    }
141
142
    /**
143
     * @param ModuleContract $module
144
     */
145 12
    public function addModuleMenuItems(ModuleContract $module): void
146
    {
147 12
        foreach ($module->getMenuTypes() as $type) {
148 11
            if (!in_array($type, $this->menuTypes)) {
149 11
                $this->menuTypes[] = $type;
150
            }
151 11
            $menu = $module->getMenu($type);
152 11
            if (!isset($this->menuItems[$type])) {
153 11
                $this->menuItems[$type] = [];
154
            }
155 11
            $this->menuItems[$type][] = $menu;
156
        }
157 12
    }
158
159
    /**
160
     * @param array $parts
161
     * @return ModuleContract|null
162
     */
163 12
    private function getCurrentModuleNameFromRoute(array $parts): ?ModuleContract
164
    {
165 12
        foreach ($parts as $part) {
166 2
            if (in_array($part, array_keys($this->modules))) {
167 2
                return $this->modules[$part];
168
            }
169
        }
170 10
        return null;
171
    }
172
173
    /**
174
     * @return ModuleContract[]
175
     */
176 5
    public function getModules(): array
177
    {
178 5
        return $this->modules;
179
    }
180
181
    /**
182
     * @param string $type
183
     * @return array
184
     */
185 2
    public function getMenuItems(string $type): array
186
    {
187 2
        if (!in_array($type, $this->menuTypes)) {
188 1
            throw new UnknownMenuTypeException();
189
        }
190 1
        return $this->menuItems[$type] ?? [];
191
    }
192
193
    /**
194
     * @return array
195
     */
196 3
    public function getServiceProviders(): array
197
    {
198 3
        return $this->serviceProviders;
199
    }
200
201
    /**
202
     * @return ModuleContract|null
203
     */
204 2
    public function getCurrentModule(): ?ModuleContract
205
    {
206 2
        return $this->currentModule;
207
    }
208
}
209