Core.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Cache;
  7. class Core extends \Zend_Cache_Core
  8. {
  9. /**
  10. * Available options
  11. *
  12. * ====> (array) backend_decorators :
  13. * - array of decorators to decorate cache backend. Each element of this array should contain:
  14. * -- 'class' - concrete decorator, descendant of \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator
  15. * -- 'options' - optional array of specific decorator options
  16. * @var array
  17. */
  18. protected $_specificOptions = ['backend_decorators' => [], 'disable_save' => false];
  19. /**
  20. * Make and return a cache id
  21. *
  22. * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null
  23. *
  24. * @param string $cacheId Cache id
  25. * @return string Cache id (with or without prefix)
  26. */
  27. protected function _id($cacheId)
  28. {
  29. if ($cacheId !== null) {
  30. $cacheId = str_replace('.', '__', $cacheId); //reduce collision chances
  31. $cacheId = preg_replace('/([^a-zA-Z0-9_]{1,1})/', '_', $cacheId);
  32. if (isset($this->_options['cache_id_prefix'])) {
  33. $cacheId = $this->_options['cache_id_prefix'] . $cacheId;
  34. }
  35. }
  36. return $cacheId;
  37. }
  38. /**
  39. * Prepare tags
  40. *
  41. * @param string[] $tags
  42. * @return string[]
  43. */
  44. protected function _tags($tags)
  45. {
  46. foreach ($tags as $key => $tag) {
  47. $tags[$key] = $this->_id($tag);
  48. }
  49. return $tags;
  50. }
  51. /**
  52. * Save some data in a cache
  53. *
  54. * @param mixed $data Data to put in cache (can be another type than string if
  55. * automatic_serialization is on)
  56. * @param null|string $cacheId Cache id (if not set, the last cache id will be used)
  57. * @param string[] $tags Cache tags
  58. * @param bool|int $specificLifetime If != false, set a specific lifetime for this cache record
  59. * (null => infinite lifetime)
  60. * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by
  61. * some particular backends
  62. * @return bool True if no problem
  63. */
  64. public function save($data, $cacheId = null, $tags = [], $specificLifetime = false, $priority = 8)
  65. {
  66. if ($this->getOption('disable_save')) {
  67. return true;
  68. }
  69. $tags = $this->_tags($tags);
  70. return parent::save($data, $cacheId, $tags, $specificLifetime, $priority);
  71. }
  72. /**
  73. * Clean cache entries
  74. *
  75. * Available modes are :
  76. * 'all' (default) => remove all cache entries ($tags is not used)
  77. * 'old' => remove too old cache entries ($tags is not used)
  78. * 'matchingTag' => remove cache entries matching all given tags
  79. * ($tags can be an array of strings or a single string)
  80. * 'notMatchingTag' => remove cache entries not matching one of the given tags
  81. * ($tags can be an array of strings or a single string)
  82. * 'matchingAnyTag' => remove cache entries matching any given tags
  83. * ($tags can be an array of strings or a single string)
  84. *
  85. * @param string $mode
  86. * @param string[] $tags
  87. * @throws \Zend_Cache_Exception
  88. * @return bool True if ok
  89. */
  90. public function clean($mode = 'all', $tags = [])
  91. {
  92. $tags = $this->_tags($tags);
  93. return parent::clean($mode, $tags);
  94. }
  95. /**
  96. * Return an array of stored cache ids which match given tags
  97. *
  98. * In case of multiple tags, a logical AND is made between tags
  99. *
  100. * @param string[] $tags array of tags
  101. * @return string[] array of matching cache ids (string)
  102. */
  103. public function getIdsMatchingTags($tags = [])
  104. {
  105. $tags = $this->_tags($tags);
  106. return parent::getIdsMatchingTags($tags);
  107. }
  108. /**
  109. * Return an array of stored cache ids which don't match given tags
  110. *
  111. * In case of multiple tags, a logical OR is made between tags
  112. *
  113. * @param string[] $tags array of tags
  114. * @return string[] array of not matching cache ids (string)
  115. */
  116. public function getIdsNotMatchingTags($tags = [])
  117. {
  118. $tags = $this->_tags($tags);
  119. return parent::getIdsNotMatchingTags($tags);
  120. }
  121. /**
  122. * Set the backend
  123. *
  124. * @param \Zend_Cache_Backend $backendObject
  125. * @return void
  126. */
  127. public function setBackend(\Zend_Cache_Backend $backendObject)
  128. {
  129. $backendObject = $this->_decorateBackend($backendObject);
  130. parent::setBackend($backendObject);
  131. }
  132. /**
  133. * Decorate cache backend with additional functionality
  134. *
  135. * @param \Zend_Cache_Backend $backendObject
  136. * @return \Zend_Cache_Backend
  137. */
  138. protected function _decorateBackend(\Zend_Cache_Backend $backendObject)
  139. {
  140. if (!is_array($this->_specificOptions['backend_decorators'])) {
  141. \Zend_Cache::throwException("'backend_decorator' option should be an array");
  142. }
  143. foreach ($this->_specificOptions['backend_decorators'] as $decoratorName => $decoratorOptions) {
  144. if (!is_array($decoratorOptions) || !array_key_exists('class', $decoratorOptions)) {
  145. \Zend_Cache::throwException(
  146. "Concrete decorator options in '" . $decoratorName . "' should be an array containing 'class' key"
  147. );
  148. }
  149. $classOptions = array_key_exists('options', $decoratorOptions) ? $decoratorOptions['options'] : [];
  150. $classOptions['concrete_backend'] = $backendObject;
  151. if (!class_exists($decoratorOptions['class'])) {
  152. \Zend_Cache::throwException(
  153. "Class '" . $decoratorOptions['class'] . "' specified in '" . $decoratorName . "' does not exist"
  154. );
  155. }
  156. $backendObject = new $decoratorOptions['class']($classOptions);
  157. if (!$backendObject instanceof \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator) {
  158. \Zend_Cache::throwException(
  159. "Decorator in '" .
  160. $decoratorName .
  161. "' should extend \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator"
  162. );
  163. }
  164. }
  165. return $backendObject;
  166. }
  167. }