简体   繁体   中英

How to load plugins with modules

I have this plugin in the plugins directory within the admin module directory. So, it is in application/modules/admin/plugins/LayoutPlugin.php :

<?php
class LayoutPlugin extends Zend_Controller_Plugin_Abstract
{
   public function preDispatch(Zend_Controller_Request_Abstract $request)
   {
      $layout = Zend_Layout::getMvcInstance();
      $view = $layout->getView();

      $view->whatever = 'foo';
   }
}

I'd like to use it for sending variables to the layout view. It happens that I get Fatal error: Class 'LayoutPlugin' not found every time I try Zend_Controller_Front::getInstance()->registerPlugin(new LayoutPlugin()); in the admin bootstrap.

How do I load a plugin inside a module?

I know this is an old question but this is always something that bugged me. I don't know if ZF 2 has done anything to solve it (I've not had the chance to play with it yet), but I wrote a plugin loader plugin to deal with this for ZF 1!

The problem is, of course, that even when setting up a module autoloader and keeping your plugins in a module's plugin folder, this only setups up autoloading (which is cross module anyway) not registration. It means you can instantiate the plugin with a line in your application.ini, but it will be autoloaded and registered for every module.

Anyway, here's a possible solution to make sure module plugins are only registered for the active module. Alternatively, instead of providing a class map, you could loop through all the files in a module's plugins directory, but that feels ugly... and probably slow.

<?php

class BaseTen_Controller_Plugin_ModulePluginLoader extends Zend_Controller_Plugin_Abstract {

    private $_pluginMap;

    public function __construct(array $pluginMap) {
        $this->_pluginMap = $pluginMap;
    }

    public function routeShutdown(Zend_Controller_Request_Abstract $request) {
        $module = $request->getModuleName();

        if(isset($this->_pluginMap[$module])) {

            $front = Zend_Controller_Front::getInstance();

            foreach($this->_pluginMap[$module] as $plugin) {
                $front->registerPlugin(new $plugin());
            }
        }
    }
}

Because we need to pass a classMap to the constructor, we need to explicity instantiate and register this plugin with the Front Controller rather than with a line in application.ini:

public function _initPluginLoader() {
    $front = Zend_Controller_Front::getInstance();
    $front->registerPlugin(new BaseTen_Controller_Plugin_ModulePluginLoader(array(
        'default' => array(
            'Plugin_Foo',
            'Plugin_Bar',
            ...
        ),
        'foo' => array(
            'Foo_Plugin_Foo',
            'Foo_Plugin_Bar',
            ...
        )
    )));
}

The earliest the plugin can run is at routeShutdown otherwise we won't know the active module. What this means though is that any other plugins registered using this method can only run from dispatchLoopStartup onwards. Mostly, we're probably interested in preDispatch and postDispatch hooks but worth bearing in mind.

Module bootstraps setup the module autoloader by default, so if you rename your class to Admin_Plugin_LayoutPlugin ZF should be able to find it.

Keep in mind that the admin bootstrap (like all bootstraps) will be run regardless of whether you're in the admin module or not, so if your intention is to assign some extra variables just for your admin pages you'll need to ensure that admin is the current module before registering the plugin.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM