Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In an Observer method, how do you tell Magento to not process code after the dispatched event

I have some code in the checkout where I set a key in the session if that key is set to false anywhere in the checkout I need to send them back to the billing page. I have the code for it, but I also can't have any of the code that is typically ran after the observer because it will call a third party service and come back as wrong because of this key that is missing in the session

Here is my code, I have everything I want but i need the response to happen immediatly and for nothing after the dispatched event line to be fired only the response sent back to the browser.

public function checkForOrdKey(Varien_Event_Observer $observer)
    {
        $controllerAction = $observer->getControllerAction();
        $request = $controllerAction->getRequest();
        $controllerName = $request->getControllerName();
        $stepData = $this->_getCheckoutSession()->getStepData();
        $ordKeyRemoved = $this->_getCheckoutSession()->getOrdKeyRemoved();
        // if it is the checkout onepage controller or inventory controller don't do anything
        if (isset($controllerName) && $controllerName === "onepage" && $stepData['shipping']['complete'] && $ordKeyRemoved) {
            $this->_getCheckoutSession()->setStepData('shipping', 'complete', false);
            $result['goto_section'] = 'billing';
            Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($result));
            $this->_getCheckoutSession()->setOrdKeyRemoved(false);

        }
    }
like image 395
dan.codes Avatar asked Mar 13 '11 16:03

dan.codes


People also ask

When the observers are executed in Magento?

Magento 2 Observers They are executed whenever a specific event for which they were set to listen is triggered. To create an observer in Magento 2, you must place your class file under the ModuleRoot/Observer directory.

What is the class that handles event dispatching in Magento 2?

Events can be dispatched using the Magento\Framework\Event\ManagerInterface class. This class can be obtained through dependency injection by defining the dependency in your constructor.

In which order the observers will get executed which are listening to the same event?

Observers listening to the same event may be invoked in any order when that event is dispatched.

How do I redirect observer in Magento 2?

In above execute() function, When you need redirect to specific URL, You need to pass your custom URL instead of customer/account/login as the second parameter in redirect() function.


1 Answers

Basically you need to take control of the creation and sending of the Response object. The normal flow of the controller will process all the method's inline logic, fire it's Events and collect additions to the Response along the way, then the Magento framework will finalize and send the Response.

You can short-circuit that flow in the Observer by attaching to the preDispatch event (controller_action_predispatch_checkout_onepage_savebilling) and then executing this:

$request = Mage::app()->getRequest();
$action = $request->getActionName();
Mage::app()->getFrontController()->getAction()->setFlag($action, Mage_Core_Controller_Varien_Action::FLAG_NO_DISPATCH, true);

The lines above instruct Mage_Core_Controller_Varien_Action (grandparent of all controllers) to bypass the action that has been called (review line 414 in CE 1.4.2 to see how this works). Then proceed with creating your own response and sending it back to the browser. You will need to investigate the correct JSON format to have to the checkout JS classes render any error messages, but something along these lines...

$response = Mage::app()->getResponse();
$response->setHttpResponseCode(500);  //adjust to be whatever code is relevant
$json = Mage::helper('core')->jsonEncode($this->__('Your message here'));  //adjust
$response->setBody($json);
//don't need to sendResponse() as the framework will do this later

That way you're working within the Zend/Magento framework and you don't need to Override the CheckoutController (please, never ever...) or use "exit/die()" hackiness. The reason that exit/die is bad is that it prevents any later Observers that have registered an interest in that Event being able to act. It would be extremely frustrating as a developer to register an Observer that never gets called because another developer has exit'd before you get hit!!

Note that setting the no-dispatch flag will only work if you are hooked into the predispatch Event.

For further info, review the Magento sequence diagram to see how you are bypassing the Layout/Block/Template sections of the flow.

like image 77
Jonathan Day Avatar answered Oct 05 '22 23:10

Jonathan Day