Completed
Push — master ( be9660...707803 )
by Georges
16s queued 13s
created

ItemExtendedTrait   A

Complexity

Total Complexity 42

Size/Duplication

Total Lines 327
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 91
c 2
b 0
f 0
dl 0
loc 327
rs 9.0399
wmc 42

21 Methods

Rating   Name   Duplication   Size   Complexity  
A prepend() 0 13 3
A setExpirationDate() 0 3 1
A jsonSerialize() 0 3 1
A setModificationDate() 0 8 2
A isExpired() 0 3 1
A getExpirationDate() 0 3 1
A getTtl() 0 3 1
A setCreationDate() 0 8 2
A getModificationDate() 0 7 2
A __debugInfo() 0 6 1
A getCreationDate() 0 7 2
A __construct() 0 13 3
A isNull() 0 3 1
A doesItemBelongToThatDriverBackend() 0 3 1
A append() 0 13 3
A isEmpty() 0 3 1
A decrement() 0 10 2
A increment() 0 10 2
A getEncodedKey() 0 13 3
A getLength() 0 16 6
A getDataAsJsonString() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like ItemExtendedTrait 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.

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 ItemExtendedTrait, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 *
5
 * This file is part of phpFastCache.
6
 *
7
 * @license MIT License (MIT)
8
 *
9
 * For full copyright and license information, please see the docs/CREDITS.txt file.
10
 *
11
 * @author Khoa Bui (khoaofgod)  <[email protected]> https://www.phpfastcache.com
12
 * @author Georges.L (Geolim4)  <[email protected]>
13
 *
14
 */
15
declare(strict_types=1);
16
17
namespace Phpfastcache\Core\Item;
18
19
use Countable;
20
use DateTime;
21
use DateTimeInterface;
22
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
23
use Phpfastcache\Exceptions\{PhpfastcacheInvalidArgumentException, PhpfastcacheInvalidArgumentTypeException, PhpfastcacheLogicException};
24
use Phpfastcache\Util\ClassNamespaceResolverTrait;
25
26
27
/**
28
 * Class ItemExtendedTrait
29
 * @package phpFastCache\Core\Item
30
 * @property DateTimeInterface $expirationDate Expiration date of the item
31
 * @property DateTimeInterface $creationDate Creation date of the item
32
 * @property DateTimeInterface $modificationDate Modification date of the item
33
 * @property mixed $data Data of the item
34
 * @property bool $fetched Fetch flag status
35
 * @property string $key The item key
36
 */
37
trait ItemExtendedTrait
38
{
39
    use ClassNamespaceResolverTrait;
40
    use TaggableCacheItemTrait;
41
42
    /********************
43
     *
44
     * PSR-6 Extended Methods
45
     *
46
     *******************/
47
48
    /**
49
     * @var ExtendedCacheItemPoolInterface
50
     */
51
    protected $driver;
52
53
    /**
54
     * @var string
55
     */
56
    protected $encodedKey;
57
58
    /**
59
     * Item constructor.
60
     * @param ExtendedCacheItemPoolInterface $driver
61
     * @param $key
62
     * @throws PhpfastcacheInvalidArgumentException
63
     */
64
    public function __construct(ExtendedCacheItemPoolInterface $driver, $key)
65
    {
66
        if (\is_string($key)) {
67
            $this->key = $key;
68
            $this->driver = $driver;
69
            $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

69
            $this->driver->setItem(/** @scrutinizer ignore-type */ $this);
Loading history...
70
            $this->expirationDate = new DateTime();
71
            if ($this->driver->getConfig()->isItemDetailedDate()) {
72
                $this->creationDate = new DateTime();
73
                $this->modificationDate = new DateTime();
74
            }
75
        } else {
76
            throw new PhpfastcacheInvalidArgumentTypeException('string', $key);
77
        }
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getEncodedKey(): string
84
    {
85
        if (!$this->encodedKey) {
86
            $keyHashFunction = $this->driver->getConfig()->getDefaultKeyHashFunction();
87
88
            if ($keyHashFunction) {
89
                $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

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

120
        return $this->/** @scrutinizer ignore-call */ expiresAt($expiration);
Loading history...
121
    }
122
123
    /**
124
     * @return DateTimeInterface
125
     * @throws PhpfastcacheLogicException
126
     */
127
    public function getCreationDate(): DateTimeInterface
128
    {
129
        if ($this->driver->getConfig()->isItemDetailedDate()) {
130
            return $this->creationDate;
131
        }
132
133
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
134
    }
135
136
    /**
137
     * @param DateTimeInterface $date
138
     * @return ExtendedCacheItemInterface
139
     * @throws PhpfastcacheLogicException
140
     */
141
    public function setCreationDate(DateTimeInterface $date): ExtendedCacheItemInterface
142
    {
143
        if ($this->driver->getConfig()->isItemDetailedDate()) {
144
            $this->creationDate = $date;
145
            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...
146
        }
147
148
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
149
    }
150
151
    /**
152
     * @return DateTimeInterface
153
     * @throws PhpfastcacheLogicException
154
     */
155
    public function getModificationDate(): DateTimeInterface
156
    {
157
        if ($this->driver->getConfig()->isItemDetailedDate()) {
158
            return $this->modificationDate;
159
        }
160
161
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
162
    }
163
164
    /**
165
     * @param DateTimeInterface $date
166
     * @return ExtendedCacheItemInterface
167
     * @throws PhpfastcacheLogicException
168
     */
169
    public function setModificationDate(DateTimeInterface $date): ExtendedCacheItemInterface
170
    {
171
        if ($this->driver->getConfig()->isItemDetailedDate()) {
172
            $this->modificationDate = $date;
173
            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...
174
        }
175
176
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
177
    }
178
179
    /**
180
     * @return int
181
     */
182
    public function getTtl(): int
183
    {
184
        return \max(0, $this->expirationDate->getTimestamp() - \time());
185
    }
186
187
    /**
188
     * @return bool
189
     */
190
    public function isExpired(): bool
191
    {
192
        return $this->expirationDate->getTimestamp() < (new DateTime())->getTimestamp();
193
    }
194
195
    /**
196
     * @return bool
197
     */
198
    public function isNull(): bool
199
    {
200
        return $this->data === null;
201
    }
202
203
    /**
204
     * @return bool
205
     */
206
    public function isEmpty(): bool
207
    {
208
        return empty($this->data);
209
    }
210
211
    /**
212
     * Return the data length:
213
     * Either the string length if it's a string (binary mode)
214
     * # or the number of element (count) if it's an array
215
     * # or the number returned by count() if it's an object implementing \Countable interface
216
     * # -1 for anything else
217
     * @return int
218
     */
219
    public function getLength(): int
220
    {
221
        switch (\gettype($this->data)) {
222
            case 'array':
223
            case 'object':
224
                if (\is_array($this->data) || $this->data instanceof Countable) {
225
                    return \count($this->data);
226
                }
227
                break;
228
229
            case 'string':
230
                return \strlen($this->data);
231
                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...
232
        }
233
234
        return -1;
235
    }
236
237
238
    /**
239
     * @param int $step
240
     * @return ExtendedCacheItemInterface
241
     * @throws PhpfastcacheInvalidArgumentException
242
     */
243
    public function increment($step = 1): ExtendedCacheItemInterface
244
    {
245
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
246
            $this->fetched = true;
247
            $this->data += $step;
248
        } else {
249
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
250
        }
251
252
        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...
253
    }
254
255
    /**
256
     * @param int $step
257
     * @return ExtendedCacheItemInterface
258
     * @throws PhpfastcacheInvalidArgumentException
259
     */
260
    public function decrement($step = 1): ExtendedCacheItemInterface
261
    {
262
        if (\is_int($step)) {
0 ignored issues
show
introduced by
The condition is_int($step) is always true.
Loading history...
263
            $this->fetched = true;
264
            $this->data -= $step;
265
        } else {
266
            throw new PhpfastcacheInvalidArgumentException('$step must be numeric.');
267
        }
268
269
        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...
270
    }
271
272
    /**
273
     * @param array|string $data
274
     * @return ExtendedCacheItemInterface
275
     * @throws PhpfastcacheInvalidArgumentException
276
     */
277
    public function append($data): ExtendedCacheItemInterface
278
    {
279
        if (\is_array($this->data)) {
280
            $this->data[] = $data;
281
        } else {
282
            if (\is_string($data)) {
283
                $this->data .= (string)$data;
284
            } else {
285
                throw new PhpfastcacheInvalidArgumentException('$data must be either array nor string.');
286
            }
287
        }
288
289
        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...
290
    }
291
292
293
    /**
294
     * @param array|string $data
295
     * @return ExtendedCacheItemInterface
296
     * @throws PhpfastcacheInvalidArgumentException
297
     */
298
    public function prepend($data): ExtendedCacheItemInterface
299
    {
300
        if (\is_array($this->data)) {
301
            \array_unshift($this->data, $data);
302
        } else {
303
            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
310
        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...
311
    }
312
313
    /**
314
     * Return the data as a well-formatted string.
315
     * Any scalar value will be casted to an array
316
     * @param int $option \json_encode() options
317
     * @param int $depth \json_encode() depth
318
     * @return string
319
     */
320
    public function getDataAsJsonString(int $option = 0, int $depth = 512): string
321
    {
322
        $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

322
        /** @scrutinizer ignore-call */ 
323
        $data = $this->get();
Loading history...
323
324
        if (\is_object($data) || \is_array($data)) {
325
            $data = \json_encode($data, $option, $depth);
326
        } else {
327
            $data = \json_encode([$data], $option, $depth);
328
        }
329
330
        return \json_encode($data, $option, $depth);
331
    }
332
333
    /**
334
     * Implements \JsonSerializable interface
335
     * @return mixed
336
     */
337
    public function jsonSerialize()
338
    {
339
        return $this->get();
340
    }
341
342
    /**
343
     * @param ExtendedCacheItemPoolInterface $driverPool
344
     * @return bool
345
     * @throws PhpfastcacheInvalidArgumentException
346
     */
347
    public function doesItemBelongToThatDriverBackend(ExtendedCacheItemPoolInterface $driverPool): bool
348
    {
349
        return $driverPool->getClassNamespace() === $this->getClassNamespace();
350
    }
351
352
    /**
353
     * @return array
354
     * @todo Is it still useful ??
355
     *
356
     * Prevent recursions for Debug (php 5.6+)
357
     */
358
    final public function __debugInfo()
359
    {
360
        $info = \get_object_vars($this);
361
        $info['driver'] = 'object(' . \get_class($info['driver']) . ')';
362
363
        return $info;
364
    }
365
}
366