停止Magento事件观察员结账的正确方法是什么?

时间:2011-01-18 21:47:52

标签: php magento

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

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

3 个答案:

答案 0 :(得分:9)

(这些都不是经过测试的代码,但概念可以让你到达目的地)

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

答案 1 :(得分:9)

Alan Storm的回答一如既往,提供了丰富的信息和启发。但在这种情况下,单页结账主要是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);
}

答案 2 :(得分:3)

我想出了一个不同的方法,不必覆盖控制器。基本上我做同样的事情,但只是在观察者方法。所以我使用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->getFullActionName()

所以我用它来观察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操作中设置的响应主体。