Author: Michael Slusarz (slusarz@horde.org)
Example #1
0
 /**
  * @see showInlineImage
  */
 protected function _showInlineImage(IMP_Contents $contents)
 {
     global $injector, $prefs;
     if ($this->alwaysShow || !$prefs->getValue('image_replacement')) {
         return true;
     }
     if (!$contents || !($tmp = $contents->getHeader()->getHeader('from')) || !($from = $tmp->getAddressList(true))) {
         return false;
     }
     $res = $injector->getInstance('IMP_Contacts')->searchEmail($from->first()->bare_address, array('email_exact' => true));
     if (count($res)) {
         /* Don't allow personal addresses by default - this is the only
          * e-mail address a Spam sender for sure knows you will recognize
          * so it is too much of a loophole. */
         $res->setIteratorFilter(0, $injector->getInstance('IMP_Identity')->getAllFromAddresses());
         foreach ($from as $val) {
             if ($res->contains($val)) {
                 return true;
             }
         }
     }
     /* Check safe address list. */
     $safeAddrs = $injector->getInstance('IMP_Prefs_Special_ImageReplacement')->safeAddrList();
     foreach ($from as $val) {
         if ($safeAddrs->contains($val)) {
             return true;
         }
     }
     return false;
 }
Example #2
0
 /**
  */
 public function report(IMP_Contents $contents, $action)
 {
     global $injector, $registry;
     $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create();
     switch ($this->_format) {
         case 'redirect':
             /* Send the message. */
             try {
                 $imp_compose->redirectMessage($contents->getIndicesOb());
                 $imp_compose->sendRedirectMessage($this->_email, false);
                 return true;
             } catch (IMP_Compose_Exception $e) {
                 $e->log();
             }
             break;
         case 'digest':
         default:
             try {
                 $from_line = $injector->getInstance('IMP_Identity')->getFromLine();
             } catch (Horde_Exception $e) {
                 $from_line = null;
             }
             /* Build the MIME structure. */
             $mime = new Horde_Mime_Part();
             $mime->setType('multipart/digest');
             $rfc822 = new Horde_Mime_Part();
             $rfc822->setType('message/rfc822');
             $rfc822->setContents($contents->fullMessageText(array('stream' => true)));
             $mime->addPart($rfc822);
             $spam_headers = new Horde_Mime_Headers();
             $spam_headers->addMessageIdHeader();
             $spam_headers->addHeader('Date', date('r'));
             $spam_headers->addHeader('To', $this->_email);
             if (!is_null($from_line)) {
                 $spam_headers->addHeader('From', $from_line);
             }
             $spam_headers->addHeader('Subject', sprintf(_("%s report from %s"), $action == IMP_Spam::SPAM ? 'spam' : 'innocent', $registry->getAuth()));
             /* Send the message. */
             try {
                 $recip_list = $imp_compose->recipientList(array('to' => $this->_email));
                 $imp_compose->sendMessage($recip_list['list'], $spam_headers, $mime, 'UTF-8');
                 $rfc822->clearContents();
                 return true;
             } catch (IMP_Compose_Exception $e) {
                 $e->log();
                 $rfc822->clearContents();
             }
             break;
     }
     return false;
 }
Example #3
0
File: View.php Project: horde/horde
 /**
  * @throws IMP_Exception
  */
 public function composeAttachPreview($id, $autodetect = false, $ctype = null)
 {
     if (!($atc = $this->_compose[$id]) || !($mime = $atc->getPart(true))) {
         $e = new IMP_Exception(_("Could not display attachment data."));
         $e->logged = true;
         throw $e;
     }
     $mime->setMimeId($id);
     $contents = new IMP_Contents($mime);
     $render = $contents->renderMIMEPart($id, $contents::RENDER_RAW_FALLBACK, array('autodetect' => $autodetect, 'type' => $ctype));
     if (!empty($render)) {
         return reset($render);
     } elseif ($autodetect) {
         $e = new IMP_Exception(_("Could not display attachment data."));
         $e->logged = true;
         throw $e;
     }
     return array();
 }
Example #4
0
 /**
  * Get a MIME Part for use in creating download.
  *
  * @param string $id  MIME ID.
  *
  * @return Horde_Mime_Part  MIME part.
  */
 protected function _getRawDownloadPart($id)
 {
     $mime = $this->_contents->getMIMEPart($id);
     if ($this->_contents->canDisplay($id, IMP_Contents::RENDER_RAW)) {
         $render = $this->_contents->renderMIMEPart($id, IMP_Contents::RENDER_RAW);
         $part = reset($render);
         $mime->setContents($part['data'], array('encoding' => 'binary'));
     }
     return $mime;
 }
Example #5
0
File: View.php Project: horde/horde
 /**
  * Get a MIME Part for use in creating download.
  *
  * @param string $id  MIME ID.
  *
  * @return Horde_Mime_Part  MIME part, or null on error.
  */
 protected function _getRawDownloadPart($id)
 {
     if (!($mime = $this->_contents->getMimePart($id))) {
         return null;
     }
     if ($this->_contents->canDisplay($id, IMP_Contents::RENDER_RAW)) {
         $render = $this->_contents->renderMIMEPart($id, IMP_Contents::RENDER_RAW);
         $part = reset($render);
         $mime->setContents($part['data'], array('encoding' => 'binary', 'usestream' => true));
     }
     return $mime;
 }
Example #6
0
 /**
  */
 public function report(IMP_Contents $contents, $action)
 {
     /* Use a pipe to write the message contents. This should be
      * secure. */
     $proc = proc_open($this->_binary, array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
     if (!is_resource($proc)) {
         Horde::log(sprintf('Cannot open spam reporting program: %s', $proc), 'ERR');
         return false;
     }
     stream_copy_to_stream($contents->fullMessageText(array('stream' => true)), $pipes[0]);
     fclose($pipes[0]);
     $stderr = '';
     while (!feof($pipes[2])) {
         $stderr .= fgets($pipes[2]);
     }
     fclose($pipes[2]);
     if (!empty($stderr)) {
         Horde::log(sprintf('Error reporting spam: %s', $stderr), 'ERR');
     }
     proc_close($proc);
     return true;
 }
Example #7
0
 /**
  * @see showInlineImage
  */
 protected function _showInlineImage(IMP_Contents $contents)
 {
     global $injector, $prefs, $registry;
     if ($this->alwaysShow || !$prefs->getValue('image_replacement')) {
         return true;
     }
     if (!$contents || !($from = $contents->getHeader()->getOb('from'))) {
         return false;
     }
     if ($registry->hasMethod('contacts/search')) {
         $sparams = $injector->getInstance('IMP_Contacts')->getAddressbookSearchParams();
         try {
             $res = $registry->call('contacts/search', array($from->bare_addresses, array('customStrict' => array('email'), 'fields' => array_fill_keys($sparams['sources'], array('email')), 'returnFields' => array('email'), 'rfc822Return' => true, 'sources' => $sparams['sources'])));
             // Don't allow personal addresses by default - this is the
             // only e-mail address a Spam sender for sure knows you will
             // recognize so it is too much of a loophole.
             $res->setIteratorFilter(0, $injector->getInstance('IMP_Identity')->getAllFromAddresses());
             foreach ($from as $val) {
                 if ($res->contains($val)) {
                     return true;
                 }
             }
         } catch (Horde_Exception $e) {
             // Ignore errors from the search - default to not showing
             // images.
             Horde::log($e, 'INFO');
         }
     }
     /* Check safe address list. */
     $safeAddrs = $injector->getInstance('IMP_Prefs_Special_ImageReplacement')->safeAddrList();
     foreach ($from as $val) {
         if ($safeAddrs->contains($val)) {
             return true;
         }
     }
     return false;
 }
Example #8
0
 /**
  * Generate inline message display.
  *
  * @param array $options  Options:
  *   - mask: (integer) The mask needed for a getSummary() call.
  *   - mimeid: (string) Restrict output to this MIME ID (and children).
  *
  * @return array  See getInlineOutput().
  */
 protected function _getInlineOutput(array $options)
 {
     global $prefs, $registry;
     $atc_parts = $display_ids = $i = $metadata = $msgtext = $wrap_ids = array();
     $text_out = '';
     $view = $registry->getView();
     $contents_mask = isset($options['mask']) ? $options['mask'] : 0;
     $mimeid_filter = isset($options['mimeid']) ? new Horde_Mime_Id($options['mimeid']) : null;
     $show_parts = $prefs->getValue('parts_display');
     foreach ($this->contents->getMIMEMessage()->partIterator() as $part) {
         $mime_id = $part->getMimeId();
         $i[] = $mime_id;
         if (isset($display_ids[$mime_id]) || isset($atc_parts[$mime_id])) {
             continue;
         }
         if ($mimeid_filter && (strval($mimeid_filter) != $mime_id && !$mimeid_filter->isChild($mime_id))) {
             continue;
         }
         if (!($render_mode = $this->contents->canDisplay($mime_id, IMP_Contents::RENDER_INLINE_AUTO))) {
             if (IMP_Mime_Attachment::isAttachment($part)) {
                 if ($show_parts == 'atc') {
                     $atc_parts[$mime_id] = 1;
                 }
                 if ($contents_mask) {
                     $msgtext[$mime_id] = array('text' => $this->_formatSummary($this->contents->getSummary($mime_id, $contents_mask), true));
                 }
             }
             continue;
         }
         $render_part = $this->contents->renderMIMEPart($mime_id, $render_mode);
         if ($show_parts == 'atc' && IMP_Mime_Attachment::isAttachment($part) && (empty($render_part) || !($render_mode & IMP_Contents::RENDER_INLINE))) {
             $atc_parts[$mime_id] = 1;
         }
         if (empty($render_part)) {
             if ($contents_mask && IMP_Mime_Attachment::isAttachment($part)) {
                 $msgtext[$mime_id] = array('text' => $this->_formatSummary($this->contents->getSummary($mime_id, $contents_mask), true));
             }
             continue;
         }
         reset($render_part);
         while (list($id, $info) = each($render_part)) {
             $display_ids[$id] = 1;
             if (empty($info)) {
                 continue;
             }
             $part_text = $contents_mask && empty($info['nosummary']) ? $this->_formatSummary($this->contents->getSummary($id, $contents_mask), !empty($info['attach'])) : '';
             if (empty($info['attach'])) {
                 if (isset($info['status'])) {
                     if (!is_array($info['status'])) {
                         $info['status'] = array($info['status']);
                     }
                     $render_issues = array();
                     foreach ($info['status'] as $val) {
                         if (in_array($view, $val->views)) {
                             if ($val instanceof IMP_Mime_Status_RenderIssue) {
                                 $render_issues[] = $val;
                             } else {
                                 $part_text .= strval($val);
                             }
                         }
                     }
                     if (!empty($render_issues)) {
                         $render_issues_ob = new IMP_Mime_Status_RenderIssue_Display();
                         $render_issues_ob->addIssues($render_issues);
                         $part_text .= strval($render_issues_ob);
                     }
                 }
                 $part_text .= '<div class="mimePartData">' . $info['data'] . '</div>';
             } elseif ($show_parts == 'atc') {
                 $atc_parts[$id] = 1;
             }
             $msgtext[$id] = array('text' => $part_text, 'wrap' => empty($info['wrap']) ? null : $info['wrap']);
             if (isset($info['metadata'])) {
                 /* Format: array(identifier, ...[data]...) */
                 $metadata = array_merge($metadata, $info['metadata']);
             }
         }
     }
     if (!empty($msgtext)) {
         uksort($msgtext, 'strnatcmp');
     }
     reset($msgtext);
     while (list($id, $part) = each($msgtext)) {
         while (!empty($wrap_ids)) {
             $id_ob = new Horde_Mime_Id(end($wrap_ids));
             if ($id_ob->isChild($id)) {
                 break;
             }
             array_pop($wrap_ids);
             $text_out .= '</div>';
         }
         if (!empty($part['wrap'])) {
             $text_out .= '<div class="' . $part['wrap'] . '" impcontentsmimeid="' . $id . '">';
             $wrap_ids[] = $id;
         }
         $text_out .= '<div class="mimePartBase"' . (empty($part['wrap']) ? ' impcontentsmimeid="' . $id . '"' : '') . '>' . $part['text'] . '</div>';
     }
     $text_out .= str_repeat('</div>', count($wrap_ids));
     if (!strlen($text_out)) {
         $text_out = strval(new IMP_Mime_Status(null, _("There are no parts that can be shown inline.")));
     }
     $atc_parts = $show_parts == 'all' ? $i : array_keys($atc_parts);
     return array('atc_parts' => $atc_parts, 'display_ids' => array_keys($display_ids), 'metadata' => $metadata, 'msgtext' => $text_out, 'one_part' => count($i) === 1);
 }
Example #9
0
 /**
  * Regenerates body text for use in the compose screen from IMAP data.
  *
  * @param IMP_Contents $contents  An IMP_Contents object.
  * @param array $options          Additional options:
  * <ul>
  *  <li>html: (boolean) Return text/html part, if available.</li>
  *  <li>imp_msg: (integer) If non-empty, the message data was created by
  *               IMP. Either:
  *   <ul>
  *    <li>self::COMPOSE</li>
  *    <li>self::FORWARD</li>
  *    <li>self::REPLY</li>
  *   </ul>
  *  </li>
  *  <li>replylimit: (boolean) Enforce length limits?</li>
  *  <li>toflowed: (boolean) Do flowed conversion?</li>
  * </ul>
  *
  * @return mixed  Null if bodypart not found, or array with the following
  *                keys:
  *   - charset: (string) The guessed charset to use.
  *   - flowed: (Horde_Text_Flowed) A flowed object, if the text is flowed.
  *             Otherwise, null.
  *   - id: (string) The MIME ID of the bodypart.
  *   - mode: (string) Either 'text' or 'html'.
  *   - text: (string) The body text.
  */
 protected function _getMessageText($contents, array $options = array())
 {
     global $conf, $injector, $notification, $prefs;
     $body_id = null;
     $mode = 'text';
     $options = array_merge(array('imp_msg' => self::COMPOSE), $options);
     if (!empty($options['html']) && self::canHtmlCompose() && ($body_id = $contents->findBody('html')) !== null) {
         $mime_message = $contents->getMIMEMessage();
         switch ($mime_message->getPrimaryType()) {
             case 'multipart':
                 if ($body_id != '1' && $mime_message->getSubType() == 'mixed' && ($id_ob = new Horde_Mime_Id('1')) && !$id_ob->isChild($body_id)) {
                     $body_id = null;
                 } else {
                     $mode = 'html';
                 }
                 break;
             default:
                 if (strval($body_id) != '1') {
                     $body_id = null;
                 } else {
                     $mode = 'html';
                 }
                 break;
         }
     }
     if (is_null($body_id)) {
         $body_id = $contents->findBody();
         if (is_null($body_id)) {
             return null;
         }
     }
     if (!($part = $contents->getMimePart($body_id))) {
         return null;
     }
     $type = $part->getType();
     $part_charset = $part->getCharset();
     $msg = Horde_String::convertCharset($part->getContents(), $part_charset, 'UTF-8');
     /* Enforce reply limits. */
     if (!empty($options['replylimit']) && !empty($conf['compose']['reply_limit'])) {
         $limit = $conf['compose']['reply_limit'];
         if (Horde_String::length($msg) > $limit) {
             $msg = Horde_String::substr($msg, 0, $limit) . "\n" . _("[Truncated Text]");
         }
     }
     if ($mode == 'html') {
         $dom = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter($msg, 'Xss', array('charset' => $this->charset, 'return_dom' => true, 'strip_style_attributes' => false));
         /* If we are replying to a related part, and this part refers
          * to local message parts, we need to move those parts into this
          * message (since the original message may disappear during the
          * compose process). */
         if ($related_part = $contents->findMimeType($body_id, 'multipart/related')) {
             $this->_setMetadata('related_contents', $contents);
             $related_ob = new Horde_Mime_Related($related_part);
             $related_ob->cidReplace($dom, array($this, '_getMessageTextCallback'), $part_charset);
             $this->_setMetadata('related_contents', null);
         }
         /* Convert any Data URLs to attachments. */
         $xpath = new DOMXPath($dom->dom);
         foreach ($xpath->query('//*[@src]') as $val) {
             $data_url = new Horde_Url_Data($val->getAttribute('src'));
             if (strlen($data_url->data)) {
                 $data_part = new Horde_Mime_Part();
                 $data_part->setContents($data_url->data);
                 $data_part->setType($data_url->type);
                 try {
                     $atc = $this->addAttachmentFromPart($data_part);
                     $val->setAttribute('src', $atc->viewUrl());
                     $this->addRelatedAttachment($atc, $val, 'src');
                 } catch (IMP_Compose_Exception $e) {
                     $notification->push($e, 'horde.warning');
                 }
             }
         }
         $msg = $dom->returnBody();
     } elseif ($type == 'text/html') {
         $msg = $injector->getInstance('Horde_Core_Factory_TextFilter')->filter($msg, 'Html2text');
         $type = 'text/plain';
     }
     /* Always remove leading/trailing whitespace. The data in the
      * message body is not intended to be the exact representation of the
      * original message (use forward as message/rfc822 part for that). */
     $msg = trim($msg);
     if ($type == 'text/plain') {
         if ($prefs->getValue('reply_strip_sig') && ($pos = strrpos($msg, "\n-- ")) !== false) {
             $msg = rtrim(substr($msg, 0, $pos));
         }
         /* Remove PGP armored text. */
         $pgp = $injector->getInstance('Horde_Crypt_Pgp_Parse')->parseToPart($msg);
         if (!is_null($pgp)) {
             $msg = '';
             $pgp->buildMimeIds();
             foreach ($pgp->partIterator() as $val) {
                 if ($val->getPrimaryType() === 'text') {
                     $msg .= $val->getContents();
                 }
             }
         }
         if ($part->getContentTypeParameter('format') == 'flowed') {
             $flowed = new Horde_Text_Flowed($msg, 'UTF-8');
             if (Horde_String::lower($part->getContentTypeParameter('delsp')) == 'yes') {
                 $flowed->setDelSp(true);
             }
             $flowed->setMaxLength(0);
             $msg = $flowed->toFixed(false);
         } else {
             /* If the input is *not* in flowed format, make sure there is
              * no padding at the end of lines. */
             $msg = preg_replace("/\\s*\n/U", "\n", $msg);
         }
         if (isset($options['toflowed'])) {
             $flowed = new Horde_Text_Flowed($msg, 'UTF-8');
             $msg = $options['toflowed'] ? $flowed->toFlowed(true) : $flowed->toFlowed(false, array('nowrap' => true));
         }
     }
     if (strcasecmp($part->getCharset(), 'windows-1252') === 0) {
         $part_charset = 'ISO-8859-1';
     }
     return array('charset' => $part_charset, 'flowed' => isset($flowed) ? $flowed : null, 'id' => $body_id, 'mode' => $mode, 'text' => $msg);
 }
Example #10
0
 /**
  * Create the object used to display the message.
  *
  * @param array $args  Configuration parameters:
  *   - headers: (array) The headers desired in the returned headers array
  *              (only used with non-preview view).
  *   - preview: (boolean) Is this the preview view?
  *
  * @return array  Array with the following keys:
  *   - atc_download: The download all link
  *   - atc_label: The label to use for Attachments
  *   - atc_list: The list (HTML code) of attachments
  *   - bcc (FULL): The Bcc addresses
  *   - cc: The CC addresses
  *   - fulldate (FULL): The full canonical date.
  *   - from: The From addresses
  *   - headers (FULL): An array of headers (not including basic headers)
  *   - js: Javascript code to run on display
  *   - list_info (FULL): List information.
  *   - localdate (PREVIEW): The date formatted to the user's timezone
  *   - md: Metadata
  *   - msgtext: The text of the message
  *   - onepart: True if message only contains one part.
  *   - replyTo (FULL): The Reply-to addresses
  *   - save_as: The save link
  *   - subject: The subject
  *   - subjectlink: The subject with linked URLs/email addresses (defaults
  *                  to 'subject')
  *   - title (FULL): The title of the page
  *   - to: The To addresses
  *
  * @throws IMP_Exception
  */
 public function showMessage($args)
 {
     global $injector, $page_output, $prefs, $registry, $session;
     $preview = !empty($args['preview']);
     $result = array();
     $mime_headers = $this->_peek ? $this->_contents->getHeader() : $this->_contents->getHeaderAndMarkAsSeen();
     $headers = array();
     $imp_ui = $injector->getInstance('IMP_Message_Ui');
     /* Develop the list of Headers to display now. Deal with the 'basic'
      * header information first since there are various manipulations
      * done to them. */
     $basic_headers = $imp_ui->basicHeaders();
     if (empty($args['headers'])) {
         $args['headers'] = array('from', 'date', 'to', 'cc', 'bcc');
     }
     $headers_list = array_intersect_key($basic_headers, array_flip($args['headers']));
     /* Build From/To/Cc/Bcc/Reply-To links. */
     foreach (array('from', 'to', 'cc', 'bcc', 'reply-to') as $val) {
         if (isset($headers_list[$val]) && (!$preview || $val != 'reply-to')) {
             if ($tmp = $this->getAddressHeader($val)) {
                 $result[$val] = $tmp;
             }
             if ($preview) {
                 unset($headers_list[$val]);
             }
         }
     }
     /* Build the rest of the headers. */
     foreach ($headers_list as $head => $str) {
         if ($val = $mime_headers->getValue($head)) {
             if ($head == 'date') {
                 /* Add local time to date header. */
                 $date_ob = new IMP_Message_Date($this->_envelope->date);
                 $val = htmlspecialchars($date_ob->format($date_ob::DATE_LOCAL));
                 if ($preview) {
                     $result['localdate'] = $val;
                 } else {
                     $result['fulldate'] = $date_ob->format($date_ob::DATE_FORCE);
                 }
             } elseif (!$preview) {
                 $val = htmlspecialchars($val);
             }
             if (!$preview) {
                 $headers[$head] = array('id' => Horde_String::ucfirst($head), 'name' => $str, 'value' => $val);
             }
         }
     }
     if (empty($result['reply-to']) || $result['from']['addr'][0]->b == $result['reply-to']['addr'][0]->b) {
         unset($result['reply-to'], $headers['reply-to']);
     }
     /* JS requires camelized name for reply-to. */
     if (!$preview && isset($headers['reply-to'])) {
         $result['replyTo'] = $result['reply-to'];
         $headers['reply-to']['id'] = 'ReplyTo';
         unset($result['reply-to']);
     }
     /* Maillog information. */
     $ajax_queue = $injector->getInstance('IMP_Ajax_Queue');
     $ajax_queue->maillog($this->_indices);
     if (!$preview) {
         /* Display the user-specified headers for the current identity. */
         $user_hdrs = $imp_ui->getUserHeaders();
         foreach ($user_hdrs as $user_hdr) {
             $user_val = $mime_headers->getValue($user_hdr);
             if (!empty($user_val)) {
                 if (!is_array($user_val)) {
                     $user_val = array($user_val);
                 }
                 foreach ($user_val as $val) {
                     $headers[] = array('name' => $user_hdr, 'value' => htmlspecialchars($val));
                 }
             }
         }
         $result['headers'] = array_values($headers);
     }
     /* Process the subject. */
     $subject = $mime_headers->getValue('subject');
     if ($subject) {
         $text_filter = $injector->getInstance('Horde_Core_Factory_TextFilter');
         $filtered_subject = preg_replace("/\\b\\s+\\b/", ' ', IMP::filterText($subject));
         $result['subject'] = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML));
         $subjectlink = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO));
         if ($subjectlink != $result['subject']) {
             $result['subjectlink'] = $subjectlink;
         }
         if (!$preview) {
             $result['title'] = $subject;
         }
     } else {
         $result['subject'] = _("[No Subject]");
         if (!$preview) {
             $result['title'] = _("[No Subject]");
         }
     }
     // Create message text and attachment list.
     $result['msgtext'] = '';
     $show_parts = $prefs->getValue('parts_display');
     switch ($registry->getView()) {
         case $registry::VIEW_SMARTMOBILE:
             $contents_mask = 0;
             break;
         default:
             $contents_mask = IMP_Contents::SUMMARY_BYTES | IMP_Contents::SUMMARY_SIZE | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_DESCRIP_LINK | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_DOWNLOAD_ZIP | IMP_Contents::SUMMARY_PRINT_STUB;
             break;
     }
     $part_info = $part_info_display = array('icon', 'description', 'size', 'download', 'download_zip');
     $part_info_display[] = 'print';
     list($mbox, $uid) = $this->_indices->getSingle();
     /* Do MDN processing now. */
     switch ($registry->getView()) {
         case $registry::VIEW_DYNAMIC:
             if ($imp_ui->MDNCheck(new IMP_Indices($mbox, $uid), $mime_headers)) {
                 $status = new IMP_Mime_Status(array(_("The sender of this message is requesting notification from you when you have read this message."), sprintf(_("Click %s to send the notification message."), Horde::link('#', '', '', '', '', '', '', array('id' => 'send_mdn_link')) . _("HERE") . '</a>')));
                 $status->domid('sendMdnMessage');
                 $result['msgtext'] .= strval($status);
             }
     }
     /* Build body text. This needs to be done before we build the
      * attachment list. */
     $session->close();
     $inlineout = $this->_contents->getInlineOutput(array('mask' => $contents_mask, 'part_info_display' => $part_info_display, 'show_parts' => $show_parts));
     $session->start();
     $result['md'] = $inlineout['metadata'];
     $result['msgtext'] .= $inlineout['msgtext'];
     if ($inlineout['one_part']) {
         $result['onepart'] = true;
     }
     if (count($inlineout['atc_parts']) || $show_parts == 'all' && count($inlineout['display_ids']) > 2) {
         $result['atc_label'] = $show_parts == 'all' ? _("Parts") : sprintf(ngettext("%d Attachment", "%d Attachments", count($inlineout['atc_parts'])), count($inlineout['atc_parts']));
         if (count($inlineout['atc_parts']) > 2) {
             $result['atc_download'] = Horde::link($this->_contents->urlView($this->_contents->getMIMEMessage(), 'download_all')) . '[' . _("Save All") . ']</a>';
         }
     }
     /* Show attachment information in headers? */
     if (!empty($inlineout['atc_parts'])) {
         $partlist = array();
         if ($show_parts == 'all') {
             array_unshift($part_info, 'id');
         }
         foreach ($inlineout['atc_parts'] as $id) {
             $contents_mask |= IMP_Contents::SUMMARY_DESCRIP | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_SIZE;
             $part_info[] = 'description_raw';
             $part_info[] = 'download_url';
             $summary = $this->_contents->getSummary($id, $contents_mask);
             $tmp = array();
             foreach ($part_info as $val) {
                 if (isset($summary[$val])) {
                     $tmp[$val] = $summary[$val] instanceof Horde_Url ? strval($summary[$val]->setRaw(true)) : $summary[$val];
                 }
             }
             $partlist[] = array_filter($tmp);
         }
         $result['atc_list'] = $partlist;
     }
     $result['save_as'] = IMP_Contents_View::downloadUrl(htmlspecialchars_decode($result['subject']), array_merge(array('actionID' => 'save_message'), $mbox->urlParams($uid)));
     if ($preview) {
         /* Need to grab cached inline scripts. */
         Horde::startBuffer();
         $page_output->outputInlineScript(true);
         if ($js_inline = Horde::endBuffer()) {
             $result['js'] = array($js_inline);
         }
         $result['save_as'] = strval($result['save_as']->setRaw(true));
     } else {
         $list_info = $imp_ui->getListInformation($mime_headers);
         if (!empty($list_info['exists'])) {
             $result['list_info'] = $list_info;
         }
     }
     /* Add changed flag information. */
     if (!$this->_peek && $mbox->is_imap) {
         $status = $mbox->imp_imap->status($mbox, Horde_Imap_Client::STATUS_PERMFLAGS);
         if (in_array(Horde_Imap_Client::FLAG_SEEN, $status['permflags'])) {
             $ajax_queue->flag(array(Horde_Imap_Client::FLAG_SEEN), true, $this->_indices);
         }
     }
     return array_filter($result);
 }