0

我在管理模块目录中的plugins目录中有这个插件。所以,它在: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';
   }
}

我想用它来将变量发送到布局视图。碰巧我Fatal error: Class 'LayoutPlugin' not found每次尝试管理员引导程序Zend_Controller_Front::getInstance()->registerPlugin(new LayoutPlugin());时都会得到。

如何在模块中加载插件?

4

2 回答 2

1

模块引导程序默认设置模块自动加载器,因此如果您将类重命名为 Admin_Plugin_LayoutPlugin ZF 应该能够找到它。

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

于 2010-09-08T19:32:54.590 回答
1

我知道这是一个老问题,但这总是困扰着我。我不知道 ZF 2 是否已经解决了这个问题(我还没有机会玩它),但我为 ZF 1 编写了一个插件加载器插件来处理这个问题!

当然,问题是即使设置了模块自动加载器并将插件保存在模块的插件文件夹中,这也只会设置自动加载(无论如何都是跨模块)而不是注册。这意味着您可以在 application.ini 中使用一行来实例化插件,但它将为每个模块自动加载和注册。

无论如何,这里有一个可能的解决方案来确保模块插件只为活动模块注册。或者,您可以遍历模块插件目录中的所有文件,而不是提供类映射,但这感觉很难看……而且可能很慢。

<?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());
            }
        }
    }
}

因为我们需要传递一个 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',
            ...
        )
    )));
}

插件可以运行的最早时间是在,routeShutdown否则我们将不知道活动模块。这意味着任何其他使用此方法注册的插件只能从dispatchLoopStartup以后运行。大多数情况下,我们可能对钩子感兴趣,preDispatchpostDispatch值得牢记。

于 2012-11-16T12:47:43.493 回答