2012-03-17 23 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