Skip to content

Commit

Permalink
Implementing a global event manager
Browse files Browse the repository at this point in the history
  • Loading branch information
lorenzo committed Dec 25, 2011
1 parent bb62f05 commit f1acd70
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 0 deletions.
43 changes: 43 additions & 0 deletions lib/Cake/Event/CakeEventManager.php
Expand Up @@ -35,13 +35,51 @@ class CakeEventManager {
*/
public static $defaultPriority = 10;

/**
* The globally available instance, used for dispatching events attached from any scope
*
* @var CakeEventManager
*/
protected static $_generalManager = null;

/**
* List of listener callbacks associated to
*
* @var object $Listeners
*/
protected $_listeners = array();

/**
* Internal flag to distinguish a common manager from the sigleton
*
* @var boolean
*/
protected $_isGlobal = false;


/**
* Returns the globally available instance of a CakeEventManager
* this is used for dispatching events attached from outside the scope
* other managers were created. Usually for creating hook systems or inter-class
* communication
*
* If called with a first params, it will be set as the globally available instance
*
* @param CakeEventManager $manager
* @return CakeEventManager the global event manager
*/
public static function instance($manager = null) {
if ($manager instanceof CakeEventManager) {
self::$_generalManager = $manager;
}
if (empty(self::$_generalManager)) {
self::$_generalManager = new CakeEventManager;
}

self::$_generalManager->_isGlobal = true;
return self::$_generalManager;
}

/**
* Adds a new listener to an event. Listeners
*
Expand Down Expand Up @@ -142,6 +180,11 @@ public function dispatch($event) {
if (is_string($event)) {
$Event = new CakeEvent($event);
}

if (!$this->_isGlobal) {
self::instance()->dispatch($event);
}

if (empty($this->_listeners[$event->name()])) {
return;
}
Expand Down
28 changes: 28 additions & 0 deletions lib/Cake/Test/Case/Event/CakeEventManagerTest.php
Expand Up @@ -273,4 +273,32 @@ public function testDetachSubscriber() {
$this->assertEquals(array(), $manager->listeners('fake.event'));
$this->assertEquals(array(), $manager->listeners('another.event'));
}

/**
* Tests that it is possible to get/set the manager singleton
*
* @return void
*/
public function testGlobalDispatcherGetter() {
$this->assertInstanceOf('CakeEventManager', CakeEventManager::instance());
$manager = new CakeEventManager;

CakeEventManager::instance($manager);
$this->assertSame($manager, CakeEventManager::instance());
}

/**
* Tests that the global event manager gets the event too from any other manager
*
* @return void
*/
public function testDispatchWithGlobal() {
$generalManager = $this->getMock('CakeEventManager', array('dispatch'));
$manager = new CakeEventManager;
$event = new CakeEvent('fake.event');
CakeEventManager::instance($generalManager);

$generalManager->expects($this->once())->method('dispatch')->with($event);
$manager->dispatch($event);
}
}

0 comments on commit f1acd70

Please sign in to comment.