/Controller/Action/Helper/Cache.php

https://github.com/massiveart/ZF-ZOOLU · PHP · 256 lines · 114 code · 19 blank · 123 comment · 18 complexity · 39b2f31f7a27e29bcdc20d1d867faaa7 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_Controller
  17. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. * @version $Id$
  20. */
  21. /**
  22. * @see Zend_Controller_Action_Helper_Abstract
  23. */
  24. require_once 'Zend/Controller/Action/Helper/Abstract.php';
  25. /**
  26. * @see Zend_Controller_Action_Exception
  27. */
  28. require_once 'Zend/Controller/Action/Exception.php';
  29. /**
  30. * @see Zend_Cache_Manager
  31. */
  32. require_once 'Zend/Cache/Manager.php';
  33. /**
  34. * @category Zend
  35. * @package Zend_Controller
  36. * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
  37. * @license http://framework.zend.com/license/new-bsd New BSD License
  38. */
  39. class Zend_Controller_Action_Helper_Cache
  40. extends Zend_Controller_Action_Helper_Abstract
  41. {
  42. /**
  43. * Local Cache Manager object used by Helper
  44. *
  45. * @var Zend_Cache_Manager
  46. */
  47. protected $_manager = null;
  48. /**
  49. * Indexed map of Actions to attempt Page caching on by Controller
  50. *
  51. * @var array
  52. */
  53. protected $_caching = array();
  54. /**
  55. * Indexed map of Tags by Controller and Action
  56. *
  57. * @var array
  58. */
  59. protected $_tags = array();
  60. /**
  61. * Track output buffering condition
  62. */
  63. protected $_obStarted = false;
  64. /**
  65. * Tell the helper which actions are cacheable and under which
  66. * tags (if applicable) they should be recorded with
  67. *
  68. * @param array $actions
  69. * @param array $tags
  70. * @return void
  71. */
  72. public function direct(array $actions, array $tags = array())
  73. {
  74. $controller = $this->getRequest()->getControllerName();
  75. $actions = array_unique($actions);
  76. if (!isset($this->_caching[$controller])) {
  77. $this->_caching[$controller] = array();
  78. }
  79. if (!empty($tags)) {
  80. $tags = array_unique($tags);
  81. if (!isset($this->_tags[$controller])) {
  82. $this->_tags[$controller] = array();
  83. }
  84. }
  85. foreach ($actions as $action) {
  86. $this->_caching[$controller][] = $action;
  87. if (!empty($tags)) {
  88. $this->_tags[$controller][$action] = array();
  89. foreach ($tags as $tag) {
  90. $this->_tags[$controller][$action][] = $tag;
  91. }
  92. }
  93. }
  94. }
  95. /**
  96. * Remove a specific page cache static file based on its
  97. * relative URL from the application's public directory.
  98. * The file extension is not required here; usually matches
  99. * the original REQUEST_URI that was cached.
  100. *
  101. * @param string $relativeUrl
  102. * @param bool $recursive
  103. * @return mixed
  104. */
  105. public function removePage($relativeUrl, $recursive = false)
  106. {
  107. if ($recursive) {
  108. return $this->getCache(Zend_Cache_Manager::PAGECACHE)
  109. ->getBackend()->removeRecursive($relativeUrl);
  110. } else {
  111. return $this->getCache(Zend_Cache_Manager::PAGECACHE)
  112. ->getBackend()->remove($relativeUrl);
  113. }
  114. }
  115. /**
  116. * Remove a specific page cache static file based on its
  117. * relative URL from the application's public directory.
  118. * The file extension is not required here; usually matches
  119. * the original REQUEST_URI that was cached.
  120. *
  121. * @param array $tags
  122. * @return mixed
  123. */
  124. public function removePagesTagged(array $tags)
  125. {
  126. return $this->getCache(Zend_Cache_Manager::PAGECACHE)
  127. ->clean(Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG, $tags);
  128. }
  129. /**
  130. * Commence page caching for any cacheable actions
  131. *
  132. * @return void
  133. */
  134. public function preDispatch()
  135. {
  136. $controller = $this->getRequest()->getControllerName();
  137. $action = $this->getRequest()->getActionName();
  138. $stats = ob_get_status(true);
  139. foreach ($stats as $status) {
  140. if ($status['name'] == 'Zend_Cache_Frontend_Page::_flush'
  141. || $status['name'] == 'Zend_Cache_Frontend_Capture::_flush') {
  142. $obStarted = true;
  143. }
  144. }
  145. if (!isset($obStarted) && isset($this->_caching[$controller]) &&
  146. in_array($action, $this->_caching[$controller])) {
  147. $reqUri = $this->getRequest()->getRequestUri();
  148. $tags = array();
  149. if (isset($this->_tags[$controller][$action])
  150. && !empty($this->_tags[$controller][$action])) {
  151. $tags = array_unique($this->_tags[$controller][$action]);
  152. }
  153. $this->getCache(Zend_Cache_Manager::PAGECACHE)
  154. ->start($this->_encodeCacheId($reqUri), $tags);
  155. }
  156. }
  157. /**
  158. * Encode a Cache ID as hexadecimal. This is a workaround because Backend ID validation
  159. * is trapped in the Frontend classes. Will try to get this reversed for ZF 2.0
  160. * because it's a major annoyance to have IDs so restricted!
  161. *
  162. * @return string
  163. * @param string $requestUri
  164. */
  165. protected function _encodeCacheId($requestUri)
  166. {
  167. return bin2hex($requestUri);
  168. }
  169. /**
  170. * Set an instance of the Cache Manager for this helper
  171. *
  172. * @param Zend_Cache_Manager $manager
  173. * @return void
  174. */
  175. public function setManager(Zend_Cache_Manager $manager)
  176. {
  177. $this->_manager = $manager;
  178. return $this;
  179. }
  180. /**
  181. * Get the Cache Manager instance or instantiate the object if not
  182. * exists. Attempts to load from bootstrap if available.
  183. *
  184. * @return Zend_Cache_Manager
  185. */
  186. public function getManager()
  187. {
  188. if (!is_null($this->_manager)) {
  189. return $this->_manager;
  190. }
  191. $front = Zend_Controller_Front::getInstance();
  192. if ($front->getParam('bootstrap')
  193. && $front->getParam('bootstrap')->getResource('CacheManager')) {
  194. return $front->getParam('bootstrap')
  195. ->getResource('CacheManager');
  196. }
  197. $this->_manager = new Zend_Cache_Manager;
  198. return $this->_manager;
  199. }
  200. /**
  201. * Return a list of actions for the current Controller marked for
  202. * caching
  203. *
  204. * @return array
  205. */
  206. public function getCacheableActions()
  207. {
  208. return $this->_caching;
  209. }
  210. /**
  211. * Return a list of tags set for all cacheable actions
  212. *
  213. * @return array
  214. */
  215. public function getCacheableTags()
  216. {
  217. return $this->_tags;
  218. }
  219. /**
  220. * Proxy non-matched methods back to Zend_Cache_Manager where
  221. * appropriate
  222. *
  223. * @param string $method
  224. * @param array $args
  225. * @return mixed
  226. */
  227. public function __call($method, $args)
  228. {
  229. if (method_exists($this->getManager(), $method)) {
  230. return call_user_func_array(
  231. array($this->getManager(), $method), $args
  232. );
  233. }
  234. throw new Zend_Controller_Action_Exception('Method does not exist:'
  235. . $method);
  236. }
  237. }