Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dev/core#2316 - Symfony EventDispatcher dispatch() signature kerfuffle - try 3 #24132

Merged
merged 14 commits into from
Nov 11, 2022
Merged
2 changes: 1 addition & 1 deletion Civi.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public static function container() {
/**
* Get the event dispatcher.
*
* @return \Symfony\Component\EventDispatcher\EventDispatcherInterface
* @return \Civi\Core\CiviEventDispatcherInterface
*/
public static function dispatcher() {
// NOTE: The dispatcher object is initially created as a boot service
Expand Down
2 changes: 1 addition & 1 deletion Civi/API/Event/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* Class Event
* @package Civi\API\Event
*/
class Event extends \Symfony\Component\EventDispatcher\Event {
class Event extends \Civi\Core\Event\GenericHookEvent {

use RequestTrait;

Expand Down
8 changes: 4 additions & 4 deletions Civi/API/Kernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
class Kernel {

/**
* @var \Symfony\Component\EventDispatcher\EventDispatcher
* @var \Civi\Core\CiviEventDispatcherInterface
*/
protected $dispatcher;

Expand All @@ -33,7 +33,7 @@ class Kernel {
protected $apiProviders;

/**
* @param \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
* @param \Civi\Core\CiviEventDispatcherInterface $dispatcher
* The event dispatcher which receives kernel events.
* @param array $apiProviders
* Array of ProviderInterface.
Expand Down Expand Up @@ -462,14 +462,14 @@ public function registerApiProvider($apiProvider) {
}

/**
* @return \Symfony\Component\EventDispatcher\EventDispatcher
* @return \Civi\Core\CiviEventDispatcherInterface
*/
public function getDispatcher() {
return $this->dispatcher;
}

/**
* @param \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
* @param \Civi\Core\CiviEventDispatcherInterface $dispatcher
* The event dispatcher which receives kernel events.
* @return Kernel
*/
Expand Down
4 changes: 2 additions & 2 deletions Civi/ActionSchedule/Event/MailingQueryEvent.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?php
namespace Civi\ActionSchedule\Event;

use Symfony\Component\EventDispatcher\Event;
use Civi\Core\Event\GenericHookEvent;

/**
* Class MailingQueryEvent
Expand Down Expand Up @@ -49,7 +49,7 @@
*
* Event name: 'civi.actionSchedule.prepareMailingQuery'
*/
class MailingQueryEvent extends Event {
class MailingQueryEvent extends GenericHookEvent {

/**
* The schedule record which produced this mailing.
Expand Down
4 changes: 2 additions & 2 deletions Civi/ActionSchedule/Event/MappingRegisterEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
namespace Civi\ActionSchedule\Event;

use Civi\ActionSchedule\MappingInterface;
use Symfony\Component\EventDispatcher\Event;
use Civi\Core\Event\GenericHookEvent;

/**
* Class ActionScheduleEvent
Expand All @@ -12,7 +12,7 @@
*
* Event name: 'civi.actionSchedule.getMappings'
*/
class MappingRegisterEvent extends Event {
class MappingRegisterEvent extends GenericHookEvent {

/**
* @var array
Expand Down
4 changes: 2 additions & 2 deletions Civi/Api4/Event/PostSelectQueryEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
namespace Civi\Api4\Event;

use Civi\Api4\Query\Api4SelectQuery;
use Symfony\Component\EventDispatcher\Event;
use Civi\Core\Event\GenericHookEvent;

class PostSelectQueryEvent extends Event {
class PostSelectQueryEvent extends GenericHookEvent {

/**
* @var array
Expand Down
2 changes: 1 addition & 1 deletion Civi/Api4/Event/SchemaMapBuildEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
namespace Civi\Api4\Event;

use Civi\Api4\Service\Schema\SchemaMap;
use Symfony\Component\EventDispatcher\Event as BaseEvent;
use Civi\Core\Event\GenericHookEvent as BaseEvent;

class SchemaMapBuildEvent extends BaseEvent {
/**
Expand Down
8 changes: 4 additions & 4 deletions Civi/Api4/Service/Schema/SchemaMapBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
use Civi\Api4\Event\SchemaMapBuildEvent;
use Civi\Api4\Service\Schema\Joinable\CustomGroupJoinable;
use Civi\Api4\Service\Schema\Joinable\Joinable;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Civi\Core\Service\AutoService;
use Civi\Core\CiviEventDispatcherInterface;
use CRM_Core_DAO_AllCoreTables as AllCoreTables;

/**
Expand All @@ -27,7 +27,7 @@
class SchemaMapBuilder extends AutoService {

/**
* @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
* @var \Civi\Core\CiviEventDispatcherInterface
*/
protected $dispatcher;
/**
Expand All @@ -36,10 +36,10 @@ class SchemaMapBuilder extends AutoService {
protected $apiEntities;

/**
* @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $dispatcher
* @inject dispatcher
* @param \Civi\Core\CiviEventDispatcherInterface $dispatcher
*/
public function __construct(EventDispatcherInterface $dispatcher) {
public function __construct(CiviEventDispatcherInterface $dispatcher) {
$this->dispatcher = $dispatcher;
$this->apiEntities = array_keys((array) Entity::get(FALSE)->addSelect('name')->execute()->indexBy('name'));
}
Expand Down
66 changes: 58 additions & 8 deletions Civi/Core/CiviEventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

namespace Civi\Core;

use Civi\Core\Event\GenericHookEvent;
use Civi\Core\Event\HookStyleListener;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* Class CiviEventDispatcher
Expand All @@ -16,10 +16,15 @@
*
* @see \CRM_Utils_Hook
*/
class CiviEventDispatcher extends EventDispatcher {
class CiviEventDispatcher implements CiviEventDispatcherInterface {

const DEFAULT_HOOK_PRIORITY = -100;

/**
* @var Symfony\Component\EventDispatcher\EventDispatcher
*/
private $dispatcher;

/**
* Track the list of hook-events for which we have autoregistered
* the hook adapter.
Expand Down Expand Up @@ -51,6 +56,20 @@ class CiviEventDispatcher extends EventDispatcher {
*/
private $dispatchPolicyRegex = NULL;

/**
* Constructor
*/
public function __construct() {
$this->dispatcher = new UnoptimizedEventDispatcher();
}

/**
* Get Event Dispatcher
*/
public function getDispatcher() {
return $this->dispatcher;
}

/**
* Determine whether $eventName should delegate to the CMS hook system.
*
Expand Down Expand Up @@ -90,6 +109,27 @@ public function addSubscriberServiceMap(string $subscriber, array $events) {
}
}

/**
* @inheritDoc
*/
public function addSubscriber(EventSubscriberInterface $subscriber) {
return $this->dispatcher->addSubscriber($subscriber);
}

/**
* @inheritDoc
*/
public function removeSubscriber(EventSubscriberInterface $subscriber) {
return $this->dispatcher->removeSubscriber($subscriber);
}

/**
* @inheritDoc
*/
public function getListenerPriority($eventName, $listener) {
return $this->dispatcher->getListenerPriority($eventName, $listener);
}

/**
* Add a test listener.
*
Expand All @@ -106,7 +146,7 @@ public function addListener($eventName, $listener, $priority = 0) {
$eventName = substr($eventName, 1);
$listener = new HookStyleListener($listener);
}
parent::addListener($eventName, $listener, $priority);
$this->dispatcher->addListener($eventName, $listener, $priority);
}

/**
Expand Down Expand Up @@ -169,7 +209,7 @@ public function addListenerService($eventName, $callback, $priority = 0) {
/**
* @inheritDoc
*/
public function dispatch($eventName, Event $event = NULL) {
public function dispatch($eventName, $event = NULL) {
// Dispatch policies add systemic overhead and (normally) should not be evaluated. JNZ.
if ($this->dispatchPolicyRegex !== NULL) {
switch ($mode = $this->checkDispatchPolicy($eventName)) {
Expand Down Expand Up @@ -214,15 +254,25 @@ public function dispatch($eventName, Event $event = NULL) {
}
}
$this->bindPatterns($eventName);
return parent::dispatch($eventName, $event);
if ($event === NULL) {
$event = GenericHookEvent::create([]);
}
return $this->dispatcher->dispatch($event, $eventName);
}

/**
* @inheritDoc
*/
public function getListeners($eventName = NULL) {
$this->bindPatterns($eventName);
return parent::getListeners($eventName);
return $this->dispatcher->getListeners($eventName);
}

/**
* @inheritDoc
*/
public function removeListener($eventName, $listener) {
return $this->dispatcher->removeListener($eventName, $listener);
}

/**
Expand All @@ -231,7 +281,7 @@ public function getListeners($eventName = NULL) {
public function hasListeners($eventName = NULL) {
// All hook_* events have default listeners, so hasListeners(NULL) is a truism.
return ($eventName === NULL || $this->isHookEvent($eventName))
? TRUE : parent::hasListeners($eventName);
? TRUE : $this->dispatcher->hasListeners($eventName);
}

/**
Expand Down
94 changes: 94 additions & 0 deletions Civi/Core/CiviEventDispatcherInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<?php

/*
* This is the same as symfony 4 EventDispatcherInterface
* except the Event parameter to dispatch() can be an object, to support
* symfony 5+ because there is no Event definition anymore.
*
* Also some style changes to make it pass style checking.
*/

namespace Civi\Core;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
* The EventDispatcherInterface is the central point of Symfony's event listener system.
* Listeners are registered on the manager and events are dispatched through the
* manager.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
interface CiviEventDispatcherInterface {

/**
* Dispatches an event to all registered listeners.
*
* @param string $eventName The name of the event to dispatch. The name of
* the event is the name of the method that is invoked on listeners.
* @param Event|null $event The event to pass to the event handlers/listeners
* If not supplied, an empty Event instance is created
*
* @return Event
*/
public function dispatch($eventName, $event = NULL);

/**
* Adds an event listener that listens on the specified events.
*
* @param string $eventName The event to listen on
* @param callable $listener The listener
* @param int $priority The higher this value, the earlier an event
* listener will be triggered in the chain (defaults to 0)
*/
public function addListener($eventName, $listener, $priority = 0);

/**
* Adds an event subscriber.
*
* The subscriber is asked for all the events it is
* interested in and added as a listener for these events.
*/
public function addSubscriber(EventSubscriberInterface $subscriber);

/**
* Removes an event listener from the specified events.
*
* @param string $eventName The event to remove a listener from
* @param callable $listener The listener to remove
*/
public function removeListener($eventName, $listener);

public function removeSubscriber(EventSubscriberInterface $subscriber);

/**
* Gets the listeners of a specific event or all listeners sorted by descending priority.
*
* @param string|null $eventName The name of the event
*
* @return array The event listeners for the specified event, or all event listeners by event name
*/
public function getListeners($eventName = NULL);

/**
* Gets the listener priority for a specific event.
*
* Returns null if the event or the listener does not exist.
*
* @param string $eventName The name of the event
* @param callable $listener The listener
*
* @return int|null The event listener priority
*/
public function getListenerPriority($eventName, $listener);

/**
* Checks whether an event has any registered listeners.
*
* @param string|null $eventName The name of the event
*
* @return bool true if the specified event has any listeners, false otherwise
*/
public function hasListeners($eventName = NULL);

}
4 changes: 2 additions & 2 deletions Civi/Core/Container.php
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ public function createAngularManager() {
}

/**
* @return \Symfony\Component\EventDispatcher\EventDispatcher
* @return \Civi\Core\CiviEventDispatcherInterface
*/
public function createEventDispatcher() {
// Continue building on the original dispatcher created during bootstrap.
Expand Down Expand Up @@ -490,7 +490,7 @@ public static function createLockManager() {
}

/**
* @param \Symfony\Component\EventDispatcher\EventDispatcher $dispatcher
* @param \Civi\Core\CiviEventDispatcherInterface $dispatcher
* @param $magicFunctionProvider
*
* @return \Civi\API\Kernel
Expand Down
2 changes: 1 addition & 1 deletion Civi/Core/DAO/Event/PostDelete.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* Class PostUpdate
* @package Civi\Core\DAO\Event
*/
class PostDelete extends \Symfony\Component\EventDispatcher\Event {
class PostDelete extends \Civi\Core\Event\GenericHookEvent {

/**
* @var \CRM_Core_DAO
Expand Down
Loading