1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
25: 26: 27: 28: 29: 30:
31: class Cache extends Object {
32: 33: 34: 35: 36: 37:
38: var $_Engine = null;
39: 40: 41: 42: 43: 44:
45: var $__config = array();
46: 47: 48: 49: 50: 51:
52: var $__name = 'default';
53: 54: 55: 56: 57: 58:
59: var $__reset = false;
60: 61: 62: 63: 64: 65: 66:
67: function &getInstance() {
68: static $instance = array();
69: if (!$instance) {
70: $instance[0] =& new Cache();
71: }
72: return $instance[0];
73: }
74: 75: 76: 77: 78: 79: 80:
81: function __loadEngine($name) {
82: if (!class_exists($name . 'Engine')) {
83: require LIBS . 'cache' . DS . strtolower($name) . '.php';
84: }
85: return true;
86: }
87: 88: 89: 90: 91: 92: 93: 94: 95: 96:
97: function config($name = null, $settings = array()) {
98: $_this =& Cache::getInstance();
99: if (is_array($name)) {
100: $settings = $name;
101: }
102:
103: if ($name === null || !is_string($name)) {
104: $name = $_this->__name;
105: }
106:
107: $current = array();
108: if (isset($_this->__config[$name])) {
109: $current = $_this->__config[$name];
110: }
111:
112: if (!empty($settings)) {
113: $_this->__name = null;
114: $_this->__config[$name] = array_merge($current, $settings);
115: }
116:
117: if (empty($_this->__config[$name]['engine'])) {
118: return false;
119: }
120:
121: $_this->__name = $name;
122: $engine = $_this->__config[$name]['engine'];
123:
124: if (!$_this->isInitialized($engine)) {
125: if ($_this->engine($engine, $_this->__config[$name]) === false) {
126: return false;
127: }
128: $settings = $_this->__config[$name] = $_this->settings($engine);
129: } else {
130: $settings = $_this->__config[$name] = $_this->set($_this->__config[$name]);
131: }
132: return compact('engine', 'settings');
133: }
134: 135: 136: 137: 138: 139: 140: 141: 142:
143: function engine($name = 'File', $settings = array()) {
144: $cacheClass = $name . 'Engine';
145: $_this =& Cache::getInstance();
146: if (!isset($_this->_Engine[$name])) {
147: if ($_this->__loadEngine($name) === false) {
148: return false;
149: }
150: $_this->_Engine[$name] =& new $cacheClass();
151: }
152:
153: if ($_this->_Engine[$name]->init($settings)) {
154: if (time() % $_this->_Engine[$name]->settings['probability'] === 0) {
155: $_this->_Engine[$name]->gc();
156: }
157: return true;
158: }
159: $_this->_Engine[$name] = null;
160: return false;
161: }
162: 163: 164: 165: 166: 167: 168: 169: 170: 171:
172: function set($settings = array(), $value = null) {
173: $_this =& Cache::getInstance();
174: if (!isset($_this->__config[$_this->__name])) {
175: return false;
176: }
177:
178: $engine = $_this->__config[$_this->__name]['engine'];
179: if (isset($settings['engine'])) {
180: $engine = $settings['engine'];
181: }
182:
183: if (!empty($settings)) {
184: $_this->__reset = true;
185: }
186:
187: if ($_this->__reset === true) {
188: if (empty($settings)) {
189: $_this->__reset = false;
190: $settings = $_this->__config[$_this->__name];
191: } else {
192: if (is_string($settings) && $value !== null) {
193: $settings = array($settings => $value);
194: }
195: $settings = array_merge($_this->__config[$_this->__name], $settings);
196: }
197: $_this->_Engine[$engine]->init($settings);
198: }
199:
200: return $_this->settings($engine);
201: }
202: 203: 204: 205: 206: 207: 208: 209: 210:
211: function gc() {
212: $_this =& Cache::getInstance();
213: $config = $_this->config();
214: $_this->_Engine[$config['engine']]->gc();
215: }
216: 217: 218: 219: 220: 221: 222: 223: 224: 225:
226: function write($key, $value, $config = null) {
227: $_this =& Cache::getInstance();
228:
229: if (is_array($config)) {
230: extract($config);
231: } else if ($config && (is_numeric($config) || is_numeric($config[0]) || (isset($config[1]) && is_numeric($config[1])))) {
232: $config = null;
233: }
234:
235: if ($config && isset($_this->__config[$config])) {
236: $settings = $_this->set($_this->__config[$config]);
237: } else {
238: $settings = $_this->settings();
239: }
240:
241: if (empty($settings)) {
242: return null;
243: }
244: extract($settings);
245:
246: if (!$_this->isInitialized($engine)) {
247: return false;
248: }
249:
250: if (!$key = $_this->_Engine[$engine]->key($key)) {
251: return false;
252: }
253:
254: if (is_resource($value)) {
255: return false;
256: }
257:
258: if ($duration < 1) {
259: return false;
260: }
261:
262: $success = $_this->_Engine[$engine]->write($settings['prefix'] . $key, $value, $duration);
263: $settings = $_this->set();
264: return $success;
265: }
266: 267: 268: 269: 270: 271: 272: 273: 274:
275: function read($key, $config = null) {
276: $_this =& Cache::getInstance();
277:
278: if (isset($_this->__config[$config])) {
279: $settings = $_this->set($_this->__config[$config]);
280: } else {
281: $settings = $_this->settings();
282: }
283:
284: if (empty($settings)) {
285: return null;
286: }
287: extract($settings);
288:
289: if (!$_this->isInitialized($engine)) {
290: return false;
291: }
292: if (!$key = $_this->_Engine[$engine]->key($key)) {
293: return false;
294: }
295:
296: $success = $_this->_Engine[$engine]->read($settings['prefix'] . $key);
297:
298: if ($config !== null && $config !== $_this->__name) {
299: $settings = $_this->set();
300: }
301: return $success;
302: }
303: 304: 305: 306: 307: 308: 309: 310: 311:
312: function delete($key, $config = null) {
313: $_this =& Cache::getInstance();
314: if (isset($_this->__config[$config])) {
315: $settings = $_this->set($_this->__config[$config]);
316: } else {
317: $settings = $_this->settings();
318: }
319:
320: if (empty($settings)) {
321: return null;
322: }
323: extract($settings);
324:
325: if (!$_this->isInitialized($engine)) {
326: return false;
327: }
328:
329: if (!$key = $_this->_Engine[$engine]->key($key)) {
330: return false;
331: }
332:
333: $success = $_this->_Engine[$engine]->delete($settings['prefix'] . $key);
334: $settings = $_this->set();
335: return $success;
336: }
337: 338: 339: 340: 341: 342: 343: 344: 345:
346: function clear($check = false, $config = null) {
347: $_this =& Cache::getInstance();
348: if (isset($_this->__config[$config])) {
349: $settings = $_this->set($_this->__config[$config]);
350: } else {
351: $settings = $_this->settings();
352: }
353:
354: if (empty($settings)) {
355: return null;
356: }
357: extract($settings);
358:
359: if (isset($engine) && !$_this->isInitialized($engine)) {
360: return false;
361: }
362: $success = $_this->_Engine[$engine]->clear($check);
363: $settings = $_this->set();
364: return $success;
365: }
366: 367: 368: 369: 370: 371: 372: 373: 374:
375: function isInitialized($engine = null) {
376: if (Configure::read('Cache.disable')) {
377: return false;
378: }
379: $_this =& Cache::getInstance();
380: if (!$engine && isset($_this->__config[$_this->__name]['engine'])) {
381: $engine = $_this->__config[$_this->__name]['engine'];
382: }
383: return isset($_this->_Engine[$engine]);
384: }
385:
386: 387: 388: 389: 390: 391: 392: 393:
394: function settings($engine = null) {
395: $_this =& Cache::getInstance();
396: if (!$engine && isset($_this->__config[$_this->__name]['engine'])) {
397: $engine = $_this->__config[$_this->__name]['engine'];
398: }
399:
400: if (isset($_this->_Engine[$engine]) && !is_null($_this->_Engine[$engine])) {
401: return $_this->_Engine[$engine]->settings();
402: }
403: return array();
404: }
405: }
406: 407: 408: 409: 410: 411:
412: class CacheEngine extends Object {
413: 414: 415: 416: 417: 418:
419: var $settings = array();
420: 421: 422: 423: 424: 425: 426: 427: 428:
429: function init($settings = array()) {
430: $this->settings = array_merge(array('prefix' => 'cake_', 'duration'=> 3600, 'probability'=> 100), $this->settings, $settings);
431: if (!is_numeric($this->settings['duration'])) {
432: $this->settings['duration'] = strtotime($this->settings['duration']) - time();
433: }
434: return true;
435: }
436: 437: 438: 439: 440: 441: 442:
443: function gc() {
444: }
445: 446: 447: 448: 449: 450: 451: 452: 453:
454: function write($key, &$value, $duration) {
455: trigger_error(sprintf(__('Method write() not implemented in %s', true), get_class($this)), E_USER_ERROR);
456: }
457: 458: 459: 460: 461: 462: 463:
464: function read($key) {
465: trigger_error(sprintf(__('Method read() not implemented in %s', true), get_class($this)), E_USER_ERROR);
466: }
467: 468: 469: 470: 471: 472: 473:
474: function delete($key) {
475: }
476: 477: 478: 479: 480: 481: 482:
483: function clear($check) {
484: }
485: 486: 487: 488: 489: 490:
491: function settings() {
492: return $this->settings;
493: }
494: 495: 496: 497: 498: 499: 500:
501: function key($key) {
502: if (empty($key)) {
503: return false;
504: }
505: $key = Inflector::underscore(str_replace(array(DS, '/', '.'), '_', strval($key)));
506: return $key;
507: }
508: }
509: ?>