(array) backend_decorators : * - array of decorators to decorate cache backend. Each element of this array should contain: * -- 'class' - concrete decorator, descendant of \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator * -- 'options' - optional array of specific decorator options * @var array */ protected $_specificOptions = ['backend_decorators' => [], 'disable_save' => false]; /** * Make and return a cache id * * Checks 'cache_id_prefix' and returns new id with prefix or simply the id if null * * @param string $cacheId Cache id * @return string Cache id (with or without prefix) */ protected function _id($cacheId) { if ($cacheId !== null) { $cacheId = str_replace('.', '__', $cacheId); //reduce collision chances $cacheId = preg_replace('/([^a-zA-Z0-9_]{1,1})/', '_', $cacheId); if (isset($this->_options['cache_id_prefix'])) { $cacheId = $this->_options['cache_id_prefix'] . $cacheId; } } return $cacheId; } /** * Prepare tags * * @param string[] $tags * @return string[] */ protected function _tags($tags) { foreach ($tags as $key => $tag) { $tags[$key] = $this->_id($tag); } return $tags; } /** * Save some data in a cache * * @param mixed $data Data to put in cache (can be another type than string if * automatic_serialization is on) * @param null|string $cacheId Cache id (if not set, the last cache id will be used) * @param string[] $tags Cache tags * @param bool|int $specificLifetime If != false, set a specific lifetime for this cache record * (null => infinite lifetime) * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by * some particular backends * @return bool True if no problem */ public function save($data, $cacheId = null, $tags = [], $specificLifetime = false, $priority = 8) { if ($this->getOption('disable_save')) { return true; } $tags = $this->_tags($tags); return parent::save($data, $cacheId, $tags, $specificLifetime, $priority); } /** * Clean cache entries * * Available modes are : * 'all' (default) => remove all cache entries ($tags is not used) * 'old' => remove too old cache entries ($tags is not used) * 'matchingTag' => remove cache entries matching all given tags * ($tags can be an array of strings or a single string) * 'notMatchingTag' => remove cache entries not matching one of the given tags * ($tags can be an array of strings or a single string) * 'matchingAnyTag' => remove cache entries matching any given tags * ($tags can be an array of strings or a single string) * * @param string $mode * @param string[] $tags * @throws \Zend_Cache_Exception * @return bool True if ok */ public function clean($mode = 'all', $tags = []) { $tags = $this->_tags($tags); return parent::clean($mode, $tags); } /** * Return an array of stored cache ids which match given tags * * In case of multiple tags, a logical AND is made between tags * * @param string[] $tags array of tags * @return string[] array of matching cache ids (string) */ public function getIdsMatchingTags($tags = []) { $tags = $this->_tags($tags); return parent::getIdsMatchingTags($tags); } /** * Return an array of stored cache ids which don't match given tags * * In case of multiple tags, a logical OR is made between tags * * @param string[] $tags array of tags * @return string[] array of not matching cache ids (string) */ public function getIdsNotMatchingTags($tags = []) { $tags = $this->_tags($tags); return parent::getIdsNotMatchingTags($tags); } /** * Set the backend * * @param \Zend_Cache_Backend $backendObject * @return void */ public function setBackend(\Zend_Cache_Backend $backendObject) { $backendObject = $this->_decorateBackend($backendObject); parent::setBackend($backendObject); } /** * Decorate cache backend with additional functionality * * @param \Zend_Cache_Backend $backendObject * @return \Zend_Cache_Backend */ protected function _decorateBackend(\Zend_Cache_Backend $backendObject) { if (!is_array($this->_specificOptions['backend_decorators'])) { \Zend_Cache::throwException("'backend_decorator' option should be an array"); } foreach ($this->_specificOptions['backend_decorators'] as $decoratorName => $decoratorOptions) { if (!is_array($decoratorOptions) || !array_key_exists('class', $decoratorOptions)) { \Zend_Cache::throwException( "Concrete decorator options in '" . $decoratorName . "' should be an array containing 'class' key" ); } $classOptions = array_key_exists('options', $decoratorOptions) ? $decoratorOptions['options'] : []; $classOptions['concrete_backend'] = $backendObject; if (!class_exists($decoratorOptions['class'])) { \Zend_Cache::throwException( "Class '" . $decoratorOptions['class'] . "' specified in '" . $decoratorName . "' does not exist" ); } $backendObject = new $decoratorOptions['class']($classOptions); if (!$backendObject instanceof \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator) { \Zend_Cache::throwException( "Decorator in '" . $decoratorName . "' should extend \Magento\Framework\Cache\Backend\Decorator\AbstractDecorator" ); } } return $backendObject; } }