Passed
Push — v7 ( 0b13ab...4b7cde )
by Georges
01:44
created

ItemExtendedTrait::getUncommittedData()   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\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 \DateTimeInterface
102
     */
103
    public function getExpirationDate(): \DateTimeInterface
104
    {
105
        return $this->expirationDate;
106
    }
107
108
    /**
109
     * Alias of expireAt() with forced $expiration param
110
     *
111
     * @param \DateTimeInterface $expiration
112
     *   The point in time after which the item MUST be considered expired.
113
     *   If null is passed explicitly, a default value MAY be used. If none is set,
114
     *   the value should be stored permanently or for as long as the
115
     *   implementation allows.
116
     *
117
     * @return ExtendedCacheItemInterface
118
     *   The called object.
119
     */
120
    public function setExpirationDate(\DateTimeInterface $expiration): ExtendedCacheItemInterface
121
    {
122
        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

122
        return $this->/** @scrutinizer ignore-call */ expiresAt($expiration);
Loading history...
123
    }
124
125
    /**
126
     * @return \DateTimeInterface
127
     * @throws PhpfastcacheLogicException
128
     */
129
    public function getCreationDate(): \DateTimeInterface
130
    {
131
        if ($this->driver->getConfig()->isItemDetailedDate()) {
132
            return $this->creationDate;
133
        }
134
135
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
136
    }
137
138
    /**
139
     * @param \DateTimeInterface $date
140
     * @return ExtendedCacheItemInterface
141
     * @throws PhpfastcacheLogicException
142
     */
143
    public function setCreationDate(\DateTimeInterface $date): ExtendedCacheItemInterface
144
    {
145
        if ($this->driver->getConfig()->isItemDetailedDate()) {
146
            $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...
147
            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...
148
        }
149
150
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
151
    }
152
153
    /**
154
     * @return \DateTimeInterface
155
     * @throws PhpfastcacheLogicException
156
     */
157
    public function getModificationDate(): \DateTimeInterface
158
    {
159
        if ($this->driver->getConfig()->isItemDetailedDate()) {
160
            return $this->modificationDate;
161
        }
162
163
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
164
    }
165
166
    /**
167
     * @param \DateTimeInterface $date
168
     * @return ExtendedCacheItemInterface
169
     * @throws PhpfastcacheLogicException
170
     */
171
    public function setModificationDate(\DateTimeInterface $date): ExtendedCacheItemInterface
172
    {
173
        if ($this->driver->getConfig()->isItemDetailedDate()) {
174
            $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...
175
            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...
176
        }
177
178
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
179
    }
180
181
    /**
182
     * @return int
183
     */
184
    public function getTtl(): int
185
    {
186
        return max(0, $this->expirationDate->getTimestamp() - \time());
187
    }
188
189
    /**
190
     * @return bool
191
     */
192
    public function isExpired(): bool
193
    {
194
        return $this->expirationDate->getTimestamp() < (new \DateTime())->getTimestamp();
195
    }
196
197
    /**
198
     * @return bool
199
     */
200
    public function isNull(): bool
201
    {
202
        return $this->data === null;
203
    }
204
205
    /**
206
     * @return bool
207
     */
208
    public function isEmpty(): bool
209
    {
210
        return empty($this->data);
211
    }
212
213
    /**
214
     * Return the data length:
215
     * Either the string length if it's a string (binary mode)
216
     * # or the number of element (count) if it's an array
217
     * # or the number returned by count() if it's an object implementing \Countable interface
218
     * # -1 for anything else
219
     * @return int
220
     */
221
    public function getLength(): int
222
    {
223
        switch (\gettype($this->data))
224
        {
225
            case 'array':
226
            case 'object':
227
                if(\is_array($this->data) || $this->data instanceof \Countable){
228
                    return \count($this->data);
229
                }
230
            break;
231
232
            case 'string':
233
                return \strlen($this->data);
234
                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...
235
        }
236
237
        return -1;
238
    }
239
240
241
    /**
242
     * @param int $step
243
     * @return ExtendedCacheItemInterface
244
     * @throws PhpfastcacheInvalidArgumentException
245
     */
246
    public function increment($step = 1): ExtendedCacheItemInterface
247
    {
248
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
249
            $this->fetched = true;
250
            $this->data += $step;
251
        } else {
252
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
253
        }
254
255
        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...
256
    }
257
258
    /**
259
     * @param int $step
260
     * @return ExtendedCacheItemInterface
261
     * @throws PhpfastcacheInvalidArgumentException
262
     */
263
    public function decrement($step = 1): ExtendedCacheItemInterface
264
    {
265
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
266
            $this->fetched = true;
267
            $this->data -= $step;
268
        } else {
269
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
270
        }
271
272
        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...
273
    }
274
275
    /**
276
     * @param array|string $data
277
     * @return ExtendedCacheItemInterface
278
     * @throws PhpfastcacheInvalidArgumentException
279
     */
280
    public function append($data): ExtendedCacheItemInterface
281
    {
282
        if (\is_array($this->data)) {
283
            $this->data[] = $data;
284
        } else if (\is_string($data)) {
285
            $this->data .= (string)$data;
286
        } else {
287
            throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
288
        }
289
290
        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...
291
    }
292
293
294
    /**
295
     * @param array|string $data
296
     * @return ExtendedCacheItemInterface
297
     * @throws PhpfastcacheInvalidArgumentException
298
     */
299
    public function prepend($data): ExtendedCacheItemInterface
300
    {
301
        if (\is_array($this->data)) {
302
            \array_unshift($this->data, $data);
303
        } else if (\is_string($data)) {
304
            $this->data = (string)$data . $this->data;
305
        } else {
306
            throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
307
        }
308
309
        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...
310
    }
311
312
    /**
313
     * @param $tagName
314
     * @return ExtendedCacheItemInterface
315
     * @throws PhpfastcacheInvalidArgumentException
316
     */
317
    public function addTag($tagName): ExtendedCacheItemInterface
318
    {
319
        if (\is_string($tagName)) {
320
            $this->tags = \array_unique(\array_merge($this->tags, [$tagName]));
321
322
            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...
323
        }
324
325
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
326
    }
327
328
    /**
329
     * @param array $tagNames
330
     * @return ExtendedCacheItemInterface
331
     */
332
    public function addTags(array $tagNames): ExtendedCacheItemInterface
333
    {
334
        foreach ($tagNames as $tagName) {
335
            $this->addTag($tagName);
336
        }
337
338
        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...
339
    }
340
341
    /**
342
     * @param array $tags
343
     * @return ExtendedCacheItemInterface
344
     * @throws PhpfastcacheInvalidArgumentException
345
     */
346
    public function setTags(array $tags): ExtendedCacheItemInterface
347
    {
348
        if (\count($tags)) {
349
            if (\array_filter($tags, 'is_string')) {
350
                $this->tags = $tags;
351
            } else {
352
                throw new PhpfastcacheInvalidArgumentException('$tagName must be an array of string');
353
            }
354
        }
355
356
        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...
357
    }
358
359
    /**
360
     * @return array
361
     */
362
    public function getTags(): array
363
    {
364
        return $this->tags;
365
    }
366
367
    /**
368
     * @param string $separator
369
     * @return string
370
     */
371
    public function getTagsAsString($separator = ', '): string
372
    {
373
        return \implode($separator, $this->tags);
374
    }
375
376
    /**
377
     * @param $tagName
378
     * @return ExtendedCacheItemInterface
379
     */
380
    public function removeTag($tagName): ExtendedCacheItemInterface
381
    {
382
        if (($key = array_search($tagName, $this->tags)) !== false) {
383
            unset($this->tags[ $key ]);
384
            $this->removedTags[] = $tagName;
385
        }
386
387
        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...
388
    }
389
390
    /**
391
     * @param array $tagNames
392
     * @return ExtendedCacheItemInterface
393
     */
394
    public function removeTags(array $tagNames): ExtendedCacheItemInterface
395
    {
396
        foreach ($tagNames as $tagName) {
397
            $this->removeTag($tagName);
398
        }
399
400
        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...
401
    }
402
403
    /**
404
     * @return array
405
     */
406
    public function getRemovedTags(): array
407
    {
408
        return \array_diff($this->removedTags, $this->tags);
409
    }
410
411
    /**
412
     * Return the data as a well-formatted string.
413
     * Any scalar value will be casted to an array
414
     * @param int $option \json_encode() options
415
     * @param int $depth \json_encode() depth
416
     * @return string
417
     */
418
    public function getDataAsJsonString($option = 0, $depth = 512): string
419
    {
420
        $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

420
        /** @scrutinizer ignore-call */ 
421
        $data = $this->get();
Loading history...
421
422
        if (\is_object($data) || \is_array($data)) {
423
            $data = \json_encode($data, $option, $depth);
424
        } else {
425
            $data = \json_encode([$data], $option, $depth);
426
        }
427
428
        return \json_encode($data, $option, $depth);
429
    }
430
431
    /**
432
     * Implements \JsonSerializable interface
433
     * @return mixed
434
     */
435
    public function jsonSerialize()
436
    {
437
        return $this->get();
438
    }
439
440
441
    /**
442
     * Set the EventManager instance
443
     *
444
     * @param EventManager $em
445
     * @return ExtendedCacheItemInterface
446
     */
447
    public function setEventManager(EventManager $em): ExtendedCacheItemInterface
448
    {
449
        $this->eventManager = $em;
450
451
        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...
452
    }
453
454
455
    /**
456
     * Prevent recursions for Debug (php 5.6+)
457
     * @return array
458
     */
459
    final public function __debugInfo()
460
    {
461
        $info = \get_object_vars($this);
462
        $info[ 'driver' ] = 'object(' . \get_class($info[ 'driver' ]) . ')';
463
464
        return (array)$info;
465
    }
466
}