Completed
Push — V6 ( 0098cc...760f65 )
by Georges
02:58
created

CacheItemPoolTrait::deleteItem()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 25
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 25
rs 8.8571
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
15
namespace phpFastCache\Core\Pool;
16
17
use phpFastCache\Core\Item\ExtendedCacheItemInterface;
18
use phpFastCache\CacheManager;
19
use phpFastCache\EventManager;
20
use phpFastCache\Exceptions\phpFastCacheCoreException;
21
use Psr\Cache\CacheItemInterface;
22
use phpFastCache\Util\ClassNamespaceResolverTrait;
23
24
/**
25
 * Trait StandardPsr6StructureTrait
26
 * @package phpFastCache\Core
27
 *
28
 */
29
trait CacheItemPoolTrait
30
{
31
    use ClassNamespaceResolverTrait;
32
33
    /**
34
     * @var array
35
     */
36
    protected $deferredList = [];
37
38
    /**
39
     * @var ExtendedCacheItemInterface[]
40
     */
41
    protected $itemInstances = [];
42
43
    /**
44
     * @var EventManager
45
     */
46
    protected $eventManager;
47
48
    /**
49
     * @param string $key
50
     * @return \phpFastCache\Core\Item\ExtendedCacheItemInterface
51
     * @throws \InvalidArgumentException
52
     * @throws \LogicException
53
     * @throws phpFastCacheCoreException
54
     */
55
    public function getItem($key)
56
    {
57
        if (is_string($key)) {
58
            if (!array_key_exists($key, $this->itemInstances)) {
59
60
                /**
61
                 * @var $item ExtendedCacheItemInterface
62
                 */
63
                CacheManager::$ReadHits++;
64
                $class = new \ReflectionClass((new \ReflectionObject($this))->getNamespaceName() . '\Item');
65
                $item = $class->newInstanceArgs([$this, $key]);
66
                $item->setEventManager($this->eventManager);
67
                $driverArray = $this->driverRead($item);
68
69
                if ($driverArray) {
70
                    if(!is_array($driverArray)){
71
                        throw new phpFastCacheCoreException(sprintf('The driverRead method returned an unexpected variable type: %s', gettype($driverArray)));
72
                    }
73
                    $item->set($this->driverUnwrapData($driverArray));
74
                    $item->expiresAt($this->driverUnwrapEdate($driverArray));
75
76
                    if($this->config['itemDetailedDate']){
0 ignored issues
show
Bug introduced by
The property config does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
77
78
                        /**
79
                         * If the itemDetailedDate has been
80
                         * set after caching, we MUST inject
81
                         * a new DateTime object on the fly
82
                         */
83
                        $item->setCreationDate($this->driverUnwrapCdate($driverArray) ?: new \DateTime());
84
                        $item->setModificationDate($this->driverUnwrapMdate($driverArray) ?: new \DateTime());
85
                    }
86
87
                    $item->setTags($this->driverUnwrapTags($driverArray));
88
                    if ($item->isExpired()) {
89
                        /**
90
                         * Using driverDelete() instead of delete()
91
                         * to avoid infinite loop caused by
92
                         * getItem() call in delete() method
93
                         * As we MUST return an item in any
94
                         * way, we do not de-register here
95
                         */
96
                        $this->driverDelete($item);
97
                    } else {
98
                        $item->setHit(true);
99
                    }
100
                }else{
101
                    $item->expiresAfter(abs((int) $this->getConfig()[ 'defaultTtl' ]));
102
                }
103
104
            }
105
        } else {
106
            throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
107
        }
108
109
        /**
110
         * @eventName CacheGetItem
111
         * @param $this ExtendedCacheItemPoolInterface
112
         * @param $this ExtendedCacheItemInterface
113
         */
114
        $this->eventManager->dispatch('CacheGetItem', $this, $this->itemInstances[ $key ]);
115
116
        return $this->itemInstances[ $key ];
117
    }
118
119
    /**
120
     * @param \Psr\Cache\CacheItemInterface $item
121
     * @return $this
122
     * @throws \InvalidArgumentException
123
     */
124
    public function setItem(CacheItemInterface $item)
125
    {
126
        if ($this->getClassNamespace() . '\\Item' === get_class($item)) {
127
            $this->itemInstances[ $item->getKey() ] = $item;
128
129
            return $this;
130
        } else {
131
            throw new \InvalidArgumentException(sprintf('Invalid Item Class "%s" for this driver.', get_class($item)));
132
        }
133
    }
134
135
    /**
136
     * @param array $keys
137
     * @return CacheItemInterface[]
138
     * @throws \InvalidArgumentException
139
     */
140
    public function getItems(array $keys = [])
141
    {
142
        $collection = [];
143
        foreach ($keys as $key) {
144
            $collection[ $key ] = $this->getItem($key);
145
        }
146
147
        return $collection;
148
    }
149
150
    /**
151
     * @param string $key
152
     * @return bool
153
     * @throws \InvalidArgumentException
154
     */
155
    public function hasItem($key)
156
    {
157
        CacheManager::$ReadHits++;
158
159
        return $this->getItem($key)->isHit();
160
    }
161
162
    /**
163
     * @return bool
164
     */
165
    public function clear()
166
    {
167
        /**
168
         * @eventName CacheClearItem
169
         * @param $this ExtendedCacheItemPoolInterface
170
         * @param $deferredList ExtendedCacheItemInterface[]
171
         */
172
        $this->eventManager->dispatch('CacheClearItem', $this, $this->itemInstances);
173
174
        CacheManager::$WriteHits++;
175
        $this->itemInstances = [];
176
177
        return $this->driverClear();
178
    }
179
180
    /**
181
     * @param string $key
182
     * @return bool
183
     * @throws \InvalidArgumentException
184
     */
185
    public function deleteItem($key)
186
    {
187
        $item = $this->getItem($key);
188
        if ($this->hasItem($key) && $this->driverDelete($item)) {
189
            $item->setHit(false);
190
            CacheManager::$WriteHits++;
191
192
            /**
193
             * @eventName CacheCommitItem
194
             * @param $this ExtendedCacheItemPoolInterface
195
             * @param $item ExtendedCacheItemInterface
196
             */
197
            $this->eventManager->dispatch('CacheDeleteItem', $this, $item);
198
199
            /**
200
             * De-register the item instance
201
             * then collect gc cycles
202
             */
203
            $this->deregisterItem($key);
204
205
            return true;
206
        }
207
208
        return false;
209
    }
210
211
    /**
212
     * @param array $keys
213
     * @return bool
214
     * @throws \InvalidArgumentException
215
     */
216
    public function deleteItems(array $keys)
217
    {
218
        $return = null;
219
        foreach ($keys as $key) {
220
            $result = $this->deleteItem($key);
221
            if ($result !== false) {
222
                $return = $result;
223
            }
224
        }
225
226
        return (bool) $return;
227
    }
228
229
    /**
230
     * @param \Psr\Cache\CacheItemInterface $item
231
     * @return mixed
232
     * @throws \InvalidArgumentException
233
     * @throws \RuntimeException
234
     */
235
    public function save(CacheItemInterface $item)
236
    {
237
        /**
238
         * @var ExtendedCacheItemInterface $item
239
         */
240 View Code Duplication
        if (!array_key_exists($item->getKey(), $this->itemInstances)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
241
            $this->itemInstances[ $item->getKey() ] = $item;
242
        } else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
243
            throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
244
        }
245
246
        /**
247
         * @eventName CacheSaveItem
248
         * @param $this ExtendedCacheItemPoolInterface
249
         * @param $this ExtendedCacheItemInterface
250
         */
251
        $this->eventManager->dispatch('CacheSaveItem', $this, $item);
252
253
        if ($this->driverWrite($item) && $this->driverWriteTags($item)) {
254
            $item->setHit(true);
255
            CacheManager::$WriteHits++;
256
257
            return true;
258
        }
259
260
        return false;
261
    }
262
263
264
    /**
265
     * @param \Psr\Cache\CacheItemInterface $item
266
     * @return \Psr\Cache\CacheItemInterface
267
     * @throws \RuntimeException
268
     */
269
    public function saveDeferred(CacheItemInterface $item)
270
    {
271 View Code Duplication
        if (!array_key_exists($item->getKey(), $this->itemInstances)) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
272
            $this->itemInstances[ $item->getKey() ] = $item;
273
        }else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
274
            throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
275
        }
276
277
        /**
278
         * @eventName CacheSaveDeferredItem
279
         * @param $this ExtendedCacheItemPoolInterface
280
         * @param $this ExtendedCacheItemInterface
281
         */
282
        $this->eventManager->dispatch('CacheSaveDeferredItem', $this, $item);
283
284
        return $this->deferredList[ $item->getKey() ] = $item;
285
    }
286
287
    /**
288
     * @return mixed|null
289
     * @throws \InvalidArgumentException
290
     */
291
    public function commit()
292
    {
293
        /**
294
         * @eventName CacheCommitItem
295
         * @param $this ExtendedCacheItemPoolInterface
296
         * @param $deferredList ExtendedCacheItemInterface[]
297
         */
298
        $this->eventManager->dispatch('CacheCommitItem', $this, $this->deferredList);
299
300
        $return = null;
301
        foreach ($this->deferredList as $key => $item) {
302
            $result = $this->save($item);
303
            if ($return !== false) {
304
                unset($this->deferredList[ $key ]);
305
                $return = $result;
306
            }
307
        }
308
309
        return (bool) $return;
310
    }
311
}