Return the body part data for a MIME ID.
public bodyPart ( string $id, array $opts = [] ) | ||
$id | string | The MIME ID to obtain the body part text for. |
$opts | array | The following options are available: - decode: (boolean) Attempt to server-side decode the bodypart data if it is MIME transfer encoded. DEFAULT: false - length: (integer) The length of the substring to return. DEFAULT: The entire text is returned. - peek: (boolean) If set, does not set the '\Seen' flag on the message. DEFAULT: The seen flag is set. - start: (integer) If a portion of the full text is desired to be returned, the starting position is identified here. DEFAULT: The entire text is returned. |
/** * Given an IMAP URL, fetches the corresponding part. * * @param Horde_Imap_Client_Url_Imap $url An IMAP URL. * * @return resource The section contents in a stream. Returns null if * the part could not be found. * * @throws Horde_Imap_Client_Exception */ public function fetchFromUrl(Horde_Imap_Client_Url_Imap $url) { $ids_ob = $this->_socket->getIdsOb($url->uid); // BODY[] if (is_null($url->section)) { $query = new Horde_Imap_Client_Fetch_Query(); $query->fullText(array('peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getFullMsg(true); } $section = trim($url->section); // BODY[<#.>HEADER.FIELDS<.NOT>()] if (($pos = stripos($section, 'HEADER.FIELDS')) !== false) { $hdr_pos = strpos($section, '('); $cmd = substr($section, 0, $hdr_pos); $query = new Horde_Imap_Client_Fetch_Query(); $query->headers('section', explode(' ', substr($section, $hdr_pos + 1, strrpos($section, ')') - $hdr_pos)), array('id' => $pos ? substr($section, 0, $pos - 1) : 0, 'notsearch' => stripos($cmd, '.NOT') !== false, 'peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getHeaders('section', Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } // BODY[#] if (is_numeric(substr($section, -1))) { $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyPart($section, array('peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getBodyPart($section, true); } // BODY[<#.>HEADER] if (($pos = stripos($section, 'HEADER')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->headerText(array('id' => $id, 'peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getHeaderText($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } // BODY[<#.>TEXT] if (($pos = stripos($section, 'TEXT')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyText(array('id' => $id, 'peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getBodyText($id, true); } // BODY[<#.>MIMEHEADER] if (($pos = stripos($section, 'MIME')) !== false) { $id = $pos ? substr($section, 0, $pos - 1) : 0; $query = new Horde_Imap_Client_Fetch_Query(); $query->mimeHeader($id, array('peek' => true)); $fetch = $this->_socket->fetch($url->mailbox, $query, array('ids' => $ids_ob)); return $fetch[$url->uid]->getMimeHeader($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM); } return null; }
private function load() { $headers = []; $fetch_query = new \Horde_Imap_Client_Fetch_Query(); $fetch_query->bodyPart($this->attachmentId); $fetch_query->mimeHeader($this->attachmentId); $headers = array_merge($headers, ['importance', 'list-post', 'x-priority']); $headers[] = 'content-type'; $fetch_query->headers('imp', $headers, ['cache' => true]); // $list is an array of Horde_Imap_Client_Data_Fetch objects. $ids = new \Horde_Imap_Client_Ids($this->messageId); $headers = $this->conn->fetch($this->mailBox, $fetch_query, ['ids' => $ids]); /** @var $fetch Horde_Imap_Client_Data_Fetch */ if (!isset($headers[$this->messageId])) { throw new DoesNotExistException('Unable to load the attachment.'); } $fetch = $headers[$this->messageId]; $mimeHeaders = $fetch->getMimeHeader($this->attachmentId, Horde_Imap_Client_Data_Fetch::HEADER_PARSE); $this->mimePart = new \Horde_Mime_Part(); // To prevent potential problems with the SOP we serve all files with the // MIME type "application/octet-stream" $this->mimePart->setType('application/octet-stream'); // Serve all files with a content-disposition of "attachment" to prevent Cross-Site Scripting $this->mimePart->setDisposition('attachment'); // Extract headers from part $contentDisposition = $mimeHeaders->getValue('content-disposition', \Horde_Mime_Headers::VALUE_PARAMS); if (!is_null($contentDisposition)) { $vars = ['filename']; foreach ($contentDisposition as $key => $val) { if (in_array($key, $vars)) { $this->mimePart->setDispositionParameter($key, $val); } } } else { $contentDisposition = $mimeHeaders->getValue('content-type', \Horde_Mime_Headers::VALUE_PARAMS); $vars = ['name']; foreach ($contentDisposition as $key => $val) { if (in_array($key, $vars)) { $this->mimePart->setContentTypeParameter($key, $val); } } } /* Content transfer encoding. */ if ($tmp = $mimeHeaders->getValue('content-transfer-encoding')) { $this->mimePart->setTransferEncoding($tmp); } $body = $fetch->getBodyPart($this->attachmentId); $this->mimePart->setContents($body); }
/** * Parse a FETCH response (RFC 3501 [7.4.2]). A FETCH response may occur * due to a FETCH command, or due to a change in a message's state (i.e. * the flags change). * * @param Horde_Imap_Client_Interaction_Pipeline $pipeline Pipeline * object. * @param integer $id The message sequence number. * @param Horde_Imap_Client_Tokenize $data The server response. */ protected function _parseFetch(Horde_Imap_Client_Interaction_Pipeline $pipeline, $id, Horde_Imap_Client_Tokenize $data) { if ($data->next() !== true) { return; } $ob = $pipeline->fetch->get($id); $ob->setSeq($id); $flags = $modseq = $uid = false; while (($tag = $data->next()) !== false) { $tag = strtoupper($tag); switch ($tag) { case 'BODYSTRUCTURE': $data->next(); $structure = $this->_parseBodystructure($data); $structure->buildMimeIds(); $ob->setStructure($structure); break; case 'ENVELOPE': $data->next(); $ob->setEnvelope($this->_parseEnvelope($data)); break; case 'FLAGS': $data->next(); $ob->setFlags($data->flushIterator()); $flags = true; break; case 'INTERNALDATE': $ob->setImapDate($data->next()); break; case 'RFC822.SIZE': $ob->setSize($data->next()); break; case 'UID': $ob->setUid($data->next()); $uid = true; break; case 'MODSEQ': $data->next(); $modseq = $data->next(); $data->next(); /* MODSEQ must be greater than 0, so do sanity checking. */ if ($modseq > 0) { $ob->setModSeq($modseq); /* Store MODSEQ value. It may be used as the highestmodseq * once a tagged response is received (RFC 7162 [6]). */ $pipeline->data['modseqs'][] = $modseq; } break; default: // Catch BODY[*]<#> responses if (strpos($tag, 'BODY[') === 0) { // Remove the beginning 'BODY[' $tag = substr($tag, 5); // BODY[HEADER.FIELDS] request if (!empty($pipeline->data['fetch_lookup']) && strpos($tag, 'HEADER.FIELDS') !== false) { $data->next(); $sig = $tag . ' (' . implode(' ', array_map('strtoupper', $data->flushIterator())) . ')'; // Ignore the trailing bracket $data->next(); $ob->setHeaders($pipeline->data['fetch_lookup'][$sig], $data->next()); } else { // Remove trailing bracket and octet start info $tag = substr($tag, 0, strrpos($tag, ']')); if (!strlen($tag)) { // BODY[] request if (!is_null($tmp = $data->next())) { $ob->setFullMsg($tmp); } } elseif (is_numeric(substr($tag, -1))) { // BODY[MIMEID] request if (!is_null($tmp = $data->next())) { $ob->setBodyPart($tag, $tmp); } } else { // BODY[HEADER|TEXT|MIME] request if (($last_dot = strrpos($tag, '.')) === false) { $mime_id = 0; } else { $mime_id = substr($tag, 0, $last_dot); $tag = substr($tag, $last_dot + 1); } if (!is_null($tmp = $data->next())) { switch ($tag) { case 'HEADER': $ob->setHeaderText($mime_id, $tmp); break; case 'TEXT': $ob->setBodyText($mime_id, $tmp); break; case 'MIME': $ob->setMimeHeader($mime_id, $tmp); break; } } } } } elseif (strpos($tag, 'BINARY[') === 0) { // Catch BINARY[*]<#> responses // Remove the beginning 'BINARY[' and the trailing bracket // and octet start info $tag = substr($tag, 7, strrpos($tag, ']') - 7); $body = $data->next(); if (is_null($body)) { /* Dovecot bug (as of 2.2.12): binary fetch of body * part may fail with NIL return if decoding failed on * server. Try again with non-decoded body. */ $bq = $pipeline->data['binaryquery'][$tag]; unset($bq['decode']); $query = new Horde_Imap_Client_Fetch_Query(); $query->bodyPart($tag, $bq); $qids = ($quid = $ob->getUid()) ? new Horde_Imap_Client_Ids($quid) : new Horde_Imap_Client_Ids($id, true); $pipeline->data['fetch_followup'][] = array('_query' => $query, 'ids' => $qids); } else { $ob->setBodyPart($tag, $body, empty($this->_temp['literal8']) ? '8bit' : 'binary'); } } elseif (strpos($tag, 'BINARY.SIZE[') === 0) { // Catch BINARY.SIZE[*] responses // Remove the beginning 'BINARY.SIZE[' and the trailing // bracket and octet start info $tag = substr($tag, 12, strrpos($tag, ']') - 12); $ob->setBodyPartSize($tag, $data->next()); } break; } } /* MODSEQ issue: Oh joy. Per RFC 5162 (see Errata #1807), FETCH FLAGS * responses are NOT required to provide UID information, even if * QRESYNC is explicitly enabled. Caveat: the FLAGS information * returned during a SELECT/EXAMINE MUST contain UIDs so we are OK * there. * The good news: all decent IMAP servers (Cyrus, Dovecot) will always * provide UID information, so this is not normally an issue. * The bad news: spec-wise, this behavior cannot be 100% guaranteed. * Compromise: We will watch for a FLAGS response with a MODSEQ and * check if a UID exists also. If not, put the sequence number in a * queue - it is possible the UID information may appear later in an * untagged response. When the command is over, double check to make * sure there are none of these MODSEQ/FLAGS that are still UID-less. * In the (rare) event that there is, don't cache anything and * immediately close the mailbox: flags will be correctly sync'd next * mailbox open so we only lose a bit of caching efficiency. * Otherwise, we could end up with an inconsistent cached state. * This Errata has been fixed in 7162 [3.2.4]. */ if ($flags && $modseq && !$uid) { $pipeline->data['modseqs_nouid'][] = $id; } }
/** * Fetch data from the IMAP client. * * @param array $params Parameter array. * - html_id (string) The MIME id of the HTML part, if any. * - text_id (string) The MIME id of the plain part, if any. * * @return Horde_Imap_Client_Data_Fetch The results. */ protected function _fetchData(array $params) { $query = new Horde_Imap_Client_Fetch_Query(); $query_opts = array('decode' => true, 'peek' => true); // Get body information if ($this->_version >= Horde_ActiveSync::VERSION_TWELVE) { if (!empty($params['html_id'])) { $query->bodyPartSize($params['html_id']); $query->bodyPart($params['html_id'], $query_opts); } if (!empty($params['text_id'])) { $query->bodyPart($params['text_id'], $query_opts); $query->bodyPartSize($params['text_id']); } } else { // EAS 2.5 Plaintext body $query->bodyPart($params['text_id'], $query_opts); $query->bodyPartSize($params['text_id']); } try { $fetch_ret = $this->_imap->fetch($this->_mbox, $query, array('ids' => new Horde_Imap_Client_Ids(array($this->_uid)))); } catch (Horde_Imap_Client_Exception $e) { throw new Horde_ActiveSync_Exception($e); } if (!($data = $fetch_ret->first())) { throw new Horde_Exception_NotFound(sprintf('Could not load message %s from server.', $this->_uid)); } return $data; }
/** * Gets the raw text for one section of the message. * * @param integer $id The ID of the MIME part. * @param array $options Additional options: * - decode: (boolean) Attempt to decode the bodypart on the remote * server. * DEFAULT: No * - length: (integer) If set, only download this many bytes of the * bodypart from the server. * DEFAULT: All data is retrieved. * - mimeheaders: (boolean) Include the MIME headers also? * DEFAULT: No * - stream: (boolean) If true, return a stream. * DEFAULT: No * * @return object Object with the following properties: * - data: (mixed) The text of the part or a stream resource if 'stream' * option is true. * - decode: (string) If 'decode' option is true, and bodypart decoded * on server, the content-type of the decoded data. */ public function getBodyPart($id, $options = array()) { $ret = new stdClass(); $ret->data = ''; $ret->decode = null; if (empty($id)) { return $ret; } if (!$this->_indices || $this->isEmbedded($id)) { if (empty($options['mimeheaders']) || in_array($id, $this->_embedded)) { $ob = $this->getMimePart($id, array('nocontents' => true)); if (empty($options['stream'])) { if (!is_null($ob)) { $ret->data = $ob->getContents(); } } else { $ret->data = is_null($ob) ? fopen('php://temp', 'r+') : $ob->getContents(array('stream' => true)); } return $ret; } $base_id = new Horde_Mime_Id($id); while (!in_array($base_id->id, $this->_embedded, true)) { $base_id->id = $base_id->idArithmetic($base_id::ID_UP); if (is_null($base_id->id)) { return $ret; } } $body = ''; $part = $this->getMimePart($base_id->id, array('nocontents' => true)); if ($part) { $txt = $part->addMimeHeaders()->toString() . "\n" . $part->getContents(); try { $body = Horde_Mime_Part::getRawPartText($txt, 'header', '1') . "\n\n" . Horde_Mime_Part::getRawPartText($txt, 'body', '1'); } catch (Horde_Mime_Exception $e) { } } if (empty($options['stream'])) { $ret->data = $body; return $ret; } $ret->data = fopen('php://temp', 'r+'); if (strlen($body)) { fwrite($ret->data, $body); fseek($ret->data, 0); } return $ret; } $query = new Horde_Imap_Client_Fetch_Query(); if (substr($id, -2) === '.0') { $rfc822 = true; $id = substr($id, 0, -2); $options['mimeheaders'] = true; } else { $rfc822 = false; } if (!isset($options['length']) || !empty($options['length'])) { $bodypart_params = array('decode' => !empty($options['decode']), 'peek' => true); if (isset($options['length'])) { $bodypart_params['start'] = 0; $bodypart_params['length'] = $options['length']; } if ($rfc822) { $bodypart_params['id'] = $id; $query->bodyText($bodypart_params); } else { $query->bodyPart($id, $bodypart_params); } } if (!empty($options['mimeheaders'])) { if ($rfc822) { $query->headerText(array('id' => $id, 'peek' => true)); } else { $query->mimeHeader($id, array('peek' => true)); } } if ($res = $this->_fetchData($query)) { try { if (empty($options['mimeheaders'])) { $ret->decode = $res->getBodyPartDecode($id); $ret->data = $rfc822 ? $res->getBodyText($id, !empty($options['stream'])) : $res->getBodyPart($id, !empty($options['stream'])); return $ret; } elseif (empty($options['stream'])) { $ret->data = $rfc822 ? $res->getHeaderText($id) . $res->getBodyText($id) : $res->getMimeHeader($id) . $res->getBodyPart($id); return $ret; } if ($rfc822) { $data = array($res->getHeaderText($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM), $res->getBodyText($id, true)); } else { $data = array($res->getMimeHeader($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM), $res->getBodyPart($id, true)); } $ret->data = Horde_Stream_Wrapper_Combine::getStream($data); return $ret; } catch (Horde_Exception $e) { } } if (!empty($options['stream'])) { $ret->data = fopen('php://temp', 'r+'); } return $ret; }
/** * Retrieves a bodypart for the given message ID and mime part ID. * * @param string $folder The folder to fetch the messages from. * @param array $uid The message UID. * @param array $id The mime part ID. * * @return resource The body part, as a stream resource. */ public function fetchBodypart($folder, $uid, $id) { $query = new Horde_Imap_Client_Fetch_Query(); $query->structure(); $query->bodyPart($id, array('decode' => true)); try { $ret = $this->getBackend()->fetch($folder, $query, array('ids' => new Horde_Imap_Client_Ids($uid))); $part = $ret[$uid]->getStructure()->getPart($id); $part->setContents($ret[$uid]->getBodyPart($id, true), array('encoding' => $ret[$uid]->getBodyPartDecode($id), 'usestream' => true)); return $part->getContents(array('stream' => true)); } catch (Horde_Imap_Client_Exception_ServerResponse $e) { throw new Horde_Kolab_Storage_Exception($e->details); } catch (Horde_Imap_Client_Exception $e) { throw new Horde_Kolab_Storage_Exception($e); } }
/** * Process a message again to add body and attachment data. * * @param \Horde_Imap_Client_Data_Fetch $basemessagedata The structure and part of the message body * @param string|\Horde_Imap_Client_Ids $messageid The Hore message Uid * @return \stdClass The current value of the messagedata */ private function process_message_data_body(\Horde_Imap_Client_Data_Fetch $basemessagedata, $messageid) { global $CFG; // Get the current mailbox. $mailbox = $this->get_mailbox(); // We need the structure at various points below. $structure = $basemessagedata->getStructure(); // Now fetch the rest of the message content. $query = new \Horde_Imap_Client_Fetch_Query(); $query->fullText(); // Fetch all of the message parts too. $typemap = $structure->contentTypeMap(); foreach ($typemap as $part => $type) { // The body of the part - attempt to decode it on the server. $query->bodyPart($part, array('decode' => true, 'peek' => true)); $query->bodyPartSize($part); } $messagedata = $this->client->fetch($mailbox, $query, array('ids' => $messageid))->first(); // Store the data for this message. $contentplain = ''; $contenthtml = ''; $attachments = array('inline' => array(), 'attachment' => array()); $plainpartid = $structure->findBody('plain'); $htmlpartid = $structure->findBody('html'); foreach ($typemap as $part => $type) { // Get the message data from the body part, and combine it with the structure to give a fully-formed output. $stream = $messagedata->getBodyPart($part, true); $partdata = $structure->getPart($part); $partdata->setContents($stream, array('usestream' => true)); if ($part === $plainpartid) { $contentplain = $this->process_message_part_body($messagedata, $partdata, $part); } else { if ($part === $htmlpartid) { $contenthtml = $this->process_message_part_body($messagedata, $partdata, $part); } else { if ($filename = $partdata->getName($part)) { if ($attachment = $this->process_message_part_attachment($messagedata, $partdata, $part, $filename)) { // The disposition should be one of 'attachment', 'inline'. // If an empty string is provided, default to 'attachment'. $disposition = $partdata->getDisposition(); $disposition = $disposition == 'inline' ? 'inline' : 'attachment'; $attachments[$disposition][] = $attachment; } } } } // We don't handle any of the other MIME content at this stage. } // The message ID should always be in the first part. $this->currentmessagedata->plain = $contentplain; $this->currentmessagedata->html = $contenthtml; $this->currentmessagedata->attachments = $attachments; return $this->currentmessagedata; }
/** * Gets the raw text for one section of the message. * * @param integer $id The ID of the MIME part. * @param array $options Additional options: * - decode: (boolean) Attempt to decode the bodypart on the remote * server. If successful, sets self::$_lastBodyPartDecode to * the content-type of the decoded data. * DEFAULT: No * - length: (integer) If set, only download this many bytes of the * bodypart from the server. * DEFAULT: All data is retrieved. * - mimeheaders: (boolean) Include the MIME headers also? * DEFAULT: No * - stream: (boolean) If true, return a stream. * DEFAULT: No * * @return mixed The text of the part or a stream resource if 'stream' * is true. * @todo Simplify by removing 'mimeheaders' parameter (not used). */ public function getBodyPart($id, $options) { $options = array_merge(array('decode' => false, 'mimeheaders' => false, 'stream' => false), $options); $this->_lastBodyPartDecode = null; $query = new Horde_Imap_Client_Fetch_Query(); if (!isset($options['length']) || !empty($options['length'])) { $bodypart_params = array('decode' => true, 'peek' => true); if (isset($options['length'])) { $bodypart_params['start'] = 0; $bodypart_params['length'] = $options['length']; } $query->bodyPart($id, $bodypart_params); } if (!empty($options['mimeheaders'])) { $query->mimeHeader($id, array('peek' => true)); } $fetch_res = $this->_imap->fetch($this->_mbox, $query, array('ids' => new Horde_Imap_Client_Ids(array($this->uid)))); if (empty($options['mimeheaders'])) { $this->_lastBodyPartDecode = $fetch_res[$this->uid]->getBodyPartDecode($id); return $fetch_res[$this->uid]->getBodyPart($id, $options['stream']); } elseif (empty($options['stream'])) { return $fetch_res[$this->uid]->getMimeHeader($id) . $fetch_res[$this->uid]->getBodyPart($id); } else { $swrapper = new Horde_Support_CombineStream(array($fetch_res[$this->uid]->getMimeHeader($id, Horde_Imap_Client_Data_Fetch::HEADER_STREAM), $fetch_res[$this->uid]->getBodyPart($id, true))); return $swrapper->fopen(); } }
public function fetchbody($message_no, $partno) { $file = $this->getCacheFileName(__FUNCTION__, $message_no, $partno); if ($this->cacheEnabled && file_exists($file)) { return json_decode(file_get_contents($file)); } else { $oQuery = new Horde_Imap_Client_Fetch_Query(); $oQuery->structure(); $oQuery->bodyPart($partno, array('decode' => true, 'peek' => true)); $oQuery->fullText(array('peek' => true)); $message = $this->imap_imp->fetch($this->currentFolder, $oQuery, array('ids' => new Horde_Imap_Client_Ids($message_no))); $message = $message[$message_no]; $part = $message->getStructure(); $body = $part->getPart($partno); $tmp = $message->getBodyPart($partno); if (!$message->getBodyPartDecode($partno)) { $body->setContents($tmp); $tmp = $body->getContents(); } if ($tmp) { file_put_contents($file, json_encode($tmp)); } return $tmp; } }
private function queryBodyPart($partId) { $fetch_query = new \Horde_Imap_Client_Fetch_Query(); $ids = new \Horde_Imap_Client_Ids($this->message_id); $bodypart_params = array('decode' => true); $fetch_query->bodyPart($partId, $bodypart_params); $headers = $this->conn->fetch($this->folder_id, $fetch_query, array('ids' => $ids)); $fetch = $headers[$this->message_id]; return $fetch->getBodyPart($partId); }
/** * @depends testOptimizedSearches */ public function testComplexFetch() { // Fetching message information from complex MIME message. $complex_fetch = new Horde_Imap_Client_Fetch_Query(); $complex_fetch->fullText(array('length' => 100, 'peek' => true)); // Header of entire message $complex_fetch->headerText(array('length' => 100, 'peek' => true)); // Header of message/rfc822 part $complex_fetch->headerText(array('id' => 2, 'length' => 100, 'peek' => true)); // Body text of entire message $complex_fetch->bodyText(array('length' => 100, 'peek' => true)); // Body text of message/rfc822 part $complex_fetch->bodyText(array('id' => 2, 'length' => 100, 'peek' => true)); // MIME Header of multipart/alternative part $complex_fetch->mimeHeader('1', array('length' => 100, 'peek' => true)); // MIME Header of text/plain part embedded in message/rfc822 part $complex_fetch->mimeHeader('2.1', array('length' => 100, 'peek' => true)); // Body text of multipart/alternative part $complex_fetch->bodyPart('1', array('length' => 100, 'peek' => true)); // Body text of image/png part embedded in message/rfc822 part // Try to do server-side decoding, if available $complex_fetch->mimeHeader('2.2', array('decode' => true, 'length' => 100, 'peek' => true)); // If supported, return decoded body part size $complex_fetch->bodyPartSize('2.2'); // Select message-id header from base message header $complex_fetch->headers('headersearch1', array('message-id'), array('length' => 100, 'peek' => true)); // Select everything but message-id header from message/rfc822 header $complex_fetch->headers('headersearch2', array('message-id'), array('id' => '2', 'length' => 100, 'notsearch' => true, 'peek' => true)); $complex_fetch->structure(); $complex_fetch->flags(); $complex_fetch->imapDate(); $complex_fetch->size(); $complex_fetch->uid(); if (self::$live->capability->query('CONDSTORE')) { $complex_fetch->modseq(); } try { $res = self::$live->fetch(self::$test_mbox, $complex_fetch, array('ids' => new Horde_Imap_Client_Ids(3, true))); } catch (Horde_Imap_Client_Exception $e) { if ($e->getCode() === $e::MBOXNOMODSEQ) { $this->markTestSkipped('Mailbox does not support MODSEQ.'); } throw $e; } $this->assertInstanceOf('Horde_Imap_Client_Fetch_Results', $res); $this->assertEquals(1, count($res)); $this->assertEquals('Message-ID: <*****@*****.**>', trim($res[3]->getHeaders('headersearch1'))); /* Return stream instead. */ $this->assertInternalType('resource', $res[3]->getHeaders('headersearch1', Horde_Imap_Client_Data_Fetch::HEADER_STREAM)); /* Parse headers instead. */ $this->assertInstanceOf('Horde_Mime_Headers', $res[3]->getHeaders('headersearch1', Horde_Imap_Client_Data_Fetch::HEADER_PARSE)); }
/** * @param \Horde_Mime_Part $p * @param int $partNo * @return string * @throws DoesNotExistException * @throws \Exception */ private function loadBodyData($p, $partNo) { // DECODE DATA $fetch_query = new \Horde_Imap_Client_Fetch_Query(); $ids = new \Horde_Imap_Client_Ids($this->messageId); $fetch_query->bodyPart($partNo, ['peek' => true]); $fetch_query->bodyPartSize($partNo); $fetch_query->mimeHeader($partNo, ['peek' => true]); $headers = $this->conn->fetch($this->mailBox, $fetch_query, ['ids' => $ids]); /** @var $fetch \Horde_Imap_Client_Data_Fetch */ $fetch = $headers[$this->messageId]; if (is_null($fetch)) { throw new DoesNotExistException("Mail body for this mail({$this->messageId}) could not be loaded"); } $mimeHeaders = $fetch->getMimeHeader($partNo, Horde_Imap_Client_Data_Fetch::HEADER_PARSE); if ($enc = $mimeHeaders->getValue('content-transfer-encoding')) { $p->setTransferEncoding($enc); } $data = $fetch->getBodyPart($partNo); $p->setContents($data); $data = $p->getContents(); $data = iconv($p->getCharset(), 'utf-8//IGNORE', $data); return $data; }
function GetMessage($message) { $uid = new Horde_Imap_Client_Ids($message->getUid()); $this->plainmsg = ""; $this->htmlmsg = ""; $part = $message->getStructure(); $plain_id = $part->findBody("plain"); $plain_body = $part->getPart($plain_id); $html_id = $part->findBody("html"); $html_body = $part->getPart($html_id); $query2 = new Horde_Imap_Client_Fetch_Query(); $query2->bodyPart($plain_id, array('decode' => true)); $list2 = $this->conn->fetch('INBOX', $query2, array('ids' => $uid)); $message2 = $list2->first(); $this->plainmsg = $message2->getBodyPart($plain_id); if (!$message2->getBodyPartDecode($plain_id) && $plain_body) { // Quick way to transfer decode contents $plain_body->setContents($this->plainmsg); $this->plainmsg = $plain_body->getContents(); } if ($html_id != "") { $query2 = new Horde_Imap_Client_Fetch_Query(); $query2->bodyPart($html_id, array('decode' => true)); $list2 = $this->conn->fetch('INBOX', $query2, array('ids' => $uid)); $message2 = $list2->first(); $this->htmlmsg = $message2->getBodyPart($html_id); if (!$message2->getBodyPartDecode($html_id) && $html_body) { // Quick way to transfer decode contents $html_body->setContents($this->htmlmsg); $this->htmlmsg = $html_body->getContents(); } } if (empty($this->plainmsg)) { $this->plainmsg = "EMPTY"; } if (empty($this->htmlmsg)) { $this->htmlmsg = "EMPTY"; } if (strlen($this->plainmsg) < 10 && strlen($this->htmlmsg) > 20) { require_once JPATH_SITE . DS . 'components' . DS . 'com_fss' . DS . 'helper' . DS . 'third' . DS . 'html2text.php'; $h2t = new html2text($this->htmlmsg); $this->plainmsg = $h2t->get_text(); } }