Implementing a global event manager

This commit is contained in:
Jose Lorenzo Rodriguez 2011-12-14 00:35:11 -04:30
parent bb62f05890
commit f1acd70bad
2 changed files with 71 additions and 0 deletions

View file

@ -35,6 +35,13 @@ class CakeEventManager {
*/ */
public static $defaultPriority = 10; 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 * List of listener callbacks associated to
* *
@ -42,6 +49,37 @@ class CakeEventManager {
*/ */
protected $_listeners = array(); 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 * Adds a new listener to an event. Listeners
* *
@ -142,6 +180,11 @@ class CakeEventManager {
if (is_string($event)) { if (is_string($event)) {
$Event = new CakeEvent($event); $Event = new CakeEvent($event);
} }
if (!$this->_isGlobal) {
self::instance()->dispatch($event);
}
if (empty($this->_listeners[$event->name()])) { if (empty($this->_listeners[$event->name()])) {
return; return;
} }

View file

@ -273,4 +273,32 @@ class CakeEventManagerTest extends CakeTestCase {
$this->assertEquals(array(), $manager->listeners('fake.event')); $this->assertEquals(array(), $manager->listeners('fake.event'));
$this->assertEquals(array(), $manager->listeners('another.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);
}
} }