Domanda

Nella mia funzione di osservatore, ottengo una variabile passata per l'evento del genere:

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

Se sth è un oggetto, che può alterare lo chiamando i metodi su di esso. Ma come posso alterare sth se si tratta di una semplice stringa? Ho provato il seguente senza successo:

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

Ho appena appreso che alcuni eventi anche passare un oggetto trasporto in cui la stringa può essere modificata (grazie Alex ), ma il page_block_html_topmenu_gethtml_after evento non lo fa. Allora, cosa posso fare?

L'evento in questione viene inviato come questo e voglio alterare $ html:

$html = $this->_getHtml($this->_menu, $childrenWrapClass);
Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
    'menu' => $this->_menu,
    'html' => $html
));
È stato utile?

Soluzione

Non è possibile.

Il motivo l'approccio object trasporti funziona è oggetti di PHP sono alias / riferimenti . Quando si modifica un oggetto, si sta modificando l'unico vero oggetto.

tipi primitivi di PHP (INT, stringhe, booleani, ecc) non sono oggetti, e cadono sotto PHP di passare valore regole per argomenti. Se un modulo sviluppatore Magento si passa una stringa prima in un osservatore evento

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

che è il loro modo di dire

Si può guardare a questo valore, ma io non voglio che tu modificarlo.

Lasceremo se si tratti di una decisione di progettazione intenzionale o uno sviluppatore non pensare cose attraverso come un esercizio per il lettore.

Per quanto riguarda la tua domanda inespressa, se si desidera modificare il menu in alto, c'è un paio di approcci Io prenderei. Agganciando nell'evento page_block_html_topmenu_gethtml_before e modificare l'oggetto menu

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

dovrebbe funzionare, dal momento che _menu è un oggetto

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

In secondo luogo, è possibile riscrivere la classe di generazione del menu

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

In terzo luogo, è possibile utilizzare il layout aggiornamenti per rimuovere il blocco di menu superiore esistente e inserire un nuovo blocco con una classe personalizzata che hai creato. Si classe personalizzata dovrebbe estendere la classe menu in alto esistente e getHtml quindi ridefinire. Questo è più complicato, ma evita i problemi connessi con riscritture.

Altri suggerimenti

direi che è un bug di progettazione in tal caso.

Oggetti viene passato in giro per riferimento, in modo che possano essere manipolati. Le stringhe vengono sempre copiati. Quindi in questo caso la stringa non può essere manipolata all'interno l'osservatore, anche l'evento page_block_html_topmenu_gethtml_after appena mi sembra il suo scopo è quello di dare la possibilità di manipolare il $html.

è possibile modificare uscita del blocco con stringa trasportati osservando l'evento core_block_abstract_to_html_after (link) . In tal caso, il contenuto visualizzato viene trasportato dal l'istanza del blocco per l'istanza di osservatore, e - soprattutto - il contenuto trasportato è ciò che viene restituito dalla classe blocco. Nota che c'è una considerazione importante di caching che ho spiegato qui di seguito l'esempio.

Esempio

Poiché questo evento viene generato per tutti blocco rendering, è necessario configurare l'osservatore come Singleton e test che il tipo di blocco è un esempio di 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);
     }
}

La logica manipolazione potrebbe essere implementato nel metodo di osservazione o collocato in un altro metodo nell'osservatore.

Pubblicazioni

Perché coinvolge manipolazione uscita e l'osservatore è chiamato per tutti i blocchi rende, questo dovrebbe essere utilizzato solo quando la preoccupazione principale è di evitare una riscrittura blocco. Inoltre, la contenuto generato in questo osservatore viene manipolato post-block_html cache di scrittura (tramite chiamata del istanza di blocco a _saveCache()), in modo che avrebbe sia bisogno di ri-cache l'entrata block_html nell'osservatore (un po 'appiccicoso, come ci si sia utilizzare Riflessione o duplicare la logica da entrambi i metodi _saveCache() e _getSidPlaceholder() per scrivere la voce della cache. e, infine, se hai bisogno di manipolare qualsiasi cosa relativa ai dati del nodo albero, si dovrebbe generare una copia dei dati nodo della struttura. Questo potrebbe essere teoricamente fatto afferrando il singleton Mage_Catalog_Model_Observer e afferrando l'albero da esso ... anzi molto appiccicoso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange
scroll top