1: <?php
2: /**
3: * Wincache storage engine for cache.
4: *
5: * Supports wincache 1.1.0 and higher.
6: *
7: * PHP 5
8: *
9: * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
10: * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
11: *
12: * Licensed under The MIT License
13: * Redistributions of files must retain the above copyright notice.
14: *
15: * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
16: * @link http://cakephp.org CakePHP(tm) Project
17: * @package Cake.Cache.Engine
18: * @since CakePHP(tm) v 1.2.0.4933
19: * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
20: */
21:
22: /**
23: * Wincache storage engine for cache
24: *
25: * @package Cake.Cache.Engine
26: */
27: class WincacheEngine extends CacheEngine {
28:
29: /**
30: * Contains the compiled group names
31: * (prefixed witht the global configuration prefix)
32: *
33: * @var array
34: **/
35: protected $_compiledGroupNames = array();
36:
37: /**
38: * Initialize the Cache Engine
39: *
40: * Called automatically by the cache frontend
41: * To reinitialize the settings call Cache::engine('EngineName', [optional] settings = array());
42: *
43: * @param array $settings array of setting for the engine
44: * @return boolean True if the engine has been successfully initialized, false if not
45: * @see CacheEngine::__defaults
46: */
47: public function init($settings = array()) {
48: if (!isset($settings['prefix'])) {
49: $settings['prefix'] = Inflector::slug(APP_DIR) . '_';
50: }
51: $settings += array('engine' => 'Wincache');
52: parent::init($settings);
53: return function_exists('wincache_ucache_info');
54: }
55:
56: /**
57: * Write data for key into cache
58: *
59: * @param string $key Identifier for the data
60: * @param mixed $value Data to be cached
61: * @param integer $duration How long to cache the data, in seconds
62: * @return boolean True if the data was successfully cached, false on failure
63: */
64: public function write($key, $value, $duration) {
65: $expires = time() + $duration;
66:
67: $data = array(
68: $key . '_expires' => $expires,
69: $key => $value
70: );
71: $result = wincache_ucache_set($data, null, $duration);
72: return empty($result);
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
80: * there was an error fetching it
81: */
82: public function read($key) {
83: $time = time();
84: $cachetime = intval(wincache_ucache_get($key . '_expires'));
85: if ($cachetime < $time || ($time + $this->settings['duration']) < $cachetime) {
86: return false;
87: }
88: return wincache_ucache_get($key);
89: }
90:
91: /**
92: * Increments the value of an integer cached key
93: *
94: * @param string $key Identifier for the data
95: * @param integer $offset How much to increment
96: * @return New incremented value, false otherwise
97: */
98: public function increment($key, $offset = 1) {
99: return wincache_ucache_inc($key, $offset);
100: }
101:
102: /**
103: * Decrements the value of an integer cached key
104: *
105: * @param string $key Identifier for the data
106: * @param integer $offset How much to subtract
107: * @return New decremented value, false otherwise
108: */
109: public function decrement($key, $offset = 1) {
110: return wincache_ucache_dec($key, $offset);
111: }
112:
113: /**
114: * Delete a key from the cache
115: *
116: * @param string $key Identifier for the data
117: * @return boolean True if the value was successfully deleted, false if it didn't exist or couldn't be removed
118: */
119: public function delete($key) {
120: return wincache_ucache_delete($key);
121: }
122:
123: /**
124: * Delete all keys from the cache. This will clear every
125: * item in the cache matching the cache config prefix.
126: *
127: * @param boolean $check If true, nothing will be cleared, as entries will
128: * naturally expire in wincache..
129: * @return boolean True Returns true.
130: */
131: public function clear($check) {
132: if ($check) {
133: return true;
134: }
135: $info = wincache_ucache_info();
136: $cacheKeys = $info['ucache_entries'];
137: unset($info);
138: foreach ($cacheKeys as $key) {
139: if (strpos($key['key_name'], $this->settings['prefix']) === 0) {
140: wincache_ucache_delete($key['key_name']);
141: }
142: }
143: return true;
144: }
145:
146: /**
147: * Returns the `group value` for each of the configured groups
148: * If the group initial value was not found, then it initializes
149: * the group accordingly.
150: *
151: * @return array
152: **/
153: public function groups() {
154: if (empty($this->_compiledGroupNames)) {
155: foreach ($this->settings['groups'] as $group) {
156: $this->_compiledGroupNames[] = $this->settings['prefix'] . $group;
157: }
158: }
159:
160: $groups = wincache_ucache_get($this->_compiledGroupNames);
161: if (count($groups) !== count($this->settings['groups'])) {
162: foreach ($this->_compiledGroupNames as $group) {
163: if (!isset($groups[$group])) {
164: wincache_ucache_set($group, 1);
165: $groups[$group] = 1;
166: }
167: }
168: ksort($groups);
169: }
170:
171: $result = array();
172: $groups = array_values($groups);
173: foreach ($this->settings['groups'] as $i => $group) {
174: $result[] = $group . $groups[$i];
175: }
176: return $result;
177: }
178:
179: /**
180: * Increments the group value to simulate deletion of all keys under a group
181: * old values will remain in storage until they expire.
182: *
183: * @return boolean success
184: **/
185: public function clearGroup($group) {
186: $success = null;
187: wincache_ucache_inc($this->settings['prefix'] . $group, 1, $success);
188: return $success;
189: }
190:
191: }
192: