Question

I'm trying to make a maintenance redirect page for a website, so that a "Maintenance / Update Mode" can be activated, which will result in redirecting every page request to a "Down for Maintenance Page". I've set the switch to a global variable written using Configure::write() and checking with Configure::read().

The problem I'm having is -- when it IS in offline mode, how do I redirect every page request? My first thought was a conditional $this->redirect(...) in AppController's beforeFilter() function. But this resulted in a "Redirect Loop" error:

enter image description here

My second thought was that perhaps (I'm new to CakePHP) this was getting called so often, being the base class Controller's first filter, that this idea was stupid. I thought I could fix this by creating a "MaintenanceFilter" that checked the same variable for online or offline status for redirecting. However, the CookBook mentions filters being new to Cake 2.2, and this website uses 2.1. The filter also appears not to work, even when I give it priority 1. (defined in app/Routing/Filter).

App::uses('DispatcherFilter', 'Routing');

class MaintenanceFilter extends DispatcherFilter
{
    public function beforeDispatch(CakeEvent $event)
    {
        if (strcmp(Configure::read('ServerStatus'), 'online') == 0)
        {
            $event->stopPropagation();

            $dispatcher = new Dispatcher();

            $dispatcher->dispatch(array('controller' => 'errors', 
                            'action' => 'maintenance'));
        }
    }
}

I then thought that perhaps I could just do this more generally, and set a Routing condition with Router::connect('*', ...) that would redirect ALL pages to /Errors/maintenance, where the conditional server status check is:

Router::connect('*', array('controller' => 'Errors', 
                        'action' => 'maintenance')); 

I placed this at the top of the routing file so it would get processed first. As you might have guessed, no pages ever redirected to the maintenance page.

I was thinking I could just make a custom exception handler and throw an exception when the server is in "offline mode", but then how would I redirect to a maintenance page from within a handler's method body?

I must be missing either something specific about Cake 2.1, or just Cake/MVC in general. Anyone see what it might be?

Was it helpful?

Solution

Your first solution, which gave you the redirect error, should be OK - most likely, you haven't done a check to see if you're already on the Maintenance page, so that means that when you get redirected to the maintenance page, like every other page, it just automatically redirects you to the maintenance page again - hence the loop.

This is untested code, but it should work, or at least set you on the right track:

function beforeFilter() {

    // Check if we are in offline mode
    if(!empty(Configure::read('offline_mode'))){

        // Check if we are already on the maintenance page
        $firstParam = ($this->request->params['pass'][0]))? $this->request->params['pass'][0]: '';
        if (isset($this->request->controller == 'pages' and $firstParam == 'maintenance')) {
            // Don't do anything - we don't want to redirect again.
        } else {
            // Redirect to the maintenance page
            $this->redirect(array('controller' => 'pages', 'action' => 'display', 'maintenance'));
        }
    }
}

OTHER TIPS

You could use the following filter to enable maintenance mode in your app

cakephp-maintenance-mode

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top