From: Michael M Slusarz Date: Tue, 30 Jun 2009 02:51:38 +0000 (-0600) Subject: Request #3359: Horde_Mime_Part & streams X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=8a436842e46e1ad943914031e0b54acadaac26b9;p=horde.git Request #3359: Horde_Mime_Part & streams Use PHP temporary streams when working with message body data to reduce memory usage. --- diff --git a/imp/docs/CHANGES b/imp/docs/CHANGES index e8348b66a..33442076b 100644 --- a/imp/docs/CHANGES +++ b/imp/docs/CHANGES @@ -2,6 +2,8 @@ v5.0-git -------- +[mms] Use PHP temporary streams when working with message body data to reduce + memory usage (Request #3359). [mms] Add ability to expand/collapse all folders in DIMP. [mms] Add Folder Options menu to DIMP. [mms] Add save link to full message display in DIMP. diff --git a/imp/lib/Contents.php b/imp/lib/Contents.php index 3fa4dc30c..36aac8f3c 100644 --- a/imp/lib/Contents.php +++ b/imp/lib/Contents.php @@ -151,17 +151,24 @@ class IMP_Contents /** * Returns the entire body of the message. * - * @return string The text of the body of the message. + * @param array $options Additional options: + *
+     * 'stream' - (boolean) If true, return a stream.
+     *            DEFAULT: No
+     * 
+ * + * @return mixed The text of the part, or a stream resource if 'stream' + * is true. */ - public function getBody() + public function getBody($options = array()) { if (is_null($this->_mailbox)) { - return $this->_message->toString(); + return $this->_message->toString(true, !empty($options['stream'])); } try { $res = $GLOBALS['imp_imap']->ob->fetch($this->_mailbox, array( - Horde_Imap_Client::FETCH_BODYTEXT => array(array('peek' => true)) + Horde_Imap_Client::FETCH_BODYTEXT => array(array('peek' => true, 'stream' => !empty($options['stream']))) ), array('ids' => array($this->_index))); return $res[$this->_index]['bodytext'][0]; } catch (Horde_Imap_Client_Exception $e) { @@ -180,9 +187,12 @@ class IMP_Contents * DEFAULT: All data is retrieved. * 'mimeheaders' - (boolean) Include the MIME headers also? * DEFAULT: No + * 'stream' - (boolean) If true, return a stream. + * DEFAULT: No * * - * @return string The text of the part. + * @return mixed The text of the part, or a stream resource if 'stream' + * is true. */ public function getBodyPart($id, $options = array()) { @@ -199,7 +209,7 @@ class IMP_Contents } $query = array( - Horde_Imap_Client::FETCH_BODYPART => array(array('id' => $id, 'peek' => true)) + Horde_Imap_Client::FETCH_BODYPART => array(array('id' => $id, 'peek' => true, 'stream' => !empty($options['stream']))) ); if (!empty($options['length'])) { $query[Horde_Imap_Client::FETCH_BODYPART][0]['start'] = 0; @@ -227,10 +237,11 @@ class IMP_Contents public function fullMessageText() { if (is_null($this->_mailbox)) { - return $this->_message->toString(true); + return $this->_message->toString(); } try { + // TODO - use streams $res = $GLOBALS['imp_imap']->ob->fetch($this->_mailbox, array( Horde_Imap_Client::FETCH_HEADERTEXT => array(array('peek' => true)), Horde_Imap_Client::FETCH_BODYTEXT => array(array('peek' => true)) @@ -304,7 +315,7 @@ class IMP_Contents empty($options['nocontents']) && !is_null($this->_mailbox) && !$part->getContents()) { - $contents = $this->getBodyPart($id, array('length' => empty($options['length']) ? null : $options['length'])); + $contents = $this->getBodyPart($id, array('length' => empty($options['length']) ? null : $options['length'], 'stream' => true)); if (($part->getPrimaryType() == 'text') && (Horde_String::upper($part->getCharset()) == 'US-ASCII') && Horde_Mime::is8bit($contents)) { diff --git a/imp/lib/Mime/Viewer/Partial.php b/imp/lib/Mime/Viewer/Partial.php index 4572198f1..3a7b236d4 100644 --- a/imp/lib/Mime/Viewer/Partial.php +++ b/imp/lib/Mime/Viewer/Partial.php @@ -67,7 +67,7 @@ class IMP_Horde_Mime_Viewer_Partial extends Horde_Mime_Viewer_Driver if ($val == $number) { $parts[$number] = $this->_mimepart->getContents(); } else { - $ic = &IMP_Contents::singleton($val . IMP::IDX_SEP . $mbox); + $ic = IMP_Contents::singleton($val . IMP::IDX_SEP . $mbox); $parts[$ic->getMIMEMessage()->getContentTypeParameter('number')] = $ic->getBody(); } } diff --git a/imp/view.php b/imp/view.php index 06505bc33..05c034e7e 100644 --- a/imp/view.php +++ b/imp/view.php @@ -55,12 +55,12 @@ $id = Horde_Util::getFormData('id'); * get the necessary Horde_Mime_Part. */ if ($actionID == 'compose_attach_preview') { /* Initialize the IMP_Compose:: object. */ - $imp_compose = &IMP_Compose::singleton(Horde_Util::getFormData('composeCache')); + $imp_compose = IMP_Compose::singleton(Horde_Util::getFormData('composeCache')); $mime = $imp_compose->buildAttachment($id); /* Create a dummy IMP_Contents() object so we can use the view code below. * Then use the 'view_attach' handler to output. */ - $contents = &IMP_Contents::singleton($mime); + $contents = IMP_Contents::singleton($mime); $actionID = 'view_attach'; $id = $mime->getMimeId(); } else { @@ -75,7 +75,7 @@ if ($actionID == 'compose_attach_preview') { } try { - $contents = &IMP_Contents::singleton($uid . IMP::IDX_SEP . $mailbox); + $contents = IMP_Contents::singleton($uid . IMP::IDX_SEP . $mailbox); } catch (Horde_Exception $e) { Horde::fatal($e, __FILE__, __LINE__); } @@ -103,7 +103,7 @@ case 'download_all': } if (!empty($tosave)) { - $horde_compress = &Horde_Compress::singleton('zip'); + $horde_compress = Horde_Compress::singleton('zip'); $body = $horde_compress->compress($tosave); $browser->downloadHeaders($zipfile, 'application/zip', false, strlen($body)); echo $body; @@ -115,9 +115,20 @@ case 'download_render': switch ($actionID) { case 'download_attach': $mime = $contents->getMIMEPart($id); - $body = $mime->getContents(); - $type = $mime->getType(true); - $name = $mime->getName(true); + if (!$name = $mime->getName(true)) { + $name = _("unnamed"); + } + + /* Compress output? */ + if (Horde_Util::getFormData('zip')) { + $horde_compress = Horde_Compress::singleton('zip'); + $body = $horde_compress->compress(array(array('data' => $mime->getContents(), 'name' => $name))); + $name .= '.zip'; + $type = 'application/zip'; + } else { + $body = $mime->getContentsAsStream(); + $type = $mime->getType(true); + } break; case 'download_render': @@ -126,23 +137,18 @@ case 'download_render': $key = key($render); $body = $render[$key]['data']; $type = $render[$key]['type']; - $name = $render[$key]['name']; + if (!$name = $render[$key]['name']) { + $name = _("unnamed"); + } break; } - if (empty($name)) { - $name = _("unnamed"); - } - - /* Compress output? */ - if (($actionID == 'download_attach') && Horde_Util::getFormData('zip')) { - $horde_compress = &Horde_Compress::singleton('zip'); - $body = $horde_compress->compress(array(array('data' => $body, 'name' => $name))); - $name .= '.zip'; - $type = 'application/zip'; - } $browser->downloadHeaders($name, $type, false, strlen($body)); - echo $body; + if (is_resource($body)) { + fpassthru($body); + } else { + echo $body; + } exit; case 'view_attach':