StrategyCollection::getStatus()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Humweb\Features;
4
5
use Humweb\Features\Resolvers\StrategyResolver;
6
use Humweb\Features\Strategy\StrategyInterface;
7
8
/**
9
 * StrategyCollection.
10
 */
11
class StrategyCollection implements \ArrayAccess
12
{
13
    const STATUS_DISABLED = 0;
14
    const STATUS_ENABLED  = 1;
15
16
    /**
17
     * @var array
18
     */
19
    public $strategies;
20
21
    protected $resolver;
22
23
    protected $status = 1;
24
25
    protected $threshold = 1;
26
27
28
    /**
29
     * @param array $strategies
30
     */
31
    public function __construct($strategies = array())
32
    {
33
        $this->resolver   = new StrategyResolver();
34
        $this->strategies = $strategies;
35
    }
36
37
38
    /**
39
     * Adds strategies to feature object.
40
     *
41
     * @param string|array                    $name
42
     * @param callable|StrategyInterface|null $strategy
43
     *
44
     * @return $this
45
     */
46
    public function add($name, $strategy = null, $args = [])
47
    {
48
        if (is_array($name)) {
49
            $strategy = $name;
50
            foreach ($strategy as $name => $class) {
51
                $args = isset($class[1]) ? $class[1] : [];
52
                $this->addStrategy($name, $class[0], $args);
53
            }
54
        } else {
55
            $this->addStrategy($name, $strategy, $args);
56
        }
57
58
        return $this;
59
    }
60
61
62
    /**
63
     * Adds strategy to feature object.
64
     *
65
     * @param string                          $name
66
     * @param callable|StrategyInterface|null $class Strategy class name.
67
     * @param array                           $args
68
     *
69
     * @return $this
70
     * @throws InvalidArgumentException
71
     */
72
    public function addStrategy($name, $class = null, $args = [])
73
    {
74
        if (is_callable($class)) {
75
            $this->strategies[$name] = [
76
                'class' => $class,
77
                'args'  => $args,
78
                'type'  => 'function'
79
            ];
80
        } elseif ($class instanceof StrategyInterface) {
81
            $this->strategies[$name] = [
82
                'class' => $class,
83
                'args'  => $args,
84
                'type'  => 'class_instance'
85
            ];
86
        } else {
87
88
            // Strategy must be a string
89
            if ( ! is_string($class)) {
90
                throw new \InvalidArgumentException(sprintf('Expected a string. Actual: %s', gettype($class)));
91
            }
92
93
            $class = $this->resolver->resolve($class);
94
95
            $this->strategies[$name] = [
96
                'class' => $class,
97
                'args'  => $args,
98
                'type'  => 'class'
99
            ];
100
        }
101
102
        return $this;
103
    }
104
105
106
    public function count()
107
    {
108
        return count($this->strategies);
109
    }
110
111
112
    public function flush()
113
    {
114
        return $this->strategies = [];
115
    }
116
117
118
    /**
119
     * @param array $args
120
     *
121
     * @return bool
122
     */
123
    public function check($args = [])
124
    {
125
        if ($this->status === self::STATUS_DISABLED) {
126
            return false;
127
        }
128
129
        $isEnabled = 0;
130
        foreach ($this->strategies as $name => $strategy) {
131
            if ($this->isAnonymousFunctionStrategy($strategy)) {
132
                if ($strategy['class']($strategy['args'])) {
133
                    $isEnabled++;
134
                }
135
            } elseif ($this->callStrategyInstance($strategy, $args)) {
136
                $isEnabled++;
137
            }
138
        }
139
140
        return $isEnabled >= $this->threshold;
141
    }
142
143
144
    protected function callStrategyInstance($strategy, $args = [])
145
    {
146
        if ($strategy['type'] == 'class_instance') {
147
            $instance = $strategy['class'];
148
        } else {
149
            $instance = new $strategy['class']($args);
150
        }
151
        return $instance->handle($strategy['args']);
152
    }
153
154
155
    /**
156
     * (PHP 5 &gt;= 5.0.0)<br/>
157
     * Whether a offset exists.
158
     *
159
     * @link http://php.net/manual/en/arrayaccess.offsetexists.php
160
     *
161
     * @param mixed $offset <p>
162
     *                      An offset to check for.
163
     *                      </p>
164
     *
165
     * @return bool true on success or false on failure.
166
     *              </p>
167
     *              <p>
168
     *              The return value will be casted to boolean if non-boolean was returned.
169
     */
170
    public function offsetExists($offset)
171
    {
172
        return isset($this->strategies[$offset]) || isset($this->strategies['__'.$offset]);
173
    }
174
175
176
    /**
177
     * (PHP 5 &gt;= 5.0.0)<br/>
178
     * Offset to retrieve.
179
     *
180
     * @link http://php.net/manual/en/arrayaccess.offsetget.php
181
     *
182
     * @param mixed $offset <p>
183
     *                      The offset to retrieve.
184
     *                      </p>
185
     *
186
     * @return mixed Can return all value types.
187
     */
188
    public function offsetGet($offset)
189
    {
190
        return $this->strategies[$offset];
191
    }
192
193
194
    /**
195
     * (PHP 5 &gt;= 5.0.0)<br/>
196
     * Offset to set.
197
     *
198
     * @link http://php.net/manual/en/arrayaccess.offsetset.php
199
     *
200
     * @param mixed $offset <p>
201
     *                      The offset to assign the value to.
202
     *                      </p>
203
     * @param mixed $value  <p>
204
     *                      The value to set.
205
     *                      </p>
206
     */
207
    public function offsetSet($offset, $value)
208
    {
209
        $this->add([$offset => $value]);
210
    }
211
212
213
    /**
214
     * (PHP 5 &gt;= 5.0.0)<br/>
215
     * Offset to unset.
216
     *
217
     * @link http://php.net/manual/en/arrayaccess.offsetunset.php
218
     *
219
     * @param mixed $offset <p>
220
     *                      The offset to unset.
221
     *                      </p>
222
     */
223
    public function offsetUnset($offset)
224
    {
225
        unset($this->strategies[$offset]);
226
    }
227
228
229
    public function off()
230
    {
231
        $this->status = self::STATUS_DISABLED;
232
233
        return $this;
234
    }
235
236
237
    public function on()
238
    {
239
        $this->status = self::STATUS_ENABLED;
240
241
        return $this;
242
    }
243
244
245
    public function getStatus()
246
    {
247
        return $this->status;
248
    }
249
250
251
    /**
252
     * @param int $threshold
253
     *
254
     * @return StrategyCollection
255
     */
256
    public function setThreshold($threshold)
257
    {
258
        $this->threshold = $threshold;
259
260
        return $this;
261
    }
262
263
264
    protected function isAnonymousFunctionStrategy($strategy = [])
265
    {
266
        return $strategy['type'] === 'function';
267
    }
268
269
270
    /**
271
     * @return int
272
     */
273
    public function getThreshold()
274
    {
275
        return $this->threshold;
276
    }
277
278
279
    /**
280
     * @return array
281
     */
282
    public function getStrategies()
283
    {
284
        return $this->strategies;
285
    }
286
}
287