Author: Jan Schneider (jan@horde.org)
Example #1
0
 /**
  */
 protected function _notify(Horde_Notification_Handler $handler, Horde_Notification_Listener $listener)
 {
     if ($listener instanceof Horde_Notification_Listener_Status && ($ob = $GLOBALS['injector']->getInstance('IMP_Factory_Imap'))) {
         /* Display IMAP alerts. */
         foreach ($ob->alerts() as $alert) {
             $handler->push($alert, 'horde.warning');
         }
     }
 }
Example #2
0
 /**
  */
 public function create(Horde_Injector $injector)
 {
     global $registry;
     if (isset($this->_notify)) {
         return $this->_notify;
     }
     $this->_notify = new Horde_Notification_Handler(new Horde_Core_Notification_Storage_Session());
     $this->_notify->addType('default', '*', 'Horde_Core_Notification_Event_Status');
     $this->_notify->addType('status', 'horde.*', 'Horde_Core_Notification_Event_Status');
     $this->_notify->addDecorator(new Horde_Notification_Handler_Decorator_Alarm($injector->getInstance('Horde_Core_Factory_Alarm'), $registry->getAuth()));
     $this->_notify->addDecorator(new Horde_Core_Notification_Handler_Decorator_Hordelog());
     return $this->_notify;
 }
Example #3
0
 /**
  */
 public function notify(array $options = array())
 {
     if ($this->_apps) {
         foreach ($this->_apps as $key => $val) {
             if (!$val) {
                 $this->addAppHandler($key);
             }
         }
         $this->_apps = false;
     }
     return parent::notify($options);
 }
Example #4
0
File: List.php Project: horde/horde
 /**
  * Parses a comma separated list of names and e-mail addresses into a list
  * of attendees.
  *
  * @param string $newAttendees                      A comma separated
  *                                                  attendee list.
  * @param Horde_Notification_Handler $notification  A notification handler.
  *
  * @return Kronolith_Attendee_List  The parsed attendee list.
  */
 public static function parse($newAttendees, Horde_Notification_Handler $notification)
 {
     $attendees = new self();
     if (empty($newAttendees)) {
         return $attendees;
     }
     /* Parse the address without validation to see what we can get out of
      * it. We allow email addresses (john@example.com), email address with
      * user information (John Doe <*****@*****.**>), and plain names
      * (John Doe). */
     $parser = new Horde_Mail_Rfc822();
     $result = $parser->parseAddressList($newAttendees);
     $result->setIteratorFilter(Horde_Mail_Rfc822_List::HIDE_GROUPS);
     foreach ($result as $newAttendee) {
         if (!$newAttendee->valid) {
             // If we can't even get a mailbox out of the address, then it
             // is likely unuseable. Reject it entirely.
             $notification->push(sprintf(_("Unable to recognize \"%s\" as an email address."), $newAttendee), 'horde.error');
             continue;
         }
         // If there is only a mailbox part, then it is just a local name.
         if (is_null($newAttendee->host)) {
             $email = null;
             $name = $newAttendee->bare_address;
         } else {
             // Build a full email address again and validate it.
             try {
                 $parser->parseAddressList($newAttendee->writeAddress(true));
             } catch (Horde_Mail_Exception $e) {
                 $notification->push($e, 'horde.error');
                 continue;
             }
             $email = $newAttendee->bare_address;
             $name = $newAttendee->label != $newAttendee->bare_address ? $newAttendee->label : '';
         }
         $attendees->add(new Kronolith_Attendee(array('email' => $email, 'role' => Kronolith::PART_REQUIRED, 'response' => Kronolith::RESPONSE_NONE, 'name' => $name)));
     }
     return $attendees;
 }
Example #5
0
 /**
  * Sends out iTip task notification to the assignee.
  *
  * Can be used to send task invitations, updates, and cancellations.
  *
  * @param Nag_Task $task  The task in question.
  * @param Horde_Notification_Handler $notification
  *        A notification object used to show result status.
  * @param integer $action
  *        The type of notification to send. One of the Nag::ITIP_* values.
  * @param Horde_Date $instance
  *        If cancelling a single instance of a recurring task, the date of
  *        this instance.
  * @param  string $range  The range parameter if this is a recurring event.
  *                        Possible values are self::RANGE_THISANDFUTURE
  */
 public static function sendITipNotifications(Nag_Task $task, Horde_Notification_Handler $notification, $action, Horde_Date $instance = null, $range = null)
 {
     global $injector, $registry, $nag_shares;
     if (!$task->assignee) {
         return;
     }
     $ident = $injector->getInstance('Horde_Core_Factory_Identity')->create($task->creator);
     if (!$ident->getValue('from_addr')) {
         $notification->push(sprintf(_("You do not have an email address configured in your Personal Information Preferences. You must set one %shere%s before event notifications can be sent."), $registry->getServiceLink('prefs', 'kronolith')->add(array('app' => 'horde', 'group' => 'identities'))->link(), '</a>'), 'horde.error', array('content.raw'));
         return;
     }
     // Generate image mime part first and only once, because we
     // need the Content-ID.
     $image = self::getImagePart('big_invitation.png');
     $share = $nag_shares->getShare($task->tasklist);
     $view = new Horde_View(array('templatePath' => NAG_TEMPLATES . '/itip'));
     new Horde_View_Helper_Text($view);
     $view->identity = $ident;
     $view->task = $task;
     $view->imageId = $image->getContentId();
     $email = Nag::getUserEmail($task->assignee);
     if (strpos($email, '@') === false) {
         continue;
     }
     /* Determine all notification-specific strings. */
     $method = 'REQUEST';
     switch ($action) {
         case self::ITIP_CANCEL:
             /* Cancellation. */
             $method = 'CANCEL';
             $filename = 'task-cancellation.ics';
             $view->subject = sprintf(_("Cancelled: %s"), $task->name);
             if (empty($instance)) {
                 $view->header = sprintf(_("%s has cancelled \"%s\"."), $ident->getName(), $task->name);
             } else {
                 $view->header = sprintf(_("%s has cancelled an instance of the recurring \"%s\"."), $ident->getName(), $task->name);
             }
             break;
         case self::ITIP_UPDATE:
             if (!empty($task->organizer) && $task->organizer != Nag::getUserEmail($task->creator)) {
                 // Sending a progress update.
                 $method = 'REPLY';
             } else {
                 $method = 'UPDATE';
             }
         case self::ITIP_REQUEST:
         default:
             if (empty($task->status) || $task->status == self::RESPONSE_NONE) {
                 /* Invitation. */
                 $filename = 'task-invitation.ics';
                 $view->subject = $task->name;
                 $view->header = sprintf(_("%s wishes to make you aware of \"%s\"."), $ident->getName(), $task->name);
             } else {
                 $filename = 'task-update.ics';
                 $view->subject = sprintf(_("Updated: %s."), $task->name);
                 $view->header = sprintf(_("%s wants to notify you about changes of \"%s\"."), $ident->getName(), $task->name);
             }
             break;
     }
     $view->attendees = $email;
     $view->organizer = empty($task->organizer) ? $registry->convertUserName($task->creator, false) : $task->organizer;
     /* Build the iCalendar data */
     $iCal = new Horde_Icalendar();
     $iCal->setAttribute('METHOD', $method);
     $vevent = $task->toiCalendar($iCal);
     $iCal->addComponent($vevent);
     /* text/calendar part */
     $ics = new Horde_Mime_Part();
     $ics->setType('text/calendar');
     $ics->setContents($iCal->exportvCalendar());
     $ics->setName($filename);
     $ics->setContentTypeParameter('METHOD', $method);
     $ics->setCharset('UTF-8');
     $ics->setEOL("\r\n");
     /* application/ics part */
     $ics2 = clone $ics;
     $ics2->setType('application/ics');
     /* multipart/mixed part */
     $multipart = new Horde_Mime_Part();
     $multipart->setType('multipart/mixed');
     $inner = self::buildMimeMessage($view, 'notification', $image);
     $inner->addPart($ics);
     $multipart->addPart($inner);
     $multipart->addPart($ics2);
     $recipient = $method != 'REPLY' ? new Horde_Mail_Rfc822_Address($email) : new Horde_Mail_Rfc822_Address($task->organizer);
     $mail = new Horde_Mime_Mail(array('Subject' => $view->subject, 'To' => $recipient, 'From' => $ident->getDefaultFromAddress(true), 'User-Agent' => 'Nag ' . $registry->getVersion()));
     $mail->setBasePart($multipart);
     try {
         $mail->send($injector->getInstance('Horde_Mail'));
         $notification->push(sprintf(_("The task request notification to %s was successfully sent."), $recipient), 'horde.success');
     } catch (Horde_Mime_Exception $e) {
         $notification->push(sprintf(_("There was an error sending a task request notification to %s: %s"), $recipient, $e->getMessage(), $e->getCode()), 'horde.error');
     }
 }
Example #6
0
 /**
  */
 protected function _notify(Horde_Notification_Handler $handler, Horde_Notification_Listener $listener)
 {
     global $injector, $prefs, $session;
     if (!$prefs->getValue('newmail_notify') || !$listener instanceof Horde_Notification_Listener_Status) {
         return;
     }
     /* Rate limit. If rate limit is not yet set, this is the initial
      * login so skip. */
     $curr = time();
     $ratelimit = $session->get('imp', self::SESS_RATELIMIT);
     if ($ratelimit && $ratelimit + self::RATELIMIT > $curr) {
         return;
     }
     $session->set('imp', self::SESS_RATELIMIT, $curr);
     if (!$ratelimit) {
         return;
     }
     $ajax_queue = $injector->getInstance('IMP_Ajax_Queue');
     $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
     $recent = array();
     try {
         foreach ($imp_imap->status($injector->getInstance('IMP_Ftree')->poll->getPollList(), Horde_Imap_Client::STATUS_RECENT_TOTAL, array('sort' => true)) as $key => $val) {
             if (!empty($val['recent_total'])) {
                 /* Open the mailbox R/W so we ensure the 'recent' flag is
                  * cleared. */
                 $imp_imap->openMailbox($key, Horde_Imap_Client::OPEN_READWRITE);
                 $mbox = IMP_Mailbox::get($key);
                 $recent[$mbox->display] = $val['recent_total'];
                 $ajax_queue->poll($mbox);
             }
         }
     } catch (Exception $e) {
     }
     if (empty($recent)) {
         return;
     }
     $recent_sum = array_sum($recent);
     reset($recent);
     switch (count($recent)) {
         case 1:
             $mbox_list = key($recent);
             break;
         case 2:
             $mbox_list = implode(_(" and "), array_keys($recent));
             break;
         default:
             $akeys = array_keys($recent);
             $mbox_list = $akeys[0] . ', ' . $akeys[1] . ', ' . _("and") . ' ' . $akeys[2];
             if ($addl_mbox = count($recent) - 3) {
                 $mbox_list .= ' (' . sprintf(ngettext("and %d more mailbox", "and %d more mailboxes", $addl_mbox), $addl_mbox) . ')';
             }
             break;
     }
     $text = sprintf(ngettext("You have %d new mail message in %s.", "You have %d new mail messages in %s.", $recent_sum), $recent_sum, $mbox_list);
     /* Status notification. */
     $handler->push($text, 'horde.message');
     /* Web notifications. */
     $handler->attach('webnotification', null, 'Horde_Core_Notification_Listener_Webnotification');
     $handler->push(Horde_Core_Notification_Event_Webnotification::createEvent($text, array('icon' => strval(Horde_Themes::img('unseen.png')))), 'webnotification');
     if ($audio = $prefs->getValue('newmail_audio')) {
         $handler->attach('audio');
         $handler->push(Horde_Themes::sound($audio), 'audio');
     }
 }
Example #7
0
 public function testMethodClearHasPostconditionThatAllUnattachedEventsHaveBeenClearedFromStorageIfNoListenerWasSpecified()
 {
     $storage = $this->getMock('Horde_Notification_Storage_Interface');
     $storage->expects($this->once())->method('clear')->with('_unattached');
     $handler = new Horde_Notification_Handler($storage);
     $handler->clear();
 }
Example #8
0
 /**
  * Sends out iTip event notifications to all attendees of a specific
  * event.
  *
  * Can be used to send event invitations, event updates as well as event
  * cancellations.
  *
  * @param Kronolith_Event $event
  *        The event in question.
  * @param Horde_Notification_Handler $notification
  *        A notification object used to show result status.
  * @param integer $action
  *        The type of notification to send. One of the Kronolith::ITIP_*
  *        values.
  * @param Horde_Date $instance
  *        If cancelling a single instance of a recurring event, the date of
  *        this instance.
  * @param  string $range  The range parameter if this is a recurring event.
  *                        Possible values are self::RANGE_THISANDFUTURE
  * @param array $cancellations  If $action is 'CANCEL', but it is due to
  *                              removing attendees and not canceling the
  *                              entire event, these are the email addresses
  *                              of the uninvited attendees and are the ONLY
  *                              people that will receive the CANCEL iTIP.
  *                              @since  4.2.10
  *
  */
 public static function sendITipNotifications(Kronolith_Event $event, Horde_Notification_Handler $notification, $action, Horde_Date $instance = null, $range = null, array $cancellations = array())
 {
     global $injector, $registry;
     if (!$event->attendees) {
         return;
     }
     $ident = $injector->getInstance('Horde_Core_Factory_Identity')->create($event->creator);
     if (!$ident->getValue('from_addr')) {
         $notification->push(sprintf(_("You do not have an email address configured in your Personal Information Preferences. You must set one %shere%s before event notifications can be sent."), $registry->getServiceLink('prefs', 'kronolith')->add(array('app' => 'horde', 'group' => 'identities'))->link(), '</a>'), 'horde.error', array('content.raw'));
         return;
     }
     // Generate image mime part first and only once, because we
     // need the Content-ID.
     $image = self::getImagePart('big_invitation.png');
     $share = $injector->getInstance('Kronolith_Shares')->getShare($event->calendar);
     $view = new Horde_View(array('templatePath' => KRONOLITH_TEMPLATES . '/itip'));
     new Horde_View_Helper_Text($view);
     $view->identity = $ident;
     $view->event = $event;
     $view->imageId = $image->getContentId();
     if ($action == self::ITIP_CANCEL && !empty($cancellations)) {
         $mail_attendees = $cancellations;
     } else {
         $mail_attendees = $event->attendees;
     }
     foreach ($mail_attendees as $email => $status) {
         /* Don't bother sending an invitation/update if the recipient does
          * not need to participate, or has declined participating, or
          * doesn't have an email address. */
         if (strpos($email, '@') === false || $status['response'] == self::RESPONSE_DECLINED) {
             continue;
         }
         /* Determine all notification-specific strings. */
         switch ($action) {
             case self::ITIP_CANCEL:
                 /* Cancellation. */
                 $method = 'CANCEL';
                 $filename = 'event-cancellation.ics';
                 $view->subject = sprintf(_("Cancelled: %s"), $event->getTitle());
                 if (empty($instance)) {
                     $view->header = sprintf(_("%s has cancelled \"%s\"."), $ident->getName(), $event->getTitle());
                 } else {
                     $view->header = sprintf(_("%s has cancelled an instance of the recurring \"%s\"."), $ident->getName(), $event->getTitle());
                 }
                 break;
             case self::ITIP_REQUEST:
             default:
                 $method = 'REQUEST';
                 if ($status['response'] == self::RESPONSE_NONE) {
                     /* Invitation. */
                     $filename = 'event-invitation.ics';
                     $view->subject = $event->getTitle();
                     $view->header = sprintf(_("%s wishes to make you aware of \"%s\"."), $ident->getName(), $event->getTitle());
                 } else {
                     /* Update. */
                     $filename = 'event-update.ics';
                     $view->subject = sprintf(_("Updated: %s."), $event->getTitle());
                     $view->header = sprintf(_("%s wants to notify you about changes of \"%s\"."), $ident->getName(), $event->getTitle());
                 }
                 break;
         }
         $view->attendees = strval(self::getAttendeeEmailList($event->attendees));
         $view->organizer = $registry->convertUserName($event->creator, false);
         if ($action == self::ITIP_REQUEST) {
             $attend_link = Horde::url('attend.php', true, -1)->add(array('c' => $event->calendar, 'e' => $event->id, 'u' => $email));
             $view->linkAccept = (string) $attend_link->add('a', 'accept');
             $view->linkTentative = (string) $attend_link->add('a', 'tentative');
             $view->linkDecline = (string) $attend_link->add('a', 'decline');
         }
         /* Build the iCalendar data */
         $iCal = new Horde_Icalendar();
         $iCal->setAttribute('METHOD', $method);
         $iCal->setAttribute('X-WR-CALNAME', $share->get('name'));
         $vevent = $event->toiCalendar($iCal);
         if ($action == self::ITIP_CANCEL && !empty($instance)) {
             // Recurring event instance deletion, need to specify the
             // RECURRENCE-ID but NOT the EXDATE.
             foreach ($vevent as &$ve) {
                 try {
                     $uid = $ve->getAttribute('UID');
                 } catch (Horde_Icalendar_Exception $e) {
                     continue;
                 }
                 if ($event->uid == $uid) {
                     $ve->setAttribute('RECURRENCE-ID', $instance);
                     if (!empty($range)) {
                         $ve->setParameter('RECURRENCE-ID', array('RANGE' => $range));
                     }
                     $ve->setAttribute('DTSTART', $instance, array(), false);
                     $diff = $event->end->timestamp() - $event->start->timestamp();
                     $end = clone $instance;
                     $end->sec += $diff;
                     $ve->setAttribute('DTEND', $end, array(), false);
                     $ve->removeAttribute('EXDATE');
                     break;
                 }
             }
         }
         $iCal->addComponent($vevent);
         /* text/calendar part */
         $ics = new Horde_Mime_Part();
         $ics->setType('text/calendar');
         $ics->setContents($iCal->exportvCalendar());
         $ics->setName($filename);
         $ics->setContentTypeParameter('method', $method);
         $ics->setCharset('UTF-8');
         $ics->setEOL("\r\n");
         /* application/ics part */
         $ics2 = clone $ics;
         $ics2->setType('application/ics');
         /* multipart/mixed part */
         $multipart = new Horde_Mime_Part();
         $multipart->setType('multipart/mixed');
         $inner = self::buildMimeMessage($view, 'notification', $image);
         $inner->addPart($ics);
         $multipart->addPart($inner);
         $multipart->addPart($ics2);
         $recipient = new Horde_Mail_Rfc822_Address($email);
         if (!empty($status['name'])) {
             $recipient->personal = $status['name'];
         }
         $mail = new Horde_Mime_Mail(array('Subject' => $view->subject, 'To' => $recipient, 'From' => $ident->getDefaultFromAddress(true), 'User-Agent' => 'Kronolith ' . $registry->getVersion()));
         $mail->setBasePart($multipart);
         try {
             $mail->send($injector->getInstance('Horde_Mail'));
             $notification->push(sprintf(_("The event notification to %s was successfully sent."), $recipient), 'horde.success');
         } catch (Horde_Mime_Exception $e) {
             $notification->push(sprintf(_("There was an error sending an event notification to %s: %s"), $recipient, $e->getMessage(), $e->getCode()), 'horde.error');
         }
     }
 }
Example #9
0
 /**
  * Modifies the global notification handler.
  *
  * @param Horde_Notification_Handler $handler  A notification handler.
  */
 public function setupNotification(Horde_Notification_Handler $handler)
 {
     $handler->addDecorator(new IMP_Notification_Handler_Decorator_ImapAlerts());
     $handler->addDecorator(new IMP_Notification_Handler_Decorator_NewmailNotify());
     $handler->addType('status', 'imp.*', 'IMP_Notification_Event_Status');
 }
Example #10
0
 /**
  * @deprecated
  */
 public function addApplicationHandlers()
 {
     return $this->_notify->attachAllAppHandlers();
 }