Search code examples
formsmagentoblockmagento-1.6magento-1.9

Magento 1.9 Block Cache - prevent form key caching on Mage Catalog Block Product View


Hey Magento Professionals,

I was using Magentos Block Cache mechanism for better performance on product pages. It worked great on Magento CE 1.6.2 but now I'm upgrading to CE 1.9.0.1 and block caching does not go well with Magentos new form keys.

The product pages are still being cached, but they're naturally cached including the new form key in the forms actions. When another user tries to add products to cart it won't work, because the other users form key was cached. So no product is being added and the cart stays empty.

Is there a way to kind of inject the form key into the cached code or another way for caching product pages ?

The caching methods in my extended Mage_Catalog_Block_Product_View looks like this

protected function _construct()
{
        $this->addData(array(
            'cache_tags'        => array(Mage_Catalog_Model_Product::CACHE_TAG . "_" . $this->getProduct()->getId()),
        ));
}

public function getCacheKey()
{
    if (!$this->hasData('cache_key')) {
        //$cacheKey = LAYOUTNAME_STORE+ID_PRODUCT+ID
        $cacheKey = $this->getNameInLayout().'_STORE'.Mage::app()->getStore()->getId().'_PRODUCT'.$this->getProduct()->getId();         
        $this->setCacheKey($cacheKey);
    }
    return $this->getData('cache_key');
}

public function getCacheLifetime()
{     
      if($this->getNameInLayout()!='product.info') return null;
      if(!$this->cacheEnabled()) return null;         
      return 9999999999;
}

public static function cacheEnabled() {
    return true;
}   

Solution

  • I found a quickfix for now, but still looking for a better solutions. For now I added the _afterToHtml($html) method in my extended block and inject the form_key before returning the html from cache. If someone else needs this quickfix make sure the if condition is right. It makes sure that this is only done in the block I'm really caching and not on other Product View Blocks.

    So this is my current quickfix:

    public function _afterToHtml($html) {
        if($this->getNameInLayout() == 'product.info') {
            $formkey = Mage::getSingleton('core/session')->getFormKey();
            $formkey = "/form_key/".$formkey."/";        
            $html = preg_replace("/\/form_key\/[a-zA-Z0-9,.-]+\//", $formkey, $html); 
        }  
        return parent::_afterToHtml($html);
    }
    

    I'm thinking of switching to a full page cache in future but fixing this would be nice as configuring another cache method takes a lot time as well.

    So please help if you have a better idea than this dirty quick fix.