vendor/symfony/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php
changeset 0 7f95f8617b0b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vendor/symfony/src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php	Sat Sep 24 15:40:41 2011 +0200
@@ -0,0 +1,103 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\FrameworkBundle;
+
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcher;
+use Symfony\Component\EventDispatcher\Event;
+
+/**
+ * Lazily loads listeners and subscribers from the dependency injection
+ * container
+ *
+ * @author Fabien Potencier <fabien@symfony.com>
+ * @author Bernhard Schussek <bernhard.schussek@symfony.com>
+ */
+class ContainerAwareEventDispatcher extends EventDispatcher
+{
+    /**
+     * The container from where services are loaded
+     * @var ContainerInterface
+     */
+    private $container;
+
+    /**
+     * The service IDs of the event listeners and subscribers
+     * @var array
+     */
+    private $listenerIds = array();
+
+    /**
+     * The services registered as listeners
+     * @var array
+     */
+    private $listeners = array();
+
+    /**
+     * Constructor.
+     *
+     * @param ContainerInterface $container A ContainerInterface instance
+     */
+    public function __construct(ContainerInterface $container)
+    {
+        $this->container = $container;
+    }
+
+    /**
+     * Adds a service as event listener
+     *
+     * @param string   $eventName Event for which the listener is added
+     * @param array    $callback  The service ID of the listener service & the method
+     *                            name that has to be called
+     * @param integer  $priority  The higher this value, the earlier an event listener
+     *                            will be triggered in the chain.
+     *                            Defaults to 0.
+     */
+    public function addListenerService($eventName, $callback, $priority = 0)
+    {
+        if (!is_array($callback) || 2 !== count($callback)) {
+            throw new \InvalidArgumentException('Expected an array("service", "method") argument');
+        }
+
+        $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * Lazily loads listeners for this event from the dependency injection
+     * container.
+     *
+     * @throws \InvalidArgumentException if the service is not defined
+     */
+    public function dispatch($eventName, Event $event = null)
+    {
+        if (isset($this->listenerIds[$eventName])) {
+            foreach ($this->listenerIds[$eventName] as $args) {
+                list($serviceId, $method, $priority) = $args;
+                $listener = $this->container->get($serviceId);
+
+                $key = $serviceId.'.'.$method;
+                if (!isset($this->listeners[$eventName][$key])) {
+                    $this->addListener($eventName, array($listener, $method), $priority);
+                } elseif ($listener !== $this->listeners[$eventName][$key]) {
+                    $this->removeListener($eventName, array($this->listeners[$eventName][$key], $method));
+                    $this->addListener($eventName, array($listener, $method), $priority);
+                }
+
+                $this->listeners[$eventName][$key] = $listener;
+            }
+        }
+
+        parent::dispatch($eventName, $event);
+    }
+}