Skip to content

Commit

Permalink
Added EventManager::prioritisedListeners() function to alow the globa…
Browse files Browse the repository at this point in the history
…l event manager to return unprocessed listeners array

Refs #2105
  • Loading branch information
Andy Hobbs authored and markstory committed Nov 11, 2013
1 parent e8984a9 commit 615f700
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 4 deletions.
21 changes: 19 additions & 2 deletions lib/Cake/Event/CakeEventManager.php
Expand Up @@ -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]);
}

Expand All @@ -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];
}
}
95 changes: 93 additions & 2 deletions lib/Cake/Test/Case/Event/CakeEventManagerTest.php
Expand Up @@ -213,6 +213,29 @@ public function testDispatch() {
$manager->dispatch($event);
}

/**
* 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
*
Expand Down Expand Up @@ -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);
}

Expand All @@ -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));
Expand All @@ -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.