mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-24 11:08:45 +02:00
EventService: refactoring
This commit is contained in:
@@ -73,17 +73,17 @@ class EventData
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array|null $aCallbackData
|
||||
* @param mixed $aCallbackData
|
||||
*/
|
||||
public function SetCallbackData(?array $aCallbackData)
|
||||
public function SetCallbackData($aCallbackData)
|
||||
{
|
||||
$this->aCallbackData = $aCallbackData;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
* @return mixed
|
||||
*/
|
||||
public function GetCallbackData(): array
|
||||
public function GetCallbackData()
|
||||
{
|
||||
return $this->aCallbackData;
|
||||
}
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @copyright Copyright (C) 2010-2020 Combodo SARL
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
|
||||
namespace Combodo\iTop\Service;
|
||||
|
||||
|
||||
class EventName
|
||||
{
|
||||
// Core
|
||||
//
|
||||
// OrmDocument
|
||||
const DOWNLOAD_DOCUMENT = 'DownloadDocument';
|
||||
|
||||
// DBObject
|
||||
const DB_OBJECT_LOADED = 'DBObjectLoaded';
|
||||
const DB_OBJECT_RELOAD = 'DBObjectReload';
|
||||
const DB_OBJECT_NEW = 'DBObjectNew';
|
||||
const BEFORE_INSERT = 'BeforeInsert';
|
||||
const DB_OBJECT_KEY_READY = 'DBObjectKeyReady';
|
||||
const AFTER_INSERT = 'AfterInsert';
|
||||
const BEFORE_UPDATE = 'BeforeUpdate';
|
||||
const AFTER_UPDATE = 'AfterUpdate';
|
||||
const BEFORE_DELETE = 'BeforeDelete';
|
||||
const AFTER_DELETE = 'AfterDelete';
|
||||
const BEFORE_APPLY_STIMULUS = 'BeforeApplyStimulus';
|
||||
const AFTER_APPLY_STIMULUS = 'AfterApplyStimulus';
|
||||
const ON_CHECK_TO_WRITE = 'OnCheckToWrite';
|
||||
const ON_CHECK_TO_DELETE = 'OnCheckToDelete';
|
||||
const DISPLAY_OBJECT_DETAILS = 'DisplayObjectDetails';
|
||||
|
||||
// Application
|
||||
//
|
||||
const LOGIN = 'OnLogin';
|
||||
|
||||
// Web Pages
|
||||
const AFTER_DISPLAY_PAGE = 'AfterDisplayPage';
|
||||
}
|
||||
@@ -16,8 +16,9 @@ define('LOG_EVENT_SERVICE_CHANNEL', 'EventService');
|
||||
|
||||
class EventService
|
||||
{
|
||||
private static $aEvents = array();
|
||||
public static $aEventListeners = [];
|
||||
private static $iEventIdCounter = 0;
|
||||
private static $aEventDescription = [];
|
||||
|
||||
/**
|
||||
* Register a callback for a specific event
|
||||
@@ -25,7 +26,7 @@ class EventService
|
||||
* @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 array|null $aCallbackData optional data given by the registrar to the callback
|
||||
* @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
|
||||
*
|
||||
@@ -33,11 +34,11 @@ class EventService
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public static function Register(string $sEvent, callable $callback, $sEventSource = null, ?array $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): string
|
||||
{
|
||||
is_callable($callback, false, $sName);
|
||||
|
||||
$aEventCallbacks = self::$aEvents[$sEvent] ?? [];
|
||||
$aEventCallbacks = self::$aEventListeners[$sEvent] ?? [];
|
||||
$sId = 'event_'.self::$iEventIdCounter++;
|
||||
$aEventCallbacks[] = array(
|
||||
'id' => $sId,
|
||||
@@ -57,10 +58,10 @@ class EventService
|
||||
|
||||
return ($fPriorityA < $fPriorityB) ? -1 : 1;
|
||||
});
|
||||
self::$aEvents[$sEvent] = $aEventCallbacks;
|
||||
self::$aEventListeners[$sEvent] = $aEventCallbacks;
|
||||
|
||||
$iTotalRegistrations = 0;
|
||||
foreach (self::$aEvents as $aEvent) {
|
||||
foreach (self::$aEventListeners as $aEvent) {
|
||||
$iTotalRegistrations += count($aEvent);
|
||||
}
|
||||
$sEventName = "$sEvent:".self::GetSourcesAsString($sEventSource);
|
||||
@@ -69,6 +70,11 @@ class EventService
|
||||
return $sId;
|
||||
}
|
||||
|
||||
public static function GetListenersAsJSON()
|
||||
{
|
||||
return json_encode(self::$aEventListeners, JSON_PRETTY_PRINT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fire an event. Call all the callbacks registered for this event.
|
||||
*
|
||||
@@ -84,14 +90,14 @@ class EventService
|
||||
$sSource = isset($aEventData['debug_info']) ? " {$aEventData['debug_info']}" : '';
|
||||
$sEventName = "$sEvent:".self::GetSourcesAsString($eventSource);
|
||||
IssueLog::Trace("Fire event '$sEventName'$sSource", LOG_EVENT_SERVICE_CHANNEL);
|
||||
if (!isset(self::$aEvents[$sEvent])) {
|
||||
if (!isset(self::$aEventListeners[$sEvent])) {
|
||||
IssueLog::Trace("No registration found for event '$sEvent'", LOG_EVENT_SERVICE_CHANNEL);
|
||||
$oKPI->ComputeStats('FireEvent', $sEvent);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (self::$aEvents[$sEvent] as $aEventCallback) {
|
||||
foreach (self::$aEventListeners[$sEvent] as $aEventCallback) {
|
||||
if (!self::MatchEventSource($aEventCallback['source'], $eventSource)) {
|
||||
continue;
|
||||
}
|
||||
@@ -199,8 +205,8 @@ class EventService
|
||||
{
|
||||
$bRemoved = self::Browse(function ($sEvent, $idx, $aEventCallback) use ($sId) {
|
||||
if ($aEventCallback['id'] == $sId) {
|
||||
$sName = self::$aEvents[$sEvent][$idx]['name'];
|
||||
unset (self::$aEvents[$sEvent][$idx]);
|
||||
$sName = self::$aEventListeners[$sEvent][$idx]['name'];
|
||||
unset (self::$aEventListeners[$sEvent][$idx]);
|
||||
IssueLog::Trace("Unregistered callback '$sName' id $sId' on event '$sEvent'", LOG_EVENT_SERVICE_CHANNEL);
|
||||
|
||||
return false;
|
||||
@@ -221,13 +227,13 @@ class EventService
|
||||
*/
|
||||
public static function UnRegisterEvent(string $sEvent)
|
||||
{
|
||||
if (!isset(self::$aEvents[$sEvent])) {
|
||||
if (!isset(self::$aEventListeners[$sEvent])) {
|
||||
IssueLog::Trace("No registration found for event '$sEvent'", LOG_EVENT_SERVICE_CHANNEL);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
unset(self::$aEvents[$sEvent]);
|
||||
unset(self::$aEventListeners[$sEvent]);
|
||||
IssueLog::Trace("Unregistered all the callbacks on event '$sEvent'", LOG_EVENT_SERVICE_CHANNEL);
|
||||
}
|
||||
|
||||
@@ -236,7 +242,7 @@ class EventService
|
||||
*/
|
||||
public static function UnRegisterAll()
|
||||
{
|
||||
self::$aEvents = array();
|
||||
self::$aEventListeners = array();
|
||||
IssueLog::Trace("Unregistered all events", LOG_EVENT_SERVICE_CHANNEL);
|
||||
}
|
||||
|
||||
@@ -249,7 +255,7 @@ class EventService
|
||||
*/
|
||||
private static function Browse(closure $callback): bool
|
||||
{
|
||||
foreach (self::$aEvents as $sEvent => $aCallbackList) {
|
||||
foreach (self::$aEventListeners as $sEvent => $aCallbackList) {
|
||||
foreach ($aCallbackList as $idx => $aEventCallback) {
|
||||
if (call_user_func($callback, $sEvent, $idx, $aEventCallback) === false) {
|
||||
return true;
|
||||
@@ -259,4 +265,39 @@ class EventService
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// For information only
|
||||
public static function RegisterEvent(string $sEvent, string $sDescription, string $sModule)
|
||||
{
|
||||
if (isset(self::$aEventDescription[$sEvent])) {
|
||||
$sPrevious = self::$aEventDescription[$sEvent]['module'];
|
||||
IssueLog::Error("The Event $sEvent defined by $sModule has already been defined in $sPrevious, check your delta", LOG_EVENT_SERVICE_CHANNEL);
|
||||
}
|
||||
|
||||
self::$aEventDescription[$sEvent] = [
|
||||
'constant'=> 'EVENT_SERVICE_'.strtoupper(self::FromCamelCase($sEvent)),
|
||||
'name'=> $sEvent,
|
||||
'description' => $sDescription,
|
||||
'module' => $sModule,
|
||||
];
|
||||
}
|
||||
|
||||
// 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]+)!';
|
||||
preg_match_all($sPattern, $sInput, $aMatches);
|
||||
$aRet = $aMatches[0];
|
||||
foreach ($aRet as &$sMatch) {
|
||||
$sMatch = $sMatch == strtoupper($sMatch) ?
|
||||
strtolower($sMatch) :
|
||||
lcfirst($sMatch);
|
||||
}
|
||||
return implode('_', $aRet);
|
||||
}
|
||||
|
||||
|
||||
public static function GetDefinedEventsAsJSON()
|
||||
{
|
||||
return json_encode(self::$aEventDescription, JSON_PRETTY_PRINT);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,6 @@ use Combodo\iTop\Application\UI\Base\iUIBlock;
|
||||
use Combodo\iTop\Application\UI\Base\Layout\iUIContentBlock;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
class AjaxPage extends WebPage implements iTabbedPage
|
||||
{
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
use Combodo\iTop\Service\EventData;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
/**
|
||||
@@ -53,7 +52,7 @@ class CLIPage implements Page
|
||||
{
|
||||
$aData['debug_info'] = 'from: '.get_class($this).":[$this->s_title]";
|
||||
$aData['object'] = $this;
|
||||
EventService::FireEvent(new EventData(EventName::AFTER_DISPLAY_PAGE, get_class($this), $aData));
|
||||
EventService::FireEvent(new EventData(EVENT_SERVICE_AFTER_DISPLAY_PAGE, get_class($this), $aData));
|
||||
}
|
||||
|
||||
public function add($sText)
|
||||
|
||||
@@ -15,8 +15,7 @@
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with iTop. If not, see <http://www.gnu.org/licenses/>
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
|
||||
/**
|
||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
/**
|
||||
* Class JsonPage
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -22,8 +22,6 @@ use Combodo\iTop\Application\Branding;
|
||||
use Combodo\iTop\Application\TwigBase\Twig\TwigHelper;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
$sPortalBaseFolderRelPath = 'env-' . utils::GetCurrentEnvironment() . '/itop-portal-base/portal/';
|
||||
$sPortalSourcesFolderRelPath = $sPortalBaseFolderRelPath . 'src/';
|
||||
|
||||
@@ -18,7 +18,6 @@ use Combodo\iTop\Application\UI\Base\Layout\UIContentBlock;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Service\EventData;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
|
||||
@@ -1355,7 +1354,7 @@ JS;
|
||||
{
|
||||
$aData['debug_info'] = 'from: '.get_class($this).":[$this->s_title]";
|
||||
$aData['object'] = $this;
|
||||
EventService::FireEvent(new EventData(EventName::AFTER_DISPLAY_PAGE, get_class($this), $aData));
|
||||
EventService::FireEvent(new EventData(EVENT_SERVICE_AFTER_DISPLAY_PAGE, get_class($this), $aData));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,8 +23,6 @@
|
||||
* @license http://opensource.org/licenses/AGPL-3.0
|
||||
*/
|
||||
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
/**
|
||||
* Simple web page with no includes or fancy formatting, useful to generateXML documents
|
||||
|
||||
@@ -22,8 +22,6 @@ use Combodo\iTop\Application\UI\Base\UIBlock;
|
||||
use Combodo\iTop\Application\UI\Printable\BlockPrintHeader\BlockPrintHeader;
|
||||
use Combodo\iTop\Renderer\BlockRenderer;
|
||||
use Combodo\iTop\Renderer\Console\ConsoleBlockRenderer;
|
||||
use Combodo\iTop\Service\EventName;
|
||||
use Combodo\iTop\Service\EventService;
|
||||
|
||||
/**
|
||||
* Web page with some associated CSS and scripts (jquery) for a fancier display
|
||||
|
||||
Reference in New Issue
Block a user