Magento - 从Observer方法重定向客户

Kno*_*ing 8 php redirect magento

在这种情况下checkout_cart_add_product_complete,我希望将客户重定向到外部网页http://www.example.com/.为此,我使用的代码根本不起作用: -

public function moduleMethod() {
    /* @var $response1 Mage_Core_Controller_Response_Http */
    $response1 = $observer->getEvent()->getResponse();

    /* @var $response2 Mage_Core_Controller_Response_Http */
    $response2 = Mage::app()->getResponse();

    $url = 'http://www.example.com/';
    $response1->setRedirect($url);

    return;
}
Run Code Online (Sandbox Code Playgroud)

setRedirect()在这些变量" $response1"和" $response2" 上都使用了" "方法,但它们都显示了购物车页面,而我希望看到这个页面http://www.example.com/.

我想要的是:

  • 当我可以有效地使用Event Observer进程时,我不想覆盖Controller类,只是为了重定向Customer.
  • header()当Magento框架以有效的方式提供此功能时,我不想使用PHP内置函数" ".

ben*_*rks 17

tl; dr:底部的正确观察者代码.

我回答之前的注意事项:确保观察者被触发; 单步执行代码或使用die('here');.如上所述,您的示例方法没有正确的原型来接收事件观察者数据(缺少参数).

在这种情况下,使用事件观察器进行重定向逻辑是完全合适的,正如核心团队明确地将请求和响应对象传递给观察者所表明的那样.你的尝试是好的,但我认为你有条件和配置导致执行流向Mage_Checkout_CartController::_goBack(),特别是线

$this->_redirect('checkout/cart');
Run Code Online (Sandbox Code Playgroud)

所以我们需要修改我们的方法.现在,您可以通过操作响应并调用Front Controller的sendResponse()方法来阻止任何请求/响应逻辑在事件观察者之后进行处理,如下所示(nb:不要这样做!):

public function moduleMethod($observer) //note I added a param
{
    /* @var $response1 Mage_Core_Controller_Response_Http */
    $response1 = $observer->getResponse(); // observers have event args

    $url = 'http://www.example.com/';
    $response1->setRedirect($url);

    /* SHOULDN'T DO THIS */
    Mage::app()->getFrontController()->sendResponse();
}
Run Code Online (Sandbox Code Playgroud)

这应该可行,但我认为它通过触发空灵系统组件(EDA)的输出来混淆关注的领域.让我们看看命令控制结构中是否有我们可以使用的东西......

就在checkout_cart_add_product_complete事件执行到了购物车控制器的_goBack()方法之后.这个方法名称的问题在于它的名称超出了它的名称:

/**
 * Set back redirect url to response
 *
 * @return Mage_Checkout_CartController
 */
protected function _goBack()
{
    $returnUrl = $this->getRequest()->getParam('return_url');
    if ($returnUrl) {
        // clear layout messages in case of external url redirect
        if ($this->_isUrlInternal($returnUrl)) {
            $this->_getSession()->getMessages(true);
        }
        $this->getResponse()->setRedirect($returnUrl);
    }
    //...
}
Run Code Online (Sandbox Code Playgroud)

看起来我们可以return_url在请求对象上设置一个参数并完成我们需要的工作.

public function moduleMethod(Varien_Event_Observer $observer)
{
    $observer->getRequest()->setParam('return_url','http://www.google.com/');
}
Run Code Online (Sandbox Code Playgroud)

我已经测试了这个,它应该可以做到!

  • @Slimshadddyyy你提到的方法有效.但是,它涉及在事件观察器内部刷新输出,而不是从调用堆栈中的通常点(Front Controller的`dispatch()`方法).这违反了关注点的分离,这有助于使Magento(和其他MVC框架)变得更加混乱.但是,如果它适合你并且你有一个令人信服的案例采取这种方法,那就去吧!(在我的回答中,我确实涵盖了您提出的解决方案,BTW.) (2认同)