From: Michael M Slusarz Date: Tue, 9 Feb 2010 03:52:45 +0000 (-0700) Subject: Don't attach events to listeners by default (attach when notify() is X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=bf94ab2ee58ffe15add8169edda91ecf15da2dce;p=horde.git Don't attach events to listeners by default (attach when notify() is called on a listener). Remove _initNotification() workaround. Since the notification system no longer attaches events to listeners until notify() is called, it is safe to change notification listeners as needed directly within _init() calls. --- diff --git a/framework/Core/lib/Horde/Registry.php b/framework/Core/lib/Horde/Registry.php index d629be2ea..8b4583b5e 100644 --- a/framework/Core/lib/Horde/Registry.php +++ b/framework/Core/lib/Horde/Registry.php @@ -232,6 +232,7 @@ class Horde_Registry $injector->addBinder('Horde_Template', new Horde_Core_Binder_Template()); $injector->addBinder('Net_DNS_Resolver', new Horde_Core_Binder_Dns()); + $GLOBALS['registry'] = $this; $injector->setInstance('Horde_Registry', $this); /* Initialize browser object. */ @@ -314,11 +315,10 @@ class Horde_Registry $GLOBALS['perms'] = Horde_Perms::singleton(); $injector->setInstance('Horde_Perms', $GLOBALS['perms']); - /** - * Initialize notification object. - * No listeners are attached at this point. - */ + /* Initialize notification object. Always attach status listener by + * default. */ $GLOBALS['notification'] = Horde_Notification::singleton(); + $GLOBALS['notification']->attach('status'); $injector->setInstance('Horde_Notification', $GLOBALS['notification']); } diff --git a/framework/Core/lib/Horde/Registry/Application.php b/framework/Core/lib/Horde/Registry/Application.php index c5c6446cd..1ed11be6a 100644 --- a/framework/Core/lib/Horde/Registry/Application.php +++ b/framework/Core/lib/Horde/Registry/Application.php @@ -77,7 +77,6 @@ class Horde_Registry_Application } $this->_init(); - $this->_initNotification($GLOBALS['notification']); } } @@ -89,17 +88,4 @@ class Horde_Registry_Application { } - /** - * Initialization for Notification system. - * This is run after _init() is called so app-specific code can appear - * inside. - * - * @param Horde_Notification_Handler_Base $notify The notification - * object. - */ - protected function _initNotification($notify) - { - $notify->attach('status'); - } - } diff --git a/framework/Notification/lib/Horde/Notification/Handler/Base.php b/framework/Notification/lib/Horde/Notification/Handler/Base.php index dfb27a0c8..22381371c 100644 --- a/framework/Notification/lib/Horde/Notification/Handler/Base.php +++ b/framework/Notification/lib/Horde/Notification/Handler/Base.php @@ -90,8 +90,7 @@ implements Horde_Notification_Handler_Interface } /** - * Remove a listener from the notification list. This will discard any - * notifications in this listeners stack. + * Remove a listener from the notification list. * * @param string $listner The name of the listener to detach. * @@ -100,49 +99,73 @@ implements Horde_Notification_Handler_Interface public function detach($listener) { $listener = Horde_String::lower(basename($listener)); - if (!isset($this->_listeners[$listener])) { + if (isset($this->_listeners[$listener])) { + unset($this->_listeners[$listener]); + } else { throw new Horde_Exception(sprintf('Notification listener %s not found.', $listener)); } - - $instance = $this->_listeners[$listener]; - unset($this->_listeners[$listener]); - $this->_storage->clear($instance->getName()); } /** - * Replaces a listener in the notification list. This preserves all - * notifications in this listeners stack. If the listener does not exist, - * the new listener will be added automatically. + * Replaces a listener in the notification list. If the listener does not + * exist, the new listener will be added automatically. * * @param string $listener See attach(). * @param array $params See attach(). * @param string $class See attach(). * - * @return Horde_Notification_Listener See attach() - * @throws Horde_Exception + * @return Horde_Notification_Listener See attach(). */ public function replace($listener, array $params = array(), $class = null) { - $listener = Horde_String::lower(basename($listener)); - unset($this->_listeners[$listener]); + try { + $this->detach($listener); + } catch (Horde_Exception $e) {} + return $this->attach($listener, $params, $class); } /** + * Clear any notification events that may exist in a listener. + * + * @param string $listener The name of the listener to flush. If null, + * clears all unattached events. + */ + public function clear($listener = null) + { + if (is_null($listener)) { + $this->_storage->clear('_unattached'); + } else { + $listener = Horde_String::lower(basename($listener)); + if (isset($this->_listeners[$listener])) { + $this->_storage->clear($this->_listeners[$listener]->getName()); + } + } + } + + /** * Add an event to the Horde message stack. * * The event type parameter should begin with 'horde.' unless the * application defines its own Horde_Notification_Listener subclass that * handles additional codes. * - * @param mixed $event Horde_Notification_Event object or message string. - * @param integer $type The type of message: 'horde.error', - * 'horde.warning', 'horde.success', or - * 'horde.message'. - * @param array $flags Array of optional flags that will be passed to the - * registered listeners. + * @param mixed $event Horde_Notification_Event object or message + * string. + * @param integer $type The type of message. + * @param array $flags Array of optional flags that will be passed to + * the registered listeners. + * @param array $options Additional options: + *
+     * 'immediate' - (boolean) If true, immediately tries to attach to a
+     *               listener. If no listener exists for this type, the
+     *               message will be dropped.
+     *               DEFAULT: false (message will be attached to available
+     *               handler at the time notify() is called).
+     * 
*/ - public function push($event, $type = null, array $flags = array()) + public function push($event, $type = null, array $flags = array(), + $options = array()) { if ($event instanceof Horde_Notification_Event) { $event->flags = $flags; @@ -152,9 +175,13 @@ implements Horde_Notification_Handler_Interface $event = new Horde_Notification_Event($event, $type, $flags); } - foreach ($this->_listeners as $listener) { - if ($listener->handles($event->type)) { - $this->_storage->push($listener->getName(), $event); + if (empty($options['immediate'])) { + $this->_storage->push('_unattached', $event); + } else { + foreach ($this->_listeners as $listener) { + if ($listener->handles($event->type)) { + $this->_storage->push($listener->getName(), $event); + } } } } @@ -207,11 +234,30 @@ implements Horde_Notification_Handler_Interface */ public function notifyListeners(array $options) { + $unattached = $this->_storage->exists('_unattached') + ? $this->_storage->get('_unattached') + : array(); + foreach ($options['listeners'] as $listener) { if (isset($this->_listeners[$listener])) { - $this->_listeners[$listener]->notify($this->_storage->get($this->_listeners[$listener]->getName()), $options); + $instance = $this->_listeners[$listener]; + + foreach (array_keys($unattached) as $val) { + if ($instance->handles($unattached[$val]->type)) { + $this->_storage->push($instance->getName(), $unattached[$val]); + unset($unattached[$val]); + } + } + + $instance->notify($this->_storage->get($instance->getName()), $options); } } + + if (empty($unattached)) { + $this->_storage->clear('_unattached'); + } else { + $this->_storage->set('_unattached', $unattached); + } } /** @@ -225,17 +271,18 @@ implements Horde_Notification_Handler_Interface */ public function count($my_listener = null) { - if (is_null($my_listener)) { - $count = 0; - foreach ($this->_listeners as $listener) { - if ($this->_storage->exists($listener->getName())) { - $count += count($this->_storage->get($listener->getName())); - } + if (!is_null($my_listener)) { + return @count($this->_storage->get($this->_listeners[Horde_String::lower($my_listener)]->getName())); + } + + $count = 0; + foreach (array_merge($this->_listeners, array('_unattached')) as $val) { + if ($this->_storage->exists($val->getName())) { + $count += count($this->_storage->get($val->getName())); } - return $count; } - return @count($this->_storage->get($this->_listeners[Horde_String::lower($my_listener)]->getName())); + return $count; } } diff --git a/imp/lib/Application.php b/imp/lib/Application.php index 176457160..11b6cce5f 100644 --- a/imp/lib/Application.php +++ b/imp/lib/Application.php @@ -87,13 +87,8 @@ class IMP_Application extends Horde_Registry_Application * Global variables defined: * $imp_imap - An IMP_Imap object * $imp_mbox - Current mailbox information + * $imp_notify - A Horde_Notification_Listener object * $imp_search - An IMP_Search object - * - * When calling Horde_Registry::appInit(), the following parameters are - * also supported: - *
-     * 'tz' - (boolean) If true, sets the current time zone on the server.
-     * 
*/ protected function _init() { @@ -111,27 +106,14 @@ class IMP_Application extends Horde_Registry_Application // Initialize global $imp_mbox array. This call also initializes the // IMP_Search object. IMP::setCurrentMailboxInfo(); - } - /** - * Initialization for Notification system. - * - * Global variables defined: - * $imp_notify - A Horde_Notification_Listener object - * - * @param Horde_Notification_Handler_Base $notify The notification - * object. - */ - protected function _initNotification($notify) - { $viewmode = IMP::getViewMode(); - if ($viewmode == 'mimp') { - $GLOBALS['imp_notify'] = $notify->attach('status', null, 'IMP_Notification_Listener_StatusMobile'); + $GLOBALS['imp_notify'] = $GLOBALS['notification']->replace('status', array(), 'IMP_Notification_Listener_StatusMobile'); } else { - $GLOBALS['imp_notify'] = $notify->attach('status', array('viewmode' => $viewmode), 'IMP_Notification_Listener_Status'); + $GLOBALS['imp_notify'] = $GLOBALS['notification']->replace('status', array('viewmode' => $viewmode), 'IMP_Notification_Listener_Status'); if ($viewmode == 'imp') { - $notify->attach('audio'); + $GLOBALS['notification']->attach('audio'); } } } diff --git a/kronolith/lib/Application.php b/kronolith/lib/Application.php index 2e3a96a1a..53ca8c9d2 100644 --- a/kronolith/lib/Application.php +++ b/kronolith/lib/Application.php @@ -45,6 +45,7 @@ class Kronolith_Application extends Horde_Registry_Application * Initialization function. * * Global variables defined: + * $kronolith_notify - A Horde_Notification_Listener object. * $kronolith_shares - TODO */ protected function _init() @@ -64,20 +65,8 @@ class Kronolith_Application extends Horde_Registry_Application $GLOBALS['kronolith_shares'] = Horde_Share::singleton($GLOBALS['registry']->getApp()); Kronolith::initialize(); - } - /** - * Initialization for Notification system. - * - * Global variables defined: - * $kronolith_notify - A Horde_Notification_Listener object. - * - * @param Horde_Notification_Handler_Base $notify The notification - * object. - */ - protected function _initNotification($notify) - { - $GLOBALS['kronolith_notify'] = $notify->attach('status', null, 'Kronolith_Notification_Listener_Status'); + $GLOBALS['kronolith_notify'] = $GLOBALS['notification']->replace('status', array(), 'Kronolith_Notification_Listener_Status'); } /** diff --git a/nag/lib/Application.php b/nag/lib/Application.php index acdc5f8c3..4a5690c2e 100644 --- a/nag/lib/Application.php +++ b/nag/lib/Application.php @@ -47,27 +47,15 @@ class Nag_Application extends Horde_Registry_Application */ protected function _init() { - // Set the timezone variable. - Horde_Nls::setTimeZone(); + // Set the timezone variable. + Horde_Nls::setTimeZone(); - // Create a share instance. - $GLOBALS['nag_shares'] = Horde_Share::singleton($GLOBALS['registry']->getApp()); + // Create a share instance. + $GLOBALS['nag_shares'] = Horde_Share::singleton($GLOBALS['registry']->getApp()); - Nag::initialize(); - } + Nag::initialize(); - /** - * Initialization for Notification system. - * - * Global variables defined: - * $kronolith_notify - A Horde_Notification_Listener object. - * - * @param Horde_Notification_Handler_Base $notify The notification - * object. - */ - protected function _initNotification($notify) - { - $notify->attach('status', null, 'Nag_Notification_Listener_Status'); + $GLOBALS['notification']->replace('status', array(), 'Nag_Notification_Listener_Status'); } /**