Depends what you want to do. We use block caching for almost all our blocks. So what we do is replace the Magento Form key with example: "$$FORMKEY$$" and than CACHE IT !
Then the onlything you need is to replace this with the REAL formkey just before sending back to client.
<frontend>
<events>
<controller_front_send_response_before>
<observers>
<gn_blockcache>
<type>singleton</type>
<class>gn_blockcache/observer</class>
<method>controllerFrontSendResponseBefore</method>
</gn_blockcache>
</observers>
</controller_front_send_response_before>
</events>
</frontend>
This is the replace code:
/**
* Fix form_key in html coming from cache
*
* @param Varien_Event_Observer $observer
*
* @return boolean
*/
public function controllerFrontSendResponseBefore($observer) {
/** @var Zend_Controller_Response_Http $response */
/** @noinspection PhpUndefinedMethodInspection */
$response = $observer->getFront()->getResponse();
$headers = $response->getHeaders();
$isHtml = true; // Because it's default in PHP
foreach ($headers as $header) {
if ('Content-Type' == $header['name'] && false === strpos($header['value'], 'text/html')) {
$isHtml = false;
break;
}
}
if ($isHtml) {
$html = $response->getBody();
/** @noinspection PhpUndefinedMethodInspection */
$newFormKey = Mage::getSingleton('core/session')->getFormKey();
$templateFormkey = '$$FORMKEY$$';
$html = str_replace($templateFormkey, $newFormKey, $html);
$response->setBody($html);
}
return true;
}
You can also do this on the "afterToHtml()" of the block it selfs, but we have decided for a generic sollution that works for all blocks with "$$FORMKEY$$".
How to inject the $$FORMKEY$$ constant (cart example):
class Gn_BlockCache_Helper_Cart extends Mage_Checkout_Helper_Cart {
/** @var Gn_BlockCache_Helper_Data */
protected $helper;
public function __construct() {
$this->helper = Mage::helper('gn_blockcache');
}
/**
* Add to url: /form_key/$$FORMKEY$$/ <== Will be replace on "controller_front_send_response_before"
*
* @param Mage_Catalog_Model_Product $product
* @param array $additional
*
* @return string
*/
public function getAddUrl($product, $additional = array()) {
if ($this->helper->getEnabledCartFormkey()) {
return parent::getAddUrl($product, array_merge([Mage_Core_Model_Url::FORM_KEY => '$$FORMKEY$$'], $additional));
} else {
return parent::getAddUrl($product, $additional);
}
}
}