Mit PreDispatch Controller-Actions ändern
Einen Core-Controller umzuleiten fühlt sich irgendwie nicht so richtig schick an. Alleine deswegen weil eine merkwürdige require-Anweisung im Kopf des Controllers stehen muss. Aber wie geht es besser? Predispatch ist die Antwort auf die Frage.
Bei jedem Controller wird vor dem Aufruf der Action ein PreDispatch und ein PostDispatch aufgerufen. Zwischen den beiden findet die eigentliche Aktion, also die Implementierung statt. Will man nun die weiteren Schritte im Checkout nur erlauben falls eine bestimmte Mindestmenge oder ein Mindestumsatz erfüllt ist reicht es nicht aus nur den “zur Kasse”-Button zu entfernen. Wichtig ist ebenfalls das der Checkout nicht über den Direktlink aufgerufen werden kann.Wir hängen uns also als den PreDispatch Event des Controllers. Dazu ergänzen wir die config.xml wie folgt:
<global> [..] <events> <controller_action_predispatch_checkout> <observers> <mindestumsatz_controller_action_predispatch_checkout> <class>mindestumsatz/observer</class> <method>controller_action_predispatch_checkout</method> </mindestumsatz_controller_action_predispatch_checkout> </observers> </controller_action_predispatch_checkout> </events> [..] </global>
Bevor nun die Action des Controllers aufgerufen wird unsere Methode controller_action_predispatch_checkout im Observer-Model aufgerufen:
<?php
class Codex_Mindestumsatz_Model_Observer {
public function controller_action_predispatch_checkout( $event ) {
$controller = $event->getControllerAction();
/* @var $controller Mage_Checkout_CartController */
if( $controller->getRequest()->getControllerName() == 'onepage' && !Mage::helper('mindestumsatz')->getIsMindestumsatz() ) {
/*
* Wenn der Mindestumsatz nicht erfüllt wurde aber der Checkout onepage aufgerufen wird
* auf den Cart-Index umleiten
*/
$controller->getResponse()->setRedirect( Mage::getUrl('*/cart') );
$controller->getResponse()->sendResponse();
$controller->getRequest()->setDispatched( true );
}
}
}
Da wir uns komplett am Modul checkout angedockt haben müssen wir nun noch abfragen ob der Controller den Namen “onepage” hat. Falls zutreffend wollen wir direkt auf den Warenkorb umleiten. Dazu holen wir uns vom Controller den Response, starten einen Redirect und sorgen, mittels setDispatched dafür das alles andere nicht weiterverarbeitet wird. Fertig, und alles ohne einen Controller Rewrite!
Update: Eine weitere (ähnliche) Möglichkeit stellt Karl Spies in seinem Blog-Beitrag vor.
Der Autor
Tobias Vogt arbeitet seit 2008 mit Magento und ist seit 2011 durch Magento zertifizierter Entwickler. Beschäftigt ist er bei der code-x GmbH, einer Agentur für Internet und Marketing aus Paderborn. Er gehört zum Gründer-Team der Webguys und ist seit November 2011 Bachelor of Science (Wirtschaftsinformatik). Sie erreichen Ihn per E-Mail unter tobi@webguys.de.




[...] Controller Actions mit Events überschreiben neue Anregungen. Ähnlich dazu auch folgender Text: mit PreDispatch Controller-Actions ändern.Eine schöne Idee, die ich aufgreifen möchte, wird bei magebase beschrieben: man soll die [...]
Sehr clever, gefällt mir!
Viele Grüße!
Danke
Mit diesem Code werden noch zu abarbeitende Error Messages ausgegeben:
$controller = $observer->getControllerAction()->setFlag('',Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH,true); $controller->getResponse()->setRedirect('customer/account/login');Das sendResponse() ist hier dann nicht mehr nötig sowie setDispatched(true).
Das sendResponse() hat dummerweise die Messages die ich im pre-dispatch gesetzt habe gelöscht.
Ich habe mal PHP-Tags zu deinem Code hinzugefügt damit er lesbar ist
Guter Hinweis, danke!