Completed
Push — master ( 95226d...bcd068 )
by Georges
15s queued 12s
created

ExtendedCacheItemTrait   B

Complexity

Total Complexity 51

Size/Duplication

Total Lines 305
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 95
dl 0
loc 305
rs 7.92
c 0
b 0
f 0
wmc 51

23 Methods

Rating   Name   Duplication   Size   Complexity  
A getTtl() 0 3 1
A isEmpty() 0 3 1
A getLength() 0 15 5
A isNull() 0 3 1
A isExpired() 0 3 1
A setModificationDate() 0 8 2
A getEncodedKey() 0 14 3
A __construct() 0 13 3
A setDriver() 0 10 2
A cloneInto() 0 12 2
A jsonSerialize() 0 3 1
A append() 0 13 5
A increment() 0 9 3
A doesItemBelongToThatDriverBackend() 0 3 1
A getRawValue() 0 3 1
A getExpirationDate() 0 3 1
A getCreationDate() 0 7 2
A setCreationDate() 0 8 2
A getModificationDate() 0 7 2
A setExpirationDate() 0 3 1
A prepend() 0 13 5
A decrement() 0 9 3
A getDataAsJsonString() 0 11 3

How to fix   Complexity   

Complex Class

Complex classes like ExtendedCacheItemTrait 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 ExtendedCacheItemTrait, 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 and LICENCE files.
10
 *
11
 * @author Georges.L (Geolim4)  <[email protected]>
12
 * @author Contributors  https://github.com/PHPSocialNetwork/phpfastcache/graphs/contributors
13
 */
14
declare(strict_types=1);
15
16
namespace Phpfastcache\Core\Item;
17
18
use DateTime;
19
use DateTimeInterface;
20
use Phpfastcache\Core\Pool\ExtendedCacheItemPoolInterface;
21
use Phpfastcache\Event\EventManagerInterface;
22
use Phpfastcache\Exceptions\PhpfastcacheInvalidArgumentException;
23
use Phpfastcache\Exceptions\PhpfastcacheInvalidTypeException;
24
use Phpfastcache\Exceptions\PhpfastcacheLogicException;
25
26
trait ExtendedCacheItemTrait
27
{
28
    use CacheItemTrait;
29
30
    protected ExtendedCacheItemPoolInterface $driver;
31
32
    protected string $encodedKey;
33
34
    /**
35
     * Item constructor.
36
     * @param ExtendedCacheItemPoolInterface $driver
37
     * @param string $key
38
     * @param EventManagerInterface $em
39
     * @throws PhpfastcacheInvalidArgumentException
40
     */
41
    public function __construct(ExtendedCacheItemPoolInterface $driver, string $key, EventManagerInterface $em)
42
    {
43
        $this->data = null;
44
        $this->key = $key;
45
        $this->setEventManager($em);
46
        $this->setDriver($driver);
47
        if ($driver->getConfig()->isUseStaticItemCaching()) {
48
            $this->driver->setItem($this);
1 ignored issue
show
Bug introduced by
$this of type Phpfastcache\Core\Item\ExtendedCacheItemTrait 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

48
            $this->driver->setItem(/** @scrutinizer ignore-type */ $this);
Loading history...
49
        }
50
        $this->expirationDate = new DateTime();
51
        if ($this->driver->getConfig()->isItemDetailedDate()) {
52
            $this->creationDate = new DateTime();
53
            $this->modificationDate = new DateTime();
54
        }
55
    }
56
57
    /**
58
     * @param ExtendedCacheItemPoolInterface $driver
59
     * @return ExtendedCacheItemInterface
60
     * @throws PhpfastcacheInvalidArgumentException
61
     */
62
    public function setDriver(ExtendedCacheItemPoolInterface $driver): ExtendedCacheItemInterface
63
    {
64
        $driverClass = $this->getDriverClass();
65
        if ($driver instanceof $driverClass) {
66
            $this->driver = $driver;
67
68
            return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
69
        }
70
71
        throw new PhpfastcacheInvalidArgumentException(\sprintf('Invalid driver instance "%s" for cache item "%s"', $driver::class, static::class));
72
    }
73
74
    /**
75
     * @inheritDoc
76
     */
77
    public function getEncodedKey(): string
78
    {
79
        // Only calculate the encoded key on demand to save resources
80
        if (!isset($this->encodedKey)) {
81
            $keyHashFunction = $this->driver->getConfig()->getDefaultKeyHashFunction();
82
83
            if ($keyHashFunction) {
84
                $this->encodedKey = $keyHashFunction($this->getKey());
85
            } else {
86
                $this->encodedKey = $this->getKey();
87
            }
88
        }
89
90
        return $this->encodedKey;
91
    }
92
93
    /**
94
     * @inheritDoc
95
     */
96
    public function getRawValue(): mixed
97
    {
98
        return $this->data;
99
    }
100
101
    /**
102
     * @inheritDoc
103
     */
104
    public function getExpirationDate(): DateTimeInterface
105
    {
106
        return $this->expirationDate;
107
    }
108
109
    /**
110
     * @inheritDoc
111
     * @throws PhpfastcacheInvalidArgumentException
112
     */
113
    public function setExpirationDate(DateTimeInterface $expiration): ExtendedCacheItemInterface
114
    {
115
        return $this->expiresAt($expiration);
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this->expiresAt($expiration) returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
116
    }
117
118
    /**
119
     * @inheritDoc
120
     * @throws PhpfastcacheLogicException
121
     */
122
    public function getCreationDate(): DateTimeInterface
123
    {
124
        if ($this->driver->getConfig()->isItemDetailedDate()) {
125
            return $this->creationDate;
126
        }
127
128
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
129
    }
130
131
    /**
132
     * @inheritDoc
133
     * @throws PhpfastcacheLogicException
134
     */
135
    public function setCreationDate(DateTimeInterface $date): ExtendedCacheItemInterface
136
    {
137
        if ($this->driver->getConfig()->isItemDetailedDate()) {
138
            $this->creationDate = $date;
139
            return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
140
        }
141
142
        throw new PhpfastcacheLogicException('Cannot access to the creation date when the "itemDetailedDate" configuration is disabled.');
143
    }
144
145
    /**
146
     * @inheritDoc
147
     * @throws PhpfastcacheLogicException
148
     */
149
    public function getModificationDate(): DateTimeInterface
150
    {
151
        if ($this->driver->getConfig()->isItemDetailedDate()) {
152
            return $this->modificationDate;
153
        }
154
155
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
156
    }
157
158
    /**
159
     * @inheritDoc
160
     * @throws PhpfastcacheLogicException
161
     */
162
    public function setModificationDate(DateTimeInterface $date): ExtendedCacheItemInterface
163
    {
164
        if ($this->driver->getConfig()->isItemDetailedDate()) {
165
            $this->modificationDate = $date;
166
            return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
167
        }
168
169
        throw new PhpfastcacheLogicException('Cannot access to the modification date when the "itemDetailedDate" configuration is disabled.');
170
    }
171
172
    public function getTtl(): int
173
    {
174
        return \max(0, $this->expirationDate->getTimestamp() - \time());
175
    }
176
177
    public function isExpired(): bool
178
    {
179
        return $this->expirationDate->getTimestamp() < (new DateTime())->getTimestamp();
180
    }
181
182
    public function isNull(): bool
183
    {
184
        return $this->get() === null;
185
    }
186
187
    public function isEmpty(): bool
188
    {
189
        return empty($this->get());
190
    }
191
192
    /**
193
     * Return the data length:
194
     * Either the string length if it's a string (binary mode)
195
     * # or the number of element (count) if it's an array
196
     * # or the number returned by count() if it's an object implementing \Countable interface
197
     * # -1 for anything else
198
     * @return int
199
     */
200
    public function getLength(): int
201
    {
202
        switch (\gettype($this->data)) {
203
            case 'array':
204
            case 'object':
205
                if (\is_countable($this->data)) {
206
                    return \count($this->data);
207
                }
208
                break;
209
210
            case 'string':
211
                return \strlen($this->data);
212
        }
213
214
        return -1;
215
    }
216
217
    /**
218
     * @throws PhpfastcacheInvalidTypeException
219
     */
220
    public function increment(int $step = 1): ExtendedCacheItemInterface
221
    {
222
        if ($this->data !== null && !\is_numeric($this->data)) {
223
            throw new PhpfastcacheInvalidTypeException(\sprintf('Cannot increment on a "%s" type.', \gettype($this->data)));
224
        }
225
226
        $this->data += $step;
227
228
        return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
229
    }
230
231
    /**
232
     * @throws PhpfastcacheInvalidTypeException
233
     */
234
    public function decrement(int $step = 1): ExtendedCacheItemInterface
235
    {
236
        if ($this->data !== null && !\is_numeric($this->data)) {
237
            throw new PhpfastcacheInvalidTypeException(\sprintf('Cannot decrement on a "%s" type.', \gettype($this->data)));
238
        }
239
240
        $this->data -= $step;
241
242
        return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
243
    }
244
245
    /**
246
     * @throws PhpfastcacheInvalidTypeException
247
     */
248
    public function append(array|string $data): ExtendedCacheItemInterface
249
    {
250
        if ($this->data !== null && !\is_string($this->data) && !\is_array($this->data)) {
251
            throw new PhpfastcacheInvalidTypeException(\sprintf('Cannot append on a "%s" type.', \gettype($this->data)));
252
        }
253
254
        if (\is_array($this->data)) {
255
            $this->data[] = $data;
256
        } else {
257
            $this->data .= $data;
258
        }
259
260
        return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
261
    }
262
263
    /**
264
     * @throws PhpfastcacheInvalidTypeException
265
     */
266
    public function prepend(array|string $data): ExtendedCacheItemInterface
267
    {
268
        if ($this->data !== null && !\is_string($this->data) && !\is_array($this->data)) {
269
            throw new PhpfastcacheInvalidTypeException(\sprintf('Cannot prepend on a "%s" type.', \gettype($this->data)));
270
        }
271
272
        if (\is_array($this->data)) {
273
            \array_unshift($this->data, $data);
274
        } else {
275
            $this->data = $data . $this->data;
1 ignored issue
show
Bug introduced by
Are you sure $data of type array can be used in concatenation? ( Ignorable by Annotation )

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

275
            $this->data = /** @scrutinizer ignore-type */ $data . $this->data;
Loading history...
276
        }
277
278
        return $this;
1 ignored issue
show
Bug Best Practice introduced by
The expression return $this returns the type Phpfastcache\Core\Item\ExtendedCacheItemTrait which is incompatible with the type-hinted return Phpfastcache\Core\Item\ExtendedCacheItemInterface.
Loading history...
279
    }
280
281
    /**
282
     * Return the data as a well-formatted string.
283
     * Any scalar value will be casted to an array
284
     * @param int $options \json_encode() options
285
     * @param int $depth \json_encode() depth
286
     * @return string
287
     */
288
    public function getDataAsJsonString(int $options = JSON_THROW_ON_ERROR, int $depth = 512): string
289
    {
290
        $data = $this->get();
291
292
        if (\is_object($data) || \is_array($data)) {
293
            $data = \json_encode($data, $options, $depth);
294
        } else {
295
            $data = \json_encode([$data], $options, $depth);
296
        }
297
298
        return \json_encode($data, $options, $depth);
299
    }
300
301
    public function jsonSerialize(): mixed
302
    {
303
        return $this->get();
304
    }
305
306
    public function doesItemBelongToThatDriverBackend(ExtendedCacheItemPoolInterface $driverPool): bool
307
    {
308
        return $driverPool::getClassNamespace() === self::getClassNamespace();
309
    }
310
311
    /**
312
     * @throws PhpfastcacheLogicException
313
     * @throws PhpfastcacheInvalidArgumentException
314
     */
315
    public function cloneInto(ExtendedCacheItemInterface $itemTarget, ?ExtendedCacheItemPoolInterface $itemPoolTarget = null): void
316
    {
317
        $itemTarget->setEventManager($this->getEventManager())
318
            ->set($this->getRawValue())
319
            ->setHit($this->isHit())
320
            ->setTags($this->getTags())
0 ignored issues
show
Bug introduced by
It seems like getTags() 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

320
            ->setTags($this->/** @scrutinizer ignore-call */ getTags())
Loading history...
321
            ->expiresAt($this->getExpirationDate())
322
            ->setDriver($itemPoolTarget ?? $this->driver);
323
324
        if ($this->driver->getConfig()->isItemDetailedDate()) {
325
            $itemTarget->setCreationDate($this->getCreationDate())
326
                ->setModificationDate($this->getModificationDate());
327
        }
328
    }
329
330
    abstract protected function getDriverClass(): string;
331
}
332