ModuleProcedure   B
last analyzed

Complexity

Total Complexity 37

Size/Duplication

Total Lines 283
Duplicated Lines 11.31 %

Coupling/Cohesion

Components 1
Dependencies 7

Test Coverage

Coverage 95.33%

Importance

Changes 0
Metric Value
wmc 37
c 0
b 0
f 0
lcom 1
cbo 7
dl 32
loc 283
ccs 102
cts 107
cp 0.9533
rs 8.6

17 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A getOutput() 0 4 1
A setOutput() 0 4 1
A import() 16 16 3
A update() 16 16 3
B remove() 0 29 4
A rollbackImport() 0 6 1
A installModule() 0 15 3
A importDependencies() 0 11 4
A importModule() 0 7 2
A updateModule() 0 4 1
A removeModule() 0 4 1
A retrieveOriginalModuleData() 0 4 1
B completeModuleParams() 0 16 7
A buildConfigPath() 0 7 1
A sort() 0 5 1
A log() 0 6 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
namespace Samurai\Module;
3
4
use Balloon\Factory\BalloonFactory;
5
use Samurai\Project\Composer\Composer;
6
use Symfony\Component\Console\Output\OutputInterface;
7
8
/**
9
 * Class ModuleProcedure
10
 * @package Samurai\Module
11
 * @author Raphaël Lefebvre <[email protected]>
12
 */
13
class ModuleProcedure
14
{
15
    /**
16
     * @var ModuleManager
17
     */
18
    private $moduleManager;
19
20
    /**
21
     * @var Composer
22
     */
23
    private $composer;
24
25
    /**
26
     * @var BalloonFactory
27
     */
28
    private $balloonFactory;
29
30
    /**
31
     * @var ModulesSorter
32
     */
33
    private $modulesSorter;
34
35
    /**
36
     * @var OutputInterface
37
     */
38
    private $output;
39
40
    /**
41
     * @param ModuleManager $moduleManager
42
     * @param Composer $composer
43
     * @param BalloonFactory $balloonFactory
44
     * @param ModulesSorter $modulesSorter
45
     */
46 14
    public function __construct(
47
        ModuleManager $moduleManager,
48
        Composer $composer,
49
        BalloonFactory $balloonFactory,
50
        ModulesSorter $modulesSorter)
51
    {
52 14
        $this->moduleManager = $moduleManager;
53 14
        $this->composer = $composer;
54 14
        $this->balloonFactory = $balloonFactory;
55 14
        $this->modulesSorter = $modulesSorter;
56 14
    }
57
58
    /**
59
     * Getter of $output
60
     *
61
     * @return OutputInterface
62
     */
63 13
    public function getOutput()
64
    {
65 13
        return $this->output;
66
    }
67
68
    /**
69
     * Setter of $output
70
     *
71
     * @param OutputInterface $output
72
     */
73 13
    public function setOutput(OutputInterface $output)
74
    {
75 13
        $this->output = $output;
76 13
    }
77
78
    /**
79
     * @param Module $module
80
     * @param bool $mustSortModules
81
     * @return bool
82
     */
83 6 View Code Duplication
    public function import(Module $module, $mustSortModules = true)
84
    {
85 6
        $this->log(sprintf('<info>Starting installation of %s</info>', $module->getPackage()));
86
87 6
        if (!$this->importModule($module)) {
88 2
            $this->log(sprintf('<error>An error occurred during the installation of %s</error>', $module->getPackage()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 121 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
89 2
            return false;
90
        }
91
92 5
        if(!$this->installModule($module, $mustSortModules)){
93 1
            $this->rollbackImport($module);
94 1
            return false;
95
        }
96
97 4
        return true;
98
    }
99
100
    /**
101
     * @param Module $module
102
     * @param bool $mustSortModules
103
     * @return bool
104
     */
105 3 View Code Duplication
    public function update(Module $module, $mustSortModules = true)
106
    {
107 3
        $this->log(sprintf('<info>Updating %s</info>', $module->getPackage()));
108
109 3
        if (!$this->updateModule($module)) {
110 1
            $this->log(sprintf('<error>An error occurred during the update of %s</error>', $module->getPackage()));
111 1
            return false;
112
        }
113
114 2
        if(!$this->installModule($module, $mustSortModules)){ //todo if dependencies are removed, we need to clean them.
115
            $this->log(sprintf('<error>An error occurred. You need to clean your modules. Try to remove "%s" and re-install it.</error>', $module->getPackage()));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 162 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
116
            return false;
117
        }
118
119 2
        return true;
120
    }
121
122
    /**
123
     * @param Module $module
124
     * @param bool $mustSortModules
125
     * @return bool
126
     */
127 4
    public function remove(Module $module, $mustSortModules = true)
128
    {
129 4
        $this->log(sprintf('<info>Removing %s</info>', $module->getPackage()));
130
131 4
        $dependents = $module->retrieveDependents($this->moduleManager->getAll());
132 4
        if($dependents->count()){
133 1
            $this->log(sprintf(
134 1
                '<info>The module "%s" cant not be removed because is a dependency of "%s". First remove "%s".</info>',
135 1
                $module->getName(),
136 1
                implode(', ', array_keys($dependents->getArrayCopy())),
137 1
                implode(', ', array_keys($dependents->getArrayCopy()))
138
139 1
            ));
140 1
            return false;
141
        }
142
143 3
        if (!$this->removeModule($module)) {
144 1
            $this->log(sprintf('<error>An error occurred during the remove of %s</error>', $module->getPackage()));
145 1
            return false;
146
        }
147
148 2
        $this->moduleManager->remove($module->getName());
149
150 2
        if($mustSortModules){
151 2
            $this->sort();
152 2
        }
153
154 2
        return true;
155
    }
156
157
    /**
158
     * @param Module $module
159
     */
160 1
    private function rollbackImport(Module $module)
161
    {
162 1
        $this->log(sprintf('<info>Roll-backing installation of %s</info>', $module->getPackage()));
163 1
        $this->removeModule($module);
164 1
        $this->moduleManager->clear();
165 1
    }
166
167
    /**
168
     * @param Module $module
169
     * @param bool $mustSortModules
170
     * @return bool
171
     */
172 7
    private function installModule(Module $module, $mustSortModules)
173
    {
174 7
        $module = $this->completeModuleParams($module, $this->retrieveOriginalModuleData($module));
175 7
        $this->moduleManager->add($module);
176
177 7
        if (!$this->importDependencies($module->getDependencies())) {
178 1
            return false;
179
        }
180
181 6
        if($mustSortModules){
182 6
            $this->sort();
183 6
        }
184
185 6
        return true;
186
    }
187
188
    /**
189
     * @param Modules $dependencies
190
     * @return bool
191
     */
192 7
    private function importDependencies(Modules $dependencies)
193
    {
194 7
        foreach ($dependencies as $dependency) {
195 2
            if (!count($this->moduleManager->getByPackage($dependency->getPackage()))) {
196 2
                if (!$this->import($dependency, false)) {
197 1
                    return false;
198
                }
199 1
            }
200 6
        }
201 6
        return true;
202
    }
203
204
    /**
205
     * @param Module $module
206
     * @return bool
207
     */
208 6
    private function importModule(Module $module)
209
    {
210 6
        if($module->getSource()){
211
            throw new \RuntimeException('Sorry, for now Samurai does not manage a custom module source...');
212
        }
213 6
        return $this->composer->requirePackage($module->getPackage(), $module->getVersion(), true) === 0;
214
    }
215
216
    /**
217
     * @param Module $module
218
     * @return bool
219
     */
220 3
    private function updateModule(Module $module)
221
    {
222 3
        return $this->composer->updatePackage($module->getPackage(), true) === 0;
223
    }
224
225
    /**
226
     * @param Module $module
227
     * @return bool
228
     */
229 4
    private function removeModule(Module $module)
230
    {
231 4
        return $this->composer->removePackage($module->getPackage(), true) === 0;
232
    }
233
234
    /**
235
     * @param Module $module
236
     * @return array
237
     */
238 7
    private function retrieveOriginalModuleData(Module $module)
239
    {
240 7
        return $this->balloonFactory->create($this->buildConfigPath($module))->getAll();
241
    }
242
243
    /**
244
     * @param Module $module
245
     * @param array $moduleData
246
     * @return Module
247
     */
248 7
    private function completeModuleParams(Module $module, array $moduleData)
249
    {
250 7
        if (!$module->getDescription() && !empty($moduleData['description'])) {
251 3
            $module->setDescription($moduleData['description']);
252 3
        }
253 7
        if (!$module->getSource() && !empty($moduleData['source'])) {
254
            $module->setDescription($moduleData['source']);
255
        }
256 7
        if (!empty($moduleData['dependencies'])) {
257 2
            $module->setDependencies($moduleData['dependencies']);
258 2
        }
259 7
        if (!empty($moduleData['tasks'])) {
260 3
            $module->setTasks((array)$moduleData['tasks']);
261 3
        }
262 7
        return $module;
263
    }
264
265
    /**
266
     * @param Module $module
267
     * @return string
268
     */
269 7
    private function buildConfigPath(Module $module)
270
    {
271 7
        return $this->composer->getHomePath()
272
            . '/vendor/'
273 7
            . $module->getPackage()
274 7
            . '/.samurai.json';
275
    }
276
277
    /**
278
     *
279
     */
280 8
    private function sort()
281
    {
282 8
        $this->log('<info>Sorting modules</info>');
283 8
        $this->moduleManager->set($this->modulesSorter->sort($this->moduleManager->getAll()));
284 8
    }
285
286
    /**
287
     * @param string $message
288
     */
289 13
    private function log($message)
290
    {
291 13
        if($this->getOutput()){
292 13
            $this->getOutput()->writeln($message);
293 13
        }
294 13
    }
295
}
296