7

I am having trouble to create a working redirect in Magento from an observer.

As far as I know there are many events that got the response object with them (in the $observer object). Another way would be to use something like

Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));

as mentioned here https://stackoverflow.com/a/4730200/1700048 by the great Alan Storm.

Unfortunately this does not work for me, even when I add sendResponse() like this:

Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'))->sendResponse();

For example:

I want to prevent some email addresses to newsletter subscription. Therefore I created an observer for the newsletter_subscriber_save_before Event.

In my observer method I check some cases and if they trigger I want to prevent the saving of the newsletter subscribtion. My plan was to add an error like this:

Mage::getSingleton('checkout/session')->addError('Email is spam!');

and just let the current page reload (showing the error message) with a redirect as seen above (checkout/cart in the example is just to see it really works).

Unfortunately the redirect does not work. Why does sendResponse not send the response in this case?

Thanks for help :)

Community
  • 1
  • 1
Celldweller
  • 309
  • 1
  • 3
  • 12
  • The closest approach to a solutiuon seems to be like discussed here: http://www.magentocommerce.com/boards/viewthread/15792/#t325035 Mage::app()->getResponse()->setRedirect($url); Mage::app()->getResponse()->sendResponse(); exit; The exit() is essential for this to work. Unfortunately this leads to some errors inluding rollback errors in some cases. I am not sure if it is clean enough to be a base of a general solution. – Celldweller Nov 07 '12 at 12:00
  • For Magento 2 what we can do? – Jackson Mar 02 '17 at 02:53

4 Answers4

20

This works but it is not super elegant:

Mage::getSingleton('core/session')->addError('Email is spam!');
Mage::app()->getFrontController()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'));
Mage::app()->getResponse()->sendResponse();
exit;
David G
  • 94,763
  • 41
  • 167
  • 253
Silas Palmer
  • 201
  • 2
  • 3
9

I am going to short and correct Silas Palmer's code.

Mage::getSingleton('checkout/session')->addError('Email is spam!');
Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'))->sendResponse();
exit;

hope this helps someone!

Lalit Kaushik
  • 1,062
  • 2
  • 12
  • 30
0

That should work fine :s

Have you tried just exiting the script immediately after the setRedirect() call to see if it's definitely getting there?

Simon
  • 31,675
  • 9
  • 80
  • 92
HughieW
  • 139
  • 1
  • 4
  • 15
  • Yes. I am definitely there. When I log the response object with Mage::log() I can see that the redirect information are in there. Problem is the sendResponse method seems to do nothing so the newsletter SubscriberController (newAction) resets it at the end and does a $this->_redirectReferer() – Celldweller Nov 05 '12 at 17:15
  • Hmm then could you perhaps throw an exception instead of adding an error message? Suggested here: http://stackoverflow.com/questions/5425416/stopping-product-saving-process-in-observer – HughieW Nov 05 '12 at 17:22
  • Yes. Should be a smart way. I already tried it. Problem here is that the app\code\core\Mage\Newsletter\controllers\SubscriberController.php catches all exceptions. So I unfortunately can not throw my own prepared exception with prepareForward. Without the exception catching of the newsletter controller it would be a great way. I was hoping for a solution that always works. Regardless in whatever observer I am. I hoped the Mage::app:getResponse way would be that way – Celldweller Nov 05 '12 at 17:34
  • Oh snap :( I'm out of ideas then I'm afraid! Without digging around it myself, I've got nothing :( – HughieW Nov 06 '12 at 12:24
0

Instead of creating a Observer, have you think about override the save news letter controller with your own custom module and do you spam logic there and then add the the news letter code below your logics.

You could also change the url for save news letter to a new custom module url then do your spam filter and if you think it is a valid email then you do a internal forward to the regular save news letter (see how to call one action from another in magento?)

Therefore you wouldn't have any issues redirecting from a controller

Community
  • 1
  • 1
MagePal Extensions
  • 17,646
  • 2
  • 47
  • 62
  • Thanks for your advice. It would work the way you suggested but I hoped I could bypass the need to overwrite with the observer. It is not the first time I have the need to stop the normal workflow from within an observer and do a custom redirect. My hope was to get an universal solution that works in every observer, not only the observers that get the response object explicitly. And I still don't understand why code like Mage::app()->getResponse()->setRedirect(Mage::getUrl('checkout/cart'))->sendResponse(); doesn't work from within the observer. – Celldweller Nov 05 '12 at 20:28