ModulesSorter::areAllAlreadyPresent()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 4
nop 1
crap 4
1
<?php
2
namespace Samurai\Module;
3
4
/**
5
 * Class ModulesSorter
6
 * @package Samurai\module
7
 * @author Raphaël Lefebvre <[email protected]>
8
 */
9
class ModulesSorter 
10
{
11
    /**
12
     * @var Module[]
13
     */
14
    private $initial;
15
16
    /**
17
     * @var Module[]
18
     */
19
    private $result;
20
21
    /**
22
     * @param Modules $modules
23
     * @return Modules
24
     */
25 8
    public function sort(Modules $modules)
26
    {
27 8
        $this->result = [];
28 8
        $this->initial = $modules->getArrayCopy();
29 8
        $this->run();
30 7
        return new Modules($this->result);
31
    }
32
33
    /**
34
     *
35
     */
36 8
    private function run()
37
    {
38 8
        while ($this->initial) {
39 6
            if (!$this->sortOnce()) {
40 1
                throw new \RuntimeException(
41 1
                    sprintf(
42 1
                        'Modules sort not possible. Maybe circular dependencies between these modules: %s.',
43 1
                        implode(', ', array_keys($this->initial))
44 1
                    )
45 1
                );
46
            }
47 8
        };
48 7
    }
49
50
    /**
51
     * @return bool
52
     */
53 6
    private function sortOnce()
54
    {
55 6
        $result = false;
56 6
        foreach ($this->initial as $name => $module) {
57 6
            if ($this->canBeAdded($module)) {
58 6
                $this->result[$name] = $module;
59 6
                unset($this->initial[$name]);
60 6
                $result = true;
61 6
            }
62 6
        }
63 6
        return $result;
64
    }
65
66
    /**
67
     * @param Module $module
68
     * @return bool
69
     */
70 6
    private function canBeAdded($module)
71
    {
72 6
        if ($module->getDependencies()->count()) {
73 2
            return $this->areAllAlreadyPresent($module->getDependencies());
74
        }
75 6
        return true;
76
    }
77
78
    /**
79
     * @param Modules $dependencies
80
     * @return bool
81
     */
82 2
    private function areAllAlreadyPresent(Modules $dependencies)
83
    {
84 2
        $count = 0;
85 2
        foreach($dependencies as $iDependency){
86 2
            foreach($this->result as $rDependency){
87 2
                if($iDependency->getPackage() === $rDependency->getPackage()){
88 1
                    $count++;
89 1
                    break;
90
                }
91 2
            }
92 2
        }
93 2
        return $count === count($dependencies);
94
    }
95
96
}
97