1: <?php
2: /**
3: * Xcache storage engine for cache.
4: *
5: * PHP 5
6: *
7: * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
8: * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
9: *
10: * Licensed under The MIT License
11: * Redistributions of files must retain the above copyright notice.
12: *
13: * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
14: * @link http://cakephp.org CakePHP(tm) Project
15: * @package Cake.Cache.Engine
16: * @since CakePHP(tm) v 1.2.0.4947
17: * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
18: */
19:
20: /**
21: * Xcache storage engine for cache
22: *
23: * @link http://trac.lighttpd.net/xcache/ Xcache
24: * @package Cake.Cache.Engine
25: */
26: class XcacheEngine extends CacheEngine {
27:
28: /**
29: * Settings
30: *
31: * - PHP_AUTH_USER = xcache.admin.user, default cake
32: * - PHP_AUTH_PW = xcache.admin.password, default cake
33: *
34: * @var array
35: */
36: public $settings = array();
37:
38: /**
39: * Initialize the Cache Engine
40: *
41: * Called automatically by the cache frontend
42: * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
43: *
44: * @param array $settings array of setting for the engine
45: * @return boolean True if the engine has been successfully initialized, false if not
46: */
47: public function init($settings = array()) {
48: if (php_sapi_name() !== 'cli') {
49: parent::init(array_merge(array(
50: 'engine' => 'Xcache',
51: 'prefix' => Inflector::slug(APP_DIR) . '_',
52: 'PHP_AUTH_USER' => 'user',
53: 'PHP_AUTH_PW' => 'password'
54: ), $settings)
55: );
56: return function_exists('xcache_info');
57: }
58: return false;
59: }
60:
61: /**
62: * Write data for key into cache
63: *
64: * @param string $key Identifier for the data
65: * @param mixed $value Data to be cached
66: * @param integer $duration How long to cache the data, in seconds
67: * @return boolean True if the data was successfully cached, false on failure
68: */
69: public function write($key, $value, $duration) {
70: $expires = time() + $duration;
71: xcache_set($key . '_expires', $expires, $duration);
72: return xcache_set($key, $value, $duration);
73: }
74:
75: /**
76: * Read a key from the cache
77: *
78: * @param string $key Identifier for the data
79: * @return mixed The cached data, or false if the data doesn't exist, has expired, or if there was an error fetching it
80: */
81: public function read($key) {
82: if (xcache_isset($key)) {
83: $time = time();
84: $cachetime = intval(xcache_get($key . '_expires'));
85: if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
86: return false;
87: }
88: return xcache_get($key);
89: }
90: return false;
91: }
92:
93: /**
94: * Increments the value of an integer cached key
95: * If the cache key is not an integer it will be treated as 0
96: *
97: * @param string $key Identifier for the data
98: * @param integer $offset How much to increment
99: * @return New incremented value, false otherwise
100: */
101: public function increment($key, $offset = 1) {
102: return xcache_inc($key, $offset);
103: }
104:
105: /**
106: * Decrements the value of an integer cached key.
107: * If the cache key is not an integer it will be treated as 0
108: *
109: * @param string $key Identifier for the data
110: * @param integer $offset How much to subtract
111: * @return New decremented value, false otherwise
112: */
113: public function decrement($key, $offset = 1) {
114: return xcache_dec($key, $offset);
115: }
116:
117: /**
118: * Delete a key from the cache
119: *
120: * @param string $key Identifier for the data
121: * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
122: */
123: public function delete($key) {
124: return xcache_unset($key);
125: }
126:
127: /**
128: * Delete all keys from the cache
129: *
130: * @param boolean $check
131: * @return boolean True if the cache was successfully cleared, false otherwise
132: */
133: public function clear($check) {
134: $this->_auth();
135: $max = xcache_count(XC_TYPE_VAR);
136: for ($i = 0; $i < $max; $i++) {
137: xcache_clear_cache(XC_TYPE_VAR, $i);
138: }
139: $this->_auth(true);
140: return true;
141: }
142:
143: /**
144: * Returns the `group value` for each of the configured groups
145: * If the group initial value was not found, then it initializes
146: * the group accordingly.
147: *
148: * @return array
149: **/
150: public function groups() {
151: $result = array();
152: foreach ($this->settings['groups'] as $group) {
153: $value = xcache_get($this->settings['prefix'] . $group);
154: if (!$value) {
155: $value = 1;
156: xcache_set($this->settings['prefix'] . $group, $value, 0);
157: }
158: $result[] = $group . $value;
159: }
160: return $result;
161: }
162:
163: /**
164: * Increments the group value to simulate deletion of all keys under a group
165: * old values will remain in storage until they expire.
166: *
167: * @return boolean success
168: **/
169: public function clearGroup($group) {
170: return (bool)xcache_inc($this->settings['prefix'] . $group, 1);
171: }
172:
173: /**
174: * Populates and reverses $_SERVER authentication values
175: * Makes necessary changes (and reverting them back) in $_SERVER
176: *
177: * This has to be done because xcache_clear_cache() needs to pass Basic Http Auth
178: * (see xcache.admin configuration settings)
179: *
180: * @param boolean $reverse Revert changes
181: * @return void
182: */
183: protected function _auth($reverse = false) {
184: static $backup = array();
185: $keys = array('PHP_AUTH_USER' => 'user', 'PHP_AUTH_PW' => 'password');
186: foreach ($keys as $key => $setting) {
187: if ($reverse) {
188: if (isset($backup[$key])) {
189: $_SERVER[$key] = $backup[$key];
190: unset($backup[$key]);
191: } else {
192: unset($_SERVER[$key]);
193: }
194: } else {
195: $value = env($key);
196: if (!empty($value)) {
197: $backup[$key] = $value;
198: }
199: if (!empty($this->settings[$setting])) {
200: $_SERVER[$key] = $this->settings[$setting];
201: } elseif (!empty($this->settings[$key])) {
202: $_SERVER[$key] = $this->settings[$key];
203: } else {
204: $_SERVER[$key] = $value;
205: }
206: }
207: }
208: }
209: }
210: