1 <?php
2 /**
3 * @package Joomla.Platform
4 * @subpackage Cache
5 *
6 * @copyright Copyright (C) 2005 - 2017 Open Source Matters, Inc. All rights reserved.
7 * @license GNU General Public License version 2 or later; see LICENSE
8 */
9
10 defined('JPATH_PLATFORM') or die;
11
12 /**
13 * XCache cache storage handler
14 *
15 * @link http://xcache.lighttpd.net/
16 * @since 11.1
17 */
18 class JCacheStorageXcache extends JCacheStorage
19 {
20 /**
21 * Check if the cache contains data stored by ID and group
22 *
23 * @param string $id The cache data ID
24 * @param string $group The cache data group
25 *
26 * @return boolean
27 *
28 * @since 3.7.0
29 */
30 public function contains($id, $group)
31 {
32 return xcache_isset($this->_getCacheId($id, $group));
33 }
34
35 /**
36 * Get cached data by ID and group
37 *
38 * @param string $id The cache data ID
39 * @param string $group The cache data group
40 * @param boolean $checkTime True to verify cache time expiration threshold
41 *
42 * @return mixed Boolean false on failure or a cached data object
43 *
44 * @since 11.1
45 */
46 public function get($id, $group, $checkTime = true)
47 {
48 // Make sure XCache is configured properly
49 if (static::isSupported() == false)
50 {
51 return false;
52 }
53
54 $cache_id = $this->_getCacheId($id, $group);
55 $cache_content = xcache_get($cache_id);
56
57 if ($cache_content === null)
58 {
59 return false;
60 }
61
62 return $cache_content;
63 }
64
65 /**
66 * Get all cached data
67 *
68 * @return mixed Boolean false on failure or a cached data object
69 *
70 * @since 11.1
71 * @note This requires the php.ini setting xcache.admin.enable_auth = Off.
72 */
73 public function getAll()
74 {
75 // Make sure XCache is configured properly
76 if (static::isSupported() == false)
77 {
78 return array();
79 }
80
81 $allinfo = xcache_list(XC_TYPE_VAR, 0);
82 $keys = $allinfo['cache_list'];
83 $secret = $this->_hash;
84
85 $data = array();
86
87 foreach ($keys as $key)
88 {
89 $namearr = explode('-', $key['name']);
90
91 if ($namearr !== false && $namearr[0] == $secret && $namearr[1] == 'cache')
92 {
93 $group = $namearr[2];
94
95 if (!isset($data[$group]))
96 {
97 $item = new JCacheStorageHelper($group);
98 }
99 else
100 {
101 $item = $data[$group];
102 }
103
104 $item->updateSize($key['size']);
105
106 $data[$group] = $item;
107 }
108 }
109
110 return $data;
111 }
112
113 /**
114 * Store the data to cache by ID and group
115 *
116 * @param string $id The cache data ID
117 * @param string $group The cache data group
118 * @param string $data The data to store in cache
119 *
120 * @return boolean
121 *
122 * @since 11.1
123 */
124 public function store($id, $group, $data)
125 {
126 // Make sure XCache is configured properly
127 if (static::isSupported() == false)
128 {
129 return false;
130 }
131
132 return xcache_set($this->_getCacheId($id, $group), $data, $this->_lifetime);
133 }
134
135 /**
136 * Remove a cached data entry by ID and group
137 *
138 * @param string $id The cache data ID
139 * @param string $group The cache data group
140 *
141 * @return boolean
142 *
143 * @since 11.1
144 */
145 public function remove($id, $group)
146 {
147 // Make sure XCache is configured properly
148 if (static::isSupported() == false)
149 {
150 return false;
151 }
152
153 $cache_id = $this->_getCacheId($id, $group);
154
155 if (!xcache_isset($cache_id))
156 {
157 return true;
158 }
159
160 return xcache_unset($cache_id);
161 }
162
163 /**
164 * Clean cache for a group given a mode.
165 *
166 * group mode : cleans all cache in the group
167 * notgroup mode : cleans all cache not in the group
168 *
169 * @param string $group The cache data group
170 * @param string $mode The mode for cleaning cache [group|notgroup]
171 *
172 * @return boolean
173 *
174 * @since 11.1
175 */
176 public function clean($group, $mode = null)
177 {
178 // Make sure XCache is configured properly
179 if (static::isSupported() == false)
180 {
181 return true;
182 }
183
184 $allinfo = xcache_list(XC_TYPE_VAR, 0);
185 $keys = $allinfo['cache_list'];
186 $secret = $this->_hash;
187
188 foreach ($keys as $key)
189 {
190 if (strpos($key['name'], $secret . '-cache-' . $group . '-') === 0 xor $mode != 'group')
191 {
192 xcache_unset($key['name']);
193 }
194 }
195
196 return true;
197 }
198
199 /**
200 * Test to see if the storage handler is available.
201 *
202 * @return boolean
203 *
204 * @since 12.1
205 */
206 public static function isSupported()
207 {
208 if (extension_loaded('xcache'))
209 {
210 // XCache Admin must be disabled for Joomla to use XCache
211 $xcache_admin_enable_auth = ini_get('xcache.admin.enable_auth');
212
213 // Some extensions ini variables are reported as strings
214 if ($xcache_admin_enable_auth == 'Off')
215 {
216 return true;
217 }
218
219 // We require a string with contents 0, not a null value because it is not set since that then defaults to On/True
220 if ($xcache_admin_enable_auth === '0')
221 {
222 return true;
223 }
224
225 // In some enviorments empty is equivalent to Off; See JC: #34044 && Github: #4083
226 if ($xcache_admin_enable_auth === '')
227 {
228 return true;
229 }
230 }
231
232 // If the settings are not correct, give up
233 return false;
234 }
235 }
236