Pregunta

En mi función de observador, me sale una variable pasada por el evento de esa manera:

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

Si sth es un objeto, que puede alterarlo mediante llamadas a métodos en él. Pero ¿cómo puedo alterar sth si se trata de una simple cadena? He intentado lo siguiente sin éxito:

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

Me acaba de enterarse de que algunos eventos también pasan un objeto de transporte en el que la cadena puede ser alterado (gracias Alex ), pero el page_block_html_topmenu_gethtml_after caso no es así. Entonces, ¿qué puedo hacer?

El evento en cuestión se envió como esto y yo quiero alterar $ html:

$html = $this->_getHtml($this->_menu, $childrenWrapClass);
Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
    'menu' => $this->_menu,
    'html' => $html
));
¿Fue útil?

Solución

No se puede.

La razón el enfoque de objetos de transporte funciona es objetos de PHP son alias / referencias . Cuando se modifica un objeto, se está modificando el único y verdadero objeto.

tipos primitivos de PHP (Ints, secuencias, booleanos, etc.) no son objetos, y caen bajo PHP de pasar por régimen de los valores de argumentos. Si un desarrollador de módulos de Magento que pasa una cadena de texto en un observador de eventos

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

que es su manera de decir

Puede mirar a este valor, pero no quiero que modificarlo.

Saldremos si esta es una decisión de diseño deliberada o un desarrollador no pensar las cosas como ejercicio para el lector.

En cuanto a su pregunta sin respuesta, si desea modificar el menú superior, hay algunos enfoques que tomaría. Enganchar en el evento page_block_html_topmenu_gethtml_before y modificar el objeto menu

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

debe trabajar, ya que _menu es un objeto

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

En segundo lugar, puede volver a escribir la clase de generación de menú

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

En tercer lugar, se podría utilizar la disposición actualizaciones para quitar el bloqueo de menú superior existente, e insertar un nuevo bloque con una clase personalizada que ha creado. Usted clase personalizada ampliar la clase menú superior existente, y luego getHtml redefinen. Esto es más complicado, pero evita los problemas asociados con reescrituras.

Otros consejos

Yo diría que es un error de diseño en ese evento.

Los objetos van pasando alrededor por referencia, para que puedan ser manipulados. Cuerdas siempre se copian. Así que en este caso la cadena no se puede manipular el interior del observador, incluso el evento page_block_html_topmenu_gethtml_after sólo se parece a mí como su propósito es darle la oportunidad de manipular el $html.

es posible modificar salida del bloque a través de la cadena transportado mediante la observación del evento core_block_abstract_to_html_after (enlace) . En este caso, el contenido presentado es transportado desde la instancia del bloque a la instancia de observador, y - más importante - el contenido transportado es lo que se devuelve por la clase bloque. Tenga en cuenta que hay una importante consideración de la memoria caché, que he explicado a continuación el ejemplo.

Ejemplo

Debido a que este evento es despedido por todos bloque de render, debe configurar el observador como un conjunto unitario y la prueba de que el tipo de bloque es una instancia de 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);
     }
}

Su lógica manipulación podría ser implementado en el método de la observación o colocado en otro método en el observador.

Publicaciones

Debido a que implica la manipulación de salida y el observador se llama para todos bloque hace, esto sólo se debe utilizar cuando la principal preocupación es evitar una reescritura bloque. Además, el contenido generado en este observador es manipulado post-block_html caché de escritura (a través de la llamada de la instancia del bloque de _saveCache()), por lo que sería o bien tendrá que re-caché la entrada block_html en el observador (una pegajosa poco, ya que o bien estaría utilizando la reflexión o duplicar la lógica tanto de los métodos _saveCache() y _getSidPlaceholder() a escribir la entrada de caché. y, por último, si usted necesita para manipular todo lo relacionado con los datos del nodo de árbol, que tendría que generar una copia de los datos del nodo de árbol. Esto podría ser teóricamente hecho por el acaparamiento de la Singleton Mage_Catalog_Model_Observer y agarrando el árbol de él ... de hecho muy pegajosa.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a magento.stackexchange
scroll top