diff --git a/benchmarks/ZendBenchmark/EventManager/AttachBenchmark.php b/benchmarks/ZendBenchmark/EventManager/AttachBenchmark.php
new file mode 100644
index 00000000000..f11ee6f4153
--- /dev/null
+++ b/benchmarks/ZendBenchmark/EventManager/AttachBenchmark.php
@@ -0,0 +1,45 @@
+eventManager = new EventManager();
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function attachOneThousandListeners()
+ {
+ for ($i = 0 ; $i != 1000 ; ++$i) {
+ $this->eventManager->attach('eventName', function() {;});
+ }
+ }
+}
diff --git a/benchmarks/ZendBenchmark/EventManager/TriggerEvmBenchmark.php b/benchmarks/ZendBenchmark/EventManager/TriggerEvmBenchmark.php
new file mode 100644
index 00000000000..a13f43a75bd
--- /dev/null
+++ b/benchmarks/ZendBenchmark/EventManager/TriggerEvmBenchmark.php
@@ -0,0 +1,86 @@
+eventManager = new EventManager();
+
+ // Add one hundred listeners to two different events with random priorities
+ for ($i = 0 ; $i != 100 ; ++$i) {
+ $this->eventManager->attach('eventName1', function() {}, rand(0, 100));
+ $this->eventManager->attach('eventName2', function() {}, rand(0, 100));
+ }
+
+ // Attach also fifty listeners to the wildcard
+ for ($i = 0 ; $i != 10 ; ++$i) {
+ $this->eventManager->attach('*', function() {}, rand(0, 100));
+ }
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventOneTimeWithoutSharedManager()
+ {
+ $this->eventManager->trigger('eventName1');
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventOneTimeWithEmptySharedManager()
+ {
+ $this->eventManager->setSharedManager(new SharedEventManager());
+ $this->eventManager->trigger('eventName1');
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventTenTimesWithoutSharedManager()
+ {
+ for ($i = 0 ; $i !== 10 ; ++$i) {
+ $this->eventManager->trigger('eventName1');
+ }
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventTenTimesWithEmptySharedManager()
+ {
+ $this->eventManager->setSharedManager(new SharedEventManager());
+
+ for ($i = 0 ; $i !== 10 ; ++$i) {
+ $this->eventManager->trigger('eventName1');
+ }
+ }
+}
diff --git a/benchmarks/ZendBenchmark/EventManager/TriggerEvmWithSemBenchmark.php b/benchmarks/ZendBenchmark/EventManager/TriggerEvmWithSemBenchmark.php
new file mode 100644
index 00000000000..dd6ef9f7ec0
--- /dev/null
+++ b/benchmarks/ZendBenchmark/EventManager/TriggerEvmWithSemBenchmark.php
@@ -0,0 +1,81 @@
+eventManager = new EventManager();
+ $this->sharedManager = new SharedEventManager();
+
+ $this->eventManager->setIdentifiers(['identifier1', 'identifier2']);
+ $this->eventManager->setSharedManager($this->sharedManager);
+
+ // Add fifty listeners to two different events with random priorities in the EVM and SEM
+ for ($i = 0 ; $i != 50 ; ++$i) {
+ $this->eventManager->attach('eventName1', function() {}, rand(0, 100));
+ $this->eventManager->attach('eventName2', function() {}, rand(0, 100));
+
+ $this->sharedManager->attach('identifier1', 'eventName1', function() {}, rand(0, 100));
+ $this->sharedManager->attach('identifier2', 'eventName1', function() {}, rand(0, 100));
+ $this->sharedManager->attach('identifier3', 'eventName1', function() {}, rand(0, 100));
+ }
+
+ // Attach also fifty listeners to the wildcard
+ for ($i = 0 ; $i != 10 ; ++$i) {
+ $this->eventManager->attach('*', function() {}, rand(0, 100));
+ $this->sharedManager->attach('*', 'eventName1', function() {}, rand(0, 100));
+ $this->sharedManager->attach('identifier1', '*', function() {}, rand(0, 100));
+ $this->sharedManager->attach('*', '*', function() {}, rand(0, 100));
+ }
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventOneTime()
+ {
+ $this->eventManager->trigger('eventName1');
+ }
+
+ /**
+ * @iterations 50
+ */
+ public function triggerEventTenTimes()
+ {
+ for ($i = 0 ; $i !== 10 ; ++$i) {
+ $this->eventManager->trigger('eventName1');
+ }
+ }
+}
diff --git a/composer.json b/composer.json
index b165a6b9b04..099b525ef72 100644
--- a/composer.json
+++ b/composer.json
@@ -12,6 +12,7 @@
"php": ">=5.3.3"
},
"require-dev": {
+ "athletic/athletic": "0.1.7",
"doctrine/annotations": ">=1.0",
"ircmaxell/random-lib": "dev-master",
"ircmaxell/security-lib": "dev-master",
@@ -29,6 +30,12 @@
"autoload": {
"psr-0": {
"Zend\\": "library/"
+
+ }
+ },
+ "autoload-dev": {
+ "psr-0": {
+ "ZendBenchmark\\": "benchmarks/"
}
},
"bin": [
diff --git a/demos/bench-evm.php b/demos/bench-evm.php
new file mode 100644
index 00000000000..65a6c6858a0
--- /dev/null
+++ b/demos/bench-evm.php
@@ -0,0 +1,61 @@
+attach('event', 'emptyFunc', $i % 10);
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d\n", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+echo "Triggers {$numberOfTriggers} events: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $eventManager->trigger('event');
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d\n", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+$sharedManager = new \Zend\EventManager\SharedEventManager();
+$eventManager->setSharedManager($sharedManager);
+
+echo "Attach {$numberOfListeners} shared listeners: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $sharedManager->attach('myid1', 'event', 'emptyFunc', $i % 10);
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d\n", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+echo "Triggers {$numberOfTriggers} events: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $eventManager->trigger('event');
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d\n", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+printf("\nTotal: time=%f, mem=%d\n", microtime(true) - $totalTimeStart, memory_get_peak_usage(true));
diff --git a/demos/index.php b/demos/index.php
new file mode 100644
index 00000000000..b0d86479ccf
--- /dev/null
+++ b/demos/index.php
@@ -0,0 +1,61 @@
+attach('event', 'emptyFunc', $i);
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d
", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+echo "Triggers {$numberOfTriggers} events: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $eventManager->trigger('event');
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d
", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+$sharedManager = new \Zend\EventManager\SharedEventManager();
+$eventManager->setSharedManager($sharedManager);
+
+echo "Attach {$numberOfListeners} shared listeners: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $sharedManager->attach('myid', 'event', 'emptyFunc', $i);
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d
", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+echo "Triggers {$numberOfTriggers} events: ";
+$memStart = memory_get_usage();
+$timeStart = microtime(true);
+for ($i = 0; $i < $numberOfListeners; ++$i) {
+ $eventManager->trigger('event');
+}
+$timeEnd = microtime(true);
+$memEnd = memory_get_usage(true);
+printf("time=%f, mem=%d
", $timeEnd - $timeStart, $memEnd - $memStart);
+
+
+printf("
Total: time=%f, mem=%d\n", microtime(true) - $totalTimeStart, memory_get_peak_usage(true));
diff --git a/library/Zend/Db/TableGateway/Feature/EventFeature/TableGatewayEvent.php b/library/Zend/Db/TableGateway/Feature/EventFeature/TableGatewayEvent.php
index af7531eeffd..2ff5a07512d 100644
--- a/library/Zend/Db/TableGateway/Feature/EventFeature/TableGatewayEvent.php
+++ b/library/Zend/Db/TableGateway/Feature/EventFeature/TableGatewayEvent.php
@@ -133,7 +133,7 @@ public function stopPropagation($flag = true)
*
* @return bool
*/
- public function propagationIsStopped()
+ public function isPropagationStopped()
{
return false;
}
diff --git a/library/Zend/EventManager/AbstractListenerAggregate.php b/library/Zend/EventManager/AbstractListenerAggregate.php
index 4d4a443d0d8..491d88f088d 100644
--- a/library/Zend/EventManager/AbstractListenerAggregate.php
+++ b/library/Zend/EventManager/AbstractListenerAggregate.php
@@ -9,26 +9,7 @@
namespace Zend\EventManager;
-
-/**
- * Abstract aggregate listener
- */
abstract class AbstractListenerAggregate implements ListenerAggregateInterface
{
- /**
- * @var \Zend\Stdlib\CallbackHandler[]
- */
- protected $listeners = array();
-
- /**
- * {@inheritDoc}
- */
- public function detach(EventManagerInterface $events)
- {
- foreach ($this->listeners as $index => $callback) {
- if ($events->detach($callback)) {
- unset($this->listeners[$index]);
- }
- }
- }
+ use ListenerAggregateTrait;
}
diff --git a/library/Zend/EventManager/Event.php b/library/Zend/EventManager/Event.php
index 31037b9f14f..a9f0eb9ca74 100644
--- a/library/Zend/EventManager/Event.php
+++ b/library/Zend/EventManager/Event.php
@@ -9,7 +9,7 @@
namespace Zend\EventManager;
-use ArrayAccess;
+use Traversable;
/**
* Representation of an event
@@ -19,20 +19,15 @@
*/
class Event implements EventInterface
{
- /**
- * @var string Event name
- */
- protected $name;
-
/**
* @var string|object The event target
*/
protected $target;
/**
- * @var array|ArrayAccess|object The event parameters
+ * @var array The event parameters
*/
- protected $params = array();
+ protected $params = [];
/**
* @var bool Whether or not to stop propagation
@@ -44,19 +39,12 @@ class Event implements EventInterface
*
* Accept a target and its parameters.
*
- * @param string $name Event name
- * @param string|object $target
- * @param array|ArrayAccess $params
+ * @param string|object $target
+ * @param array|Traversable $params
*/
- public function __construct($name = null, $target = null, $params = null)
+ public function __construct($target = null, $params = null)
{
- if (null !== $name) {
- $this->setName($name);
- }
-
- if (null !== $target) {
- $this->setTarget($target);
- }
+ $this->setTarget($target);
if (null !== $params) {
$this->setParams($params);
@@ -64,21 +52,17 @@ public function __construct($name = null, $target = null, $params = null)
}
/**
- * Get event name
- *
- * @return string
+ * {@inheritDoc}
*/
- public function getName()
+ public function setTarget($target)
{
- return $this->name;
+ $this->target = $target;
}
/**
- * Get the event target
+ * {@inheritDoc}
*
* This may be either an object, or the name of a static method.
- *
- * @return string|object
*/
public function getTarget()
{
@@ -86,111 +70,47 @@ public function getTarget()
}
/**
- * Set parameters
- *
- * Overwrites parameters
- *
- * @param array|ArrayAccess|object $params
- * @return Event
- * @throws Exception\InvalidArgumentException
+ * {@inheritDoc}
*/
public function setParams($params)
{
- if (!is_array($params) && !is_object($params)) {
- throw new Exception\InvalidArgumentException(sprintf(
- 'Event parameters must be an array or object; received "%s"', gettype($params)
- ));
+ if ($params instanceof Traversable) {
+ $params = iterator_to_array($params);
}
$this->params = $params;
- return $this;
}
/**
- * Get all parameters
- *
- * @return array|object|ArrayAccess
- */
- public function getParams()
- {
- return $this->params;
- }
-
- /**
- * Get an individual parameter
- *
- * If the parameter does not exist, the $default value will be returned.
- *
- * @param string|int $name
- * @param mixed $default
- * @return mixed
+ * {@inheritDoc}
*/
- public function getParam($name, $default = null)
- {
- // Check in params that are arrays or implement array access
- if (is_array($this->params) || $this->params instanceof ArrayAccess) {
- if (!isset($this->params[$name])) {
- return $default;
- }
-
- return $this->params[$name];
- }
-
- // Check in normal objects
- if (!isset($this->params->{$name})) {
- return $default;
- }
- return $this->params->{$name};
- }
-
- /**
- * Set the event name
- *
- * @param string $name
- * @return Event
- */
- public function setName($name)
+ public function setParam($name, $value)
{
- $this->name = (string) $name;
- return $this;
+ $this->params[$name] = $value;
}
/**
- * Set the event target/context
- *
- * @param null|string|object $target
- * @return Event
+ * {@inheritDoc}
*/
- public function setTarget($target)
+ public function getParams()
{
- $this->target = $target;
- return $this;
+ return $this->params;
}
/**
- * Set an individual parameter to a value
- *
- * @param string|int $name
- * @param mixed $value
- * @return Event
+ * {@inheritDoc}
*/
- public function setParam($name, $value)
+ public function getParam($name, $default = null)
{
- if (is_array($this->params) || $this->params instanceof ArrayAccess) {
- // Arrays or objects implementing array access
- $this->params[$name] = $value;
- } else {
- // Objects
- $this->params->{$name} = $value;
+ if (!isset($this->params[$name])) {
+ return $default;
}
- return $this;
+
+ return $this->params[$name];
}
/**
- * Stop further event propagation
- *
- * @param bool $flag
- * @return void
+ * {@inheritDoc}
*/
public function stopPropagation($flag = true)
{
@@ -198,11 +118,9 @@ public function stopPropagation($flag = true)
}
/**
- * Is propagation stopped?
- *
- * @return bool
+ * {@inheritDoc}
*/
- public function propagationIsStopped()
+ public function isPropagationStopped()
{
return $this->stopPropagation;
}
diff --git a/library/Zend/EventManager/EventInterface.php b/library/Zend/EventManager/EventInterface.php
index 7974f6e9ac8..518a8ae51d2 100644
--- a/library/Zend/EventManager/EventInterface.php
+++ b/library/Zend/EventManager/EventInterface.php
@@ -9,7 +9,7 @@
namespace Zend\EventManager;
-use ArrayAccess;
+use Traversable;
/**
* Representation of an event
@@ -17,11 +17,12 @@
interface EventInterface
{
/**
- * Get event name
+ * Set the event target/context
*
- * @return string
+ * @param null|string|object $target
+ * @return void
*/
- public function getName();
+ public function setTarget($target);
/**
* Get target/context from which event was triggered
@@ -31,53 +32,37 @@ public function getName();
public function getTarget();
/**
- * Get parameters passed to the event
- *
- * @return array|ArrayAccess
- */
- public function getParams();
-
- /**
- * Get a single parameter by name
- *
- * @param string $name
- * @param mixed $default Default value to return if parameter does not exist
- * @return mixed
- */
- public function getParam($name, $default = null);
-
- /**
- * Set the event name
+ * Set event parameters (overwrite parameters)
*
- * @param string $name
+ * @param array|Traversable $params
* @return void
*/
- public function setName($name);
+ public function setParams($params);
/**
- * Set the event target/context
+ * Set a single parameter by key
*
- * @param null|string|object $target
+ * @param string $name
+ * @param mixed $value
* @return void
*/
- public function setTarget($target);
+ public function setParam($name, $value);
/**
- * Set event parameters
+ * Get parameters passed to the event
*
- * @param string $params
- * @return void
+ * @return array
*/
- public function setParams($params);
+ public function getParams();
/**
- * Set a single parameter by key
+ * Get a single parameter by name
*
* @param string $name
- * @param mixed $value
- * @return void
+ * @param mixed $default Default value to return if parameter does not exist
+ * @return mixed
*/
- public function setParam($name, $value);
+ public function getParam($name, $default = null);
/**
* Indicate whether or not the parent EventManagerInterface should stop propagating events
@@ -92,5 +77,5 @@ public function stopPropagation($flag = true);
*
* @return bool
*/
- public function propagationIsStopped();
+ public function isPropagationStopped();
}
diff --git a/library/Zend/EventManager/EventManager.php b/library/Zend/EventManager/EventManager.php
index de51b1e96ad..0fbe4183bb0 100644
--- a/library/Zend/EventManager/EventManager.php
+++ b/library/Zend/EventManager/EventManager.php
@@ -9,11 +9,8 @@
namespace Zend\EventManager;
-use ArrayAccess;
use ArrayObject;
use Traversable;
-use Zend\Stdlib\CallbackHandler;
-use Zend\Stdlib\PriorityQueue;
/**
* Event manager: notification system
@@ -21,28 +18,19 @@
* Use the EventManager when you want to create a per-instance notification
* system for your objects.
*/
-class EventManager implements EventManagerInterface
+class EventManager extends FastEventManager implements SharedEventManagerAwareInterface
{
- /**
- * Subscribed events and their listeners
- * @var array Array of PriorityQueue objects
- */
- protected $events = array();
-
- /**
- * @var string Class representing the event being emitted
- */
- protected $eventClass = 'Zend\EventManager\Event';
-
/**
* Identifiers, used to pull shared signals from SharedEventManagerInterface instance
+ *
* @var array
*/
- protected $identifiers = array();
+ protected $identifiers = [];
/**
* Shared event manager
- * @var false|null|SharedEventManagerInterface
+ *
+ * @var null|SharedEventManagerInterface
*/
protected $sharedManager = null;
@@ -56,208 +44,37 @@ class EventManager implements EventManagerInterface
*/
public function __construct($identifiers = null)
{
- $this->setIdentifiers($identifiers);
- }
-
- /**
- * Set the event class to utilize
- *
- * @param string $class
- * @return EventManager
- */
- public function setEventClass($class)
- {
- $this->eventClass = $class;
- return $this;
+ if ($identifiers) {
+ $this->setIdentifiers($identifiers);
+ }
}
/**
* Set shared event manager
*
- * @param SharedEventManagerInterface $sharedEventManager
- * @return EventManager
+ * @param SharedEventManagerInterface $sharedEventManager
+ * @return void
*/
public function setSharedManager(SharedEventManagerInterface $sharedEventManager)
{
$this->sharedManager = $sharedEventManager;
- StaticEventManager::setInstance($sharedEventManager);
- return $this;
- }
-
- /**
- * Remove any shared event manager currently attached
- *
- * @return void
- */
- public function unsetSharedManager()
- {
- $this->sharedManager = false;
}
/**
* Get shared event manager
*
- * If one is not defined, but we have a static instance in
- * StaticEventManager, that one will be used and set in this instance.
- *
- * If none is available in the StaticEventManager, a boolean false is
- * returned.
- *
- * @return false|SharedEventManagerInterface
+ * @return SharedEventManagerInterface|null
*/
public function getSharedManager()
{
- // "false" means "I do not want a shared manager; don't try and fetch one"
- if (false === $this->sharedManager
- || $this->sharedManager instanceof SharedEventManagerInterface
- ) {
- return $this->sharedManager;
- }
-
- if (!StaticEventManager::hasInstance()) {
- return false;
- }
-
- $this->sharedManager = StaticEventManager::getInstance();
return $this->sharedManager;
}
- /**
- * Get the identifier(s) for this EventManager
- *
- * @return array
- */
- public function getIdentifiers()
- {
- return $this->identifiers;
- }
-
- /**
- * Set the identifiers (overrides any currently set identifiers)
- *
- * @param string|int|array|Traversable $identifiers
- * @return EventManager Provides a fluent interface
- */
- public function setIdentifiers($identifiers)
- {
- if (is_array($identifiers) || $identifiers instanceof Traversable) {
- $this->identifiers = array_unique((array) $identifiers);
- } elseif ($identifiers !== null) {
- $this->identifiers = array($identifiers);
- }
- return $this;
- }
-
- /**
- * Add some identifier(s) (appends to any currently set identifiers)
- *
- * @param string|int|array|Traversable $identifiers
- * @return EventManager Provides a fluent interface
- */
- public function addIdentifiers($identifiers)
- {
- if (is_array($identifiers) || $identifiers instanceof Traversable) {
- $this->identifiers = array_unique(array_merge($this->identifiers, (array) $identifiers));
- } elseif ($identifiers !== null) {
- $this->identifiers = array_unique(array_merge($this->identifiers, array($identifiers)));
- }
- return $this;
- }
-
- /**
- * Trigger all listeners for a given event
- *
- * Can emulate triggerUntil() if the last argument provided is a callback.
- *
- * @param string $event
- * @param string|object $target Object calling emit, or symbol describing target (such as static method name)
- * @param array|ArrayAccess $argv Array of arguments; typically, should be associative
- * @param null|callable $callback
- * @return ResponseCollection All listener return values
- * @throws Exception\InvalidCallbackException
- */
- public function trigger($event, $target = null, $argv = array(), $callback = null)
- {
- if ($event instanceof EventInterface) {
- $e = $event;
- $event = $e->getName();
- $callback = $target;
- } elseif ($target instanceof EventInterface) {
- $e = $target;
- $e->setName($event);
- $callback = $argv;
- } elseif ($argv instanceof EventInterface) {
- $e = $argv;
- $e->setName($event);
- $e->setTarget($target);
- } else {
- $e = new $this->eventClass();
- $e->setName($event);
- $e->setTarget($target);
- $e->setParams($argv);
- }
-
- if ($callback && !is_callable($callback)) {
- throw new Exception\InvalidCallbackException('Invalid callback provided');
- }
-
- // Initial value of stop propagation flag should be false
- $e->stopPropagation(false);
-
- return $this->triggerListeners($event, $e, $callback);
- }
-
- /**
- * Trigger listeners until return value of one causes a callback to
- * evaluate to true
- *
- * Triggers listeners until the provided callback evaluates the return
- * value of one as true, or until all listeners have been executed.
- *
- * @param string $event
- * @param string|object $target Object calling emit, or symbol describing target (such as static method name)
- * @param array|ArrayAccess $argv Array of arguments; typically, should be associative
- * @param callable $callback
- * @return ResponseCollection
- * @throws Exception\InvalidCallbackException if invalid callable provided
- */
- public function triggerUntil($event, $target, $argv = null, $callback = null)
- {
- if ($event instanceof EventInterface) {
- $e = $event;
- $event = $e->getName();
- $callback = $target;
- } elseif ($target instanceof EventInterface) {
- $e = $target;
- $e->setName($event);
- $callback = $argv;
- } elseif ($argv instanceof EventInterface) {
- $e = $argv;
- $e->setName($event);
- $e->setTarget($target);
- } else {
- $e = new $this->eventClass();
- $e->setName($event);
- $e->setTarget($target);
- $e->setParams($argv);
- }
-
- if (!is_callable($callback)) {
- throw new Exception\InvalidCallbackException('Invalid callback provided');
- }
-
- // Initial value of stop propagation flag should be false
- $e->stopPropagation(false);
-
- return $this->triggerListeners($event, $e, $callback);
- }
-
/**
* Attach a listener 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
- * describing the event listener combination will be returned.
+ * callback that will respond to that event.
*
* 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
@@ -266,285 +83,72 @@ public function triggerUntil($event, $target, $argv = null, $callback = null)
* You can specify "*" for the event name. In such cases, the listener will
* be triggered for every event.
*
- * @param string|array|ListenerAggregateInterface $event An event or array of event names. If a ListenerAggregateInterface, proxies to {@link attachAggregate()}.
- * @param callable|int $callback If string $event provided, expects PHP callback; for a ListenerAggregateInterface $event, this will be the priority
- * @param int $priority If provided, the priority at which to register the callable
- * @return CallbackHandler|mixed CallbackHandler if attaching callable (to allow later unsubscribe); mixed if attaching aggregate
- * @throws Exception\InvalidArgumentException
+ * @param string $eventName An event or array of event names
+ * @param callable $listener
+ * @param int $priority If provided, the priority at which to register the callable
+ * @return callable if attaching callable (to allow later unsubscribe)
*/
- public function attach($event, $callback = null, $priority = 1)
+ public function attach($eventName, callable $listener, $priority = 1)
{
- // Proxy ListenerAggregateInterface arguments to attachAggregate()
- if ($event instanceof ListenerAggregateInterface) {
- return $this->attachAggregate($event, $callback);
- }
+ // The '.0' is a hack that allows to circumvent the fact that array_merge remove
+ // any numeric key
+ $this->events[$eventName][(int) $priority . '.0'][] = $listener;
- // Null callback is invalid
- if (null === $callback) {
- throw new Exception\InvalidArgumentException(sprintf(
- '%s: expects a callback; none provided',
- __METHOD__
- ));
- }
-
- // Array of events should be registered individually, and return an array of all listeners
- if (is_array($event)) {
- $listeners = array();
- foreach ($event as $name) {
- $listeners[] = $this->attach($name, $callback, $priority);
- }
- return $listeners;
- }
-
- // If we don't have a priority queue for the event yet, create one
- if (empty($this->events[$event])) {
- $this->events[$event] = new PriorityQueue();
- }
-
- // Create a callback handler, setting the event and priority in its metadata
- $listener = new CallbackHandler($callback, array('event' => $event, 'priority' => $priority));
-
- // Inject the callback handler into the queue
- $this->events[$event]->insert($listener, $priority);
return $listener;
}
/**
- * Attach a listener aggregate
- *
- * Listener aggregates accept an EventManagerInterface instance, and call attach()
- * one or more times, typically to attach to multiple events using local
- * methods.
- *
- * @param ListenerAggregateInterface $aggregate
- * @param int $priority If provided, a suggested priority for the aggregate to use
- * @return mixed return value of {@link ListenerAggregateInterface::attach()}
- */
- public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1)
- {
- return $aggregate->attach($this, $priority);
- }
-
- /**
- * Unsubscribe a listener from an event
- *
- * @param CallbackHandler|ListenerAggregateInterface $listener
- * @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
- * @throws Exception\InvalidArgumentException if invalid listener provided
+ * {@inheritDoc}
*/
- public function detach($listener)
+ public function getListeners($eventName)
{
- if ($listener instanceof ListenerAggregateInterface) {
- return $this->detachAggregate($listener);
- }
+ // retrieve listeners
+ $listeners = isset($this->events[$eventName]) ? $this->events[$eventName] : [];
- if (!$listener instanceof CallbackHandler) {
- throw new Exception\InvalidArgumentException(sprintf(
- '%s: expected a ListenerAggregateInterface or CallbackHandler; received "%s"',
- __METHOD__,
- (is_object($listener) ? get_class($listener) : gettype($listener))
- ));
- }
+ // retrieve wildcard listeners
+ $wildcardListeners = isset($this->events['*']) ? $this->events['*'] : [];
- $event = $listener->getMetadatum('event');
- if (!$event || empty($this->events[$event])) {
- return false;
- }
- $return = $this->events[$event]->remove($listener);
- if (!$return) {
- return false;
- }
- if (!count($this->events[$event])) {
- unset($this->events[$event]);
- }
- return true;
- }
-
- /**
- * Detach a listener aggregate
- *
- * Listener aggregates accept an EventManagerInterface instance, and call detach()
- * of all previously attached listeners.
- *
- * @param ListenerAggregateInterface $aggregate
- * @return mixed return value of {@link ListenerAggregateInterface::detach()}
- */
- public function detachAggregate(ListenerAggregateInterface $aggregate)
- {
- return $aggregate->detach($this);
- }
-
- /**
- * Retrieve all registered events
- *
- * @return array
- */
- public function getEvents()
- {
- return array_keys($this->events);
- }
-
- /**
- * Retrieve all listeners for a given event
- *
- * @param string $event
- * @return PriorityQueue
- */
- public function getListeners($event)
- {
- if (!array_key_exists($event, $this->events)) {
- return new PriorityQueue();
- }
- return $this->events[$event];
- }
+ // retrieve shared manager listeners
+ $sharedListeners = (null !== $this->sharedManager)
+ ? $this->sharedManager->getListeners($this->identifiers, $eventName)
+ : [];
- /**
- * Clear all listeners for a given event
- *
- * @param string $event
- * @return void
- */
- public function clearListeners($event)
- {
- if (!empty($this->events[$event])) {
- unset($this->events[$event]);
- }
- }
+ // merge
+ $listeners = array_merge_recursive($listeners, $wildcardListeners, $sharedListeners);
+ krsort($listeners, SORT_NUMERIC);
- /**
- * Prepare arguments
- *
- * Use this method if you want to be able to modify arguments from within a
- * listener. It returns an ArrayObject of the arguments, which may then be
- * passed to trigger() or triggerUntil().
- *
- * @param array $args
- * @return ArrayObject
- */
- public function prepareArgs(array $args)
- {
- return new ArrayObject($args);
+ return $listeners;
}
/**
- * Trigger listeners
- *
- * Actual functionality for triggering listeners, to which both trigger() and triggerUntil()
- * delegate.
- *
- * @param string $event Event name
- * @param EventInterface $e
- * @param null|callable $callback
- * @return ResponseCollection
+ * {@inheritDoc}
*/
- protected function triggerListeners($event, EventInterface $e, $callback = null)
+ public function setIdentifiers($identifiers)
{
- $responses = new ResponseCollection;
- $listeners = $this->getListeners($event);
-
- // Add shared/wildcard listeners to the list of listeners,
- // but don't modify the listeners object
- $sharedListeners = $this->getSharedListeners($event);
- $sharedWildcardListeners = $this->getSharedListeners('*');
- $wildcardListeners = $this->getListeners('*');
- if (count($sharedListeners) || count($sharedWildcardListeners) || count($wildcardListeners)) {
- $listeners = clone $listeners;
-
- // Shared listeners on this specific event
- $this->insertListeners($listeners, $sharedListeners);
-
- // Shared wildcard listeners
- $this->insertListeners($listeners, $sharedWildcardListeners);
-
- // Add wildcard listeners
- $this->insertListeners($listeners, $wildcardListeners);
+ if ($identifiers instanceof Traversable) {
+ $identifiers = iterator_to_array($identifiers);
}
- foreach ($listeners as $listener) {
- $listenerCallback = $listener->getCallback();
-
- // Trigger the listener's callback, and push its result onto the
- // response collection
- $responses->push(call_user_func($listenerCallback, $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 ($callback && call_user_func($callback, $responses->last())) {
- $responses->setStopped(true);
- break;
- }
- }
-
- return $responses;
+ $this->identifiers = (array) $identifiers;
}
/**
- * Get list of all listeners attached to the shared event manager for
- * identifiers registered by this instance
- *
- * @param string $event
- * @return array
+ * {@inheritDoc}
*/
- protected function getSharedListeners($event)
+ public function addIdentifiers($identifiers)
{
- if (!$sharedManager = $this->getSharedManager()) {
- return array();
+ if ($identifiers instanceof Traversable) {
+ $identifiers = iterator_to_array($identifiers);
}
- $identifiers = $this->getIdentifiers();
- //Add wildcard id to the search, if not already added
- if (!in_array('*', $identifiers)) {
- $identifiers[] = '*';
- }
- $sharedListeners = array();
-
- foreach ($identifiers as $id) {
- if (!$listeners = $sharedManager->getListeners($id, $event)) {
- continue;
- }
-
- if (!is_array($listeners) && !($listeners instanceof Traversable)) {
- continue;
- }
-
- foreach ($listeners as $listener) {
- if (!$listener instanceof CallbackHandler) {
- continue;
- }
- $sharedListeners[] = $listener;
- }
- }
-
- return $sharedListeners;
+ $this->identifiers = array_unique(array_merge($this->identifiers, $identifiers));
}
/**
- * Add listeners to the master queue of listeners
- *
- * Used to inject shared listeners and wildcard listeners.
- *
- * @param PriorityQueue $masterListeners
- * @param PriorityQueue $listeners
- * @return void
+ * {@inheritDoc}
*/
- protected function insertListeners($masterListeners, $listeners)
+ public function getIdentifiers()
{
- foreach ($listeners as $listener) {
- $priority = $listener->getMetadatum('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);
- }
- $masterListeners->insert($listener, $priority);
- }
+ return $this->identifiers;
}
}
diff --git a/library/Zend/EventManager/EventManagerAwareInterface.php b/library/Zend/EventManager/EventManagerAwareInterface.php
index 16d8ba921be..720d36ac6ca 100644
--- a/library/Zend/EventManager/EventManagerAwareInterface.php
+++ b/library/Zend/EventManager/EventManagerAwareInterface.php
@@ -10,9 +10,9 @@
namespace Zend\EventManager;
/**
- * Interface to automate setter injection for an EventManager instance
+ * Interface for objects that are aware of an event manager
*/
-interface EventManagerAwareInterface extends EventsCapableInterface
+interface EventManagerAwareInterface
{
/**
* Inject an EventManager instance
@@ -21,4 +21,13 @@ interface EventManagerAwareInterface extends EventsCapableInterface
* @return void
*/
public function setEventManager(EventManagerInterface $eventManager);
+
+ /**
+ * Retrieve the event manager
+ *
+ * Lazy-loads an EventManager instance if none registered.
+ *
+ * @return EventManagerInterface
+ */
+ public function getEventManager();
}
diff --git a/library/Zend/EventManager/EventManagerAwareTrait.php b/library/Zend/EventManager/EventManagerAwareTrait.php
index 97012be8377..6928603164b 100644
--- a/library/Zend/EventManager/EventManagerAwareTrait.php
+++ b/library/Zend/EventManager/EventManagerAwareTrait.php
@@ -9,9 +9,45 @@
namespace Zend\EventManager;
-use \Zend\EventManager\ProvidesEvents;
-
trait EventManagerAwareTrait
{
- use ProvidesEvents;
+ /**
+ * @var EventManagerInterface
+ */
+ protected $eventManager;
+
+ /**
+ * Set the event manager instance used by this context
+ *
+ * @param EventManagerInterface $eventManager
+ * @return void
+ */
+ public function setEventManager(EventManagerInterface $eventManager)
+ {
+ if ($eventManager instanceof SharedEventManagerAwareInterface) {
+ $eventIdentifiers = isset($this->eventIdentifiers) ? (array) $this->eventIdentifiers : [];
+
+ $eventManager->setIdentifiers(
+ array_unique(array_merge([__CLASS__, get_class($this)], $eventIdentifiers)
+ ));
+ }
+
+ $this->eventManager = $eventManager;
+ }
+
+ /**
+ * Retrieve the event manager
+ *
+ * Lazy-loads an EventManager instance if none registered.
+ *
+ * @return EventManagerInterface
+ */
+ public function getEventManager()
+ {
+ if (null === $this->eventManager) {
+ $this->setEventManager(new EventManager());
+ }
+
+ return $this->eventManager;
+ }
}
diff --git a/library/Zend/EventManager/EventManagerInterface.php b/library/Zend/EventManager/EventManagerInterface.php
index e17d21b0f04..e9da80e17ea 100644
--- a/library/Zend/EventManager/EventManagerInterface.php
+++ b/library/Zend/EventManager/EventManagerInterface.php
@@ -10,135 +10,81 @@
namespace Zend\EventManager;
use Traversable;
-use Zend\Stdlib\CallbackHandler;
/**
- * Interface for messengers
+ * Interface for event manager
*/
-interface EventManagerInterface extends SharedEventManagerAwareInterface
+interface EventManagerInterface
{
/**
- * Trigger an event
- *
- * Should allow handling the following scenarios:
- * - Passing Event object only
- * - Passing event name and Event object only
- * - Passing event name, target, and Event object
- * - Passing event name, target, and array|ArrayAccess of arguments
- *
- * Can emulate triggerUntil() if the last argument provided is a callback.
- *
- * @param string $event
- * @param object|string $target
- * @param array|object $argv
- * @param null|callable $callback
- * @return ResponseCollection
- */
- public function trigger($event, $target = null, $argv = array(), $callback = null);
-
- /**
- * Trigger an event until the given callback returns a boolean false
- *
- * Should allow handling the following scenarios:
- * - Passing Event object and callback only
- * - Passing event name, Event object, and callback only
- * - Passing event name, target, Event object, and callback
- * - Passing event name, target, array|ArrayAccess of arguments, and callback
+ * Attach a listener to an event
*
- * @param string $event
- * @param object|string $target
- * @param array|object $argv
- * @param callable $callback
- * @return ResponseCollection
+ * @param string $eventName
+ * @param callable $listener
+ * @param int $priority Priority at which to register listener
+ * @return callable
*/
- public function triggerUntil($event, $target, $argv = null, $callback = null);
+ public function attach($eventName, callable $listener, $priority = 1);
/**
- * Attach a listener to an event
+ * Attach a listener aggregate
*
- * @param string $event
- * @param callable $callback
- * @param int $priority Priority at which to register listener
- * @return CallbackHandler
+ * @param ListenerAggregateInterface $aggregate
+ * @param int $priority If provided, a suggested priority for the aggregate to use
+ * @return mixed
*/
- public function attach($event, $callback = null, $priority = 1);
+ public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1);
/**
* Detach an event listener
*
- * @param CallbackHandler|ListenerAggregateInterface $listener
+ * @param callable $listener
+ * @param string $eventName optional to speed up process
* @return bool
*/
- public function detach($listener);
-
- /**
- * Get a list of events for which this collection has listeners
- *
- * @return array
- */
- public function getEvents();
+ public function detach(callable $listener, $eventName = '');
/**
- * Retrieve a list of listeners registered to a given event
+ * Detach a listener aggregate
*
- * @param string $event
- * @return array|object
- */
- public function getListeners($event);
-
- /**
- * Clear all listeners for a given event
+ * Listener aggregates accept an EventManagerInterface instance, and call detach()
+ * of all previously attached listeners
*
- * @param string $event
- * @return void
+ * @param ListenerAggregateInterface $aggregate
+ * @return bool
*/
- public function clearListeners($event);
+ public function detachAggregate(ListenerAggregateInterface $aggregate);
/**
- * Set the event class to utilize
+ * Trigger an event (optionally until using a callback returns a boolean true)
*
- * @param string $class
- * @return EventManagerInterface
+ * @param string $eventName
+ * @param EventInterface|null $event
+ * @param callable|null $callback
+ * @return ResponseCollection
*/
- public function setEventClass($class);
+ public function trigger($eventName, EventInterface $event = null, callable $callback = null);
/**
- * Get the identifier(s) for this EventManager
+ * Get a list of event names for which this collection has listeners
*
* @return array
*/
- public function getIdentifiers();
-
- /**
- * Set the identifiers (overrides any currently set identifiers)
- *
- * @param string|int|array|Traversable $identifiers
- * @return EventManagerInterface
- */
- public function setIdentifiers($identifiers);
-
- /**
- * Add some identifier(s) (appends to any currently set identifiers)
- *
- * @param string|int|array|Traversable $identifiers
- * @return EventManagerInterface
- */
- public function addIdentifiers($identifiers);
+ public function getEventNames();
/**
- * Attach a listener aggregate
+ * Retrieve a list of listeners registered to a given event
*
- * @param ListenerAggregateInterface $aggregate
- * @param int $priority If provided, a suggested priority for the aggregate to use
- * @return mixed return value of {@link ListenerAggregateInterface::attach()}
+ * @param string $eventName
+ * @return array
*/
- public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1);
+ public function getListeners($eventName);
/**
- * Detach a listener aggregate
+ * Clear all listeners for a given event
*
- * @param ListenerAggregateInterface $aggregate
- * @return mixed return value of {@link ListenerAggregateInterface::detach()}
+ * @param string $eventName
+ * @return void
*/
- public function detachAggregate(ListenerAggregateInterface $aggregate);
+ public function clearListeners($eventName);
}
diff --git a/library/Zend/EventManager/EventsCapableInterface.php b/library/Zend/EventManager/EventsCapableInterface.php
deleted file mode 100644
index 401744598ec..00000000000
--- a/library/Zend/EventManager/EventsCapableInterface.php
+++ /dev/null
@@ -1,25 +0,0 @@
-events[$eventName][(int) $priority][] = $listener;
+ $this->orderedByPriority[$eventName] = false;
+
+ return $listener;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function attachAggregate(ListenerAggregateInterface $aggregate, $priority = 1)
+ {
+ return $aggregate->attach($this, $priority);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function detach(callable $listener, $eventName = '')
+ {
+ if ($eventName !== null && isset($this->events[$eventName])) {
+ foreach ($this->events[$eventName] as &$listeners) {
+ if (($key = array_search($listener, $listeners, true)) !== false) {
+ unset($listeners[$key]);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ foreach ($this->events as &$event) {
+ foreach ($event as &$listeners) {
+ if (($key = array_search($listener, $listeners, true)) !== false) {
+ unset($listeners[$key]);
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function detachAggregate(ListenerAggregateInterface $aggregate)
+ {
+ return $aggregate->detach($this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function trigger($eventName, EventInterface $event = null, callable $callback = null)
+ {
+ // Initial value of stop propagation flag should be false
+ $event = $event ?: new Event();
+ $event->stopPropagation(false);
+
+ $responses = [];
+ $listeners = $this->getListeners($eventName);
+
+ foreach ($listeners as $listenersByPriority) {
+ foreach ($listenersByPriority as $listener) {
+ $lastResponse = $listener($event);
+ $responses[] = $lastResponse;
+
+ if (($callback && $callback($lastResponse) || $event->isPropagationStopped())) {
+ $responseCollection = new ResponseCollection($responses);
+ $responseCollection->setStopped(true);
+
+ return $responseCollection;
+ }
+ }
+ }
+
+ return new ResponseCollection($responses);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getEventNames()
+ {
+ return array_keys($this->events);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getListeners($eventName)
+ {
+ if (!isset($this->events[$eventName])) {
+ return [];
+ }
+
+ // Make sure to return listeners ordered by priority
+ // If `events[$eventName]` exists we are sure that `orderedByPriority[$eventName]` exists, too
+ if (!$this->orderedByPriority[$eventName]) {
+ krsort($this->events[$eventName], SORT_NUMERIC);
+ $this->orderedByPriority[$eventName] = true;
+ }
+
+ return $this->events[$eventName];
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function clearListeners($eventName)
+ {
+ unset($this->events[$eventName]);
+ }
+}
diff --git a/library/Zend/EventManager/Filter/FilterInterface.php b/library/Zend/EventManager/Filter/FilterInterface.php
deleted file mode 100644
index 2e4b1c6a11c..00000000000
--- a/library/Zend/EventManager/Filter/FilterInterface.php
+++ /dev/null
@@ -1,65 +0,0 @@
-setExtractFlags(self::EXTR_BOTH);
-
- // Iterate and remove any matches
- $removed = false;
- $items = array();
- $this->rewind();
- while (!$this->isEmpty()) {
- $item = $this->extract();
- if ($item['data'] === $datum) {
- $removed = true;
- continue;
- }
- $items[] = $item;
- }
-
- // Repopulate
- foreach ($items as $item) {
- $this->insert($item['data'], $item['priority']);
- }
-
- $this->setExtractFlags(self::EXTR_DATA);
- return $removed;
- }
-
- /**
- * Iterate the next filter in the chain
- *
- * Iterates and calls the next filter in the chain.
- *
- * @param mixed $context
- * @param array $params
- * @param FilterIterator $chain
- * @return mixed
- */
- public function next($context = null, array $params = array(), $chain = null)
- {
- if (empty($context) || $chain->isEmpty()) {
- return;
- }
-
- $next = $this->extract();
- if (!$next instanceof CallbackHandler) {
- return;
- }
-
- $return = call_user_func($next->getCallback(), $context, $params, $chain);
- return $return;
- }
-}
diff --git a/library/Zend/EventManager/FilterChain.php b/library/Zend/EventManager/FilterChain.php
deleted file mode 100644
index a2703602866..00000000000
--- a/library/Zend/EventManager/FilterChain.php
+++ /dev/null
@@ -1,120 +0,0 @@
-filters = new Filter\FilterIterator();
- }
-
- /**
- * Apply the filters
- *
- * Begins iteration of the filters.
- *
- * @param mixed $context Object under observation
- * @param mixed $argv Associative array of arguments
- * @return mixed
- */
- public function run($context, array $argv = array())
- {
- $chain = clone $this->getFilters();
-
- if ($chain->isEmpty()) {
- return;
- }
-
- $next = $chain->extract();
- if (!$next instanceof CallbackHandler) {
- return;
- }
-
- return call_user_func($next->getCallback(), $context, $argv, $chain);
- }
-
- /**
- * Connect a filter to the chain
- *
- * @param callable $callback PHP Callback
- * @param int $priority Priority in the queue at which to execute; defaults to 1 (higher numbers == higher priority)
- * @return CallbackHandler (to allow later unsubscribe)
- * @throws Exception\InvalidCallbackException
- */
- public function attach($callback, $priority = 1)
- {
- if (empty($callback)) {
- throw new Exception\InvalidCallbackException('No callback provided');
- }
- $filter = new CallbackHandler($callback, array('priority' => $priority));
- $this->filters->insert($filter, $priority);
- return $filter;
- }
-
- /**
- * Detach a filter from the chain
- *
- * @param CallbackHandler $filter
- * @return bool Returns true if filter found and unsubscribed; returns false otherwise
- */
- public function detach(CallbackHandler $filter)
- {
- return $this->filters->remove($filter);
- }
-
- /**
- * Retrieve all filters
- *
- * @return Filter\FilterIterator
- */
- public function getFilters()
- {
- return $this->filters;
- }
-
- /**
- * Clear all filters
- *
- * @return void
- */
- public function clearFilters()
- {
- $this->filters = new Filter\FilterIterator();
- }
-
- /**
- * Return current responses
- *
- * Only available while the chain is still being iterated. Returns the
- * current ResponseCollection.
- *
- * @return null|ResponseCollection
- */
- public function getResponses()
- {
- return null;
- }
-}
diff --git a/library/Zend/EventManager/GlobalEventManager.php b/library/Zend/EventManager/GlobalEventManager.php
deleted file mode 100644
index 047dd18cf42..00000000000
--- a/library/Zend/EventManager/GlobalEventManager.php
+++ /dev/null
@@ -1,135 +0,0 @@
-trigger($event, $context, $argv);
- }
-
- /**
- * Trigger listeners until return value of one causes a callback to evaluate
- * to true.
- *
- * @param string $event
- * @param string|object $context
- * @param array|object $argv
- * @param callable $callback
- * @return ResponseCollection
- */
- public static function triggerUntil($event, $context, $argv, $callback)
- {
- return static::getEventCollection()->triggerUntil($event, $context, $argv, $callback);
- }
-
- /**
- * Attach a listener to an event
- *
- * @param string $event
- * @param callable $callback
- * @param int $priority
- * @return CallbackHandler
- */
- public static function attach($event, $callback, $priority = 1)
- {
- return static::getEventCollection()->attach($event, $callback, $priority);
- }
-
- /**
- * Detach a callback from a listener
- *
- * @param CallbackHandler $listener
- * @return bool
- */
- public static function detach(CallbackHandler $listener)
- {
- return static::getEventCollection()->detach($listener);
- }
-
- /**
- * Retrieve list of events this object manages
- *
- * @return array
- */
- public static function getEvents()
- {
- return static::getEventCollection()->getEvents();
- }
-
- /**
- * Retrieve all listeners for a given event
- *
- * @param string $event
- * @return PriorityQueue|array
- */
- public static function getListeners($event)
- {
- return static::getEventCollection()->getListeners($event);
- }
-
- /**
- * Clear all listeners for a given event
- *
- * @param string $event
- * @return void
- */
- public static function clearListeners($event)
- {
- static::getEventCollection()->clearListeners($event);
- }
-}
diff --git a/library/Zend/EventManager/ListenerAggregateInterface.php b/library/Zend/EventManager/ListenerAggregateInterface.php
index 4d10e71da02..57af03ac514 100644
--- a/library/Zend/EventManager/ListenerAggregateInterface.php
+++ b/library/Zend/EventManager/ListenerAggregateInterface.php
@@ -26,8 +26,7 @@ interface ListenerAggregateInterface
* implementation will pass this to the aggregate.
*
* @param EventManagerInterface $events
- *
- * @return void
+ * @return mixed
*/
public function attach(EventManagerInterface $events);
@@ -35,8 +34,7 @@ public function attach(EventManagerInterface $events);
* Detach all previously attached listeners
*
* @param EventManagerInterface $events
- *
- * @return void
+ * @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
*/
public function detach(EventManagerInterface $events);
}
diff --git a/library/Zend/EventManager/ListenerAggregateTrait.php b/library/Zend/EventManager/ListenerAggregateTrait.php
index fabedc03cd8..b159c5a15d4 100644
--- a/library/Zend/EventManager/ListenerAggregateTrait.php
+++ b/library/Zend/EventManager/ListenerAggregateTrait.php
@@ -16,19 +16,24 @@
trait ListenerAggregateTrait
{
/**
- * @var \Zend\Stdlib\CallbackHandler[]
+ * @var callable[]
*/
- protected $listeners = array();
+ protected $listeners = [];
/**
* {@inheritDoc}
*/
public function detach(EventManagerInterface $events)
{
- foreach ($this->listeners as $index => $callback) {
- if ($events->detach($callback)) {
+ $found = false;
+
+ foreach ($this->listeners as $index => $listener) {
+ if ($events->detach($listener)) {
unset($this->listeners[$index]);
+ $found = true;
}
}
+
+ return $found;
}
}
diff --git a/library/Zend/EventManager/ProvidesEvents.php b/library/Zend/EventManager/ProvidesEvents.php
deleted file mode 100644
index ea46333a1f4..00000000000
--- a/library/Zend/EventManager/ProvidesEvents.php
+++ /dev/null
@@ -1,63 +0,0 @@
-eventIdentifier)) {
- if ((is_string($this->eventIdentifier))
- || (is_array($this->eventIdentifier))
- || ($this->eventIdentifier instanceof Traversable)
- ) {
- $identifiers = array_unique(array_merge($identifiers, (array) $this->eventIdentifier));
- } elseif (is_object($this->eventIdentifier)) {
- $identifiers[] = $this->eventIdentifier;
- }
- // silently ignore invalid eventIdentifier types
- }
- $events->setIdentifiers($identifiers);
- $this->events = $events;
- return $this;
- }
-
- /**
- * Retrieve the event manager
- *
- * Lazy-loads an EventManager instance if none registered.
- *
- * @return EventManagerInterface
- */
- public function getEventManager()
- {
- if (!$this->events instanceof EventManagerInterface) {
- $this->setEventManager(new EventManager());
- }
- return $this->events;
- }
-}
diff --git a/library/Zend/EventManager/README.md b/library/Zend/EventManager/README.md
index 474b103d7be..49297cfd808 100644
--- a/library/Zend/EventManager/README.md
+++ b/library/Zend/EventManager/README.md
@@ -1,7 +1,7 @@
-EventManager Component from ZF2
+EventManager Component from ZF3
===============================
-This is the EventManager component for ZF2.
+This is the EventManager component for ZF3.
- File issues at https://github.com/zendframework/zf2/issues
- Create pull requests against https://github.com/zendframework/zf2
diff --git a/library/Zend/EventManager/ResponseCollection.php b/library/Zend/EventManager/ResponseCollection.php
index 5131d1d402a..364901b2f55 100644
--- a/library/Zend/EventManager/ResponseCollection.php
+++ b/library/Zend/EventManager/ResponseCollection.php
@@ -9,15 +9,36 @@
namespace Zend\EventManager;
-use SplStack;
+use ArrayIterator;
+use Countable;
+use IteratorAggregate;
/**
* Collection of signal handler return values
+ *
+ * We used to use a SplStack in Zend Framework 2, but using an array allows us some interesting
+ * optimizations
*/
-class ResponseCollection extends SplStack
+class ResponseCollection implements Countable, IteratorAggregate
{
+ /**
+ * @var array
+ */
+ protected $responses = [];
+
+ /**
+ * @var bool
+ */
protected $stopped = false;
+ /**
+ * @param array $responses
+ */
+ public function __construct(array $responses = [])
+ {
+ $this->responses = $responses;
+ }
+
/**
* Did the last response provided trigger a short circuit of the stack?
*
@@ -32,12 +53,11 @@ public function stopped()
* Mark the collection as stopped (or its opposite)
*
* @param bool $flag
- * @return ResponseCollection
+ * @return void
*/
public function setStopped($flag)
{
$this->stopped = (bool) $flag;
- return $this;
}
/**
@@ -47,7 +67,8 @@ public function setStopped($flag)
*/
public function first()
{
- return parent::bottom();
+ reset($this->responses);
+ return current($this->responses);
}
/**
@@ -60,10 +81,11 @@ public function first()
*/
public function last()
{
- if (count($this) === 0) {
+ if (empty($this->responses)) {
return null;
}
- return parent::top();
+
+ return end($this->responses);
}
/**
@@ -74,11 +96,22 @@ public function last()
*/
public function contains($value)
{
- foreach ($this as $response) {
- if ($response === $value) {
- return true;
- }
- }
- return false;
+ return in_array($value, $this->responses, true);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function count()
+ {
+ return count($this->responses);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->responses);
}
}
diff --git a/library/Zend/EventManager/SharedEventAggregateAwareInterface.php b/library/Zend/EventManager/SharedEventAggregateAwareInterface.php
deleted file mode 100644
index 69b2b7915a4..00000000000
--- a/library/Zend/EventManager/SharedEventAggregateAwareInterface.php
+++ /dev/null
@@ -1,34 +0,0 @@
-
- * $sharedEventManager = new SharedEventManager();
- * $sharedEventManager->attach(
- * array('My\Resource\AbstractResource', 'My\Resource\EntityResource'),
- * 'getAll',
- * function ($e) use ($cache) {
- * if (!$id = $e->getParam('id', false)) {
- * return;
- * }
- * if (!$data = $cache->load(get_class($resource) . '::getOne::' . $id )) {
- * return;
- * }
- * return $data;
- * }
- * );
- *
+ * identifying components
*
- * @param string|array $id Identifier(s) for event emitting component(s)
- * @param string $event
- * @param callable $callback PHP Callback
- * @param int $priority Priority at which listener should execute
- * @return CallbackHandler|array Either CallbackHandler or array of CallbackHandlers
+ * @param string|array $identifiers Identifier(s) for event emitting component(s)
+ * @param string $eventName
+ * @param callable $listener PHP Callback
+ * @param int $priority Priority at which listener should execute
+ * @return callable
*/
- public function attach($id, $event, $callback, $priority = 1)
+ public function attach($identifiers, $eventName, callable $listener, $priority = 1)
{
- $ids = (array) $id;
- $listeners = array();
- foreach ($ids as $id) {
- if (!array_key_exists($id, $this->identifiers)) {
- $this->identifiers[$id] = new EventManager($id);
- }
- $listeners[] = $this->identifiers[$id]->attach($event, $callback, $priority);
- }
- if (count($listeners) > 1) {
- return $listeners;
+ foreach ((array) $identifiers as $identifier) {
+ $this->identifiers[$identifier][$eventName][(int) $priority . '.0'][] = $listener;
}
- return $listeners[0];
+
+ return $listener;
}
/**
@@ -84,7 +58,7 @@ public function attach($id, $event, $callback, $priority = 1)
*
* @param SharedListenerAggregateInterface $aggregate
* @param int $priority If provided, a suggested priority for the aggregate to use
- * @return mixed return value of {@link ListenerAggregateInterface::attachShared()}
+ * @return mixed return value of {@link SharedListenerAggregateInterface::attachShared()}
*/
public function attachAggregate(SharedListenerAggregateInterface $aggregate, $priority = 1)
{
@@ -94,16 +68,24 @@ public function attachAggregate(SharedListenerAggregateInterface $aggregate, $pr
/**
* Detach a listener from an event offered by a given resource
*
- * @param string|int $id
- * @param CallbackHandler $listener
+ * @param string|int $identifier
+ * @param callable $listener
* @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
*/
- public function detach($id, CallbackHandler $listener)
+ public function detach($identifier, callable $listener)
{
- if (!array_key_exists($id, $this->identifiers)) {
- return false;
+ if (isset($this->identifiers[$identifier])) {
+ foreach ($this->identifiers[$identifier] as &$event) {
+ foreach ($event as &$listeners) {
+ if (($key = array_search($listener, $listeners, true)) !== false) {
+ unset($listeners[$key]);
+ return true;
+ }
+ }
+ }
}
- return $this->identifiers[$id]->detach($listener);
+
+ return false;
}
/**
@@ -121,56 +103,80 @@ public function detachAggregate(SharedListenerAggregateInterface $aggregate)
}
/**
- * Retrieve all registered events for a given resource
+ * Retrieve all listeners for the given identifiers and for a specific event
*
- * @param string|int $id
+ * @param string[] $identifiers
+ * @param string $eventName
* @return array
*/
- public function getEvents($id)
+ public function getListeners(array $identifiers, $eventName)
{
- if (!array_key_exists($id, $this->identifiers)) {
- //Check if there are any id wildcards listeners
- if ('*' != $id && array_key_exists('*', $this->identifiers)) {
- return $this->identifiers['*']->getEvents();
+ $listeners = [];
+
+ // we detect if there is a wildcard identifier so that we can retrieve its listeners, and
+ // remove the conditional in the foreach
+ $wildcardIdentifierListeners = isset($identifiers['*']) ? $identifiers['*'] : null;
+ unset($identifiers['*']);
+
+ foreach ($identifiers as $identifier) {
+ if (isset($this->identifiers[$identifier][$eventName]) && $eventName !== '*') {
+ $listeners = array_merge_recursive($listeners, $this->identifiers[$identifier][$eventName]);
+ }
+
+ if (isset($this->identifiers[$identifier]['*'])) {
+ $listeners = array_merge_recursive($listeners, $this->identifiers[$identifier]['*']);
+ }
+ }
+
+ // merge listeners attached to wildcard identifiers
+ if (null !== $wildcardIdentifierListeners) {
+ if (isset($wildcardIdentifierListeners[$eventName]) && $eventName !== '*') {
+ $listeners = array_merge_recursive($listeners, $wildcardIdentifierListeners[$eventName]);
+ }
+
+ if (isset($wildcardIdentifierListeners['*'])) {
+ $listeners = array_merge_recursive($listeners, $wildcardIdentifierListeners['*']);
}
- return false;
}
- return $this->identifiers[$id]->getEvents();
+
+ return $listeners;
}
/**
- * Retrieve all listeners for a given identifier and event
+ * Clear all listeners for the given identifiers and optionally for a specific event
*
- * @param string|int $id
- * @param string|int $event
- * @return false|PriorityQueue
+ * @param string[] $identifiers
+ * @param null|string $eventName
+ * @return void
*/
- public function getListeners($id, $event)
+ public function clearListeners(array $identifiers, $eventName = null)
{
- if (!array_key_exists($id, $this->identifiers)) {
- return false;
+ foreach ($identifiers as $identifier) {
+ if (null === $eventName) {
+ unset($this->identifiers[$identifier]);
+ } else {
+ unset($this->identifiers[$identifier][$eventName]);
+ }
}
- return $this->identifiers[$id]->getListeners($event);
}
/**
- * Clear all listeners for a given identifier, optionally for a specific event
+ * Retrieve all registered events for a given resource
*
- * @param string|int $id
- * @param null|string $event
- * @return bool
+ * @param string|int $identifier
+ * @return array
*/
- public function clearListeners($id, $event = null)
+ public function getEventNames($identifier)
{
- if (!array_key_exists($id, $this->identifiers)) {
- return false;
- }
+ if (!isset($this->identifiers[$identifier])) {
+ // Check if there are any id wildcards listeners
+ if ('*' !== $identifier && isset($this->identifiers['*'])) {
+ return array_keys($this->identifiers['*']);
+ }
- if (null === $event) {
- unset($this->identifiers[$id]);
- return true;
+ return false;
}
- return $this->identifiers[$id]->clearListeners($event);
+ return array_keys($this->identifiers[$identifier]);
}
}
diff --git a/library/Zend/EventManager/SharedEventManagerAwareInterface.php b/library/Zend/EventManager/SharedEventManagerAwareInterface.php
index c982948a689..55d4d321ef8 100644
--- a/library/Zend/EventManager/SharedEventManagerAwareInterface.php
+++ b/library/Zend/EventManager/SharedEventManagerAwareInterface.php
@@ -9,6 +9,8 @@
namespace Zend\EventManager;
+use Traversable;
+
/**
* Interface to automate setter injection for a SharedEventManagerInterface instance
*/
@@ -30,9 +32,25 @@ public function setSharedManager(SharedEventManagerInterface $sharedEventManager
public function getSharedManager();
/**
- * Remove any shared collections
+ * Set the identifiers (overrides any currently set identifiers)
+ *
+ * @param array|Traversable $identifiers
+ * @return void
+ */
+ public function setIdentifiers($identifiers);
+
+ /**
+ * Add some identifier(s) (appends to any currently set identifiers)
*
+ * @param array|Traversable $identifiers
* @return void
*/
- public function unsetSharedManager();
+ public function addIdentifiers($identifiers);
+
+ /**
+ * Get the identifier(s) for this EventManager
+ *
+ * @return array
+ */
+ public function getIdentifiers();
}
diff --git a/library/Zend/EventManager/SharedEventManagerInterface.php b/library/Zend/EventManager/SharedEventManagerInterface.php
index ee4e0fec902..d2bb559d3dc 100644
--- a/library/Zend/EventManager/SharedEventManagerInterface.php
+++ b/library/Zend/EventManager/SharedEventManagerInterface.php
@@ -9,57 +9,71 @@
namespace Zend\EventManager;
-use Zend\Stdlib\CallbackHandler;
-use Zend\Stdlib\PriorityQueue;
-
/**
* Interface for shared event listener collections
*/
interface SharedEventManagerInterface
{
/**
- * Retrieve all listeners for a given identifier and event
+ * Attach a listener to an event
*
- * @param string|int $id
- * @param string|int $event
- * @return false|PriorityQueue
+ * @param array $identifiers Identifier(s) for event emitting component(s)
+ * @param string $eventName
+ * @param callable $listener PHP Callback
+ * @param int $priority Priority at which listener should execute
+ * @return void
*/
- public function getListeners($id, $event);
+ public function attach($identifiers, $eventName, callable $listener, $priority = 1);
/**
- * Attach a listener to an event
+ * Attach a listener aggregate
*
- * @param string|array $id Identifier(s) for event emitting component(s)
- * @param string $event
- * @param callable $callback PHP Callback
- * @param int $priority Priority at which listener should execute
- * @return void
+ * @param SharedListenerAggregateInterface $aggregate
+ * @param int $priority If provided, a suggested priority for the aggregate to use
+ * @return mixed return value of {@link SharedListenerAggregateInterface::attachShared()}
*/
- public function attach($id, $event, $callback, $priority = 1);
+ public function attachAggregate(SharedListenerAggregateInterface $aggregate, $priority = 1);
/**
* Detach a listener from an event offered by a given resource
*
- * @param string|int $id
- * @param CallbackHandler $listener
+ * @param string|int $identifier
+ * @param callable $listener
* @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
*/
- public function detach($id, CallbackHandler $listener);
+ public function detach($identifier, callable $listener);
/**
- * Retrieve all registered events for a given resource
+ * Detach a listener aggregate
*
- * @param string|int $id
+ * @param SharedListenerAggregateInterface $aggregate
+ * @return mixed return value of {@link SharedListenerAggregateInterface::detachShared()}
+ */
+ public function detachAggregate(SharedListenerAggregateInterface $aggregate);
+
+ /**
+ * Retrieve all listeners for the given identifiers and event for a specific event
+ *
+ * @param string[] $identifiers
+ * @param string $eventName
* @return array
*/
- public function getEvents($id);
+ public function getListeners(array $identifiers, $eventName);
+
+ /**
+ * Clear all listeners for the given identifiers and optionally for a specific event
+ *
+ * @param string[] $identifiers
+ * @param null|string $eventName
+ * @return void
+ */
+ public function clearListeners(array $identifiers, $eventName = null);
/**
- * Clear all listeners for a given identifier, optionally for a specific event
+ * Retrieve all registered events for a given resource
*
- * @param string|int $id
- * @param null|string $event
- * @return bool
+ * @param string|int $identifier
+ * @return array
*/
- public function clearListeners($id, $event = null);
+ public function getEventNames($identifier);
}
diff --git a/library/Zend/EventManager/SharedListenerAggregateInterface.php b/library/Zend/EventManager/SharedListenerAggregateInterface.php
index 0fd127022bd..33b641f5c63 100644
--- a/library/Zend/EventManager/SharedListenerAggregateInterface.php
+++ b/library/Zend/EventManager/SharedListenerAggregateInterface.php
@@ -26,6 +26,7 @@ interface SharedListenerAggregateInterface
* implementation will pass this to the aggregate.
*
* @param SharedEventManagerInterface $events
+ * @return mixed
*/
public function attachShared(SharedEventManagerInterface $events);
@@ -33,6 +34,7 @@ public function attachShared(SharedEventManagerInterface $events);
* Detach all previously attached listeners
*
* @param SharedEventManagerInterface $events
+ * @return bool Returns true if event and listener found, and unsubscribed; returns false if either event or listener not found
*/
public function detachShared(SharedEventManagerInterface $events);
}
diff --git a/library/Zend/EventManager/StaticEventManager.php b/library/Zend/EventManager/StaticEventManager.php
deleted file mode 100644
index 4458efafb2f..00000000000
--- a/library/Zend/EventManager/StaticEventManager.php
+++ /dev/null
@@ -1,82 +0,0 @@
-=5.3.3",
- "zendframework/zend-stdlib": "self.version"
+ "php": ">=5.4"
},
"extra": {
"branch-alias": {
- "dev-master": "2.2-dev",
- "dev-develop": "2.3-dev"
+ "dev-master": "3.0-dev",
+ "dev-develop": "3.1-dev"
}
}
}
diff --git a/library/Zend/Stdlib/CallbackHandler.php b/library/Zend/Stdlib/CallbackHandler.php
index f1ac4a65b36..bdec2d95d30 100644
--- a/library/Zend/Stdlib/CallbackHandler.php
+++ b/library/Zend/Stdlib/CallbackHandler.php
@@ -32,35 +32,18 @@ class CallbackHandler
*/
protected $metadata;
- /**
- * PHP version is greater as 5.4rc1?
- * @var bool
- */
- protected static $isPhp54;
-
/**
* Constructor
*
- * @param string|array|object|callable $callback PHP callback
- * @param array $metadata Callback metadata
+ * @param Callable $callback PHP callback
+ * @param array $metadata Callback metadata
*/
- public function __construct($callback, array $metadata = array())
+ public function __construct(Callable $callback, array $metadata = array())
{
- $this->metadata = $metadata;
- $this->registerCallback($callback);
- }
+ $this->metadata = $metadata;
- /**
- * Registers the callback provided in the constructor
- *
- * @param callable $callback
- * @throws Exception\InvalidCallbackException
- * @return void
- */
- protected function registerCallback($callback)
- {
- if (!is_callable($callback)) {
- throw new Exception\InvalidCallbackException('Invalid callback provided; not callable');
+ if (is_string($callback) && strpos($callback, '::') !== false) {
+ $callback = explode('::', $callback, 2);
}
$this->callback = $callback;
@@ -69,7 +52,7 @@ protected function registerCallback($callback)
/**
* Retrieve registered callback
*
- * @return callable
+ * @return Callable
*/
public function getCallback()
{
@@ -85,53 +68,26 @@ public function getCallback()
public function call(array $args = array())
{
$callback = $this->getCallback();
-
- // Minor performance tweak, if the callback gets called more than once
- if (!isset(static::$isPhp54)) {
- static::$isPhp54 = version_compare(PHP_VERSION, '5.4.0rc1', '>=');
- }
-
$argCount = count($args);
- if (static::$isPhp54 && is_string($callback)) {
- $result = $this->validateStringCallbackFor54($callback);
-
- if ($result !== true && $argCount <= 3) {
- $callback = $result;
- // Minor performance tweak, if the callback gets called more
- // than once
- $this->callback = $result;
- }
- }
-
// Minor performance tweak; use call_user_func() until > 3 arguments
// reached
switch ($argCount) {
case 0:
- if (static::$isPhp54) {
- return $callback();
- }
- return call_user_func($callback);
+ return $callback();
case 1:
- if (static::$isPhp54) {
- return $callback(array_shift($args));
- }
- return call_user_func($callback, array_shift($args));
+ return $callback(array_shift($args));
case 2:
$arg1 = array_shift($args);
$arg2 = array_shift($args);
- if (static::$isPhp54) {
- return $callback($arg1, $arg2);
- }
- return call_user_func($callback, $arg1, $arg2);
+
+ return $callback($arg1, $arg2);
case 3:
$arg1 = array_shift($args);
$arg2 = array_shift($args);
$arg3 = array_shift($args);
- if (static::$isPhp54) {
- return $callback($arg1, $arg2, $arg3);
- }
- return call_user_func($callback, $arg1, $arg2, $arg3);
+
+ return $callback($arg1, $arg2, $arg3);
default:
return call_user_func_array($callback, $args);
}
@@ -165,54 +121,6 @@ public function getMetadata()
*/
public function getMetadatum($name)
{
- if (array_key_exists($name, $this->metadata)) {
- return $this->metadata[$name];
- }
- return null;
- }
-
- /**
- * Validate a static method call
- *
- * Validates that a static method call in PHP 5.4 will actually work
- *
- * @param string $callback
- * @return true|array
- * @throws Exception\InvalidCallbackException if invalid
- */
- protected function validateStringCallbackFor54($callback)
- {
- if (!strstr($callback, '::')) {
- return true;
- }
-
- list($class, $method) = explode('::', $callback, 2);
-
- if (!class_exists($class)) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a class that does not exist',
- $callback
- ));
- }
-
- $r = new ReflectionClass($class);
- if (!$r->hasMethod($method)) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a method that does not exist',
- $callback
- ));
- }
- $m = $r->getMethod($method);
- if (!$m->isStatic()) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a method that is not static',
- $callback
- ));
- }
-
- // returning a non boolean value may not be nice for a validate method,
- // but that allows the usage of a static string callback without using
- // the call_user_func function.
- return array($class, $method);
+ return isset($this->metadata[$name]) ? $this->metadata[$name] : null;
}
}
diff --git a/library/Zend/Stdlib/Exception/InvalidCallbackException.php b/library/Zend/Stdlib/Exception/InvalidCallbackException.php
deleted file mode 100644
index 30e97e83bda..00000000000
--- a/library/Zend/Stdlib/Exception/InvalidCallbackException.php
+++ /dev/null
@@ -1,17 +0,0 @@
-listener = new MockAbstractListenerAggregate();
- }
-
- /**
- * @covers \Zend\EventManager\AbstractListenerAggregate::detach
- */
- public function testDetach()
- {
- $eventManager = $this->getMock('Zend\\EventManager\\EventManagerInterface');
- $unrelatedEventManager = $this->getMock('Zend\\EventManager\\EventManagerInterface');
- $callbackHandlers = array();
- $test = $this;
-
- $eventManager
- ->expects($this->exactly(2))
- ->method('attach')
- ->will($this->returnCallback(function () use (&$callbackHandlers, $test) {
- return $callbackHandlers[] = $test->getMock('Zend\\Stdlib\\CallbackHandler', array(), array(), '', false);
- }));
-
- $this->listener->attach($eventManager);
- $this->assertSame($callbackHandlers, $this->listener->getCallbacks());
-
- $this->listener->detach($unrelatedEventManager);
-
- $this->assertSame($callbackHandlers, $this->listener->getCallbacks());
-
- $eventManager
- ->expects($this->exactly(2))
- ->method('detach')
- ->with($this->callback(function ($callbackHandler) use ($callbackHandlers) {
- return in_array($callbackHandler, $callbackHandlers, true);
- }))
- ->will($this->returnValue(true));
-
- $this->listener->detach($eventManager);
- $this->assertEmpty($this->listener->getCallbacks());
- }
-}
diff --git a/tests/ZendTest/EventManager/Asset/EventManagerAwareObject.php b/tests/ZendTest/EventManager/Asset/EventManagerAwareObject.php
new file mode 100644
index 00000000000..0bf434b3f55
--- /dev/null
+++ b/tests/ZendTest/EventManager/Asset/EventManagerAwareObject.php
@@ -0,0 +1,29 @@
+getObjectForTrait('\Zend\EventManager\EventManagerAwareTrait');
-
- $this->assertAttributeEquals(null, 'events', $object);
-
- $eventManager = new EventManager;
-
- $object->setEventManager($eventManager);
-
- $this->assertAttributeEquals($eventManager, 'events', $object);
- }
-
- public function testGetEventManager()
- {
- $object = $this->getObjectForTrait('\Zend\EventManager\EventManagerAwareTrait');
-
- $this->assertInstanceOf('\Zend\EventManager\EventManagerInterface', $object->getEventManager());
-
- $eventManager = new EventManager;
+ $eventManager = new EventManager();
+ $object = new EventManagerAwareObject();
$object->setEventManager($eventManager);
- $this->assertSame($eventManager, $object->getEventManager());
+ $identifiers = $eventManager->getIdentifiers();
+ $this->assertContains(get_class($object), $identifiers);
+ $this->assertContains('MyIdentifier', $identifiers, 'Assert class identifiers are merged');
}
}
diff --git a/tests/ZendTest/EventManager/EventManagerTest.php b/tests/ZendTest/EventManager/EventManagerTest.php
index 380dc86355f..f0e7a72fbc4 100644
--- a/tests/ZendTest/EventManager/EventManagerTest.php
+++ b/tests/ZendTest/EventManager/EventManagerTest.php
@@ -10,668 +10,236 @@
namespace ZendTest\EventManager;
-use ArrayIterator;
-use stdClass;
use Zend\EventManager\Event;
use Zend\EventManager\EventInterface;
use Zend\EventManager\EventManager;
-use Zend\EventManager\ResponseCollection;
use Zend\EventManager\SharedEventManager;
-use Zend\EventManager\StaticEventManager;
-use Zend\Stdlib\CallbackHandler;
-/**
- * @category Zend
- * @package Zend_EventManager
- * @subpackage UnitTests
- * @group Zend_EventManager
- */
class EventManagerTest extends \PHPUnit_Framework_TestCase
{
- public function setUp()
+ public function testEventManagerHasNoIdentifiersByDefault()
{
- StaticEventManager::resetInstance();
-
- if (isset($this->message)) {
- unset($this->message);
- }
- $this->events = new EventManager;
- StaticEventManager::resetInstance();
+ $eventManager = new EventManager();
+ $this->assertEmpty($eventManager->getIdentifiers());
}
- public function tearDown()
+ public function testCanSetIdentifiersThroughConstructor()
{
- StaticEventManager::resetInstance();
- }
+ $identifiers = ['identifier1', 'identifier2'];
+ $eventManager = new EventManager($identifiers);
- public function testAttachShouldReturnCallbackHandler()
- {
- $listener = $this->events->attach('test', array($this, __METHOD__));
- $this->assertTrue($listener instanceof CallbackHandler);
+ $this->assertEquals($identifiers, $eventManager->getIdentifiers());
}
- public function testAttachShouldAddListenerToEvent()
+ public function testSetIdentifiersReplace()
{
- $listener = $this->events->attach('test', array($this, __METHOD__));
- $listeners = $this->events->getListeners('test');
- $this->assertEquals(1, count($listeners));
- $this->assertContains($listener, $listeners);
+ $eventManager = new EventManager(['identifier1']);
+ $eventManager->setIdentifiers(['identifier2']);
+
+ $this->assertEquals(['identifier2'], $eventManager->getIdentifiers());
}
- public function testAttachShouldAddEventIfItDoesNotExist()
+ public function testAddIdentifiersAppend()
{
- $events = $this->events->getEvents();
- $this->assertTrue(empty($events), var_export($events, 1));
- $listener = $this->events->attach('test', array($this, __METHOD__));
- $events = $this->events->getEvents();
- $this->assertFalse(empty($events));
- $this->assertContains('test', $events);
+ $eventManager = new EventManager(['identifier1']);
+ $eventManager->addIdentifiers(['identifier2', 'identifier2']);
+
+ $this->assertEquals(['identifier1', 'identifier2'], $eventManager->getIdentifiers());
}
- public function testAllowsPassingArrayOfEventNamesWhenAttaching()
+ public function testEventManagerHasNoSharedEventManagerByDefault()
{
- $callback = function ($e) {
- return $e->getName();
- };
- $this->events->attach(array('foo', 'bar'), $callback);
-
- foreach (array('foo', 'bar') as $event) {
- $listeners = $this->events->getListeners($event);
- $this->assertTrue(count($listeners) > 0);
- foreach ($listeners as $listener) {
- $this->assertSame($callback, $listener->getCallback());
- }
- }
+ $eventManager = new EventManager();
+ $this->assertNull($eventManager->getSharedManager());
}
- public function testPassingArrayOfEventNamesWhenAttachingReturnsArrayOfCallbackHandlers()
+ public function testCanAttachListener()
{
- $callback = function ($e) {
- return $e->getName();
- };
- $listeners = $this->events->attach(array('foo', 'bar'), $callback);
+ $eventManager = new EventManager();
+ $count = 0;
- $this->assertInternalType('array', $listeners);
+ $eventManager->attach('event', function() use (&$count) { $count++; });
+ $eventManager->attach('event', function() use (&$count) { $count++; });
- foreach ($listeners as $listener) {
- $this->assertInstanceOf('Zend\Stdlib\CallbackHandler', $listener);
- $this->assertSame($callback, $listener->getCallback());
- }
- }
+ $eventManager->trigger('unknownEvent');
+ $this->assertEquals(0, $count);
- public function testDetachShouldRemoveListenerFromEvent()
- {
- $listener = $this->events->attach('test', array($this, __METHOD__));
- $listeners = $this->events->getListeners('test');
- $this->assertContains($listener, $listeners);
- $this->events->detach($listener);
- $listeners = $this->events->getListeners('test');
- $this->assertNotContains($listener, $listeners);
- }
+ $eventManager->trigger('event');
+ $this->assertEquals(2, $count);
- public function testDetachShouldReturnFalseIfEventDoesNotExist()
- {
- $listener = $this->events->attach('test', array($this, __METHOD__));
- $this->events->clearListeners('test');
- $this->assertFalse($this->events->detach($listener));
- }
+ // Test clearing listeners
+ $eventManager->clearListeners('unknownEvent');
+ $eventManager->trigger('event');
+ $this->assertEquals(4, $count);
- public function testDetachShouldReturnFalseIfListenerDoesNotExist()
- {
- $listener1 = $this->events->attach('test', array($this, __METHOD__));
- $this->events->clearListeners('test');
- $listener2 = $this->events->attach('test', array($this, 'handleTestEvent'));
- $this->assertFalse($this->events->detach($listener1));
+ $eventManager->clearListeners('event');
+ $eventManager->trigger('event');
+ $this->assertEquals(4, $count);
}
- public function testRetrievingAttachedListenersShouldReturnEmptyArrayWhenEventDoesNotExist()
+ public function testCanAttachAggregate()
{
- $listeners = $this->events->getListeners('test');
- $this->assertEquals(0, count($listeners));
- }
+ $listenerAggregate = $this->getMock('Zend\EventManager\ListenerAggregateInterface');
+ $eventManager = new EventManager();
- public function testTriggerShouldTriggerAttachedListeners()
- {
- $listener = $this->events->attach('test', array($this, 'handleTestEvent'));
- $this->events->trigger('test', $this, array('message' => 'test message'));
- $this->assertEquals('test message', $this->message);
- }
+ $listenerAggregate->expects($this->once())
+ ->method('attach')
+ ->with($eventManager, 1);
- public function testTriggerShouldReturnAllListenerReturnValues()
- {
- $this->events->attach('string.transform', function ($e) {
- $string = $e->getParam('string', '__NOT_FOUND__');
- return trim($string);
- });
- $this->events->attach('string.transform', function ($e) {
- $string = $e->getParam('string', '__NOT_FOUND__');
- return str_rot13($string);
- });
- $responses = $this->events->trigger('string.transform', $this, array('string' => ' foo '));
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertEquals(2, $responses->count());
- $this->assertEquals('foo', $responses->first());
- $this->assertEquals(\str_rot13(' foo '), $responses->last());
+ $eventManager->attachAggregate($listenerAggregate);
}
- public function testTriggerUntilShouldReturnAsSoonAsCallbackReturnsTrue()
+ public function testDetachUnknownListener()
{
- $this->events->attach('foo.bar', function ($e) {
- $string = $e->getParam('string', '');
- $search = $e->getParam('search', '?');
- return strpos($string, $search);
- });
- $this->events->attach('foo.bar', function ($e) {
- $string = $e->getParam('string', '');
- $search = $e->getParam('search', '?');
- return strstr($string, $search);
- });
- $responses = $this->events->triggerUntil(
- 'foo.bar',
- $this,
- array('string' => 'foo', 'search' => 'f'),
- array($this, 'evaluateStringCallback')
- );
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertSame(0, $responses->last());
- }
+ $eventManager = new EventManager();
- public function testTriggerResponseCollectionContains()
- {
- $this->events->attach('string.transform', function ($e) {
- $string = $e->getParam('string', '');
- return trim($string);
- });
- $this->events->attach('string.transform', function ($e) {
- $string = $e->getParam('string', '');
- return str_rot13($string);
- });
- $responses = $this->events->trigger('string.transform', $this, array('string' => ' foo '));
- $this->assertTrue($responses->contains('foo'));
- $this->assertTrue($responses->contains(\str_rot13(' foo ')));
- $this->assertFalse($responses->contains(' foo '));
+ $this->assertFalse($eventManager->detach(function() {}));
+ $this->assertFalse($eventManager->detach(function() {}, 'event'));
}
- public function handleTestEvent($e)
+ public function testCanDetachListenerWithoutEventName()
{
- $message = $e->getParam('message', '__NOT_FOUND__');
- $this->message = $message;
- }
+ $eventManager = new EventManager();
+ $count = 0;
- public function evaluateStringCallback($value)
- {
- return (!$value);
- }
+ $listener = $eventManager->attach('event', function() use (&$count) { $count++; });
+ $this->assertTrue($eventManager->detach($listener));
- public function testTriggerUntilShouldMarkResponseCollectionStoppedWhenConditionMet()
- {
- $this->events->attach('foo.bar', function () { return 'bogus'; }, 4);
- $this->events->attach('foo.bar', function () { return 'nada'; }, 3);
- $this->events->attach('foo.bar', function () { return 'found'; }, 2);
- $this->events->attach('foo.bar', function () { return 'zero'; }, 1);
- $responses = $this->events->triggerUntil('foo.bar', $this, array(), function ($result) {
- return ($result === 'found');
- });
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertTrue($responses->stopped());
- $result = $responses->last();
- $this->assertEquals('found', $result);
- $this->assertFalse($responses->contains('zero'));
- }
+ $eventManager->trigger('event');
- public function testTriggerUntilShouldMarkResponseCollectionStoppedWhenConditionMetByLastListener()
- {
- $this->events->attach('foo.bar', function () { return 'bogus'; });
- $this->events->attach('foo.bar', function () { return 'nada'; });
- $this->events->attach('foo.bar', function () { return 'zero'; });
- $this->events->attach('foo.bar', function () { return 'found'; });
- $responses = $this->events->triggerUntil('foo.bar', $this, array(), function ($result) {
- return ($result === 'found');
- });
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertTrue($responses->stopped());
- $this->assertEquals('found', $responses->last());
+ $this->assertEquals(0, $count);
}
- public function testResponseCollectionIsNotStoppedWhenNoCallbackMatchedByTriggerUntil()
+ public function testCanDetachListenerWithEventName()
{
- $this->events->attach('foo.bar', function () { return 'bogus'; }, 4);
- $this->events->attach('foo.bar', function () { return 'nada'; }, 3);
- $this->events->attach('foo.bar', function () { return 'found'; }, 2);
- $this->events->attach('foo.bar', function () { return 'zero'; }, 1);
- $responses = $this->events->triggerUntil('foo.bar', $this, array(), function ($result) {
- return ($result === 'never found');
- });
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertFalse($responses->stopped());
- $this->assertEquals('zero', $responses->last());
- }
+ $eventManager = new EventManager();
+ $count = 0;
- public function testCanAttachListenerAggregate()
- {
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attachAggregate($aggregate);
- $events = $this->events->getEvents();
- foreach (array('foo.bar', 'foo.baz') as $event) {
- $this->assertContains($event, $events);
- }
- }
+ $listener = $eventManager->attach('event', function() use (&$count) { $count++; });
+ $this->assertTrue($eventManager->detach($listener), 'event');
- public function testCanAttachListenerAggregateViaAttach()
- {
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attach($aggregate);
- $events = $this->events->getEvents();
- foreach (array('foo.bar', 'foo.baz') as $event) {
- $this->assertContains($event, $events);
- }
- }
+ $eventManager->trigger('event');
- public function testAttachAggregateReturnsAttachOfListenerAggregate()
- {
- $aggregate = new TestAsset\MockAggregate();
- $method = $this->events->attachAggregate($aggregate);
- $this->assertSame('ZendTest\EventManager\TestAsset\MockAggregate::attach', $method);
+ $this->assertEquals(0, $count);
}
- public function testCanDetachListenerAggregates()
+ public function testCanDetachAggregate()
{
- // setup some other event listeners, to ensure appropriate items are detached
- $listenerFooBar1 = $this->events->attach('foo.bar', function () {
- return true;
- });
- $listenerFooBar2 = $this->events->attach('foo.bar', function () {
- return true;
- });
- $listenerFooBaz1 = $this->events->attach('foo.baz', function () {
- return true;
- });
- $listenerOther = $this->events->attach('other', function () {
- return true;
- });
-
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attachAggregate($aggregate);
- $this->events->detachAggregate($aggregate);
- $events = $this->events->getEvents();
- foreach (array('foo.bar', 'foo.baz', 'other') as $event) {
- $this->assertContains($event, $events);
- }
-
- $listeners = $this->events->getListeners('foo.bar');
- $this->assertEquals(2, count($listeners));
- $this->assertContains($listenerFooBar1, $listeners);
- $this->assertContains($listenerFooBar2, $listeners);
-
- $listeners = $this->events->getListeners('foo.baz');
- $this->assertEquals(1, count($listeners));
- $this->assertContains($listenerFooBaz1, $listeners);
-
- $listeners = $this->events->getListeners('other');
- $this->assertEquals(1, count($listeners));
- $this->assertContains($listenerOther, $listeners);
- }
+ $listenerAggregate = $this->getMock('Zend\EventManager\ListenerAggregateInterface');
+ $eventManager = new EventManager();
- public function testCanDetachListenerAggregatesViaDetach()
- {
- // setup some other event listeners, to ensure appropriate items are detached
- $listenerFooBar1 = $this->events->attach('foo.bar', function () {
- return true;
- });
- $listenerFooBar2 = $this->events->attach('foo.bar', function () {
- return true;
- });
- $listenerFooBaz1 = $this->events->attach('foo.baz', function () {
- return true;
- });
- $listenerOther = $this->events->attach('other', function () {
- return true;
- });
-
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attach($aggregate);
- $this->events->detach($aggregate);
- $events = $this->events->getEvents();
- foreach (array('foo.bar', 'foo.baz', 'other') as $event) {
- $this->assertContains($event, $events);
- }
-
- $listeners = $this->events->getListeners('foo.bar');
- $this->assertEquals(2, count($listeners));
- $this->assertContains($listenerFooBar1, $listeners);
- $this->assertContains($listenerFooBar2, $listeners);
-
- $listeners = $this->events->getListeners('foo.baz');
- $this->assertEquals(1, count($listeners));
- $this->assertContains($listenerFooBaz1, $listeners);
-
- $listeners = $this->events->getListeners('other');
- $this->assertEquals(1, count($listeners));
- $this->assertContains($listenerOther, $listeners);
- }
+ $listenerAggregate->expects($this->once())
+ ->method('detach')
+ ->with($eventManager);
- public function testDetachAggregateReturnsDetachOfListenerAggregate()
- {
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attachAggregate($aggregate);
- $method = $this->events->detachAggregate($aggregate);
- $this->assertSame('ZendTest\EventManager\TestAsset\MockAggregate::detach', $method);
+ $eventManager->detachAggregate($listenerAggregate);
}
- public function testAttachAggregateAcceptsOptionalPriorityValue()
+ public function testExtractEventNames()
{
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attachAggregate($aggregate, 1);
- $this->assertEquals(1, $aggregate->priority);
- }
+ $eventManager = new EventManager();
- public function testAttachAggregateAcceptsOptionalPriorityValueViaAttachCallbackArgument()
- {
- $aggregate = new TestAsset\MockAggregate();
- $this->events->attach($aggregate, 1);
- $this->assertEquals(1, $aggregate->priority);
- }
+ $eventManager->attach('event1', function() {});
+ $eventManager->attach('event2', function() {});
- public function testCallingEventsStopPropagationMethodHaltsEventEmission()
- {
- $this->events->attach('foo.bar', function ($e) { return 'bogus'; }, 4);
- $this->events->attach('foo.bar', function ($e) { $e->stopPropagation(true); return 'nada'; }, 3);
- $this->events->attach('foo.bar', function ($e) { return 'found'; }, 2);
- $this->events->attach('foo.bar', function ($e) { return 'zero'; }, 1);
- $responses = $this->events->trigger('foo.bar', $this, array());
- $this->assertTrue($responses instanceof ResponseCollection);
- $this->assertTrue($responses->stopped());
- $this->assertEquals('nada', $responses->last());
- $this->assertTrue($responses->contains('bogus'));
- $this->assertFalse($responses->contains('found'));
- $this->assertFalse($responses->contains('zero'));
+ $this->assertEquals(['event1', 'event2'], $eventManager->getEventNames());
}
- public function testCanAlterParametersWithinAEvent()
+ public function testCanTriggerListenersByPriority()
{
- $this->events->attach('foo.bar', function ($e) { $e->setParam('foo', 'bar'); });
- $this->events->attach('foo.bar', function ($e) { $e->setParam('bar', 'baz'); });
- $this->events->attach('foo.bar', function ($e) {
- $foo = $e->getParam('foo', '__NO_FOO__');
- $bar = $e->getParam('bar', '__NO_BAR__');
- return $foo . ":" . $bar;
- });
- $responses = $this->events->trigger('foo.bar', $this, array());
- $this->assertEquals('bar:baz', $responses->last());
- }
+ $eventManager = new EventManager();
- public function testParametersArePassedToEventByReference()
- {
- $params = array( 'foo' => 'bar', 'bar' => 'baz');
- $args = $this->events->prepareArgs($params);
- $this->events->attach('foo.bar', function ($e) { $e->setParam('foo', 'FOO'); });
- $this->events->attach('foo.bar', function ($e) { $e->setParam('bar', 'BAR'); });
- $responses = $this->events->trigger('foo.bar', $this, $args);
- $this->assertEquals('FOO', $args['foo']);
- $this->assertEquals('BAR', $args['bar']);
- }
+ // When using listeners with same priority, assert first one is executed first
+ $chain = '';
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '1'; });
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '2'; });
+ $eventManager->trigger('event');
- public function testCanPassObjectForEventParameters()
- {
- $params = (object) array( 'foo' => 'bar', 'bar' => 'baz');
- $this->events->attach('foo.bar', function ($e) { $e->setParam('foo', 'FOO'); });
- $this->events->attach('foo.bar', function ($e) { $e->setParam('bar', 'BAR'); });
- $responses = $this->events->trigger('foo.bar', $this, $params);
- $this->assertEquals('FOO', $params->foo);
- $this->assertEquals('BAR', $params->bar);
- }
+ $this->assertEquals('12', $chain);
- public function testCanPassEventObjectAsSoleArgumentToTrigger()
- {
- $event = new Event();
- $event->setName(__FUNCTION__);
- $event->setTarget($this);
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->trigger($event);
- $this->assertSame($event, $responses->last());
- }
+ // Assert priority is respected
+ $chain = '';
+ $eventManager->clearListeners('event');
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '1'; }, 50);
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '3'; }, -50);
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '2'; }, 0);
+ $eventManager->trigger('event');
- public function testCanPassEventNameAndEventObjectAsSoleArgumentsToTrigger()
- {
- $event = new Event();
- $event->setTarget($this);
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->trigger(__FUNCTION__, $event);
- $this->assertSame($event, $responses->last());
- $this->assertEquals(__FUNCTION__, $event->getName());
- }
+ $this->assertEquals('123', $chain);
- public function testCanPassEventObjectAsArgvToTrigger()
- {
- $event = new Event();
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->trigger(__FUNCTION__, $this, $event);
- $this->assertSame($event, $responses->last());
- $this->assertEquals(__FUNCTION__, $event->getName());
- $this->assertSame($this, $event->getTarget());
- }
+ // Assert wildcard is always executed, and respect priority
+ $chain = '';
+ $eventManager->clearListeners('event');
+ $eventManager->attach('*', function() use (&$chain) { $chain .= '2'; }, -500);
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '1'; }, -50);
+ $eventManager->trigger('event');
- public function testCanPassEventObjectAndCallbackAsSoleArgumentsToTriggerUntil()
- {
- $event = new Event();
- $event->setName(__FUNCTION__);
- $event->setTarget($this);
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->triggerUntil($event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
- $this->assertSame($event, $responses->last());
+ $this->assertEquals('12', $chain);
}
- public function testCanPassEventNameAndEventObjectAndCallbackAsSoleArgumentsToTriggerUntil()
+ public function testCanTriggerListenersWithSharedManager()
{
- $event = new Event();
- $event->setTarget($this);
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->triggerUntil(__FUNCTION__, $event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
- $this->assertSame($event, $responses->last());
- $this->assertEquals(__FUNCTION__, $event->getName());
- }
+ $eventManager = new EventManager(['identifier']);
+ $sharedEventManager = new SharedEventManager();
- public function testCanPassEventObjectAsArgvToTriggerUntil()
- {
- $event = new Event();
- $event->setParams(array('foo' => 'bar'));
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
- $responses = $this->events->triggerUntil(__FUNCTION__, $this, $event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
- $this->assertSame($event, $responses->last());
- $this->assertEquals(__FUNCTION__, $event->getName());
- $this->assertSame($this, $event->getTarget());
- }
+ $eventManager->setSharedManager($sharedEventManager);
- public function testTriggerCanTakeAnOptionalCallbackArgumentToEmulateTriggerUntil()
- {
- $this->events->attach(__FUNCTION__, function ($e) {
- return $e;
- });
-
- // Four scenarios:
- // First: normal signature:
- $responses = $this->events->trigger(__FUNCTION__, $this, array(), function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
-
- // Second: Event as $argv parameter:
- $event = new Event();
- $responses = $this->events->trigger(__FUNCTION__, $this, $event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
-
- // Third: Event as $target parameter:
- $event = new Event();
- $event->setTarget($this);
- $responses = $this->events->trigger(__FUNCTION__, $event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
-
- // Fourth: Event as $event parameter:
- $event = new Event();
- $event->setTarget($this);
- $event->setName(__FUNCTION__);
- $responses = $this->events->trigger($event, function ($r) {
- return ($r instanceof EventInterface);
- });
- $this->assertTrue($responses->stopped());
+ //
}
- public function testDuplicateIdentifiersAreNotRegistered()
+ /**
+ * This test assert that if an event manager contains listeners with same priority for event name,
+ * wildcard and shared manager, those listeners are executed in an expected order (first event, then
+ * wildcard, then shared manager)
+ */
+ public function testAssertOrder()
{
- $events = new EventManager(array(__CLASS__, get_class($this)));
- $identifiers = $events->getIdentifiers();
- $this->assertSame(count($identifiers), 1);
- $this->assertSame($identifiers[0], __CLASS__);
- $events->addIdentifiers(__CLASS__);
- $this->assertSame(count($identifiers), 1);
- $this->assertSame($identifiers[0], __CLASS__);
- }
+ $eventManager = new EventManager(['identifier']);
+ $sharedEventManager = new SharedEventManager();
+ $chain = '';
- public function testIdentifierGetterSettersWorkWithStrings()
- {
- $identifier1 = 'foo';
- $identifiers = array($identifier1);
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->setIdentifiers($identifier1));
- $this->assertSame($this->events->getIdentifiers(), $identifiers);
- $identifier2 = 'baz';
- $identifiers = array($identifier1, $identifier2);
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->addIdentifiers($identifier2));
- $this->assertSame($this->events->getIdentifiers(), $identifiers);
- }
+ $eventManager->setSharedManager($sharedEventManager);
- public function testIdentifierGetterSettersWorkWithArrays()
- {
- $identifiers = array('foo', 'bar');
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->setIdentifiers($identifiers));
- $this->assertSame($this->events->getIdentifiers(), $identifiers);
- $identifiers[] = 'baz';
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->addIdentifiers($identifiers));
-
- // This is done because the keys doesn't matter, just the values
- $expectedIdentifiers = $this->events->getIdentifiers();
- sort($expectedIdentifiers);
- sort($identifiers);
- $this->assertSame($expectedIdentifiers, $identifiers);
- }
+ $eventManager->attach('*', function() use (&$chain) { $chain .= '2'; });
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '1'; });
+ $sharedEventManager->attach('identifier', 'event', function() use (&$chain) { $chain .= '3'; });
- public function testIdentifierGetterSettersWorkWithTraversables()
- {
- $identifiers = new ArrayIterator(array('foo', 'bar'));
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->setIdentifiers($identifiers));
- $this->assertSame($this->events->getIdentifiers(), (array) $identifiers);
- $identifiers = new ArrayIterator(array('foo', 'bar', 'baz'));
- $this->assertInstanceOf('Zend\EventManager\EventManager', $this->events->addIdentifiers($identifiers));
-
- // This is done because the keys doesn't matter, just the values
- $expectedIdentifiers = $this->events->getIdentifiers();
- sort($expectedIdentifiers);
- $identifiers = (array) $identifiers;
- sort($identifiers);
- $this->assertSame($expectedIdentifiers, $identifiers);
- }
+ $eventManager->trigger('event');
- public function testListenersAttachedWithWildcardAreTriggeredForAllEvents()
- {
- $test = new stdClass;
- $test->events = array();
- $callback = function ($e) use ($test) {
- $test->events[] = $e->getName();
- };
-
- $this->events->attach('*', $callback);
- foreach (array('foo', 'bar', 'baz') as $event) {
- $this->events->trigger($event);
- $this->assertContains($event, $test->events);
- }
+ $this->assertEquals('123', $chain);
}
- public function testSettingSharedEventManagerSetsStaticEventManagerInstance()
+ public function testCanStopPropagationUsingEventObject()
{
- $shared = new SharedEventManager();
- $this->events->setSharedManager($shared);
- $this->assertSame($shared, $this->events->getSharedManager());
- $this->assertSame($shared, StaticEventManager::getInstance());
- }
+ $event = new Event();
+ $eventManager = new EventManager();
+ $chain = '';
- public function testSharedEventManagerAttachReturnsCallbackHandler()
- {
- $shared = new SharedEventManager;
- $callbackHandler = $shared->attach(
- 'foo',
- 'bar',
- function ($e) {
- return true;
- }
- );
- $this->assertTrue($callbackHandler instanceof CallbackHandler);
- }
+ $eventManager->attach('event', function(EventInterface $event) use (&$chain) {
+ $chain .= '1';
+ $event->stopPropagation(true);
+ }, 50);
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '2'; });
- public function testDoesNotCreateStaticInstanceIfNonePresent()
- {
- StaticEventManager::resetInstance();
- $this->assertFalse($this->events->getSharedManager());
+ $response = $eventManager->trigger('event', $event);
+
+ $this->assertTrue($event->isPropagationStopped());
+ $this->assertTrue($response->stopped());
+ $this->assertEquals('1', $chain);
}
- public function testTriggerSetsStopPropagationFlagToFalse()
+ public function testCanStopPropagationUsingCallback()
{
- $marker = (object) array('propagationIsStopped' => true);
- $this->events->attach('foo', function ($e) use ($marker) {
- $marker->propagationIsStopped = $e->propagationIsStopped();
- });
+ $event = new Event();
+ $eventManager = new EventManager();
+ $chain = '';
- $event = new Event();
- $event->stopPropagation(true);
- $this->events->trigger('foo', $event);
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '1'; });
+ $eventManager->attach('event', function() use (&$chain) { $chain .= '2'; });
- $this->assertFalse($marker->propagationIsStopped);
- $this->assertFalse($event->propagationIsStopped());
- }
+ $response = $eventManager->trigger('event', $event, function() { return true; });
- public function testTriggerUntilSetsStopPropagationFlagToFalse()
- {
- $marker = (object) array('propagationIsStopped' => true);
- $this->events->attach('foo', function ($e) use ($marker) {
- $marker->propagationIsStopped = $e->propagationIsStopped();
- });
-
- $criteria = function ($r) {
- return false;
- };
- $event = new Event();
- $event->stopPropagation(true);
- $this->events->triggerUntil('foo', $event, $criteria);
-
- $this->assertFalse($marker->propagationIsStopped);
- $this->assertFalse($event->propagationIsStopped());
+ $this->assertTrue($response->stopped());
+ $this->assertEquals('1', $chain);
}
}
diff --git a/tests/ZendTest/EventManager/EventTest.php b/tests/ZendTest/EventManager/EventTest.php
new file mode 100644
index 00000000000..d328ceb0bf9
--- /dev/null
+++ b/tests/ZendTest/EventManager/EventTest.php
@@ -0,0 +1,77 @@
+assertSame($target, $event->getTarget());
+ $this->assertEquals($params, $event->getParams());
+ }
+
+ public function paramsProvider()
+ {
+ return array(
+ array(
+ 'foo' => 'bar',
+ 'baz' => 'cat'
+ ),
+ array(
+ new \ArrayIterator(array(
+ 'foo' => 'bar',
+ 'baz' => 'cat'
+ ))
+ )
+ );
+ }
+
+ /**
+ * @dataProvider paramsProvider
+ */
+ public function testSetParams($params)
+ {
+ $event = new Event();
+ $event->setParams($params);
+
+ if ($params instanceof Traversable) {
+ $params = iterator_to_array($params);
+ }
+
+ $this->assertEquals($params, $event->getParams());
+ }
+
+ public function testCanGetDefaultParam()
+ {
+ $event = new Event();
+
+ $event->setParam('foo', 'bar');
+ $this->assertEquals('bar', $event->getParam('foo'));
+
+ $this->assertEquals('default', $event->getParam('baz', 'default'));
+ }
+
+ public function testAssertPropagationIsStoppedByDefault()
+ {
+ $event = new Event();
+ $this->assertFalse($event->isPropagationStopped());
+
+ $event->stopPropagation(true);
+ $this->assertTrue($event->isPropagationStopped());
+ }
+}
diff --git a/tests/ZendTest/EventManager/FilterChainTest.php b/tests/ZendTest/EventManager/FilterChainTest.php
deleted file mode 100644
index b0cb741d0b3..00000000000
--- a/tests/ZendTest/EventManager/FilterChainTest.php
+++ /dev/null
@@ -1,146 +0,0 @@
-message)) {
- unset($this->message);
- }
- $this->filterchain = new FilterChain;
- }
-
- public function testSubscribeShouldReturnCallbackHandler()
- {
- $handle = $this->filterchain->attach(array( $this, __METHOD__ ));
- $this->assertTrue($handle instanceof CallbackHandler);
- }
-
- public function testSubscribeShouldAddCallbackHandlerToFilters()
- {
- $handler = $this->filterchain->attach(array($this, __METHOD__));
- $handlers = $this->filterchain->getFilters();
- $this->assertEquals(1, count($handlers));
- $this->assertTrue($handlers->contains($handler));
- }
-
- public function testDetachShouldRemoveCallbackHandlerFromFilters()
- {
- $handle = $this->filterchain->attach(array( $this, __METHOD__ ));
- $handles = $this->filterchain->getFilters();
- $this->assertTrue($handles->contains($handle));
- $this->filterchain->detach($handle);
- $handles = $this->filterchain->getFilters();
- $this->assertFalse($handles->contains($handle));
- }
-
- public function testDetachShouldReturnFalseIfCallbackHandlerDoesNotExist()
- {
- $handle1 = $this->filterchain->attach(array( $this, __METHOD__ ));
- $this->filterchain->clearFilters();
- $handle2 = $this->filterchain->attach(array( $this, 'handleTestTopic' ));
- $this->assertFalse($this->filterchain->detach($handle1));
- }
-
- public function testRetrievingAttachedFiltersShouldReturnEmptyArrayWhenNoFiltersExist()
- {
- $handles = $this->filterchain->getFilters();
- $this->assertEquals(0, count($handles));
- }
-
- public function testFilterChainShouldReturnLastResponse()
- {
- $this->filterchain->attach(function ($context, $params, $chain) {
- if (isset($params['string'])) {
- $params['string'] = trim($params['string']);
- }
- $return = $chain->next($context, $params, $chain);
- return $return;
- });
- $this->filterchain->attach(function ($context, array $params) {
- $string = isset($params['string']) ? $params['string'] : '';
- return str_rot13($string);
- });
- $value = $this->filterchain->run($this, array('string' => ' foo '));
- $this->assertEquals(str_rot13(trim(' foo ')), $value);
- }
-
- public function testFilterIsPassedContextAndArguments()
- {
- $this->filterchain->attach(array( $this, 'filterTestCallback1' ));
- $obj = (object) array('foo' => 'bar', 'bar' => 'baz');
- $value = $this->filterchain->run($this, array('object' => $obj));
- $this->assertEquals('filtered', $value);
- $this->assertEquals('filterTestCallback1', $this->message);
- $this->assertEquals('foobarbaz', $obj->foo);
- }
-
- public function testInterceptingFilterShouldReceiveChain()
- {
- $this->filterchain->attach(array($this, 'filterReceivalCallback'));
- $this->filterchain->run($this);
- }
-
- public function testFilteringStopsAsSoonAsAFilterFailsToCallNext()
- {
- $this->filterchain->attach(function ($context, $params, $chain) {
- if (isset($params['string'])) {
- $params['string'] = trim($params['string']);
- }
- return $chain->next($context, $params, $chain);
- }, 10000);
- $this->filterchain->attach(function ($context, array $params) {
- $string = isset($params['string']) ? $params['string'] : '';
- return str_rot13($string);
- }, 1000);
- $this->filterchain->attach(function ($context, $params, $chain) {
- $string = isset($params['string']) ? $params['string'] : '';
- return hash('md5', $string);
- }, 100);
- $value = $this->filterchain->run($this, array('string' => ' foo '));
- $this->assertEquals(str_rot13(trim(' foo ')), $value);
- }
-
- public function handleTestTopic($message)
- {
- $this->message = $message;
- }
-
- public function filterTestCallback1($context, array $params)
- {
- $context->message = __FUNCTION__;
- if (isset($params['object']) && is_object($params['object'])) {
- $params['object']->foo = 'foobarbaz';
- }
- return 'filtered';
- }
-
- public function filterReceivalCallback($context, array $params, $chain)
- {
- $this->assertInstanceOf('Zend\EventManager\Filter\FilterIterator', $chain);
- }
-}
diff --git a/tests/ZendTest/EventManager/GlobalEventManagerTest.php b/tests/ZendTest/EventManager/GlobalEventManagerTest.php
deleted file mode 100644
index 27f627a2edf..00000000000
--- a/tests/ZendTest/EventManager/GlobalEventManagerTest.php
+++ /dev/null
@@ -1,90 +0,0 @@
-assertInstanceOf('Zend\EventManager\EventManager', $events);
- }
-
- public function testPassingNullValueForEventCollectionResetsInstance()
- {
- $events = GlobalEventManager::getEventCollection();
- $this->assertInstanceOf('Zend\EventManager\EventManager', $events);
- GlobalEventManager::setEventCollection(null);
- $events2 = GlobalEventManager::getEventCollection();
- $this->assertInstanceOf('Zend\EventManager\EventManager', $events2);
- $this->assertNotSame($events, $events2);
- }
-
- public function testProxiesAllStaticOperationsToEventCollectionInstance()
- {
- $test = new \stdClass();
- $listener = GlobalEventManager::attach('foo.bar', function ($e) use ($test) {
- $test->event = $e->getName();
- $test->target = $e->getTarget();
- $test->params = $e->getParams();
- return $test->params;
- });
- $this->assertInstanceOf('Zend\Stdlib\CallbackHandler', $listener);
-
- GlobalEventManager::trigger('foo.bar', $this, array('foo' => 'bar'));
- $this->assertSame($this, $test->target);
- $this->assertEquals('foo.bar', $test->event);
- $this->assertEquals(array('foo' => 'bar'), $test->params);
-
- $results = GlobalEventManager::triggerUntil('foo.bar', $this, array('baz' => 'bat'), function ($r) {
- return is_array($r);
- });
- $this->assertTrue($results->stopped());
- $this->assertEquals(array('baz' => 'bat'), $test->params);
- $this->assertEquals(array('baz' => 'bat'), $results->last());
-
- $events = GlobalEventManager::getEvents();
- $this->assertEquals(array('foo.bar'), $events);
-
- $listeners = GlobalEventManager::getListeners('foo.bar');
- $this->assertEquals(1, count($listeners));
- $this->assertTrue($listeners->contains($listener));
-
- GlobalEventManager::detach($listener);
- $events = GlobalEventManager::getEvents();
- $this->assertEquals(array(), $events);
-
- $listener = GlobalEventManager::attach('foo.bar', function ($e) use ($test) {
- $test->event = $e->getEvent();
- $test->target = $e->getTarget();
- $test->params = $e->getParams();
- });
- $events = GlobalEventManager::getEvents();
- $this->assertEquals(array('foo.bar'), $events);
- GlobalEventManager::clearListeners('foo.bar');
- $events = GlobalEventManager::getEvents();
- $this->assertEquals(array(), $events);
- }
-}
diff --git a/tests/ZendTest/EventManager/ListenerAggregateTraitTest.php b/tests/ZendTest/EventManager/ListenerAggregateTraitTest.php
deleted file mode 100644
index b2be00f2e44..00000000000
--- a/tests/ZendTest/EventManager/ListenerAggregateTraitTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-getMock('Zend\\EventManager\\EventManagerInterface');
- $unrelatedEventManager = $this->getMock('Zend\\EventManager\\EventManagerInterface');
- $callbackHandlers = array();
- $test = $this;
-
- $eventManager
- ->expects($this->exactly(2))
- ->method('attach')
- ->will($this->returnCallback(function () use (&$callbackHandlers, $test) {
- return $callbackHandlers[] = $test->getMock('Zend\\Stdlib\\CallbackHandler', array(), array(), '', false);
- }));
-
- $listener->attach($eventManager);
- $this->assertSame($callbackHandlers, $listener->getCallbacks());
-
- $listener->detach($unrelatedEventManager);
-
- $this->assertSame($callbackHandlers, $listener->getCallbacks());
-
- $eventManager
- ->expects($this->exactly(2))
- ->method('detach')
- ->with($this->callback(function ($callbackHandler) use ($callbackHandlers) {
- return in_array($callbackHandler, $callbackHandlers, true);
- }))
- ->will($this->returnValue(true));
-
- $listener->detach($eventManager);
- $this->assertEmpty($listener->getCallbacks());
- }
-}
diff --git a/tests/ZendTest/EventManager/ResponseCollectionTest.php b/tests/ZendTest/EventManager/ResponseCollectionTest.php
new file mode 100644
index 00000000000..79792ae7b78
--- /dev/null
+++ b/tests/ZendTest/EventManager/ResponseCollectionTest.php
@@ -0,0 +1,43 @@
+assertFalse($responseCollection->stopped());
+ $this->assertEquals('value3', $responseCollection->last());
+ $this->assertEquals('value1', $responseCollection->first());
+
+ $responseCollection->setStopped(true);
+ $this->assertTrue($responseCollection->stopped());
+ $this->assertTrue($responseCollection->contains('value1'));
+ $this->assertFalse($responseCollection->contains('value4'));
+ }
+
+ public function testResponseCollectionIsIterableAndCountable()
+ {
+ $responseCollection = new ResponseCollection(array('value1', 'value2', 'value3'));
+ $i = 1;
+
+ foreach ($responseCollection as $response) {
+ $this->assertEquals("value$i", $response);
+ ++$i;
+ }
+
+ $this->assertCount(3, $responseCollection);
+ }
+}
diff --git a/tests/ZendTest/EventManager/SharedEventManagerTest.php b/tests/ZendTest/EventManager/SharedEventManagerTest.php
new file mode 100644
index 00000000000..247c0bba605
--- /dev/null
+++ b/tests/ZendTest/EventManager/SharedEventManagerTest.php
@@ -0,0 +1,40 @@
+getMock('Zend\EventManager\SharedListenerAggregateInterface');
+ $sharedEventManager = new SharedEventManager();
+
+ $listenerAggregate->expects($this->once())
+ ->method('attachShared')
+ ->with($sharedEventManager, 1);
+
+ $sharedEventManager->attachAggregate($listenerAggregate);
+ }
+
+ public function testCanDetachAggregate()
+ {
+ $listenerAggregate = $this->getMock('Zend\EventManager\SharedListenerAggregateInterface');
+ $sharedEventManager = new SharedEventManager();
+
+ $listenerAggregate->expects($this->once())
+ ->method('detachShared')
+ ->with($sharedEventManager);
+
+ $sharedEventManager->detachAggregate($listenerAggregate);
+ }
+}
diff --git a/tests/ZendTest/EventManager/StaticEventManagerTest.php b/tests/ZendTest/EventManager/StaticEventManagerTest.php
deleted file mode 100644
index c4818e86f0c..00000000000
--- a/tests/ZendTest/EventManager/StaticEventManagerTest.php
+++ /dev/null
@@ -1,334 +0,0 @@
-assertSame($expected, $test);
- }
-
- public function testCanResetInstance()
- {
- $original = StaticEventManager::getInstance();
- StaticEventManager::resetInstance();
- $test = StaticEventManager::getInstance();
- $this->assertNotSame($original, $test);
- }
-
- public function testSingletonInstanceIsInstanceOfClass()
- {
- $this->assertInstanceOf('Zend\EventManager\StaticEventManager', StaticEventManager::getInstance());
- }
-
- public function testCanAttachCallbackToEvent()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- $this->assertContains('bar', $events->getEvents('foo'));
- $expected = array($this, __FUNCTION__);
- $found = false;
- $listeners = $events->getListeners('foo', 'bar');
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertTrue(0 < count($listeners), 'Empty listeners!');
- foreach ($listeners as $listener) {
- if ($expected === $listener->getCallback()) {
- $found = true;
- break;
- }
- }
- $this->assertTrue($found, 'Did not find listener!');
- }
-
- public function testCanAttachCallbackToMultipleEventsAtOnce()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('bar', array('foo', 'test'), array($this, __FUNCTION__));
- $this->assertContains('foo', $events->getEvents('bar'));
- $this->assertContains('test', $events->getEvents('bar'));
- $expected = array($this, __FUNCTION__);
- foreach (array('foo', 'test') as $event) {
- $found = false;
- $listeners = $events->getListeners('bar', $event);
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertTrue(0 < count($listeners), 'Empty listeners!');
- foreach ($listeners as $listener) {
- if ($expected === $listener->getCallback()) {
- $found = true;
- break;
- }
- }
- $this->assertTrue($found, 'Did not find listener!');
- }
- }
-
- public function testCanAttachSameEventToMultipleResourcesAtOnce()
- {
- $events = StaticEventManager::getInstance();
- $events->attach(array('foo', 'test'), 'bar', array($this, __FUNCTION__));
- $this->assertContains('bar', $events->getEvents('foo'));
- $this->assertContains('bar', $events->getEvents('test'));
- $expected = array($this, __FUNCTION__);
- foreach (array('foo', 'test') as $id) {
- $found = false;
- $listeners = $events->getListeners($id, 'bar');
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertTrue(0 < count($listeners), 'Empty listeners!');
- foreach ($listeners as $listener) {
- if ($expected === $listener->getCallback()) {
- $found = true;
- break;
- }
- }
- $this->assertTrue($found, 'Did not find listener!');
- }
- }
-
- public function testCanAttachCallbackToMultipleEventsOnMultipleResourcesAtOnce()
- {
- $events = StaticEventManager::getInstance();
- $events->attach(array('bar', 'baz'), array('foo', 'test'), array($this, __FUNCTION__));
- $this->assertContains('foo', $events->getEvents('bar'));
- $this->assertContains('test', $events->getEvents('bar'));
- $expected = array($this, __FUNCTION__);
- foreach (array('bar', 'baz') as $resource) {
- foreach (array('foo', 'test') as $event) {
- $found = false;
- $listeners = $events->getListeners($resource, $event);
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertTrue(0 < count($listeners), 'Empty listeners!');
- foreach ($listeners as $listener) {
- if ($expected === $listener->getCallback()) {
- $found = true;
- break;
- }
- }
- $this->assertTrue($found, 'Did not find listener!');
- }
- }
- }
-
- public function testListenersAttachedUsingWildcardEventWillBeTriggeredByResource()
- {
- $test = new stdClass;
- $test->events = array();
- $callback = function ($e) use ($test) {
- $test->events[] = $e->getName();
- };
-
- $staticEvents = StaticEventManager::getInstance();
- $staticEvents->attach('bar', '*', $callback);
-
- $events = new EventManager('bar');
- $events->setSharedManager($staticEvents);
-
- foreach (array('foo', 'bar', 'baz') as $event) {
- $events->trigger($event);
- $this->assertContains($event, $test->events);
- }
- }
-
- public function testCanDetachListenerFromResource()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- foreach ($events->getListeners('foo', 'bar') as $listener) {
- // only one; retrieving it so we can detach
- }
- $events->detach('foo', $listener);
- $listeners = $events->getListeners('foo', 'bar');
- $this->assertEquals(0, count($listeners));
- }
-
- public function testCanGetEventsByResource()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- $this->assertEquals(array('bar'), $events->getEvents('foo'));
- }
-
- public function testCanGetEventsByWildcard()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('*', 'bar', array($this, __FUNCTION__));
- $this->assertEquals(array('bar'), $events->getEvents('foo'));
- }
-
- public function testCanGetListenersByResourceAndEvent()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- $listeners = $events->getListeners('foo', 'bar');
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertEquals(1, count($listeners));
- }
-
- public function testCanNotGetListenersByResourceAndEventWithWildcard()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('*', 'bar', array($this, __FUNCTION__));
- $listeners = $events->getListeners('foo', 'bar');
- $this->assertFalse($listeners);
- }
-
- public function testCanGetListenersByWildcardAndEvent()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('*', 'bar', array($this, __FUNCTION__));
- $listeners = $events->getListeners('*', 'bar');
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $listeners);
- $this->assertEquals(1, count($listeners));
- }
-
- public function testCanClearListenersByResource()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- $events->attach('foo', 'baz', array($this, __FUNCTION__));
- $events->clearListeners('foo');
- $this->assertFalse($events->getListeners('foo', 'bar'));
- $this->assertFalse($events->getListeners('foo', 'baz'));
- }
-
- public function testCanClearListenersByResourceAndEvent()
- {
- $events = StaticEventManager::getInstance();
- $events->attach('foo', 'bar', array($this, __FUNCTION__));
- $events->attach('foo', 'baz', array($this, __FUNCTION__));
- $events->attach('foo', 'bat', array($this, __FUNCTION__));
- $events->clearListeners('foo', 'baz');
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $events->getListeners('foo', 'baz'));
- $this->assertEquals(0, count($events->getListeners('foo', 'baz')));
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $events->getListeners('foo', 'bar'));
- $this->assertEquals(1, count($events->getListeners('foo', 'bar')));
- $this->assertInstanceOf('Zend\Stdlib\PriorityQueue', $events->getListeners('foo', 'bat'));
- $this->assertEquals(1, count($events->getListeners('foo', 'bat')));
- }
-
- public function testCanPassArrayOfIdentifiersToConstructor()
- {
- $identifiers = array('foo', 'bar');
- $manager = new EventManager($identifiers);
- }
-
- public function testListenersAttachedToAnyIdentifierProvidedToEventManagerWillBeTriggered()
- {
- $identifiers = array('foo', 'bar');
- $events = StaticEventManager::getInstance();
- $manager = new EventManager($identifiers);
- $manager->setSharedManager($events);
-
- $test = new \stdClass;
- $test->triggered = 0;
- $events->attach('foo', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $events->attach('bar', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $manager->trigger('bar', $this, array());
- $this->assertEquals(2, $test->triggered);
- }
-
- public function testListenersAttachedToWildcardsWillBeTriggered()
- {
- $identifiers = array('foo', 'bar');
- $events = StaticEventManager::getInstance();
- $manager = new EventManager($identifiers);
- $manager->setSharedManager($events);
-
- $test = new \stdClass;
- $test->triggered = 0;
- $events->attach('*', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- //Tests one can have multiple wildcards attached
- $events->attach('*', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $manager->trigger('bar', $this, array());
- $this->assertEquals(2, $test->triggered);
- }
-
- public function testListenersAttachedToAnyIdentifierProvidedToEventManagerOrWildcardsWillBeTriggered()
- {
- $identifiers = array('foo', 'bar');
- $events = StaticEventManager::getInstance();
- $manager = new EventManager($identifiers);
- $manager->setSharedManager($events);
-
- $test = new \stdClass;
- $test->triggered = 0;
- $events->attach('foo', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $events->attach('bar', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $events->attach('*', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- //Tests one can have multiple wildcards attached
- $events->attach('*', 'bar', function ($e) use ($test) {
- $test->triggered++;
- });
- $manager->trigger('bar', $this, array());
- $this->assertEquals(4, $test->triggered);
- }
-
- public function testCanAttachListenerAggregate()
- {
- $staticManager = StaticEventManager::getInstance();
- $aggregate = new TestAsset\SharedMockAggregate('bazinga');
- $staticManager->attachAggregate($aggregate);
-
- $events = $staticManager->getEvents('bazinga');
- $this->assertCount(2, $events);
- }
-
- public function testCanDetachListenerAggregate()
- {
- $staticManager = StaticEventManager::getInstance();
- $aggregate = new TestAsset\SharedMockAggregate('bazinga');
-
- $staticManager->attachAggregate($aggregate);
- $events = $staticManager->getEvents('bazinga');
- $this->assertCount(2, $events);
-
- $staticManager->detachAggregate($aggregate);
- $events = $staticManager->getEvents('bazinga');
- $this->assertCount(0, $events);
- }
-}
diff --git a/tests/ZendTest/EventManager/StaticIntegrationTest.php b/tests/ZendTest/EventManager/StaticIntegrationTest.php
deleted file mode 100644
index 2a82fcae7cc..00000000000
--- a/tests/ZendTest/EventManager/StaticIntegrationTest.php
+++ /dev/null
@@ -1,148 +0,0 @@
- 0);
- $events = StaticEventManager::getInstance();
- $events->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($counter) {
- $counter->count++;
- }
- );
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->setSharedManager($events);
- $class->foo();
- $this->assertEquals(1, $counter->count);
- }
-
- public function testLocalHandlersAreExecutedPriorToStaticHandlersWhenSetWithSamePriority()
- {
- $test = (object) array('results' => array());
- $events = StaticEventManager::getInstance();
- $events->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($test) {
- $test->results[] = 'static';
- }
- );
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->attach('foo', function ($e) use ($test) {
- $test->results[] = 'local';
- });
- $class->getEventManager()->setSharedManager($events);
- $class->foo();
- $this->assertEquals(array('local', 'static'), $test->results);
- }
-
- public function testLocalHandlersAreExecutedInPriorityOrderRegardlessOfStaticOrLocalRegistration()
- {
- $test = (object) array('results' => array());
- $events = StaticEventManager::getInstance();
- $events->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($test) {
- $test->results[] = 'static';
- },
- 10000 // high priority
- );
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->attach('foo', function ($e) use ($test) {
- $test->results[] = 'local';
- }, 1); // low priority
- $class->getEventManager()->attach('foo', function ($e) use ($test) {
- $test->results[] = 'local2';
- }, 1000); // medium priority
- $class->getEventManager()->attach('foo', function ($e) use ($test) {
- $test->results[] = 'local3';
- }, 15000); // highest priority
- $class->getEventManager()->setSharedManager($events);
- $class->foo();
- $this->assertEquals(array('local3', 'static', 'local2', 'local'), $test->results);
- }
-
- public function testCallingUnsetSharedManagerDisablesStaticManager()
- {
- $counter = (object) array('count' => 0);
- StaticEventManager::getInstance()->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($counter) {
- $counter->count++;
- }
- );
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->unsetSharedManager();
- $class->foo();
- $this->assertEquals(0, $counter->count);
- }
-
- public function testCanPassAlternateStaticConnectionsHolder()
- {
- $counter = (object) array('count' => 0);
- StaticEventManager::getInstance()->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($counter) {
- $counter->count++;
- }
- );
- $mockStaticEvents = new TestAsset\StaticEventsMock();
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->setSharedManager($mockStaticEvents);
- $this->assertSame($mockStaticEvents, $class->getEventManager()->getSharedManager());
- $class->foo();
- $this->assertEquals(0, $counter->count);
- }
-
- public function testTriggerMergesPrioritiesOfStaticAndInstanceListeners()
- {
- $test = (object) array('results' => array());
- $events = StaticEventManager::getInstance();
- $events->attach(
- 'ZendTest\EventManager\TestAsset\ClassWithEvents',
- 'foo',
- function ($e) use ($test) {
- $test->results[] = 'static';
- },
- 100
- );
- $class = new TestAsset\ClassWithEvents();
- $class->getEventManager()->attach('foo', function ($e) use ($test) {
- $test->results[] = 'local';
- }, -100);
- $class->getEventManager()->setSharedManager($events);
- $class->foo();
- $this->assertEquals(array('static', 'local'), $test->results);
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/ClassWithEvents.php b/tests/ZendTest/EventManager/TestAsset/ClassWithEvents.php
deleted file mode 100644
index c752d2ba15d..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/ClassWithEvents.php
+++ /dev/null
@@ -1,41 +0,0 @@
-events = $events;
- }
- if (null === $this->events) {
- $this->events = new EventManager(__CLASS__);
- }
- return $this->events;
- }
-
- public function foo()
- {
- $this->getEventManager()->trigger(__FUNCTION__, $this, array());
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/Functor.php b/tests/ZendTest/EventManager/TestAsset/Functor.php
deleted file mode 100644
index be696480c16..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/Functor.php
+++ /dev/null
@@ -1,19 +0,0 @@
-listeners[] = $events->attach('foo.bar', array($this, 'doFoo'));
- $this->listeners[] = $events->attach('foo.baz', array($this, 'doFoo'));
- }
-
- public function getCallbacks()
- {
- return $this->listeners;
- }
-
- public function doFoo()
- {
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/MockAggregate.php b/tests/ZendTest/EventManager/TestAsset/MockAggregate.php
deleted file mode 100644
index 6d962d57283..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/MockAggregate.php
+++ /dev/null
@@ -1,59 +0,0 @@
-priority = $priority;
-
- $listeners = array();
- $listeners[] = $events->attach('foo.bar', array( $this, 'fooBar' ));
- $listeners[] = $events->attach('foo.baz', array( $this, 'fooBaz' ));
-
- $this->listeners[ \spl_object_hash($events) ] = $listeners;
-
- return __METHOD__;
- }
-
- public function detach(EventManagerInterface $events)
- {
- foreach ($this->listeners[ \spl_object_hash($events) ] as $listener) {
- $events->detach($listener);
- }
-
- return __METHOD__;
- }
-
- public function fooBar()
- {
- return __METHOD__;
- }
-
- public function fooBaz()
- {
- return __METHOD__;
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/MockListenerAggregateTrait.php b/tests/ZendTest/EventManager/TestAsset/MockListenerAggregateTrait.php
deleted file mode 100644
index 13d02e2f15f..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/MockListenerAggregateTrait.php
+++ /dev/null
@@ -1,40 +0,0 @@
-listeners[] = $events->attach('foo.bar', array($this, 'doFoo'));
- $this->listeners[] = $events->attach('foo.baz', array($this, 'doFoo'));
- }
-
- public function getCallbacks()
- {
- return $this->listeners;
- }
-
- public function doFoo()
- {
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/SharedMockAggregate.php b/tests/ZendTest/EventManager/TestAsset/SharedMockAggregate.php
deleted file mode 100644
index 8750fd0cea9..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/SharedMockAggregate.php
+++ /dev/null
@@ -1,66 +0,0 @@
-identity = $identity;
- }
-
- protected $listeners = array();
- public $priority;
-
- public function attachShared(SharedEventManagerInterface $events, $priority = null)
- {
- $this->priority = $priority;
-
- $listeners = array();
- $listeners[] = $events->attach($this->identity, 'foo.bar', array( $this, 'fooBar' ));
- $listeners[] = $events->attach($this->identity, 'foo.baz', array( $this, 'fooBaz' ));
-
- $this->listeners[ \spl_object_hash($events) ] = $listeners;
-
- return __METHOD__;
- }
-
- public function detachShared(SharedEventManagerInterface $events)
- {
- foreach ($this->listeners[ \spl_object_hash($events) ] as $listener) {
- $events->detach($this->identity, $listener);
- }
-
- return __METHOD__;
- }
-
- public function fooBar()
- {
- return __METHOD__;
- }
-
- public function fooBaz()
- {
- return __METHOD__;
- }
-}
diff --git a/tests/ZendTest/EventManager/TestAsset/StaticEventsMock.php b/tests/ZendTest/EventManager/TestAsset/StaticEventsMock.php
deleted file mode 100644
index 4fdb7eada88..00000000000
--- a/tests/ZendTest/EventManager/TestAsset/StaticEventsMock.php
+++ /dev/null
@@ -1,79 +0,0 @@
-setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('boguscallback');
}
@@ -72,53 +72,39 @@ public function testCallShouldReturnTheReturnValueOfTheCallback()
public function testStringCallbackResolvingToClassDefiningInvokeNameShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\Invokable');
}
public function testStringCallbackReferringToClassWithoutDefinedInvokeShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$class = new SignalHandlers\InstanceMethod();
$handler = new CallbackHandler($class);
}
public function testCallbackConsistingOfStringContextWithNonStaticMethodShouldNotRaiseExceptionButWillRaiseEStrict()
{
- $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod', 'handler'));
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
$error = true;
}, E_STRICT);
- $handler->call();
+
+ $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod', 'handler'));
+
restore_error_handler();
+
$this->assertTrue($error);
}
public function testStringCallbackConsistingOfNonStaticMethodShouldRaiseException()
{
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::handler');
-
- if (version_compare(PHP_VERSION, '5.4.0rc1', '>=')) {
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
- $handler->call();
- } else {
- $error = false;
- set_error_handler(function ($errno, $errstr) use (&$error) {
- $error = true;
- }, E_STRICT);
- $handler->call();
- restore_error_handler();
- $this->assertTrue($error);
- }
}
public function testStringStaticCallbackForPhp54()
{
- if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) {
- $this->markTestSkipped('Requires PHP 5.4');
- }
-
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler');
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
@@ -132,10 +118,6 @@ public function testStringStaticCallbackForPhp54()
public function testStringStaticCallbackForPhp54WithMoreThan3Args()
{
- if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) {
- $this->markTestSkipped('Requires PHP 5.4');
- }
-
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler');
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
@@ -147,9 +129,9 @@ public function testStringStaticCallbackForPhp54WithMoreThan3Args()
$this->assertSame('staticHandler', $result);
}
- public function testCallbackToClassImplementingOverloadingButNotInvocableShouldRaiseException()
+ public function testCallbackToClassImplementingOverloadingButNotInvokableShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('foo', array( 'ZendTest\\Stdlib\\SignalHandlers\\Overloadable', 'foo' ));
}