Want to do something in every single controller? Use a Front Controller Plugin

On our latest site, we are splitting the actual website into 3 different applications. Although some will be screaming “use Zend’s module feature!”, there is a good reason why we want to do this. Mainly, it’s because, the actually front-end advertising website will be hosted on a different domain to the actual content-rich back-end.

Part of this logic means that for the site we are currently developing, every single controller used in the back-end needs to check if the user is authenticated, and if not, needs to forward the user to the login controller.  The easy way to do this is to use call the Auth model in each controllers _init function, and do the check there. What I wanted to achieve was a global site-wide check on each and every controller so that all the authentication checks are in one place.

Step forward the Front Controller plugin.

Firstly, you have to understand a little about how the dispatch process works in order to fully understand how and where to create your FC plugin. I found reading the Zend_Controller Basics page of the Zend Framework manual extremely helpful (see “More reading…” below).

The next question was where do I want the authentication to take place.  I decided that before the dispatch process was best, and so decided to bind my function at the pre-dispatch stage.  It saves the whole dispatch process from being run-through if the user is not authenticated.

So, to the code; firstly, I created the plugin that extends Zend_Controller_Plugin_Abstract.

application/plugins/AuthPlugin.php
/**
 * Application auth plugin
 *
 * @uses Zend_Controller_Plugin_Abstract
 */

class Central_Plugin_AuthPlugin extends Zend_Controller_Plugin_Abstract
{
	 public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
	 {
	 	// if not logged in, redirect to the login page
	 	// create an instance of Zend_Auth
	 	$auth = Zend_Auth::getInstance();
	 	// if not logged in
		if (!$auth->hasIdentity())
		{
			// set the new controller name to be the login controller
			$request->setControllerName('login')
			// set dispached to be false so the dispatch loop starts again
			->setDispatched(false);
		}
	 }
}

Next up, we need to load the plugin from the bootstrap:

// grab an instance of the front controller
$front = Zend_Controller_Front::getInstance();
// register a fc plugin
$front->registerPlugin(new Central_Plugin_AuthPlugin());
// go go go!
$front->dispatch();

It’s really as simple as that, I would like to investigate in the future loading the controller from the application.ini which I believe is possible. But for now, this works.

Edit:
Using the application.ini really is a much simpler way of loading your plugins… try this on for size:

resources.frontController.plugins[] = "Plugin_AuthPlugin"

More reading…

Your Comments are Awesome, Please Leave Them!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s