CakePHP 3.x:如何在插件/插件 src 目录中实现事件侦听器未加载
CakePHP 3.x: how to implement event listener in plugin / plugins src-directory doesn't get loaded
为了用 CakePHP 构建一个可扩展的博客系统,我想在 Wordpress 中实现类似扩展挂钩的东西。我的计划是有一个基础 SQL 来加载主应用程序中的文章。这个 SQL 应该可以通过一组可变的插件进行扩展(每个特殊文章类型一个插件)。
我已经知道 CakePHP 实现类似功能的方法是事件系统。不过,我在注册驻留在我的插件中的侦听器时遇到了一些问题。
官方文档(3.x Book;http://book.cakephp.org/3.0/en/core-libraries/events.html#registering-listeners)说,监听器可以这样注册:
// Attach the UserStatistic object to the Order's event manager
$statistics = new UserStatistic();
$this->Orders->eventManager()->on($statistics);
不幸的是,它没有告诉将此代码放在哪里以便在引导时自动注册侦听器。将以下行放在我的插件的 bootstrap.php
中,如下所示:
$tester = new Lib\Tester();
$this->Orders->eventManager()->on($tester);
…(当然 plugins/MyPlugin/src/Lib
中有 class Tester
)会导致错误。
在第一行中找不到侦听器 class (“Error: Class 'Lib\Tester' not found”
)。并且在第二行中 $this
不得在 bootstrap.php
(“Error: Using $this when not in object context”
) 的上下文中使用。
在旧线程 (Where to register event listeners) 中,其他人提出了同样的问题并得到了非常详细的答案。不过,它适用于 CakePHP 2.x,并且不再适用于 CakePHP 3.x。例如,函数 App::uses
在 CakePHP 3.x 中不存在,我找不到替代品。
那么:谁能帮我找到在 CakePHP 的插件中设置工作侦听器的正确方法 3.x?
[更新 #1]
我找到了适合我的解决方法(但非常难看)。在插件的 bootstrap.php
中,我能够像这样实例化事件侦听器 class 的对象:
require __DIR__ . '/../src/Lib/Tester.php';
$tester = new MyPlugin\Lib\Tester();
之后我可以在 Articles 模型上注册监听器(当然也在 bootstrap.php
中):
Cake\ORM\TableRegistry::get('Articles')->eventManager()->on($tester);
通过这种方式,我现在可以在文章 table 上建立基本请求并将其发送到多个插件。然后插件可以丰富加入特殊 table 之类的请求。
因此,还有一个问题:如何避免在 bootstrap.php
中使用 __DIR__
?如何正确实例化监听器?
[更新 #2]
我的插件的完整 src
子目录似乎不在导入路径中。我放在那里的 class 中的 None 被加载了。这意味着当我将一个简单的控制器放在那里时,CakePHP 找不到一个简单的控制器。
总的来说我做错了什么吗?或者这可能是 CakePHP 中的错误?
不幸的是,我找不到 CakePHP 的插件 3.x,其源代码可以帮助我理解我可能做错了什么。
... 正如 ndm 在上面的评论中假设的那样,我在 composer.json
文件中手动插入的部分有问题。修复后 运行 dumpautoload
再次加载所有 类,现在。
为了用 CakePHP 构建一个可扩展的博客系统,我想在 Wordpress 中实现类似扩展挂钩的东西。我的计划是有一个基础 SQL 来加载主应用程序中的文章。这个 SQL 应该可以通过一组可变的插件进行扩展(每个特殊文章类型一个插件)。
我已经知道 CakePHP 实现类似功能的方法是事件系统。不过,我在注册驻留在我的插件中的侦听器时遇到了一些问题。
官方文档(3.x Book;http://book.cakephp.org/3.0/en/core-libraries/events.html#registering-listeners)说,监听器可以这样注册:
// Attach the UserStatistic object to the Order's event manager
$statistics = new UserStatistic();
$this->Orders->eventManager()->on($statistics);
不幸的是,它没有告诉将此代码放在哪里以便在引导时自动注册侦听器。将以下行放在我的插件的 bootstrap.php
中,如下所示:
$tester = new Lib\Tester();
$this->Orders->eventManager()->on($tester);
…(当然 plugins/MyPlugin/src/Lib
中有 class Tester
)会导致错误。
在第一行中找不到侦听器 class (“Error: Class 'Lib\Tester' not found”
)。并且在第二行中 $this
不得在 bootstrap.php
(“Error: Using $this when not in object context”
) 的上下文中使用。
在旧线程 (Where to register event listeners) 中,其他人提出了同样的问题并得到了非常详细的答案。不过,它适用于 CakePHP 2.x,并且不再适用于 CakePHP 3.x。例如,函数 App::uses
在 CakePHP 3.x 中不存在,我找不到替代品。
那么:谁能帮我找到在 CakePHP 的插件中设置工作侦听器的正确方法 3.x?
[更新 #1]
我找到了适合我的解决方法(但非常难看)。在插件的 bootstrap.php
中,我能够像这样实例化事件侦听器 class 的对象:
require __DIR__ . '/../src/Lib/Tester.php';
$tester = new MyPlugin\Lib\Tester();
之后我可以在 Articles 模型上注册监听器(当然也在 bootstrap.php
中):
Cake\ORM\TableRegistry::get('Articles')->eventManager()->on($tester);
通过这种方式,我现在可以在文章 table 上建立基本请求并将其发送到多个插件。然后插件可以丰富加入特殊 table 之类的请求。
因此,还有一个问题:如何避免在 bootstrap.php
中使用 __DIR__
?如何正确实例化监听器?
[更新 #2]
我的插件的完整 src
子目录似乎不在导入路径中。我放在那里的 class 中的 None 被加载了。这意味着当我将一个简单的控制器放在那里时,CakePHP 找不到一个简单的控制器。
总的来说我做错了什么吗?或者这可能是 CakePHP 中的错误?
不幸的是,我找不到 CakePHP 的插件 3.x,其源代码可以帮助我理解我可能做错了什么。
... 正如 ndm 在上面的评论中假设的那样,我在 composer.json
文件中手动插入的部分有问题。修复后 运行 dumpautoload
再次加载所有 类,现在。