Here is another situation I have run into while trying to build a modular application: sometimes you need to run a frontcontroller plugin ONLY when a specific module is requested.

An example could be authentication. Say I have a public site and an admin section. The most obvious solution is to enable the authentication plugin only when the admin section is requested. This is something that is not possible with Zend_Application and the frontcontroller resource.

So, as I did for loading module specific layouts, I wrote a frontcontroller plugin for registering module specific frontcontroller plugins: the Rexus_Controller_Plugin_RequestedModulePluginLoader. It works together with a Zend_Application resource called Rexus_Application_Resource_Moduleplugins. Let’s get started.

Usage Example

First we load the frontcontroller plugin Rexus_Controller_Plugin_RequestedModulePluginLoader in the main application.ini:

resources.frontController.plugins.pluginloader = Rexus_Controller_Plugin_RequestedModulePluginLoader;

Then we use the Zend_Application resource Rexus_Application_Resource_Moduleplugins in our config file to load the the authentication plugin only for our module.
If you use my ModuleSetup resource as described in module config, you can set the module plugin options in the module.ini for that module :

resources.moduleplugins.auth = "Rexus_Controller_Plugin_Authentication"

or, you can set the module plugins config in your application.ini normally, as described in the Zend Framework reference:

modulename.resources.moduleplugins.auth = "Rexus_Controller_Plugin_Authentication"

The result is that the frontcontroller plugin Rexus_Controller_Plugin_Authentication is only loaded if the module ‘modulename’ is requested.

Code

class Rexus_Controller_Plugin_RequestedModulePluginLoader
    extends Zend_Controller_Plugin_Abstract
{
    protected $_modulePlugins = array();
    public function registerFrontControllerPlugin($module, $pluginName)
    {
        if (array_key_exists($module, $this->_modulePlugins)
                        && is_array($this->_modulePlugins[$module])) {
            array_push($this->_modulePlugins[$module], $pluginName);
        } else {
            $this->_modulePlugins[$module] = array($pluginName);
        }
    }
    public function routeShutdown(Zend_Controller_Request_Abstract $request)
    {
        if (isset($this->_modulePlugins[$request->getModuleName()])) {
            $frontController = Zend_Controller_Front::getInstance();
            foreach ($this->_modulePlugins[$request->getModuleName()] as $pluginName) {
                $frontController->registerPlugin( new $pluginName);
            }
        }
    }
}

Just drop this class in your library and register the plugin with the frontcontroller as shown above to use it.

Note that this plugin does its work on routeShutdown. On routShutDown is the earliest hook in the dispatch loop where the request has been parsed and routed. This is important because all plugins we register with this plugin can subsequently only be registered with the frontcontroller as early as the next step after the one on which this plugin is executed.

Next we need the code for the Zend_Application resource Rexus_Application_Resource_Moduleplugins:

class Rexus_Application_Resource_Moduleplugins
    extends Zend_Application_Resource_ResourceAbstract
{
    public function init()
    {
        $bootstrap = $this->getBootstrap();
        $bootstrap->bootstrap('frontcontroller');
        $front = $bootstrap->getResource('frontcontroller');
        $pluginLoader = $front->getPlugin('Rexus_Controller_Plugin_RequestedModulePluginLoader');
        $options = $this->getOptions();
        foreach ($options as $pluginName) {
            $pluginLoader->registerFrontControllerPlugin(
                strtolower($this->getBootstrap()->getModuleName()), $pluginName);
        }
    }
}