2012-09-14 6 views
5

Ich versuche, einen Beobachter zu verwenden, um die Antwort der Add-to-Cart-Controlleraktion zu modifizieren, aber nur im Kontext einer AJAX-Anforderung.Antwort in einem Magento-Ereignisbeobachter kann nicht geändert werden, obwohl der Beobachter feuert

Mein Beobachter ist genannt und meine JS Daten fein abruft, habe ich dies bestätigt durch eine die() in meiner Beobachtungsfunktion cartAdd() und Überprüfung der Antwort Entwicklerkonsole setzen, die ich das Ergebnis meiner Antwort sehen bin mit von Magento. JS ist hier nicht das Problem.

Mein Hauptproblem ist, dass ich nicht scheinen kann, die Antwort durch die normalen Funktionen zu ändern. Ich bekomme die Anfrage, indem ich $observer->getEvent()->getControllerAction()->getResponse() benutze und dann Änderungen daran durch setHeader(), oder setBody(), oder jede andere Funktion, die die Antwort ändert, aber es gibt absolut keinen Effekt auf die Antwort!

Hat jemand irgendeine Ahnung, warum ich die Antwort in meinem Beobachter nicht ändern kann?

In /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> 

In /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); 
    } 
} 

Bitte beachten Sie: Ich weiß, dass dieser Code überhaupt nicht AJAXify hinzufügen wird (was mein Endziel ist). Im Moment bin ich nur versucht, dieses Problem zu beheben

ich nur am Ende immer die Inhalte der Seite, die Sie sich als Ergebnis der Ausführung eines Add den Warenkorb Aktion enden würde:

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

+1

99% sicher, dass die Anforderung nach dem Auslösen des dynamischen Predispatch-Ereignisses eine andere Redirect-Einstellung enthält. Bestätigt jetzt, wird antworten. – benmarks

Antwort

8

Wenn ein Produkt zum Warenkorb hinzugefügt wird, gibt es ein vom Administrator konfigurierbares Verhalten, um eine Person zur Einkaufswagenseite zu senden oder um sie zurück zur Produktseite zu leiten. Weitere Informationen finden Sie unter System> Konfiguration> Checkout> Einkaufswagen: Nach dem Hinzufügen einer Produktumleitung zum Einkaufswagen Feld.

Dieses Redirect-Verhalten wird über eine Weiterleitung erreicht, die jede Redirect-Menge im dynamischen controller_action_predispatch_checkout_cart_add-Event ersetzt; ref. the final bit of logic von der Mage_Checkout_CartController::addAction(). Hab keine Angst! Magento-Core-Entwickler müssen dieses Verhalten ebenfalls außer Kraft setzen. Daher ist es möglich, das Mage_Checkout Wagensteuergerät addAction() zu informieren, um das normale Umleitungsverhalten zu umgehen, wenn ein Flag für das Objekt checkout/session gesetzt wurde. Es gibt nicht nur einen Haken und unterstützende Logik, um es zum Laufen zu bringen, sondern es gibt auch ein funktionierendes Beispiel aus dem Kern - immer eine gute Sache für Entwickler.

Unmittelbar vor der endgültigen Umleitungslogik in der addAction()-Methode löst die addAction()-Methode des Wagencontrollers das Ereignis checkout_cart_add_product_complete aus. This event is observed von der Mage_Wishlist Beobachter. Eine schnelle Überprüfung von relevant final logic von der Mage_Wishlist_Model_Observer::processAddToCart() Methode zeigt, wie verhindert werden kann, dass die addAction()-Methode des Wagenreglers umleitet - nämlich durch Setzen des no_cart_redirect-Flags auf checkout/session Objekt, das die Redirect-Set für das Antwortobjekt erhält.

Es gibt eine weitere Überlegung in diesem Fall. Es ist wahrscheinlich, dass das Mage_Wishlist Beobachter-Verhalten beibehalten werden sollte, nämlich: nachdem ein Produkt aus der Wunschliste in den Warenkorb hinzugefügt wurde, kann ein Kunde zum nächsten Produkt auf seiner Wunschliste weitergeleitet werden. Dies ist einer der Fälle, in denen die Reihenfolge der Beobachterverarbeitung von Bedeutung ist. Um sicherzustellen, dass das Mage_Wishlist Modul zum Warenkorb Verhalten beibehalten wird, sollten andere Module, die das Ereignis checkout_cart_add_product_complete verbrauchen, vor dem Mage_Wishlist Beobachter ausgelöst werden. In der Deklarationsdatei für das benutzerdefinierte Modul sollte das Mage_Wishlist Modul in Abhängigkeit von dem benutzerdefinierten Modul eingestellt werden, die sicherstellen, dass der Beobachter benutzerdefinierten Modul vor dem Mage_Wishlist Modul ausgelöst wird:

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

Wenn die Mage_Wishlist Modul war kein Faktor, das besser zielgerichtete Ereignis wäre das dynamisch erzeugte Ereignis controller_action_postdispatch_checkout_cart_add, das das letzte Zielereignis vor dem generischen Ereignis controller_front_send_response_before ist.

+0

Wirklich nützliche Informationen Danke! Ich habe auch bemerkt, dass die Ereignisse komplett umgangen werden, wenn sie nicht eingeloggt sind, aber das kann etwas für meine Umgebung sein. 'customer/session-> authenticate()' wird irgendwo aufgerufen und leitet auf die Anmeldeseite um, ohne das 'no_cart_redirect'-Flag zu beachten. Dies ist jedoch in Ordnung, da es nicht möglich ist, den Warenkorb hinzuzufügen, es sei denn, in meinem Fall angemeldet ist. Ich werde das Frontend einfach anders verhalten lassen. Danke nochmal –

+0

@benmarks tolle Antwort wie immer. Übrigens bekomme ich es nicht: '$ this -> _ getSession() -> getNoCartRedirect (true)'. Was bedeuten args 'true'? Sieht so aus, als würde das Flag 'no_redirect_flag' nur als Daten in' Varien_Object' gesetzt/abgerufen, da ich es im 'checkout/session' Modell nicht explizit als 'attribute' definiere. Habe ich recht? – ivantedja

+1

@ivantedja Die Sitzungsmodelle haben einen modifizierten Getter. Wenn Sie den Wert true übergeben, wird der Wert abgerufen und die Eigenschaft wird nicht gesetzt. – benmarks