Skip to content

Commit f1acd70

Browse files
committed
Implementing a global event manager
1 parent bb62f05 commit f1acd70

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

lib/Cake/Event/CakeEventManager.php

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,51 @@ class CakeEventManager {
3535
*/
3636
public static $defaultPriority = 10;
3737

38+
/**
39+
* The globally available instance, used for dispatching events attached from any scope
40+
*
41+
* @var CakeEventManager
42+
*/
43+
protected static $_generalManager = null;
44+
3845
/**
3946
* List of listener callbacks associated to
4047
*
4148
* @var object $Listeners
4249
*/
4350
protected $_listeners = array();
4451

52+
/**
53+
* Internal flag to distinguish a common manager from the sigleton
54+
*
55+
* @var boolean
56+
*/
57+
protected $_isGlobal = false;
58+
59+
60+
/**
61+
* Returns the globally available instance of a CakeEventManager
62+
* this is used for dispatching events attached from outside the scope
63+
* other managers were created. Usually for creating hook systems or inter-class
64+
* communication
65+
*
66+
* If called with a first params, it will be set as the globally available instance
67+
*
68+
* @param CakeEventManager $manager
69+
* @return CakeEventManager the global event manager
70+
*/
71+
public static function instance($manager = null) {
72+
if ($manager instanceof CakeEventManager) {
73+
self::$_generalManager = $manager;
74+
}
75+
if (empty(self::$_generalManager)) {
76+
self::$_generalManager = new CakeEventManager;
77+
}
78+
79+
self::$_generalManager->_isGlobal = true;
80+
return self::$_generalManager;
81+
}
82+
4583
/**
4684
* Adds a new listener to an event. Listeners
4785
*
@@ -142,6 +180,11 @@ public function dispatch($event) {
142180
if (is_string($event)) {
143181
$Event = new CakeEvent($event);
144182
}
183+
184+
if (!$this->_isGlobal) {
185+
self::instance()->dispatch($event);
186+
}
187+
145188
if (empty($this->_listeners[$event->name()])) {
146189
return;
147190
}

lib/Cake/Test/Case/Event/CakeEventManagerTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -273,4 +273,32 @@ public function testDetachSubscriber() {
273273
$this->assertEquals(array(), $manager->listeners('fake.event'));
274274
$this->assertEquals(array(), $manager->listeners('another.event'));
275275
}
276+
277+
/**
278+
* Tests that it is possible to get/set the manager singleton
279+
*
280+
* @return void
281+
*/
282+
public function testGlobalDispatcherGetter() {
283+
$this->assertInstanceOf('CakeEventManager', CakeEventManager::instance());
284+
$manager = new CakeEventManager;
285+
286+
CakeEventManager::instance($manager);
287+
$this->assertSame($manager, CakeEventManager::instance());
288+
}
289+
290+
/**
291+
* Tests that the global event manager gets the event too from any other manager
292+
*
293+
* @return void
294+
*/
295+
public function testDispatchWithGlobal() {
296+
$generalManager = $this->getMock('CakeEventManager', array('dispatch'));
297+
$manager = new CakeEventManager;
298+
$event = new CakeEvent('fake.event');
299+
CakeEventManager::instance($generalManager);
300+
301+
$generalManager->expects($this->once())->method('dispatch')->with($event);
302+
$manager->dispatch($event);
303+
}
276304
}

0 commit comments

Comments
 (0)