SimpleCacheEngine.php 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.7.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Cache;
  16. use Cake\Cache\CacheEngineInterface;
  17. use Psr\SimpleCache\CacheInterface;
  18. /**
  19. * Wrapper for Cake engines that allow them to support
  20. * the PSR16 Simple Cache Interface
  21. *
  22. * @since 3.7.0
  23. * @link https://www.php-fig.org/psr/psr-16/
  24. */
  25. class SimpleCacheEngine implements CacheInterface, CacheEngineInterface
  26. {
  27. /**
  28. * The wrapped cache engine object.
  29. *
  30. * @var \Cake\Cache\CacheEngine
  31. */
  32. protected $innerEngine;
  33. /**
  34. * Constructor
  35. *
  36. * @param \Cake\Cache\CacheEngine $innerEngine The decorated engine.
  37. */
  38. public function __construct(CacheEngine $innerEngine)
  39. {
  40. $this->innerEngine = $innerEngine;
  41. }
  42. /**
  43. * Ensure the validity of the given cache key.
  44. *
  45. * @param string $key Key to check.
  46. * @return void
  47. * @throws \Cake\Cache\InvalidArgumentException When the key is not valid.
  48. */
  49. protected function ensureValidKey($key)
  50. {
  51. if (!is_string($key) || strlen($key) === 0) {
  52. throw new InvalidArgumentException('A cache key must be a non-empty string.');
  53. }
  54. }
  55. /**
  56. * Ensure the validity of the given cache keys.
  57. *
  58. * @param mixed $keys The keys to check.
  59. * @return void
  60. * @throws \Cake\Cache\InvalidArgumentException When the keys are not valid.
  61. */
  62. protected function ensureValidKeys($keys)
  63. {
  64. if (!is_array($keys) && !($keys instanceof \Traversable)) {
  65. throw new InvalidArgumentException('A cache key set must be either an array or a Traversable.');
  66. }
  67. foreach ($keys as $key) {
  68. $this->ensureValidKey($key);
  69. }
  70. }
  71. /**
  72. * Fetches the value for a given key from the cache.
  73. *
  74. * @param string $key The unique key of this item in the cache.
  75. * @param mixed $default Default value to return if the key does not exist.
  76. * @return mixed The value of the item from the cache, or $default in case of cache miss.
  77. * @throws \Cake\Cache\InvalidArgumentException If the $key string is not a legal value.
  78. */
  79. public function get($key, $default = null)
  80. {
  81. $this->ensureValidKey($key);
  82. $result = $this->innerEngine->read($key);
  83. if ($result === false) {
  84. return $default;
  85. }
  86. return $result;
  87. }
  88. /**
  89. * Persists data in the cache, uniquely referenced by the given key with an optional expiration TTL time.
  90. *
  91. * @param string $key The key of the item to store.
  92. * @param mixed $value The value of the item to store, must be serializable.
  93. * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
  94. * the driver supports TTL then the library may set a default value
  95. * for it or let the driver take care of that.
  96. * @return bool True on success and false on failure.
  97. * @throws \Cake\Cache\InvalidArgumentException
  98. * MUST be thrown if the $key string is not a legal value.
  99. */
  100. public function set($key, $value, $ttl = null)
  101. {
  102. $this->ensureValidKey($key);
  103. if ($ttl !== null) {
  104. $restore = $this->innerEngine->getConfig('duration');
  105. $this->innerEngine->setConfig('duration', $ttl);
  106. }
  107. try {
  108. $result = $this->innerEngine->write($key, $value);
  109. return (bool)$result;
  110. } finally {
  111. if (isset($restore)) {
  112. $this->innerEngine->setConfig('duration', $restore);
  113. }
  114. }
  115. }
  116. /**
  117. * Delete an item from the cache by its unique key.
  118. *
  119. * @param string $key The unique cache key of the item to delete.
  120. * @return bool True if the item was successfully removed. False if there was an error.
  121. * @throws \Cake\Cache\InvalidArgumentException If the $key string is not a legal value.
  122. */
  123. public function delete($key)
  124. {
  125. $this->ensureValidKey($key);
  126. return $this->innerEngine->delete($key);
  127. }
  128. /**
  129. * Wipes clean the entire cache's keys.
  130. *
  131. * @return bool True on success and false on failure.
  132. */
  133. public function clear()
  134. {
  135. return $this->innerEngine->clear(false);
  136. }
  137. /**
  138. * Obtains multiple cache items by their unique keys.
  139. *
  140. * @param iterable $keys A list of keys that can obtained in a single operation.
  141. * @param mixed $default Default value to return for keys that do not exist.
  142. * @return iterable A list of key => value pairs. Cache keys that do not exist or are stale will have $default as value.
  143. * @throws \Cake\Cache\InvalidArgumentException If $keys is neither an array nor a Traversable,
  144. * or if any of the $keys are not a legal value.
  145. */
  146. public function getMultiple($keys, $default = null)
  147. {
  148. $this->ensureValidKeys($keys);
  149. $results = $this->innerEngine->readMany($keys);
  150. foreach ($results as $key => $value) {
  151. if ($value === false) {
  152. $results[$key] = $default;
  153. }
  154. }
  155. return $results;
  156. }
  157. /**
  158. * Persists a set of key => value pairs in the cache, with an optional TTL.
  159. *
  160. * @param iterable $values A list of key => value pairs for a multiple-set operation.
  161. * @param null|int|\DateInterval $ttl Optional. The TTL value of this item. If no value is sent and
  162. * the driver supports TTL then the library may set a default value
  163. * for it or let the driver take care of that.
  164. * @return bool True on success and false on failure.
  165. * @throws \Cake\Cache\InvalidArgumentException If $values is neither an array nor a Traversable,
  166. * or if any of the $values are not a legal value.
  167. */
  168. public function setMultiple($values, $ttl = null)
  169. {
  170. $this->ensureValidKeys(array_keys($values));
  171. if ($ttl !== null) {
  172. $restore = $this->innerEngine->getConfig('duration');
  173. $this->innerEngine->setConfig('duration', $ttl);
  174. }
  175. try {
  176. $result = $this->innerEngine->writeMany($values);
  177. foreach ($result as $key => $success) {
  178. if ($success === false) {
  179. return false;
  180. }
  181. }
  182. return true;
  183. } finally {
  184. if (isset($restore)) {
  185. $this->innerEngine->setConfig('duration', $restore);
  186. }
  187. }
  188. return false;
  189. }
  190. /**
  191. * Deletes multiple cache items in a single operation.
  192. *
  193. * @param iterable $keys A list of string-based keys to be deleted.
  194. * @return bool True if the items were successfully removed. False if there was an error.
  195. * @throws \Cake\Cache\InvalidArgumentException If $keys is neither an array nor a Traversable,
  196. * or if any of the $keys are not a legal value.
  197. */
  198. public function deleteMultiple($keys)
  199. {
  200. $this->ensureValidKeys($keys);
  201. $result = $this->innerEngine->deleteMany($keys);
  202. foreach ($result as $key => $success) {
  203. if ($success === false) {
  204. return false;
  205. }
  206. }
  207. return true;
  208. }
  209. /**
  210. * Determines whether an item is present in the cache.
  211. *
  212. * NOTE: It is recommended that has() is only to be used for cache warming type purposes
  213. * and not to be used within your live applications operations for get/set, as this method
  214. * is subject to a race condition where your has() will return true and immediately after,
  215. * another script can remove it making the state of your app out of date.
  216. *
  217. * @param string $key The cache item key.
  218. * @return bool
  219. * @throws \Cake\Cache\InvalidArgumentException If the $key string is not a legal value.
  220. */
  221. public function has($key)
  222. {
  223. return $this->get($key) !== null;
  224. }
  225. /**
  226. * {@inheritDoc}
  227. */
  228. public function add($key, $value)
  229. {
  230. return $this->innerEngine->add($key, $value);
  231. }
  232. /**
  233. * {@inheritDoc}
  234. */
  235. public function increment($key, $offset = 1)
  236. {
  237. return $this->innerEngine->increment($key, $offset);
  238. }
  239. /**
  240. * {@inheritDoc}
  241. */
  242. public function decrement($key, $offset = 1)
  243. {
  244. return $this->innerEngine->decrement($key, $offset);
  245. }
  246. /**
  247. * {@inheritDoc}
  248. */
  249. public function clearGroup($group)
  250. {
  251. return $this->innerEngine->clearGroup($group);
  252. }
  253. }