diff --git a/lib/Cake/Event/CakeEventManager.php b/lib/Cake/Event/CakeEventManager.php index 5fe7cc65dd3..e4f92388644 100644 --- a/lib/Cake/Event/CakeEventManager.php +++ b/lib/Cake/Event/CakeEventManager.php @@ -35,6 +35,13 @@ 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 * @@ -42,6 +49,37 @@ class CakeEventManager { */ 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 * @@ -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; } diff --git a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php index 40295cc6c99..2a5d28085e7 100644 --- a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php +++ b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php @@ -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); + } } \ No newline at end of file