Frage

In meiner Observer -Funktion erhalte ich eine Variable, die das Ereignis wie diese übergeben hat:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
}

Wenn sth ist ein Objekt, ich kann es ändern, indem ich Methoden darauf aufruft. Aber wie kann ich verändern? sth Wenn es eine einfache Zeichenfolge ist? Ich habe das Folgende ohne Erfolg ausprobiert:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
    $observer->getEvent()->setSth('test');
    $observer->setSth('test');
}

Ich habe gerade erfahren, dass einige Ereignisse auch ein Transportobjekt verabschieden, in dem die Saite geändert werden kann (danke Alex), aber die Veranstaltung page_block_html_topmenu_gethtml_after nicht. Was kann ich also tun?

Die fragliche Veranstaltung wird so versandt und ich möchte $ html ändern:

$html = $this->_getHtml($this->_menu, $childrenWrapClass);
Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
    'menu' => $this->_menu,
    'html' => $html
));
War es hilfreich?

Lösung

Du kannst nicht.

Der Grund, warum der Ansatz des Transportobjekts funktioniert, sind die Objekte von PHP sind Aliase/Referenzen. Wenn Sie ein Objekt ändern, ändern Sie das eine wahre Objekt.

Die primitiven Typen von PHP (INTs, Saiten, Booleans usw.) sind keine Objekte und fallen unter PHPs nach Wert passieren Regeln für Argumente. Wenn ein Magento -Modulentwickler Ihnen in einem Ereignisbeobachter eine rohe Schnur übergibt

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
        'menu' => $this->_menu,
        'html' => $html
    ));

Das ist ihre Art zu sagen

Sie können sich diesen Wert ansehen, aber ich möchte nicht, dass Sie ihn ändern.

Wir werden verlassen, ob dies eine absichtliche Designentscheidung oder ein Entwickler ist, der Dinge nicht als Übung für den Leser durchdacht.

Wenn Sie das obere Menü ändern möchten, gibt es einige Ansätze, die ich verfolgen würde, wenn Sie das obere Menü ändern möchten. In das einhaken page_block_html_topmenu_gethtml_before Ereignis und Änderung der menu Objekt

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_before', array(
        'menu' => $this->_menu
    ));

sollte arbeiten, seitdem funktionieren _menu ist ein Objekt

/**
 * Top menu data tree
 *
 * @var Varien_Data_Tree_Node
 */
protected $_menu;

Zweitens können Sie die Menügenerierungsklasse neu schreiben

public function getHtml($outermostClass = '', $childrenWrapClass = '')
{
    $html = parent::getHtml($outermostClass, $childrenWrapClass);
    //monkey with $html here to add your menu items or custom markup
    return $html;
}

Drittens können Sie Layout -Updates verwenden, um den vorhandenen oberen Menüblock zu entfernen und einen neuen Block mit einer benutzerdefinierten Klasse einzufügen, die Sie erstellt haben. Ihre benutzerdefinierte Klasse würde die vorhandene Top -Menüklasse erweitern und dann neu definieren getHtml. Dies ist komplizierter, vermeidet jedoch die Probleme, die mit Umschreiben verbunden sind.

Andere Tipps

Ich würde sagen, das ist ein Designfehler in diesem Event.

Objekte werden durch Referenz weitergegeben, damit sie manipuliert werden können. Saiten werden immer kopiert. In diesem Fall kann die Saite also nicht im Beobachter manipuliert werden, auch der page_block_html_topmenu_gethtml_after Event sieht mir nur so aus, als ob es sein Zweck ist, Ihnen die Möglichkeit zu geben, das zu manipulieren $html.

Es ist Möglich core_block_abstract_to_html_after Veranstaltung (Verknüpfung). In diesem Fall wird der gerenderte Inhalt von der Blockinstanz zur Observer -Instanz transportiert, und vor allem wird der transportierte Inhalt von der Blockklasse zurückgegeben. Beachten Sie, dass es eine wichtige Überlegung gibt, die ich unter dem Beispiel erklärt habe.

Beispiel

Weil dieses Ereignis entlassen wird jeder Block -Render Mage_Page_Block_Html_Topmenu.

public function manipulateTopmenuOutput(Varien_Event_Observer $obs)
{
     if ($obs->getBlock() instanceof Mage_Page_Block_Html_Topmenu){
         $initialOutput = $obs->getTransport()->getHtml();
         //e.g. $modified output = $this->yourManipulationMethod($initialOutput);
         $obs->getTransport()->setHtml($modifiedOutput);
     }
}

Ihre Manipulationslogik könnte in der Beobachtungsmethode implementiert oder in eine andere Methode im Beobachter platziert werden.

Ausgaben

Weil es die Ausgabemanipulation beinhaltet und Der Beobachter wird für alle Blockreverter gefordert. Dies sollte nur verwendet werden, wenn das Hauptanliegen darin besteht, ein Block -Umschreiben zu vermeiden. Außerdem wird der generierte Inhalt in diesem Beobachter nach der manipuliertenblock_html Cache schreiben (über den Aufruf der Blockinstanz an _saveCache()), so müssten Sie entweder das erneut aufnehmen block_html Eintritt in den Beobachter (etwas klebrig, da Sie entweder Reflexion verwenden oder die Logik von beiden duplizieren würden _saveCache() und _getSidPlaceholder() Methoden zum Schreiben des Cache -Eintrags. Und schließlich müssten Sie eine Kopie der Baumknotendaten generieren, wenn Sie etwas zu den Baumknotendaten manipulieren müssen. Dies könnte theoretisch geschehen, indem Sie das greifen Mage_Catalog_Model_Observer Singleton und packt den Baum davon ... sehr klebrig.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit magento.stackexchange
scroll top