Skip to content

Instantly share code, notes, and snippets.

@dawehner
Created April 24, 2014 16:48
Show Gist options
  • Save dawehner/11261395 to your computer and use it in GitHub Desktop.
Save dawehner/11261395 to your computer and use it in GitHub Desktop.
diff --git a/core/lib/Drupal/Core/EventDispatcher/LiteEventDispatcher.php b/core/lib/Drupal/Core/EventDispatcher/LiteEventDispatcher.php
new file mode 100644
index 0000000..81d5987
--- /dev/null
+++ b/core/lib/Drupal/Core/EventDispatcher/LiteEventDispatcher.php
@@ -0,0 +1,194 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\EventDispatcher\LiteEventDispatcher.
+ */
+
+namespace Drupal\Core\EventDispatcher;
+
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerAwareTrait;
+use Symfony\Component\EventDispatcher\Event;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class LiteEventDispatcher implements EventDispatcherInterface, ContainerAwareInterface {
+
+ use ContainerAwareTrait;
+
+ protected $listeners = array();
+ protected $sorted = array();
+
+ /**
+ * @var bool
+ */
+ protected $deferSort;
+
+ protected $containerSubscribers;
+ protected $services;
+
+ /**
+ * {@inheritdoc}
+ */
+ public function dispatch($event_name, Event $event = NULL) {
+ if ($event === NULL) {
+ $event = new Event();
+ }
+
+ $event->setDispatcher($this);
+ $event->setName($event_name);
+
+ // @todo Is this actually a helpful optimization?
+ if (!isset($this->sorted[$event_name])) {
+ return $event;
+ }
+
+ // Ensure that code is just loaded if it is needed.
+ if (!isset($this->loaded[$event_name])) {
+ $this->lazyLoad($event_name);
+ $this->loaded[$event_name] = TRUE;
+ }
+
+ $this->doDispatch($this->sorted[$event_name], $event_name, $event);
+ return $event;
+ }
+
+ public function lazyLoad($event_name) {
+ foreach ($this->containerSubscribers as $service_name) {
+ if (!isset($this->services[$service_name])) {
+ $this->services[$service_name] = $this->container->get($service_name);
+ }
+ }
+ }
+
+ /**
+ * Triggers the listeners of an event.
+ *
+ * This method can be overridden to add functionality that is executed for
+ * each listener.
+ *
+ * @param callable[] $listeners
+ * The event listeners.
+ * @param string $event_name
+ * The name of the event to dispatch.
+ * @param \Symfony\Component\EventDispatcher\Event
+ * $event The event object to pass to the event handlers/listeners.
+ */
+ protected function doDispatch($listeners, $event_name, Event $event) {
+ foreach ($listeners as $listener) {
+ call_user_func($listener, $event, $event_name, $this);
+ }
+ }
+
+ public function setDeferSorting($defer = TRUE) {
+ $this->deferSort = $defer;
+ }
+
+ public function sortAll() {
+ $this->sorted = array();
+
+ foreach ($this->listeners as $event_name => $event_listeners) {
+ krsort($this->listeners[$event_name]);
+ $this->sorted[$event_name] = call_user_func_array('array_merge', $this->listeners[$event_name]);
+ }
+ }
+
+ public function sort($event_name) {
+ krsort($this->listeners[$event_name]);
+ $this->sorted[$event_name] = call_user_func_array('array_merge', $this->listeners[$event_name]);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addListener($eventName, $listener, $priority = 0) {
+ $this->listeners[$eventName][$priority][] = $listener;
+ if (!$this->deferSort) {
+ $this->sortAll();
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addSubscriber(EventSubscriberInterface $subscriber) {
+ $events = array();
+ foreach ($subscriber->getSubscribedEvents() as $event_name => $params) {
+ if (is_string($params)) {
+ $this->addListener($event_name, array($subscriber, $params));
+ }
+ elseif (is_string($params[0])) {
+ $this->addListener($event_name, array($subscriber, $params[0]), isset($params[1]) ? $params[1] : 0);
+ }
+ else {
+ foreach ($params as $listener) {
+ $this->addListener($event_name, array($subscriber, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
+ }
+ }
+ $events[$event_name] = $event_name;
+ }
+
+ foreach ($events as $event_name) {
+ $this->sort($event_name);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeListener($event_name, $listener) {
+ if (!isset($this->listeners[$event_name])) {
+ return;
+ }
+
+ foreach ($this->listeners[$event_name] as $priority => $listeners) {
+ if (($key = array_search($listener, $listeners, TRUE)) !== FALSE) {
+ unset($this->listeners[$event_name][$priority][$key], $this->sorted[$event_name]);
+ }
+ }
+
+ $this->sort($event_name);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function removeSubscriber(EventSubscriberInterface $subscriber) {
+ $events = array();
+ foreach ($subscriber->getSubscribedEvents() as $event_name => $params) {
+ if (is_array($params) && is_array($params[0])) {
+ foreach ($params as $listener) {
+ $this->removeListener($event_name, array($subscriber, $listener[0]));
+ }
+ }
+ else {
+ $this->removeListener($event_name, array($subscriber, is_string($params) ? $params : $params[0]));
+ }
+ $events[$event_name] = $event_name;
+ }
+
+ foreach ($events as $event_name) {
+ $this->sort($event_name);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getListeners($event_name = NULL) {
+ if ($event_name !== NULL) {
+ return $this->sorted[$event_name];
+ }
+ return $this->sorted;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function hasListeners($event_name = NULL) {
+ return (bool) count($this->getListeners($event_name));
+ }
+
+}
+
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment