Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'prototype/mvc-module' of https://github.com/weierophinn…
Browse files Browse the repository at this point in the history
…ey/zf2 into prototype/mvc-module
  • Loading branch information
DASPRiD committed Oct 2, 2011
12 parents db42bc8 + d5bfcbb + 70d6fcf + b400ede + 34626a6 + b1c5795 + fb59823 + 16b8f20 + 83086b6 + a81c8a5 + f17f9ea + c86ed1e commit 55ef06c
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 29 deletions.
74 changes: 49 additions & 25 deletions src/EventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@
use Zend\Stdlib\CallbackHandler,
Zend\Stdlib\Exception\InvalidCallbackException,
Zend\Stdlib\PriorityQueue,
ArrayObject;
ArrayObject,
SplPriorityQueue,
Traversable;

/**
* Event manager: notification system
Expand Down Expand Up @@ -345,62 +347,84 @@ protected function triggerListeners($event, EventDescription $e, $callback)
{
$responses = new ResponseCollection;

$listeners = $this->getListeners($event);
$listeners = clone $this->getListeners($event);
foreach ($this->getStaticListeners($event) as $listener) {
$priority = $listener->getOption('priority');
if (null === $priority) {
$priority = 1;
} elseif (is_array($priority)) {
// If we have an array, likely using PriorityQueue. Grab first
// element of the array, as that's the actual priority.
$priority = array_shift($priority);
}
$listeners->insert($listener, $priority);
}

if ($listeners->isEmpty()) {
return $this->triggerStaticListeners($callback, $e, $responses);
return $responses;
}

foreach ($listeners as $listener) {
// If we have an invalid listener, detach it, and move on to the next
if (!$listener->isValid()) {
$this->detach($listener);
continue;
}

// Trigger the listener's callback, and push its result onto the
// response collection
$responses->push(call_user_func($listener->getCallback(), $e));

// If the event was asked to stop propagating, do so
if ($e->propagationIsStopped()) {
$responses->setStopped(true);
break;
}

// If the result causes our validation callback to return true,
// stop propagation
if (call_user_func($callback, $responses->last())) {
$responses->setStopped(true);
break;
}
}

if (!$responses->stopped()) {
$this->triggerStaticListeners($callback, $e, $responses);
}
return $responses;
}

/**
* Emit listeners matching the current identifier found in the static listener
*
* @param callback $callback
* @param Event $event
* @param ResponseCollection $responses
* @return ResponseCollection
* Get list of all listeners attached to the static collection for
* identifiers registered by this instance
*
* @param string $event
* @return array
*/
protected function triggerStaticListeners($callback, Event $event, ResponseCollection $responses)
protected function getStaticListeners($event)
{
if (!$staticConnections = $this->getStaticConnections()) {
return $responses;
return array();
}

$identifiers = (array) $this->identifier;
$identifiers = (array) $this->identifier;
$staticListeners = array();

foreach ($identifiers as $id) {
if (!$listeners = $staticConnections->getListeners($id, $event->getName())) {
if (!$listeners = $staticConnections->getListeners($id, $event)) {
continue;
}

if (!is_array($listeners) && !($listeners instanceof Traversable)) {
continue;
}

foreach ($listeners as $listener) {
$responses->push(call_user_func($listener->getCallback(), $event));
if ($event->propagationIsStopped()) {
$responses->setStopped(true);
break;
}
if (call_user_func($callback, $responses->last())) {
$responses->setStopped(true);
break;
if (!$listener instanceof CallbackHandler) {
continue;
}
$staticListeners[] = $listener;
}
}

return $responses;
return $staticListeners;
}
}
2 changes: 1 addition & 1 deletion src/StaticEventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ public static function resetInstance()
* @param int $priority Priority at which listener should execute
* @return void
*/
public function attach($id, $event, $callback, $priority = 1000)
public function attach($id, $event, $callback, $priority = 1)
{
$ids = (array) $id;
foreach ($ids as $id) {
Expand Down
16 changes: 16 additions & 0 deletions test/EventManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -445,4 +445,20 @@ public function testTriggerCanTakeAnOptionalCallbackArgumentToEmulateTriggerUnti
});
$this->assertTrue($responses->stopped());
}

public function testWeakRefsAreHonoredWhenTriggering()
{
if (!class_exists('WeakRef', false)) {
$this->markTestSkipped('Requires pecl/weakref');
}

$functor = new TestAsset\Functor;
$this->events->attach('test', $functor);

unset($functor);

$result = $this->events->trigger('test', $this, array());
$message = $result->last();
$this->assertNull($message);
}
}
25 changes: 22 additions & 3 deletions test/StaticIntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ function ($e) use ($counter) {
$this->assertEquals(1, $counter->count);
}

public function testLocalHandlersAreExecutedPriorToStaticHandlers()
public function testLocalHandlersAreExecutedPriorToStaticHandlersWhenSetWithSamePriority()
{
$test = (object) array('results' => array());
StaticEventManager::getInstance()->attach(
Expand All @@ -73,7 +73,7 @@ function ($e) use ($test) {
$this->assertEquals(array('local', 'static'), $test->results);
}

public function testLocalHandlersAreExecutedPriorToStaticHandlersRegardlessOfPriority()
public function testLocalHandlersAreExecutedInPriorityOrderRegardlessOfStaticOrLocalRegistration()
{
$test = (object) array('results' => array());
StaticEventManager::getInstance()->attach(
Expand All @@ -95,7 +95,7 @@ function ($e) use ($test) {
$test->results[] = 'local3';
}, 15000); // highest priority
$class->foo();
$this->assertEquals(array('local3', 'local2', 'local', 'static'), $test->results);
$this->assertEquals(array('local3', 'static', 'local2', 'local'), $test->results);
}

public function testPassingNullValueToSetStaticConnectionsDisablesStaticConnections()
Expand Down Expand Up @@ -131,4 +131,23 @@ function ($e) use ($counter) {
$class->foo();
$this->assertEquals(0, $counter->count);
}

public function testTriggerMergesPrioritiesOfStaticAndInstanceListeners()
{
$test = (object) array('results' => array());
StaticEventManager::getInstance()->attach(
'ZendTest\EventManager\TestAsset\ClassWithEvents',
'foo',
function ($e) use ($test) {
$test->results[] = 'static';
},
100
);
$class = new TestAsset\ClassWithEvents();
$class->events()->attach('foo', function ($e) use ($test) {
$test->results[] = 'local';
}, -100);
$class->foo();
$this->assertEquals(array('static', 'local'), $test->results);
}
}
11 changes: 11 additions & 0 deletions test/TestAsset/Functor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

namespace ZendTest\EventManager\TestAsset;

class Functor
{
public function __invoke($e)
{
return __METHOD__;
}
}

0 comments on commit 55ef06c

Please sign in to comment.