From 717fab3db3df3b8d078ed97d9f12c08f63d089f1 Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Wed, 12 Nov 2008 20:21:22 -0700 Subject: [PATCH] Use new rendering code. getSummary() now only returns a single part info. It is the job of the calling code to plan the UI output and step through the message accordingly. This should (eventually) prevent us from having to create Horde_Mime_Viewer objects for every part of the message, and should be a bit more memory friendly (since we are only dealing with a part at a time. --- imp/lib/Contents.php | 362 ++++++++++++++++++++++++++------------------------- imp/lib/Message.php | 9 +- imp/message.php | 125 ++++++++++-------- imp/view.php | 8 +- 4 files changed, 260 insertions(+), 244 deletions(-) diff --git a/imp/lib/Contents.php b/imp/lib/Contents.php index d9b8077ff..06af04f44 100644 --- a/imp/lib/Contents.php +++ b/imp/lib/Contents.php @@ -14,17 +14,21 @@ class IMP_Contents { /* Mask entries for getSummary(). */ - const SUMMARY_RENDER = 1; - const SUMMARY_BYTES = 2; - const SUMMARY_SIZE = 4; - const SUMMARY_ICON = 8; - const SUMMARY_DESCRIP_LINK = 16; - const SUMMARY_DESCRIP_NOLINK = 32; - const SUMMARY_DOWNLOAD = 64; - const SUMMARY_DOWNLOAD_ZIP = 128; - const SUMMARY_IMAGE_SAVE = 256; - const SUMMARY_STRIP_LINK = 512; - const SUMMARY_DOWNLOAD_ALL = 1024; + const SUMMARY_BYTES = 1; + const SUMMARY_SIZE = 2; + const SUMMARY_ICON = 4; + const SUMMARY_DESCRIP_LINK = 8; + const SUMMARY_DESCRIP_NOLINK = 16; + const SUMMARY_DOWNLOAD = 32; + const SUMMARY_DOWNLOAD_ZIP = 64; + const SUMMARY_IMAGE_SAVE = 128; + const SUMMARY_STRIP_LINK = 256; + + /* TODO */ + const RENDER_FULL = 1; + const RENDER_INLINE = 2; + const RENDER_INLINE_DISP_NO = 4; + const RENDER_INFO = 8; /** * The IMAP index of the message. @@ -55,6 +59,13 @@ class IMP_Contents protected $_build = false; /** + * Cached rendering info. + * + * @param array + */ + protected $_rendercache = array(); + + /** * Attempts to return a reference to a concrete IMP_Contents instance. * If an IMP_Contents object is currently stored in the local cache, * recreate that object. Else, create a new instance. @@ -290,18 +301,9 @@ class IMP_Contents * identified in the MIME part. * * - * @return array An array of information: - *
-     * 'data' - (string) The rendered data.
-     * 'ids' - (array) TODO
-     * 'name' - (string) The name of the part.
-     * 'status' - (array) An array of status information to be displayed to
-     *            the user.  Consists of arrays with the following keys:
-     *            'position' - (string) Either 'top' or 'bottom'
-     *            'text' - (string) The text to display
-     *            'type' - (string) Either 'info' or 'warning'
-     * 'type' - (string) The MIME type of the rendered data.
-     * 
+ * @return array See Horde_Mime_Viewer_Driver::render(). Additionally, + * a entry in the base array labeled 'name' will be present + * which contains the MIME name information. */ public function renderMIMEPart($mime_id, $mode, $options = array()) { @@ -356,7 +358,7 @@ class IMP_Contents */ public function findBody($subtype = null) { - foreach ($this->_message->contentTypeMap() as $mime_id => $mime_type) { + foreach ($this->getContentTypeMap() as $mime_id => $mime_type) { if ((strpos($mime_type, 'text/') === 0) && (intval($mime_id) == 1) && (is_null($subtype) || (substr($mime_type, 5) == $subtype))) { @@ -406,14 +408,11 @@ class IMP_Contents } /** - * Get message summary info. + * Get summary info for a MIME ID. * + * @param string $id The MIME ID. * @param integer $mask A bitmask indicating what information to return: *
-     * IMP_Contents::SUMMARY_RENDER
-     *   Output: parts = 'render_info', 'render_inline'
-     *           info = 'render'
-     *
      * IMP_Contents::SUMMARY_BYTES
      *   Output: parts = 'bytes'
      *
@@ -429,172 +428,122 @@ class IMP_Contents
      *
      * IMP_Contents::SUMMARY_DOWNLOAD
      *   Output: parts = 'download'
-     *           info = 'has' => 'download
      *
      * IMP_Contents::SUMMARY_DOWNLOAD_ZIP
      *   Output: parts = 'download_zip'
-     *           info = 'has' => 'download
      *
      * IMP_Contents::SUMMARY_IMAGE_SAVE
      *   Output: parts = 'img_save'
-     *           info = 'has' => 'img_save
      *
      * IMP_Contents::SUMMARY_STRIP_LINK
      *   Output: parts = 'strip'
-     *           info = 'has' => 'strip'
-     *
-     * IMP_Contents::SUMMARY_DOWNLOAD_ALL
-     *   Output: info = 'download_all'
      * 
* - * @return array An array with two keys: 'info' and 'parts'. See above - * for the information returned in each key. + * @return array An array with the requested information. */ - public function getSummary($mask = 0) + public function getSummary($id, $mask = 0) { - $info = array( - 'download_all' => array(), - 'has' => array(), - 'render' => array() - ); - $parts = array(); - $rfc822 = null; - - // Cache some settings before we enter the loop. $download_zip = (($mask & self::SUMMARY_DOWNLOAD_ZIP) && Util::extensionExists('zlib')); - $img_save = (($mask && self::SUMMARY_IMAGE_SAVE) && - $GLOBALS['registry']->hasMethod('images/selectGalleries')); - if ($mask && self::SUMMARY_STRIP_LINK) { - $message_token = IMP::getRequestToken('imp.impcontents'); - } + $param_array = array(); $this->_buildMessage(); - foreach ($this->_message->contentTypeMap() as $mime_id => $mime_type) { - $parts[$mime_id] = array( - 'bytes' => null, - 'download' => null, - 'download_zip' => null, - 'id' => $mime_id, - 'img_save' => null, - 'render_info' => false, - 'render_inline' => false, - 'size' => null, - 'strip' => null - ); - $part = &$parts[$mime_id]; - - $mime_part = $this->getMIMEPart($mime_id, array('nocontents' => true, 'nodecode' => true)); - - /* If this is an attachment that has no specific MIME type info, - * see if we can guess a rendering type. */ - $param_array = array(); - if (in_array($mime_type, array('application/octet-stream', 'application/base64'))) { - $mime_type = Horde_Mime_Magic::filenameToMIME($mime_part->getName()); - $param_array['ctype'] = $mime_type; - } - $part['type'] = $mime_type; - - /* Determine if part can be viewed inline or has viewable info. */ - if ($mask & self::SUMMARY_RENDER) { - $viewer = Horde_Mime_Viewer::factory($mime_part, $mime_type); - - if ($viewer->canRender('inline') && - ($mime_part->getDisposition() == 'inline')) { - $part['render_inline'] = true; - $info['render'][$mime_id] = 'inline'; - } elseif ($viewer->canRender('info')) { - $part['render_info'] = true; - $info['render'][$mime_id] = 'info'; - } - } - /* Is this part an attachment? */ - $is_atc = $this->isAttachment($mime_part); - - /* Get bytes/size information. */ - if (($mask & self::SUMMARY_BYTES) || - $download_zip || - ($mask & self::SUMMARY_SIZE)) { - $part['bytes'] = $mime_part->getBytes(); - - if ($part['bytes'] && - ($mime_part->getCurrentEncoding() == 'base64')) { - /* From RFC 2045 [6.8]: "...the encoded data are - * consistently only about 33 percent larger than the - * unencoded data." Thus, adding 33% to the byte size is - * a good estimate for our purposes. */ - $size = number_format(max((($part['bytes'] * 0.75) / 1024), 1)); - } else { - $size = $mime_part->getSize(true); - } - $part['size'] = ($size > 1024) - ? sprintf(_("%s MB"), number_format(max(($size / 1024), 1))) - : sprintf(_("%s KB"), $size); - } + $part = array( + 'bytes' => null, + 'download' => null, + 'download_zip' => null, + 'id' => $id, + 'img_save' => null, + 'size' => null, + 'strip' => null + ); - /* Get part's icon. */ - $part['icon'] = ($mask & self::SUMMARY_ICON) ? Horde::img(Horde_Mime_Viewer::getIcon($mime_type), '', array('title' => $mime_type), '') : null; + $mime_part = $this->getMIMEPart($id, array('nocontents' => true, 'nodecode' => true)); + $mime_type = $mime_part->getType(); - /* Get part's description. */ - $description = $mime_part->getDescription(true); - if (empty($description)) { - $description = _("unnamed"); + /* If this is an attachment that has no specific MIME type info, see + * if we can guess a rendering type. */ + if (in_array($mime_type, array('application/octet-stream', 'application/base64'))) { + $mime_type = Horde_Mime_Magic::filenameToMIME($mime_part->getName()); + $param_array['ctype'] = $mime_type; + } + $part['type'] = $mime_type; + + /* Is this part an attachment? */ + $is_atc = $this->isAttachment($mime_type); + + /* Get bytes/size information. */ + if (($mask & self::SUMMARY_BYTES) || + $download_zip || + ($mask & self::SUMMARY_SIZE)) { + $part['bytes'] = $mime_part->getBytes(); + + if ($part['bytes'] && + ($mime_part->getCurrentEncoding() == 'base64')) { + /* From RFC 2045 [6.8]: "...the encoded data are consistently + * only about 33 percent larger than the unencoded data." + * Thus, adding 33% to the byte size is a good estimate for + * our purposes. */ + $size = number_format(max((($part['bytes'] * 0.75) / 1024), 1)); + } else { + $size = $mime_part->getSize(true); } + $part['size'] = ($size > 1024) + ? sprintf(_("%s MB"), number_format(max(($size / 1024), 1))) + : sprintf(_("%s KB"), $size); + } - if ($mask & self::SUMMARY_DESCRIP_LINK) { - $part['description'] = (!$viewer || $viewer->canRender('full')) - ? $this->linkViewJS($mime_part, 'view_attach', htmlspecialchars($description), array('jstext' => sprintf(_("View %s [%s]"), $description, $mime_type), 'params' => $param_array)) - : htmlspecialchars($description); - } elseif ($mask & self::SUMMARY_DESCRIP_NOLINK) { - $part['description'] = htmlspecialchars($description); - } + /* Get part's icon. */ + $part['icon'] = ($mask & self::SUMMARY_ICON) ? Horde::img(Horde_Mime_Viewer::getIcon($mime_type), '', array('title' => $mime_type), '') : null; - /* Download column. */ - if ($is_atc && - ($mask & self::SUMMARY_DOWNLOAD) && - (is_null($part['bytes']) || $part['bytes'])) { - $part['download'] = $this->linkView($mime_part, 'download_attach', '', array('class' => 'downloadAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s"), $description))); - $info['has']['download'] = true; - } + /* Get part's description. */ + $description = $mime_part->getDescription(true); + if (empty($description)) { + $description = _("unnamed"); + } - /* Display the compressed download link only if size is greater - * than 200 KB. */ - if ($is_atc && - $download_zip && - ($part['bytes'] > 204800) && - !in_array($mime_type, array('application/zip', 'application/x-zip-compressed'))) { - $part['download_zip'] = $this->linkView($mime_part, 'download_attach', null, array('class' => 'downloadZipAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s in .zip Format"), $mime_part->getDescription(true)), 'params' => array('zip' => 1))); - $info['has']['download_zip'] = true; - } + if ($mask & self::SUMMARY_DESCRIP_LINK) { + $render_info = $this->getRenderInfo($id); + $part['description'] = ($render_info['mode'] & self::RENDER_FULL) + ? $this->linkViewJS($mime_part, 'view_attach', htmlspecialchars($description), array('jstext' => sprintf(_("View %s [%s]"), $description, $mime_type), 'params' => $param_array)) + : htmlspecialchars($description); + } elseif ($mask & self::SUMMARY_DESCRIP_NOLINK) { + $part['description'] = htmlspecialchars($description); + } - /* Display the image save link if the required registry calls are - * present. */ - if ($img_save && ($mime_part->getPrimaryType() == 'image')) { - if (empty($info['has']['img_save'])) { - Horde::addScriptFile('prototype.js', 'horde', true); - Horde::addScriptFile('popup.js', 'imp', true); - $info['has']['img_save'] = true; - } - $part['img_save'] = Horde::link('#', _("Save Image in Gallery"), 'saveImgAtc', null, IMP::popupIMPString('saveimage.php', array('index' => ($this->_index . IMP::IDX_SEP . $this->_mailbox), 'id' => $mime_id), 450, 200) . "return false;") . ''; - } + /* Download column. */ + if ($is_atc && + ($mask & self::SUMMARY_DOWNLOAD) && + (is_null($part['bytes']) || $part['bytes'])) { + $part['download'] = $this->linkView($mime_part, 'download_attach', '', array('class' => 'downloadAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s"), $description))); + } - /* Strip the Attachment? */ - if ($mask && self::SUMMARY_STRIP_LINK) { - if (is_null($rfc822) || (strpos($mime_id, $rfc822) !== 0)) { - $rfc822 = ($mime_type == 'message/rfc822') ? $mime_id . '.' : null; - $url = Util::removeParameter(Horde::selfUrl(true), array('actionID', 'imapid', 'index')); - $url = Util::addParameter($url, array('actionID' => 'strip_attachment', 'imapid' => $mime_id, 'index' => $this->_index, 'message_token' => $message_token)); - $part['strip'] = Horde::link($url, _("Strip Attachment"), 'stripAtc', null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete this attachment?")) . "');") . ''; - $info['has']['strip'] = true; - } - } + /* Display the compressed download link only if size is greater + * than 200 KB. */ + if ($is_atc && + $download_zip && + ($part['bytes'] > 204800) && + !in_array($mime_type, array('application/zip', 'application/x-zip-compressed'))) { + $part['download_zip'] = $this->linkView($mime_part, 'download_attach', null, array('class' => 'downloadZipAtc', 'dload' => true, 'jstext' => sprintf(_("Download %s in .zip Format"), $mime_part->getDescription(true)), 'params' => array('zip' => 1))); + } - if ($is_atc && ($mask && self::SUMMARY_DOWNLOAD_ALL)) { - $info['download_all'][] = $mime_id; - } + /* Display the image save link if the required registry calls are + * present. */ + if (($mask && self::SUMMARY_IMAGE_SAVE) && + $GLOBALS['registry']->hasMethod('images/selectGalleries') && + ($mime_part->getPrimaryType() == 'image')) { + $part['img_save'] = Horde::link('#', _("Save Image in Gallery"), 'saveImgAtc', null, IMP::popupIMPString('saveimage.php', array('index' => ($this->_index . IMP::IDX_SEP . $this->_mailbox), 'id' => $id), 450, 200) . "return false;") . ''; } - return array('info' => $info, 'parts' => $parts); + /* Strip the Attachment? */ + if ($mask && self::SUMMARY_STRIP_LINK && + !$this->isParent($id, 'message/rfc822')) { + $url = Util::removeParameter(Horde::selfUrl(true), array('actionID', 'imapid', 'index')); + $url = Util::addParameter($url, array('actionID' => 'strip_attachment', 'imapid' => $id, 'index' => $this->_index, 'message_token' => IMP::getRequestToken('imp.impcontents'))); + $part['strip'] = Horde::link($url, _("Strip Attachment"), 'stripAtc', null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete this attachment?")) . "');") . ''; + } + + return $part; } /** @@ -694,20 +643,22 @@ class IMP_Contents } /** - * Determines if a MIME part is an attachment. + * Determines if a MIME type is an attachment. * For IMP's purposes, an attachment is any MIME part that can be * downloaded by itself (i.e. all the data needed to view the part is * contained within the download data). * - * @param Horde_Mime_Part $mime_part The MIME part object. + * @param string $mime_part The MIME type. * * @return boolean True if an attachment. */ - public function isAttachment($mime_part) + public function isAttachment($mime_type) { - switch ($mime_part->getPrimaryType()) { + list($ptype,) = explode('/', $mime_type, 2); + + switch ($ptype) { case 'message': - return ($mime_part->getType() == 'message/rfc822'); + return ($mime_type == 'message/rfc822'); case 'multipart': return false; @@ -774,11 +725,68 @@ class IMP_Contents * * @return boolean True if the part can be displayed. */ - public function canDisplayInline($id, $info = false) + public function getRenderInfo($part, $mime_type = null) { - $mime_part = $this->getMIMEPart($id, array('nocontents' => true, 'nodecode' => true)); - $viewer = Horde_Mime_Viewer::factory($mime_part); - return ($viewer->canRender('inline') && $mime_part->getDisposition() == 'inline') || - ($info && $viewer->canRender('info')); + $id = is_object($part) ? $part->getMimeId() : $part; + $sig = $part . '|' . $mime_type; + + if (isset($this->_rendercache[$sig])) { + return $this->_rendercache[$sig]; + } + + if (!is_object($part)) { + $part = $this->getMIMEPart($part, array('nocontents' => true, 'nodecode' => true)); + } + $viewer = Horde_Mime_Viewer::factory($part, $mime_type); + + $mode = 0; + if ($viewer->canRender('full')) { + $mode |= self::RENDER_FULL; + } + if ($viewer->canRender('inline')) { + $mode |= self::RENDER_INLINE_DISP_NO; + if ($part->getDisposition() == 'inline') { + $mode |= self::RENDER_INLINE; + } + } + if ($viewer->canRender('info')) { + $mode |= self::RENDER_INFO; + } + + $this->_rendercache[$sig] = array( + 'driver' => $viewer->getDriver(), + 'mode' => $mode + ); + + return $this->_rendercache[$sig]; + } + + /** + * Given a MIME ID, determines if the given MIME type is a parent. + * + * @param string $id The MIME ID string. + * @param string $type The MIME type to search for. + * + * @return boolean True if the MIME type is a parent. + */ + public function isParent($id, $type) + { + $cmap = $this->_message->contentTypeMap(); + while (($id = Horde_Mime::mimeIdArithmetic($id, 'up')) !== null) { + return isset($cmap[$id]) && ($cmap[$id] == $type); + } + return false; + } + + /** + * Returns the Content-Type map for the entire message, regenerating + * embedded parts if needed. + * + * @return array See Horde_Mime_Part::contentTypeMap(). + */ + public function getContentTypeMap() + { + $this->_buildMessage(); + return $this->_message->contentTypeMap(); } } diff --git a/imp/lib/Message.php b/imp/lib/Message.php index ca6cc2280..439815d88 100644 --- a/imp/lib/Message.php +++ b/imp/lib/Message.php @@ -465,14 +465,9 @@ class IMP_Message } else { /* Sanity checking: make sure part does not live under a * message/rfc822 part. */ - $content_map = $message->contentTypeMap(); - $id = $partid; - while (($id = Horde_Mime::mimeIdArithmetic($id)) !== null) { - if ($content_map[$id] == 'message/rfc822') { - return PEAR::raiseError(_("Cannot strip a MIME part contained within a message/rfc822 part.")); - } + if ($contents->isParent($partid, 'message/rfc822')) { + return PEAR::raiseError(_("Cannot strip a MIME part contained within a message/rfc822 part.")); } - $partids = array($partid); } diff --git a/imp/message.php b/imp/message.php index 1d36eb5cf..0961e30b7 100644 --- a/imp/message.php +++ b/imp/message.php @@ -248,25 +248,6 @@ if (is_a($imp_contents, 'PEAR_Error')) { exit; } -$contents_mask = IMP_Contents::SUMMARY_RENDER | - IMP_Contents::SUMMARY_BYTES | - IMP_Contents::SUMMARY_SIZE | - IMP_Contents::SUMMARY_ICON; -if ($printer_friendly) { - $contents_mask |= IMP_Contents::SUMMARY_DESCRIP_NOLINK; -} else { - $contents_mask |= IMP_Contents::SUMMARY_DESCRIP_LINK | - IMP_Contents::SUMMARY_DOWNLOAD | - IMP_Contents::SUMMARY_DOWNLOAD_ZIP | - IMP_Contents::SUMMARY_IMAGE_SAVE | - IMP_Contents::SUMMARY_DOWNLOAD_ALL; - if (!$readonly && $prefs->getValue('strip_attachments')) { - $contents_mask |= IMP_Contents::SUMMARY_STRIP_LINK; - } -} - -$summary = $imp_contents->getSummary($contents_mask); - /* Get the title/mailbox label of the mailbox page. */ $page_label = IMP::getLabel($imp_mbox['mailbox']); @@ -648,55 +629,88 @@ foreach ($all_list_headers as $head => $val) { $hdrs[] = array('name' => $list_headers_lookup[$head], 'val' => $val, 'i' => (++$i % 2)); } -/* Determine the fields that will appear in the MIME info entries. */ -$part_info = array('icon', 'description', 'type', 'size'); -foreach (array('download', 'download_zip', 'img_save', 'strip') as $val) { - if (isset($summary['info']['has'][$val])) { - $part_info[] = $val; +$contents_mask = IMP_Contents::SUMMARY_BYTES | + IMP_Contents::SUMMARY_SIZE | + IMP_Contents::SUMMARY_ICON; +if ($printer_friendly) { + $contents_mask |= IMP_Contents::SUMMARY_DESCRIP_NOLINK; +} else { + $contents_mask |= IMP_Contents::SUMMARY_DESCRIP_LINK | + IMP_Contents::SUMMARY_DOWNLOAD | + IMP_Contents::SUMMARY_DOWNLOAD_ZIP | + IMP_Contents::SUMMARY_IMAGE_SAVE; + if (!$readonly && $prefs->getValue('strip_attachments')) { + $contents_mask |= IMP_Contents::SUMMARY_STRIP_LINK; } } -/* Build body text. This needs to be done before we build the attachment list - * that lives in the header. */ +/* Determine the fields that will appear in the MIME info entries. */ +$part_info = array('icon', 'description', 'type', 'size', 'download', 'download_zip', 'img_save', 'strip'); + $show_all_parts = Util::getFormData('show_all_parts'); -$display_ids = array(); +$parts_list = $imp_contents->getContentTypeMap(); +$atc_parts = $display_ids = array(); $msgtext = ''; -foreach ($summary['info']['render'] as $mime_id => $type) { + +if ($show_all_parts) { + $atc_parts = array_keys($parts_list); +} + +/* Build body text. This needs to be done before we build the attachment list + * that lives in the header. */ +foreach ($parts_list as $mime_id => $mime_type) { if (in_array($mime_id, $display_ids)) { continue; } + $render_info = $imp_contents->getRenderInfo($mime_id); + if ($render_info['mode'] & IMP_Contents::RENDER_INLINE) { + $type = 'inline'; + } elseif ($render_info['mode'] & IMP_Contents::RENDER_INFO) { + $type = 'info'; + } else { + if (!$show_all_parts && $imp_contents->isAttachment($mime_type)) { + $atc_parts[] = $mime_id; + } + continue; + } + $render_part = $imp_contents->renderMIMEPart($mime_id, $type); - if (($type == 'inline') && empty($render_part['ids'])) { + if (($type == 'inline') && empty($render_part)) { /* This meant that nothing was rendered - allow this part to appear * in the attachment list instead. */ + if (!$show_all_parts) { + $atc_parts[] = $mime_id; + } continue; } - $display_ids = array_merge($display_ids, $render_part['ids']); - $summary_id = isset($render_part['summary_id']) - ? $render_part['summary_id'] - : $mime_id; - $ptr = $summary['parts'][$summary_id]; - $tmp_part = $tmp_status = array(); + reset($render_part); + while (list($id, $info) = each($render_part)) { + $display_ids[] = $id; - foreach ($part_info as $val) { - $tmp_part[] = $ptr[$val]; - } + if (empty($info)) { + continue; + } - foreach ($render_part['status'] as $val) { - $tmp_status[] = $imp_ui->formatStatusMsg($val); - } + $tmp_summary = $tmp_status = array(); - $msgtext .= '' . - implode(' ', $tmp_part) . - '' . - implode("\n", $tmp_status) . - $render_part['data']; + $summary = $imp_contents->getSummary($id, $contents_mask); + foreach ($part_info as $val) { + $tmp_summary[] = $summary[$val]; + } + + foreach ($info['status'] as $val) { + $tmp_status[] = $imp_ui->formatStatusMsg($val); + } + + $msgtext .= '' . implode(' ', $tmp_summary) . '' . + implode("\n", $tmp_status) . + $info['data']; + } } /* Build the Attachments menu. */ -$atc_parts = array_diff($summary['info']['download_all'], $display_ids); if (!$printer_friendly) { $a_template->set('atc', Horde::widget('#', _("Attachments"), 'widget hasmenu', '', '', _("Attachments"), true)); if ($show_all_parts) { @@ -705,7 +719,7 @@ if (!$printer_friendly) { $a_template->set('switch_atc_view', Horde::widget(Util::addParameter($headersURL, array('show_all_parts' => 1)), _("Show All Message Parts"), 'widget', '', '', _("Show All Message Parts"), true)); } if (count($atc_parts) || (count($display_ids) > 2)) { - $a_template->set('download_all', Horde::widget($imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all', array('params' => array('download_ids' => serialize($summary['info']['download_all'])))), _("Download All Attachments (in .zip file)"), 'widget', '', '', _("Download All Attachments (in .zip file)"), true)); + $a_template->set('download_all', Horde::widget($imp_contents->urlView($imp_contents->getMIMEMessage(), 'download_all', array('params' => array('download_ids' => serialize($atc_parts)))), _("Download All Attachments (in .zip file)"), 'widget', '', '', _("Download All Attachments (in .zip file)"), true)); if ($prefs->getValue('strip_attachments')) { $a_template->set('strip_all', Horde::widget(Util::addParameter(Util::removeParameter(Horde::selfUrl(true), array('actionID')), array('actionID' => 'strip_all', 'message_token' => $message_token)), _("Strip All Attachments"), 'widget', '', "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete all attachments?")) . "');", _("Strip All Attachments"), true)); } @@ -713,11 +727,11 @@ if (!$printer_friendly) { } /* Show attachment information in headers? */ -if ($show_all_parts) { - $show_atc = true; -} else { - $show_atc = false; - if (!empty($atc_parts)) { +$show_atc = false; +if (!empty($atc_parts)) { + if ($show_all_parts) { + $show_atc = true; + } else { $atc_display = $prefs->getValue('attachment_display'); $show_atc = (($atc_display == 'list') || ($atc_display == 'both')); } @@ -727,15 +741,14 @@ if ($show_atc) { $tmp = array(); if ($show_all_parts) { - $atc_parts = array_keys($summary['parts']); array_unshift($part_info, 'id'); } foreach ($atc_parts as $id) { + $summary = $imp_contents->getSummary($id, $contents_mask); $tmp[] = ''; - $ptr = $summary['parts'][$id]; foreach ($part_info as $val) { - $tmp[] = '' . $ptr[$val] . ''; + $tmp[] = '' . $summary[$val] . ''; } $tmp[] = ''; } diff --git a/imp/view.php b/imp/view.php index 5a7e53ef0..f11856c44 100644 --- a/imp/view.php +++ b/imp/view.php @@ -113,8 +113,8 @@ case 'download_render': case 'download_render': $render = $contents->renderMIMEPart($id, Util::getFormData('mode', 'full'), array('type' => $ctype)); - $body = $render['data']; - $type = $render['type']; + $body = $render[$id]['data']; + $type = $render[$id]['type']; $name = $render['name']; break; } @@ -136,8 +136,8 @@ case 'download_render': case 'view_attach': $render = $contents->renderMIMEPart($id, Util::getFormData('mode', 'full'), array('type' => $ctype)); - $browser->downloadHeaders($render['name'], $render['type'], true, strlen($render['data'])); - echo $render['data']; + $browser->downloadHeaders($render['name'], $render[$id]['type'], true, strlen($render[$id]['data'])); + echo $render[$id]['data']; exit; case 'view_source': -- 2.11.0