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

发布于 2024-10-21 20:57:11 字数 1191 浏览 2 评论 0原文

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

        }
    }

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

        }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

往日 2024-10-28 20:57:11

基本上,您需要控制 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()”黑客行为。退出/死亡不好的原因是它阻止了任何已注册对该事件感兴趣的后续观察者能够采取行动。作为一名开发人员,注册一个永远不会被调用的观察者是非常令人沮丧的,因为在你被击中之前另一个开发人员已经退出了!

请注意,设置no-dispatch 标志在您挂接到预调度事件中时才起作用。

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文