Display events in the datamodel page

This commit is contained in:
Eric Espie
2022-06-01 08:44:12 +02:00
parent 1ceef602f0
commit f6855b0d2b
8 changed files with 338 additions and 198 deletions

View File

@@ -188,300 +188,347 @@
<events>
<event id="EVENT_SERVICE_DB_INSERT_REQUESTED" _delta="define">
<description>An object insert in the database has been requested. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnInsert</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_INSERT" _delta="define">
<description>An object is about to be inserted in the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnInsert</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_INSERT_DONE" _delta="define">
<description>An object has been inserted into the database (but not reloaded). All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterInsert</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object inserted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UPDATE_REQUESTED" _delta="define">
<description>An object update has been requested. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnUpdate, DBObject::DoComputeValues</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_UPDATE" _delta="define">
<description>An object is about to be updated in the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnUpdate</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_UPDATE_DONE" _delta="define">
<description>An object has been updated into the database and reloaded. All changes to the object will be persisted automatically.</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterUpdate</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object updated</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_ABOUT_TO_DELETE" _delta="define">
<description>An object is about to be deleted in the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::OnDelete</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object deleted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_DELETE_DONE" _delta="define">
<description>An object has been deleted into the database</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>DBObject::AfterDelete</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object deleted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_BEFORE_APPLY_STIMULUS" _delta="define">
<description>A stimulus is about to be applied to an object</description>
<arguments>
<argument id="object">
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_AFTER_APPLY_STIMULUS" _delta="define">
<description>A stimulus has been applied to an object</description>
<arguments>
<argument id="object">
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
</event_datum>
<event_datum id="save_object">
<description>The object is asked to be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_APPLY_STIMULUS_FAILED" _delta="define">
<description>A stimulus has failed</description>
<arguments>
<argument id="action">
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="action">
<description>The action that failed to apply the stimulus</description>
<type>string</type>
</argument>
<argument id="object">
</event_datum>
<event_datum id="object">
<description>The object where the stimulus is targeted</description>
<type>DBObject</type>
</argument>
<argument id="stimulus">
</event_datum>
<event_datum id="stimulus">
<description>Current stimulus applied</description>
<type>string</type>
</argument>
<argument id="previous_state">
</event_datum>
<event_datum id="previous_state">
<description>Object previous state</description>
<type>string</type>
</argument>
<argument id="new_state">
</event_datum>
<event_datum id="new_state">
<description>Object new state</description>
<type>string</type>
</argument>
<argument id="save_object">
</event_datum>
<event_datum id="save_object">
<description>The object must be saved in the database</description>
<type>boolean</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_OBJECT_RELOAD" _delta="define">
<description>An object has been re-loaded from the database</description>
<arguments>
<argument id="object">
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object re-loaded</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_CHECK_TO_WRITE" _delta="define">
<description>Check an object before it is written into the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToWrite</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</argument>
<argument id="error_messages">
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DB_CHECK_TO_DELETE" _delta="define">
<description>Check an object before it is deleted from the database (no change possible)</description>
<sources>
<source id="cmdbAbstractObject">cmdbAbstractObject</source>
</sources>
<replaces>cmdbAbstractObject::DoCheckToDelete</replaces>
<arguments>
<argument id="object">
<event_data>
<event_datum id="object">
<description>The object to check</description>
<type>DBObject</type>
</argument>
<argument id="error_messages">
</event_datum>
<event_datum id="error_messages">
<description>Array of strings where all the errors found during the object checking are added</description>
<type>array</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_DOWNLOAD_DOCUMENT" _delta="define">
<description>A document has been downloaded from the GUI</description>
<arguments>
<argument id="object">
<sources>
<source id="ormDocument">ormDocument</source>
</sources>
<event_data>
<event_datum id="object">
<description>The object containing the document</description>
<type>DBObject</type>
</argument>
<argument id="document">
</event_datum>
<event_datum id="document">
<description>The document downloaded</description>
<type>ormDocument</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_AFTER_DISPLAY_PAGE" _delta="define">
<description>The current page is completely displayed</description>
<available_filters>Class hierarchy of the displayed page</available_filters>
<arguments>
<argument id="object">
<sources>
<source id="CLIPage">CLIPage</source>
<source id="WebPage">WebPage</source>
</sources>
<event_data>
<event_datum id="object">
<description>The page displayed</description>
<type>Page</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_LOGIN" _delta="define">
<description>Inform the listeners about the connection states</description>
<available_filters/>
<arguments>
<argument id="code">
<event_data>
<event_datum id="code">
<description>The login step result code (LoginWebPage::EXIT_CODE_...) </description>
<type>integer</type>
</argument>
<argument id="state">
</event_datum>
<event_datum id="state">
<description>Current login state (LoginWebPage::LOGIN_STATE_CONNECTED...)</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
</events>
<meta>

View File

@@ -26,8 +26,8 @@
namespace Combodo\iTop;
use \DOMDocument;
use \DOMFormatException;
use DOMDocument;
use DOMFormatException;
/**
* Class \Combodo\iTop\DesignDocument
@@ -175,6 +175,26 @@ class DesignElement extends \DOMElement
return $this->ownerDocument->GetNodes($sXPath, $this);
}
public static function ToArray(DesignElement $oNode)
{
$aRes = [];
if ($oNode->GetNodes('./*')->length == 0) {
return $oNode->GetText('');
}
foreach ($oNode->GetNodes('./*') as $oSubNode) {
/** @var \Combodo\iTop\DesignElement $oSubNode */
$aSubArray = DesignElement::ToArray($oSubNode);
if ($oSubNode->hasAttribute('id')) {
$aRes[$oSubNode->getAttribute('id')] = $aSubArray;
} else {
$aRes[$oSubNode->tagName] = $aSubArray;
}
}
return $aRes;
}
/**
* Create an HTML representation of the DOM, for debugging purposes
*

View File

@@ -291,34 +291,40 @@
<event id="EVENT_SERVICE_ATTACHMENT_AFTER_UPDATE" _delta="define">
<description>An attachment has been updated in database.</description>
<replaces>Attachment::AfterUpdate</replaces>
<arguments>
<argument id="object">
<sources>
<source id="Attachment">Attachment</source>
</sources>
<event_data>
<event_datum id="object">
<description>The attachment updated</description>
<type>DBObject</type>
</argument>
<argument id="changes">
</event_datum>
<event_datum id="changes">
<description>Array of all the attributes changed</description>
<type>array</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
<event id="EVENT_SERVICE_ATTACHMENT_AFTER_DELETE" _delta="define">
<description>An attachment has been deleted from database.</description>
<replaces>Attachment::AfterDelete</replaces>
<arguments>
<argument id="object">
<sources>
<source id="Attachment">Attachment</source>
</sources>
<event_data>
<event_datum id="object">
<description>The attachment deleted</description>
<type>DBObject</type>
</argument>
<argument id="debug_info">
</event_datum>
<event_datum id="debug_info">
<description>Debug string</description>
<type>string</type>
</argument>
</arguments>
</event_datum>
</event_data>
</event>
</events>
</itop_design>

View File

@@ -804,6 +804,11 @@ We hope youll enjoy this version as much as we enjoyed imagining and creating
'UI:Schema:DisplaySelector/Code' => 'Code~~',
'UI:Schema:Attribute/Filter' => 'Filter~~',
'UI:Schema:DefaultNullValue' => 'Default null : "%1$s"~~',
'UI:Schema:Events' => 'Events',
'UI:Schema:Events:Defined' => 'Defined events',
'UI:Schema:Events:NoEvent' => 'No event defined',
'UI:Schema:Events:Listeners' => 'Event listeners',
'UI:Schema:Events:NoListener' => 'No event listener',
'UI:LinksWidget:Autocomplete+' => 'Type the first 3 characters...',
'UI:Edit:SearchQuery' => 'Select a predefined query',
'UI:Edit:TestQuery' => 'Test query',

View File

@@ -12,6 +12,7 @@ use Combodo\iTop\Application\UI\Base\Component\Input\Select\SelectOptionUIBlockF
use Combodo\iTop\Application\UI\Base\Component\Panel\PanelUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Component\Title\TitleUIBlockFactory;
use Combodo\iTop\Application\UI\Base\Layout\PageContent\PageContentWithSideContent;
use Combodo\iTop\Service\EventService;
require_once('../approot.inc.php');
require_once(APPROOT.'/application/application.inc.php');
@@ -264,7 +265,58 @@ function DisplayTriggers($oPage, $sClass)
cmdbAbstractObject::DisplaySet($oPage, $oSet, array('block_id' => 'triggers'));
}
function DisplayEvents(WebPage $oPage, $sClass)
{
$aEvents = EventService::GetEventsByClass($sClass);
$aColumns = [
'event' => ['label' => 'Event'],
'description' => ['label' => 'Description'],
];
$aRows = [];
foreach ($aEvents as $sEvent => $aEventInfo) {
$aDesc = $aEventInfo['description'];
$aRows[] = [
'event' => $sEvent,
'description' => $aDesc['description'] ?? '',
];
}
$oTable = DataTableUIBlockFactory::MakeForStaticData(Dict::S('UI:Schema:Events:Defined'), $aColumns, $aRows);
$oPage->AddSubBlock($oTable);
$oObject = MetaModel::NewObject($sClass);
$aSources = [$oObject->GetObjectUniqId()];
foreach (MetaModel::EnumParentClasses($sClass, ENUM_PARENT_CLASSES_ALL, false) as $sParentClass) {
$aSources[] = $sParentClass;
}
$aListeners = [];
foreach (array_keys($aEvents) as $sEvent) {
$aListeners = array_merge($aListeners, EventService::GetListeners($sEvent, $aSources));
}
$aColumns = [
'event' => ['label' => 'Event'],
'listener' => ['label' => 'Listener'],
'priority' => ['label' => 'Priority'],
'module' => ['label' => 'Module'],
];
$aRows = [];
foreach ($aListeners as $aListener) {
if (is_object($aListener['callback'][0])) {
$sListener = get_class($aListener['callback'][0]).'->'.$aListener['callback'][1].'(Combodo\iTop\Service\EventData $oEventData)';
} else {
$sListener = $aListener['callback'][0].'::'.$aListener['callback'][1].'(Combodo\iTop\Service\EventData $oEventData)';
}
$aRows[] = [
'event' => $aListener['event'],
'listener' => $sListener,
'priority' => $aListener['priority'],
'module' => $aListener['module'],
];
}
$oTable = DataTableUIBlockFactory::MakeForStaticData(Dict::S('UI:Schema:Events:Listeners'), $aColumns, $aRows);
$oPage->AddSubBlock($oTable);
}
/**
* Display the list of classes from the business model
*/
@@ -1061,6 +1113,9 @@ EOF
$oPage->SetCurrentTab('UI:Schema:Triggers');
DisplayTriggers($oPage, $sClass);
$oPage->SetCurrentTab('UI:Schema:Events');
DisplayEvents($oPage, $sClass);
$oPage->SetCurrentTab();
$oPage->SetCurrentTabContainer();
}

View File

@@ -1078,23 +1078,13 @@ EOF
protected function CompileEvent(DesignElement $oEvent, string $sModuleName)
{
$sName = $oEvent->getAttribute('id');
$oDescription = $oEvent->GetOptionalElement('description');
$sDescription = empty($oDescription) ? '' : $oDescription->GetText('');
$aArguments = [];
foreach ($oEvent->GetNodes('./arguments/argument') as $oArgumentNode) {
$aArg = [];
$sArgId = $oArgumentNode->getAttribute('id');
$oArgDesc = $oArgumentNode->GetOptionalElement('description');
$aArg['description'] = empty($oArgDesc) ? '' : $oArgDesc->GetText('');
$oArgType = $oArgumentNode->GetOptionalElement('type');
$aArg['type'] = empty($oArgType) ? '' : $oArgType->GetText('');
$aArguments[$sArgId] = $aArg;
}
$sArguments = var_export($aArguments, true);
$aEventDescription = DesignElement::ToArray($oEvent);
$sDescription = var_export($aEventDescription, true);
$sConstant = $sName;
$sOutput = "define('$sConstant', '$sName');\n";
$sOutput .= "Combodo\iTop\Service\EventService::RegisterEvent('$sName', '$sDescription', $sArguments, '$sModuleName');\n";
$sOutput .= "Combodo\iTop\Service\EventService::RegisterEvent('$sName', $sDescription, '$sModuleName');\n";
return $sOutput;
}
@@ -1329,7 +1319,7 @@ EOF
}
$sListenerPriority = (float)($oListener->GetChildText('priority', '0'));
$sEvents .= "\n Combodo\iTop\Service\EventService::RegisterListener(\"$sEventName\", $sEventListener, \$this->m_sObjectUniqId, \"$sListenerId\", null, $sListenerPriority);";
$sEvents .= "\n Combodo\iTop\Service\EventService::RegisterListener(\"$sEventName\", $sEventListener, \$this->m_sObjectUniqId, \"$sListenerId\", null, $sListenerPriority, '$sModuleRelativeDir');";
}
}
@@ -3698,7 +3688,7 @@ EOF;
$sEventSource = $aHook['source'];
$sContext = $aHook['context'];
$sPriority = $aHook['priority'];
$sRegister .= "\nCombodo\iTop\Service\EventService::RegisterListener(\"$sEventName\", '$sClassName::$sCallback', $sEventSource, null, $sContext, $sPriority);";
$sRegister .= "\nCombodo\iTop\Service\EventService::RegisterListener(\"$sEventName\", '$sClassName::$sCallback', $sEventSource, null, $sContext, $sPriority, '$sModuleId');";
$sCallbackFct = $aHook['content'];
$sMethods .= "\n {$sCallbackFct}\n\n";
}

View File

@@ -12,13 +12,13 @@ use Exception;
use ExecutionKPI;
use IssueLog;
use LogChannels;
use ReflectionClass;
class EventService
{
public static $aEventListeners = [];
private static $iEventIdCounter = 0;
private static $aEventDescription = [];
Private static $aReentranceProtection = [];
/**
* Register a callback for a specific event
@@ -33,20 +33,24 @@ class EventService
* @return string Id of the registration (used for unregistering)
*
*/
public static function RegisterListener(string $sEvent, callable $callback, $sEventSource = null, $aCallbackData = [], $context = null, float $fPriority = 0.0): string
public static function RegisterListener(string $sEvent, callable $callback, $sEventSource = null, $aCallbackData = [], $context = null, float $fPriority = 0.0, $sModuleId = ''): string
{
is_callable($callback, false, $sName);
if (!is_callable($callback, false, $sName)) {
return false;
}
$aEventCallbacks = self::$aEventListeners[$sEvent] ?? [];
$sId = 'event_'.self::$iEventIdCounter++;
$aEventCallbacks[] = array(
'id' => $sId,
'event' => $sEvent,
'callback' => $callback,
'source' => $sEventSource,
'name' => $sName,
'data' => $aCallbackData,
'context' => $context,
'priority' => $fPriority,
'module' => $sModuleId,
);
usort($aEventCallbacks, function ($a, $b) {
$fPriorityA = $a['priority'];
@@ -96,31 +100,15 @@ class EventService
return;
}
foreach (self::$aEventListeners[$sEvent] as $aEventCallback) {
if (!self::MatchEventSource($aEventCallback['source'], $eventSource)) {
continue;
}
foreach (self::GetListeners($sEvent, $eventSource) as $aEventCallback) {
if (!self::MatchContext($aEventCallback['context'])) {
continue;
}
$sName = $aEventCallback['name'];
// Reentrance protection
if (isset(self::$aReentranceProtection[$aEventCallback['id']])) {
if (!self::$aReentranceProtection[$aEventCallback['id']]) {
unset(self::$aReentranceProtection[$aEventCallback['id']]);
}
IssueLog::Debug("Reentrance protection for '$sLogEventName'$sSource for '$sName'", LogChannels::EVENT_SERVICE);
continue;
}
IssueLog::Debug("Fire event '$sLogEventName'$sSource calling '$sName'", LogChannels::EVENT_SERVICE);
try {
if (is_callable($aEventCallback['callback'])) {
$oEventData->SetCallbackData($aEventCallback['data']);
call_user_func($aEventCallback['callback'], $oEventData);
} else {
IssueLog::Debug("Callback '$sName' not a callable anymore, unregister", LogChannels::EVENT_SERVICE);
self::UnRegisterCallback($aEventCallback['id']);
}
}
catch (Exception $e) {
IssueLog::Error("Event '$sLogEventName' for '$sName' id {$aEventCallback['id']} failed with error: ".$e->getMessage());
@@ -130,6 +118,20 @@ class EventService
$oKPI->ComputeStats('FireEvent', $sEvent);
}
public static function GetListeners($sEvent, $eventSource)
{
$aListeners = [];
if (isset(self::$aEventListeners[$sEvent])) {
foreach (self::$aEventListeners[$sEvent] as $aEventCallback) {
if (self::MatchEventSource($aEventCallback['source'], $eventSource)) {
$aListeners[] = $aEventCallback;
}
}
}
return $aListeners;
}
private static function MatchEventSource($srcRegistered, $srcEvent): bool
{
if (empty($srcRegistered)) {
@@ -208,7 +210,7 @@ class EventService
*
* @param string $sId the callback registration id
*/
public static function UnRegisterCallback(string $sId)
public static function UnRegisterListener(string $sId)
{
$bRemoved = self::Browse(function ($sEvent, $idx, $aEventCallback) use ($sId) {
if ($aEventCallback['id'] == $sId) {
@@ -232,7 +234,7 @@ class EventService
*
* @param string $sEvent event to unregister
*/
public static function UnRegisterEvent(string $sEvent)
public static function UnRegisterEventListeners(string $sEvent)
{
if (!isset(self::$aEventListeners[$sEvent])) {
IssueLog::Trace("No registration found for event '$sEvent'", LogChannels::EVENT_SERVICE);
@@ -274,7 +276,7 @@ class EventService
}
// For information only
public static function RegisterEvent(string $sEvent, string $sDescription, array $aArguments, string $sModule)
public static function RegisterEvent(string $sEvent, array $aDescription, string $sModule)
{
if (isset(self::$aEventDescription[$sEvent])) {
$sPrevious = self::$aEventDescription[$sEvent]['module'];
@@ -282,14 +284,29 @@ class EventService
}
self::$aEventDescription[$sEvent] = [
'constant'=> 'EVENT_SERVICE_'.strtoupper(self::FromCamelCase($sEvent)),
'name'=> $sEvent,
'description' => $sDescription,
'arguments' => $aArguments,
'description' => $aDescription,
'module' => $sModule,
];
}
public static function GetEventsByClass($sClass)
{
$aRes = [];
$oClass = new ReflectionClass($sClass);
foreach (self::$aEventDescription as $sEvent => $aEventInfo) {
if (isset($aEventInfo['description']['sources'])) {
foreach ($aEventInfo['description']['sources'] as $sSource) {
if ($sClass == $sSource || $oClass->isSubclassOf($sSource)) {
$aRes[$sEvent] = $aEventInfo;
}
}
}
}
return $aRes;
}
// Intentionally duplicated from SetupUtils, not yet loaded when RegisterEvent is called
private static function FromCamelCase($sInput) {
$sPattern = '!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!';

View File

@@ -228,7 +228,7 @@ class EventTest extends ItopTestCase
EventService::FireEvent(new EventData('event2'));
$this->assertEquals(4, self::$iEventCalls);
EventService::UnRegisterEvent('event1');
EventService::UnRegisterEventListeners('event1');
EventService::FireEvent(new EventData('event1'));
$this->assertEquals(4, self::$iEventCalls);
@@ -282,7 +282,7 @@ class EventTest extends ItopTestCase
EventService::FireEvent(new EventData('event2'));
$this->assertEquals(4, self::$iEventCalls);
EventService::UnRegisterCallback($sIdToRemove);
EventService::UnRegisterListener($sIdToRemove);
EventService::FireEvent(new EventData('event1'));
$this->assertEquals(6, self::$iEventCalls);