Permalink
Browse files

Added EventManager::prioritisedListeners() function to alow the globa…

…l event manager to return unprocessed listeners array

Refs #2105
  • Loading branch information...
1 parent e8984a9 commit 615f700d22c40160af265f93a7a39fd3b67879c7 Andy Hobbs committed with markstory Sep 13, 2013
Showing with 112 additions and 4 deletions.
  1. +19 −2 lib/Cake/Event/CakeEventManager.php
  2. +93 −2 lib/Cake/Test/Case/Event/CakeEventManagerTest.php
@@ -264,14 +264,19 @@ public function dispatch($event) {
* @return array
*/
public function listeners($eventKey) {
- if (empty($this->_listeners[$eventKey])) {
+ $globalListeners = array();
+ if (!$this->_isGlobal) {
+ $globalListeners = self::instance()->prioritisedListeners($eventKey);
+ }
+
+ if (empty($this->_listeners[$eventKey]) && empty($globalListeners)) {
return array();
}
$listeners = $this->_listeners[$eventKey];
foreach ($globalListeners as $priority => $priorityQ) {
if (!empty($listeners[$priority])) {
- $listeners[$priority] = array_merge($listeners[$priority], $priorityQ);
+ $listeners[$priority] = array_merge($priorityQ, $listeners[$priority]);
unset($globalListeners[$priority]);
}
@@ -286,4 +291,16 @@ public function listeners($eventKey) {
return $result;
}
+/**
+ * Returns the listeners for the specified event key indexed by priority
+ *
+ * @param string $eventKey
+ * @return array
+ */
+ public function prioritisedListeners($eventKey) {
+ if (empty($this->_listeners[$eventKey])) {
+ return array();
+ }
+ return $this->_listeners[$eventKey];
+ }
}
@@ -214,6 +214,29 @@ public function testDispatch() {
}
/**
+ * Tests event dispatching
+ *
+ * @return void
+ */
+ public function testDispatchClosure() {
+ $this->skipIf(
+ version_compare(PHP_VERSION, '5.3.0', '<'),
+ 'These tests fail in PHP version < 5.3'
+ );
+
+ $manager = new CakeEventManager;
+ $listener = $this->getMock('CakeEventTestListener');
+ $anotherListener = $this->getMock('CakeEventTestListener');
+
+ $manager->attach(function($testEvent) use ($listener) { $listener->listenerFunction($testEvent); }, 'fake.event');
+
+ $event = new CakeEvent('fake.event');
+
+ $listener->expects($this->once())->method('listenerFunction')->with($event);
+ $manager->dispatch($event);
+ }
+
+/**
* Tests event dispatching using event key name
*
* @return void
@@ -388,12 +411,12 @@ public function testGlobalDispatcherGetter() {
* @return void
*/
public function testDispatchWithGlobal() {
- $generalManager = $this->getMock('CakeEventManager', array('dispatch'));
+ $generalManager = $this->getMock('CakeEventManager', array('prioritisedListeners'));
$manager = new CakeEventManager;
$event = new CakeEvent('fake.event');
CakeEventManager::instance($generalManager);
- $generalManager->expects($this->once())->method('dispatch')->with($event);
+ $generalManager->expects($this->once())->method('prioritisedListeners')->with('fake.event');
$manager->dispatch($event);
}
@@ -405,6 +428,13 @@ public function testDispatchWithGlobal() {
public function testStopPropagation() {
$manager = new CakeEventManager;
$listener = new CakeEventTestListener;
+
+ CakeEventManager::instance($generalManager);
+ $generalManager->expects($this->any())
+ ->method('prioritisedListeners')
+ ->with('fake.event')
+ ->will($this->returnValue(array()));
+
$manager->attach(array($listener, 'listenerFunction'), 'fake.event');
$manager->attach(array($listener, 'stopListener'), 'fake.event', array('priority' => 8));
$manager->attach(array($listener, 'secondListenerFunction'), 'fake.event', array('priority' => 5));
@@ -414,4 +444,65 @@ public function testStopPropagation() {
$expected = array('secondListenerFunction');
$this->assertEquals($expected, $listener->callStack);
}
+
+/**
+ * Tests event dispatching using priorities
+ *
+ * @return void
+ */
+ public function testDispatchPrioritizedWithGlobal() {
+ $generalManager = $this->getMock('CakeEventManager');
+ $manager = new CakeEventManager;
+ $listener = new CustomTestEventListerner;
+ $event = new CakeEvent('fake.event');
+
+ CakeEventManager::instance($generalManager);
+ $generalManager->expects($this->any())
+ ->method('prioritisedListeners')
+ ->with('fake.event')
+ ->will($this->returnValue(
+ array(11 => array(
+ array('callable' => array($listener, 'secondListenerFunction'), 'passParams' => false)
+ ))
+ ));
+
+
+ $manager->attach(array($listener, 'listenerFunction'), 'fake.event');
+ $manager->attach(array($listener, 'thirdListenerFunction'), 'fake.event', array('priority' => 15));
+
+ $manager->dispatch($event);
+
+ $expected = array('listenerFunction', 'secondListenerFunction', 'thirdListenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+ }
+
+ /**
+ * Tests event dispatching using priorities
+ *
+ * @return void
+ */
+ public function testDispatchGlobalBeforeLocal() {
+ $generalManager = $this->getMock('CakeEventManager');
+ $manager = new CakeEventManager;
+ $listener = new CustomTestEventListerner;
+ $event = new CakeEvent('fake.event');
+
+ CakeEventManager::instance($generalManager);
+ $generalManager->expects($this->any())
+ ->method('prioritisedListeners')
+ ->with('fake.event')
+ ->will($this->returnValue(
+ array(10 => array(
+ array('callable' => array($listener, 'listenerFunction'), 'passParams' => false)
+ ))
+ ));
+
+
+ $manager->attach(array($listener, 'secondListenerFunction'), 'fake.event');
+
+ $manager->dispatch($event);
+
+ $expected = array('listenerFunction', 'secondListenerFunction');
+ $this->assertEquals($expected, $listener->callStack);
+ }
}

0 comments on commit 615f700

Please sign in to comment.