View source
<?php
namespace Drupal\Component\EventDispatcher;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ContainerAwareEventDispatcher implements EventDispatcherInterface {
protected $container;
protected $listeners;
protected $unsorted;
public function __construct(ContainerInterface $container, array $listeners = []) {
$this->container = $container;
$this->listeners = $listeners;
$this->unsorted = [];
}
public function dispatch($event_name, Event $event = NULL) {
if ($event === NULL) {
$event = new Event();
}
if (isset($this->listeners[$event_name])) {
if (isset($this->unsorted[$event_name])) {
krsort($this->listeners[$event_name]);
unset($this->unsorted[$event_name]);
}
foreach ($this->listeners[$event_name] as $priority => &$definitions) {
foreach ($definitions as $key => &$definition) {
if (!isset($definition['callable'])) {
$definition['callable'] = [
$this->container
->get($definition['service'][0]),
$definition['service'][1],
];
}
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
$definition['callable'][0] = $definition['callable'][0]();
}
call_user_func($definition['callable'], $event, $event_name, $this);
if ($event
->isPropagationStopped()) {
return $event;
}
}
}
}
return $event;
}
public function getListeners($event_name = NULL) {
$result = [];
if ($event_name === NULL) {
foreach (array_keys($this->listeners) as $event_name) {
$listeners = $this
->getListeners($event_name);
if (!empty($listeners)) {
$result[$event_name] = $listeners;
}
}
}
elseif (isset($this->listeners[$event_name])) {
if (isset($this->unsorted[$event_name])) {
krsort($this->listeners[$event_name]);
unset($this->unsorted[$event_name]);
}
foreach ($this->listeners[$event_name] as $priority => &$definitions) {
foreach ($definitions as $key => &$definition) {
if (!isset($definition['callable'])) {
$definition['callable'] = [
$this->container
->get($definition['service'][0]),
$definition['service'][1],
];
}
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
$definition['callable'][0] = $definition['callable'][0]();
}
$result[] = $definition['callable'];
}
}
}
return $result;
}
public function getListenerPriority($event_name, $listener) {
if (!isset($this->listeners[$event_name])) {
return;
}
if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
}
foreach ($this->listeners[$event_name] as $priority => &$definitions) {
foreach ($definitions as $key => &$definition) {
if (!isset($definition['callable'])) {
$definition['callable'] = [
$this->container
->get($definition['service'][0]),
$definition['service'][1],
];
}
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
$definition['callable'][0] = $definition['callable'][0]();
}
if ($definition['callable'] === $listener) {
return $priority;
}
}
}
}
public function hasListeners($event_name = NULL) {
if ($event_name !== NULL) {
return !empty($this->listeners[$event_name]);
}
foreach ($this->listeners as $event_listeners) {
if ($event_listeners) {
return TRUE;
}
}
return FALSE;
}
public function addListener($event_name, $listener, $priority = 0) {
$this->listeners[$event_name][$priority][] = [
'callable' => $listener,
];
$this->unsorted[$event_name] = TRUE;
}
public function removeListener($event_name, $listener) {
if (!isset($this->listeners[$event_name])) {
return;
}
foreach ($this->listeners[$event_name] as $priority => $definitions) {
foreach ($definitions as $key => $definition) {
if (!isset($definition['callable'])) {
if (!$this->container
->initialized($definition['service'][0])) {
continue;
}
$definition['callable'] = [
$this->container
->get($definition['service'][0]),
$definition['service'][1],
];
}
if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure && !$listener instanceof \Closure) {
$definition['callable'][0] = $definition['callable'][0]();
}
if (is_array($definition['callable']) && isset($definition['callable'][0]) && !$definition['callable'][0] instanceof \Closure && is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
$listener[0] = $listener[0]();
}
if ($definition['callable'] === $listener) {
unset($definitions[$key]);
}
}
if ($definitions) {
$this->listeners[$event_name][$priority] = $definitions;
}
else {
unset($this->listeners[$event_name][$priority]);
}
}
}
public function addSubscriber(EventSubscriberInterface $subscriber) {
foreach ($subscriber
->getSubscribedEvents() as $event_name => $params) {
if (is_string($params)) {
$this
->addListener($event_name, [
$subscriber,
$params,
]);
}
elseif (is_string($params[0])) {
$this
->addListener($event_name, [
$subscriber,
$params[0],
], isset($params[1]) ? $params[1] : 0);
}
else {
foreach ($params as $listener) {
$this
->addListener($event_name, [
$subscriber,
$listener[0],
], isset($listener[1]) ? $listener[1] : 0);
}
}
}
}
public function removeSubscriber(EventSubscriberInterface $subscriber) {
foreach ($subscriber
->getSubscribedEvents() as $event_name => $params) {
if (is_array($params) && is_array($params[0])) {
foreach ($params as $listener) {
$this
->removeListener($event_name, [
$subscriber,
$listener[0],
]);
}
}
else {
$this
->removeListener($event_name, [
$subscriber,
is_string($params) ? $params : $params[0],
]);
}
}
}
}