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

时间:2011-03-13 16:15:27

标签: php magento observers

我在结帐时有一些代码,我在会话中设置了一个密钥,如果在结帐时将该密钥设置为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);

        }
    }

1 个答案:

答案 0 :(得分: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);

上面的行指示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

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

请注意,如果您已连接到predispatch事件,则设置no-dispatch标记

有关详细信息,请查看Magento sequence diagram,了解您如何绕过流程的布局/阻止/模板部分。