Passed
Push — v7 ( c2ec86...629ebb )
by Georges
01:43
created

isUsableInAutoContext()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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
declare(strict_types=1);
15
16
namespace Phpfastcache\Core\Pool;
17
18
use Phpfastcache\Core\Item\ExtendedCacheItemInterface;
19
use Phpfastcache\EventManager;
20
use Phpfastcache\Exceptions\{
21
  PhpfastcacheInvalidArgumentException, PhpfastcacheLogicException
22
};
23
use Psr\Cache\CacheItemInterface;
24
25
/**
26
 * Trait ExtendedCacheItemPoolTrait
27
 * @package Phpfastcache\Core\Pool
28
 * @method bool driverWriteTags() Imported from DriverBaseTrait
29
 */
30
trait ExtendedCacheItemPoolTrait
31
{
32
    use CacheItemPoolTrait;
33
34
    /**
35
     * @inheritdoc
36
     */
37
    public function getItemsAsJsonString(array $keys = [], $option = 0, $depth = 512): string
38
    {
39
        $callback = function (CacheItemInterface $item) {
40
            return $item->get();
41
        };
42
        return \json_encode(\array_map($callback, \array_values($this->getItems($keys))), $option, $depth);
43
    }
44
45
    /**
46
     * @inheritdoc
47
     */
48
    public function getItemsByTag($tagName)
49
    {
50
        if (\is_string($tagName)) {
51
            $driverResponse = $this->getItem($this->getTagKey($tagName));
0 ignored issues
show
Bug introduced by
It seems like getTagKey() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

51
            $driverResponse = $this->getItem($this->/** @scrutinizer ignore-call */ getTagKey($tagName));
Loading history...
52
            if ($driverResponse->isHit()) {
53
                $items = (array)$driverResponse->get();
54
55
                /**
56
                 * getItems() may provides expired item(s)
57
                 * themselves provided by a cache of item
58
                 * keys based stored the tag item.
59
                 * Therefore we pass a filter callback
60
                 * to remove the expired Item(s) provided by
61
                 * the item keys passed through getItems()
62
                 *
63
                 * #headache
64
                 */
65
                return \array_filter($this->getItems(\array_unique(\array_keys($items))), function (ExtendedCacheItemInterface $item) {
66
                    return $item->isHit();
67
                });
68
            }
69
            return [];
70
        }
71
72
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
73
    }
74
75
    /**
76
     * @inheritdoc
77
     */
78
    public function getItemsByTags(array $tagNames)
79
    {
80
        $items = [];
81
        foreach (\array_unique($tagNames) as $tagName) {
82
            if (\is_string($tagName)) {
83
                $items = \array_merge($items, $this->getItemsByTag($tagName));
84
            } else {
85
                throw new PhpfastcacheInvalidArgumentException('$tagName must be a a string');
86
            }
87
        }
88
89
        return $items;
90
    }
91
92
93
    /**
94
     * @inheritdoc
95
     */
96
    public function getItemsByTagsAll(array $tagNames)
97
    {
98
        $items = $this->getItemsByTags($tagNames);
99
100
        foreach ($items as $key => $item) {
101
            if (\array_diff($tagNames, $item->getTags())) {
102
                unset($items[ $key ]);
103
            }
104
        }
105
106
        return $items;
107
    }
108
109
110
    /**
111
     * @inheritdoc
112
     */
113
    public function getItemsByTagsAsJsonString(array $tagNames, $option = 0, $depth = 512)
114
    {
115
        $callback = function (CacheItemInterface $item) {
116
            return $item->get();
117
        };
118
119
        return \json_encode(\array_map($callback, \array_values($this->getItemsByTags($tagNames))), $option, $depth);
120
    }
121
122
    /**
123
     * @inheritdoc
124
     */
125
    public function deleteItemsByTag($tagName)
126
    {
127
        if (\is_string($tagName)) {
128
            $return = null;
129
            foreach ($this->getItemsByTag($tagName) as $item) {
130
                $result = $this->deleteItem($item->getKey());
131
                if ($return !== false) {
132
                    $return = $result;
133
                }
134
            }
135
136
            return $return;
137
        }
138
139
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
140
    }
141
142
    /**
143
     * @inheritdoc
144
     */
145
    public function deleteItemsByTags(array $tagNames)
146
    {
147
        $return = null;
148
        foreach ($tagNames as $tagName) {
149
            $result = $this->deleteItemsByTag($tagName);
150
            if ($return !== false) {
151
                $return = $result;
152
            }
153
        }
154
155
        return $return;
156
    }
157
158
    /**
159
     * @inheritdoc
160
     */
161
    public function deleteItemsByTagsAll(array $tagNames)
162
    {
163
        $return = null;
164
        $items = $this->getItemsByTagsAll($tagNames);
165
166
        foreach ($items as $key => $item) {
167
            $result = $this->deleteItem($item->getKey());
168
            if ($return !== false) {
169
                $return = $result;
170
            }
171
        }
172
173
        return $return;
174
    }
175
176
    /**
177
     * @inheritdoc
178
     */
179
    public function incrementItemsByTag($tagName, $step = 1)
180
    {
181
        if (\is_string($tagName) && \is_int($step)) {
182
            foreach ($this->getItemsByTag($tagName) as $item) {
183
                $item->increment($step);
184
                $this->saveDeferred($item);
185
            }
186
187
            return $this->commit();
188
        }
189
190
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string and $step an integer');
191
    }
192
193
    /**
194
     * @inheritdoc
195
     */
196
    public function incrementItemsByTags(array $tagNames, $step = 1)
197
    {
198
        $return = null;
199
        foreach ($tagNames as $tagName) {
200
            $result = $this->incrementItemsByTag($tagName, $step);
201
            if ($return !== false) {
202
                $return = $result;
203
            }
204
        }
205
206
        return $return;
207
    }
208
209
    /**
210
     * @inheritdoc
211
     */
212
    public function incrementItemsByTagsAll(array $tagNames, $step = 1)
213
    {
214
        if (\is_int($step)) {
215
            $items = $this->getItemsByTagsAll($tagNames);
216
217
            foreach ($items as $key => $item) {
218
                $item->increment($step);
219
                $this->saveDeferred($item);
220
            }
221
            return $this->commit();
222
        }
223
224
        throw new PhpfastcacheInvalidArgumentException('$step must be an integer');
225
    }
226
227
    /**
228
     * @inheritdoc
229
     */
230
    public function decrementItemsByTag($tagName, $step = 1)
231
    {
232
        if (\is_string($tagName) && \is_int($step)) {
233
            foreach ($this->getItemsByTag($tagName) as $item) {
234
                $item->decrement($step);
235
                $this->saveDeferred($item);
236
            }
237
238
            return $this->commit();
239
        }
240
241
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string and $step an integer');
242
    }
243
244
    /**
245
     * @inheritdoc
246
     */
247
    public function decrementItemsByTags(array $tagNames, $step = 1)
248
    {
249
        $return = null;
250
        foreach ($tagNames as $tagName) {
251
            $result = $this->decrementItemsByTag($tagName, $step);
252
            if ($return !== false) {
253
                $return = $result;
254
            }
255
        }
256
257
        return $return;
258
    }
259
260
    /**
261
     * @inheritdoc
262
     */
263
    public function decrementItemsByTagsAll(array $tagNames, $step = 1)
264
    {
265
        if (\is_int($step)) {
266
            $items = $this->getItemsByTagsAll($tagNames);
267
268
            foreach ($items as $key => $item) {
269
                $item->decrement($step);
270
                $this->saveDeferred($item);
271
            }
272
            return $this->commit();
273
        }
274
275
        throw new PhpfastcacheInvalidArgumentException('$step must be an integer');
276
    }
277
278
    /**
279
     * @inheritdoc
280
     */
281
    public function appendItemsByTag($tagName, $data)
282
    {
283
        if (\is_string($tagName)) {
284
            foreach ($this->getItemsByTag($tagName) as $item) {
285
                $item->append($data);
286
                $this->saveDeferred($item);
287
            }
288
289
            return $this->commit();
290
        }
291
292
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
293
    }
294
295
    /**
296
     * @inheritdoc
297
     */
298
    public function appendItemsByTags(array $tagNames, $data)
299
    {
300
        $return = null;
301
        foreach ($tagNames as $tagName) {
302
            $result = $this->appendItemsByTag($tagName, $data);
303
            if ($return !== false) {
304
                $return = $result;
305
            }
306
        }
307
308
        return $return;
309
    }
310
311
    /**
312
     * @inheritdoc
313
     */
314
    public function appendItemsByTagsAll(array $tagNames, $data)
315
    {
316
        if (is_scalar($data)) {
317
            $items = $this->getItemsByTagsAll($tagNames);
318
319
            foreach ($items as $key => $item) {
320
                $item->append($data);
321
                $this->saveDeferred($item);
322
            }
323
            return $this->commit();
324
        }
325
326
        throw new PhpfastcacheInvalidArgumentException('$data must be scalar');
327
    }
328
329
    /**
330
     * @inheritdoc
331
     */
332
    public function prependItemsByTag($tagName, $data)
333
    {
334
        if (\is_string($tagName)) {
335
            foreach ($this->getItemsByTag($tagName) as $item) {
336
                $item->prepend($data);
337
                $this->saveDeferred($item);
338
            }
339
340
            return $this->commit();
341
        }
342
343
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
344
    }
345
346
    /**
347
     * @inheritdoc
348
     */
349
    public function prependItemsByTags(array $tagNames, $data)
350
    {
351
        $return = null;
352
        foreach ($tagNames as $tagName) {
353
            $result = $this->prependItemsByTag($tagName, $data);
354
            if ($return !== false) {
355
                $return = $result;
356
            }
357
        }
358
359
        return $return;
360
    }
361
362
    /**
363
     * @inheritdoc
364
     */
365
    public function prependItemsByTagsAll(array $tagNames, $data)
366
    {
367
        if (\is_scalar($data)) {
368
            $items = $this->getItemsByTagsAll($tagNames);
369
370
            foreach ($items as $key => $item) {
371
                $item->prepend($data);
372
                $this->saveDeferred($item);
373
            }
374
            return $this->commit();
375
        }
376
377
        throw new PhpfastcacheInvalidArgumentException('$data must be scalar');
378
    }
379
380
    /**
381
     * @param \Psr\Cache\CacheItemInterface $item
382
     * @return void
383
     */
384
    public function detachItem(CacheItemInterface $item)
385
    {
386
        if (isset($this->itemInstances[ $item->getKey() ])) {
387
            $this->deregisterItem($item);
388
        }
389
    }
390
391
    /**
392
     * @inheritdoc
393
     */
394
    public function detachAllItems()
395
    {
396
        foreach ($this->itemInstances as $item) {
397
            $this->detachItem($item);
398
        }
399
    }
400
401
    /**
402
     * @inheritdoc
403
     */
404
    public function attachItem(CacheItemInterface $item)
405
    {
406
        if (isset($this->itemInstances[ $item->getKey() ]) && \spl_object_hash($item) !== \spl_object_hash($this->itemInstances[ $item->getKey() ])) {
407
            throw new PhpfastcacheLogicException('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.');
408
        }
409
410
        $this->itemInstances[ $item->getKey() ] = $item;
411
    }
412
413
414
    /**
415
     * @internal This method de-register an item from $this->itemInstances
416
     * @param CacheItemInterface|string $item
417
     * @throws PhpfastcacheInvalidArgumentException
418
     */
419
    protected function deregisterItem($item)
420
    {
421
        if ($item instanceof CacheItemInterface) {
422
            unset($this->itemInstances[ $item->getKey() ]);
423
424
        } else if (\is_string($item)) {
0 ignored issues
show
introduced by
The condition is_string($item) is always true.
Loading history...
425
            unset($this->itemInstances[ $item ]);
426
        } else {
427
            throw new PhpfastcacheInvalidArgumentException('Invalid type for $item variable');
428
        }
429
        if (\gc_enabled()) {
430
            \gc_collect_cycles();
431
        }
432
    }
433
434
    /**
435
     * @param ExtendedCacheItemInterface $item
436
     */
437
    protected function cleanItemTags(ExtendedCacheItemInterface $item)
438
    {
439
        $this->driverWriteTags($item->removeTags($item->getTags()));
0 ignored issues
show
Unused Code introduced by
The call to Phpfastcache\Core\Pool\E...rait::driverWriteTags() has too many arguments starting with $item->removeTags($item->getTags()). ( Ignorable by Annotation )

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

439
        $this->/** @scrutinizer ignore-call */ 
440
               driverWriteTags($item->removeTags($item->getTags()));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
440
    }
441
442
    /**
443
     * Returns true if the item exists, is attached and the Spl Hash matches
444
     * Returns false if the item exists, is attached and the Spl Hash mismatches
445
     * Returns null if the item does not exists
446
     *
447
     * @param \Psr\Cache\CacheItemInterface $item
448
     * @return bool|null
449
     */
450
    public function isAttached(CacheItemInterface $item)
451
    {
452
        if (isset($this->itemInstances[ $item->getKey() ])) {
453
            return \spl_object_hash($item) === \spl_object_hash($this->itemInstances[ $item->getKey() ]);
454
        }
455
        return null;
456
    }
457
458
    /**
459
     * Set the EventManager instance
460
     *
461
     * @param EventManager $em
462
     * @return ExtendedCacheItemPoolInterface
463
     */
464
    public function setEventManager(EventManager $em): ExtendedCacheItemPoolInterface
465
    {
466
        $this->eventManager = $em;
467
468
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Pool\ExtendedCacheItemPoolTrait which is incompatible with the type-hinted return Phpfastcache\Core\Pool\E...dCacheItemPoolInterface.
Loading history...
469
    }
470
471
    /**
472
     * @inheritdoc
473
     */
474
    public function saveMultiple(...$items): bool
475
    {
476
        if (isset($items[ 0 ]) && \is_array($items[ 0 ])) {
477
            foreach ($items[ 0 ] as $item) {
478
                $this->save($item);
479
            }
480
            return true;
481
        }
482
483
        if (\is_array($items)) {
484
            foreach ($items as $item) {
485
                $this->save($item);
486
            }
487
            return true;
488
        }
489
        return false;
490
    }
491
492
    /**
493
     * @inheritdoc
494
     */
495
    public static function isUsableInAutoContext(): bool
496
    {
497
        return true;
498
    }
499
500
    /**
501
     * @return string
502
     */
503
    public function getHelp(): string
504
    {
505
        return '';
506
    }
507
508
    /**
509
     * Driver-related methods
510
     */
511
512
    /**
513
     * @return bool
514
     */
515
    abstract protected function driverCheck(): bool;
516
517
    /**
518
     * @return bool
519
     */
520
    abstract protected function driverConnect(): bool;
521
522
    /**
523
     * @param \Psr\Cache\CacheItemInterface $item
524
     * @return null|array [
525
     *      'd' => 'THE ITEM DATA'
526
     *      't' => 'THE ITEM DATE EXPIRATION'
527
     *      'g' => 'THE ITEM TAGS'
528
     * ]
529
     *
530
     */
531
    abstract protected function driverRead(CacheItemInterface $item);
532
533
    /**
534
     * @param \Psr\Cache\CacheItemInterface $item
535
     * @return bool
536
     */
537
    abstract protected function driverWrite(CacheItemInterface $item): bool;
538
539
    /**
540
     * @param \Psr\Cache\CacheItemInterface $item
541
     * @return bool
542
     */
543
    abstract protected function driverDelete(CacheItemInterface $item): bool;
544
545
    /**
546
     * @return bool
547
     */
548
    abstract protected function driverClear(): bool;
549
}