Completed
Push — master ( f29cb1...1705d4 )
by Povilas
8s
created

ExtensionResolver::resolve()   A

Complexity

Conditions 4
Paths 6

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 19
rs 9.2
cc 4
eloc 11
nc 6
nop 1
1
<?php
2
3
namespace Povils\PHPMND;
4
5
use Povils\PHPMND\Extension\ArgumentExtension;
6
use Povils\PHPMND\Extension\ArrayExtension;
7
use Povils\PHPMND\Extension\AssignExtension;
8
use Povils\PHPMND\Extension\ConditionExtension;
9
use Povils\PHPMND\Extension\DefaultParameterExtension;
10
use Povils\PHPMND\Extension\Extension;
11
use Povils\PHPMND\Extension\OperationExtension;
12
use Povils\PHPMND\Extension\PropertyExtension;
13
use Povils\PHPMND\Extension\ReturnExtension;
14
use Povils\PHPMND\Extension\SwitchCaseExtension;
15
16
/**
17
 * Class ExtensionResolver
18
 *
19
 * @package Povils\PHPMND
20
 */
21
class ExtensionResolver
22
{
23
    const ALL_EXTENSIONS = 'all';
24
25
    /**
26
     * @var Extension[]
27
     */
28
    private $allExtensions;
29
30
    /**
31
     * @var Extension[]
32
     */
33
    private $defaultExtensions;
34
35
    /**
36
     * @var Extension[]
37
     */
38
    private $resolvedExtensions = [];
39
40
    public function resolve(array $extensionNames)
41
    {
42
        $this->resolvedExtensions = $this->defaults();
43
        if (($allKey = array_search(self::ALL_EXTENSIONS, $extensionNames)) !== false) {
44
            $this->resolvedExtensions = $this->all();
45
            unset($extensionNames[$allKey]);
46
        }
47
48
        foreach ($extensionNames as $extensionName) {
49
            if ($this->startsWithMinus($extensionName)) {
50
                $this->removeExtension($extensionName);
51
                continue;
52
            }
53
54
            $this->addExtension($extensionName);
55
        }
56
57
        return $this->resolvedExtensions;
58
    }
59
60
    /**
61
     * @return Extension[]
62
     */
63
    public function defaults()
64
    {
65
        if (null === $this->defaultExtensions) {
66
            $this->defaultExtensions = [
67
                new ConditionExtension,
68
                new ReturnExtension,
69
                new SwitchCaseExtension
70
            ];
71
        }
72
73
        return $this->defaultExtensions;
74
    }
75
76
    /**
77
     * @return Extension[]
78
     */
79
    public function all()
80
    {
81
        if (null === $this->allExtensions) {
82
            $this->allExtensions = array_merge(
83
                [
84
                    new ArgumentExtension,
85
                    new ArrayExtension,
86
                    new AssignExtension,
87
                    new DefaultParameterExtension,
88
                    new OperationExtension,
89
                    new PropertyExtension
90
                ],
91
                $this->defaults()
92
            );
93
        }
94
95
        return $this->allExtensions;
96
    }
97
98
    /**
99
     * @param string $extensionName
100
     */
101
    private function addExtension($extensionName)
102
    {
103
        if ($this->exists($extensionName)) {
104
            foreach ($this->all() as $extension) {
105
                if ($extension->getName() === $extensionName) {
106
                    $this->resolvedExtensions[] = $extension;
107
108
                    return;
109
                }
110
            };
111
        }
112
    }
113
114
    /**
115
     * @param string $extensionName
116
     *
117
     * @throws \Exception
118
     */
119
    private function removeExtension($extensionName)
120
    {
121
        $extensionNameWithoutMinus = substr($extensionName, 1);
122
        if ($this->exists($extensionNameWithoutMinus)) {
123
            foreach ($this->resolvedExtensions as $key => $resolvedExtension) {
124
                if ($extensionNameWithoutMinus === $resolvedExtension->getName()) {
125
                    unset($this->resolvedExtensions[$key]);
126
127
                    return;
128
                }
129
            }
130
        }
131
    }
132
133
    /**
134
     * @param string $extensionName
135
     * @return bool
136
     *
137
     * @throws \Exception
138
     */
139
    private function exists($extensionName)
140
    {
141
        foreach ($this->all() as $extension) {
142
            if ($extension->getName() === $extensionName) {
143
                return true;
144
            }
145
        }
146
147
        throw new \InvalidArgumentException(sprintf('Extension "%s" does not exist', $extensionName));
148
    }
149
150
    /**
151
     * @param string $extensionName
152
     *
153
     * @return bool
154
     */
155
    private function startsWithMinus($extensionName)
156
    {
157
        return 0 === strpos($extensionName, '-');
158
    }
159
}
160