Sometimes the simple things can be challenging. Zend Framework has a "plugins" concept, where you can write code that will be executed at certain points in the process of rendering a page. Before rendering, after rendering, etc. This is a great thing as it allows the developer to do many things in a relatively easy manner without placing random blocks of code throughout the application. Logging all requests can be done from a plugin, making sure a user is logged in before viewing a page can be done from a plugin, etc. However, getting plugins to work properly can be a lesson in humility. Having just gone through the rough stuff myself, I am sharing the details below.
Absolute basics:
With the new Zend_Application approach to autoloading classes, you need to use the correct name for your plugin class and place it in the correct directory.
The Zend_Application_Module_Autoloader class (which is usually called from your bootstrap file) sets up some default "namespaces" and maps those namespaces to directories. For plugins, the namespace is "Plugin_", and this maps to the "../application/plugins" directory. If you have set up your project using the "zftool" command line script, you will not have a "plugins" directory - you'll have to create this manually. In addition, the zftool script cannot create a plugin file for you. Again, you'll have to do this manually.
Building your Plugin:
Building the plugin has been well discussed online, and the actual coding for a plugin has not seen any changes with newer versions of Zend Framework. Only the naming standard, has changed. You can check out these resources for learning to build your plugins:
- The Zend Framework Documentation - Plugins - the official source for details
- Front Controller Plugins in Zend Framework - a more thorough guide to understanding plugins aimed at a casual programmer.
Implementation:
So, armed with this information, if you want to ensure a user is logged into the application before showing them any pages, you might create an "Authentication" plugin. This plugin may look like this:
class Plugin_Authenticate extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$req = $this->getRequest();
$resp = $this->getResponse();
//ignore the login pages. (if we are requesting a page with the login controller, then we can just exit)
if (strtolower($req->getControllerName()) == "login")
{
return true;
}
// make sure the user is logged in. If not, redirect to the login page.
$session = Zend_Registry::get("session");
if (empty($session->userid))
{
//user is not logged in, redirect to the login page.
$resp->setRedirect('login');
}
}
The important thing to note here is the name of the class "Plugin_Authenticate". This class file would then be stored in the ".../application/plugins/Authenticate.php" file.
Next you need to make sure your autoloader is setup and that you register the plugin with the Front Controller. Both these tasks can be done in the bootstrap class (in the application/Bootstrap.php file):
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH));
return $moduleLoader;
}
function _initPlugins()
{
$front = Zend_Controller_Front::getInstance();
$front->registerPlugin(new Plugin_Authenticate());
}
}
As usual, any function named "_initXXXX" (where the X's is an arbitrary but unique name) will be automatically executed in the bootstrap process. So, the _initAutoload() function above builds a module autoloader. This autoloader defines a number of predefined "namespaces" - "Model_", "Plugin_", etc. Examine the library/Zend/Application/Module/Autoloader.php file for the full list. Without this step, the _initPlugins() function would throw an error saying the Plugin_Authenticate class could not be found.
The second function - _initPlugins() - gets an instance of the front controller, then registers our plugin with it. The hard part here is making sure the plugin class is automatically loaded for us without doing a require_once() on the class file. But the autoloader takes care of that for us.
Of course, your bootstrap class may have other functions defined or you may choose to move the plugin registration elsewhere. The important part is to first understand the process - so I kept this pretty basic for now.
And with that, our application now requires a "userid" property in our session before we can see any pages. The only exception here being the "Login" controller, which handles the login related actions. Tweak the plugin as needed.