2012-09-14 14 views
5

Estoy intentando usar un observador para modificar la respuesta de la acción del controlador añadir al carrito, pero solo en el contexto de una solicitud AJAX.No se puede modificar la respuesta en un observador de eventos Magento, aunque el observador está disparando

Mi observador es llamada y mi JS está recuperando bien de datos, he verificado esto poniendo un die() en mi función de observador cartAdd() y verificación de la consola del programador de respuesta, que estoy usando para ver el resultado de mi respuesta de Magento. Entonces JS no es el problema aquí.

Mi problema principal es que parece que no puedo modificar la respuesta a través de las funciones normales. Recibo la solicitud usando $observer->getEvent()->getControllerAction()->getResponse() y luego hago cambios en ella por setHeader(), o setBody(), o cualquier otra función que modifique la respuesta, ¡pero no hay ningún efecto en la respuesta!

¿Alguien tiene alguna pista de por qué no puedo modificar la respuesta en mi observador?

En /app/code/local/mynamespace/mymodule/etc/config.xml:

<frontend> 
.... 
    <events> 
     <controller_action_predispatch_checkout_cart_add> 
      <observers> 
       <mymodule_cart_add> 
        <type>singleton</type> 
        <class>mymodule/observer</class> 
        <method>cartAdd</method> 
       </mymodule_cart_add> 
      </observers> 
     </controller_action_predispatch_checkout_cart_add> 
    </events> 
</frontend> 

En /app/code/local/mynamespace/mymodule/Model/Observer.php:

public function cartAdd(Varien_Event_Observer $observer) 
{ 
    $controllerAction = $observer->getEvent()->getControllerAction(); 
    if($controllerAction->getRequest()->isAjax()) { 
     $response = $controllerAction->getResponse(); 
     // I've even tried using: 
     // $response = Mage::app()->getResponse(); 
     $response->setHeader('HTTP/1.1','403 Forbidden'); //using this because i will need it in my final code and it will make it immediatly obvious the response has been changed 
     $response->setHeader('Content-type', 'application/json'); 
     $response->setBody('hello world!!!!'); 
     // this is to stop the product from being added to the cart 
     $controllerAction->setFlag('', Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true); 
    } 
} 

Tenga en cuenta: Sé que este código no va a añadir nada al carrito (que es mi objetivo final). En este momento estoy tratando de resolver este problema

termino sólo conseguir el contenido de la página que terminarían como un resultado de ejecutar un complemento a la cesta de acción:

An example of the data I am seeing in the console, as shown to me by my JS code

+1

99% Asegúrese de que la solicitud tenga un redireccionamiento diferente configurado después de que se active el evento de predispatch dinámico. Confirmando ahora, responderá. – benmarks

Respuesta

8

Cuando se agrega un producto al carrito, existe un comportamiento configurable por el administrador para enviar a una persona a la página del carrito o redirigirlo a la página del producto. Consulte el Sistema> Configuración> Pagar> Carro de la compra: después de agregar un redireccionamiento de producto al carro de la compra campo.

Este comportamiento de redirección se realiza mediante una redirección que desplazará cualquier conjunto de redirección en el evento controller_action_predispatch_checkout_cart_add dinámico; ref. the final bit of logic del Mage_Checkout_CartController::addAction(). ¡No tengas miedo, sin embargo! Los desarrolladores principales de Magento también tienen que anular este comportamiento, por lo que es posible informar al Mage_Checkout método addAction() del controlador de carro para eludir el comportamiento de redirección normal si se ha establecido un indicador en el objeto checkout/session. No solo hay un gancho y una lógica de soporte para hacerlo funcionar, sino que en realidad hay un ejemplo de trabajo desde el núcleo, siempre es algo bueno para los desarrolladores.

Justo antes de la lógica de redirección final en el método addAction(), el método addAction() del controlador de la carretilla distribuye el evento checkout_cart_add_product_complete. This event is observed por el Mage_Wishlist observador. Una revisión rápida de relevant final logic del método Mage_Wishlist_Model_Observer::processAddToCart() muestra cómo evitar el redireccionamiento del método addAction() del controlador de carro, es decir, estableciendo el indicador no_cart_redirect en el objeto checkout/session, que conserva el conjunto de redirección en el objeto de respuesta.

Hay una consideración más en este caso. Es probable que se preserve el comportamiento de los observadores Mage_Wishlist, a saber: después de agregar un producto al carrito de la lista de deseos, un cliente puede ser redirigido al siguiente producto en su lista de deseos. Esta es una de las instancias en las que importa el orden de procesamiento del observador. Para asegurarse de que se conserva el comportamiento Mage_Wishlist add to cart, otros módulos que consumen el evento checkout_cart_add_product_complete deben activarse antes del Mage_Wishlist observador. En el expediente de declaración para el módulo personalizado, el módulo Mage_Wishlist debe establecerse como dependiente del módulo personalizado, lo que asegurará que observador del módulo personalizado se disparará antes de la Mage_Wishlist módulo:

<?xml version="1.0" encoding="UTF-8"?> 
<config> 
    <modules> 
     <Custom_Module> 
      <active>true</active> 
      <codePool>local</codePool> 
     </Custom_Module> 
     <Mage_Wishlist> 
      <depends> 
       <Custom_Module /> 
      </depends> 
     </Mage_Wishlist> 
    </modules> 
</config> 

Si el Mage_Wishlist módulo no fueron un factor, el evento mejor dirigido a consumir sería el evento controller_action_postdispatch_checkout_cart_add generado dinámicamente, que es el último evento específico antes del evento genérico controller_front_send_response_before.

+0

Información realmente útil gracias! También noté que los eventos se omiten por completo cuando no estoy conectado, pero eso puede ser algo específico de mi entorno. 'customer/session-> authenticate()' se llama en algún lugar y redirige a la página de inicio de sesión sin consultar el indicador 'no_cart_redirect'. Sin embargo, esto está bien, ya que no se puede agregar al carrito a menos que esté registrado en mi caso. Haré que el frontend se comporte de manera diferente. Gracias de nuevo –

+0

@benmarks gran respuesta como siempre. Por cierto, no lo entiendo: '$ this -> _ getSession() -> getNoCartRedirect (true)'. ¿Cuál es el significado de args 'true'? Parece que la bandera 'no_redirect_flag' solo establece/obtiene como datos en' Varien_Object', ya que no la veo explícitamente definida como 'attribute' en el modelo' checkout/session'. ¿Estoy en lo cierto? – ivantedja

+1

@ivantedja los modelos de sesión tienen un getter modificado. Al pasar en verdadero, se recupera el valor y luego la propiedad no está configurada. – benmarks

Cuestiones relacionadas