在 Magento 中停止事件观察者结帐的正确方法是什么?

发布于 2024-10-12 19:51:33 字数 168 浏览 1 评论 0原文

我正在 checkout_controller_onepage_save_shipping_method 事件期间验证运输报价,如果验证失败,我想将用户发送回运输方式选择,但我还想显示一条消息,说明失败的原因。 Magento 有内置的方法吗?

我已经在验证数据,只是缺少重定向到运输方式和显示消息的方式。

I am verifying shipping quotes during the event checkout_controller_onepage_save_shipping_method and if the verification fails i want to send the user back to shipping method selection but I would also like to display a message saying why it failed. Does Magento have a way of doing this built in?

I am already verifying the data I just lack the redirect to shipping methods and way to display a message.

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

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

发布评论

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

评论(3

若沐 2024-10-19 19:51:33

艾伦·斯托姆的回答一如既往地内容丰富且富有启发性。但在这种情况下,单页结帐主要是 AJAX,它会忽略会话错误消息,直到离开结帐页面时您才会看到它。

saveShippingMethodAction 中有以下行:

$result = $this->getOnepage()->saveShippingMethod($data);

...然后 $result 是 JSON 编码的。如果您重写 Mage_Checkout_Model_Type_Onepage::saveShippingMethod 来执行检查,然后控制返回的内容,您可以插入一条错误消息,该消息将返回到浏览器并在弹出窗口中显示给用户。

您的覆盖可能看起来像这样:

public function saveShippingMethod($shippingMethod)
{
    if ($this->doesntApplyHere()) {
        return array('error' => -1, 'message' => $this->_helper->__('Explain the problem here.'));
    }
    return parent::saveShippingMethod($shippingMethod);
}

Alan Storm's answer is, as ever, informative and enlightening. But in this situation the onepage checkout is mostly AJAX which ignores the session error message, you won't see it until leaving the checkout page.

In saveShippingMethodAction there is the following line:

$result = $this->getOnepage()->saveShippingMethod($data);

...and then $result is JSON encoded. If you override Mage_Checkout_Model_Type_Onepage::saveShippingMethod to perform your check then control what is returned you can insert an error message that will be returned to the browser and shown to the user in a popup.

Your override might look something like this:

public function saveShippingMethod($shippingMethod)
{
    if ($this->doesntApplyHere()) {
        return array('error' => -1, 'message' => $this->_helper->__('Explain the problem here.'));
    }
    return parent::saveShippingMethod($shippingMethod);
}
千笙结 2024-10-19 19:51:33

(这些都不是经过测试的代码,但这些概念应该可以帮助您到达您需要去的地方)

Magento 是一个由一群软件工程师运行的项目。当您与一群软件工程师一起工作时,文档就是代码。

即,每当您需要使用 Magento 做一些常见的事情时,请观察核心团队是如何完成的,并考虑到您应该将自己限制为观察者、覆盖和新代码,因为您无法与所述核心团队讨论您的更改。

看一下单页结帐控制器的 IndexAction 方法

app/code/core/Mage/Checkout/controllers/OnepageController.php
public function indexAction()
{
    if (!Mage::helper('checkout')->canOnepageCheckout()) {
        Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
        $this->_redirect('checkout/cart');
        return;
    }
    ... 

Magento 允许您向会话对象添加错误,该错误将由下一个请求的消息块进行处理。

Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));

处理错误的那个。接下来是重定向。这种情况发生在这里,

$this->_redirect('checkout/cart');

因为您是从观察者调用此代码,所以您将无权访问此方法。但是,如果您检查控制器,

/**
 * Retrieve request object
 *
 * @return Mage_Core_Controller_Request_Http
 */
public function getRequest()
{
    return $this->_request;
}
...
protected function _redirect($path, $arguments=array())
{
    $this->getResponse()->setRedirect(Mage::getUrl($path, $arguments));
    return $this;
}

您可以看到它使用响应对象。 Magento 使用全局响应对象(类似于 Zend 和其他 Web 框架)来处理发送回浏览器的内容(即重定向标头)。您可以通过以下方式获取对同一对象的引用

Mage::app()->getResponse()

,并可以使用类似的内容执行重定向

Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));

(None of this is tested code, but the concepts should get you where you need to go)

Magento is a project run by a bunch of software engineers. When you're working with a bunch of software engineers, the documentation is the code.

i.e. Whenever you need to do something common with Magento, observe how the core team has done it, taking into account that you should limit yourself to observers, overrides, and new code since you can't discuss your changes with said core team.

Take a look at the one page checkout controller's IndexAction method

app/code/core/Mage/Checkout/controllers/OnepageController.php
public function indexAction()
{
    if (!Mage::helper('checkout')->canOnepageCheckout()) {
        Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));
        $this->_redirect('checkout/cart');
        return;
    }
    ... 

Magento allows you add errors to the session object, which will be processed by the messaging block on the next request.

Mage::getSingleton('checkout/session')->addError($this->__('The onepage checkout is disabled.'));

That that handles an error. Next, there's the redirect. This happens here

$this->_redirect('checkout/cart');

Since you're calling this code from an observer, you won't have access to this method. However, if you examine the controller

/**
 * Retrieve request object
 *
 * @return Mage_Core_Controller_Request_Http
 */
public function getRequest()
{
    return $this->_request;
}
...
protected function _redirect($path, $arguments=array())
{
    $this->getResponse()->setRedirect(Mage::getUrl($path, $arguments));
    return $this;
}

You can see its using the response object. Magento uses a global response object (similar to Zend, and other Web frameworks) to handle what gets sent back to the browser (i.e. redirect headers). You can get a reference to the same object via

Mage::app()->getResponse()

and could perform a redirect with something like

Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));
沙与沫 2024-10-19 19:51:33

我为此想出了一种不同的方法,不必覆盖控制器。基本上我做同样的事情,但只是用观察者方法。因此,我也使用 checkout_controller_onepage_save_shipping_method 来验证运输方法,如果出现错误,我会将该错误添加到会话变量中,如下所示

 $error = array('error' => -1, 'message' => Mage::helper('core')->__("Message here"));
 Mage::getSingleton('checkout/session')->setSavedMethodError($error);

然后,您可以为每个操作应用另一个观察者到 'controller_action_postdispatch_'.$this-> )

所以我用它来观察controller_action_postdispatch_checkout_onepage_saveShippingMethod,在那里我检查会话错误变量并设置响应正文(如果存在

$error =  Mage::getSingleton('checkout/session')->getSavedMethodError();
if($error){
   Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($error));
}
Mage::getSingleton('checkout/session')->setSavedMethodError(false);

。我不确定这是好是坏,所以请留下任何评论,但我知道我更希望能够做到这一点,而不必对课程进行任何重写。

这是有效的,因为您正在覆盖在 saveShippingMethod 操作中设置的响应正文。

I came up with a different approach for this, not having to override the controller. Basically I do the same thing but just in observer methods. So I am using checkout_controller_onepage_save_shipping_method to validate the shipping methods as well and if there is an error I add that error to a session variable like the following

 $error = array('error' => -1, 'message' => Mage::helper('core')->__("Message here"));
 Mage::getSingleton('checkout/session')->setSavedMethodError($error);

Then you can for every action apply another observer to 'controller_action_postdispatch_'.$this->getFullActionName()

So I used that to observe controller_action_postdispatch_checkout_onepage_saveShippingMethod Which in there I check for the session error variable and set the response body if it exists.

$error =  Mage::getSingleton('checkout/session')->getSavedMethodError();
if($error){
   Mage::app()->getResponse()->setBody(Mage::helper('core')->jsonEncode($error));
}
Mage::getSingleton('checkout/session')->setSavedMethodError(false);

I am not sure if this is better or worse, so please leave any comments but I know I preferred to be able to do this without having to do any rewriting of the class.

This works because you are overriding the response body that was set in the saveShippingMethod action.

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