2012-03-17 55 views
8

在此事件checkout_cart_add_product_complete,我希望客户被重定向到外部网页http://www.example.com/。对于这个我使用这个代码,这是不工作: -Magento - 从观察者方法重定向客户

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

我已经使用了“setRedirect()”的方法在这两个变量“$response1”和“$response2”,但他们都告诉我购物车页面,而我希望看到此页http://www.example.com/

我想要什么:

  • 我不希望重写控制器类,只是重定向客户,当我能够有效地使用事件观察器进程。
  • 当Magento框架以有效的方式提供此功能时,我不想使用PHP内置函数“header()”。

回答

16

tl; dr:正确的观察员代码在底部。

我回答之前的一个注意事项:确保观察者正在被触发;浏览您的代码或使用die('here');。正如所写,您的示例方法没有正确的原型来接收事件观察者数据(缺少参数)。

在此上下文中使用事件观察者来完成重定向逻辑,正如核心团队明确将请求和响应对象传递给观察者所证明的那样。您的尝试是好的,但我认为你有这导致执行流向Mage_Checkout_CartController::_goBack()条件和配置,具体线路

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

所以我们需要修改我们的做法。现在,你可以防止处理任何请求/响应逻辑的事件观察后,通过操作响应和调用前端控制器sendResponse()方法,如下面所示(注:不这样做!):

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

这应该可行,但我认为它通过触发空灵系统组件(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); 
    } 
    //... 
} 

看起来我们可以只设置请求对象的return_url PARAM,完成我们所需要的。

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

我测试了这个,它应该做的窍门!

+0

非常感谢,因为你在这个答案中的可怕细节,这是完美的工作!是的,我错过了在方法定义中提到的论点,所以谢谢你纠正我。如果您能详细说明EDA及其在Magento上的利弊,那将非常棒! – 2012-03-18 17:40:40

+1

Magento具有遍历多个图层的深层调用堆栈。如果没有它的事件架构,许多定制将会非常容易入侵,并且会导致很多繁琐。 – benmarks 2012-03-18 21:37:28

+0

大帮忙,谢谢! – 2013-08-04 00:39:46

2

我不得不通过getFront

public function moduleMethod($observer) { 
    $observer->getEvent()->getFront()->getResponse()->setRedirect('http://www.google.com'); 
} 
+0

如果您看到“Ben”给出的答案,您将看到他使用上下文对象('$ this')来获取Response $ this-> getResponse()而不是$ observer对象。 希望它有帮助。 – 2013-05-09 05:28:26

+0

是的,但是他的最终解决方案(即在请求中设置'return_url'参数)对于我正在做的事情没有效果,我认为这是不直观的。这段代码完成了我相信你的代码最初试图做的事情。 – Klaus 2013-05-13 21:03:30

+0

是的,我的要求是一个非常具体的要求,所以我相信“本”提供的解决方案可能无法为您工作。我很抱歉早些时候的混乱。同样为了获得响应,你可以试试'$ observer-> getResponse()'?我在我的Magento本地尝试了它,它为我工作,而不是使用'$ observer-> getEvent() - > getFront() - > getResponse()'。希望能帮助到你。 – 2013-05-16 06:29:55