Completed
Push — 0.x ( fce172...24652b )
by Andrew
01:16
created

ModuleLoader::resolveDependencies()   C

Complexity

Conditions 10
Paths 15

Size

Total Lines 57
Code Lines 32

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 32
CRAP Score 10

Importance

Changes 0
Metric Value
dl 0
loc 57
ccs 32
cts 32
cp 1
rs 6.7123
c 0
b 0
f 0
cc 10
eloc 32
nc 15
nop 0
crap 10

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Cadre\Module;
3
4
use Aura\Di\Container;
5
use Aura\Di\ContainerConfigInterface;
6
7
class ModuleLoader implements ModuleLoaderInterface
8
{
9
    protected $modules = [];
10
    protected $environment;
11
    protected $context;
12
    protected $isResolved = false;
13
    protected $containerConfigs = [];
14
    protected $conflictsWith = [];
15
    protected $replacedWith = [];
16
    protected $touchedModules = [];
17
18 18
    public function __construct(array $modules, $environment = '', $context = '')
19
    {
20 18
        $this->modules = $modules;
21 18
        $this->environment = $environment;
22 18
        $this->context = $context;
23 18
    }
24
25 16
    public function define(Container $di)
26
    {
27 16
        $this->resolveDependencies();
28 10
        foreach ($this->containerConfigs as $containerConfig) {
29 10
            if ($containerConfig instanceof ContainerConfigInterface) {
0 ignored issues
show
Bug introduced by
The class Aura\Di\ContainerConfigInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
30 10
                $containerConfig->define($di);
31
            }
32
        }
33 10
    }
34
35 10
    public function modify(Container $di)
36
    {
37 10
        $this->resolveDependencies();
38 10
        foreach ($this->containerConfigs as $containerConfig) {
39 10
            if ($containerConfig instanceof ContainerConfigInterface) {
0 ignored issues
show
Bug introduced by
The class Aura\Di\ContainerConfigInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
40 10
                $containerConfig->modify($di);
41
            }
42
        }
43 10
    }
44
45 2
    public function loaded($name)
46
    {
47 2
        $this->resolveDependencies();
48 2
        return isset($this->containerConfigs[$name]);
49
    }
50
51 1
    public function isEnv($environment)
52
    {
53 1
        return 0 === strcmp($environment, $this->environment);
54
    }
55
56 1
    public function isContext($context)
57
    {
58 1
        return 0 === strcmp($context, $this->context);
59
    }
60
61 16
    protected function resolveDependencies()
62
    {
63 16
        if ($this->isResolved) {
64 10
            return;
65
        }
66
67 16
        $idx = 0;
68
69 16
        while ($idx < count($this->modules)) {
70 16
            $module = $this->getModule($this->modules[$idx]);
71 15
            $name = get_class($module);
72
73 15
            if (isset($this->containerConfigs[$name])) {
74 1
                $idx++;
75 1
                continue;
76
            }
77
78 15
            if (isset($this->replacedWith[$name])) {
79 1
                $idx++;
80 1
                continue;
81
            }
82
83 15
            if (isset($this->conflictsWith[$name])) {
84 1
                throw new ConflictingModuleException($name, $this->conflictsWith[$name]);
85
            }
86
87 15
            if (empty($this->touchedModules[$name])) {
88 15
                $this->touchedModules[$name] = 0;
89
            }
90
91 15
            if (1 < $this->touchedModules[$name]) {
92 1
                throw new CircularReferenceException($name, $this->touchedModules[$name]);
93
            }
94
95 15
            $this->touchedModules[$name]++;
96
97 15
            if ($module instanceof ModuleInterface) {
98 14
                $this->resolveRequire($idx, $module);
99 14
                $this->resolveRequireEnv($idx, $module);
100 14
                $this->resolveConflict($module, $name);
101 14
                $this->resolveReplace($module, $name);
102
            }
103
104 15
            $module = $this->getModule($this->modules[$idx]);
105 15
            if (0 === strcmp($name, get_class($module))) {
106
                // No new modules were inserted
107 14
                $this->containerConfigs[$name] = $module;
108
            } else {
109
                // Do not increment $idx, reprocess this $idx
110 7
                continue;
111
            }
112
113 14
            $idx++;
114
        }
115
116 10
        $this->isResolved = true;
117 10
    }
118
119 14
    protected function injectRequiredModule($idx, $requiredModules)
120
    {
121 14
        foreach ($requiredModules as $requiredModule) {
122 7
            $foundIdx = array_search($requiredModule, $this->modules);
123 7
            if (false === $foundIdx) {
124
                // New module, not found yet
125 5
                array_splice($this->modules, $idx, 0, $requiredModule);
126 7
            } elseif ($idx < $foundIdx) {
127
                // Found module after us in list. Move up
128 2
                array_splice($this->modules, $foundIdx, 1);
129 7
                array_splice($this->modules, $idx, 0, $requiredModule);
130
            }
131
        }
132 14
    }
133
134 14
    protected function resolveRequire($idx, ModuleInterface $module)
135
    {
136 14
        $requiredModules = $module->require();
137 14
        $this->injectRequiredModule($idx, $requiredModules);
138 14
    }
139
140 14
    protected function resolveRequireEnv($idx, ModuleInterface $module)
141
    {
142 14
        $envMethod = 'require' . str_replace(' ', '', ucwords(
143 14
            strtolower(str_replace('_', ' ', trim($this->environment)))
144
        ));
145 14
        if ('require' !== $envMethod && method_exists($module, $envMethod)) {
146 2
            $requiredModules = $module->$envMethod();
147 2
            $this->injectRequiredModule($idx, $requiredModules);
148
        }
149 14
    }
150
151 14
    protected function resolveConflict(ModuleInterface $module, $name)
152
    {
153 14
        $conflictingModules = $module->conflict();
154 14
        foreach ($conflictingModules as $conflictingModule) {
155 3
            $this->conflictsWith[$conflictingModule] = $name;
156 3
            if (isset($this->containerConfigs[$conflictingModule])) {
157 3
                throw new ConflictingModuleException($conflictingModule, $name);
158
            }
159
        }
160 14
    }
161
162 14
    protected function resolveReplace(ModuleInterface $module, $name)
163
    {
164 14
        $replacesModules = $module->replace();
165 14
        foreach ($replacesModules as $replacesModule) {
166 3
            if (isset($this->replacedWith[$replacesModule])) {
167 1
                throw new AlreadyReplacedException(
168 1
                    $name,
169 1
                    $replacesModule,
170 1
                    $this->replacedWith[$replacesModule]
171
                );
172
            }
173 3
            if (isset($this->containerConfigs[$replacesModule])) {
174 1
                throw new AlreadyLoadedException(
175 1
                    $name,
176 1
                    'replace',
177 1
                    $replacesModule
178
                );
179
            }
180 2
            $this->replacedWith[$replacesModule] = $name;
181
        }
182 14
    }
183
184 16
    protected function getModule($module)
185
    {
186 16
        if (is_string($module)) {
187 16
            $module = new $module($this);
188
        }
189
190 16
        if (! $module instanceof ContainerConfigInterface) {
0 ignored issues
show
Bug introduced by
The class Aura\Di\ContainerConfigInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
191 1
            throw new \InvalidArgumentException(
192 1
                'Modules must implement ModuleInterface or ContainerConfigInterface'
193
            );
194
        }
195
196 15
        return $module;
197
    }
198
}
199