Completed
Push — V6 ( 927ad1...3487d5 )
by Georges
03:17
created

ExtendedCacheItemPoolTrait   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 398
Duplicated Lines 33.17 %

Coupling/Cohesion

Components 2
Dependencies 3

Importance

Changes 4
Bugs 1 Features 2
Metric Value
c 4
b 1
f 2
dl 132
loc 398
rs 6.8
wmc 55
lcom 2
cbo 3

26 Methods

Rating   Name   Duplication   Size   Complexity  
A clean() 0 5 1
A getItemsAsJsonString() 7 7 1
B getItemsByTag() 0 27 3
A getItemsByTags() 0 9 2
A getItemsByTagsAsJsonString() 8 8 1
A deleteItemsByTag() 0 16 4
A deleteItemsByTags() 12 12 3
A incrementItemsByTag() 13 13 4
A incrementItemsByTags() 12 12 3
A decrementItemsByTag() 13 13 4
A decrementItemsByTags() 12 12 3
A appendItemsByTag() 13 13 3
A appendItemsByTags() 12 12 3
A prependItemsByTag() 13 13 3
A prependItemsByTags() 12 12 3
A detachItem() 0 6 2
A detachAllItems() 0 6 2
A attachItem() 5 8 3
A deregisterItem() 0 14 4
A isAttached() 0 7 2
A setEventManager() 0 4 1
driverRead() 0 1 ?
driverWrite() 0 1 ?
driverClear() 0 1 ?
driverConnect() 0 1 ?
driverDelete() 0 1 ?

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like ExtendedCacheItemPoolTrait often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ExtendedCacheItemPoolTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 *
4
 * This file is part of phpFastCache.
5
 *
6
 * @license MIT License (MIT)
7
 *
8
 * For full copyright and license information, please see the docs/CREDITS.txt file.
9
 *
10
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 *
13
 */
14
15
namespace phpFastCache\Core\Pool;
16
17
use InvalidArgumentException;
18
use phpFastCache\Core\Item\ExtendedCacheItemInterface;
19
use phpFastCache\EventManager;
20
use Psr\Cache\CacheItemInterface;
21
22
23
trait ExtendedCacheItemPoolTrait
24
{
25
    use CacheItemPoolTrait;
26
27
    /**
28
     * Deletes all items in the pool.
29
     * @deprecated Use clear() instead
30
     * Will be removed in 5.1
31
     *
32
     * @return bool
33
     *   True if the pool was successfully cleared. False if there was an error.
34
     */
35
    public function clean()
36
    {
37
        trigger_error('Cache clean() method is deprecated, use clear() method instead', E_USER_DEPRECATED);
38
        return $this->clear();
39
    }
40
41
    /**
42
     * @param array $keys
43
     * An indexed array of keys of items to retrieve.
44
     * @param int $option json_encode() options
45
     * @param int $depth json_encode() depth
46
     * @return string
47
     * @throws \InvalidArgumentException
48
     */
49 View Code Duplication
    public function getItemsAsJsonString(array $keys = [], $option = 0, $depth = 512)
1 ignored issue
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...
50
    {
51
        $callback = function(CacheItemInterface $item){
52
            return $item->get();
53
        };
54
        return json_encode(array_map($callback, array_values($this->getItems($keys))), $option, $depth);
55
    }
56
57
    /**
58
     * @param string $tagName
59
     * @return \phpFastCache\Core\Item\ExtendedCacheItemInterface[]
60
     * @throws InvalidArgumentException
61
     */
62
    public function getItemsByTag($tagName)
63
    {
64
        if (is_string($tagName)) {
65
            $driverResponse = $this->getItem($this->getTagKey($tagName));
66
            if ($driverResponse->isHit()) {
67
                $items = (array) $driverResponse->get();
68
69
                /**
70
                 * getItems() may provides expired item(s)
71
                 * themselves provided by a cache of item
72
                 * keys based stored the tag item.
73
                 * Therefore we pass a filter callback
74
                 * to remove the expired Item(s) provided by
75
                 * the item keys passed through getItems()
76
                 *
77
                 * #headache
78
                 */
79
                return array_filter($this->getItems(array_unique(array_keys($items))), function(ExtendedCacheItemInterface $item){
80
                    return $item->isHit();
81
                });
82
            } else {
83
                return [];
84
            }
85
        } else {
86
            throw new InvalidArgumentException('$tagName must be a string');
87
        }
88
    }
89
90
    /**
91
     * @param array $tagNames
92
     * @return \phpFastCache\Core\Item\ExtendedCacheItemInterface[]
93
     * @throws InvalidArgumentException
94
     */
95
    public function getItemsByTags(array $tagNames)
96
    {
97
        $items = [];
98
        foreach (array_unique($tagNames) as $tagName) {
99
            $items = array_merge($items, $this->getItemsByTag($tagName));
100
        }
101
102
        return $items;
103
    }
104
105
    /**
106
     * Returns A json string that represents an array of items by tags-based.
107
     *
108
     * @param array $tagNames
109
     * An indexed array of keys of items to retrieve.
110
     * @param int $option json_encode() options
111
     * @param int $depth json_encode() depth
112
     *
113
     * @throws InvalidArgumentException
114
     *   If any of the keys in $keys are not a legal value a \Psr\Cache\InvalidArgumentException
115
     *   MUST be thrown.
116
     *
117
     * @return string
118
     */
119 View Code Duplication
    public function getItemsByTagsAsJsonString(array $tagNames, $option = 0, $depth = 512)
1 ignored issue
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...
120
    {
121
        $callback = function(CacheItemInterface $item){
122
            return $item->get();
123
        };
124
125
        return json_encode(array_map($callback, array_values($this->getItemsByTags($tagNames))), $option, $depth);
126
    }
127
128
    /**
129
     * @param string $tagName
130
     * @return bool|null
131
     * @throws InvalidArgumentException
132
     */
133
    public function deleteItemsByTag($tagName)
134
    {
135
        if (is_string($tagName)) {
136
            $return = null;
137
            foreach ($this->getItemsByTag($tagName) as $item) {
138
                $result = $this->deleteItem($item->getKey());
139
                if ($return !== false) {
140
                    $return = $result;
141
                }
142
            }
143
144
            return $return;
145
        } else {
146
            throw new InvalidArgumentException('$tagName must be a string');
147
        }
148
    }
149
150
    /**
151
     * @param array $tagNames
152
     * @return bool|null
153
     * @throws InvalidArgumentException
154
     */
155 View Code Duplication
    public function deleteItemsByTags(array $tagNames)
1 ignored issue
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...
156
    {
157
        $return = null;
158
        foreach ($tagNames as $tagName) {
159
            $result = $this->deleteItemsByTag($tagName);
160
            if ($return !== false) {
161
                $return = $result;
162
            }
163
        }
164
165
        return $return;
166
    }
167
168
    /**
169
     * @inheritdoc
170
     */
171 View Code Duplication
    public function incrementItemsByTag($tagName, $step = 1)
1 ignored issue
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...
172
    {
173
        if (is_string($tagName) && is_int($step)) {
174
            foreach ($this->getItemsByTag($tagName) as $item) {
175
                $item->increment($step);
176
                $this->saveDeferred($item);
177
            }
178
179
            return $this->commit();
180
        } else {
181
            throw new InvalidArgumentException('$tagName must be a string and $step an integer');
182
        }
183
    }
184
185
    /**
186
     * @inheritdoc
187
     */
188 View Code Duplication
    public function incrementItemsByTags(array $tagNames, $step = 1)
1 ignored issue
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...
189
    {
190
        $return = null;
191
        foreach ($tagNames as $tagName) {
192
            $result = $this->incrementItemsByTag($tagName, $step);
193
            if ($return !== false) {
194
                $return = $result;
195
            }
196
        }
197
198
        return $return;
199
    }
200
201
    /**
202
     * @inheritdoc
203
     */
204 View Code Duplication
    public function decrementItemsByTag($tagName, $step = 1)
1 ignored issue
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...
205
    {
206
        if (is_string($tagName) && is_int($step)) {
207
            foreach ($this->getItemsByTag($tagName) as $item) {
208
                $item->decrement($step);
209
                $this->saveDeferred($item);
210
            }
211
212
            return $this->commit();
213
        } else {
214
            throw new InvalidArgumentException('$tagName must be a string and $step an integer');
215
        }
216
    }
217
218
    /**
219
     * @inheritdoc
220
     */
221 View Code Duplication
    public function decrementItemsByTags(array $tagNames, $step = 1)
1 ignored issue
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...
222
    {
223
        $return = null;
224
        foreach ($tagNames as $tagName) {
225
            $result = $this->decrementItemsByTag($tagName, $step);
226
            if ($return !== false) {
227
                $return = $result;
228
            }
229
        }
230
231
        return $return;
232
    }
233
234
    /**
235
     * @inheritdoc
236
     */
237 View Code Duplication
    public function appendItemsByTag($tagName, $data)
1 ignored issue
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...
238
    {
239
        if (is_string($tagName)) {
240
            foreach ($this->getItemsByTag($tagName) as $item) {
241
                $item->append($data);
242
                $this->saveDeferred($item);
243
            }
244
245
            return $this->commit();
246
        } else {
247
            throw new InvalidArgumentException('$tagName must be a string');
248
        }
249
    }
250
251
    /**
252
     * @inheritdoc
253
     */
254 View Code Duplication
    public function appendItemsByTags(array $tagNames, $data)
1 ignored issue
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...
255
    {
256
        $return = null;
257
        foreach ($tagNames as $tagName) {
258
            $result = $this->decrementItemsByTag($tagName, $data);
259
            if ($return !== false) {
260
                $return = $result;
261
            }
262
        }
263
264
        return $return;
265
    }
266
267
    /**
268
     * @inheritdoc
269
     */
270 View Code Duplication
    public function prependItemsByTag($tagName, $data)
1 ignored issue
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...
271
    {
272
        if (is_string($tagName)) {
273
            foreach ($this->getItemsByTag($tagName) as $item) {
274
                $item->prepend($data);
275
                $this->saveDeferred($item);
276
            }
277
278
            return $this->commit();
279
        } else {
280
            throw new InvalidArgumentException('$tagName must be a string');
281
        }
282
    }
283
284
    /**
285
     * @inheritdoc
286
     */
287 View Code Duplication
    public function prependItemsByTags(array $tagNames, $data)
1 ignored issue
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...
288
    {
289
        $return = null;
290
        foreach ($tagNames as $tagName) {
291
            $result = $this->decrementItemsByTag($tagName, $data);
292
            if ($return !== false) {
293
                $return = $result;
294
            }
295
        }
296
297
        return $return;
298
    }
299
300
    /**
301
     * @param \Psr\Cache\CacheItemInterface $item
302
     * @return void
303
     */
304
    public function detachItem(CacheItemInterface $item)
305
    {
306
        if(isset($this->itemInstances[$item->getKey()])){
307
            $this->deregisterItem($item);
308
        }
309
    }
310
311
    /**
312
     * @return void
313
     */
314
    public function detachAllItems()
315
    {
316
        foreach ($this->itemInstances as $item) {
317
            $this->detachItem($item);
318
        }
319
    }
320
321
    /**
322
     * @param \Psr\Cache\CacheItemInterface $item
323
     * @return void
324
     * @throws \LogicException
325
     */
326
    public function attachItem(CacheItemInterface $item)
327
    {
328 View Code Duplication
        if(isset($this->itemInstances[$item->getKey()]) && spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
1 ignored issue
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...
329
            throw new \LogicException('The item already exists and cannot be overwritten because the Spl object hash mismatches ! You probably tried to re-attach a detached item which has been already retrieved from cache.');
330
        }else{
331
            $this->itemInstances[$item->getKey()] = $item;
332
        }
333
    }
334
335
336
    /**
337
     * @internal This method de-register an item from $this->itemInstances
338
     * @param CacheItemInterface|string $item
339
     * @throws \InvalidArgumentException
340
     */
341
    protected function deregisterItem($item)
342
    {
343
        if($item instanceof CacheItemInterface){
344
            unset($this->itemInstances[ $item->getKey() ]);
345
346
        }else if(is_string($item)){
347
            unset($this->itemInstances[ $item ]);
348
        }else{
349
            throw new \InvalidArgumentException('Invalid type for $item variable');
350
        }
351
        if(gc_enabled()){
352
            gc_collect_cycles();
353
        }
354
    }
355
356
    /**
357
     * Returns true if the item exists, is attached and the Spl Hash matches
358
     * Returns false if the item exists, is attached and the Spl Hash mismatches
359
     * Returns null if the item does not exists
360
     *
361
     * @param \Psr\Cache\CacheItemInterface $item
362
     * @return bool|null
363
     * @throws \LogicException
364
     */
365
    public function isAttached(CacheItemInterface $item)
366
    {
367
        if(isset($this->itemInstances[$item->getKey()])){
368
            return spl_object_hash($item) === spl_object_hash($this->itemInstances[ $item->getKey() ]);
369
        }
370
        return null;
371
    }
372
373
    /**
374
     * Set the EventManager instance
375
     *
376
     * @param EventManager $em
377
     */
378
    public function setEventManager(EventManager $em)
379
    {
380
        $this->eventManager = $em;
381
    }
382
383
384
    /**
385
     * Driver-related methods
386
     */
387
388
    /**
389
     * @param \Psr\Cache\CacheItemInterface $item
390
     * @return array [
391
     *      'd' => 'THE ITEM DATA'
392
     *      't' => 'THE ITEM DATE EXPIRATION'
393
     *      'g' => 'THE ITEM TAGS'
394
     * ]
395
     *
396
     */
397
    abstract protected function driverRead(CacheItemInterface $item);
398
399
    /**
400
     * @param \Psr\Cache\CacheItemInterface $item
401
     * @return mixed
402
     */
403
    abstract protected function driverWrite(CacheItemInterface $item);
404
405
    /**
406
     * @return bool
407
     */
408
    abstract protected function driverClear();
409
410
    /**
411
     * @return bool
412
     */
413
    abstract protected function driverConnect();
414
415
    /**
416
     * @param \Psr\Cache\CacheItemInterface $item
417
     * @return bool
418
     */
419
    abstract protected function driverDelete(CacheItemInterface $item);
420
}