public function notify(array $options = array())
{
/* Convert the 'listeners' option into the format expected by the
* notification handler. */
if (!isset($options['listeners'])) {
$listeners = array_keys($this->_listeners);
} elseif (!is_array($options['listeners'])) {
$listeners = array($options['listeners']);
} else {
$listeners = $options['listeners'];
}
$events = array();
$unattached = $this->_storage->exists('_unattached') ? $this->_storage->get('_unattached') : array();
/* Pass the message stack to all listeners and asks them to handle
* their messages. */
foreach ($listeners as $listener) {
$listener = Horde_String::lower($listener);
if (isset($this->_listeners[$listener])) {
$instance = $this->_listeners[$listener];
$name = $instance->getName();
foreach (array_keys($unattached) as $val) {
if ($unattached[$val] instanceof Horde_Notification_Event && $instance->handles($unattached[$val]->type)) {
$this->_storage->push($name, $unattached[$val]);
unset($unattached[$val]);
}
}
foreach ($this->_decorators as $decorator) {
$this->_forceAttach = true;
try {
$decorator->notify($this, $instance);
} catch (Horde_Notification_Exception $e) {
$this->push($e);
}
$this->_forceAttach = false;
}
if (!$this->_storage->exists($name)) {
continue;
}
$tmp = $this->_storage->get($name);
if (empty($options['raw'])) {
$instance->notify($tmp, $options);
}
$this->_storage->clear($name);
$events = array_merge($events, $tmp);
}
}
if (empty($unattached)) {
$this->_storage->clear('_unattached');
} else {
$this->_storage->set('_unattached', $unattached);
}
return $events;
}