Completed
Push — 0.x ( 477f4a...8f7b39 )
by Andrew
06:34
created

ModuleLoader::resolveRequireEnv()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 12
ccs 8
cts 8
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 3
nop 2
crap 4
1
<?php
2
namespace Cadre\Module;
3
4
use ArrayIterator;
5
use Aura\Di\Container;
6
use Aura\Di\ContainerConfigInterface;
7
8
class ModuleLoader implements ModuleLoaderInterface
9
{
10
    protected $modules = [];
11
    protected $environment;
12
    protected $isResolved = false;
13
    protected $containerConfigs = [];
14
    protected $conflictsWith = [];
15
    protected $replacedWith = [];
16
17 13
    public function __construct(array $modules, $environment = '')
18
    {
19 13
        $this->modules = $modules;
20 13
        $this->environment = $environment;
21 13
    }
22
23 13
    public function define(Container $di)
24
    {
25 13
        $this->resolveDependencies();
26 8
        foreach ($this->containerConfigs as $containerConfig) {
27 8
            if ($containerConfig instanceof ContainerConfigInterface) {
28 8
                $containerConfig->define($di);
29
            }
30
        }
31 8
    }
32
33 8
    public function modify(Container $di)
34
    {
35 8
        $this->resolveDependencies();
36 8
        foreach ($this->containerConfigs as $containerConfig) {
37 8
            if ($containerConfig instanceof ContainerConfigInterface) {
38 8
                $containerConfig->modify($di);
39
            }
40
        }
41 8
    }
42
43 2
    public function loaded($name)
44
    {
45 2
        $this->resolveDependencies();
46 2
        return isset($this->containerConfigs[$name]);
47
    }
48
49 13
    protected function resolveDependencies()
50
    {
51 13
        if ($this->isResolved) {
52 8
            return;
53
        }
54
55 13
        $modules = new ArrayIterator($this->modules);
56
57 13
        foreach ($modules as $module) {
58 13
            $module = $this->getModule($module);
59 12
            $name = get_class($module);
60
61 12
            if (isset($this->containerConfigs[$name])) {
62 1
                continue;
63
            }
64
65 12
            if (isset($this->replacedWith[$name])) {
66 1
                continue;
67
            }
68
69 12
            if (isset($this->conflictsWith[$name])) {
70 1
                throw new ConflictingModuleException($name, $this->conflictsWith[$name]);
71
            }
72
73 12
            $this->containerConfigs[$name] = $module;
74
75 12
            $this->resolveRequire($modules, $module);
76 12
            $this->resolveRequireEnv($modules, $module);
77 12
            $this->resolveConflict($module, $name);
78 12
            $this->resolveReplace($module, $name);
79
        }
80
81 8
        $this->isResolved = true;
82 8
    }
83
84 12
    protected function resolveRequire($modules, $module)
85
    {
86 12
        $requiredModules = $module->require();
87 12
        foreach ($requiredModules as $requiredModule) {
88 3
            $modules->append($requiredModule);
89
        }
90 12
    }
91
92 12
    protected function resolveRequireEnv($modules, $module)
93
    {
94 12
        $envMethod = 'require' . str_replace(' ', '', ucwords(
95 12
            strtolower(str_replace('_', ' ', trim($this->environment)))
96
        ));
97 12
        if ('require' !== $envMethod && method_exists($module, $envMethod)) {
98 2
            $requiredModules = $module->$envMethod();
99 2
            foreach ($requiredModules as $requiredModule) {
100 2
                $modules->append($requiredModule);
101
            }
102
        }
103 12
    }
104
105 12
    protected function resolveConflict($module, $name)
106
    {
107 12
        $conflictingModules = $module->conflict();
108 12
        foreach ($conflictingModules as $conflictingModule) {
109 3
            $this->conflictsWith[$conflictingModule] = $name;
110 3
            if (isset($this->containerConfigs[$conflictingModule])) {
111 3
                throw new ConflictingModuleException($conflictingModule, $name);
112
            }
113
        }
114 12
    }
115
116 12
    protected function resolveReplace($module, $name)
117
    {
118 12
        $replacesModules = $module->replace();
119 12
        foreach ($replacesModules as $replacesModule) {
120 3
            if (isset($this->replacedWith[$replacesModule])) {
121 1
                throw new AlreadyReplacedException(
122
                    $name,
123
                    $replacesModule,
124 1
                    $this->replacedWith[$replacesModule]
125
                );
126
            }
127 3
            if (isset($this->containerConfigs[$replacesModule])) {
128 1
                throw new AlreadyLoadedException(
129
                    $name,
130 1
                    'replace',
131
                    $replacesModule
132
                );
133
            }
134 2
            $this->replacedWith[$replacesModule] = $name;
135
        }
136 12
    }
137
138 13
    protected function getModule($module)
139
    {
140 13
        if (is_string($module)) {
141 13
            $module = new $module($this);
142
        }
143
144 13
        if (! $module instanceof ModuleInterface) {
145 1
            throw new \InvalidArgumentException(
146 1
                'Modules must implement ModuleInterface'
147
            );
148
        }
149
150 12
        return $module;
151
    }
152
}
153