3.phpBB Extension Events and Listeners

行业资讯 admin 发布时间:2024-03-19 浏览:55 次

介绍

phpBB 3.1引入了整个代码库和模板文件中的事件系统,允许扩展使用侦听器来添加功能,注入代码和写改现有的功能和行为。

本教程将介绍如何使用事件和侦听器:

Template Events & ListenersPHP Core Events & Listeners

Template Events & Listeners

模板事件允许扩展将代码注入到模板文件中。 事件可以在phpBB样式的整个模板结构中找到,提供多个有用的注入点。 典型的模板事件如下所示:

<!-- EVENT event_name_and_position -->

也可以看看

在我们的维基中查看模板事件的完整列表。https://wiki.phpbb.com/Event_List#Template_Events

Listening for an event

要订阅模板事件,我们必须创建一个监听器,一个与我们想要使用的模板事件的标识符完全相同的模板文件,并将其放在样式模板文件夹的事件/子目录中。

例如,我们将使用overall_header_navigation_prepend事件在板的导航栏中的现有链接之前添加一个新链接。 此活动的听众将是:

acme/demo/styles/prosilver/template/event/overall_header_navigation_prepend.html

小提示

如果您希望所有样式使用模板侦听器,则应将其放在all / style目录中,例如供应商/ extname/风格/所有/模板/事件/。 这有助于防止代码重复并简化样式文件管理。

对于必须根据每种风格定制的模板文件,应该使用prosilver和subsilver2目录。 同样,如果第三方风格需要额外的自定义来维护兼容性,那么该样式的文件夹应该包含在这些模板文件中。

要添加ACP模板侦听器,请将这些文件放在vendor/extname/adm/style/event /中。

在模板侦听器中,我们将创建一个导航栏链接。 这包括一个简单的列表元素,具有链接和描述:

{L_DEMO_PAGE}

</li>

一旦创建了模板侦听器,您应该能够看到该板的导航栏中的新链接,其中包含FAQ链接的图标和文本DEMO_PAGE。 我们将在下一节中修正链接文本。

小提示

如果链接没有出现,您可能需要从ACP的主页上清除板缓存。 您还可以在config.php文件中启用DEBUG_MODE,这将强制模板引擎始终在呈现页面时查找模板侦听器。

重要的是要明白,当phpBB编译模板时,目前还没有确定优先级的系统,其中来自不同扩展名的模板侦听器被编译为同一个事件。 在极少数情况下,一些扩展可能会导致冲突,在这种情况下,建议是扩展作者为了冲突的模板侦听器而合作解决方案。

PHP Core Events & Listeners

事件允许扩展在核心phpBB代码中的许多位置执行代码,而不修改任何代码。 这样扩展可以轻松添加功能,删除功能或修改行为,同时保持兼容性和简单的更新过程。

也可以看看

在我们的Wiki中查看支持的PHP事件的完整列表。https://wiki.phpbb.com/Event_List

The event listener

在上一节中,我们创建了一个模板侦听器,它将Acme Demo扩展的链接添加到phpBB的导航栏。我们现在将使用PHP事件加载包含DEMO_PAGE语言密钥的语言文件,以便我们的导航栏链接将显示正确的文本。

为此,我们需要创建一个PHP事件侦听器类(a.k.a. subscriber class)。该类包括一组侦听器方法,每个方法都可以在phpBB的代码库中订阅PHP事件。侦听器类必须在扩展目录的事件/子目录中创建,否则它将无法正常工作。它还必须符合以下要求:

遵循扩展类名称 - 间距约定:vendor \ extname \ event \ subscribername.php。

实现Symfony的Symfony \ Component \ EventDispatcher \ EventSubscriberInterface接口。

使用静态方法getSubscribedEvents()将侦听器中的方法预订为特定事件,其中的键包含事件名称,其值包含侦听器函数名称。

在Acme Demo扩展中,我们要加载我们的语言文件到处。因此,我们将订阅一个监听器函数到phpBB的core.user_setup事件:

<?php namespace acme\demo\event; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class main_listener implements EventSubscriberInterface { /** * Assign functions defined in this class to event listeners in the core * * @return array */ static public function getSubscribedEvents() { return array( core.user_setup => load_language_on_setup, ); } /** * Load the Acme Demo language file * acme/demo/language/en/demo.php * * @param \phpbb\event\data $event The event object */ public function load_language_on_setup($event) { $lang_set_ext = $event[lang_set_ext]; $lang_set_ext[] = array( ext_name => acme/demo, lang_set => demo, ); $event[lang_set_ext] = $lang_set_ext; } }

那么上面的main_listener.php类是什么呢?

getSubscribedEvents()方法将我们的侦听器函数load_language_on_setup()订阅到名为core.user_setup的事件。 这意味着当这个事件发生时,我们的函数将执行。

小提示

您可以使用数组为单个事件分配多个侦听器函数:

core.user_setup=> array(array(foo_method),array(bar_method))

load_language_on_setup()监听器方法只是将语言文件添加到phpBB的语言数据数组中。 一般来说,一个监听器只是一个在用户类中的public函数,在getSubscribedEvents()返回的数组中引用。 它需要一个参数$ event。 此参数允许您从核心代码访问和修改给予事件的变量。 在这种情况下,我们通过添加Acme Demo的语言文件来修改lang_set_ext变量。

注意

请注意,lang_set_ext事件变量首先如何通过将其分配给局部变量进行复制,然后进行修改,然后将其复制。 此快捷方式不起作用:$ event [foo] [bar] = $ baz; 这是因为事件变量是重载的,这是PHP中的限制。

Registering the listener

要使phpBB自动加载并执行我们的事件侦听器类,我们需要为它创建一个服务定义。 这是通过在扩展中创建一个config / services.yml文件完成的:

services:acme.demo.listener:class:acme\demo\event\main_listenertags:- {name:event.listener }

警告

YAML文件缩进敏感。 它们需要每个缩进的缩进大小为4个空格,不要使用制表符。

第一行告诉phpBB正在注册服务列表。 在下一行,我们指定服务的名称,这是在这种情况下为我们的事件侦听器。

重要

服务名称必须以您的供应商和分机名称为前缀。

类属性必须包含正在注册的服务的名称空间和类名。 名称空间取决于文件的位置,在ext /目录中。 因此,文件ext / acme / demo / event / main_listener.php具有命名空间acme \ demo \ event和类名main_listener。 因此,该类的全名是acme \ demo \ event \ main_listener,这是我们需要在此处指定的。

tags属性告诉phpBB该服务是一个事件监听器。

一旦服务YAML文件被创建(或修改),phpBB的缓存需要被清除。 在ACP中清除缓存后,导航栏中链接的描述现在应显示Demo而不是DEMO_PAGE。

注意

phpBB的核心PHP和模板文件已经准备好了几十个事件位置。 但是,如果没有您的扩展可能需要的事件,phpBB开发团队欢迎在区域http://51.com事件请求论坛上的事件请求。

Prioritising event listeners (optional)

有时不同的扩展可能在竞争使用相同的PHP核心事件时遇到问题。 在尝试解决这些问题时,扩展开发人员可能希望将其扩展优先于其他人,以便在其他扩展之前触发扩展。

在这种情况下,getSubscribedEvents()方法提供了一个参数来设置事件侦听器方法的优先级。 例如:

static public function getSubscribedEvents() { return array( core.user_setup => array(foo_method, $priority) ); }

在此示例中,$ priority是一个整数,其值默认为0.将此整数设置为更高的值等于更重第一行告诉phpBB正在注册服务列表。 在下一行,我们指定服务的名称,这是在这种情况下为我们的事件侦听器。

重要

服务名称必须以您的供应商和分机名称为前缀。

类属性必须包含正在注册的服务的名称空间和类名。 名称空间取决于文件的位置,在ext /目录中。 因此,文件ext / acme / demo / event / main_listener.php具有命名空间acme \ demo \ event和类名main_listener。 因此,该类的全名是acme \ demo \ event \ main_listener,这是我们需要在此处指定的。

tags属性告诉phpBB该服务是一个事件监听器。

一旦服务YAML文件被创建(或修改),phpBB的缓存需要被清除。 在ACP中清除缓存后,导航栏中链接的描述现在应显示Demo而不是DEMO_PAGE。

注意

phpB要,因此该侦听器将比其他订阅此事件的触发器早。

我们现在已经使用事件和监听器来修改phpBB,并在导航栏中插入一个很好的链接。 但是,该链接仍然没有工作。 继续阅读下一节,了解如何使用控制器和路由,使我们的导航栏链接打开自定义的面向用户的页面。

在线咨询

点击这里给我发消息售前咨询专员

点击这里给我发消息售后服务专员

在线咨询

免费通话

24h咨询:400-888-8888


如您有问题,可以咨询我们的24H咨询电话!

免费通话

微信扫一扫

微信联系
返回顶部