简体   繁体   English

如何使用模块加载插件

[英]How to load plugins with modules

I have this plugin in the plugins directory within the admin module directory. 我在管理模块目录下的plugins目录中有此插件。 So, it is in application/modules/admin/plugins/LayoutPlugin.php : 因此,它位于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()); 发生Fatal error: Class 'LayoutPlugin' not found每次尝试Zend_Controller_Front::getInstance()->registerPlugin(new LayoutPlugin()); Fatal error: Class 'LayoutPlugin' not found 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! 我不知道ZF 2是否已做任何事情来解决它(我还没有机会玩这个游戏),但是我写了一个插件加载器插件来处理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. 这意味着您可以在application.ini中用一行实例化该插件,但是它将自动加载并为每个模块注册。

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. 另外,除了提供类映射之外,您还可以遍历模块的plugins目录中的所有文件,但这听起来很丑,而且可能很慢。

<?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: 因为我们需要将classMap传递给构造函数,所以我们需要显式实例化此插件并将其注册到Front Controller中,而不是使用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. 插件最早可以运行在routeShutdown否则我们将不知道活动模块。 What this means though is that any other plugins registered using this method can only run from dispatchLoopStartup onwards. 但是,这意味着使用此方法注册的任何其他插件只能从dispatchLoopStartup开始运行。 Mostly, we're probably interested in preDispatch and postDispatch hooks but worth bearing in mind. 通常,我们可能对preDispatchpostDispatch挂钩感兴趣,但要记住。

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. 默认情况下,模块引导程序会设置模块自动加载器,因此,如果您将类重命名为Admin_Plugin_LayoutPlugin,则ZF应该能够找到它。

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. 请记住,无论您是否在admin模块中,都将运行admin引导程序(就像所有引导程序一样),因此,如果您打算为管理页面分配一些额外的变量,则需要确保admin是注册插件之前的当前模块。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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