Manager::selectFrom()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 17
ccs 7
cts 7
cp 1
rs 10
c 0
b 0
f 0
cc 3
nc 3
nop 3
crap 3
1
<?php namespace Comodojo\SimpleCache;
2
3
use \Comodojo\SimpleCache\Providers\AbstractProvider;
4
use \Comodojo\SimpleCache\Providers\Vacuum;
5
use \Comodojo\SimpleCache\Interfaces\SimpleCacheManagerInterface;
6
use \Comodojo\SimpleCache\Interfaces\EnhancedSimpleCacheInterface;
7
use \Comodojo\Cache\Traits\NamespaceTrait;
8
use \Comodojo\Cache\Traits\GenericManagerTrait;
9
use \Comodojo\SimpleCache\Components\StackManager;
10
use \Comodojo\Foundation\Validation\DataFilter;
11
use \Comodojo\SimpleCache\Components\ConfigurationParser;
12
use \Comodojo\Foundation\Base\Configuration;
13
use \Psr\Log\LoggerInterface;
14
use \ArrayObject;
15
16
/**
17
 * @package     Comodojo Cache
18
 * @author      Marco Giovinazzi <[email protected]>
19
 * @license     MIT
20
 *
21
 * LICENSE:
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
29
 * THE SOFTWARE.
30
 */
31
32
class Manager extends AbstractProvider implements SimpleCacheManagerInterface {
33
34
    use NamespaceTrait, GenericManagerTrait {
35
        GenericManagerTrait::setNamespace insteadof NamespaceTrait;
36
    }
37
38
    const DEFAULT_PICK_MODE = 1;
39
40
    protected $pick_mode;
41
42
    protected $stack;
43
44
    protected $align_cache;
45
46
    protected $vacuum;
47
48
    protected $selected;
49
50 35
    public function __construct(
51
        $pick_mode = null,
52
        LoggerInterface $logger = null,
53
        $align_cache = true,
54
        $flap_interval = null
55
    ) {
56
57 35
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, self::DEFAULT_PICK_MODE);
0 ignored issues
show
Bug introduced by
6 of type integer is incompatible with the type array expected by parameter $max of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, /** @scrutinizer ignore-type */ 6, self::DEFAULT_PICK_MODE);
Loading history...
Bug introduced by
self::DEFAULT_PICK_MODE of type integer is incompatible with the type array expected by parameter $default of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, /** @scrutinizer ignore-type */ self::DEFAULT_PICK_MODE);
Loading history...
Bug introduced by
1 of type integer is incompatible with the type array expected by parameter $min of Comodojo\Foundation\Vali...Filter::filterInteger(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

57
        $this->pick_mode = DataFilter::filterInteger($pick_mode, /** @scrutinizer ignore-type */ 1, 6, self::DEFAULT_PICK_MODE);
Loading history...
58
59 35
        $this->align_cache = DataFilter::filterBoolean($align_cache, false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type array expected by parameter $default of Comodojo\Foundation\Vali...Filter::filterBoolean(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

59
        $this->align_cache = DataFilter::filterBoolean($align_cache, /** @scrutinizer ignore-type */ false);
Loading history...
60
61 35
        $stack = new ArrayObject([]);
62
63 35
        $this->stack = new StackManager($stack->getIterator());
64 35
        $this->stack->setFlapInterval($flap_interval);
65
66 35
        parent::__construct($logger);
67
68 35
        $this->vacuum = new Vacuum([], $this->logger);
69
70 35
        $this->logger->debug("SimpleCache Manager online; pick mode ".$this->pick_mode);
71
72 35
    }
73
74 34
    public function addProvider(EnhancedSimpleCacheInterface $provider, $weight = 0) {
75
76 34
        return $this->genericAddProvider($provider, $weight);
77
78
    }
79
80 24
    public function get($key, $default = null) {
81
82 24
        return $this->selectFrom('GET', $key, $default);
83
84
    }
85
86 30
    public function set($key, $value, $ttl = null) {
87
88 30
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->set($key, $value, $ttl);
89
90 29
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
91 1
            return $this->selectProvider()->set($key, $value, $ttl);
92
        }
93
94 28
        $result = [];
95
96 28
        foreach ( $this->stack as $provider ) {
97
98 28
            $pro = $provider[0];
99
100 28
            $provider_result = $pro->set($key, $value, $ttl);
101
102 27
            $this->logger->debug("Saving item $key into provider ".
103 27
                $pro->getId().": ".($provider_result ? "OK" : "NOK - ".$pro->getStateMessage()));
104
105 27
            $result[] = $provider_result;
106
107
        }
108
109 27
        return !in_array(false, $result);
110
111
    }
112
113 3
    public function delete($key) {
114
115 3
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->delete($key);
116
117 2
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
118
            return $this->selectProvider()->delete($key);
119
        }
120
121 2
        $result = [];
122
123 2
        foreach ( $this->stack as $provider ) {
124
125 2
            $result[] = $provider[0]->delete($key);
126
127
        }
128
129 2
        return !in_array(false, $result);
130
131
    }
132
133 2
    public function getMultiple($keys, $default = null) {
134
135 2
        return $this->selectFrom('GETMULTIPLE', $keys, $default);
136
137
    }
138
139 2
    public function setMultiple($values, $ttl = null) {
140
141 2
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->setMultiple($values, $ttl);
142
143 1
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
144
            return $this->selectProvider()->setMultiple($values, $ttl);
145
        }
146
147 1
        $result = [];
148
149 1
        foreach ( $this->stack as $provider ) {
150
151 1
            $result[] = $provider[0]->setMultiple($values, $ttl);
152
153
        }
154
155 1
        return !in_array(false, $result);
156
157
    }
158
159 2
    public function deleteMultiple($keys) {
160
161 2
        if ( iterator_count($this->stack) == 0 ) return $this->vacuum->deleteMultiple($keys);
162
163 1
        if ( $this->align_cache === false && $this->pick_mode < 5 ) {
0 ignored issues
show
introduced by
The condition $this->align_cache === false is always false.
Loading history...
164
            return $this->selectProvider()->deleteMultiple($keys);
165
        }
166
167 1
        $result = [];
168
169 1
        foreach ( $this->stack as $provider ) {
170
171 1
            $result[] = $provider[0]->deleteMultiple($keys);
172
173
        }
174
175 1
        return !in_array(false, $result);
176
177
    }
178
179 18
    public function has($key) {
180
181 18
        return $this->selectFrom('HAS', $key);
182
183
    }
184
185 1
    public static function createFromConfiguration(Configuration $configuration, LoggerInterface $logger, $stanza = null) {
186
187 1
        list($enable, $manager_configuration, $providers) = ConfigurationParser::parse($configuration, $logger, $stanza);
188
189 1
        $manager = new Manager(...$manager_configuration);
0 ignored issues
show
Bug introduced by
$manager_configuration is expanded, but the parameter $pick_mode of Comodojo\SimpleCache\Manager::__construct() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

189
        $manager = new Manager(/** @scrutinizer ignore-type */ ...$manager_configuration);
Loading history...
190
191 1
        if ( $enable ) {
192 1
            foreach ( $providers as $name => $provider ) {
193 1
                $instance = $provider->instance;
194 1
                $weight = $provider->weight;
195 1
                $id = $instance->getId();
196 1
                $logger->debug("Adding provider $name ($id) to cache manager (w $weight)");
197 1
                $manager->addProvider($instance, $weight);
198
            }
199
        }
200
201 1
        return $manager;
202
203
    }
204
205 30
    protected function selectFrom($mode, $key, $default = null) {
206
207 30
        if ( $this->pick_mode < 5 ) {
208
209 28
            $result = $this->fromSingleProvider($mode, $key, $default);
210
211 2
        } else if ( $this->pick_mode == 5 ) {
212
213 1
            $result = $this->fromAllProviders($mode, $key, $default);
214
215
        } else {
216
217 1
            $result = $this->traverse($mode, $key, $default);
218
219
        }
220
221 30
        return $result;
222
223
    }
224
225 28
    protected function fromSingleProvider($mode, $key, $default) {
226
227 28
        $provider = $this->selectProvider();
228
229
        switch ( $mode ) {
230
231 28
            case 'GET':
232 23
                $data = $provider->get($key, $default);
233 23
                break;
234
235 17
            case 'GETMULTIPLE':
236 2
                $data = $provider->getMultiple($key, $default);
237 2
                break;
238
239 16
            case 'HAS':
240 16
                $data = $provider->has($key);
241 16
                break;
242
243
        }
244
245 28
        return $data;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.
Loading history...
246
247
    }
248
249 1
    protected function fromAllProviders($mode, $key, $default) {
250
251 1
        $result = [];
252
253 1
        if ( $mode == 'GET' ) {
254
255 1
            foreach ( $this->stack as $provider ) {
256
257 1
                $result[] = $provider[0]->get($key, $default);
258
259
                // selected provider has no sense in this case
260 1
                $this->selected = $provider[0];
261
262
            }
263
264 1
            if ( count(array_unique($result)) == 1 ) return $result[0];
265
266 1
            return $default;
267
268 1
        } else if ( $mode == 'GETMULTIPLE' ) {
269
270
            foreach ( $this->stack as $provider ) {
271
272
                $result[] = $provider[0]->getMultiple($key, $default);
273
274
                // selected provider has no sense in this case
275
                $this->selected = $provider[0];
276
277
            }
278
279
            if ( count(array_unique($result)) == 1 ) return $result[0];
280
281
            $this->selected = $this->vacuum;
282
283
            return $this->vacuum->getMultiple($key, $default);
284
285
            // return array_combine($key, array_fill(0, count($key), $default));
286
287
        } else {
288
289 1
            foreach ( $this->stack as $provider ) {
290
291 1
                $result[] = $provider[0]->has($key);
292
293
                // selected provider has no sense in this case
294 1
                $this->selected = $provider[0];
295
296
            }
297
298 1
            return !in_array(false, $result);
299
300
        }
301
302
    }
303
304 1
    protected function traverse($mode, $key, $default) {
305
306 1
        $this->stack->rewind();
307
308 1
        if ( $mode == 'GET' ) {
309
310
            foreach ( $this->stack as $provider ) {
311
312
                $item = $provider[0]->get($key);
313
314
                if ( $item !== null ) {
315
316
                    // selected provider
317
                    $this->selected = $provider[0];
318
319
                    return $item;
320
321
                }
322
323
            }
324
325
            // selected provider has no sense in this case
326
            $this->selected = $this->vacuum;
327
328
            return $default;
329
330 1
        } else if ( $mode == 'GETMULTIPLE' ) {
331
332
            foreach ( $this->stack as $provider ) {
333
334
                $items = $provider[0]->getMultiple($key);
335
336
                $item_unique = array_unique($items);
337
338
                if ( count($item_unique) > 1 && $item_unique[0] !== null ) {
339
340
                    // selected provider
341
                    $this->selected = $provider[0];
342
343
                    return $items;
344
345
                }
346
347
            }
348
349
            // selected provider has no sense in this case
350
            $this->selected = $this->vacuum;
351
352
            return $this->vacuum->getMultiple($key, $default);
353
354
        } else {
355
356 1
            foreach ( $this->stack as $provider ) {
357
358 1
                $item = $provider[0]->has($key);
359
360 1
                if ( $item === true ) {
361
362
                    // selected provider has no sense in this case
363 1
                    $this->selected = $provider[0];
364
365 1
                    return true;
366
367
                }
368
369
            }
370
371
            // selected provider has no sense in this case
372
            $this->selected = $this->vacuum;
373
374
            return false;
375
376
        }
377
378
    }
379
380
}
381