3

I am trying to redirect to custom url if certain url is matched using event: controller_action_predispatch

a> Registering event: controller_action_predispatch

<frontend>
    <events>
        <controller_action_predispatch>
            <observers>
                <redirect_controller_action_predispatch>
                    <class>redirect/observer</class>
                    <method>controllerActionPredispatch</method>
                </redirect_controller_action_predispatch>
            </observers>
        </controller_action_predispatch>
    </events>
</frontend>

b> Implementing the observer model

<?php
class MagePsycho_Redirect_Model_Observer
{
    public function controllerActionPredispatch(Varien_Event_Observer $observer)
    {
        $action         = $observer->getControllerAction();
        $request        = $action->getRequest();
        $requestUrl     = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $request->getRequestUri();

        if (stripos($requestUrl, '/' . 'old-404-url-key') !== false) {
            $redirectUrl = Mage::getUrl('new-url-key');
            Mage::log('redirect-matched::' . $redirectUrl);
            $action->getResponse()->setRedirect($redirectUrl, 301);
            $action->getRequest()->setDispatched(true);
            return;
        }
    }
}

Above code works fine in localhost but not on live server where Full Page Cache + APC caching is turned on (Magento EE 1.13).

What am I missing, anything needs to be checked in case of Full Page Cache + APC turned on?

Any help is appreciated.

[EDIT]
The redirection issue is only for 404 error. If i try to redirect some non existing page (i.e. 404 page) to some valid page, the redirection doesn't work.

2
  • 1
    With Varnish this observer will never get fired one page is cached. Also curious how did you combined FPC and Varnish. – user487772 Jun 8 '14 at 21:32
  • @Tim it's APC, i edited my title :). Yeah it seems 404 error (cms_index_noRoute) is cached and there is no redirection thereafter even the code is called. How to fix, any idea? like bypass caching for cms_index_noRoute, something like that? – MagePsycho Jun 9 '14 at 9:31
2

As per our discussion in the IRC, use webserver redirects.

Your goal is to redirect old urls to new urls. This is the job of the webserver, not the application. Otherwise you are loading the application twice for each of these requests.

2
0

Sometimes a simple PHP solution works too, don't always think in #Magento way ;)

Replaced this piece of code:

$action->getResponse()->setRedirect($redirectUrl, 301);
$action->getRequest()->setDispatched(true);

by:

@header("HTTP/1.1 301 Moved Permanently");
@header("Location: " . $redirectUrl);
exit();

But still if someone knows how to make it work in a Magento way, I would re-consider the accepted answer.

3
  • whenever you Redirect from observer, you need to put an exit(); OR $observer->getRequest()->setParam('return_url','http://www.google.com/'); – Slimshadddyyy Jun 12 '14 at 10:13
  • I had used return statement though. – MagePsycho Jun 12 '14 at 11:55
  • But is @header("Location: " . $redirectUrl); exit(); recommended ? – Slimshadddyyy Jun 12 '14 at 12:40
0

i have find another solution which is working and it forward url to anthor page.

  1. First current get request url object. $request=Mage::app()->getRequest();

  2. Now not dispatch current urt using set ->setDispatched() function value to false.

code

$request->setDispatched(false);
  1. add a new parameter forwarded=true to request parameter using

    ->setParam('forwarded', true) Which forward to new url

code is:

$request->setParam('forwarded', true)

4. now set new forwarded url using set routename ,controller and action and code is like

$request
->setRouteName($routername)
->setControllerName($controllername)
->setActionName($actionname)

Example: i write all contacts page to index page:

    $request=Mage::app()->getRequest();
$request->setParam('forwarded', true)
                        ->setRouteName('cms')
                        ->setControllerName('index')
                        ->setActionName('index')
                         ->setDispatched(false);

Edit: for ajax request try this

  if ($request->getParam('isIframe')) {
                    $request->setParam('forwarded', true)
            ->setRouteName($routername)
                        ->setControllerName($controllername)
                        ->setActionName($actionname)
                        ->setDispatched(false);
                } elseif($request->getParam('isAjax')) {
                    $request->setParam('forwarded', true)
                        ->setControllerName($controllername)
            ->setRouteName($routername)
                        ->setActionName($actionname)
                        ->setDispatched(false);
                } else {
                    $request->setParam('forwarded', true)
                        ->setRouteName($routername)
                        ->setControllerName($controllername)
                        ->setActionName('login')
                        ->setDispatched(false);
                }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.