Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento - Redirect Customer from Observer Method

In this event checkout_cart_add_product_complete, I want the customer to be redirected to an external web page http://www.example.com/. For this I am using this code, which is not working at all:-

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

I have used the "setRedirect()" method on both these variables "$response1" and "$response2", but both of them show me the Shopping Cart page, whereas I want to see this page http://www.example.com/ instead.

What I want:

  • I don't want to override the Controller Class, just to redirect the Customer, when I can effectively use the Event Observer process.
  • I don't want to use the PHP in-built function "header()", when Magento framework provides this functionality in an efficient way.
like image 837
Knowledge Craving Avatar asked Mar 17 '12 09:03

Knowledge Craving


People also ask

How do I redirect observer in Magento 2?

In above execute() function, When you need redirect to specific URL, You need to pass your custom URL instead of customer/account/login as the second parameter in redirect() function.

How do you call observer function in Magento 2?

Magento 2 Observers To create an observer in Magento 2, you must place your class file under the ModuleRoot/Observer directory. The observer class file should use Magento\Framework\Event\Observer and Magento\Framework\Event\ObserverInterface class and define the executive function.

What is the difference between plugin and observer in Magento 2?

Observers are less versatile than plugins. Plugins can alter the functionality of any Magento public method (except for virtual and final classes, final, static and non-public methods, constructors, and objects instantiated before bootstrapping Magento\Framework\Interception).


1 Answers

tl;dr: Correct observer code at the bottom.

A note before I answer: Make sure that the observer is being triggered; step through your code or use die('here');. As written, your example method does not have the correct prototype to receive event observer data (missing an argument).

Using an event observer for redirect logic is totally appropriate in this context, as evinced by the core team explicitly passing the request and response objects in to the observer. Your attempt is good, but I think that you have conditions and configuration which cause execution to flow to Mage_Checkout_CartController::_goBack(), specifically to the line

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

So we need to revise our approach. Now, you could prevent any request/response logic from processing after your event observer by manipulating the response and calling the Front Controller's sendResponse() method as demonstrated below (nb: don't do this!):

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

This should work, but I think it mixes up areas of concern by triggering output from an ethereal system component (EDA). Let's see if there's something in the command-control structure which we can use...

Just after the checkout_cart_add_product_complete event execution comes to the cart controller's _goBack() method. The problem with this method name is that it does more than its name implies:

/**
 * 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);
    }
    //...
}

It looks like we can just set a return_url param on the request object and accomplish what we need.

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

I've tested this, and it should do the trick!

like image 104
benmarks Avatar answered Oct 06 '22 00:10

benmarks