magento disable cache for price block

2019-02-16 03:14发布

问题:

In my project we are using Magento Enterprise Edition 1.14.1. The prices in store are changed dynamically direct from Database. So the problem is Magento cache every thing (full page cache) so the changes are not effected in front end. So we are decided disable the cache for that particular block. I know it can done in layout files. I checked in layout catalog.xml and I found it the block

<block type="catalog/product_price_template" name="catalog_product_price_template" />

So here I don't know how to disable it. I have tried set fife time of cache to null in app/etc/local.xml ,

 <layout>
    <default>
         <reference name="catalog_product_price_template">
            <action method="setCacheLifetime" />
        </reference>
    </default>
    </layout>

and tried in layout/catalog.xml

<block type="catalog/product_price_template" name="catalog_product_price_template" >
         <action method="setCacheLifetime" />
        </block>

and tried ,

<block type="catalog/product_price" name="Mage_Catalog_Block_Product_Price">
        <action method="setCacheLifetime"><value>false</value></action>
        </block>

and

 <block type="catalog/product_price" name="catalog_product_price">
            <action method="setCacheLifetime"><s>null</s></action>
            </block>

But no luck.

And I have found some other price blocks in layout/bundle.xml file. We are using bundle product as well. So we have to disable this cache also ? Any help would be appreciated. Thanks.

回答1:

After deep digging in magento caching techniques I came across one decision. Before that I want describe that what I got. There is basically 2 solutions to disable cache for particular block or caching tags.

1. Disable cache using Block

It is something like set lifetime of cache

<reference name="needed block">
    <action method="setCacheLifetime"><s>null</s></action>
</reference>

But in our case magento doesn’t have specific block for rendering the price of the product. The price template is directly defined in abstract class,

Mage_Catalog_Block_Product_Abstract 

protected $_priceBlockDefaultTemplate = 'catalog/product/price.phtml';

And also this type cache will clear only the Block cache. So we can’t use this solution.

2. Hole punching : Magento having another default functionality which is we can override the FPC process using cache tags.

Magento saving caches by tag names. So that we can get that tags before the page rendering and we can disable to cache that tag again. So every time when the page loads that tag will not be cached.

I was trying to implement this using observer (core_block_abstract_to_html_before),

public function disableCache(Varien_Event_Observer $observer)
{
$block = $observer->getBlock();

if ($block instanceof Mage_Catalog_Block_Product_Price) {

//echo 'got it'; exit;
$cacheKeyData = array(
Mage_Catalog_Block_Product_Price::CACHE_TAG,
$block->getBlockId(),
Mage::app()->getStore()->getId(),
intval(Mage::app()->getStore()->isCurrentlySecure())
);
}
}

But there is no CACHE_TAG for price (not defined for price).

And we can set the life time of cache directly in price class using __construct() function, like

$this->addData(array(
‘cache_lifetime’=> false,
‘cache_tags’    => array(Mage_Core_Model_Store::CACHE_TAG, Mage_Catalog_Product_Price::CACHE_TAG)
));

As like above I mentioned, there is no CACHE_TAG for price. So we can’t use this trick also.

But I found one thing that if we save the product from admin then immediately the changes is reflecting in front end. So I dig more in that and I found the solution.

Magento calls the following control action,

Mage_Adminhtml_Catalog_ProductController::saveAction()  

and this one will call the following method,

Mage::getModel('catalogrule/rule')->applyAllRulesToProduct($productId)

If you see this function they clear cache and re-indexing.

public function applyAllRulesToProduct($product)
    {
      .......    
        $this->getResource()->applyAllRules($product);
        $this->_invalidateCache();

        Mage::getSingleton('index/indexer')->processEntityAction(
            new Varien_Object(array('id' => $product->getId())),
            Mage_Catalog_Model_Product::ENTITY,
            Mage_Catalog_Model_Product_Indexer_Price::EVENT_TYPE_REINDEX_PRICE
        );

        return $this;
    } 

So in my case I just using the following code.

$object->setPrice(555);
Mage::getModel('catalogrule/rule')->applyAllRulesToProduct($productId);
$object->save();


回答2:

You can see this link cache disable follwing method is added in this file Mage/Catalog/Block/Product/Price.php

protected function _construct()
{
    $this->addData(
      array('cache_lifetime'    => false,)
    );
}


回答3:

Magento 1.9.2.1
My solution was to add:

<action method="unsetData"><key>cache_lifetime</key></action>
<action method="unsetData"><key>cache_tags</key></action>


回答4:

Besides this being a question for the Magento Stack Exchange, you could also try

<reference name="footer">
    <action method="setCacheLifetime"></action>
</reference>

Which leaves the setCacheLifetime empty. According to your question, you didn't check that on out. Found the solution on fbrnc.net. The author there says that

This works because conveniently Varien_Object->__call() takes care of missing arguments and replaces them with null which again luckily is exactly what we need here



回答5:

Try

<action method="setCacheLifetime"><value>false</value></action>

HTH