Be careful if you use Mage_Core_Block_Abstract::toHtml()
inside an observer for core_block_to_html_after
. I did that to inject HTML from another block into an existing block with the result that everything except this new block was removed from output.
Digging through the core, I found the cause in how the event is dispatched:
/** * Use single transport object instance for all blocks */ if (self::$_transportObject === null) { self::$_transportObject = new Varien_Object; } self::$_transportObject->setHtml($html); Mage::dispatchEvent('core_block_abstract_to_html_after', array('block' => $this, 'transport' => self::$_transportObject)); $html = self::$_transportObject->getHtml();
As you see, the transport object that is used to allow modification of the HTML in observers, is a class variable of Mage_Core_Block_Abstract
, so basically acts like a singleton. I cannot think of a good reason for this, but it smells ridiculously like premature optimization.
Now what’s happening is, that during the event is processed, the new block sets its own output to the same transport object in its toHtml()
method and the original output is lost, if you didn’t save it before.
The solution to my particular problem was to generate and pre-render the new block elsewhere but if you don’t, you need to copy the output at the very beginning:
$html = $observer->getTransport()->getHtml(); // should be the first statement // now you can do what you want, create other blocks, modifiy $html ... $observer->getTransport()->setHtml($html); // should be the last statement
But observing this event “core_block_abstract_to_html_after” has a heavy price to pay with the performance it seems.
I just had a 3rd party payment gateway extension , which has eaten up 17.3750 seconds and was called 94 times.
Their code was obfuscated and the developer was no interested to show their observer method. Finally we had no other go to uninstall this extension.
Now i would like to know it was because the code of the extension or observing this event itself is not a good idea ?
This is definitely due to the code of the extension. The typical use case of observing the event and checking the block name to only take action for certain blocks will not result in significant overhead. 94 times a simple string comparison is nothing.