Преглед изворни кода

merged branch real-chocopanda/fix-hasListeners-ContainerAwareEventDispatcher (PR #2066)

Commits
-------

2cfa22c Fix Method ContainerAwareEventDispatcher::hasListeners

Discussion
----------

Fix Method ContainerAwareEventDispatcher::hasListeners

Related to #1903.

This is the squashed on 2.0 branch version of the PR #1903

---
Fix Method ContainerAwareEventDispatcher::hasListeners

Fix the fact that Method ContainerAwareEventDispatcher::hasListeners return false if my service is not lazyLoaded

---------------------------------------------------------------------------

by cedriclombardot at 2011/08/31 01:40:45 -0700

@stof it's fixed
Fabien Potencier пре 13 година
родитељ
комит
1de7ebf91b

+ 47 - 2
src/Symfony/Bundle/FrameworkBundle/ContainerAwareEventDispatcher.php

@@ -71,6 +71,38 @@ class ContainerAwareEventDispatcher extends EventDispatcher
         $this->listenerIds[$eventName][] = array($callback[0], $callback[1], $priority);
     }
 
+    /**
+    * @see EventDispatcherInterface::hasListeners
+    */
+    public function hasListeners($eventName = null)
+    {
+        if (null === $eventName) {
+            return (Boolean) count($this->listenerIds) || (Boolean) count($this->listeners);
+        }
+
+        if (isset($this->listenerIds[$eventName])) {
+            return true;
+        }
+
+        return parent::hasListeners($eventName);
+    }
+
+    /**
+    * @see EventDispatcherInterface::getListeners
+    */
+    public function getListeners($eventName = null)
+    {
+        if (null === $eventName) {
+            foreach ($this->listenerIds as $serviceEventName => $listners) {
+                $this->lazyLoad($serviceEventName);
+            }
+        } else {
+            $this->lazyLoad($eventName);
+        }
+
+        return parent::getListeners($eventName);
+    }
+
     /**
      * {@inheritDoc}
      *
@@ -80,6 +112,21 @@ class ContainerAwareEventDispatcher extends EventDispatcher
      * @throws \InvalidArgumentException if the service is not defined
      */
     public function dispatch($eventName, Event $event = null)
+    {
+        $this->lazyLoad($eventName);
+
+        parent::dispatch($eventName, $event);
+    }
+
+    /**
+     * Lazily loads listeners for this event from the dependency injection
+     * container.
+     *
+     * @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.
+     */
+    protected function lazyLoad($eventName)
     {
         if (isset($this->listenerIds[$eventName])) {
             foreach ($this->listenerIds[$eventName] as $args) {
@@ -97,7 +144,5 @@ class ContainerAwareEventDispatcher extends EventDispatcher
                 $this->listeners[$eventName][$key] = $listener;
             }
         }
-
-        parent::dispatch($eventName, $event);
     }
 }

+ 44 - 0
src/Symfony/Bundle/FrameworkBundle/Tests/ContainerAwareEventDispatcherTest.php

@@ -122,6 +122,50 @@ class ContainerAwareEventDispatcherTest extends \PHPUnit_Framework_TestCase
 
         $dispatcher->dispatch('onEvent');
     }
+
+    public function testHasListenersOnLazyLoad()
+    {
+        $event = new Event();
+
+        $service = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service');
+
+        $service
+            ->expects($this->once())
+            ->method('onEvent')
+            ->with($event)
+        ;
+
+        $container = new Container();
+        $container->set('service.listener', $service);
+
+        $dispatcher = new ContainerAwareEventDispatcher($container);
+        $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
+
+        $this->assertTrue($dispatcher->hasListeners());
+
+        if ($dispatcher->hasListeners('onEvent')) {
+            $dispatcher->dispatch('onEvent');
+        }
+    }
+
+    public function testGetListenersOnLazyLoad()
+    {
+        $event = new Event();
+
+        $service = $this->getMock('Symfony\Bundle\FrameworkBundle\Tests\Service');
+
+        $container = new Container();
+        $container->set('service.listener', $service);
+
+        $dispatcher = new ContainerAwareEventDispatcher($container);
+        $dispatcher->addListenerService('onEvent', array('service.listener', 'onEvent'));
+
+        $listeners = $dispatcher->getListeners();
+
+        $this->assertTrue(isset($listeners['onEvent']));
+
+        $this->assertEquals(1, count($dispatcher->getListeners('onEvent')));
+    }
 }
 
 class Service