tl;dr: 更正底部的观察者代码。
回答前的注意事项:确保观察者被触发;单步执行您的代码或使用die('here');。如所写,您的示例方法没有正确的原型来接收事件观察者数据(缺少参数)。
在这种情况下使用事件观察器进行重定向逻辑是完全合适的,正如核心团队将请求和响应对象显式传递给观察器所证明的那样。您的尝试很好,但我认为您的条件和配置导致执行流向Mage_Checkout_CartController::_goBack(),特别是流向该行
$this->_redirect('checkout/cart');
所以我们需要修改我们的方法。现在,您可以通过操纵响应并调用前端控制器的 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();
}
这应该可行,但我认为它会通过触发来自空灵系统组件 (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 参数并完成我们需要的操作。
public function moduleMethod(Varien_Event_Observer $observer)
{
$observer->getRequest()->setParam('return_url','http://www.google.com/');
}
我已经对此进行了测试,它应该可以解决问题!