The Event_Dispatcher acts acts as a notification dispatch table.
It is used to notify other objects of interesting things, if
they meet certain criteria. This information is encapsulated
in {@link Event_Notification} objects. Client objects register
themselves with the Event_Dispatcher as observers of specific
notifications posted by other objects. When an event occurs,
an object posts an appropriate notification to the Event_Dispatcher.
The Event_Dispatcher dispatches a message to each
registered observer, passing the notification as the sole argument.
The Event_Dispatcher is actually a combination of three design
patterns: the Singleton, {@link http://c2.com/cgi/wiki?MediatorPattern Mediator},
and Observer patterns. The idea behind Event_Dispatcher is borrowed from
{@link http://developer.apple.com/documentation/Cocoa/Conceptual/Notifications/index.html Apple's Cocoa framework}.
/** * For the given module, add all the observers of this module. */ private function addModuleObservers(Core_Module $module) { $hooks = $module->getListHooksRegistered(); foreach ($hooks as $hookName => $methodToCall) { $this->dispatcher->addObserver(array($module, $methodToCall), $hookName); } }
/** * For the given plugin, add all the observers of this plugin. */ private function addPluginObservers(Piwik_Plugin $plugin) { $hooks = $plugin->getListHooksRegistered(); foreach ($hooks as $hookName => $methodToCall) { $this->dispatcher->addObserver(array($plugin, $methodToCall), $hookName); } }
public function unloadPlugin($plugin) { if (!$plugin instanceof Piwik_Plugin) { $plugin = $this->loadPlugin($plugin); } $hooks = $plugin->getListHooksRegistered(); foreach ($hooks as $hookName => $methodToCall) { $success = $this->dispatcher->removeObserver(array($plugin, $methodToCall), $hookName); if ($success !== true) { throw new Exception("Error unloading plugin for method = {$methodToCall} // hook = {$hookName} "); } } unset($this->loadedPlugins[$plugin->getName()]); }
function sender(&$dispatcher) { $this->_dispatcher =& $dispatcher; } function foo() { $this->_dispatcher->post($this, 'onFoo', 'Some Info...'); } } /** * example observer */ function receiver1(&$notification) { echo "receiver 1 received notification<br />\n"; // the notification will be cancelled and no other observers // will be notified $notification->cancelNotification(); } /** * example observer */ function receiver2(&$notification) { echo "receiver 2 received notification<br />\n"; } $dispatcher =& Event_Dispatcher::getInstance(); $sender = new sender($dispatcher); $dispatcher->addObserver('receiver1', 'onFoo'); $dispatcher->addObserver('receiver2', 'onFoo'); $sender->foo();
/** * This logs the user out and destroys the session object if the * configuration option is set. * * @param bool set to false if no events should be fired b yhte logout * @return bool true on success or false on failure * * @access public */ function logout($direct = true) { $this->_status = LIVEUSER_STATUS_LOGGEDOUT; if ($direct) { // trigger event 'onLogout' as replacement for logout callback function $this->dispatcher->post($this, 'onLogout'); // If there's a cookie and the session hasn't idled or expired, kill that one too... $this->deleteRememberCookie(); } // If the session should be destroyed, do so now... if ($this->_options['logout']['destroy']) { session_unset(); session_destroy(); if ($this->_options['session']['force_start']) { $this->_startSession(); } } elseif (array_key_exists($this->_options['session']['varname'], $_SESSION)) { unset($_SESSION[$this->_options['session']['varname']]); } $this->disconnect(); if ($direct) { // trigger event 'postLogout', can be used to do a redirect $this->dispatcher->post($this, 'postLogout'); } return true; }
/** * Constructor * * @param bool|object $debug Boolean that indicates if a log instance * should be created or an instance of a class * that implements the PEAR:Log interface. * @return void * @access protected */ function LiveUser(&$debug) { $this->_stack =& PEAR_ErrorStack::singleton('LiveUser'); if ($debug) { $this->log =& LiveUser::PEARLogFactory($debug); $this->_stack->setLogger($this->log); } $this->_stack->setErrorMessageTemplate($this->_errorMessages); $this->dispatcher =& Event_Dispatcher::getInstance(); }
/** * PHP4 constructor * * Please use {@link getInstance()} instead. * * @access private * @param string Name of the notification dispatcher. */ function Event_Dispatcher($name) { Event_Dispatcher::__construct($name); }
/** * Registers a new listener * * Registers a new listener with the given criteria. * * @param mixed $callback A PHP callback * @param string $nName (optional) Expected notification name * * @access public * @return void * @since version 1.8.0b2 (2008-06-03) */ function addListener($callback, $nName = EVENT_DISPATCHER_GLOBAL) { $this->dispatcher =& Event_Dispatcher::getInstance(); // $this->dispatcher->setNotificationClass('PHP_CompatInfo_Audit'); $this->dispatcher->addObserver($callback, $nName); $this->_observerCount++; }
/** * Attachs a new observer. * * Adds a new observer to the Event Dispatcher that will listen * for all messages emitted by this HTML_Progress2 instance. * * @param mixed $callback PHP callback that will act as listener * @param string $nName Expected notification name, serves as a filter * * @return void * @since 2.0.0 * @access public * @throws HTML_PROGRESS2_ERROR_INVALID_CALLBACK, * HTML_PROGRESS2_ERROR_INVALID_INPUT * @see removeListener() */ function addListener($callback, $nName = EVENT_DISPATCHER_GLOBAL) { if (!is_callable($callback)) { return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_CALLBACK, 'exception', array('var' => '$callback', 'element' => 'valid Class-Method/Function', 'was' => 'callback', 'paramnum' => 1)); } elseif (!is_string($nName)) { return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_INPUT, 'exception', array('var' => '$nName', 'was' => gettype($nName), 'expected' => 'string', 'paramnum' => 2)); } $this->dispatcher =& Event_Dispatcher::getInstance('ProgressMeter'); $this->dispatcher->addObserver($callback, $nName); $this->_observerCount++; }
function test2() { $nf = new Notified(); $dm = new Dummy(); $ed2 =& Event_Dispatcher::getInstance('another'); $ed1 =& Event_Dispatcher::getInstance(); $ed2->addObserver(array(&$nf, 'notifReceived')); $not =& $ed2->post($dm, 'test', array('A', 'B')); $this->assertEquals('test:A:B:default', $nf->description(), "Error"); $this->assertEquals(1, $not->getNotificationCount(), "Error"); $not =& $ed1->post($dm, 'test', array('A2', 'B2')); $this->assertEquals(1, $not->getNotificationCount(), "Error"); $not =& $ed1->post($dm, 'test', array('A2', 'B2')); $this->assertEquals(1, $not->getNotificationCount(), "Error"); $ed2->addObserver(array(&$nf, 'notifReceived'), 'ClassFilterNotification', 'Notifier'); $not =& $ed2->post($dm, 'ClassFilterNotification'); $this->assertEquals('ClassFilterNotification::default', $nf->description(), "Error"); $this->assertEquals(1, $not->getNotificationCount(), "Error"); $ed2->addObserver(array(&$nf, 'notifReceived'), 'ClassFilterNotification', 'Dummy'); $not =& $ed2->post($dm, 'ClassFilterNotification'); $this->assertEquals(2, $not->getNotificationCount(), "Error"); }
/** * Attachs a new observer. * * Adds a new observer to the Event Dispatcher that will listen * for all messages emitted by this HTML_Progress2 instance. * * @param mixed $callback PHP callback that will act as listener * * @return void * @since 2.0.0 * @access public * @throws HTML_PROGRESS2_ERROR_INVALID_CALLBACK * @see removeListener() */ function addListener($callback) { if (!is_callable($callback)) { return $this->raiseError(HTML_PROGRESS2_ERROR_INVALID_CALLBACK, 'exception', array('var' => '$callback', 'element' => 'valid Class-Method/Function', 'was' => 'callback', 'paramnum' => 1)); } $this->dispatcher = Event_Dispatcher::getInstance(); $this->dispatcher->addObserver($callback); $this->_observerCount++; }
*/ function receiver2(&$notification) { echo "receiver 2 received notification<br />\n"; } /** * example observer */ function receiver3(&$notification) { echo "receiver 3 received notification<br />\n"; } // get the different dispatchers $dispatcher1 =& Event_Dispatcher::getInstance(); $dispatcher2 =& Event_Dispatcher::getInstance('child'); $dispatcher3 =& Event_Dispatcher::getInstance('grandchild'); // create senders in two different levels $sender1 =& new sender($dispatcher1); $sender2 =& new sender($dispatcher2); // build three levels $dispatcher1->addNestedDispatcher($dispatcher2); $dispatcher2->addNestedDispatcher($dispatcher3); // add observers in level one and two $dispatcher1->addObserver('receiver1', 'onFoo'); $dispatcher2->addObserver('receiver2', 'onFoo'); // this will bubble up from 1 to 3 echo 'sender1->foo()<br />'; $sender1->foo(); // this will not bubble up echo '<br />'; echo 'sender1->foo(), but disable bubbling<br />';
/** * Changes the default notification class. * * @param string $class name of the notification class */ public static function setDefaultNotificationClass($class) { self::$notificationClassDefault = $class; }