File indexing completed on 2024-12-29 05:27:31
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_Controller 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 * @version $Id$ 0020 */ 0021 0022 /** 0023 * @see Zend_Controller_Action_Helper_Abstract 0024 */ 0025 // require_once 'Zend/Controller/Action/Helper/Abstract.php'; 0026 0027 /** 0028 * @see Zend_Controller_Action_Exception 0029 */ 0030 // require_once 'Zend/Controller/Action/Exception.php'; 0031 0032 /** 0033 * @see Zend_Cache_Manager 0034 */ 0035 // require_once 'Zend/Cache/Manager.php'; 0036 0037 /** 0038 * @category Zend 0039 * @package Zend_Controller 0040 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0041 * @license http://framework.zend.com/license/new-bsd New BSD License 0042 */ 0043 class Zend_Controller_Action_Helper_Cache 0044 extends Zend_Controller_Action_Helper_Abstract 0045 { 0046 0047 /** 0048 * Local Cache Manager object used by Helper 0049 * 0050 * @var Zend_Cache_Manager 0051 */ 0052 protected $_manager = null; 0053 0054 /** 0055 * Indexed map of Actions to attempt Page caching on by Controller 0056 * 0057 * @var array 0058 */ 0059 protected $_caching = array(); 0060 0061 /** 0062 * Indexed map of Tags by Controller and Action 0063 * 0064 * @var array 0065 */ 0066 protected $_tags = array(); 0067 0068 /** 0069 * Indexed map of Extensions by Controller and Action 0070 * 0071 * @var array 0072 */ 0073 protected $_extensions = array(); 0074 0075 /** 0076 * Track output buffering condition 0077 */ 0078 protected $_obStarted = false; 0079 0080 /** 0081 * Tell the helper which actions are cacheable and under which 0082 * tags (if applicable) they should be recorded with 0083 * 0084 * @param array $actions 0085 * @param array $tags 0086 * @return void 0087 */ 0088 public function direct(array $actions, array $tags = array(), $extension = null) 0089 { 0090 $controller = $this->getRequest()->getControllerName(); 0091 $actions = array_unique($actions); 0092 if (!isset($this->_caching[$controller])) { 0093 $this->_caching[$controller] = array(); 0094 } 0095 if (!empty($tags)) { 0096 $tags = array_unique($tags); 0097 if (!isset($this->_tags[$controller])) { 0098 $this->_tags[$controller] = array(); 0099 } 0100 } 0101 foreach ($actions as $action) { 0102 $this->_caching[$controller][] = $action; 0103 if (!empty($tags)) { 0104 $this->_tags[$controller][$action] = array(); 0105 foreach ($tags as $tag) { 0106 $this->_tags[$controller][$action][] = $tag; 0107 } 0108 } 0109 } 0110 if ($extension) { 0111 if (!isset($this->_extensions[$controller])) { 0112 $this->_extensions[$controller] = array(); 0113 } 0114 foreach ($actions as $action) { 0115 $this->_extensions[$controller][$action] = $extension; 0116 } 0117 } 0118 } 0119 0120 /** 0121 * Remove a specific page cache static file based on its 0122 * relative URL from the application's public directory. 0123 * The file extension is not required here; usually matches 0124 * the original REQUEST_URI that was cached. 0125 * 0126 * @param string $relativeUrl 0127 * @param bool $recursive 0128 * @return mixed 0129 */ 0130 public function removePage($relativeUrl, $recursive = false) 0131 { 0132 $cache = $this->getCache(Zend_Cache_Manager::PAGECACHE); 0133 $encodedCacheId = $this->_encodeCacheId($relativeUrl); 0134 0135 if ($recursive) { 0136 $backend = $cache->getBackend(); 0137 if (($backend instanceof Zend_Cache_Backend) 0138 && method_exists($backend, 'removeRecursively') 0139 ) { 0140 $result = $backend->removeRecursively($encodedCacheId); 0141 if (is_null($result) ) { 0142 $result = $backend->removeRecursively($relativeUrl); 0143 } 0144 return $result; 0145 } 0146 } 0147 0148 $result = $cache->remove($encodedCacheId); 0149 if (is_null($result) ) { 0150 $result = $cache->remove($relativeUrl); 0151 } 0152 return $result; 0153 } 0154 0155 /** 0156 * Remove a specific page cache static file based on its 0157 * relative URL from the application's public directory. 0158 * The file extension is not required here; usually matches 0159 * the original REQUEST_URI that was cached. 0160 * 0161 * @param array $tags 0162 * @return mixed 0163 */ 0164 public function removePagesTagged(array $tags) 0165 { 0166 return $this->getCache(Zend_Cache_Manager::PAGECACHE) 0167 ->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags); 0168 } 0169 0170 /** 0171 * Commence page caching for any cacheable actions 0172 * 0173 * @return void 0174 */ 0175 public function preDispatch() 0176 { 0177 $controller = $this->getRequest()->getControllerName(); 0178 $action = $this->getRequest()->getActionName(); 0179 $stats = ob_get_status(true); 0180 foreach ($stats as $status) { 0181 if ($status['name'] == 'Zend_Cache_Frontend_Page::_flush' 0182 || $status['name'] == 'Zend_Cache_Frontend_Capture::_flush') { 0183 $obStarted = true; 0184 } 0185 } 0186 if (!isset($obStarted) && isset($this->_caching[$controller]) && 0187 in_array($action, $this->_caching[$controller])) { 0188 $reqUri = $this->getRequest()->getRequestUri(); 0189 $tags = array(); 0190 if (isset($this->_tags[$controller][$action]) 0191 && !empty($this->_tags[$controller][$action])) { 0192 $tags = array_unique($this->_tags[$controller][$action]); 0193 } 0194 $extension = null; 0195 if (isset($this->_extensions[$controller][$action])) { 0196 $extension = $this->_extensions[$controller][$action]; 0197 } 0198 $this->getCache(Zend_Cache_Manager::PAGECACHE) 0199 ->start($this->_encodeCacheId($reqUri), $tags, $extension); 0200 } 0201 } 0202 0203 /** 0204 * Encode a Cache ID as hexadecimal. This is a workaround because Backend ID validation 0205 * is trapped in the Frontend classes. Will try to get this reversed for ZF 2.0 0206 * because it's a major annoyance to have IDs so restricted! 0207 * 0208 * @return string 0209 * @param string $requestUri 0210 */ 0211 protected function _encodeCacheId($requestUri) 0212 { 0213 return bin2hex($requestUri); 0214 } 0215 0216 /** 0217 * Set an instance of the Cache Manager for this helper 0218 * 0219 * @param Zend_Cache_Manager $manager 0220 * @return void 0221 */ 0222 public function setManager(Zend_Cache_Manager $manager) 0223 { 0224 $this->_manager = $manager; 0225 return $this; 0226 } 0227 0228 /** 0229 * Get the Cache Manager instance or instantiate the object if not 0230 * exists. Attempts to load from bootstrap if available. 0231 * 0232 * @return Zend_Cache_Manager 0233 */ 0234 public function getManager() 0235 { 0236 if ($this->_manager !== null) { 0237 return $this->_manager; 0238 } 0239 $front = Zend_Controller_Front::getInstance(); 0240 if ($front->getParam('bootstrap') 0241 && $front->getParam('bootstrap')->getResource('CacheManager')) { 0242 return $front->getParam('bootstrap') 0243 ->getResource('CacheManager'); 0244 } 0245 $this->_manager = new Zend_Cache_Manager; 0246 return $this->_manager; 0247 } 0248 0249 /** 0250 * Return a list of actions for the current Controller marked for 0251 * caching 0252 * 0253 * @return array 0254 */ 0255 public function getCacheableActions() 0256 { 0257 return $this->_caching; 0258 } 0259 0260 /** 0261 * Return a list of tags set for all cacheable actions 0262 * 0263 * @return array 0264 */ 0265 public function getCacheableTags() 0266 { 0267 return $this->_tags; 0268 } 0269 0270 /** 0271 * Proxy non-matched methods back to Zend_Cache_Manager where 0272 * appropriate 0273 * 0274 * @param string $method 0275 * @param array $args 0276 * @return mixed 0277 */ 0278 public function __call($method, $args) 0279 { 0280 if (method_exists($this->getManager(), $method)) { 0281 return call_user_func_array( 0282 array($this->getManager(), $method), $args 0283 ); 0284 } 0285 throw new Zend_Controller_Action_Exception('Method does not exist:' 0286 . $method); 0287 } 0288 0289 }