在Observer方法中,如何告诉Magento在调度事件后不处理代码

dan*_*des 13 php observers magento

我在结帐时有一些代码,我在会话中设置了一个密钥,如果在结帐时将该密钥设置为false,我需要将它们发送回结算页面.我有它的代码,但我也不能拥有通常在观察者之后运行的任何代码,因为它会调用第三方服务并因为会话中缺少此密钥而返回错误

这是我的代码,我有我想要的一切,但我需要立即发生的响应,并且在调度的事件行被发送后只发送回发送回浏览器的响应.

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);

        }
    }
Run Code Online (Sandbox Code Playgroud)

Jon*_*Day 27

基本上,您需要控制Response对象的创建和发送.控制器的正常流程将处理所有方法的内联逻辑,触发它的事件并在此过程中收集响应的添加内容,然后Magento框架将完成并发送响应.

您可以通过附加到preDispatch事件(controller_action_predispatch_checkout_onepage_savebilling)然后执行以下操作来使Observer中的流短路:

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

上面的行指示Mage_Core_Controller_Varien_Action(所有控制器的祖父母)绕过已调用的动作(在CE 1.4.2中查看414行以查看其工作原理).然后继续创建自己的响应并将其发送回浏览器.您将需要调查正确的JSON格式,以便检查JS类呈现任何错误消息,但这些行中的某些内容......

$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
Run Code Online (Sandbox Code Playgroud)

这样你就可以在Zend/Magento框架内工作,你不需要覆盖CheckoutController(请永远不要......)或使用" exit/die()"hackiness.退出/死亡的原因是它阻止任何后来注册了对该事件感兴趣的观察者能够采取行动.作为开发人员注册一个永远不会被调用的Observer会非常令人沮丧,因为另一个开发人员在你被击中之前已退出!!

请注意,设置no-dispatch标志在您连接到predispatch事件时才有效.

有关详细信息,请查看Magento 序列图,了解如何绕过流的布局/块/模板部分.

  • 伟大的答案人.但是在测试之后我们可能想要更新您的答案以不发送响应,只要您设置将在最后发送的响应主体,否则它将发送相同的响应两次,这将使一切都搞乱.这是伟大的人,感谢你做了我欠你的研究.再一次,我通过提问来增加我的法师知识.这个是我的最爱. (2认同)