Completed
Push — final ( 221312...0c167f )
by Georges
10s
created

StandardPsr6StructureTrait::save()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 21
Code Lines 10

Duplication

Lines 5
Ratio 23.81 %

Importance

Changes 6
Bugs 3 Features 2
Metric Value
cc 5
eloc 10
c 6
b 3
f 2
nc 5
nop 1
dl 5
loc 21
rs 8.7624
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;
16
17
use phpFastCache\Cache\ExtendedCacheItemInterface;
18
use phpFastCache\CacheManager;
19
use Psr\Cache\CacheItemInterface;
20
21
/**
22
 * Trait StandardPsr6StructureTrait
23
 * @package phpFastCache\Core
24
 */
25
trait StandardPsr6StructureTrait
26
{
27
    use ClassNamespaceResolverTrait;
28
29
    /**
30
     * @var array
31
     */
32
    protected $deferredList = [];
33
34
    /**
35
     * @var ExtendedCacheItemInterface[]
36
     */
37
    protected $itemInstances = [];
38
39
    /**
40
     * @param string $key
41
     * @return \phpFastCache\Cache\ExtendedCacheItemInterface
42
     * @throws \InvalidArgumentException
43
     */
44
    public function getItem($key)
45
    {
46
        if (is_string($key)) {
47
            if (!array_key_exists($key, $this->itemInstances)) {
48
49
                /**
50
                 * @var $item ExtendedCacheItemInterface
51
                 */
52
                CacheManager::$ReadHits++;
53
                $class = new \ReflectionClass((new \ReflectionObject($this))->getNamespaceName() . '\Item');
54
                $item = $class->newInstanceArgs([$this, $key]);
55
                $driverArray = $this->driverRead($item);
56
57
                if ($driverArray) {
58
                    $item->set($this->driverUnwrapData($driverArray));
59
                    $item->expiresAt($this->driverUnwrapTime($driverArray));
60
                    $item->setTags($this->driverUnwrapTags($driverArray));
61
                    if ($item->isExpired()) {
62
                        /**
63
                         * Using driverDelete() instead of delete()
64
                         * to avoid infinite loop caused by
65
                         * getItem() call in delete() method
66
                         * As we MUST return an item in any
67
                         * way, we do not de-register here
68
                         */
69
                        $this->driverDelete($item);
70
71
                    } else {
72
                        $item->setHit(true);
73
                    }
74
                } else {
75
                    $item->expiresAfter(abs((int) $this->getConfig()[ 'defaultTtl' ]));
76
                }
77
78
            }
79
        } else {
80
            throw new \InvalidArgumentException(sprintf('$key must be a string, got type "%s" instead.', gettype($key)));
81
        }
82
83
        return $this->itemInstances[ $key ];
84
    }
85
86
    /**
87
     * @param \Psr\Cache\CacheItemInterface $item
88
     * @return $this
89
     * @throws \InvalidArgumentException
90
     */
91
    public function setItem(CacheItemInterface $item)
92
    {
93
        if ($this->getClassNamespace() . '\\Item' === get_class($item)) {
94
            $this->itemInstances[ $item->getKey() ] = $item;
95
96
            return $this;
97
        } else {
98
            throw new \InvalidArgumentException(sprintf('Invalid Item Class "%s" for this driver.', get_class($item)));
99
        }
100
    }
101
102
    /**
103
     * @param array $keys
104
     * @return CacheItemInterface[]
105
     * @throws \InvalidArgumentException
106
     */
107
    public function getItems(array $keys = [])
108
    {
109
        $collection = [];
110
        foreach ($keys as $key) {
111
            $collection[ $key ] = $this->getItem($key);
112
        }
113
114
        return $collection;
115
    }
116
117
    /**
118
     * @param string $key
119
     * @return bool
120
     * @throws \InvalidArgumentException
121
     */
122
    public function hasItem($key)
123
    {
124
        CacheManager::$ReadHits++;
125
126
        return $this->getItem($key)->isHit();
127
    }
128
129
    /**
130
     * @return bool
131
     */
132
    public function clear()
133
    {
134
        CacheManager::$WriteHits++;
135
        $this->itemInstances = [];
136
137
        return $this->driverClear();
138
    }
139
140
    /**
141
     * @param string $key
142
     * @return bool
143
     * @throws \InvalidArgumentException
144
     */
145
    public function deleteItem($key)
146
    {
147
        $item = $this->getItem($key);
148
        if ($this->hasItem($key) && $this->driverDelete($item)) {
149
            $item->setHit(false);
150
            CacheManager::$WriteHits++;
151
            /**
152
             * De-register the item instance
153
             * then collect gc cycles
154
             */
155
            $this->deregisterItem($key);
156
157
            return true;
158
        }
159
160
        return false;
161
    }
162
163
    /**
164
     * @param array $keys
165
     * @return bool
166
     * @throws \InvalidArgumentException
167
     */
168
    public function deleteItems(array $keys)
169
    {
170
        $return = null;
171
        foreach ($keys as $key) {
172
            $result = $this->deleteItem($key);
173
            if ($result !== false) {
174
                $return = $result;
175
            }
176
        }
177
178
        return (bool) $return;
179
    }
180
181
    /**
182
     * @param \Psr\Cache\CacheItemInterface $item
183
     * @return mixed
184
     * @throws \InvalidArgumentException
185
     * @throws \RuntimeException
186
     */
187
    public function save(CacheItemInterface $item)
188
    {
189
        /**
190
         * @var ExtendedCacheItemInterface $item
191
         */
192 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...
193
            $this->itemInstances[ $item->getKey() ] = $item;
194
        } else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
195
            throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
196
        }
197
198
199
        if ($this->driverWrite($item) && $this->driverWriteTags($item)) {
200
            $item->setHit(true);
201
            CacheManager::$WriteHits++;
202
203
            return true;
204
        }
205
206
        return false;
207
    }
208
209
    /**
210
     * @param \Psr\Cache\CacheItemInterface $item
211
     * @return \Psr\Cache\CacheItemInterface
212
     * @throws \RuntimeException
213
     */
214
    public function saveDeferred(CacheItemInterface $item)
215
    {
216 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...
217
            $this->itemInstances[ $item->getKey() ] = $item;
218
        }else if(spl_object_hash($item) !== spl_object_hash($this->itemInstances[ $item->getKey() ])){
219
            throw new \RuntimeException('Spl object hash mismatches ! You probably tried to save a detached item which has been already retrieved from cache.');
220
        }
221
222
        return $this->deferredList[ $item->getKey() ] = $item;
223
    }
224
225
    /**
226
     * @return mixed|null
227
     * @throws \InvalidArgumentException
228
     */
229
    public function commit()
230
    {
231
        $return = null;
232
        foreach ($this->deferredList as $key => $item) {
233
            $result = $this->save($item);
234
            if ($return !== false) {
235
                unset($this->deferredList[ $key ]);
236
                $return = $result;
237
            }
238
        }
239
240
        return (bool) $return;
241
    }
242
}