Version Notes
N/A
Download this release
Release Info
Developer | Jonathan Selander |
Extension | Made_Cache |
Version | 1.0.0 |
Comparing to | |
See all releases |
Version 1.0.0
- app/code/community/Made/Cache/Block/Catalog/Product/List.php +86 -0
- app/code/community/Made/Cache/Block/Catalog/Product/View.php +50 -0
- app/code/community/Made/Cache/Model/Layout.php +216 -0
- app/code/community/Made/Cache/Model/Observer.php +84 -0
- app/code/community/Made/Cache/controllers/VarnishController.php +45 -0
- app/code/community/Made/Cache/etc/config.xml +92 -0
- app/design/frontend/base/default/layout/madecache.xml +43 -0
- app/etc/modules/Made_Cache.xml +9 -0
- package.xml +28 -0
app/code/community/Made/Cache/Block/Catalog/Product/List.php
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Granular product list cache
|
4 |
+
*
|
5 |
+
* @package Made_Cache
|
6 |
+
* @author info@madepeople.se
|
7 |
+
* @copyright Copyright (c) 2012 Made People AB. (http://www.madepeople.se/)
|
8 |
+
*/
|
9 |
+
class Made_Cache_Block_Catalog_Product_List extends Mage_Catalog_Block_Product_List
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Depending on block usage, the category id resides in different places
|
13 |
+
*
|
14 |
+
* @return int
|
15 |
+
*/
|
16 |
+
protected function _getCategoryIdForCache()
|
17 |
+
{
|
18 |
+
return $this->getCategoryId() ?
|
19 |
+
$this->getCategoryId() :
|
20 |
+
Mage::getSingleton('catalog/layer')
|
21 |
+
->getCurrentCategory()
|
22 |
+
->getId()
|
23 |
+
;
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Clear on the specific category id and it's child products - when
|
28 |
+
* a product is saved, the price can have changed and the cache must
|
29 |
+
* be cleared
|
30 |
+
*
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function getCacheTags()
|
34 |
+
{
|
35 |
+
$tags = parent::getCacheTags();
|
36 |
+
$tags[] = Mage_Catalog_Model_Category::CACHE_TAG . '_' .
|
37 |
+
$this->_getCategoryIdForCache();
|
38 |
+
|
39 |
+
foreach ($this->_getProductCollection() as $_product) {
|
40 |
+
$tags[] = Mage_Catalog_Model_Product::CACHE_TAG."_".$_product->getId();
|
41 |
+
}
|
42 |
+
|
43 |
+
return $tags;
|
44 |
+
}
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Take into concern all variables that can affect the product listing
|
48 |
+
*
|
49 |
+
* @return array
|
50 |
+
*/
|
51 |
+
public function getCacheKeyInfo()
|
52 |
+
{
|
53 |
+
$keys = parent::getCacheKeyInfo();
|
54 |
+
|
55 |
+
if (!is_array($keys)) {
|
56 |
+
$keys = array();
|
57 |
+
}
|
58 |
+
|
59 |
+
$_taxRateRequest = Mage::getModel('tax/calculation')->getRateRequest();
|
60 |
+
$_customer = Mage::getSingleton('customer/session')->getCustomer();
|
61 |
+
$_categoryId = $this->_getCategoryIdForCache();
|
62 |
+
$_toolbar = new Mage_Catalog_Block_Product_List_Toolbar();
|
63 |
+
|
64 |
+
foreach (Mage::app()->getRequest()->getParams() as $key => $value) {
|
65 |
+
if (is_array($value)) {
|
66 |
+
$value = implode('_', $value);
|
67 |
+
}
|
68 |
+
$keys[] = $key . $value;
|
69 |
+
}
|
70 |
+
|
71 |
+
return array_merge($keys, array(
|
72 |
+
$_categoryId,
|
73 |
+
$_toolbar->getCurrentOrder(),
|
74 |
+
$_toolbar->getCurrentDirection(),
|
75 |
+
$_toolbar->getCurrentMode(),
|
76 |
+
$_toolbar->getCurrentPage(),
|
77 |
+
$_toolbar->getLimit(),
|
78 |
+
$_customer->getGroupId(),
|
79 |
+
$_taxRateRequest->getCountryId(),
|
80 |
+
$_taxRateRequest->getRegionId(),
|
81 |
+
$_taxRateRequest->getPostcode(),
|
82 |
+
$_taxRateRequest->getCustomerClassId(),
|
83 |
+
Mage::registry('current_tag')
|
84 |
+
));
|
85 |
+
}
|
86 |
+
}
|
app/code/community/Made/Cache/Block/Catalog/Product/View.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Granular product view cache
|
4 |
+
*
|
5 |
+
* @package Made_Cache
|
6 |
+
* @author info@madepeople.se
|
7 |
+
* @copyright Copyright (c) 2012 Made People AB. (http://www.madepeople.se/)
|
8 |
+
*/
|
9 |
+
class Made_Cache_Block_Catalog_Product_View extends Mage_Catalog_Block_Product_View
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Only clear on the specific product id - otherwise one product save
|
13 |
+
* invalidates cache for all products
|
14 |
+
*
|
15 |
+
* @return string
|
16 |
+
*/
|
17 |
+
public function getCacheTags()
|
18 |
+
{
|
19 |
+
$tags = parent::getCacheTags();
|
20 |
+
$tags[] = Mage_Catalog_Model_Product::CACHE_TAG . '_' . $this->getProduct()->getId();
|
21 |
+
return $tags;
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Take into concern all variables that can affect the product view
|
26 |
+
*
|
27 |
+
* @return array
|
28 |
+
*/
|
29 |
+
public function getCacheKeyInfo()
|
30 |
+
{
|
31 |
+
$keys = parent::getCacheKeyInfo();
|
32 |
+
|
33 |
+
if (!is_array($keys)) {
|
34 |
+
$keys = array();
|
35 |
+
}
|
36 |
+
|
37 |
+
$_taxCalculator = Mage::getModel('tax/calculation');
|
38 |
+
$_customer = Mage::getSingleton('customer/session')->getCustomer();
|
39 |
+
$_product = $this->getProduct();
|
40 |
+
|
41 |
+
return array_merge($keys, array(
|
42 |
+
$_product->getId(),
|
43 |
+
$_customer->getGroupId(),
|
44 |
+
$_taxCalculator->getRate(
|
45 |
+
$_taxCalculator->getRateRequest()
|
46 |
+
->setProductClassId($_product->getTaxClassId())
|
47 |
+
)
|
48 |
+
));
|
49 |
+
}
|
50 |
+
}
|
app/code/community/Made/Cache/Model/Layout.php
ADDED
@@ -0,0 +1,216 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Injects custom layout XML attributes and handles arbitrary block rendering
|
4 |
+
* including different layout handle definitions
|
5 |
+
*
|
6 |
+
* @package Made_Cache
|
7 |
+
* @author info@madepeople.se
|
8 |
+
* @copyright Copyright (c) 2012 Made People AB. (http://www.madepeople.se/)
|
9 |
+
*/
|
10 |
+
class Made_Cache_Model_Layout extends Mage_Core_Model_Layout
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Keep track of which blocks to cache
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected $_cacheBlocks = array();
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Default cache lifetime
|
21 |
+
*
|
22 |
+
* @var int
|
23 |
+
*/
|
24 |
+
protected $_defaultCacheLifetime = 9999999999;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Aggregate <reference> tags into the final XML to be able to
|
28 |
+
* determine if child blocks should be instantiated or not, as well as
|
29 |
+
* not try to render blocks in vain
|
30 |
+
*
|
31 |
+
* @return Mage_Core_Model_Layout
|
32 |
+
*/
|
33 |
+
public function generateXml()
|
34 |
+
{
|
35 |
+
parent::generateXml();
|
36 |
+
$xml = $this->getNode();
|
37 |
+
$doc = new DOMDocument;
|
38 |
+
$doc->loadXML($xml->asXML());
|
39 |
+
$xpath = new DOMXpath($doc);
|
40 |
+
|
41 |
+
// Aggregate references into one layout tree
|
42 |
+
$references = $xpath->query("//reference");
|
43 |
+
foreach ($references as $node) {
|
44 |
+
$blockName = $node->getAttribute('name');
|
45 |
+
$nodeList = $xpath->query("//block[@name='".$blockName."']");
|
46 |
+
if ($nodeList->length) {
|
47 |
+
$blockNode = $nodeList->item(0);
|
48 |
+
if ($node->hasChildNodes()) {
|
49 |
+
$childNodes = $xpath->query('*', $node);
|
50 |
+
foreach ($childNodes as $child) {
|
51 |
+
if ($child->nodeType == XML_ELEMENT_NODE) {
|
52 |
+
$blockNode->appendChild($child);
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
}
|
57 |
+
$node->parentNode->removeChild($node);
|
58 |
+
}
|
59 |
+
$xml = new Mage_Core_Model_Layout_Element($doc->saveXML());
|
60 |
+
$this->setXml($xml);
|
61 |
+
|
62 |
+
// Find blocks to cache
|
63 |
+
$cacheList = $xml->xpath("//cache/*");
|
64 |
+
if (count($cacheList)) {
|
65 |
+
foreach ($cacheList as $node) {
|
66 |
+
$lifetime = (int)$node->getAttribute('lifetime');
|
67 |
+
if (empty($lifetime)) {
|
68 |
+
$lifetime = $this->_defaultCacheLifetime;
|
69 |
+
}
|
70 |
+
$this->_cacheBlocks[(string)$node] = $lifetime;
|
71 |
+
}
|
72 |
+
}
|
73 |
+
|
74 |
+
// Find eventual nocache tags
|
75 |
+
$noCacheList = $xml->xpath("//nocache/*");
|
76 |
+
if (count($noCacheList)) {
|
77 |
+
foreach ($noCacheList as $node) {
|
78 |
+
$blockName = trim((string)$node);
|
79 |
+
if (isset($this->_cacheBlocks[$blockName])) {
|
80 |
+
unset($this->_cacheBlocks[$blockName]);
|
81 |
+
}
|
82 |
+
}
|
83 |
+
}
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Create layout blocks hierarchy from layout xml configuration
|
89 |
+
*
|
90 |
+
* @param Mage_Core_Layout_Element|null $parent
|
91 |
+
* @param boolean $parentIsMain Render $parent first
|
92 |
+
*/
|
93 |
+
public function generateBlocks($parent=null, $parentIsMain=false)
|
94 |
+
{
|
95 |
+
// Generate parent for single block definitions
|
96 |
+
if ($parentIsMain !== false) {
|
97 |
+
$this->_generateBlock($parent, null);
|
98 |
+
}
|
99 |
+
if (empty($parent)) {
|
100 |
+
$parent = $this->getNode();
|
101 |
+
}
|
102 |
+
$parentName = $parent->getAttribute('name');
|
103 |
+
if ($parentName) {
|
104 |
+
if (!isset($this->_blocks[$parentName])) {
|
105 |
+
return;
|
106 |
+
}
|
107 |
+
|
108 |
+
$parentBlock = $this->_blocks[$parentName];
|
109 |
+
|
110 |
+
if (!is_null($parentBlock->getCacheLifetime()) &&
|
111 |
+
Mage::app()->useCache(Mage_Core_Block_Abstract::CACHE_GROUP)) {
|
112 |
+
$cacheKey = $parentBlock->getCacheKey();
|
113 |
+
$cacheData = Mage::app()->loadCache($cacheKey);
|
114 |
+
if ($cacheData) {
|
115 |
+
return;
|
116 |
+
}
|
117 |
+
}
|
118 |
+
}
|
119 |
+
return parent::generateBlocks($parent);
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Generate cache key for block to be cached via layout XML
|
124 |
+
*
|
125 |
+
* @param Varien_Simplexml_Element $node
|
126 |
+
* @return string
|
127 |
+
*/
|
128 |
+
protected function _getCacheKey($node)
|
129 |
+
{
|
130 |
+
if (!empty($node['cache_key'])) {
|
131 |
+
$cacheKey = (string)$node['cache_tags'];
|
132 |
+
} else {
|
133 |
+
$_customer = Mage::getSingleton('customer/session')->getCustomer();
|
134 |
+
$cacheKey = (string)$node['name'] .
|
135 |
+
$this->getUpdate()->getCacheId() .
|
136 |
+
md5($_customer->getGroupId() .
|
137 |
+
join('_', Mage::app()->getRequest()->getParams()));
|
138 |
+
}
|
139 |
+
return $cacheKey;
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Add block object to layout based on xml node data
|
144 |
+
*
|
145 |
+
* @param Varien_Simplexml_Element $node
|
146 |
+
* @param Varien_Simplexml_Element $parent
|
147 |
+
* @return Mage_Core_Model_Layout
|
148 |
+
*/
|
149 |
+
protected function _generateBlock($node, $parent)
|
150 |
+
{
|
151 |
+
if (!empty($node['class'])) {
|
152 |
+
$className = (string)$node['class'];
|
153 |
+
} else {
|
154 |
+
$className = (string)$node['type'];
|
155 |
+
}
|
156 |
+
|
157 |
+
$blockName = (string)$node['name'];
|
158 |
+
$_profilerKey = 'BLOCK: '.$blockName;
|
159 |
+
Varien_Profiler::start($_profilerKey);
|
160 |
+
|
161 |
+
$block = $this->addBlock($className, $blockName);
|
162 |
+
if (!$block) {
|
163 |
+
return $this;
|
164 |
+
}
|
165 |
+
|
166 |
+
if (!empty($node['esi'])) {
|
167 |
+
$block->setData('esi', (int)$node['esi']);
|
168 |
+
}
|
169 |
+
|
170 |
+
if (in_array($blockName, array_keys($this->_cacheBlocks))) {
|
171 |
+
$block->setData('cache_lifetime', $this->_cacheBlocks[$blockName]);
|
172 |
+
$block->setData('cache_key', $this->_getCacheKey($node));
|
173 |
+
if (!empty($node['cache_tags'])) {
|
174 |
+
$block->setData('cache_tags', (string)$node['cache_tags']);
|
175 |
+
}
|
176 |
+
}
|
177 |
+
|
178 |
+
if (!empty($node['parent'])) {
|
179 |
+
$parentBlock = $this->getBlock((string)$node['parent']);
|
180 |
+
} elseif ($parent) {
|
181 |
+
$parentName = $parent->getBlockName();
|
182 |
+
if (!empty($parentName)) {
|
183 |
+
$parentBlock = $this->getBlock($parentName);
|
184 |
+
}
|
185 |
+
}
|
186 |
+
if (!empty($parentBlock)) {
|
187 |
+
$alias = isset($node['as']) ? (string)$node['as'] : '';
|
188 |
+
if (isset($node['before'])) {
|
189 |
+
$sibling = (string)$node['before'];
|
190 |
+
if ('-'===$sibling) {
|
191 |
+
$sibling = '';
|
192 |
+
}
|
193 |
+
$parentBlock->insert($block, $sibling, false, $alias);
|
194 |
+
} elseif (isset($node['after'])) {
|
195 |
+
$sibling = (string)$node['after'];
|
196 |
+
if ('-'===$sibling) {
|
197 |
+
$sibling = '';
|
198 |
+
}
|
199 |
+
$parentBlock->insert($block, $sibling, true, $alias);
|
200 |
+
} else {
|
201 |
+
$parentBlock->append($block, $alias);
|
202 |
+
}
|
203 |
+
}
|
204 |
+
if (!empty($node['template'])) {
|
205 |
+
$block->setTemplate((string)$node['template']);
|
206 |
+
}
|
207 |
+
|
208 |
+
if (!empty($node['output'])) {
|
209 |
+
$method = (string)$node['output'];
|
210 |
+
$this->addOutputBlock($blockName, $method);
|
211 |
+
}
|
212 |
+
Varien_Profiler::stop($_profilerKey);
|
213 |
+
|
214 |
+
return $this;
|
215 |
+
}
|
216 |
+
}
|
app/code/community/Made/Cache/Model/Observer.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Manage tag-specific cache cleaning
|
4 |
+
*
|
5 |
+
* @package Made_Cache
|
6 |
+
* @author info@madepeople.se
|
7 |
+
* @copyright Copyright (c) 2012 Made People AB. (http://www.madepeople.se/)
|
8 |
+
*/
|
9 |
+
class Made_Cache_Model_Observer
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Correctly clear product cache
|
13 |
+
*
|
14 |
+
* @param Varien_Event_Observer $observer
|
15 |
+
* @return type
|
16 |
+
*/
|
17 |
+
public function clearProductCache(Varien_Event_Observer $observer)
|
18 |
+
{
|
19 |
+
$_product = $observer['item']->getProduct();
|
20 |
+
if (trim(Mage::getStoreConfig('catalog/frontend/refresh_cache_when_stock_is')) == "") {
|
21 |
+
$_product->cleanCache();
|
22 |
+
return;
|
23 |
+
}
|
24 |
+
|
25 |
+
$_currentStock = $_product->getStockItem()->getQty();
|
26 |
+
$_futureStock = $_currentStock - $observer['item']->getQty();
|
27 |
+
$stocks = explode(',',','.Mage::getStoreConfig('catalog/frontend/refresh_cache_when_stock_is'));
|
28 |
+
|
29 |
+
foreach ($stocks as $stock) {
|
30 |
+
$stock = trim($stock);
|
31 |
+
|
32 |
+
if ($stock && $_currentStock > $stock && $_futureStock <= $stock) {
|
33 |
+
$_product->cleanCache();
|
34 |
+
return;
|
35 |
+
}
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Clear product cache after a review is saved
|
41 |
+
*
|
42 |
+
* @param Varien_Event_Observer $observer
|
43 |
+
*/
|
44 |
+
public function reviewSaveAfter(Varien_Event_Observer $observer)
|
45 |
+
{
|
46 |
+
$_object = $observer->getObject();
|
47 |
+
$_productCollection = $_object->getProductCollection();
|
48 |
+
|
49 |
+
foreach ($_productCollection as $_product) {
|
50 |
+
$_product->cleanCache();
|
51 |
+
}
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* ESI tags for Varnish, needs the block XML definition to have the
|
56 |
+
* attribute esi="1", as well as Varnish configured with for instance
|
57 |
+
* Phoenix_VarnishCache
|
58 |
+
*
|
59 |
+
* @param Varien_Event_Observer $observer
|
60 |
+
*/
|
61 |
+
public function addEsiTag(Varien_Event_Observer $observer)
|
62 |
+
{
|
63 |
+
$block = $observer->getEvent()->getBlock();
|
64 |
+
if ($block->getData('esi')) {
|
65 |
+
$layoutHandles = $block->getLayout()->getUpdate()
|
66 |
+
->getHandles();
|
67 |
+
|
68 |
+
$esiPath = 'madecache/varnish/esi'
|
69 |
+
. '/block/' . base64_encode($block->getNameInLayout())
|
70 |
+
. '/layout/' . base64_encode(join(',', $layoutHandles))
|
71 |
+
;
|
72 |
+
|
73 |
+
if (($product = Mage::registry('product')) !== null) {
|
74 |
+
$esiPath .= '/misc/' . base64_encode(serialize(array(
|
75 |
+
'product' => $product->getId()
|
76 |
+
)));
|
77 |
+
}
|
78 |
+
|
79 |
+
$html = '<esi:include src="' . Mage::getUrl($esiPath) . '"/>';
|
80 |
+
$transport = $observer->getEvent()->getTransport();
|
81 |
+
$transport->setHtml($html);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
app/code/community/Made/Cache/controllers/VarnishController.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Custom action for use together with Phoenix_VarnishCache to allow
|
4 |
+
* ESI block caching
|
5 |
+
*
|
6 |
+
* @package Made_Cache
|
7 |
+
* @author info@madepeople.se
|
8 |
+
* @copyright Copyright (c) 2012 Made People AB. (http://www.madepeople.se/)
|
9 |
+
*/
|
10 |
+
class Made_Cache_VarnishController extends Mage_Core_Controller_Front_Action
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Print specified block for its layout handle without the ESI tag
|
14 |
+
*/
|
15 |
+
public function esiAction()
|
16 |
+
{
|
17 |
+
$layoutHandles = explode(',', base64_decode($this->getRequest()->getParam('layout')));
|
18 |
+
$blockName = base64_decode($this->getRequest()->getParam('block'));
|
19 |
+
$misc = unserialize(base64_decode($this->getRequest()->getParam('misc')));
|
20 |
+
|
21 |
+
if (is_array($misc)) {
|
22 |
+
if (isset($misc['product'])) {
|
23 |
+
$product = Mage::getModel('catalog/product')->load($misc['product']);
|
24 |
+
Mage::register('product', $product);
|
25 |
+
}
|
26 |
+
}
|
27 |
+
|
28 |
+
$layout = $this->getLayout();
|
29 |
+
$update = $layout->getUpdate();
|
30 |
+
$update->load($layoutHandles);
|
31 |
+
|
32 |
+
$layout->generateXml();
|
33 |
+
$blockNodes = $layout->getNode()
|
34 |
+
->xpath('//*[@name="'.$blockName.'"]');
|
35 |
+
|
36 |
+
if (!empty($blockNodes)) {
|
37 |
+
foreach ($blockNodes as $node) {
|
38 |
+
$layout->generateBlocks($node, true);
|
39 |
+
}
|
40 |
+
$block = $layout->getBlock($blockName)
|
41 |
+
->setEsi(0);
|
42 |
+
$this->getResponse()->setBody($block->toHtml());
|
43 |
+
}
|
44 |
+
}
|
45 |
+
}
|
app/code/community/Made/Cache/etc/config.xml
ADDED
@@ -0,0 +1,92 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @package Made_Cache
|
5 |
+
* @author info@madepeople.se
|
6 |
+
* @copyright Copyright (c) 2011 Made People AB. (http://www.madepeople.se/)
|
7 |
+
*/
|
8 |
+
-->
|
9 |
+
<config>
|
10 |
+
<modules>
|
11 |
+
<Made_Cache>
|
12 |
+
<version>1.0.0</version>
|
13 |
+
</Made_Cache>
|
14 |
+
</modules>
|
15 |
+
<global>
|
16 |
+
<models>
|
17 |
+
<cache>
|
18 |
+
<class>Made_Cache_Model</class>
|
19 |
+
</cache>
|
20 |
+
<core>
|
21 |
+
<rewrite>
|
22 |
+
<layout>Made_Cache_Model_Layout</layout>
|
23 |
+
</rewrite>
|
24 |
+
</core>
|
25 |
+
</models>
|
26 |
+
<blocks>
|
27 |
+
<catalog>
|
28 |
+
<rewrite>
|
29 |
+
<product_view>Made_Cache_Block_Catalog_Product_View</product_view>
|
30 |
+
<product_list>Made_Cache_Block_Catalog_Product_List</product_list>
|
31 |
+
</rewrite>
|
32 |
+
</catalog>
|
33 |
+
</blocks>
|
34 |
+
<events>
|
35 |
+
<review_save_after>
|
36 |
+
<observers>
|
37 |
+
<cache_review_save_after>
|
38 |
+
<type>singleton</type>
|
39 |
+
<class>cache/observer</class>
|
40 |
+
<method>reviewSaveAfter</method>
|
41 |
+
</cache_review_save_after>
|
42 |
+
</observers>
|
43 |
+
</review_save_after>
|
44 |
+
<sales_convert_quote_item_to_order_item>
|
45 |
+
<observers>
|
46 |
+
<cache_order_success>
|
47 |
+
<type>singleton</type>
|
48 |
+
<class>cache/observer</class>
|
49 |
+
<method>clearProductCache</method>
|
50 |
+
</cache_order_success>
|
51 |
+
</observers>
|
52 |
+
</sales_convert_quote_item_to_order_item>
|
53 |
+
<core_block_abstract_to_html_after>
|
54 |
+
<observers>
|
55 |
+
<cache_add_esi_tags>
|
56 |
+
<type>singleton</type>
|
57 |
+
<class>cache/observer</class>
|
58 |
+
<method>addEsiTag</method>
|
59 |
+
</cache_add_esi_tags>
|
60 |
+
</observers>
|
61 |
+
</core_block_abstract_to_html_after>
|
62 |
+
</events>
|
63 |
+
</global>
|
64 |
+
<frontend>
|
65 |
+
<routers>
|
66 |
+
<madecache>
|
67 |
+
<use>standard</use>
|
68 |
+
<args>
|
69 |
+
<module>Made_Cache</module>
|
70 |
+
<frontName>madecache</frontName>
|
71 |
+
</args>
|
72 |
+
</madecache>
|
73 |
+
</routers>
|
74 |
+
<layout>
|
75 |
+
<updates>
|
76 |
+
<madecache>
|
77 |
+
<file>madecache.xml</file>
|
78 |
+
</madecache>
|
79 |
+
</updates>
|
80 |
+
</layout>
|
81 |
+
<!-- We rewrite catalog blocks - let's use its translations -->
|
82 |
+
<translate>
|
83 |
+
<modules>
|
84 |
+
<Made_Cache>
|
85 |
+
<files>
|
86 |
+
<default>Mage_Catalog.csv</default>
|
87 |
+
</files>
|
88 |
+
</Made_Cache>
|
89 |
+
</modules>
|
90 |
+
</translate>
|
91 |
+
</frontend>
|
92 |
+
</config>
|
app/design/frontend/base/default/layout/madecache.xml
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<!--
|
3 |
+
/**
|
4 |
+
* @package Made_Cache
|
5 |
+
* @author info@madepeople.se
|
6 |
+
* @copyright Copyright (c) 2011 Made People AB. (http://www.madepeople.se/)
|
7 |
+
*/
|
8 |
+
-->
|
9 |
+
<layout version="1.0.0">
|
10 |
+
<default>
|
11 |
+
<cache>
|
12 |
+
<!--
|
13 |
+
Render "left" with a custom lifetime, the default is
|
14 |
+
9999999999 seconds
|
15 |
+
-->
|
16 |
+
<name lifetime="86400">left</name>
|
17 |
+
<name>head</name>
|
18 |
+
<name>header</name>
|
19 |
+
<name>breadcrumbs</name>
|
20 |
+
<name>after_body_start</name>
|
21 |
+
<name>before_body_end</name>
|
22 |
+
<name>product.info</name>
|
23 |
+
<name>product_list</name>
|
24 |
+
<name>product_list_toolbar</name>
|
25 |
+
<name>category.products</name>
|
26 |
+
</cache>
|
27 |
+
</default>
|
28 |
+
|
29 |
+
<checkout_onepage_index>
|
30 |
+
<nocache>
|
31 |
+
<name>root</name>
|
32 |
+
<name>content</name>
|
33 |
+
</nocache>
|
34 |
+
</checkout_onepage_index>
|
35 |
+
|
36 |
+
<!-- For use with Made_Streamcheckout, http://streamcheckout.com -->
|
37 |
+
<streamcheckout_index_index>
|
38 |
+
<nocache>
|
39 |
+
<name>root</name>
|
40 |
+
<name>content</name>
|
41 |
+
</nocache>
|
42 |
+
</streamcheckout_index_index>
|
43 |
+
</layout>
|
app/etc/modules/Made_Cache.xml
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<Made_Cache>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</Made_Cache>
|
8 |
+
</modules>
|
9 |
+
</config>
|
package.xml
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>Made_Cache</name>
|
4 |
+
<version>1.0.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license>OSL 3.0</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Advanced Block Cache module that enhances performance by implementing cache on the most common blocks.</summary>
|
10 |
+
<description>Few know that Magento out of the box doesn't actually cache anything other than the Navigation and Footer blocks, which are basically static as it is.
|
11 |
+

|
12 |
+
This module enhances performance by allowing developers to cache any block they want via simple layout xml changes - per layout handle.
|
13 |
+

|
14 |
+
There is also support for disabling cache for specific handles such as checkout, etc, where you don't want to load the main content block from cache.
|
15 |
+

|
16 |
+
The product view and list blocks contain specific cache tags that takes the customer, tax rules and so on into concern.
|
17 |
+

|
18 |
+
A good block cache is vital for scaling a site, be sure to implement this before residing to full page cache or similar.
|
19 |
+

|
20 |
+
Consider a good layout with dynamic information grouped and a simple hierarchy, to maximize performance.</description>
|
21 |
+
<notes>N/A</notes>
|
22 |
+
<authors><author><name>Jonathan Selander</name><user>jonathan_made</user><email>jonathan@madepeople.se</email></author></authors>
|
23 |
+
<date>2012-05-07</date>
|
24 |
+
<time>18:56:16</time>
|
25 |
+
<contents><target name="magecommunity"><dir name="Made"><dir name="Cache"><dir name="Block"><dir name="Catalog"><dir name="Product"><file name="List.php" hash="b6c67645954d1a8c2175b7d98fad68e4"/><file name="View.php" hash="3670f5e5a739283783c446bdb6abf364"/></dir></dir></dir><dir name="Model"><file name="Layout.php" hash="4d8c066991271a812b9ad039b6eaedd6"/><file name="Observer.php" hash="264bad67caf1661156811fa6ae07e634"/></dir><dir name="controllers"><file name="VarnishController.php" hash="6e7207e07c5385568061b853eeca96fd"/></dir><dir name="etc"><file name="config.xml" hash="0bac4b8c124a1cf0b9b4bfe0ebb3fbaa"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Made_Cache.xml" hash="4cf53cc9b4e525eb560f7fe1278d96bd"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="madecache.xml" hash="ed18df239d381566002dafa34ffa66f6"/></dir></dir></dir></dir></target></contents>
|
26 |
+
<compatible/>
|
27 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
28 |
+
</package>
|