Passed
Pull Request — master (#755)
by Georges
01:36
created

ItemExtendedTrait   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 329
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 92
dl 0
loc 329
rs 8.96
c 2
b 0
f 0
wmc 43

21 Methods

Rating   Name   Duplication   Size   Complexity  
A setExpirationDate() 0 3 1
A isExpired() 0 3 1
A getTtl() 0 3 1
A isNull() 0 3 1
A isEmpty() 0 3 1
A prepend() 0 13 3
A setModificationDate() 0 8 2
A getModificationDate() 0 7 2
A setCreationDate() 0 8 2
A getCreationDate() 0 7 2
A append() 0 13 3
A decrement() 0 10 2
A increment() 0 10 2
A getEncodedKey() 0 13 3
A getLength() 0 16 6
A getExpirationDate() 0 3 1
A jsonSerialize() 0 3 1
A __debugInfo() 0 6 1
A __construct() 0 15 4
A doesItemBelongToThatDriverBackend() 0 3 1
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
            if($driver->getConfig()->isUseStaticItemCaching()){
70
                $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

70
                $this->driver->setItem(/** @scrutinizer ignore-type */ $this);
Loading history...
71
            }
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
     * Return the data as a well-formatted string.
317
     * Any scalar value will be casted to an array
318
     * @param int $option \json_encode() options
319
     * @param int $depth \json_encode() depth
320
     * @return string
321
     */
322
    public function getDataAsJsonString(int $option = 0, int $depth = 512): string
323
    {
324
        $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

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