Skip to content

Commit

Permalink
Moving the event stack into a separate object.
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Krämer committed May 22, 2016
1 parent 769e0b8 commit 7764965
Show file tree
Hide file tree
Showing 4 changed files with 218 additions and 48 deletions.
65 changes: 25 additions & 40 deletions src/Event/EventManager.php
Expand Up @@ -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
Expand Down Expand Up @@ -360,7 +353,7 @@ public function dispatch($event)

$listeners = $this->listeners($event->name());
if (empty($listeners)) {
$this->stackEvent($event);
$this->_stackEvent($event);
return $event;
}

Expand All @@ -377,7 +370,7 @@ public function dispatch($event)
}
}

$this->stackEvent($event);
$this->_stackEvent($event);
return $event;
}

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

/**
Expand All @@ -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;
}
Expand Down
136 changes: 136 additions & 0 deletions src/Event/EventStack.php
@@ -0,0 +1,136 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since 3.3.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Event;

use Cake\Event\Event;

/**
* The Event Stack
*/
class EventStack implements \ArrayAccess, \Countable
{

/**
* Events list
*
* @var array
*/
protected $_events = [];

/**
* Empties the stack of dispatched events.
*
* @return void
*/
public function flush()
{
$this->_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 <p>
* An offset to check for.
* </p>
* @return boolean true on success or false on failure.
* </p>
* <p>
* 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 <p>
* The offset to retrieve.
* </p>
* @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 <p>
* The offset to assign the value to.
* </p>
* @param mixed $value <p>
* The value to set.
* </p>
* @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 <p>
* The offset to unset.
* </p>
* @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.
* </p>
* <p>
* The return value is cast to an integer.
* @since 5.1.0
*/
public function count()
{
return count($this->_events);
}
}
16 changes: 8 additions & 8 deletions tests/TestCase/Event/EventManagerTest.php
Expand Up @@ -17,6 +17,7 @@
use Cake\Event\Event;
use Cake\Event\EventListenerInterface;
use Cake\Event\EventManager;
use Cake\Event\EventStack;
use Cake\TestSuite\TestCase;

/**
Expand Down Expand Up @@ -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);
}
}
49 changes: 49 additions & 0 deletions tests/TestCase/Event/EventStackTest.php
@@ -0,0 +1,49 @@
<?php
/**
* CakePHP : Rapid Development Framework (http://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP Project
* @since 3.3.0
* @license http://www.opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Test\TestCase\Event;

use Cake\Event\Event;
use Cake\Event\EventStack;
use Cake\TestSuite\TestCase;

/**
* Tests the Cake\Event\EvenStack class functionality
*/
class EvenStackTest extends TestCase
{

/**
* testAddEventAndFlush
*
* @return void
*/
public function testAddEventAndFlush()
{
$eventStack = new EventStack();
$event = new Event('my_event', $this);
$event2 = new Event('my_second_event', $this);

$eventStack->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);
}
}

0 comments on commit 7764965

Please sign in to comment.