PageRenderTime 36ms CodeModel.GetById 8ms RepoModel.GetById 0ms app.codeStats 0ms

/storage/Cache.php

https://bitbucket.org/d1rk/lithium
PHP | 295 lines | 122 code | 37 blank | 136 comment | 22 complexity | 37af898eccd8df7dd732ba6c72c1ea5a MD5 | raw file
  1. <?php
  2. /**
  3. * Lithium: the most rad php framework
  4. *
  5. * @copyright Copyright 2012, Union of RAD (http://union-of-rad.org)
  6. * @license http://opensource.org/licenses/bsd-license.php The BSD License
  7. */
  8. namespace lithium\storage;
  9. /**
  10. * The `Cache` static class provides a consistent interface to configure and utilize the different
  11. * cache adapters included with Lithium, as well as your own adapters.
  12. *
  13. * The Cache layer of Lithium inherits from the common `Adaptable` class, which provides the generic
  14. * configuration setting & retrieval logic, as well as the logic required to locate & instantiate
  15. * the proper adapter class.
  16. *
  17. * In most cases, you will configure various named cache configurations in your bootstrap process,
  18. * which will then be available to you in all other parts of your application.
  19. *
  20. * A simple example configuration:
  21. *
  22. * {{{Cache::config(array(
  23. * 'local' => array('adapter' => 'Apc'),
  24. * 'distributed' => array(
  25. * 'adapter' => 'Memcached',
  26. * 'host' => '127.0.0.1:11211',
  27. * ),
  28. * 'default' => array('adapter' => 'File')
  29. * ));}}}
  30. *
  31. * Each adapter provides a consistent interface for the basic cache operations of `write`, `read`,
  32. * `delete` and `clear`, which can be used interchangeably between all adapters. Some adapters
  33. * may provide additional methods that are not consistently available across other adapters.
  34. * To make use of these, it is always possible to call:
  35. *
  36. * {{{Cache::adapter('named-configuration')->methodName($argument);}}}
  37. *
  38. * This allows a very wide range of flexibility, at the cost of portability.
  39. *
  40. * Some cache adapters (e.g. `File`) do _not_ provide the functionality for increment/decrement.
  41. * Additionally, some cache adapters support multi-key operations for `write`, `read` and `delete`
  42. * &mdash; please see the individual documentation for cache adapters and the operations that
  43. * they support.
  44. *
  45. * @see lithium\core\Adaptable
  46. * @see lithium\storage\cache\adapter
  47. */
  48. class Cache extends \lithium\core\Adaptable {
  49. /**
  50. * Stores configurations for cache adapters
  51. *
  52. * @var array
  53. */
  54. protected static $_configurations = array();
  55. /**
  56. * Libraries::locate() compatible path to adapters for this class.
  57. *
  58. * @var string Dot-delimited path.
  59. */
  60. protected static $_adapters = 'adapter.storage.cache';
  61. /**
  62. * Libraries::locate() compatible path to strategies for this class.
  63. *
  64. * @var string Dot-delimited path.
  65. */
  66. protected static $_strategies = 'strategy.storage.cache';
  67. /**
  68. * Generates the cache key.
  69. *
  70. * @param mixed $key A string (or lambda/closure that evaluates to a string)
  71. * that will be used as the cache key.
  72. * @param array $data If a lambda/closure is used as a key and requires arguments,
  73. * pass them in here.
  74. * @return string The generated cache key.
  75. */
  76. public static function key($key, $data = array()) {
  77. return is_object($key) ? $key($data) : $key;
  78. }
  79. /**
  80. * Writes to the specified cache configuration.
  81. *
  82. * @param string $name Configuration to be used for writing
  83. * @param mixed $key Key to uniquely identify the cache entry
  84. * @param mixed $data Data to be cached
  85. * @param string $expiry A strtotime() compatible cache time
  86. * @param mixed $options Options for the method, filters and strategies.
  87. * @return boolean True on successful cache write, false otherwise
  88. * @filter This method may be filtered.
  89. */
  90. public static function write($name, $key, $data, $expiry = null, array $options = array()) {
  91. $options += array('conditions' => null, 'strategies' => true);
  92. $settings = static::config();
  93. if (!isset($settings[$name])) {
  94. return false;
  95. }
  96. $conditions = $options['conditions'];
  97. if (is_callable($conditions) && !$conditions()) {
  98. return false;
  99. }
  100. $key = static::key($key, $data);
  101. if (is_array($key)) {
  102. $expiry = $data;
  103. $data = null;
  104. }
  105. if ($options['strategies']) {
  106. $options = array('key' => $key, 'class' => __CLASS__);
  107. $data = static::applyStrategies(__FUNCTION__, $name, $data, $options);
  108. }
  109. $method = static::adapter($name)->write($key, $data, $expiry);
  110. $params = compact('key', 'data', 'expiry');
  111. return static::_filter(__FUNCTION__, $params, $method, $settings[$name]['filters']);
  112. }
  113. /**
  114. * Reads from the specified cache configuration
  115. *
  116. * @param string $name Configuration to be used for reading
  117. * @param mixed $key Key to be retrieved
  118. * @param mixed $options Options for the method and strategies.
  119. * @return mixed Read results on successful cache read, null otherwise
  120. * @filter This method may be filtered.
  121. */
  122. public static function read($name, $key, array $options = array()) {
  123. $options += array('conditions' => null, 'strategies' => true, 'write' => null);
  124. $settings = static::config();
  125. if (!isset($settings[$name])) {
  126. return false;
  127. }
  128. $conditions = $options['conditions'];
  129. if (is_callable($conditions) && !$conditions()) {
  130. return false;
  131. }
  132. $key = static::key($key);
  133. $method = static::adapter($name)->read($key);
  134. $params = compact('key');
  135. $filters = $settings[$name]['filters'];
  136. $result = static::_filter(__FUNCTION__, $params, $method, $filters);
  137. if ($result === null && ($write = $options['write'])) {
  138. $write = is_callable($write) ? $write() : $write;
  139. list($expiry, $value) = each($write);
  140. $value = is_callable($value) ? $value() : $value;
  141. if (static::write($name, $key, $value, $expiry)) {
  142. $result = $value;
  143. }
  144. }
  145. if ($options['strategies']) {
  146. $options = compact('key') + array('mode' => 'LIFO', 'class' => __CLASS__);
  147. $result = static::applyStrategies(__FUNCTION__, $name, $result, $options);
  148. }
  149. return $result;
  150. }
  151. /**
  152. * Delete a value from the specified cache configuration
  153. *
  154. * @param string $name The cache configuration to delete from
  155. * @param mixed $key Key to be deleted
  156. * @param mixed $options Options for the method and strategies.
  157. * @return boolean True on successful deletion, false otherwise
  158. * @filter This method may be filtered.
  159. */
  160. public static function delete($name, $key, array $options = array()) {
  161. $options += array('conditions' => null, 'strategies' => true);
  162. $settings = static::config();
  163. if (!isset($settings[$name])) {
  164. return false;
  165. }
  166. $conditions = $options['conditions'];
  167. if (is_callable($conditions) && !$conditions()) {
  168. return false;
  169. }
  170. $key = static::key($key);
  171. $method = static::adapter($name)->delete($key);
  172. $filters = $settings[$name]['filters'];
  173. if ($options['strategies']) {
  174. $options += array('key' => $key, 'class' => __CLASS__);
  175. $key = static::applyStrategies(__FUNCTION__, $name, $key, $options);
  176. }
  177. return static::_filter(__FUNCTION__, compact('key'), $method, $filters);
  178. }
  179. /**
  180. * Performs an atomic increment operation on specified numeric cache item
  181. * from the given cache configuration.
  182. *
  183. * @param string $name
  184. * @param string $key Key of numeric cache item to increment
  185. * @param integer $offset Offset to increment - defaults to 1.
  186. * @param mixed $options Options for this method.
  187. * @return mixed Item's new value on successful increment, false otherwise.
  188. * @filter This method may be filtered.
  189. */
  190. public static function increment($name, $key, $offset = 1, array $options = array()) {
  191. $options += array('conditions' => null);
  192. $settings = static::config();
  193. if (!isset($settings[$name])) {
  194. return false;
  195. }
  196. $conditions = $options['conditions'];
  197. if (is_callable($conditions) && !$conditions()) {
  198. return false;
  199. }
  200. $key = static::key($key);
  201. $method = static::adapter($name)->increment($key, $offset);
  202. $params = compact('key', 'offset');
  203. $filters = $settings[$name]['filters'];
  204. return static::_filter(__FUNCTION__, $params, $method, $filters);
  205. }
  206. /**
  207. * Performs an atomic decrement operation on specified numeric cache item
  208. * from the given cache configuration.
  209. *
  210. * @param string $name
  211. * @param string $key Key of numeric cache item to decrement
  212. * @param integer $offset Offset to decrement - defaults to 1.
  213. * @param mixed $options Options for this method.
  214. * @return mixed Item's new value on successful decrement, false otherwise.
  215. * @filter This method may be filtered.
  216. */
  217. public static function decrement($name, $key, $offset = 1, array $options = array()) {
  218. $options += array('conditions' => null);
  219. $settings = static::config();
  220. if (!isset($settings[$name])) {
  221. return false;
  222. }
  223. $conditions = $options['conditions'];
  224. if (is_callable($conditions) && !$conditions()) {
  225. return false;
  226. }
  227. $key = static::key($key);
  228. $method = static::adapter($name)->decrement($key, $offset);
  229. $params = compact('key', 'offset');
  230. $filters = $settings[$name]['filters'];
  231. return static::_filter(__FUNCTION__, $params, $method, $filters);
  232. }
  233. /**
  234. * Perform garbage collection on specified cache configuration.
  235. *
  236. * This method is not filterable.
  237. *
  238. * @param string $name The cache configuration to be cleaned
  239. * @return boolean True on successful clean, false otherwise
  240. */
  241. public static function clean($name) {
  242. $settings = static::config();
  243. return (isset($settings[$name])) ? static::adapter($name)->clean() : false;
  244. }
  245. /**
  246. * Remove all cache keys from specified configuration.
  247. *
  248. * This method is non-filterable.
  249. *
  250. * @param string $name The cache configuration to be cleared
  251. * @return boolean True on successful clearing, false otherwise
  252. */
  253. public static function clear($name) {
  254. $settings = static::config();
  255. return (isset($settings[$name])) ? static::adapter($name)->clear() : false;
  256. }
  257. }
  258. ?>