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

Commit

Permalink
Merge branch 'master' of ssh://git.zendframework.com:21652/zf
Browse files Browse the repository at this point in the history
  • Loading branch information
Ralph Schindler committed Aug 30, 2011
15 parents 8210d1d + 0a08fc0 + 7d37340 + ab0ab2a + b9e0b9b + e1d4bda + e251276 + 161ba87 + f10c77c + 58cc6ef + cecfbb0 + c165fb8 + 1febb29 + 3325e48 + f700c30 commit 83086b6
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 109 deletions.
138 changes: 51 additions & 87 deletions src/EventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
/**
* Event manager: notification system
*
* Use the EventManager when you want to create a per-instance notification
* Use the EventManager when you want to create a per-instance notification
* system for your objects.
*
* @category Zend
Expand Down Expand Up @@ -66,10 +66,10 @@ class EventManager implements EventCollection
/**
* Constructor
*
* Allows optionally specifying an identifier to use to pull signals from a
* Allows optionally specifying an identifier to use to pull signals from a
* StaticEventManager.
*
* @param null|string|int $identifier
*
* @param null|string|int $identifier
* @return void
*/
public function __construct($identifier = null)
Expand All @@ -79,8 +79,8 @@ public function __construct($identifier = null)

/**
* Set the event class to utilize
*
* @param string $class
*
* @param string $class
* @return EventManager
*/
public function setEventClass($class)
Expand All @@ -91,8 +91,8 @@ public function setEventClass($class)

/**
* Set static connections container
*
* @param null|StaticEventCollection $connections
*
* @param null|StaticEventCollection $connections
* @return void
*/
public function setStaticConnections(StaticEventCollection $connections = null)
Expand All @@ -107,7 +107,7 @@ public function setStaticConnections(StaticEventCollection $connections = null)

/**
* Get static connections container
*
*
* @return false|StaticEventCollection
*/
public function getStaticConnections()
Expand All @@ -120,9 +120,9 @@ public function getStaticConnections()

/**
* Trigger all handlers for a given event
*
* @param string $event
* @param string|object $context Object calling emit, or symbol describing context (such as static method name)
*
* @param string $event
* @param string|object $context Object calling emit, or symbol describing context (such as static method name)
* @param array|ArrayAccess $argv Array of arguments; typically, should be associative
* @return ResponseCollection All handler return values
*/
Expand All @@ -134,16 +134,16 @@ public function trigger($event, $context, $argv = array())
}

/**
* Trigger handlers until return value of one causes a callback to
* Trigger handlers until return value of one causes a callback to
* evaluate to true
*
* Triggers handlers until the provided callback evaluates the return
* Triggers handlers until the provided callback evaluates the return
* value of one as true, or until all handlers have been executed.
*
* @param string $event
* @param string|object $context Object calling emit, or symbol describing context (such as static method name)
*
* @param string $event
* @param string|object $context Object calling emit, or symbol describing context (such as static method name)
* @param array|ArrayAccess $argv Array of arguments; typically, should be associative
* @param Callable $callback
* @param Callable $callback
* @throws InvalidCallbackException if invalid callback provided
*/
public function triggerUntil($event, $context, $argv, $callback)
Expand Down Expand Up @@ -181,18 +181,18 @@ public function triggerUntil($event, $context, $argv, $callback)
/**
* Attach a handler to an event
*
* The first argument is the event, and the next argument describes a
* callback that will respond to that event. A CallbackHandler instance
* The first argument is the event, and the next argument describes a
* callback that will respond to that event. A CallbackHandler instance
* describing the event handler combination will be returned.
*
* The last argument indicates a priority at which the event should be
* The last argument indicates a priority at which the event should be
* executed. By default, this value is 1; however, you may set it for any
* integer value. Higher values have higher priority (i.e., execute first).
*
*
* @param string $event
* @param callback $callback PHP callback
* @param int $priority If provided, the priority at which to register the callback
* @return HandlerAggregate|CallbackHandler (to allow later unsubscribe)
* @param int $priority If provided, the priority at which to register the callback
* @return HandlerAggregate (to allow later unsubscribe)
*/
public function attach($event, $callback, $priority = 1)
{
Expand All @@ -208,42 +208,21 @@ public function attach($event, $callback, $priority = 1)
* Attach a handler aggregate
*
* Handler aggregates accept an EventCollection instance, and call attach()
* one or more times, typically to attach to multiple events using local
* one or more times, typically to attach to multiple events using local
* methods.
*
* @param HandlerAggregate|string $aggregate
* @return HandlerAggregate
*
* @param HandlerAggregate $aggregate
* @return mixed return value of {@link HandlerAggregate::attach()}
*/
public function attachAggregate($aggregate)
public function attachAggregate(HandlerAggregate $aggregate)
{
if (is_string($aggregate)) {
// Class name?
if (!class_exists($aggregate)) {
// Class doesn't exist; probably didn't provide a context
throw new Exception\InvalidArgumentException(sprintf(
'No context provided for event "%s"',
$aggregate
));
}
// Create instance
$aggregate = new $aggregate();
}
if (!$aggregate instanceof HandlerAggregate) {
// Not an HandlerAggregate? We don't know how to handle it.
throw new Exception\InvalidArgumentException(
'Invalid class or object provided as event aggregate; must implement HandlerAggregate'
);
}

// Have the event aggregate wire itself, and return it.
$aggregate->attach($this);
return $aggregate;
return $aggregate->attach($this);
}

/**
* Unsubscribe a handler from an event
*
* @param CallbackHandler $handler
*
* @param CallbackHandler $handler
* @return bool Returns true if event and handle found, and unsubscribed; returns false if either event or handle not found
*/
public function detach(CallbackHandler $handler)
Expand All @@ -263,37 +242,22 @@ public function detach(CallbackHandler $handler)
}

/**
* Detach a callback aggregate
* Detach a handler aggregate
*
* Handler aggregates accept an EventCollection instance, and call detach()
* of all previously attached handlers.
*
* Loops through all handlers of all events to identify handlers that are
* represented by the aggregate; for all matches, the handlers will be
* removed.
*
* @param HandlerAggregate $aggregate
* @return bool
* @param HandlerAggregate $aggregate
* @return mixed return value of {@link HandlerAggregate::detach()}
*/
public function detachAggregate(HandlerAggregate $aggregate)
{
foreach ($this->events as $event => $handlers) {
foreach ($handlers as $key => $handler) {
$callback = $handler->getCallback();
if (is_object($callback)) {
if ($callback === $aggregate) {
$this->detach($handler);
}
} elseif (is_array($callback)) {
if ($callback[0] === $aggregate) {
$this->detach($handler);
}
}
}
}
return true;
return $aggregate->detach($this);
}

/**
* Retrieve all registered events
*
*
* @return array
*/
public function getEvents()
Expand All @@ -303,8 +267,8 @@ public function getEvents()

/**
* Retrieve all handlers for a given event
*
* @param string $event
*
* @param string $event
* @return PriorityQueue
*/
public function getHandlers($event)
Expand All @@ -317,8 +281,8 @@ public function getHandlers($event)

/**
* Clear all handlers for a given event
*
* @param string $event
*
* @param string $event
* @return void
*/
public function clearHandlers($event)
Expand All @@ -332,10 +296,10 @@ public function clearHandlers($event)
* Prepare arguments
*
* Use this method if you want to be able to modify arguments from within a
* handler. It returns an ArrayObject of the arguments, which may then be
* handler. It returns an ArrayObject of the arguments, which may then be
* passed to trigger() or triggerUntil().
*
* @param array $args
*
* @param array $args
* @return ArrayObject
*/
public function prepareArgs(array $args)
Expand All @@ -345,10 +309,10 @@ public function prepareArgs(array $args)

/**
* Emit handlers matching the current identifier found in the static handler
*
* @param callback $callback
* @param Event $event
* @param ResponseCollection $responses
*
* @param callback $callback
* @param Event $event
* @param ResponseCollection $responses
* @return ResponseCollection
*/
protected function triggerStaticHandlers($callback, Event $event, ResponseCollection $responses)
Expand Down
16 changes: 15 additions & 1 deletion src/HandlerAggregate.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
* Interface for self-registering event handlers.
*
* Classes implementing this interface may be registered by name or instance
* with an EventManager, without an event name. The {@link connect()} method will
* with an EventManager, without an event name. The {@link attach()} method will
* then be called with the current EventManager instance, allowing the class to
* wire up one or more handlers.
*
Expand All @@ -38,5 +38,19 @@
*/
interface HandlerAggregate
{

/**
* Attach one or more handlers
*
* @param EventCollection $events
*/
public function attach(EventCollection $events);

/**
* Detach all previously attached handlers
*
* @param EventCollection $events
*/
public function detach(EventCollection $events);

}
31 changes: 12 additions & 19 deletions test/EventManagerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ public function testResponseCollectionIsNotStoppedWhenNoCallbackMatchedByTrigger
$this->assertEquals('zero', $responses->last());
}

public function testCanAttachAggregateInstances()
public function testCanAttachHandlerAggregate()
{
$aggregate = new TestAsset\MockAggregate();
$this->events->attachAggregate($aggregate);
Expand All @@ -224,26 +224,11 @@ public function testCanAttachAggregateInstances()
}
}

public function testHandlerAggregateReturnedByAttachAggregate()
public function testAttachAggregateReturnsAttachOfHandlerAggregate()
{
$aggregate = new TestAsset\MockAggregate();
$test = $this->events->attachAggregate($aggregate);
$this->assertSame($aggregate, $test);
}

public function testAttachAggregateAllowsPassingAHandlerAggregateClassName()
{
$this->events->attachAggregate('ZendTest\EventManager\TestAsset\MockAggregate');
$events = $this->events->getEvents();
foreach (array('foo.bar', 'foo.baz') as $event) {
$this->assertContains($event, $events);
}
}

public function testPassingClassNameToAttachAggregateReturnsHandlerAggregateInstance()
{
$test = $this->events->attachAggregate('ZendTest\EventManager\TestAsset\MockAggregate');
$this->assertInstanceOf('ZendTest\EventManager\TestAsset\MockAggregate', $test);
$method = $this->events->attachAggregate($aggregate);
$this->assertSame('ZendTest\EventManager\TestAsset\MockAggregate::attach', $method);
}

public function testCanDetachHandlerAggregates()
Expand Down Expand Up @@ -276,6 +261,14 @@ public function testCanDetachHandlerAggregates()
$this->assertContains($handlerOther, $handlers);
}

public function testDetachAggregateReturnsDetachOfHandlerAggregate()
{
$aggregate = new TestAsset\MockAggregate();
$this->events->attachAggregate($aggregate);
$method = $this->events->detachAggregate($aggregate);
$this->assertSame('ZendTest\EventManager\TestAsset\MockAggregate::detach', $method);
}

public function testCallingEventsStopPropagationMethodHaltsEventEmission()
{
$this->events->attach('foo.bar', function ($e) { return 'bogus'; }, 4);
Expand Down
21 changes: 19 additions & 2 deletions test/TestAsset/MockAggregate.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,27 @@
*/
class MockAggregate implements HandlerAggregate
{

protected $handles = array();

public function attach(EventCollection $events)
{
$events->attach('foo.bar', array( $this, 'fooBar' ));
$events->attach('foo.baz', array( $this, 'fooBaz' ));
$handles = array();
$handles[] = $events->attach('foo.bar', array( $this, 'fooBar' ));
$handles[] = $events->attach('foo.baz', array( $this, 'fooBaz' ));

$this->handles[ \spl_object_hash($events) ] = $handles;

return __METHOD__;
}

public function detach(EventCollection $events)
{
foreach ($this->handles[ \spl_object_hash($events) ] as $handle) {
$events->detach($handle);
}

return __METHOD__;
}

public function fooBar()
Expand Down

0 comments on commit 83086b6

Please sign in to comment.