mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Move Event service from sources/Application/Service to sources/Service
This commit is contained in:
84
sources/Service/Events/Description/EventDataDescription.php
Normal file
84
sources/Service/Events/Description/EventDataDescription.php
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events\Description;
|
||||
|
||||
/**
|
||||
* Description of the data given with an event when registering
|
||||
*
|
||||
* @api
|
||||
* @package EventsAPI
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class EventDataDescription
|
||||
{
|
||||
private string $sName;
|
||||
private string $sDescription;
|
||||
private string $sType;
|
||||
|
||||
/**
|
||||
* Create a data description
|
||||
*
|
||||
* @api
|
||||
* @param string $sName Name of the parameter
|
||||
* @param string $sDescription Description of the parameter
|
||||
* @param string $sType Type of the parameter
|
||||
*/
|
||||
public function __construct(string $sName, string $sDescription, string $sType)
|
||||
{
|
||||
$this->sName = $sName;
|
||||
$this->sDescription = $sDescription;
|
||||
$this->sType = $sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetName(): string
|
||||
{
|
||||
return $this->sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
*/
|
||||
public function SetName(string $sName): void
|
||||
{
|
||||
$this->sName = $sName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetDescription(): string
|
||||
{
|
||||
return $this->sDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDescription
|
||||
*/
|
||||
public function SetDescription(string $sDescription): void
|
||||
{
|
||||
$this->sDescription = $sDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetType(): string
|
||||
{
|
||||
return $this->sType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sType
|
||||
*/
|
||||
public function SetType(string $sType): void
|
||||
{
|
||||
$this->sType = $sType;
|
||||
}
|
||||
}
|
||||
143
sources/Service/Events/Description/EventDescription.php
Normal file
143
sources/Service/Events/Description/EventDescription.php
Normal file
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events\Description;
|
||||
|
||||
/**
|
||||
* Description of an event when registering
|
||||
*
|
||||
* @api
|
||||
* @package EventsAPI
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class EventDescription
|
||||
{
|
||||
private string $sEventName;
|
||||
/** @var string[]|string|null */
|
||||
private $mEventSources;
|
||||
private string $sDescription;
|
||||
private string $sReplaces;
|
||||
/** @var \Combodo\iTop\Service\Events\Description\EventDataDescription[] */
|
||||
private array $aEventDataDescription;
|
||||
private string $sModule;
|
||||
|
||||
/**
|
||||
* Create a description for an event
|
||||
*
|
||||
* @api
|
||||
* @param string $sEventName Name of the described event
|
||||
* @param string|string[]|null $mEventSources Source(s) for this event (can be the root class for CRUD events)
|
||||
* @param string $sDescription Description of the event
|
||||
* @param string $sReplaces In case this event obsoletes previous extensibility functions
|
||||
* @param \Combodo\iTop\Service\Events\Description\EventDataDescription[] $aEventDataDescription Description of the data associated with this event
|
||||
* @param string $sModule iTop Module name where the event is defined
|
||||
*/
|
||||
public function __construct(string $sEventName, $mEventSources, string $sDescription, string $sReplaces, array $aEventDataDescription, string $sModule)
|
||||
{
|
||||
$this->sEventName = $sEventName;
|
||||
$this->mEventSources = $mEventSources;
|
||||
$this->sDescription = $sDescription;
|
||||
$this->sReplaces = $sReplaces;
|
||||
$this->aEventDataDescription = $aEventDataDescription;
|
||||
$this->sModule = $sModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetEventName(): string
|
||||
{
|
||||
return $this->sEventName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEventName
|
||||
*/
|
||||
public function SetEventName(string $sEventName): void
|
||||
{
|
||||
$this->sEventName = $sEventName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetDescription(): string
|
||||
{
|
||||
return $this->sDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDescription
|
||||
*/
|
||||
public function SetDescription(string $sDescription): void
|
||||
{
|
||||
$this->sDescription = $sDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetReplaces(): string
|
||||
{
|
||||
return $this->sReplaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sReplaces
|
||||
*/
|
||||
public function SetReplaces(string $sReplaces): void
|
||||
{
|
||||
$this->sReplaces = $sReplaces;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function GetEventDataDescription(): array
|
||||
{
|
||||
return $this->aEventDataDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \Combodo\iTop\Service\Events\Description\EventDataDescription[] $aEventDataDescription
|
||||
*/
|
||||
public function SetEventDataDescription(array $aEventDataDescription): void
|
||||
{
|
||||
$this->aEventDataDescription = $aEventDataDescription;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function GetModule(): string
|
||||
{
|
||||
return $this->sModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sModule
|
||||
*/
|
||||
public function SetModule(string $sModule): void
|
||||
{
|
||||
$this->sModule = $sModule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|string[]|null
|
||||
*/
|
||||
public function GetEventSources()
|
||||
{
|
||||
return $this->mEventSources;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|string[]|null $mEventSources
|
||||
*/
|
||||
public function SetEventSources($mEventSources): void
|
||||
{
|
||||
$this->mEventSources = $mEventSources;
|
||||
}
|
||||
}
|
||||
112
sources/Service/Events/EventData.php
Normal file
112
sources/Service/Events/EventData.php
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
|
||||
/**
|
||||
* Data given to the Event Service callbacks
|
||||
* Class EventServiceData
|
||||
*
|
||||
* @api
|
||||
* @package EventsAPI
|
||||
* @since 3.1.0
|
||||
*/
|
||||
class EventData
|
||||
{
|
||||
private string $sEvent;
|
||||
private $mEventSource;
|
||||
private array $aEventData;
|
||||
/** @var array Additional data collected by the listener : they can be set in {@see \Combodo\iTop\Service\Events\EventService::RegisterListener} */
|
||||
private array $aCallbackData;
|
||||
|
||||
/**
|
||||
* EventServiceData constructor.
|
||||
*
|
||||
* @api
|
||||
* @param string $sEvent Event fired
|
||||
* @param string|array|null $mEventSource Event source
|
||||
* @param array $aEventData Event data for the listeners
|
||||
*/
|
||||
public function __construct(string $sEvent, $mEventSource = null, array $aEventData = [])
|
||||
{
|
||||
$this->sEvent = $sEvent;
|
||||
$this->aEventData = $aEventData;
|
||||
$this->mEventSource = $mEventSource;
|
||||
$this->aCallbackData = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the event fired.
|
||||
*
|
||||
* @api
|
||||
* @return string Event fired.
|
||||
*/
|
||||
public function GetEvent(): string
|
||||
{
|
||||
return $this->sEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any parameter from the data sent when firing the event.
|
||||
*
|
||||
* @api
|
||||
* @param $sParam
|
||||
*
|
||||
* @return mixed|null Parameter given when firing the event.
|
||||
*/
|
||||
public function Get($sParam)
|
||||
{
|
||||
if (isset($this->aEventData[$sParam])) {
|
||||
return $this->aEventData[$sParam];
|
||||
}
|
||||
|
||||
if (isset($this->aCallbackData[$sParam])) {
|
||||
return $this->aCallbackData[$sParam];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get event source of fired event.
|
||||
*
|
||||
* @api
|
||||
* @return mixed Source given when firing the event.
|
||||
*/
|
||||
public function GetEventSource()
|
||||
{
|
||||
return $this->mEventSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the data sent when firing the event.
|
||||
*
|
||||
* @api
|
||||
* @return array All the data given when firing the event.
|
||||
*/
|
||||
public function GetEventData(): array
|
||||
{
|
||||
return $this->aEventData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $aCallbackData
|
||||
*/
|
||||
public function SetCallbackData($aCallbackData)
|
||||
{
|
||||
$this->aCallbackData = $aCallbackData ?? [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @api
|
||||
* @uses static::$aCallbackData
|
||||
*/
|
||||
public function GetCallbackData(): array
|
||||
{
|
||||
return $this->aCallbackData;
|
||||
}
|
||||
}
|
||||
14
sources/Service/Events/EventException.php
Normal file
14
sources/Service/Events/EventException.php
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
use Exception;
|
||||
|
||||
class EventException extends Exception
|
||||
{
|
||||
|
||||
}
|
||||
47
sources/Service/Events/EventHelper.php
Normal file
47
sources/Service/Events/EventHelper.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
class EventHelper
|
||||
{
|
||||
public static function MatchEventSource($srcRegistered, $srcEvent): bool
|
||||
{
|
||||
if (empty($srcRegistered)) {
|
||||
// no filtering
|
||||
return true;
|
||||
}
|
||||
if (empty($srcEvent)) {
|
||||
// no match (the registered source is not empty)
|
||||
return false;
|
||||
}
|
||||
if (is_string($srcRegistered)) {
|
||||
$aSrcRegistered = [$srcRegistered];
|
||||
} elseif (is_array($srcRegistered)) {
|
||||
$aSrcRegistered = $srcRegistered;
|
||||
} else {
|
||||
$aSrcRegistered = [];
|
||||
}
|
||||
|
||||
if (is_string($srcEvent)) {
|
||||
$aSrcEvent = [$srcEvent];
|
||||
} elseif (is_array($srcEvent)) {
|
||||
$aSrcEvent = $srcEvent;
|
||||
} else {
|
||||
$aSrcEvent = [];
|
||||
}
|
||||
|
||||
foreach ($aSrcEvent as $sSrcEvent) {
|
||||
if (in_array($sSrcEvent, $aSrcRegistered)) {
|
||||
// sources matches
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// no match
|
||||
return false;
|
||||
}
|
||||
}
|
||||
374
sources/Service/Events/EventService.php
Normal file
374
sources/Service/Events/EventService.php
Normal file
@@ -0,0 +1,374 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
use Closure;
|
||||
use Combodo\iTop\Service\Events\Description\EventDescription;
|
||||
use ContextTag;
|
||||
use CoreException;
|
||||
use Exception;
|
||||
use ExecutionKPI;
|
||||
use ReflectionClass;
|
||||
use utils;
|
||||
|
||||
/**
|
||||
* Event driven extensibility.
|
||||
* Inspired by [PSR-14: Event Dispatcher](https://www.php-fig.org/psr/psr-14).
|
||||
* Adapted to iTop needs in terms of event filtering (using event source or context).
|
||||
*
|
||||
* @package EventsAPI
|
||||
* @api
|
||||
* @since 3.1.0
|
||||
*/
|
||||
final class EventService
|
||||
{
|
||||
/** @var array */
|
||||
private static array $aEventListeners = [];
|
||||
/** @var int */
|
||||
private static int $iEventIdCounter = 0;
|
||||
/** @var array */
|
||||
private static array $aEventDescriptions = [];
|
||||
|
||||
/**
|
||||
* Initialize the Event Service. This is called by iTop.
|
||||
*
|
||||
* @internal
|
||||
* @return void
|
||||
*/
|
||||
public static function InitService()
|
||||
{
|
||||
$aEventServiceSetup = utils::GetClassesForInterface(iEventServiceSetup::class, '', ['[\\\\/]lib[\\\\/]', '[\\\\/]node_modules[\\\\/]', '[\\\\/]test[\\\\/]']);
|
||||
foreach ($aEventServiceSetup as $sEventServiceSetupClass) {
|
||||
/** @var \Combodo\iTop\Service\Events\iEventServiceSetup $oEventServiceSetup */
|
||||
$oEventServiceSetup = new $sEventServiceSetupClass();
|
||||
$oEventServiceSetup->RegisterEventsAndListeners();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a callback for a specific event
|
||||
*
|
||||
* @api
|
||||
* @param string $sEvent corresponding event
|
||||
* @param callable $callback The callback to call
|
||||
* @param array|string|null $sEventSource event filtering depending on the source of the event
|
||||
* @param mixed $aCallbackData optional data given by the registrar to the callback
|
||||
* @param array|string|null $context context filter
|
||||
* @param float $fPriority optional priority for callback order
|
||||
*
|
||||
* @return string Id of the registration
|
||||
*
|
||||
*/
|
||||
public static function RegisterListener(string $sEvent, callable $callback, $sEventSource = null, array $aCallbackData = [], $context = null, float $fPriority = 0.0, $sModuleId = ''): string
|
||||
{
|
||||
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'];
|
||||
$fPriorityB = $b['priority'];
|
||||
if ($fPriorityA == $fPriorityB) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return ($fPriorityA < $fPriorityB) ? -1 : 1;
|
||||
});
|
||||
self::$aEventListeners[$sEvent] = $aEventCallbacks;
|
||||
|
||||
$sSource = self::GetSourcesAsString($sEventSource);
|
||||
EventServiceLog::Debug("Registering Listener '$sName' for event '$sEvent' source '$sSource' from '$sModuleId'");
|
||||
|
||||
return $sId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public static function GetListenersAsJSON()
|
||||
{
|
||||
return json_encode(self::$aEventListeners, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event. Call all the callbacks registered for this event.
|
||||
*
|
||||
* @api
|
||||
* @param \Combodo\iTop\Service\Events\EventData $oEventData
|
||||
*
|
||||
* @throws \Exception from the callback
|
||||
*/
|
||||
public static function FireEvent(EventData $oEventData)
|
||||
{
|
||||
$sEvent = $oEventData->GetEvent();
|
||||
if (!self::IsEventRegistered($sEvent)) {
|
||||
$sError = "Fire event error: Event $sEvent is not registered";
|
||||
EventServiceLog::Error($sError);
|
||||
throw new CoreException($sError);
|
||||
}
|
||||
$eventSource = $oEventData->GetEventSource();
|
||||
$oKPI = new ExecutionKPI();
|
||||
$sLogEventName = "$sEvent - ".self::GetSourcesAsString($eventSource).' '.json_encode($oEventData->GetEventData());
|
||||
EventServiceLog::Trace("Fire event '$sLogEventName'");
|
||||
if (!isset(self::$aEventListeners[$sEvent])) {
|
||||
$oKPI->ComputeStats('FireEvent', $sEvent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$oLastException = null;
|
||||
$sLastExceptionMessage = null;
|
||||
$bEventFired = false;
|
||||
foreach (self::GetListeners($sEvent, $eventSource) as $aEventCallback) {
|
||||
if (!self::MatchContext($aEventCallback['context'])) {
|
||||
continue;
|
||||
}
|
||||
$sName = $aEventCallback['name'];
|
||||
EventServiceLog::Debug("Fire event '$sLogEventName' calling '$sName'");
|
||||
$bEventFired = true;
|
||||
try {
|
||||
$oEventData->SetCallbackData($aEventCallback['data']);
|
||||
call_user_func($aEventCallback['callback'], $oEventData);
|
||||
}
|
||||
catch (EventException $e) {
|
||||
EventServiceLog::Error("Event '$sLogEventName' for '$sName' id {$aEventCallback['id']} failed with blocking error: ".$e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
catch (Exception $e) {
|
||||
$sLastExceptionMessage = "Event '$sLogEventName' for '$sName' id {$aEventCallback['id']} failed with non-blocking error: ".$e->getMessage();
|
||||
EventServiceLog::Error($sLastExceptionMessage);
|
||||
$oLastException = $e;
|
||||
}
|
||||
}
|
||||
if ($bEventFired) {
|
||||
EventServiceLog::Debug("End of event '$sLogEventName'");
|
||||
}
|
||||
$oKPI->ComputeStats('FireEvent', $sEvent);
|
||||
|
||||
if (!is_null($oLastException)) {
|
||||
EventServiceLog::Error("Throwing the last exception caught: $sLastExceptionMessage");
|
||||
throw $oLastException;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEvent
|
||||
* @param $eventSource
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function GetListeners(string $sEvent, $eventSource = null): array
|
||||
{
|
||||
$aListeners = [];
|
||||
if (isset(self::$aEventListeners[$sEvent])) {
|
||||
foreach (self::$aEventListeners[$sEvent] as $aEventCallback) {
|
||||
if (EventHelper::MatchEventSource($aEventCallback['source'], $eventSource)) {
|
||||
$aListeners[] = $aEventCallback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aListeners;
|
||||
}
|
||||
|
||||
private static function MatchContext($registeredContext): bool
|
||||
{
|
||||
if (empty($registeredContext)) {
|
||||
return true;
|
||||
}
|
||||
if (is_string($registeredContext)) {
|
||||
$aContexts = array($registeredContext);
|
||||
} elseif (is_array($registeredContext)) {
|
||||
$aContexts = $registeredContext;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
foreach ($aContexts as $sContext) {
|
||||
if (ContextTag::Check($sContext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static function GetSourcesAsString($srcRegistered): string
|
||||
{
|
||||
if (empty($srcRegistered)) {
|
||||
return '';
|
||||
}
|
||||
if (is_string($srcRegistered)) {
|
||||
return substr($srcRegistered, 0, 30);
|
||||
}
|
||||
if (is_array($srcRegistered)) {
|
||||
return substr(implode(',', $srcRegistered), 0, 30);
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a previously registered callback
|
||||
*
|
||||
* @param string $sId the callback registration id
|
||||
*/
|
||||
public static function UnRegisterListener(string $sId)
|
||||
{
|
||||
$bRemoved = self::Browse(function ($sEvent, $idx, $aEventCallback) use ($sId) {
|
||||
if ($aEventCallback['id'] == $sId) {
|
||||
$sName = self::$aEventListeners[$sEvent][$idx]['name'];
|
||||
unset (self::$aEventListeners[$sEvent][$idx]);
|
||||
EventServiceLog::Trace("Unregistered callback '$sName' id $sId' on event '$sEvent'");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!$bRemoved) {
|
||||
EventServiceLog::Trace("No registration found for callback '$sId'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all the listeners for an event
|
||||
*
|
||||
* @param string $sEvent event to unregister
|
||||
*/
|
||||
public static function UnRegisterEventListeners(string $sEvent)
|
||||
{
|
||||
if (!isset(self::$aEventListeners[$sEvent])) {
|
||||
EventServiceLog::Trace("No registration found for event '$sEvent'");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unset(self::$aEventListeners[$sEvent]);
|
||||
EventServiceLog::Trace("Unregistered all the callbacks on event '$sEvent'");
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister all the events
|
||||
*/
|
||||
public static function UnRegisterAll()
|
||||
{
|
||||
self::$aEventListeners = [];
|
||||
self::$aEventDescriptions = [];
|
||||
self::$iEventIdCounter = 0;
|
||||
EventServiceLog::Trace("Unregistered all events");
|
||||
}
|
||||
|
||||
/**
|
||||
* Browse all the registrations
|
||||
*
|
||||
* @param \Closure $callback function($sEvent, $idx, $aEventCallback) to call (return false to interrupt the browsing)
|
||||
*
|
||||
* @return bool true if interrupted else false
|
||||
*/
|
||||
private static function Browse(closure $callback): bool
|
||||
{
|
||||
foreach (self::$aEventListeners as $sEvent => $aCallbackList) {
|
||||
foreach ($aCallbackList as $idx => $aEventCallback) {
|
||||
if (call_user_func($callback, $sEvent, $idx, $aEventCallback) === false) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an event.
|
||||
* This allows to describe all the events available.
|
||||
* This step is mandatory before firing an event.
|
||||
*
|
||||
* @api
|
||||
* @param \Combodo\iTop\Service\Events\Description\EventDescription $oEventDescription
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function RegisterEvent(EventDescription $oEventDescription)
|
||||
{
|
||||
$sEvent = $oEventDescription->GetEventName();
|
||||
$sModule = $oEventDescription->GetModule();
|
||||
if (self::IsEventRegistered($sEvent)) {
|
||||
$sPrevious = self::$aEventDescriptions[$sEvent]['module'];
|
||||
EventServiceLog::Warning("The Event $sEvent defined by $sModule has already been defined in $sPrevious, check your delta");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
self::$aEventDescriptions[$sEvent] = [
|
||||
'name' => $sEvent,
|
||||
'description' => $oEventDescription,
|
||||
'module' => $sModule,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sClass
|
||||
*
|
||||
* @return array
|
||||
* @throws \ReflectionException
|
||||
* @throws \ReflectionException
|
||||
* @throws \ReflectionException
|
||||
*/
|
||||
public static function GetEventsByClass(string $sClass): array
|
||||
{
|
||||
$aRes = [];
|
||||
$oClass = new ReflectionClass($sClass);
|
||||
foreach (self::$aEventDescriptions as $sEvent => $aEventInfo) {
|
||||
if (is_array($aEventInfo['description']->GetEventSources())) {
|
||||
foreach ($aEventInfo['description']->GetEventSources() as $sSource) {
|
||||
if ($sClass == $sSource || $oClass->isSubclassOf($sSource)) {
|
||||
$aRes[$sEvent] = $aEventInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $aRes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check is an event is already registered.
|
||||
* Can be used to avoid exception when firing an unregistered event.
|
||||
*
|
||||
* @api
|
||||
* @param string $sEvent
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function IsEventRegistered(string $sEvent): bool
|
||||
{
|
||||
return array_key_exists($sEvent, self::$aEventDescriptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|string
|
||||
*/
|
||||
public static function GetDefinedEventsAsJSON()
|
||||
{
|
||||
return json_encode(self::$aEventDescriptions, JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
15
sources/Service/Events/EventServiceLog.php
Normal file
15
sources/Service/Events/EventServiceLog.php
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
use IssueLog;
|
||||
use LogChannels;
|
||||
|
||||
class EventServiceLog extends IssueLog
|
||||
{
|
||||
const CHANNEL_DEFAULT = LogChannels::EVENT_SERVICE;
|
||||
}
|
||||
25
sources/Service/Events/iEventServiceSetup.php
Normal file
25
sources/Service/Events/iEventServiceSetup.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
/*
|
||||
* @copyright Copyright (C) 2010-2023 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
namespace Combodo\iTop\Service\Events;
|
||||
|
||||
/**
|
||||
* Interface to implement in order to register the events and listeners
|
||||
*
|
||||
* @api
|
||||
* @package EventsAPI
|
||||
* @since 3.1.0
|
||||
*/
|
||||
interface iEventServiceSetup
|
||||
{
|
||||
/**
|
||||
* Extension point to register the events and events listeners
|
||||
*
|
||||
* @api
|
||||
* @return void
|
||||
*/
|
||||
public function RegisterEventsAndListeners();
|
||||
}
|
||||
Reference in New Issue
Block a user