PageRenderTime 92ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/app/code/local/Evogue/PageCache/Model/Processor.php

https://github.com/arush/desparation-deprecated
PHP | 325 lines | 275 code | 48 blank | 2 comment | 58 complexity | 54b07250c3094678b783e72ca818ffe8 MD5 | raw file
  1. <?php
  2. class Evogue_PageCache_Model_Processor {
  3. const NO_CACHE_COOKIE = 'NO_CACHE';
  4. const XML_NODE_ALLOWED_CACHE = 'frontend/cache/requests';
  5. const XML_PATH_ALLOWED_DEPTH = 'system/page_cache/allowed_depth';
  6. const XML_PATH_LIFE_TIME = 'system/page_cache/lifetime'; /** @deprecated after 1.8 */
  7. const XML_PATH_CACHE_MULTICURRENCY = 'system/page_cache/multicurrency';
  8. const XML_PATH_CACHE_DEBUG = 'system/page_cache/debug';
  9. const REQUEST_ID_PREFIX = 'REQEST_';
  10. const CACHE_TAG = 'FPC'; // Full Page Cache, minimize
  11. const LAST_PRODUCT_COOKIE = 'LAST_PRODUCT';
  12. const METADATA_CACHE_SUFFIX = '_metadata';
  13. protected $_requestId;
  14. protected $_requestCacheId;
  15. protected $_requestTags;
  16. protected $_metaData = null;
  17. public function __construct() {
  18. $uri = $this->_getFullPageUrl();
  19. $pieces = explode('?', $uri);
  20. $uri = array_shift($pieces);
  21. if ($uri) {
  22. if (isset($_COOKIE['store'])) {
  23. $uri = $uri.'_'.$_COOKIE['store'];
  24. }
  25. if (isset($_COOKIE['currency'])) {
  26. $uri = $uri.'_'.$_COOKIE['currency'];
  27. }
  28. if (isset($_COOKIE[Evogue_PageCache_Model_Cookie::COOKIE_CUSTOMER_GROUP])) {
  29. $uri .= '_' . $_COOKIE[Evogue_PageCache_Model_Cookie::COOKIE_CUSTOMER_GROUP];
  30. }
  31. }
  32. $this->_requestId = $uri;
  33. $this->_requestCacheId = $this->prepareCacheId($this->_requestId);
  34. $this->_requestTags = array(self::CACHE_TAG);
  35. }
  36. public function prepareCacheId($id) {
  37. return self::REQUEST_ID_PREFIX . md5($id);
  38. }
  39. public function getRequestId() {
  40. return $this->_requestId;
  41. }
  42. public function getRequestCacheId() {
  43. return $this->_requestCacheId;
  44. }
  45. public function isAllowed() {
  46. if (!$this->_requestId) {
  47. return false;
  48. }
  49. if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
  50. return false;
  51. }
  52. if (isset($_COOKIE['NO_CACHE'])) {
  53. return false;
  54. }
  55. if (isset($_GET['no_cache'])) {
  56. return false;
  57. }
  58. return true;
  59. }
  60. public function extractContent($content) {
  61. Mage::app()->getRequest();
  62. if (!$content && $this->isAllowed()) {
  63. $subprocessorClass = $this->getMetadata('cache_subprocessor');
  64. if (!$subprocessorClass) {
  65. return $content;
  66. }
  67. $subprocessor = new $subprocessorClass;
  68. $cacheId = $this->prepareCacheId($subprocessor->getPageIdWithoutApp($this));
  69. $content = Mage::app()->loadCache($cacheId);
  70. if ($content) {
  71. if (function_exists('gzuncompress')) {
  72. $content = gzuncompress($content);
  73. }
  74. $content = $this->_processContent($content);
  75. // renew recently viewed products
  76. $productId = Mage::app()->loadCache($this->getRequestCacheId() . '_current_product_id');
  77. $countLimit = Mage::app()->loadCache($this->getRecentlyViewedCountCacheId());
  78. if ($productId && $countLimit) {
  79. Evogue_PageCache_Model_Cookie::registerViewedProducts($productId, $countLimit);
  80. }
  81. }
  82. }
  83. return $content;
  84. }
  85. public function getRecentlyViewedCountCacheId() {
  86. $cookieName = Mage_Core_Model_Store::COOKIE_NAME;
  87. return 'recently_viewed_count' . (isset($_COOKIE[$cookieName]) ? '_' . $_COOKIE[$cookieName] : '');
  88. }
  89. public function getSessionInfoCacheId() {
  90. $cookieName = Mage_Core_Model_Store::COOKIE_NAME;
  91. return 'full_page_cache_session_info' . (isset($_COOKIE[$cookieName]) ? '_' . $_COOKIE[$cookieName] : '');
  92. }
  93. protected function _processContent($content) {
  94. $placeholders = array();
  95. preg_match_all(
  96. Evogue_PageCache_Model_Container_Placeholder::HTML_NAME_PATTERN,
  97. $content, $placeholders, PREG_PATTERN_ORDER
  98. );
  99. $placeholders = array_unique($placeholders[1]);
  100. $containers = array();
  101. foreach ($placeholders as $definition) {
  102. $placeholder= new Evogue_PageCache_Model_Container_Placeholder($definition);
  103. $container = $placeholder->getContainerClass();
  104. if (!$container) {
  105. continue;
  106. }
  107. $container = new $container($placeholder);
  108. if (!$container->applyWithoutApp($content)) {
  109. $containers[] = $container;
  110. }
  111. }
  112. $isProcessed = empty($containers);
  113. // renew session cookie
  114. $sessionInfo = Mage::app()->loadCache($this->getSessionInfoCacheId());
  115. if ($sessionInfo) {
  116. $sessionInfo = unserialize($sessionInfo);
  117. foreach ($sessionInfo as $cookieName => $cookieInfo) {
  118. if (isset($_COOKIE[$cookieName]) && isset($cookieInfo['lifetime'])
  119. && isset($cookieInfo['path']) && isset($cookieInfo['domain'])
  120. && isset($cookieInfo['secure']) && isset($cookieInfo['httponly'])
  121. ) {
  122. $lifeTime = (0 == $cookieInfo['lifetime']) ? 0 : time() + $cookieInfo['lifetime'];
  123. setcookie($cookieName, $_COOKIE[$cookieName], $lifeTime,
  124. $cookieInfo['path'], $cookieInfo['domain'],
  125. $cookieInfo['secure'], $cookieInfo['httponly']
  126. );
  127. }
  128. }
  129. } else {
  130. $isProcessed = false;
  131. }
  132. $sidCookieName = $this->getMetadata('sid_cookie_name');
  133. $sidCookieValue = ($sidCookieName && isset($_COOKIE[$sidCookieName]) ? $_COOKIE[$sidCookieName] : '');
  134. Evogue_PageCache_Helper_Url::restoreSid($content, $sidCookieValue);
  135. if ($isProcessed) {
  136. return $content;
  137. } else {
  138. Mage::register('cached_page_content', $content);
  139. Mage::register('cached_page_containers', $containers);
  140. Mage::app()->getRequest()
  141. ->setModuleName('pagecache')
  142. ->setControllerName('request')
  143. ->setActionName('process')
  144. ->isStraight(true);
  145. $routingInfo = array(
  146. 'aliases' => $this->getMetadata('routing_aliases'),
  147. 'requested_route' => $this->getMetadata('routing_requested_route'),
  148. 'requested_controller' => $this->getMetadata('routing_requested_controller'),
  149. 'requested_action' => $this->getMetadata('routing_requested_action')
  150. );
  151. Mage::app()->getRequest()->setRoutingInfo($routingInfo);
  152. return false;
  153. }
  154. }
  155. public function addRequestTag($tag) {
  156. if (is_array($tag)) {
  157. $this->_requestTags = array_merge($this->_requestTags, $tag);
  158. } else {
  159. $this->_requestTags[] = $tag;
  160. }
  161. return $this;
  162. }
  163. public function getRequestTags() {
  164. return $this->_requestTags;
  165. }
  166. public function processRequestResponse(Zend_Controller_Request_Http $request, Zend_Controller_Response_Http $response) {
  167. if ($this->canProcessRequest($request)) {
  168. $processor = $this->getRequestProcessor($request);
  169. if ($processor && $processor->allowCache($request)) {
  170. $this->setMetadata('cache_subprocessor', get_class($processor));
  171. $cacheId = $this->prepareCacheId($processor->getPageIdInApp($this));
  172. $content = $processor->prepareContent($response);
  173. Evogue_PageCache_Helper_Url::replaceSid($content);
  174. if (function_exists('gzcompress')) {
  175. $content = gzcompress($content);
  176. }
  177. Mage::app()->saveCache($content, $cacheId, $this->getRequestTags());
  178. $this->setMetadata('routing_aliases', Mage::app()->getRequest()->getAliases());
  179. $this->setMetadata('routing_requested_route', Mage::app()->getRequest()->getRequestedRouteName());
  180. $this->setMetadata('routing_requested_controller',
  181. Mage::app()->getRequest()->getRequestedControllerName());
  182. $this->setMetadata('routing_requested_action', Mage::app()->getRequest()->getRequestedActionName());
  183. $this->setMetadata('sid_cookie_name', Mage::getSingleton('core/session')->getSessionName());
  184. $this->_saveMetadata();
  185. }
  186. }
  187. return $this;
  188. }
  189. public function canProcessRequest(Zend_Controller_Request_Http $request) {
  190. $res = $this->isAllowed();
  191. $res = $res && Mage::app()->useCache('full_page');
  192. if ($request->getParam('no_cache')) {
  193. $res = false;
  194. }
  195. if ($res) {
  196. $maxDepth = Mage::getStoreConfig(self::XML_PATH_ALLOWED_DEPTH);
  197. $queryParams = $request->getQuery();
  198. $res = count($queryParams)<=$maxDepth;
  199. }
  200. if ($res) {
  201. $multicurrency = Mage::getStoreConfig(self::XML_PATH_CACHE_MULTICURRENCY);
  202. if (!$multicurrency && !empty($_COOKIE['currency'])) {
  203. $res = false;
  204. }
  205. }
  206. return $res;
  207. }
  208. public function getRequestProcessor(Zend_Controller_Request_Http $request) {
  209. $processor = false;
  210. $configuration = Mage::getConfig()->getNode(self::XML_NODE_ALLOWED_CACHE);
  211. if ($configuration) {
  212. $configuration = $configuration->asArray();
  213. }
  214. $module = $request->getModuleName();
  215. if (isset($configuration[$module])) {
  216. $model = $configuration[$module];
  217. $controller = $request->getControllerName();
  218. if (is_array($configuration[$module]) && isset($configuration[$module][$controller])) {
  219. $model = $configuration[$module][$controller];
  220. $action = $request->getActionName();
  221. if (is_array($configuration[$module][$controller]) && isset($configuration[$module][$controller][$action])) {
  222. $model = $configuration[$module][$controller][$action];
  223. }
  224. }
  225. if (is_string($model)) {
  226. $processor = Mage::getModel($model);
  227. }
  228. }
  229. return $processor;
  230. }
  231. public function setMetadata($key, $value) {
  232. $this->_loadMetadata();
  233. $this->_metaData[$key] = $value;
  234. return $this;
  235. }
  236. public function getMetadata($key) {
  237. $this->_loadMetadata();
  238. return (isset($this->_metaData[$key])) ? $this->_metaData[$key] : null;
  239. }
  240. protected function _getFullPageUrl() {
  241. $uri = false;
  242. if (isset($_SERVER['HTTP_HOST'])) {
  243. $uri = $_SERVER['HTTP_HOST'];
  244. } elseif (isset($_SERVER['SERVER_NAME'])) {
  245. $uri = $_SERVER['SERVER_NAME'];
  246. }
  247. if ($uri) {
  248. if (isset($_SERVER['REQUEST_URI'])) {
  249. $uri.= $_SERVER['REQUEST_URI'];
  250. } elseif (!empty($_SERVER['IIS_WasUrlRewritten']) && !empty($_SERVER['UNENCODED_URL'])) {
  251. $uri.= $_SERVER['UNENCODED_URL'];
  252. } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
  253. $uri.= $_SERVER['ORIG_PATH_INFO'];
  254. if (!empty($_SERVER['QUERY_STRING'])) {
  255. $uri.= $_SERVER['QUERY_STRING'];
  256. }
  257. }
  258. }
  259. return $uri;
  260. }
  261. protected function _saveMetadata() {
  262. Mage::app()->saveCache(
  263. serialize($this->_metaData),
  264. $this->getRequestCacheId() . self::METADATA_CACHE_SUFFIX,
  265. $this->getRequestTags()
  266. );
  267. }
  268. protected function _loadMetadata() {
  269. if ($this->_metaData === null) {
  270. $cacheMetadata = Mage::app()->loadCache($this->getRequestCacheId() . self::METADATA_CACHE_SUFFIX);
  271. if ($cacheMetadata) {
  272. $cacheMetadata = unserialize($cacheMetadata);
  273. }
  274. $this->_metaData = (empty($cacheMetadata) || !is_array($cacheMetadata)) ? array() : $cacheMetadata;
  275. }
  276. }
  277. }