From bef20e61756245d6d2744bb3c153168f9c834de9 Mon Sep 17 00:00:00 2001 From: Jose Lorenzo Rodriguez Date: Tue, 13 Dec 2011 00:55:28 -0430 Subject: [PATCH] Starting to add subscriber classes support, inverted the parameter order for CakeEventManager::attach() --- lib/Cake/Event/CakeEventListener.php | 47 +++++++++++++++++++ lib/Cake/Event/CakeEventManager.php | 30 ++++++++++-- lib/Cake/Event/CakeListener.php | 0 .../Test/Case/Event/CakeEventManagerTest.php | 40 ++++++++-------- 4 files changed, 94 insertions(+), 23 deletions(-) create mode 100644 lib/Cake/Event/CakeEventListener.php delete mode 100644 lib/Cake/Event/CakeListener.php diff --git a/lib/Cake/Event/CakeEventListener.php b/lib/Cake/Event/CakeEventListener.php new file mode 100644 index 000000000..1979804dd --- /dev/null +++ b/lib/Cake/Event/CakeEventListener.php @@ -0,0 +1,47 @@ + 'sendEmail', + * 'Article.afterBuy' => 'decrementInventory', + * 'User.onRegister' => array('callable' => 'logRegistration', 'priority' => 20, 'passParams' => true) + * ); + * } + * }}} + * + * @return array associative array or event key names pointing to the function + * that should be called in the object when the respective event is fired + */ + public function implementedEvents(); +} \ No newline at end of file diff --git a/lib/Cake/Event/CakeEventManager.php b/lib/Cake/Event/CakeEventManager.php index 46990ca5c..22d793156 100644 --- a/lib/Cake/Event/CakeEventManager.php +++ b/lib/Cake/Event/CakeEventManager.php @@ -16,6 +16,7 @@ * @license MIT License (http://www.opensource.org/licenses/mit-license.php) */ +App::uses('CakeEventListener', 'Event'); /** * The event manager is responsible for keeping track of event listeners and pass the correct @@ -44,12 +45,35 @@ class CakeEventManager { /** * Adds a new listener to an event. Listeners * - * @param mixed $eventKey The event unique identifier name to with the callback will be associated - * @param callback|CakeListener PHP valid callback type or instance of CakeListener to be called + * @param callback|CakeEventListener $callable PHP valid callback type or instance of CakeListener to be called * when the event named with $eventKey is triggered. + * @param mixed $eventKey The event unique identifier name to with the callback will be associated. If $callable + * is an instance of CakeEventListener this argument will be ignored + * @param array $options used to set the `priority` and `passParams` flags to the listener. + * Priorities are handled like queues, and multiple attachments into the same priority queue will be treated in + * the order of insertion. `passParams` means that the event data property will be converted to function arguments + * when the listener is called. If $called is an instance of CakeEventListener, this parameter will be ignored * @return void */ - public function attach($eventKey, $callable, $options = array()) { + public function attach($callable, $eventKey = null, $options = array()) { + if (!$eventKey && !($callable instanceof CakeEventListener)) { + throw new InvalidArgumentException(__d('cake_dev', 'The eventKey variable is required')); + } + if ($callable instanceof CakeEventListener) { + foreach ($callable->implementedEvents() as $eventKey => $function) { + $options = array(); + $method = null; + if (is_array($function)) { + $method = array($callable, $function['callable']); + unset($function['callable']); + $options = $function; + } else { + $method = array($callable, $function); + } + $this->attach($method, $eventKey, $options); + } + return; + } $options = $options + array('priority' => self::$defaultPriority, 'passParams' => false); $this->_listeners[$eventKey][$options['priority']][] = array( 'callable' => $callable, diff --git a/lib/Cake/Event/CakeListener.php b/lib/Cake/Event/CakeListener.php deleted file mode 100644 index e69de29bb..000000000 diff --git a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php index f35b0aebe..7d5c660ba 100644 --- a/lib/Cake/Test/Case/Event/CakeEventManagerTest.php +++ b/lib/Cake/Test/Case/Event/CakeEventManagerTest.php @@ -63,19 +63,19 @@ class CakeEventManagerTest extends CakeTestCase { */ public function testAttachListeners() { $manager = new CakeEventManager; - $manager->attach('fake.event', 'fakeFunction'); + $manager->attach('fakeFunction', 'fake.event'); $expected = array( array('callable' => 'fakeFunction', 'passParams' => false) ); $this->assertEquals($expected, $manager->listeners('fake.event')); - $manager->attach('fake.event', 'fakeFunction2'); + $manager->attach('fakeFunction2', 'fake.event'); $expected[] = array('callable' => 'fakeFunction2', 'passParams' => false); $this->assertEquals($expected, $manager->listeners('fake.event')); - $manager->attach('fake.event', 'inQ5', array('priority' => 5)); - $manager->attach('fake.event', 'inQ1', array('priority' => 1)); - $manager->attach('fake.event', 'otherInQ5', array('priority' => 5)); + $manager->attach('inQ5', 'fake.event', array('priority' => 5)); + $manager->attach('inQ1', 'fake.event', array('priority' => 1)); + $manager->attach('otherInQ5', 'fake.event', array('priority' => 5)); $expected = array_merge( array( @@ -95,9 +95,9 @@ class CakeEventManagerTest extends CakeTestCase { */ public function testAttachMultipleEventKeys() { $manager = new CakeEventManager; - $manager->attach('fake.event', 'fakeFunction'); - $manager->attach('another.event', 'fakeFunction2'); - $manager->attach('another.event', 'fakeFunction3', array('priority' => 1, 'passParams' => true)); + $manager->attach('fakeFunction', 'fake.event'); + $manager->attach('fakeFunction2', 'another.event'); + $manager->attach('fakeFunction3', 'another.event', array('priority' => 1, 'passParams' => true)); $expected = array( array('callable' => 'fakeFunction', 'passParams' => false) ); @@ -117,9 +117,9 @@ class CakeEventManagerTest extends CakeTestCase { */ public function testDetach() { $manager = new CakeEventManager; - $manager->attach('fake.event', array('AClass', 'aMethod')); - $manager->attach('another.event', array('AClass', 'anotherMethod')); - $manager->attach('another.event', 'fakeFunction', array('priority' => 1)); + $manager->attach(array('AClass', 'aMethod'), 'fake.event'); + $manager->attach(array('AClass', 'anotherMethod'), 'another.event'); + $manager->attach('fakeFunction', 'another.event', array('priority' => 1)); $manager->detach(array('AClass', 'aMethod'), 'fake.event'); $this->assertEquals(array(), $manager->listeners('fake.event')); @@ -141,9 +141,9 @@ class CakeEventManagerTest extends CakeTestCase { */ public function testDetachFromAll() { $manager = new CakeEventManager; - $manager->attach('fake.event', array('AClass', 'aMethod')); - $manager->attach('another.event', array('AClass', 'aMethod')); - $manager->attach('another.event', 'fakeFunction', array('priority' => 1)); + $manager->attach(array('AClass', 'aMethod'), 'fake.event'); + $manager->attach(array('AClass', 'aMethod'), 'another.event'); + $manager->attach('fakeFunction', 'another.event', array('priority' => 1)); $manager->detach(array('AClass', 'aMethod')); $expected = array( @@ -162,8 +162,8 @@ class CakeEventManagerTest extends CakeTestCase { $manager = new CakeEventManager; $listener = $this->getMock('CakeEventTestListener'); $anotherListener = $this->getMock('CakeEventTestListener'); - $manager->attach('fake.event', array($listener, 'listenerFunction')); - $manager->attach('fake.event', array($anotherListener, 'listenerFunction')); + $manager->attach(array($listener, 'listenerFunction'), 'fake.event'); + $manager->attach(array($anotherListener, 'listenerFunction'), 'fake.event'); $event = new CakeEvent('fake.event'); $listener->expects($this->once())->method('listenerFunction')->with($event); @@ -179,8 +179,8 @@ class CakeEventManagerTest extends CakeTestCase { public function testDispatchPrioritized() { $manager = new CakeEventManager; $listener = new CakeEventTestListener; - $manager->attach('fake.event', array($listener, 'listenerFunction')); - $manager->attach('fake.event', array($listener, 'secondListenerFunction'), array('priority' => 5)); + $manager->attach(array($listener, 'listenerFunction'), 'fake.event'); + $manager->attach(array($listener, 'secondListenerFunction'), 'fake.event', array('priority' => 5)); $event = new CakeEvent('fake.event'); $manager->dispatch($event); @@ -197,8 +197,8 @@ class CakeEventManagerTest extends CakeTestCase { $manager = new CakeEventManager; $listener = $this->getMock('CakeEventTestListener'); $anotherListener = $this->getMock('CakeEventTestListener'); - $manager->attach('fake.event', array($listener, 'listenerFunction')); - $manager->attach('fake.event', array($anotherListener, 'secondListenerFunction'), array('passParams' => true)); + $manager->attach(array($listener, 'listenerFunction'), 'fake.event'); + $manager->attach(array($anotherListener, 'secondListenerFunction'), 'fake.event', array('passParams' => true)); $event = new CakeEvent('fake.event', $this, array('some' => 'data')); $listener->expects($this->once())->method('listenerFunction')->with($event);