Completed
Push — v7 ( ec3ca5...759ac1 )
by Georges
01:51
created

ItemExtendedTrait::setEventManager()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 5
rs 9.4285
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\Item;
17
18
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
19
use Phpfastcache\EventManager;
20
use Phpfastcache\Exceptions\{
21
  PhpfastcacheInvalidArgumentException, PhpfastcacheInvalidArgumentTypeException, PhpfastcacheLogicException
22
};
23
24
/**
25
 * Class ItemExtendedTrait
26
 * @package phpFastCache\Core\Item
27
 * @property \Datetime $expirationDate Expiration date of the item
28
 * @property \Datetime $creationDate Creation date of the item
29
 * @property \Datetime $modificationDate Modification date of the item
30
 * @property mixed $data Data of the item
31
 * @property bool $fetched Fetch flag status
32
 * @property array $tags The tags array
33
 * @property array $removedTags The removed tags array
34
 * @property string $key The item key
35
 */
36
trait ItemExtendedTrait
37
{
38
    /********************
39
     *
40
     * PSR-6 Extended Methods
41
     *
42
     *******************/
43
44
    /**
45
     * @var EventManager
46
     */
47
    protected $eventManager;
48
49
50
    /**
51
     * @var ExtendedCacheItemPoolInterface
52
     */
53
    protected $driver;
54
55
    /**
56
     * @var string
57
     */
58
    protected $encodedKey;
59
60
    /**
61
     * Item constructor.
62
     * @param ExtendedCacheItemPoolInterface $driver
63
     * @param $key
64
     * @throws PhpfastcacheInvalidArgumentException
65
     */
66
    public function __construct(ExtendedCacheItemPoolInterface $driver, $key)
67
    {
68
        if (\is_string($key)) {
69
            $this->key = $key;
70
            $this->driver = $driver;
71
            $this->driver->setItem($this);
0 ignored issues
show
Bug introduced by
$this of type Phpfastcache\Core\Item\ItemExtendedTrait is incompatible with the type Psr\Cache\CacheItemInterface expected by parameter $item of Phpfastcache\Core\Pool\E...oolInterface::setItem(). ( Ignorable by Annotation )

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

71
            $this->driver->setItem(/** @scrutinizer ignore-type */ $this);
Loading history...
72
            $this->expirationDate = new \DateTime();
73
            if($this->driver->getConfigOption('itemDetailedDate')){
74
                $this->creationDate = new \DateTime();
75
                $this->modificationDate = new \DateTime();
76
            }
77
        } else {
78
            throw new PhpfastcacheInvalidArgumentTypeException('string', $key);
79
        }
80
    }
81
82
    /**
83
     * @return string
84
     */
85
    public function getEncodedKey(): string
86
    {
87
        if (!$this->encodedKey) {
88
            $keyHashFunction = $this->driver->getConfigOption('defaultKeyHashFunction');
89
90
            if ($keyHashFunction) {
91
                $this->encodedKey = $keyHashFunction($this->getKey());
0 ignored issues
show
Bug introduced by
It seems like getKey() 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

91
                $this->encodedKey = $keyHashFunction($this->/** @scrutinizer ignore-call */ getKey());
Loading history...
92
            } else {
93
                $this->encodedKey = \md5($this->getKey());
94
            }
95
        }
96
97
        return $this->encodedKey;
98
    }
99
100
    /**
101
     * @return mixed
102
     */
103
    public function getUncommittedData()
104
    {
105
        return $this->data;
106
    }
107
108
    /**
109
     * @return \DateTimeInterface
110
     */
111
    public function getExpirationDate(): \DateTimeInterface
112
    {
113
        return $this->expirationDate;
114
    }
115
116
    /**
117
     * Alias of expireAt() with forced $expiration param
118
     *
119
     * @param \DateTimeInterface $expiration
120
     *   The point in time after which the item MUST be considered expired.
121
     *   If null is passed explicitly, a default value MAY be used. If none is set,
122
     *   the value should be stored permanently or for as long as the
123
     *   implementation allows.
124
     *
125
     * @return ExtendedCacheItemInterface
126
     *   The called object.
127
     */
128
    public function setExpirationDate(\DateTimeInterface $expiration): ExtendedCacheItemInterface
129
    {
130
        return $this->expiresAt($expiration);
0 ignored issues
show
Bug introduced by
It seems like expiresAt() 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

130
        return $this->/** @scrutinizer ignore-call */ expiresAt($expiration);
Loading history...
131
    }
132
133
    /**
134
     * @return \DateTimeInterface
135
     * @throws PhpfastcacheLogicException
136
     */
137
    public function getCreationDate(): \DateTimeInterface
138
    {
139
        if ($this->driver->getConfig()->isItemDetailedDate()) {
140
            return $this->creationDate;
141
        }
142
143
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
144
    }
145
146
    /**
147
     * @param \DateTimeInterface $date
148
     * @return ExtendedCacheItemInterface
149
     * @throws PhpfastcacheLogicException
150
     */
151
    public function setCreationDate(\DateTimeInterface $date): ExtendedCacheItemInterface
152
    {
153
        if ($this->driver->getConfig()->isItemDetailedDate()) {
154
            $this->creationDate = $date;
0 ignored issues
show
Documentation Bug introduced by
$date is of type DateTimeInterface, but the property $creationDate was declared to be of type Datetime. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
155
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
156
        }
157
158
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
159
    }
160
161
    /**
162
     * @return \DateTimeInterface
163
     * @throws PhpfastcacheLogicException
164
     */
165
    public function getModificationDate(): \DateTimeInterface
166
    {
167
        if ($this->driver->getConfig()->isItemDetailedDate()) {
168
            return $this->modificationDate;
169
        }
170
171
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
172
    }
173
174
    /**
175
     * @param \DateTimeInterface $date
176
     * @return ExtendedCacheItemInterface
177
     * @throws PhpfastcacheLogicException
178
     */
179
    public function setModificationDate(\DateTimeInterface $date): ExtendedCacheItemInterface
180
    {
181
        if ($this->driver->getConfig()->isItemDetailedDate()) {
182
            $this->modificationDate = $date;
0 ignored issues
show
Documentation Bug introduced by
$date is of type DateTimeInterface, but the property $modificationDate was declared to be of type Datetime. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
183
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
184
        }
185
186
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
187
    }
188
189
    /**
190
     * @return int
191
     */
192
    public function getTtl(): int
193
    {
194
        return max(0, $this->expirationDate->getTimestamp() - \time());
195
    }
196
197
    /**
198
     * @return bool
199
     */
200
    public function isExpired(): bool
201
    {
202
        return $this->expirationDate->getTimestamp() < (new \DateTime())->getTimestamp();
203
    }
204
205
    /**
206
     * @return bool
207
     */
208
    public function isNull(): bool
209
    {
210
        return $this->data === null;
211
    }
212
213
    /**
214
     * @return bool
215
     */
216
    public function isEmpty(): bool
217
    {
218
        return empty($this->data);
219
    }
220
221
    /**
222
     * Return the data length:
223
     * Either the string length if it's a string (binary mode)
224
     * # or the number of element (count) if it's an array
225
     * # or the number returned by count() if it's an object implementing \Countable interface
226
     * # -1 for anything else
227
     * @return int
228
     */
229
    public function getLength(): int
230
    {
231
        switch (\gettype($this->data))
232
        {
233
            case 'array':
234
            case 'object':
235
                if(\is_array($this->data) || $this->data instanceof \Countable){
236
                    return \count($this->data);
237
                }
238
            break;
239
240
            case 'string':
241
                return \strlen($this->data);
242
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
243
        }
244
245
        return -1;
246
    }
247
248
249
    /**
250
     * @param int $step
251
     * @return ExtendedCacheItemInterface
252
     * @throws PhpfastcacheInvalidArgumentException
253
     */
254
    public function increment($step = 1): ExtendedCacheItemInterface
255
    {
256
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
257
            $this->fetched = true;
258
            $this->data += $step;
259
        } else {
260
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
261
        }
262
263
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
264
    }
265
266
    /**
267
     * @param int $step
268
     * @return ExtendedCacheItemInterface
269
     * @throws PhpfastcacheInvalidArgumentException
270
     */
271
    public function decrement($step = 1): ExtendedCacheItemInterface
272
    {
273
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
274
            $this->fetched = true;
275
            $this->data -= $step;
276
        } else {
277
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
278
        }
279
280
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
281
    }
282
283
    /**
284
     * @param array|string $data
285
     * @return ExtendedCacheItemInterface
286
     * @throws PhpfastcacheInvalidArgumentException
287
     */
288
    public function append($data): ExtendedCacheItemInterface
289
    {
290
        if (\is_array($this->data)) {
291
            $this->data[] = $data;
292
        } else if (\is_string($data)) {
293
            $this->data .= (string)$data;
294
        } else {
295
            throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
296
        }
297
298
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
299
    }
300
301
302
    /**
303
     * @param array|string $data
304
     * @return ExtendedCacheItemInterface
305
     * @throws PhpfastcacheInvalidArgumentException
306
     */
307
    public function prepend($data): ExtendedCacheItemInterface
308
    {
309
        if (\is_array($this->data)) {
310
            \array_unshift($this->data, $data);
311
        } else if (\is_string($data)) {
312
            $this->data = (string)$data . $this->data;
313
        } else {
314
            throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
315
        }
316
317
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
318
    }
319
320
    /**
321
     * @param $tagName
322
     * @return ExtendedCacheItemInterface
323
     * @throws PhpfastcacheInvalidArgumentException
324
     */
325
    public function addTag($tagName): ExtendedCacheItemInterface
326
    {
327
        if (\is_string($tagName)) {
328
            $this->tags = \array_unique(\array_merge($this->tags, [$tagName]));
329
330
            return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
331
        }
332
333
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
334
    }
335
336
    /**
337
     * @param array $tagNames
338
     * @return ExtendedCacheItemInterface
339
     */
340
    public function addTags(array $tagNames): ExtendedCacheItemInterface
341
    {
342
        foreach ($tagNames as $tagName) {
343
            $this->addTag($tagName);
344
        }
345
346
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
347
    }
348
349
    /**
350
     * @param array $tags
351
     * @return ExtendedCacheItemInterface
352
     * @throws PhpfastcacheInvalidArgumentException
353
     */
354
    public function setTags(array $tags): ExtendedCacheItemInterface
355
    {
356
        if (\count($tags)) {
357
            if (\array_filter($tags, 'is_string')) {
358
                $this->tags = $tags;
359
            } else {
360
                throw new PhpfastcacheInvalidArgumentException('$tagName must be an array of string');
361
            }
362
        }
363
364
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
365
    }
366
367
    /**
368
     * @return array
369
     */
370
    public function getTags(): array
371
    {
372
        return $this->tags;
373
    }
374
375
    /**
376
     * @param string $separator
377
     * @return string
378
     */
379
    public function getTagsAsString($separator = ', '): string
380
    {
381
        return \implode($separator, $this->tags);
382
    }
383
384
    /**
385
     * @param $tagName
386
     * @return ExtendedCacheItemInterface
387
     */
388
    public function removeTag($tagName): ExtendedCacheItemInterface
389
    {
390
        if (($key = array_search($tagName, $this->tags)) !== false) {
391
            unset($this->tags[ $key ]);
392
            $this->removedTags[] = $tagName;
393
        }
394
395
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
396
    }
397
398
    /**
399
     * @param array $tagNames
400
     * @return ExtendedCacheItemInterface
401
     */
402
    public function removeTags(array $tagNames): ExtendedCacheItemInterface
403
    {
404
        foreach ($tagNames as $tagName) {
405
            $this->removeTag($tagName);
406
        }
407
408
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
409
    }
410
411
    /**
412
     * @return array
413
     */
414
    public function getRemovedTags(): array
415
    {
416
        return \array_diff($this->removedTags, $this->tags);
417
    }
418
419
    /**
420
     * Return the data as a well-formatted string.
421
     * Any scalar value will be casted to an array
422
     * @param int $option \json_encode() options
423
     * @param int $depth \json_encode() depth
424
     * @return string
425
     */
426
    public function getDataAsJsonString($option = 0, $depth = 512): string
427
    {
428
        $data = $this->get();
0 ignored issues
show
Bug introduced by
It seems like get() 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

428
        /** @scrutinizer ignore-call */ 
429
        $data = $this->get();
Loading history...
429
430
        if (\is_object($data) || \is_array($data)) {
431
            $data = \json_encode($data, $option, $depth);
432
        } else {
433
            $data = \json_encode([$data], $option, $depth);
434
        }
435
436
        return \json_encode($data, $option, $depth);
437
    }
438
439
    /**
440
     * Implements \JsonSerializable interface
441
     * @return mixed
442
     */
443
    public function jsonSerialize()
444
    {
445
        return $this->get();
446
    }
447
448
449
    /**
450
     * Set the EventManager instance
451
     *
452
     * @param EventManager $em
453
     * @return ExtendedCacheItemInterface
454
     */
455
    public function setEventManager(EventManager $em): ExtendedCacheItemInterface
456
    {
457
        $this->eventManager = $em;
458
459
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ItemExtendedTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
460
    }
461
462
463
    /**
464
     * Prevent recursions for Debug (php 5.6+)
465
     * @return array
466
     */
467
    final public function __debugInfo()
468
    {
469
        $info = \get_object_vars($this);
470
        $info[ 'driver' ] = 'object(' . \get_class($info[ 'driver' ]) . ')';
471
472
        return (array)$info;
473
    }
474
}