Esempio n. 1
0
 /**
  * Actually carry out the action.
  */
 public function doAction($form_params, $form_data, $fields)
 {
     global $conf;
     $mail = new Horde_Mime_Mail();
     $mail->addHeader('From', $form_params['from']);
     $mail->addHeader('Subject', $form_params['subject']);
     $mail->addHeader('To', $form_params['to']);
     if (!empty($form_params['cc'])) {
         $mail->addHeader('Cc', $form_params['cc']);
     }
     if (!empty($form_params['bcc'])) {
         $mail->addHeader('Bcc', $form_params['bcc']);
     }
     $body = '';
     foreach ($fields as $field) {
         $value = array_shift($form_data);
         switch ($field['field_type']) {
             case 'file':
             case 'image':
                 if (!empty($value['file'])) {
                     $mail->addAttachment($value['file'], $value['name'], $value['type']);
                 }
                 break;
             default:
                 $body .= $field['field_label'] . ': ' . $this->_formatFormData($value) . "\n";
                 break;
         }
     }
     $mail->setBody($body);
     return $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'));
 }
Esempio n. 2
0
 /**
  * Push content to the recipient.
  *
  * @param Horde_Push $content The content element.
  * @param array      $options Additional options.
  *
  * @return NULL
  */
 public function push(Horde_Push $content, $options = array())
 {
     $contents = $content->getContent();
     $types = $content->getMimeTypes();
     $mail = new Horde_Mime_Mail();
     // @todo Append references
     if (isset($types['text/plain'])) {
         $mail->setBody($content->getStringContent($types['text/plain'][0]));
         unset($contents[$types['text/plain'][0]]);
     }
     if (isset($types['text/html'])) {
         $mail->setHtmlBody($content->getStringContent($types['text/html'][0]), 'UTF-8', !isset($types['text/plain']));
         unset($contents[$types['text/html'][0]]);
     }
     foreach ($contents as $part) {
         $mail->addPart($part['mime_type'], $part['content'], 'UTF-8');
     }
     $mail->addRecipients(explode(',', $this->getAcl()));
     $mail->addHeader('subject', $content->getSummary());
     if (!empty($this->_params['from'])) {
         $mail->addHeader('from', $this->_params['from']);
     }
     $mail->addHeader('to', $this->getAcl());
     if (!empty($options['pretend'])) {
         $mock = new Horde_Mail_Transport_Mock();
         $mail->send($mock);
         return sprintf("Would push mail \n\n%s\n\n%s\n to %s.", $mock->sentMessages[0]['header_text'], $mock->sentMessages[0]['body'], $this->getAcl());
     }
     $mail->send($this->_mail);
     return sprintf('Pushed mail to %s.', $this->getAcl());
 }
Esempio n. 3
0
 /**
  * Sends email notifications that a task has been added, edited, or
  * deleted to users that want such notifications.
  *
  * @param string $action      The event action. One of "add", "edit", or
  *                            "delete".
  * @param Nag_Task $task      The changed task.
  * @param Nag_Task $old_task  The original task if $action is "edit".
  *
  * @throws Nag_Exception
  */
 public static function sendNotification($action, $task, $old_task = null)
 {
     if (!in_array($action, array('add', 'edit', 'delete'))) {
         throw new Nag_Exception('Unknown event action: ' . $action);
     }
     try {
         $share = $GLOBALS['nag_shares']->getShare($task->tasklist);
     } catch (Horde_Share_Exception $e) {
         Horde::log($e->getMessage(), 'ERR');
         throw new Nag_Exception($e);
     }
     $groups = $GLOBALS['injector']->getInstance('Horde_Group');
     $recipients = array();
     $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create();
     $from = $identity->getDefaultFromAddress(true);
     $owner = $share->get('owner');
     if (strlen($owner)) {
         $recipients[$owner] = self::_notificationPref($owner, 'owner');
     }
     foreach ($share->listUsers(Horde_Perms::READ) as $user) {
         if (empty($recipients[$user])) {
             $recipients[$user] = self::_notificationPref($user, 'read', $task->tasklist);
         }
     }
     foreach ($share->listGroups(Horde_Perms::READ) as $group) {
         try {
             $group_users = $groups->listUsers($group);
         } catch (Horde_Group_Exception $e) {
             Horde::log($e, 'ERR');
             continue;
         }
         foreach ($group_users as $user) {
             if (empty($recipients[$user])) {
                 $recipients[$user] = self::_notificationPref($user, 'read', $task->tasklist);
             }
         }
     }
     $addresses = array();
     foreach ($recipients as $user => $vals) {
         if (!$vals) {
             continue;
         }
         $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user);
         $email = $identity->getValue('from_addr');
         if (strpos($email, '@') === false) {
             continue;
         }
         if (!isset($addresses[$vals['lang']][$vals['tf']][$vals['df']])) {
             $addresses[$vals['lang']][$vals['tf']][$vals['df']] = array();
         }
         $tmp = new Horde_Mail_Rfc822_Address($email);
         $tmp->personal = $identity->getValue('fullname');
         $addresses[$vals['lang']][$vals['tf']][$vals['df']][] = strval($tmp);
     }
     if (!$addresses) {
         return;
     }
     $mail = new Horde_Mime_Mail(array('User-Agent' => 'Nag ' . $GLOBALS['registry']->getVersion(), 'Precedence' => 'bulk', 'Auto-Submitted' => 'auto-generated', 'From' => $from));
     foreach ($addresses as $lang => $twentyFour) {
         $GLOBALS['registry']->setLanguageEnvironment($lang);
         $view_link = Horde::url('view.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id))->setRaw(true);
         switch ($action) {
             case 'add':
                 $subject = _("Task added:");
                 $notification_message = _("You requested to be notified when tasks are added to your task lists.") . "\n\n" . ($task->due ? _("The task \"%s\" has been added to task list \"%s\", with a due date of: %s.") : _("The task \"%s\" has been added to task list \"%s\".")) . "\n" . str_replace('%', '%%', $view_link);
                 break;
             case 'edit':
                 $subject = _("Task modified:");
                 $notification_message = _("You requested to be notified when tasks are edited on your task lists.") . "\n\n" . _("The task \"%s\" has been edited on task list \"%s\".") . "\n" . str_replace('%', '%%', $view_link) . "\n\n" . _("Changes made for this task:");
                 if ($old_task->name != $task->name) {
                     $notification_message .= "\n - " . sprintf(_("Changed name from \"%s\" to \"%s\""), $old_task->name, $task->name);
                 }
                 if ($old_task->tasklist != $task->tasklist) {
                     $old_share = $GLOBALS['nag_shares']->getShare($old_task->tasklist);
                     $notification_message .= "\n - " . sprintf(_("Changed task list from \"%s\" to \"%s\""), Nag::getLabel($old_share), Nag::getLabel($share));
                 }
                 if ($old_task->parent_id != $task->parent_id) {
                     $old_parent = $old_task->getParent();
                     try {
                         $parent = $task->getParent();
                         $notification_message .= "\n - " . sprintf(_("Changed parent task from \"%s\" to \"%s\""), $old_parent ? $old_parent->name : _("no parent"), $parent ? $parent->name : _("no parent"));
                     } catch (Nag_Exception $e) {
                     }
                 }
                 if ($old_task->assignee != $task->assignee) {
                     $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($old_task->assignee);
                     $old_name = $identity->getValue('fullname');
                     if (!strlen($old_name)) {
                         $old_name = $old_task->assignee;
                     }
                     $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($task->assignee);
                     $new_name = $identity->getValue('fullname');
                     if (!strlen($new_name)) {
                         $new_name = $new_task->assignee;
                     }
                     $notification_message .= "\n - " . sprintf(_("Changed assignee from \"%s\" to \"%s\""), $old_name, $new_name);
                 }
                 if ($old_task->private != $task->private) {
                     $notification_message .= "\n - " . ($task->private ? _("Turned privacy on") : _("Turned privacy off"));
                 }
                 if ($old_task->due != $task->due) {
                     $notification_message .= "\n - " . sprintf(_("Changed due date from %s to %s"), $old_task->due ? self::formatDate($old_task->due) : _("no due date"), $task->due ? self::formatDate($task->due) : _("no due date"));
                 }
                 if ($old_task->start != $task->start) {
                     $notification_message .= "\n - " . sprintf(_("Changed start date from %s to %s"), $old_task->start ? self::formatDate($old_task->start) : _("no start date"), $task->start ? self::formatDate($task->start) : _("no start date"));
                 }
                 if ($old_task->alarm != $task->alarm) {
                     $notification_message .= "\n - " . sprintf(_("Changed alarm from %s to %s"), self::formatAlarm($old_task->alarm), self::formatAlarm($task->alarm));
                 }
                 if ($old_task->priority != $task->priority) {
                     $notification_message .= "\n - " . sprintf(_("Changed priority from %s to %s"), $old_task->priority, $task->priority);
                 }
                 if ($old_task->estimate != $task->estimate) {
                     $notification_message .= "\n - " . sprintf(_("Changed estimate from %s to %s"), $old_task->estimate, $task->estimate);
                 }
                 if ($old_task->completed != $task->completed) {
                     $notification_message .= "\n - " . sprintf(_("Changed completion from %s to %s"), $old_task->completed ? _("completed") : _("not completed"), $task->completed ? _("completed") : _("not completed"));
                 }
                 if ($old_task->desc != $task->desc) {
                     $notification_message .= "\n - " . _("Changed description");
                 }
                 break;
             case 'delete':
                 $subject = _("Task deleted:");
                 $notification_message = _("You requested to be notified when tasks are deleted from your task lists.") . "\n\n" . _("The task \"%s\" has been deleted from task list \"%s\".");
                 break;
         }
         $mail->addHeader('Subject', $subject . ' ' . $task->name);
         foreach ($twentyFour as $tf => $dateFormat) {
             foreach ($dateFormat as $df => $df_recipients) {
                 $message = sprintf($notification_message, $task->name, Nag::getLabel($share), $task->due ? strftime($df, $task->due) . ' ' . date($tf ? 'H:i' : 'h:ia', $task->due) : '');
                 if (strlen(trim($task->desc))) {
                     $message .= "\n\n" . _("Task description:") . "\n\n" . $task->desc;
                 }
                 $mail->setBody($message);
                 $mail->clearRecipients();
                 $mail->addRecipients($df_recipients);
                 Horde::log(sprintf('Sending event notifications for %s to %s', $task->name, implode(', ', $df_recipients)), 'INFO');
                 $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'));
             }
         }
     }
 }
Esempio n. 4
0
 /**
  * Sends email notifications to a list of recipients.
  *
  * We do some ugly work in here to make sure that no one gets comments
  * mailed to them that they shouldn't see (because of group permissions).
  *
  * @param array $opts  Option hash with notification information.
  *                     Possible values:
  *                     - ticket:     (Whups_Ticket) A ticket. If not set,
  *                                   this is assumed to be a reminder
  *                                   message.
  *                     - recipients: (array|string) The list of recipients,
  *                                   with user names as keys and user roles
  *                                   as values.
  *                     - subject:    (string) The email subject.
  *                     - view:       (Horde_View) The view object for the
  *                                   message text.
  *                     - template:   (string) The template file for the
  *                                   message text.
  *                     - from:       (string) The email sender.
  *                     - new:        (boolean, optional) Whether the passed
  *                                   ticket was just created.
  */
 public function mail(array $opts)
 {
     global $conf, $registry, $prefs;
     $opts = array_merge(array('ticket' => false, 'new' => false), $opts);
     /* Set up recipients and message headers. */
     $mail = new Horde_Mime_Mail(array('X-Whups-Generated' => 1, 'User-Agent' => 'Whups ' . $registry->getVersion(), 'Precedence' => 'bulk', 'Auto-Submitted' => $opts['ticket'] ? 'auto-replied' : 'auto-generated'));
     $mail_always = null;
     if ($opts['ticket'] && !empty($conf['mail']['always_copy'])) {
         $mail_always = $conf['mail']['always_copy'];
         if (strpos($mail_always, '<@>') !== false) {
             try {
                 $mail_always = str_replace('<@>', $opts['ticket']->get('queue_name'), $mail_always);
             } catch (Whups_Exception $e) {
                 $mail_always = null;
             }
         }
         if ($mail_always && !isset($opts['recipients'][$mail_always])) {
             $opts['recipients'][$mail_always] = 'always';
         }
     }
     if ($opts['ticket'] && ($queue = $this->getQueue($opts['ticket']->get('queue'))) && !empty($queue['email'])) {
         $mail->addHeader('From', $queue['email']);
     } elseif (!empty($conf['mail']['from_addr'])) {
         $mail->addHeader('From', $conf['mail']['from_addr']);
     } else {
         $mail->addHeader('From', Whups::formatUser($opts['from']));
     }
     if (!empty($conf['mail']['return_path'])) {
         $mail->addHeader('Return-Path', $conf['mail']['return_path']);
     }
     if ($opts['ticket']) {
         $opts['subject'] = '[' . $registry->get('name') . ' #' . $opts['ticket']->getId() . '] ' . $opts['subject'];
     }
     $mail->addHeader('Subject', $opts['subject']);
     /* Get our array of comments, sorted in the appropriate order. */
     if ($opts['ticket']) {
         $comments = $this->getHistory($opts['ticket']->getId());
         if ($conf['mail']['commenthistory'] == 'new' && count($comments)) {
             $comments = array_pop($comments);
             $comments = array($comments);
         } elseif ($conf['mail']['commenthistory'] != 'chronological') {
             $comments = array_reverse($comments);
         }
     } else {
         $comments = array();
     }
     /* Don't notify any email address more than once. */
     $seen_email_addresses = array();
     /* Get VFS handle for attachments. */
     if ($opts['ticket']) {
         $vfs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Vfs')->create();
         try {
             $attachments = Whups::getAttachments($opts['ticket']->getId());
         } catch (Whups_Exception $e) {
             $attachments = array();
             Horde::log($e);
         }
     }
     $from = Whups::getUserAttributes($opts['from']);
     foreach ($opts['recipients'] as $user => $role) {
         /* Make sure to check permissions as a guest for the 'always_copy'
          * address, and as the recipient for all others. */
         $to = $full_name = '';
         if (!empty($mail_always) && $user == $mail_always) {
             $details = null;
             $mycomments = Whups::permissionsFilter($comments, 'comment', Horde_Perms::READ, '');
             $to = $mail_always;
         } else {
             $details = Whups::getUserAttributes($user);
             if (!empty($details['email'])) {
                 $to = Whups::formatUser($details);
                 $mycomments = Whups::permissionsFilter($comments, 'comment', Horde_Perms::READ, $details['user']);
             }
             $full_name = $details['name'];
         }
         /* We may have no recipients due to users excluding themselves
          * from self notifies. */
         if (!$to) {
             continue;
         }
         if ($details && $details['type'] == 'user') {
             $user_prefs = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Prefs')->create('whups', array('user' => $details['user']));
             if (($details['user'] == $registry->getAuth() || !$registry->getAuth()) && $from['type'] == 'user' && $details['user'] == $from['user'] && $user_prefs->getValue('email_others_only')) {
                 continue;
             }
         }
         if ($opts['ticket']) {
             /* Add attachments. */
             $attachmentAdded = false;
             if (empty($GLOBALS['conf']['mail']['link_attach'])) {
                 /* We need to remove all attachments because the attachment
                  * list is potentially limited by permissions. */
                 $mail->clearParts();
                 foreach ($mycomments as $comment) {
                     foreach ($comment['changes'] as $change) {
                         if ($change['type'] != 'attachment') {
                             continue;
                         }
                         foreach ($attachments as $attachment) {
                             if ($attachment['name'] != $change['value']) {
                                 continue;
                             }
                             if (!isset($attachment['part'])) {
                                 $attachment['part'] = new Horde_Mime_Part();
                                 $attachment['part']->setType(Horde_Mime_Magic::filenameToMime($change['value'], false));
                                 $attachment['part']->setDisposition('attachment');
                                 $attachment['part']->setContents($vfs->read(Whups::VFS_ATTACH_PATH . '/' . $opts['ticket']->getId(), $change['value']));
                                 $attachment['part']->setName($change['value']);
                             }
                             $mail->addMimePart($attachment['part']);
                             $attachmentAdded = true;
                             break;
                         }
                     }
                 }
             }
             $formattedComment = $this->formatComments($mycomments, $opts['ticket']->getId());
             if (!$attachmentAdded && !strlen(trim($formattedComment)) && $details && $details['type'] == 'user' && $user_prefs->getValue('email_comments_only')) {
                 continue;
             }
             $opts['view']->comment = $formattedComment;
         }
         $addr_ob = new Horde_Mail_Rfc822_Address($to);
         if ($addr_ob->valid) {
             $bare_address = $addr_ob->bare_address;
             if (!empty($seen_email_addresses[$bare_address])) {
                 continue;
             }
             $seen_email_addresses[$bare_address] = true;
             if (empty($full_name) && !is_null($addr_ob->personal)) {
                 $full_name = $addr_ob->personal;
             }
         }
         // Use email address as fallback.
         if (empty($full_name)) {
             $full_name = $to;
         }
         $opts['view']->full_name = $full_name;
         $opts['view']->role = $role;
         $body = $opts['view']->render($opts['template']);
         if (!strlen(trim($body))) {
             continue;
         }
         $mail->setBody($body);
         $mail->addHeaderOb(Horde_Mime_Headers_MessageId::create());
         if ($opts['ticket']) {
             $message_id = '<whups-' . $opts['ticket']->getId() . '-' . md5($user) . '@' . $conf['server']['name'] . '>';
             if ($opts['new']) {
                 $mail->addHeader('Message-ID', $message_id);
             } else {
                 $mail->addHeader('In-Reply-To', $message_id);
                 $mail->addHeader('References', $message_id);
             }
         }
         $mail->clearRecipients();
         $mail->addHeader('To', $to);
         try {
             $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'), true);
             $entry = sprintf('%s Message sent to %s from "%s"', $_SERVER['REMOTE_ADDR'], $to, $GLOBALS['registry']->getAuth());
             Horde::log($entry, 'INFO');
         } catch (Horde_Mime_Exception $e) {
             Horde::log($e, 'ERR');
         }
     }
 }
Esempio n. 5
0
 /**
  * Sends a SMART response.
  *
  * @throws Horde_ActiveSync_Exception
  */
 protected function _sendSmart()
 {
     $mime_message = $this->_raw->getMimeObject();
     // Need to remove content-type header from the incoming raw message
     // since in a smart request, we actually construct the full MIME msg
     // ourselves and the content-type in _headers only applies to the reply
     // text sent from the client, not the fully generated MIME message.
     $this->_headers->removeHeader('Content-Type');
     $this->_headers->removeHeader('Content-Transfer-Encoding');
     $mail = new Horde_Mime_Mail($this->_headers->toArray(array('charset' => 'UTF-8')));
     $base_part = $this->imapMessage->getStructure();
     $plain_id = $base_part->findBody('plain');
     $html_id = $base_part->findBody('html');
     try {
         $body_data = $this->imapMessage->getMessageBodyData(array('protocolversion' => $this->_version, 'bodyprefs' => array(Horde_ActiveSync::BODYPREF_TYPE_MIME => true)));
     } catch (Horde_Exception_NotFound $e) {
         throw new Horde_ActiveSync_Exception($e->getMessage());
     }
     if (!empty($html_id)) {
         $mail->setHtmlBody($this->_getHtmlPart($html_id, $mime_message, $body_data, $base_part));
     } elseif (!empty($plain_id)) {
         $mail->setBody($this->_getPlainPart($plain_id, $mime_message, $body_data, $base_part));
     }
     if ($this->_forward) {
         foreach ($base_part->contentTypeMap() as $mid => $type) {
             if ($this->imapMessage->isAttachment($mid, $type)) {
                 $mail->addMimePart($this->imapMessage->getMimePart($mid));
             }
         }
     }
     foreach ($mime_message->contentTypeMap() as $mid => $type) {
         if ($mid != 0 && $mid != $mime_message->findBody('plain') && $mid != $mime_message->findBody('html')) {
             $mail->addMimePart($mime_message->getPart($mid));
         }
     }
     try {
         $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'));
         $this->_mailer = $mail;
     } catch (Horde_Mime_Exception $e) {
         throw new Horde_ActiveSync_Exception($e);
     }
 }
Esempio n. 6
0
 /**
  * Send new posts to a distribution email address for a wider audience
  *
  * @param int $message_id  Identifier of message to be distributed
  *
  * @throws Horde_Mime_Exception
  */
 function distribute($message_id)
 {
     global $conf;
     $storage = $GLOBALS['injector']->getInstance('Agora_Factory_Driver')->create();
     $message = $storage->getMessage($message_id);
     $forum = $storage->getForum($message['forum_id']);
     if (empty($forum['forum_distribution_address'])) {
         return;
     }
     $mail = new Horde_Mime_Mail();
     $mail->addHeader('X-Horde-Agora-Post', $message_id);
     $mail->addHeader('From', strpos($message['message_author'], '@') ? $message['message_author'] : $forum['forum_distribution_address']);
     $mail->addHeader('Subject', '[' . $forum['forum_name'] . '] ' . $message['message_subject']);
     $mail->addHeader('To', $forum['forum_distribution_address']);
     $mail->setBody($message['body']);
     $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'));
 }
Esempio n. 7
0
 /**
  * Notifies about an alarm by e-mail.
  *
  * @param array $alarm  An alarm hash.
  *
  * @throws Horde_Alarm_Exception
  */
 public function notify(array $alarm)
 {
     if (!empty($alarm['internal']['mail']['sent'])) {
         return;
     }
     if (empty($alarm['params']['mail']['email'])) {
         if (empty($alarm['user'])) {
             return;
         }
         $email = $this->_identity->create($alarm['user'])->getDefaultFromAddress(true);
     } else {
         $email = $alarm['params']['mail']['email'];
     }
     try {
         $mail = new Horde_Mime_Mail(array('Subject' => $alarm['title'], 'To' => $email, 'From' => $email, 'Auto-Submitted' => 'auto-generated', 'X-Horde-Alarm' => $alarm['title']));
         if (isset($alarm['params']['mail']['mimepart'])) {
             $mail->setBasePart($alarm['params']['mail']['mimepart']);
         } elseif (empty($alarm['params']['mail']['body'])) {
             $mail->setBody($alarm['text']);
         } else {
             $mail->setBody($alarm['params']['mail']['body']);
         }
         $mail->send($this->_mail);
     } catch (Horde_Mime_Exception $e) {
         throw new Horde_Alarm_Exception($e);
     }
     $alarm['internal']['mail']['sent'] = true;
     $this->alarm->internal($alarm['id'], $alarm['user'], $alarm['internal']);
 }
Esempio n. 8
0
 public function testReusing()
 {
     $mail = new Horde_Mime_Mail(array('Subject' => 'My Subject', 'body' => "This is\nthe body", 'To' => '*****@*****.**', 'From' => '*****@*****.**', 'charset' => 'iso-8859-15'));
     $dummy = new Horde_Mail_Transport_Mock();
     $mail->send($dummy);
     $sent1 = str_replace("\r\n", "\n", $dummy->sentMessages[0]);
     $mail->addHeader('To', '*****@*****.**');
     $mail->send($dummy);
     $sent2 = str_replace("\r\n", "\n", $dummy->sentMessages[1]);
     $mail->setBody("This is\nanother body");
     $mail->send($dummy);
     $sent3 = str_replace("\r\n", "\n", $dummy->sentMessages[2]);
     $hdrs1 = Horde_Mime_Headers::parseHeaders($sent1['header_text']);
     $hdrs2 = Horde_Mime_Headers::parseHeaders($sent2['header_text']);
     $this->assertNotEquals($hdrs1->getValue('message-id'), $hdrs2->getValue('message-id'));
     $this->assertEquals(array('*****@*****.**'), $sent1['recipients']);
     $this->assertEquals(array('*****@*****.**'), $sent2['recipients']);
     $this->assertEquals("This is\nanother body\n", $sent3['body']);
 }
Esempio n. 9
0
 /**
  * Sends a SMART request.
  *
  * @throws Horde_ActiveSync_Exception
  */
 protected function _sendSmart()
 {
     $mime_message = $this->_raw->getMimeObject();
     $mail = new Horde_Mime_Mail($this->_headers->toArray(array('charset' => 'UTF-8')));
     $base_part = $this->imapMessage->getStructure();
     $plain_id = $base_part->findBody('plain');
     $html_id = $base_part->findBody('html');
     try {
         $body_data = $this->imapMessage->getMessageBodyData(array('protocolversion' => $this->_version, 'bodyprefs' => array(Horde_ActiveSync::BODYPREF_TYPE_MIME => true)));
     } catch (Horde_Exception_NotFound $e) {
         throw new Horde_ActiveSync_Exception($e->getMessage());
     }
     if (!empty($html_id)) {
         $mail->setHtmlBody($this->_getHtmlPart($html_id, $mime_message, $body_data, $base_part));
     }
     if (!empty($plain_id)) {
         $mail->setBody($this->_getPlainPart($plain_id, $mime_message, $body_data, $base_part));
     }
     if ($this->_forward) {
         foreach ($base_part->contentTypeMap() as $mid => $type) {
             if ($this->imapMessage->isAttachment($mid, $type)) {
                 $mail->addMimePart($this->imapMessage->getMimePart($mid));
             }
         }
     }
     foreach ($mime_message->contentTypeMap() as $mid => $type) {
         if ($mid != 0 && $mid != $mime_message->findBody('plain') && $mid != $mime_message->findBody('html')) {
             $mail->addMimePart($mime_message->getPart($mid));
         }
     }
     try {
         $mail->send($GLOBALS['injector']->getInstance('Horde_Mail'));
         $this->_mailer = $mail;
     } catch (Horde_Mime_Exception $e) {
         throw new Horde_ActiveSync_Exception($e);
     }
 }