From 77649650ccabfaa8b50c8dc3d2df213f01f2e5ca Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Florian=20Kr=C3=A4mer?=
Date: Mon, 23 May 2016 00:27:20 +0200
Subject: [PATCH] Moving the event stack into a separate object.
---
src/Event/EventManager.php | 65 ++++-------
src/Event/EventStack.php | 136 ++++++++++++++++++++++
tests/TestCase/Event/EventManagerTest.php | 16 +--
tests/TestCase/Event/EventStackTest.php | 49 ++++++++
4 files changed, 218 insertions(+), 48 deletions(-)
create mode 100644 src/Event/EventStack.php
create mode 100644 tests/TestCase/Event/EventStackTest.php
diff --git a/src/Event/EventManager.php b/src/Event/EventManager.php
index afe097d7ab2..bfca82ede81 100644
--- a/src/Event/EventManager.php
+++ b/src/Event/EventManager.php
@@ -54,18 +54,11 @@ class EventManager
protected $_isGlobal = false;
/**
- * A list of already dispatched events
+ * The event stack object.
*
- * @var array
+ * @var \Cake\Event\EventStack|null
*/
- protected $_dispatchedEvents = [];
-
- /**
- * Enables or disables the stacking of dispatched events
- *
- * @var bool
- */
- protected $_eventStacking = false;
+ protected $_eventStack;
/**
* Returns the globally available instance of a Cake\Event\EventManager
@@ -360,7 +353,7 @@ public function dispatch($event)
$listeners = $this->listeners($event->name());
if (empty($listeners)) {
- $this->stackEvent($event);
+ $this->_stackEvent($event);
return $event;
}
@@ -377,7 +370,7 @@ public function dispatch($event)
}
}
- $this->stackEvent($event);
+ $this->_stackEvent($event);
return $event;
}
@@ -478,57 +471,47 @@ public function matchingListeners($eventKeyPattern)
}
/**
- * Returns a list of dispatched event objects.
+ * Returns the event stack.
*
* @return array
*/
- public function getDispatchedEvents()
+ public function eventStack()
{
- return $this->_dispatchedEvents;
+ return $this->_eventStack;
}
/**
- * Enables the stacking of dispatched events.
+ * Adds an event to the stack if the stack object is present.
*
+ * @param \Cake\Event\Event $event An event to add to the stack.
* @return void
*/
- public function enableEventStacking()
+ public function _stackEvent(Event $event)
{
- $this->_eventStacking = true;
- }
-
- /**
- * Disables the stacking of dispatched events.
- *
- * @return void
- */
- public function disableEventStacking()
- {
- $this->_eventStacking = false;
- $this->flushEventStack();
+ if ($this->_eventStack) {
+ $this->_eventStack->add($event);
+ }
}
/**
- * Empties the stack of dispatched events.
+ * Enables the stacking of dispatched events.
*
+ * @param \Cake\Event\EventStack $eventStack The event stack object to use.
* @return void
*/
- public function flushEventStack()
+ public function enableEventStacking(EventStack $eventStack)
{
- $this->_dispatchedEvents = [];
+ $this->_eventStack = $eventStack;
}
/**
- * Adds an event to the stack when stacking is enabled.
+ * Disables the stacking of dispatched events.
*
- * @param \Cake\Event\Event $event An event to stack.
* @return void
*/
- protected function stackEvent(Event $event)
+ public function disableEventStacking()
{
- if ($this->_eventStacking === true) {
- $this->_dispatchedEvents[] = $event;
- }
+ $this->_eventStack = null;
}
/**
@@ -544,8 +527,10 @@ public function __debugInfo()
foreach ($this->_listeners as $key => $listeners) {
$properties['_listeners'][$key] = count($listeners) . ' listener(s)';
}
- foreach ($this->_dispatchedEvents as $event) {
- $properties['_dispatchedEvents'][] = $event->name() . ' with subject ' . get_class($event->subject());
+ if ($this->_eventStack) {
+ foreach ($this->_eventStack as $event) {
+ $properties['_dispatchedEvents'][] = $event->name() . ' with subject ' . get_class($event->subject());
+ }
}
return $properties;
}
diff --git a/src/Event/EventStack.php b/src/Event/EventStack.php
new file mode 100644
index 00000000000..868a0f47edc
--- /dev/null
+++ b/src/Event/EventStack.php
@@ -0,0 +1,136 @@
+_events = [];
+ }
+
+ /**
+ * Adds an event to the stack when stacking is enabled.
+ *
+ * @param \Cake\Event\Event $event An event to stack.
+ * @return void
+ */
+ public function add(Event $event)
+ {
+ $this->_events[] = $event;
+ }
+
+ /**
+ * Whether a offset exists
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetexists.php
+ * @param mixed $offset
+ * An offset to check for.
+ *
+ * @return boolean true on success or false on failure.
+ *
+ *
+ * The return value will be casted to boolean if non-boolean was returned.
+ * @since 5.0.0
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->_events[$offset]);
+ }
+
+ /**
+ * Offset to retrieve
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetget.php
+ * @param mixed $offset
+ * The offset to retrieve.
+ *
+ * @return mixed Can return all value types.
+ * @since 5.0.0
+ */
+ public function offsetGet($offset)
+ {
+ if ($this->offsetExists($offset)) {
+ return $this->_events[$offset];
+ }
+ return null;
+ }
+
+ /**
+ * Offset to set
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetset.php
+ * @param mixed $offset
+ * The offset to assign the value to.
+ *
+ * @param mixed $value
+ * The value to set.
+ *
+ * @return void
+ * @since 5.0.0
+ */
+ public function offsetSet($offset, $value)
+ {
+ $this->_events[$offset] = $value;
+ }
+
+ /**
+ * Offset to unset
+ *
+ * @link http://php.net/manual/en/arrayaccess.offsetunset.php
+ * @param mixed $offset
+ * The offset to unset.
+ *
+ * @return void
+ * @since 5.0.0
+ */
+ public function offsetUnset($offset)
+ {
+ unset($this->_events[$offset]);
+ }
+
+ /**
+ * Count elements of an object
+ *
+ * @link http://php.net/manual/en/countable.count.php
+ * @return int The custom count as an integer.
+ *
+ *
+ * The return value is cast to an integer.
+ * @since 5.1.0
+ */
+ public function count()
+ {
+ return count($this->_events);
+ }
+}
diff --git a/tests/TestCase/Event/EventManagerTest.php b/tests/TestCase/Event/EventManagerTest.php
index 72ddef9406e..6dc9e83ad74 100644
--- a/tests/TestCase/Event/EventManagerTest.php
+++ b/tests/TestCase/Event/EventManagerTest.php
@@ -17,6 +17,7 @@
use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\Event\EventManager;
+use Cake\Event\EventStack;
use Cake\TestSuite\TestCase;
/**
@@ -720,30 +721,29 @@ public function testDispatchWithGlobalAndLocalEvents()
*/
public function testGetDispatchedEvents()
{
+ $eventStack = new EventStack();
$event = new Event('my_event', $this);
$event2 = new Event('my_second_event', $this);
$manager = new EventManager();
- $manager->enableEventStacking();
+ $manager->enableEventStacking($eventStack);
$manager->dispatch($event);
$manager->dispatch($event2);
- $result = $manager->getDispatchedEvents();
+ $result = $manager->eventStack();
$this->assertCount(2, $result);
$this->assertEquals($result[0], $event);
$this->assertEquals($result[1], $event2);
- $manager->flushEventStack();
- $result = $manager->getDispatchedEvents();
+ $manager->eventStack()->flush();
+ $result = $manager->eventStack();
$this->assertCount(0, $result);
- $this->assertEquals($result, []);
$manager->disableEventStacking();
$manager->dispatch($event);
$manager->dispatch($event2);
- $result = $manager->getDispatchedEvents();
- $this->assertCount(0, $result);
- $this->assertEquals($result, []);
+ $result = $manager->eventStack();
+ $this->assertNull($result);
}
}
diff --git a/tests/TestCase/Event/EventStackTest.php b/tests/TestCase/Event/EventStackTest.php
new file mode 100644
index 00000000000..2bf94c81fc6
--- /dev/null
+++ b/tests/TestCase/Event/EventStackTest.php
@@ -0,0 +1,49 @@
+add($event);
+ $eventStack->add($event2);
+ $this->assertCount(2, $eventStack);
+
+ $this->assertEquals($eventStack[0], $event);
+ $this->assertEquals($eventStack[1], $event2);
+
+ $eventStack->flush();
+
+ $this->assertCount(0, $eventStack);
+ }
+}