Completed
Push — 2.0 ( a51c1d...cacff6 )
by Marco
04:49
created

Manager::deleteMultiple()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 17
Code Lines 7

Duplication

Lines 17
Ratio 100 %

Code Coverage

Tests 6
CRAP Score 4.0466

Importance

Changes 0
Metric Value
dl 17
loc 17
ccs 6
cts 7
cp 0.8571
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 3
nop 1
crap 4.0466
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
 *
18
 * @package     Comodojo Spare Parts
19
 * @author      Marco Giovinazzi <[email protected]>
20
 * @license     MIT
21
 *
22
 * LICENSE:
23
 *
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
30
 * THE SOFTWARE.
31
 */
32
33
class Manager extends AbstractProvider implements SimpleCacheManagerInterface {
34
35
    use NamespaceTrait, GenericManagerTrait {
36
        GenericManagerTrait::setNamespace insteadof NamespaceTrait;
37
    }
38
39
    const DEFAULT_PICK_MODE = 1;
40
41
    protected $pick_mode;
42
43
    protected $stack;
44
45
    protected $align_cache;
46
47
    protected $vacuum;
48
49
    protected $selected;
50
51 31 View Code Duplication
    public function __construct(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
52
        $pick_mode = null,
53
        LoggerInterface $logger = null,
54
        $align_cache = true,
55
        $flap_interval = null
56
    ) {
57
58 31
        $this->pick_mode = DataFilter::filterInteger($pick_mode, 1, 6, self::DEFAULT_PICK_MODE);
59
60 31
        $this->align_cache = DataFilter::filterBoolean($align_cache, true);
61
62 31
        $stack = new ArrayObject([]);
63
64 31
        $this->stack = new StackManager($stack->getIterator());
65 31
        $this->stack->setFlapInterval($flap_interval);
66
67 31
        parent::__construct($logger);
68
69 31
        $this->vacuum = new Vacuum($this->logger);
70
71 31
        $this->logger->info("SimpleCache Manager online; pick mode ".$this->pick_mode);
72
73 31
    }
74
75 31
    public function addProvider(EnhancedSimpleCacheInterface $provider, $weight = 0) {
76
77 31
        return $this->genericAddProvider($provider, $weight);
78
79
    }
80
81 23
    public function get($key, $default = null) {
82
83 23
        return $this->selectFrom('GET', $key, $default);
84
85
    }
86
87 27
    public function set($key, $value, $ttl = null) {
88
89 27
        if ( $this->align_cache === false && $this->pick_mode < 5) {
90
            return $this->selectProvider()->set($key, $value, $ttl);
91
        }
92
93 27
        $result = [];
94
95 27
        foreach ($this->stack as $provider) {
96
97 27
            $pro = $provider[0];
98
99 27
            $provider_result = $pro->set($key, $value, $ttl);
100
101 26
            $this->logger->debug("Saving item $key into provider ".
102 26
                $pro->getId().": ".($provider_result ? "OK" : "NOK - ".$pro->getStateMessage()));
103
104 26
            $result[] = $provider_result;
105
106
        }
107
108 26
        return !in_array(false, $result);
109
110
    }
111
112 2 View Code Duplication
    public function delete($key) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
114 2
        if ( $this->align_cache === false && $this->pick_mode < 5) {
115
            return $this->selectProvider()->delete($key);
116
        }
117
118 2
        $result = [];
119
120 2
        foreach ($this->stack as $provider) {
121
122 2
            $result[] = $provider[0]->delete($key);
123
124
        }
125
126 2
        return !in_array(false, $result);
127
128
    }
129
130 1
    public function getMultiple($keys, $default = null) {
131
132 1
        return $this->selectFrom('GETMULTIPLE', $keys, $default);
133
134
    }
135
136 1 View Code Duplication
    public function setMultiple($values, $ttl = null) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
137
138 1
        if ( $this->align_cache === false && $this->pick_mode < 5) {
139
            return $this->selectProvider()->setMultiple($values, $ttl);
140
        }
141
142 1
        $result = [];
143
144 1
        foreach ($this->stack as $provider) {
145
146 1
            $result[] = $provider[0]->setMultiple($values, $ttl);
147
148
        }
149
150 1
        return !in_array(false, $result);
151
152
    }
153
154 1 View Code Duplication
    public function deleteMultiple($keys) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
156 1
        if ( $this->align_cache === false && $this->pick_mode < 5) {
157
            return $this->selectProvider()->deleteMultiple($keys);
158
        }
159
160 1
        $result = [];
161
162 1
        foreach ($this->stack as $provider) {
163
164 1
            $result[] = $provider[0]->deleteMultiple($keys);
165
166
        }
167
168 1
        return !in_array(false, $result);
169
170
    }
171
172 17
    public function has($key) {
173
174 17
        return $this->selectFrom('HAS', $key);
175
176
    }
177
178 1 View Code Duplication
    public static function createFromConfiguration(Configuration $configuration, LoggerInterface $logger) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
179
180 1
        list($manager_configuration, $providers) = ConfigurationParser::parse($configuration, $logger);
181
182 1
        $manager = new Manager(...$manager_configuration);
183
184 1
        foreach ($providers as $name => $provider) {
185 1
            $instance = $provider->instance;
186 1
            $weight = $provider->weight;
187 1
            $id = $instance->getId();
188 1
            $logger->debug("Adding provider $name ($id) to cache manager (w $weight)");
189 1
            $manager->addProvider($instance, $weight);
190
        }
191
192 1
        return $manager;
193
194
    }
195
196 29
    protected function selectFrom($mode, $key, $default=null) {
197
198 29 View Code Duplication
        if ( $this->pick_mode < 5 ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
200 27
            $result = $this->fromSingleProvider($mode, $key, $default);
201
202 2
        } else if ( $this->pick_mode == 5 ) {
203
204 1
            $result = $this->fromAllProviders($mode, $key, $default);
205
206
        } else {
207
208 1
            $result = $this->traverse($mode, $key, $default);
209
210
        }
211
212 29
        return $result;
213
214
    }
215
216 27
    protected function fromSingleProvider($mode, $key, $default) {
217
218 27
        $provider = $this->selectProvider();
219
220
        switch ($mode) {
221
222 27
            case 'GET':
223 22
                $data = $provider->get($key, $default);
224 22
                break;
225
226 16
            case 'GETMULTIPLE':
227 1
                $data = $provider->getMultiple($key, $default);
228 1
                break;
229
230 15
            case 'HAS':
231 15
                $data = $provider->has($key);
232 15
                break;
233
234
        }
235
236 27
        return $data;
0 ignored issues
show
Bug introduced by
The variable $data does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
237
238
    }
239
240 1
    protected function fromAllProviders($mode, $key, $default) {
241
242 1
        $result = [];
243
244 1
        if ( $mode == 'GET' ) {
245
246 1
            foreach ($this->stack as $provider) {
247
248 1
                $result[] = $provider[0]->get($key, $default);
249
250
                // selected provider has no sense in this case
251 1
                $this->selected = $provider[0];
252
253
            }
254
255 1
            if ( count(array_unique($result)) == 1 ) return $result[0];
256
257 1
            return $default;
258
259 1
        } else if ( $mode == 'GETMULTIPLE' ) {
260
261
            foreach ($this->stack as $provider) {
262
263
                $result[] = $provider[0]->getMultiple($key, $default);
264
265
                // selected provider has no sense in this case
266
                $this->selected = $provider[0];
267
268
            }
269
270
            if ( count(array_unique($result)) == 1 ) return $result[0];
271
272
            $this->selected = $this->vacuum;
273
274
            return $this->vacuum->getMultiple($key, $default);
275
276
            // return array_combine($key, array_fill(0, count($key), $default));
0 ignored issues
show
Unused Code Comprehensibility introduced by
66% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
277
278 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
279
280 1
            foreach ($this->stack as $provider) {
281
282 1
                $result[] = $provider[0]->has($key);
283
284
                // selected provider has no sense in this case
285 1
                $this->selected = $provider[0];
286
287
            }
288
289 1
            return !in_array(false, $result);
290
291
        }
292
293
    }
294
295 1
    protected function traverse($mode, $key, $default) {
296
297 1
        $this->stack->rewind();
298
299 1
        if ( $mode == 'GET' ) {
300
301
            foreach ($this->stack as $provider) {
302
303
                $item = $provider[0]->get($key);
304
305
                if ( $item !== null ) {
306
307
                    // selected provider
308
                    $this->selected = $provider[0];
309
310
                    return $item;
311
312
                }
313
314
            }
315
316
            // selected provider has no sense in this case
317
            $this->selected = $this->vacuum;
318
319
            return $default;
320
321 1
        } else if ( $mode == 'GETMULTIPLE' ) {
322
323
            foreach ($this->stack as $provider) {
324
325
                $items = $provider[0]->getMultiple($key);
326
327
                $item_unique = array_unique($items);
328
329
                if ( count($item_unique) > 1 && $item_unique[0] !== null ) {
330
331
                    // selected provider
332
                    $this->selected = $provider[0];
333
334
                    return $items;
335
336
                }
337
338
            }
339
340
            // selected provider has no sense in this case
341
            $this->selected = $this->vacuum;
342
343
            return $this->vacuum->getMultiple($key, $default);
344
345 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
346
347 1
            foreach ($this->stack as $provider) {
348
349 1
                $item = $provider[0]->has($key);
350
351 1
                if ( $item === true ) {
352
353
                    // selected provider has no sense in this case
354 1
                    $this->selected = $provider[0];
355
356 1
                    return true;
357
358
                }
359
360
            }
361
362
            // selected provider has no sense in this case
363
            $this->selected = $this->vacuum;
364
365
            return false;
366
367
        }
368
369
    }
370
371
}
372