PageRenderTime 31ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/app/code/core/Enterprise/PageCache/Model/Container/Banner.php

https://bitbucket.org/kdms/sh-magento
PHP | 263 lines | 135 code | 28 blank | 100 comment | 14 complexity | 3ff1647c194510b9d3ad69be459ccfc0 MD5 | raw file
  1. <?php
  2. /**
  3. * Magento Enterprise Edition
  4. *
  5. * NOTICE OF LICENSE
  6. *
  7. * This source file is subject to the Magento Enterprise Edition License
  8. * that is bundled with this package in the file LICENSE_EE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://www.magentocommerce.com/license/enterprise-edition
  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@magentocommerce.com so we can send you a copy immediately.
  14. *
  15. * DISCLAIMER
  16. *
  17. * Do not edit or add to this file if you wish to upgrade Magento to newer
  18. * versions in the future. If you wish to customize Magento for your
  19. * needs please refer to http://www.magentocommerce.com for more information.
  20. *
  21. * @category Enterprise
  22. * @package Enterprise_PageCache
  23. * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
  24. * @license http://www.magentocommerce.com/license/enterprise-edition
  25. */
  26. /**
  27. * Banner widget container, renders and caches banner content.
  28. *
  29. * @category Enterprise
  30. * @package Enterprise_PageCache
  31. * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
  32. * @license http://www.magentocommerce.com/license/enterprise-edition
  33. */
  34. class Enterprise_PageCache_Model_Container_Banner
  35. extends Enterprise_PageCache_Model_Container_Abstract
  36. {
  37. /**
  38. * Array of ids of banner chosen to be shown to user this time
  39. */
  40. protected $_bannersSelected = null;
  41. /**
  42. * Array of ids of banners already shown during current serie
  43. */
  44. protected $_bannersSequence = null;
  45. /**
  46. * Get cache additional identifiers from cookies.
  47. * Customers are differentiated because they can have different content of banners (due to template variables)
  48. * or different sets of banners targeted to their segment.
  49. *
  50. * @return string
  51. */
  52. protected function _getIdentifier()
  53. {
  54. return $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::COOKIE_CUSTOMER, '');
  55. }
  56. /**
  57. * Returns cache identifier for informational data about customer banners
  58. *
  59. * @return string
  60. */
  61. protected function _getInfoCacheId()
  62. {
  63. return 'BANNER_INFORMATION_'
  64. . md5($this->_placeholder->getAttribute('cache_id')
  65. . '_' . $this->_getIdentifier());
  66. }
  67. /**
  68. * Saves informational cache, containing parameters used to show banners.
  69. * We don't use _saveCache() method internally, because it replaces sid in cache, that can be done only
  70. * after app is started, while this method can be called without app after rendering serie/shuffle banners.
  71. *
  72. * @param array $renderedParams
  73. * @return Enterprise_PageCache_Model_Container_Banner
  74. */
  75. protected function _saveInfoCache($renderedParams)
  76. {
  77. $data = serialize($renderedParams);
  78. $id = $this->_getInfoCacheId();
  79. $tags = array(Enterprise_PageCache_Model_Processor::CACHE_TAG);
  80. $lifetime = $this->_placeholder->getAttribute('cache_lifetime');
  81. if (!$lifetime) {
  82. $lifetime = false;
  83. }
  84. Enterprise_PageCache_Model_Cache::getCacheInstance()->save($data, $id, $tags, $lifetime);
  85. return $this;
  86. }
  87. /**
  88. * Loads informational cache, containing parameters used to show banners
  89. *
  90. * @return false|array
  91. */
  92. protected function _loadInfoCache()
  93. {
  94. $infoCacheId = $this->_getInfoCacheId();
  95. $data = $this->_loadCache($infoCacheId);
  96. if ($data === false) {
  97. return false;
  98. }
  99. return unserialize($data);
  100. }
  101. /**
  102. * Get cache identifier for banner block contents.
  103. * Used only after rendered banners are selected.
  104. *
  105. * @return string
  106. */
  107. protected function _getCacheId()
  108. {
  109. if ($this->_bannersSelected === null) {
  110. return false;
  111. }
  112. sort($this->_bannersSelected);
  113. return 'CONTAINER_BANNER_'
  114. . md5($this->_placeholder->getAttribute('cache_id')
  115. . '_' . $this->_getIdentifier())
  116. . '_' . implode(',', $this->_bannersSelected)
  117. . '_' . $this->_getCookieValue(Enterprise_PageCache_Model_Cookie::CUSTOMER_SEGMENT_IDS, '');
  118. }
  119. /**
  120. * Generates placeholder content before application was initialized and applies it to page content if possible.
  121. * First we get meta-data with list of prepared banner ids and shown ids. Then we select banners to render and
  122. * check whether we already have that content in cache.
  123. *
  124. * @param string $content
  125. * @return bool
  126. */
  127. public function applyWithoutApp(&$content)
  128. {
  129. // Load information about rendering process for current user
  130. $renderedParams = $this->_loadInfoCache();
  131. if ($renderedParams === false) {
  132. return false;
  133. }
  134. if (isset($renderedParams['bannersSequence'])) {
  135. $this->_bannersSequence = $renderedParams['bannersSequence'];
  136. }
  137. // Find a banner block to be rendered for this user
  138. $this->_bannersSelected = $this->_selectBannersToRender($renderedParams);
  139. if ($this->_bannersSelected) {
  140. $cacheId = $this->_getCacheId();
  141. $block = $this->_loadCache($cacheId);
  142. } else {
  143. // No banners to render - just fill with empty content
  144. $block = '';
  145. }
  146. if ($block !== false) {
  147. $this->_applyToContent($content, $block);
  148. return true;
  149. }
  150. return false;
  151. }
  152. /**
  153. * Selects the banners we want to show to the current customer.
  154. * The banners depend on the list of banner ids and rotation mode, that chooses banners to show from that list.
  155. *
  156. * @param array $renderedParams
  157. * @return array
  158. */
  159. protected function _selectBannersToRender($renderedParams)
  160. {
  161. $bannerIds = $renderedParams['bannerIds'];
  162. if (!$bannerIds) {
  163. return array();
  164. }
  165. $rotate = $this->_placeholder->getAttribute('rotate');
  166. switch ($rotate) {
  167. case Enterprise_Banner_Block_Widget_Banner::BANNER_WIDGET_RORATE_RANDOM:
  168. $bannerId = $bannerIds[array_rand($bannerIds, 1)];
  169. $result = array($bannerId);
  170. break;
  171. case Enterprise_Banner_Block_Widget_Banner::BANNER_WIDGET_RORATE_SERIES:
  172. case Enterprise_Banner_Block_Widget_Banner::BANNER_WIDGET_RORATE_SHUFFLE:
  173. $isShuffle = $rotate == Enterprise_Banner_Block_Widget_Banner::BANNER_WIDGET_RORATE_SHUFFLE;
  174. $bannerId = null;
  175. $bannersSequence = isset($renderedParams['bannersSequence']) ?
  176. $renderedParams['bannersSequence'] :
  177. array();
  178. if ($bannersSequence) {
  179. $canShowIds = array_merge(array_diff($bannerIds, $bannersSequence), array());
  180. if (!empty($canShowIds)) {
  181. // Stil not whole serie is shown, choose the banner to show
  182. $showKey = $isShuffle ? array_rand($canShowIds, 1) : 0;
  183. $bannerId = $canShowIds[$showKey];
  184. $bannersSequence[] = $bannerId;
  185. }
  186. }
  187. // Start new serie (either no banners has been shown at all or whole serie has been shown)
  188. if (!$bannerId) {
  189. $bannerKey = $isShuffle ? array_rand($bannerIds, 1) : 0;
  190. $bannerId = $bannerIds[$bannerKey];
  191. $bannersSequence = array($bannerId);
  192. }
  193. $renderedParams['bannersSequence'] = $bannersSequence;
  194. $this->_saveInfoCache($renderedParams); // So that serie progresses
  195. $result = array($bannerId);
  196. break;
  197. default:
  198. $result = $bannerIds;
  199. }
  200. return $result;
  201. }
  202. /**
  203. * Render banner block content
  204. *
  205. * @return string
  206. */
  207. protected function _renderBlock()
  208. {
  209. $block = $this->_getPlaceHolderBlock();
  210. $placeholder = $this->_placeholder;
  211. $parameters = array('name', 'types', 'display_mode', 'rotate', 'banner_ids', 'unique_id');
  212. foreach ($parameters as $parameter) {
  213. $value = $placeholder->getAttribute($parameter);
  214. $block->setData($parameter, $value);
  215. }
  216. /**
  217. * Ask block to render banners that we have selected. However block is not required to render that banners,
  218. * because something could change and these banners are not suitable any more (e.g. deleted, customer
  219. * changed his segment/group and so on) - in this case banner block will render suitable banner and return
  220. * new info options.
  221. */
  222. $suggestedParams = array();
  223. $suggestedParams['bannersSelected'] = $this->_bannersSelected;
  224. $suggestedParams['bannersSequence'] = $this->_bannersSequence;
  225. Mage::dispatchEvent('render_block', array('block' => $block, 'placeholder' => $this->_placeholder));
  226. $renderedInfo = $block->setSuggestedParams($suggestedParams)
  227. ->setTemplate($placeholder->getAttribute('template'))
  228. ->renderAndGetInfo();
  229. $renderedParams = $renderedInfo['params'];
  230. $this->_bannersSelected = $renderedParams['renderedBannerIds']; // Later _getCacheId() will use it
  231. unset($renderedParams['renderedBannerIds']); // We don't need it in cache info params
  232. $this->_saveInfoCache($renderedParams); // Save sequence params and possibly changed other params
  233. return $renderedInfo['html'];
  234. }
  235. }