Events API
本文档介绍 iTop 3.1 引入的 Events API,这是一种通过事件机制扩展 iTop 功能的全新方式。更多详细内容请参考 iTop 官方文档。
概述
Events 服务是 iTop 3.1 中的新功能,属于扩展性 API 的一部分。
该服务通过事件提供扩展性。主要行为是事件提供者注册他们要触发的事件,事件监听器注册当事件触发时要调用的回调函数。
示例
事件发布者
注册
提供者必须在 PHP 中触发事件之前,先在 XML 中注册事件。注册需要:
- event:大致上是一个唯一的名称
- event_data:与事件一起提供的参数
- sources:监听器可用的过滤条件,可选且特定于事件
事件 ID
事件 ID 应遵循常量命名规范(即全大写,仅使用下划线字符),并建议事件名称包含 ‘EVENT’。
- 当然,它在 iTop 和所有扩展中必须是唯一的
- 在以下示例中,我们将事件命名为
EVENT_DOWNLOAD_DOCUMENT - 将自动创建一个与名称相同的字符串常量
const EVENT_DOWNLOAD_DOCUMENT = 'EVENT_DOWNLOAD_DOCUMENT';
事件数据
事件数据由事件提供者在事件触发时提供给所有监听器。它是与事件一起提供的信息,以便监听器可以在有足够信息的情况下采取行动。
- 数据特定于提供者,由扁平的值列表组成
- 值可以是任何 PHP 值,如对象或数组,必须在声明中指定
- 事件数据及其类型在提供者事件注册中声明
- 它们特定于每个事件
在以下示例中,声明了 5 个 event_datum:
object:DBObjectdocument:ormDocumentatt_code和content_disposition:字符串debug_info:字符串,在 Combodo 创建的事件中始终存在
事件源
事件源是一种根据事件来源过滤事件的方式。
例如,对于数据模型对象上的事件,对象的类是监听器可以使用的源。实际上,所有父类都被添加到事件源中,因此监听器可以在类树的任何级别过滤事件。监听器可以指定监听 “Ticket” 事件。在继承自 Ticket 的对象上触发的所有事件都将发送给此监听器。
XML 结果
<events>
<event id="EVENT_DOWNLOAD_DOCUMENT" _delta="define">
<description>A document has been downloaded from the GUI</description>
<sources>
<source id="Document">Document</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object containing the document</description>
<type>DBObject</type>
</event_datum>
<event_datum id="document">
<description>The document downloaded</description>
<type>ormDocument</type>
</event_datum>
<event_datum id="att_code">
<description>Attribute code of the object, containing the document</description>
<type>string</type>
</event_datum>
<event_datum id="content_disposition">
<description>To differentiate if the document was displayed in preview or truly downloaded</description>
<type>string</type>
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</event_datum>
</event_data>
</event>
</events>
所有 iTop 事件
- 所有 iTop 核心事件声明可以在
<itop>/code/datamodel.application.xml中找到 - 当然,这不包括由 iTop 扩展带来的事件
事件触发
此部分用 PHP 编写。由事件提供者在适合触发事件时执行。必须提供:
- 与注册中声明的
id和type一致的事件数据 - 适用的事件源
public static function DownloadDocument(WebPage $oPage, $sClass, $id, $sAttCode, $sContentDisposition = 'attachment', $sSecretField = null, $sSecretValue = null)
{
// ...
$aEventData = array(
'debug_info' => $oDocument->GetFileName(),
'object' => $oObj,
'document' => $oDocument,
'att_code' => $sAttCode,
'content_disposition' => $sContentDisposition,
);
$aEventSources = [];
foreach (MetaModel::EnumParentClasses(get_class($this), ENUM_PARENT_CLASSES_ALL, false) as $sClass) {
$aEventSources[] = $sClass;
}
Combodo\iTop\Service\Events\EventService::FireEvent(
new Combodo\iTop\Service\Events\EventData(EVENT_DOWNLOAD_DOCUMENT, $aEventSources , $aEventData)
);
// ...
}
事件监听器
监听器将指定,如果特定事件在其指定的过滤器匹配的源上触发,则执行特定的 PHP 代码。
- event:事件的字符串名称
- callback:匹配过滤条件的事件发生时执行的代码
- filter:一组字符串。如果事件的
$aEventSources中有任何一个过滤字符串,则执行回调代码。对于许多触发器,这些字符串对应于类名。此参数可选。 - rank:如果您不是唯一响应该事件的扩展,可以指定一个 rank,以确保在另一个您知道其 rank 的扩展之前或之后执行
注册可以通过多种方式完成。
在类中的 XML 方式
您可以在 UserRequest 类中定义一个监听器,为此指定:
event_listener id:给它任何您喜欢的名称,在类中必须唯一event:在 XML 标签event下,如EVENT_DB_AFTER_WRITEcallback:在 XML 标签callback下,提供此类中方法的名称rank:在 XML 标签rank下filter:在集合filters/filter下,但在类中声明时是隐式的
<class id="UserRequest" _created_in="itop-request-mgmt" _delta="must_exist">
<event_listeners>
<event_listener id="OnUserRequestUpdateDone" _delta="define">
<event>EVENT_DB_AFTER_WRITE</event>
<callback>OnUserRequestUpdateDone</callback>
<rank>0</rank>
</event_listener>
</event_listeners>
注册 EVENT_DB_AFTER_WRITE 事件:
- 类似于重写
UserRequest::OnUpdate,但没有被另一个定制覆盖的风险,因为事件的所有监听器按顺序调用执行各自的工作 - 类似于实现
iObjectApplicationExtension OnDBUpdate(),但对于许多事件,等效的接口方法不存在,而且使用接口无法控制执行顺序
在 XML 中使用直接代码
此处 XML 声明在任何类之外,在 itop_design XML 树的根级别。
注意:
- 需要 XML
filter标签来声明适用的类 - 如果
event对filter中的类不适用,不会失败,不会显示警告,只是回调永远不会被调用 - 方法没有名称
- 您无法访问
$this,当前$oObject由事件提供($oEventData->Get('object'))
<event_listeners>
<event_listener id="OnAttachmentDownloadActivateTriggers" _delta="define">
<event>EVENT_DOWNLOAD_DOCUMENT</event>
<filters>
<filter>Attachment</filter>
</filters>
<rank>0</rank>
<code><![CDATA[
function(Combodo\iTop\Service\Events\EventData $oEventData)
{
if ($oEventData->Get('content_disposition') !== ormDocument::ENUM_CONTENT_DISPOSITION_ATTACHMENT) {
return;
}
$oObject = $oEventData->Get('object');
$sAttCode = $oEventData->Get('att_code');
$oDocument = $oEventData->Get('document');
...
}
]]></code>
</event_listener>
</event_listeners>
回调
如果您在 XML 中的类里注册了监听器,则在类上创建回调作为 PHP 方法。
public function OnUserRequestUpdateDone(Combodo\iTop\Service\Events\EventData $oEventData)
{
$sEvent = $oEventData->GetEvent();
$aChange = $oEventData->Get('changes');
// 执行您的处理
}
在回调代码中:
- 您可以通过
$oEventData->Get('xx')获取事件发布者注册的事件数据(其中 ‘xx’ 是 XML 标签中 ’event_datum’ 的 ‘id’) - 在某些事件中,对象上可以使用标准方法,如
DBObject::AddCheckIssue()、DBObject::ListChanges()等 - 当事件和回调方法在类本身上声明时,可以使用
$this代替$oEventData->Get('object')
示例:人员变更时
在标准 iTop 中,我们通过此事件机制防止门户用户在人员组织变更时失去访问权限。
PHP 中的监听器
如果您在 PHP 中进行注册和回调,最简单的方式是声明一个实现 iEventServiceSetup 的新类。在一个地方执行 RegisterEventsAndListeners() 中的注册,并指定回调代码。
监听器可以指定它们要监听的源。
class AttributeBlobEventListener implements iEventServiceSetup
{
public function RegisterEventsAndListeners()
{
EventService::RegisterListener(
EVENT_DOWNLOAD_DOCUMENT,
[$this, 'OnAttributeBlobDownloadActivateTrigger']
);
}
public function OnAttributeBlobDownloadActivateTrigger(Combodo\iTop\Service\Events\EventData $oEventData): void
{
// 回调代码
...
}
}
class EventListener implements iEventServiceSetup
{
public function RegisterEventsAndListeners()
{
EventService::RegisterListener(
EVENT_DOWNLOAD_DOCUMENT,
[$this, 'OnAttachmentDownloadActivateTriggers'],
'Attachment'
);
}
public function OnAttachmentDownloadActivateTriggers(Combodo\iTop\Service\Events\EventData $oEventData): void
{
if ($oEventData->Get('content_disposition') !== ormDocument::ENUM_CONTENT_DISPOSITION_ATTACHMENT) {
return;
}
$oObject = $oEventData->Get('object');
$sAttCode = $oEventData->Get('att_code');
$oDocument = $oEventData->Get('document');
...
}
}
现有事件
要获取更多关于 CRUD 事件 的详细信息:
- 它们的名称和用法
- 它们的数据
- 回调代码中可调用的 DBObject 方法
查找与数据模型类关联的事件
在数据模型页面中,可以查看为特定类注册的所有事件和监听器。
原文:https://www.itophub.io/wiki/page?id=3_2_0:customization:events_api
版本:3_2_0/customization/events_api.txt · Last modified: 2024/09/10 10:25 by 127.0.0.1