Completed
Push — master ( 01f736...b5cb56 )
by Mark
07:04 queued 01:27
created

src/Cache/Engine/ApcuEngine.php (2 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
4
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
5
 *
6
 * Licensed under The MIT License
7
 * For full copyright and license information, please see the LICENSE.txt
8
 * Redistributions of files must retain the above copyright notice.
9
 *
10
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
11
 * @link          https://cakephp.org CakePHP(tm) Project
12
 * @since         3.5.4
13
 * @license       https://opensource.org/licenses/mit-license.php MIT License
14
 */
15
namespace Cake\Cache\Engine;
16
17
use APCuIterator;
18
use Cake\Cache\CacheEngine;
19
20
/**
21
 * APCu storage engine for cache
22
 */
23
class ApcuEngine extends CacheEngine
24
{
25
26
    /**
27
     * Contains the compiled group names
28
     * (prefixed with the global configuration prefix)
29
     *
30
     * @var string[]
31
     */
32
    protected $_compiledGroupNames = [];
33
34
    /**
35
     * Initialize the Cache Engine
36
     *
37
     * Called automatically by the cache frontend
38
     *
39
     * @param array $config array of setting for the engine
40
     * @return bool True if the engine has been successfully initialized, false if not
41
     */
42
    public function init(array $config = [])
43
    {
44
        if (!extension_loaded('apcu')) {
45
            return false;
46
        }
47
48
        return parent::init($config);
49
    }
50
51
    /**
52
     * Write data for key into cache
53
     *
54
     * @param string $key Identifier for the data
55
     * @param mixed $value Data to be cached
56
     * @return bool True if the data was successfully cached, false on failure
57
     * @link https://secure.php.net/manual/en/function.apcu-store.php
58
     */
59
    public function write($key, $value)
60
    {
61
        $key = $this->_key($key);
62
        $duration = $this->_config['duration'];
63
64
        return apcu_store($key, $value, $duration);
0 ignored issues
show
Bug Compatibility introduced by
The expression apcu_store($key, $value, $duration); of type boolean|array adds the type array to the return on line 64 which is incompatible with the return type declared by the abstract method Cake\Cache\CacheEngine::write of type boolean.
Loading history...
65
    }
66
67
    /**
68
     * Read a key from the cache
69
     *
70
     * @param string $key Identifier for the data
71
     * @return mixed The cached data, or false if the data doesn't exist,
72
     *   has expired, or if there was an error fetching it
73
     * @link https://secure.php.net/manual/en/function.apcu-fetch.php
74
     */
75
    public function read($key)
76
    {
77
        $key = $this->_key($key);
78
79
        return apcu_fetch($key);
80
    }
81
82
    /**
83
     * Increments the value of an integer cached key
84
     *
85
     * @param string $key Identifier for the data
86
     * @param int $offset How much to increment
87
     * @return bool|int New incremented value, false otherwise
88
     * @link https://secure.php.net/manual/en/function.apcu-inc.php
89
     */
90
    public function increment($key, $offset = 1)
91
    {
92
        $key = $this->_key($key);
93
94
        return apcu_inc($key, $offset);
95
    }
96
97
    /**
98
     * Decrements the value of an integer cached key
99
     *
100
     * @param string $key Identifier for the data
101
     * @param int $offset How much to subtract
102
     * @return bool|int New decremented value, false otherwise
103
     * @link https://secure.php.net/manual/en/function.apcu-dec.php
104
     */
105
    public function decrement($key, $offset = 1)
106
    {
107
        $key = $this->_key($key);
108
109
        return apcu_dec($key, $offset);
110
    }
111
112
    /**
113
     * Delete a key from the cache
114
     *
115
     * @param string $key Identifier for the data
116
     * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed
117
     * @link https://secure.php.net/manual/en/function.apcu-delete.php
118
     */
119
    public function delete($key)
120
    {
121
        $key = $this->_key($key);
122
123
        return apcu_delete($key);
0 ignored issues
show
Bug Compatibility introduced by
The expression apcu_delete($key); of type boolean|string[] adds the type string[] to the return on line 123 which is incompatible with the return type declared by the abstract method Cake\Cache\CacheEngine::delete of type boolean.
Loading history...
124
    }
125
126
    /**
127
     * Delete all keys from the cache. This will clear every cache config using APC.
128
     *
129
     * @param bool $check If true, nothing will be cleared, as entries are removed
130
     *    from APC as they expired. This flag is really only used by FileEngine.
131
     * @return bool True Returns true.
132
     * @link https://secure.php.net/manual/en/function.apcu-cache-info.php
133
     * @link https://secure.php.net/manual/en/function.apcu-delete.php
134
     */
135
    public function clear($check)
136
    {
137
        if ($check) {
138
            return true;
139
        }
140
        if (class_exists('APCuIterator', false)) {
141
            $iterator = new APCuIterator(
142
                '/^' . preg_quote($this->_config['prefix'], '/') . '/',
143
                APC_ITER_NONE
144
            );
145
            apcu_delete($iterator);
146
147
            return true;
148
        }
149
150
        $cache = apcu_cache_info(); // Raises warning by itself already
151
        foreach ($cache['cache_list'] as $key) {
152
            if (strpos($key['info'], $this->_config['prefix']) === 0) {
153
                apcu_delete($key['info']);
154
            }
155
        }
156
157
        return true;
158
    }
159
160
    /**
161
     * Write data for key into cache if it doesn't exist already.
162
     * If it already exists, it fails and returns false.
163
     *
164
     * @param string $key Identifier for the data.
165
     * @param mixed $value Data to be cached.
166
     * @return bool True if the data was successfully cached, false on failure.
167
     * @link https://secure.php.net/manual/en/function.apcu-add.php
168
     */
169
    public function add($key, $value)
170
    {
171
        $key = $this->_key($key);
172
        $duration = $this->_config['duration'];
173
174
        return apcu_add($key, $value, $duration);
175
    }
176
177
    /**
178
     * Returns the `group value` for each of the configured groups
179
     * If the group initial value was not found, then it initializes
180
     * the group accordingly.
181
     *
182
     * @return array
183
     * @link https://secure.php.net/manual/en/function.apcu-fetch.php
184
     * @link https://secure.php.net/manual/en/function.apcu-store.php
185
     */
186
    public function groups()
187
    {
188 View Code Duplication
        if (empty($this->_compiledGroupNames)) {
189
            foreach ($this->_config['groups'] as $group) {
190
                $this->_compiledGroupNames[] = $this->_config['prefix'] . $group;
191
            }
192
        }
193
194
        $success = false;
195
        $groups = apcu_fetch($this->_compiledGroupNames, $success);
196
        if ($success && count($groups) !== count($this->_config['groups'])) {
197
            foreach ($this->_compiledGroupNames as $group) {
198
                if (!isset($groups[$group])) {
199
                    $value = 1;
200
                    if (apcu_store($group, $value) === false) {
201
                        $this->warning(
202
                            sprintf('Failed to store key "%s" with value "%s" into APCu cache.', $group, $value)
203
                        );
204
                    }
205
                    $groups[$group] = $value;
206
                }
207
            }
208
            ksort($groups);
209
        }
210
211
        $result = [];
212
        $groups = array_values($groups);
213
        foreach ($this->_config['groups'] as $i => $group) {
214
            $result[] = $group . $groups[$i];
215
        }
216
217
        return $result;
218
    }
219
220
    /**
221
     * Increments the group value to simulate deletion of all keys under a group
222
     * old values will remain in storage until they expire.
223
     *
224
     * @param string $group The group to clear.
225
     * @return bool success
226
     * @link https://secure.php.net/manual/en/function.apcu-inc.php
227
     */
228
    public function clearGroup($group)
229
    {
230
        $success = false;
231
        apcu_inc($this->_config['prefix'] . $group, 1, $success);
232
233
        return $success;
234
    }
235
}
236