Magento: Block-Inhalt verschwindet nach core_block_to_html_after Event

Vorsicht mit Mage_Core_Block_Abstract::toHtml() innerhalb eines Observers für core_block_to_html_after! Ich habe die Methode genutzt, um HTML aus einem Block in einen existierenden Block zu injizieren, mit dem Ergebnis dass alles außer diesem neuen Block von der Ausgabe entfernt wurde.

Beim Debugging im Core habe ich die Ursache darin gefunden, wie das Event dispatched wird:

        /**
         * 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();

Wie man sieht, ist das Transport-Objekt, das genutzt wird um Änderungen am HTML in Observern zu ermöglichen, eine Klassenvariable von Mage_Core_Block_Abstract, und verhält sich ähnlich wie ein Singleton. Ich kann mir keinen guten Grund dafür denken aber es riecht verdächtig nach premature optimization.

Was nun passiert ist, dass während das Event verarbeitet wird, der neue Block seine eigene Ausgabe in seinem eigenen toHtml() Aufruf dem selben Transport-Objekt zuweist und die ursprüngliche Ausgabe verloren geht, wenn man sie nicht vorher gesichert hat.

Die Lösung für mein konkretes Problem war, den Block an anderer Stelle zu erstellen und vorzurendern, aber wenn das nicht getan wird, muss die Ausgabe direkt zu Beginn im Observer in eine neue Variable kopiert werden:

$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

2 Replies to “Magento: Block-Inhalt verschwindet nach core_block_to_html_after Event”

  1. 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 ?

    1. 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.

Comments are closed.