13

我在结帐中有一些代码,我在会话中设置了一个键,如果该键在结帐中的任何地方设置为 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);

        }
    }
4

1 回答 1

27

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

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

$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 (请永远不要......)或使用“ exit/die()”hackiness。exit/die 不好的原因是它阻止了任何后来注册对该事件感兴趣的观察者能够采取行动。作为一个开发者注册一个永远不会被调用的观察者是非常令人沮丧的,因为另一个开发者在你被击中之前已经退出了!

请注意,设置no-dispatch标志在您参与预调度事件时才有效。

有关更多信息,请查看 Magento序列图以了解您如何绕过流程的布局/块/模板部分。

于 2011-03-13T22:19:26.497 回答