I had this problem with EE 1.14.2 and it looks like the same issue has come up in CE 1.9.2. I documented my problem and solution on this SE question.
Basically due to the following code being added to the constructor of Mage_Cms_Block_Block
:
$this->setCacheTags(array(Mage_Cms_Model_Block::CACHE_TAG));
$this->setCacheLifetime(false);
CMS static blocks are now cached. The problem arises from how the cache key info is generated. It falls back to the Mage_Core_Block_Abstract
behavior of using the blocks name in layout. If the block hasn't been added with layout, e.g on a cms page, this name doesn't exist. This can result in static blocks sharing the same cache key and getting mixed up in cache.
My solution was to override the Mage_Cms_Block_Block
class and set the cache key info based on the block id and current store.
/**
* Override cms/block to add cache key. This started being a problem as of EE 1.14.2 and CE 1.9.2 when the _construct
* method was added which turns on caching for cms blocks
*/
class Mysite_Cms_Block_Block extends Mage_Cms_Block_Block
{
/**
* If this block has a block id, use that as the cache key.
*
* @return array
*/
public function getCacheKeyInfo()
{
if ($this->getBlockId()) {
return array(
Mage_Cms_Model_Block::CACHE_TAG,
Mage::app()->getStore()->getId(),
$this->getBlockId(),
(int) Mage::app()->getStore()->isCurrentlySecure()
);
} else {
return parent::getCacheKeyInfo();
}
}
}
Obviously this would need to be added in your own module with a config.xml
file and block override etc. Alternatively you could copy Mage_Cms_Block_Block
to the local code pool and add the cache key there.
You can see the new lines added in 1.9.2 here
This is how I solved it eventually, add the following methods to the block in question:
const FORM_KEY_PLACEHOLDER = '{{FORM_KEY}}';
protected function _toHtml()
{
return $this->_insertFormKeyPlaceholder(parent::_toHtml());
}
protected function _afterToHtml($html)
{
return $this->_restoreFormKey(parent::_afterToHtml($html));
}
protected function _insertFormKeyPlaceholder($html)
{
/** @var $session Mage_Core_Model_Session */
$session = Mage::getSingleton('core/session');
return str_replace($session->getFormKey(), self::FORM_KEY_PLACEHOLDER, $html);
}
protected function _restoreFormKey($html)
{
/** @var $session Mage_Core_Model_Session */
$session = Mage::getSingleton('core/session');
return str_replace(self::FORM_KEY_PLACEHOLDER, $session->getFormKey(), $html);
}
Explanation:
I replace the form key with a placeholder before the rendered block is cached and replace the placeholder with the current form key again after the block has been loaded from cache.
I use _toHtml
to insert the placeholder because the return value of this method is immediately written to the cache.
I use _afterToHtml
to restore the form key because this method is called immediately after the content has been loaded from cache (or after it has been saved to the cache if it was not cached yet). This method is guaranteed to be called, regardless of the block cache.
Further thougts
A generic solution does not seem to exist yet, but the method described above works for any dynamic content and if you need it in more than one block or with different content, it should be easy to extract the placeholder logic to a separate model.
For replacing the placeholders you could also use the core_block_abstract_to_html_after
event, but unfortunately no event exists right before the rendered block gets cached, so an "observer only" solution is not possible without introducing new events in the core.
Best Answer
By default, Magento CMS Block will not be cached. So it would be nice if we cache CMS static blocks. This is what this extension does (one of my free extension). Feel free to use it.
Basically this extension listens to the event
core_block_abstract_to_html_before
and enable cacheing for CMS Blocks. This is what observer doesWhat this Observer Does : It first retrieve each static blocks from the layout and then apply cache. The unique
cache key
is generated for each static blocks. This unique key is made up ofSo the
cache key
will be unique in most of the circumstances and you already saw that for secure and not secure urls, cache key will be different. That's it.Note : As @AdershKatri pointed out, you should also have look on this thread
If you have any doubts, let me know.