Completed
Push — master ( 4e7427...4a94bb )
by Georges
12s
created

ItemExtendedTrait::getLength()   A

Complexity

Conditions 6
Paths 6

Size

Total Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 6
nc 6
nop 0
dl 0
loc 16
rs 9.1111
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]> https://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\Event\EventInterface;
20
use Phpfastcache\Exceptions\{
21
    PhpfastcacheInvalidArgumentException, PhpfastcacheInvalidArgumentTypeException, PhpfastcacheLogicException
22
};
23
24
/**
25
 * Class ItemExtendedTrait
26
 * @package phpFastCache\Core\Item
27
 * @property \DateTimeInterface $expirationDate Expiration date of the item
28
 * @property \DateTimeInterface $creationDate Creation date of the item
29
 * @property \DateTimeInterface $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 EventInterface
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->getConfig()->isItemDetailedDate()) {
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->getConfig()->getDefaultKeyHashFunction();
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;
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;
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
            case 'array':
225
            case 'object':
226
                if (\is_array($this->data) || $this->data instanceof \Countable) {
227
                    return \count($this->data);
228
                }
229
                break;
230
231
            case 'string':
232
                return \strlen($this->data);
233
                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...
234
        }
235
236
        return -1;
237
    }
238
239
240
    /**
241
     * @param int $step
242
     * @return ExtendedCacheItemInterface
243
     * @throws PhpfastcacheInvalidArgumentException
244
     */
245
    public function increment($step = 1): ExtendedCacheItemInterface
246
    {
247
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
248
            $this->fetched = true;
249
            $this->data += $step;
250
        } else {
251
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
252
        }
253
254
        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...
255
    }
256
257
    /**
258
     * @param int $step
259
     * @return ExtendedCacheItemInterface
260
     * @throws PhpfastcacheInvalidArgumentException
261
     */
262
    public function decrement($step = 1): ExtendedCacheItemInterface
263
    {
264
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
265
            $this->fetched = true;
266
            $this->data -= $step;
267
        } else {
268
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
269
        }
270
271
        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...
272
    }
273
274
    /**
275
     * @param array|string $data
276
     * @return ExtendedCacheItemInterface
277
     * @throws PhpfastcacheInvalidArgumentException
278
     */
279
    public function append($data): ExtendedCacheItemInterface
280
    {
281
        if (\is_array($this->data)) {
282
            $this->data[] = $data;
283
        } else {
284
            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
291
        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...
292
    }
293
294
295
    /**
296
     * @param array|string $data
297
     * @return ExtendedCacheItemInterface
298
     * @throws PhpfastcacheInvalidArgumentException
299
     */
300
    public function prepend($data): ExtendedCacheItemInterface
301
    {
302
        if (\is_array($this->data)) {
303
            \array_unshift($this->data, $data);
304
        } else {
305
            if (\is_string($data)) {
306
                $this->data = (string)$data . $this->data;
307
            } else {
308
                throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
309
            }
310
        }
311
312
        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...
313
    }
314
315
    /**
316
     * @param $tagName
317
     * @return ExtendedCacheItemInterface
318
     * @throws PhpfastcacheInvalidArgumentException
319
     */
320
    public function addTag($tagName): ExtendedCacheItemInterface
321
    {
322
        if (\is_string($tagName)) {
323
            $this->tags = \array_unique(\array_merge($this->tags, [$tagName]));
324
325
            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...
326
        }
327
328
        throw new PhpfastcacheInvalidArgumentException('$tagName must be a string');
329
    }
330
331
    /**
332
     * @param array $tagNames
333
     * @return ExtendedCacheItemInterface
334
     */
335
    public function addTags(array $tagNames): ExtendedCacheItemInterface
336
    {
337
        foreach ($tagNames as $tagName) {
338
            $this->addTag($tagName);
339
        }
340
341
        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...
342
    }
343
344
    /**
345
     * @param array $tags
346
     * @return ExtendedCacheItemInterface
347
     * @throws PhpfastcacheInvalidArgumentException
348
     */
349
    public function setTags(array $tags): ExtendedCacheItemInterface
350
    {
351
        if (\count($tags)) {
352
            if (\array_filter($tags, 'is_string')) {
353
                $this->tags = $tags;
354
            } else {
355
                throw new PhpfastcacheInvalidArgumentException('$tagName must be an array of string');
356
            }
357
        }
358
359
        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...
360
    }
361
362
    /**
363
     * @return array
364
     */
365
    public function getTags(): array
366
    {
367
        return $this->tags;
368
    }
369
370
    /**
371
     * @param string $separator
372
     * @return string
373
     */
374
    public function getTagsAsString($separator = ', '): string
375
    {
376
        return \implode($separator, $this->tags);
377
    }
378
379
    /**
380
     * @param $tagName
381
     * @return ExtendedCacheItemInterface
382
     */
383
    public function removeTag($tagName): ExtendedCacheItemInterface
384
    {
385
        if (($key = \array_search($tagName, $this->tags)) !== false) {
386
            unset($this->tags[$key]);
387
            $this->removedTags[] = $tagName;
388
        }
389
390
        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...
391
    }
392
393
    /**
394
     * @param array $tagNames
395
     * @return ExtendedCacheItemInterface
396
     */
397
    public function removeTags(array $tagNames): ExtendedCacheItemInterface
398
    {
399
        foreach ($tagNames as $tagName) {
400
            $this->removeTag($tagName);
401
        }
402
403
        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...
404
    }
405
406
    /**
407
     * @return array
408
     */
409
    public function getRemovedTags(): array
410
    {
411
        return \array_diff($this->removedTags, $this->tags);
412
    }
413
414
    /**
415
     * Return the data as a well-formatted string.
416
     * Any scalar value will be casted to an array
417
     * @param int $option \json_encode() options
418
     * @param int $depth \json_encode() depth
419
     * @return string
420
     */
421
    public function getDataAsJsonString($option = 0, $depth = 512): string
422
    {
423
        $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

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