public function testClientSideThreadOrderedSubject() { $data = array(array('Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 1'), array('Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 2'), array('Sat, 26 Jul 2008 22:29:20 -0500 (CDT)', 'Re: Test e-mail 2'), array('Sat, 26 Jul 2008 21:10:00 -0500 (CDT)', 'Test e-mail 1')); $results = new Horde_Imap_Client_Fetch_Results(); foreach ($data as $key => $val) { $data = new Horde_Imap_Client_Data_Fetch(); $data->setEnvelope(new Horde_Imap_Client_Data_Envelope(array('date' => $val[0], 'subject' => $val[1]))); $results[++$key] = $data; } $thread = $this->sort_ob->threadOrderedSubject($results, true); foreach (array(1, 4) as $val) { $t = $thread->getThread($val); $this->assertEquals(array(1, 4), array_keys($t)); $this->assertEquals(1, $t[1]->base); $this->assertEquals(1, $t[1]->last); $this->assertEquals(0, $t[1]->level); $this->assertEquals(1, $t[4]->base); $this->assertEquals(1, $t[4]->last); $this->assertEquals(1, $t[4]->level); } foreach (array(2, 3) as $val) { $t = $thread->getThread($val); $this->assertEquals(array(2, 3), array_keys($t)); $this->assertEquals(2, $t[2]->base); $this->assertEquals(1, $t[2]->last); $this->assertEquals(0, $t[2]->level); $this->assertEquals(2, $t[3]->base); $this->assertEquals(1, $t[3]->last); $this->assertEquals(1, $t[3]->level); } }
public function testIconvHtmlMessage() { $conn = $this->getMockBuilder('Horde_Imap_Client_Socket')->disableOriginalConstructor()->setMethods(['fetch'])->getMock(); $urlGenerator = $this->getMockBuilder('\\OCP\\IURLGenerator')->disableOriginalConstructor()->getMock(); //linkToRoute 'mail.proxy.proxy' $urlGenerator->expects($this->any())->method('linkToRoute')->will($this->returnCallback(function ($url) { return "https://docs.example.com/server/go.php?to={$url}"; })); $htmlService = new \OCA\Mail\Service\Html($urlGenerator); // mock first fetch $firstFetch = new Horde_Imap_Client_Data_Fetch(); $firstPart = Horde_Mime_Part::parseMessage(file_get_contents(__DIR__ . '/data/mail-message-123.txt'), ['level' => 1]); $firstFetch->setStructure($firstPart); $firstFetch->setBodyPart(1, $firstPart->getPart(1)->getContents()); $firstFetch->setBodyPart(2, $firstPart->getPart(2)->getContents()); $firstResult = new Horde_Imap_Client_Fetch_Results(); $firstResult[123] = $firstFetch; $conn->expects($this->any())->method('fetch')->willReturn($firstResult); $message = new \OCA\Mail\Message($conn, 'INBOX', 123, null, true, $htmlService); $htmlBody = $message->getHtmlBody(0, 0, 123, function () { return null; }); $this->assertTrue(strlen($htmlBody) > 1000); $plainTextBody = $message->getPlainBody(); $this->assertTrue(strlen($plainTextBody) > 1000); }
/** * Constructor * * @param Horde_Imap_Client_Base $imap The imap client object. * @param Horde_Imap_Client_Mailbox $mbox The mailbox object. * @param Horde_Imap_Client_Data_Fetch $data The data returned from a FETCH * must contain at least uid, * structure and flags. */ public function __construct(Horde_Imap_Client_Base $imap, Horde_Imap_Client_Mailbox $mbox, Horde_Imap_Client_Data_Fetch $data) { $this->_imap = $imap; $this->_message = new Horde_ActiveSync_Mime($data->getStructure()); $this->_uid = $data->getUid(); $this->_flags = $data->getFlags(); $this->_mbox = $mbox; $this->_data = $data; $this->_envelope = $data->getEnvelope(); }
/** * Return the full message text. * * @param boolean $stream Return data as a stream? * * @return mixed A string or stream resource. * @throws Horde_ActiveSync_Exception */ public function getFullMsg($stream = false) { // First see if we already have it. if ($stream) { $full = new Horde_Stream_Existing(array('stream' => $this->_data->getFullMsg($stream))); $length = $full->length(); if (!$length) { $full->close(); } } else { $full = $this->_data->getFullMsg(false); $length = strlen($full); } if (!$length) { $query = new Horde_Imap_Client_Fetch_Query(); $query->fullText(array('peek' => true)); 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); } $data = $fetch_ret[$this->uid]; $full = $data->getFullMsg($stream); } return $full; }
/** * TODO */ public function fetchEnvelope($indices) { $result = array(); foreach ($indices as $uid) { foreach (array_keys($this->_folders['INBOX']) as $i) { if ($this->_folders['INBOX'][$i]['uid'] == $uid) { $fetch = new Horde_Imap_Client_Data_Fetch(); $fetch->setEnvelope(array('from' => $this->_fixtures[$this->_folders['INBOX'][$i]['fixture']]->getValue('from'))); $fetch->setUid = $uid; $result[$uid] = $fetch; } } } return $result; }
/** * Build the data needed for the BodyPart part. * * @param Horde_Imap_Client_Data_Fetch $data The FETCH results. * @param Horde_Mime_Part $mime The plaintext MIME part. * @param boolean $to_html If true, $id is assumed to be a text/plain * part and is converted to html. * * @return array The BodyPart data. * - charset: (string) The charset of the text. * - body: (string) The body text. * - truncated: (boolean) True if text was truncated. * - size: (integer) The original part size, in bytes. */ protected function _getBodyPart(Horde_Imap_Client_Data_Fetch $data, Horde_Mime_Part $mime, $to_html) { $id = $mime->getMimeId(); $text = $data->getBodyPart($id); if (!$data->getBodyPartDecode($id)) { $mime->setContents($text); $text = $mime->getContents(); } if ($to_html) { $text = Horde_Text_Filter::filter($text, 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO, 'charset' => $mime->getCharset())); $size = strlen($text); } else { $size = !is_null($data->getBodyPartSize($id)) ? $data->getBodyPartSize($id) : strlen($text); } if (!empty($this->_options['bodypartprefs']['truncationsize'])) { $text = Horde_String::substr($text, 0, $this->_options['bodypartprefs']['truncationsize'], $mime->getCharset()); } return array('charset' => $mime->getCharset(), 'body' => $text, 'truncated' => $size > strlen($text), 'size' => $size); }
/** * Process a message again to add body and attachment data. * * @param \Horde_Imap_Client_Data_Fetch $messagedata The structure and part of the message body * @param \Horde_Mime_Part $partdata The part data * @param string $part The part ID. * @param string $filename The filename of the attachment * @return \stdClass * @throws \core\message\inbound\processing_failed_exception If the attachment can't be saved to disk. */ private function process_message_part_attachment($messagedata, $partdata, $part, $filename) { global $CFG; // If a filename is present, assume that this part is an attachment. $attachment = new \stdClass(); $attachment->filename = $filename; $attachment->type = $partdata->getType(); $attachment->content = $partdata->getContents(); $attachment->charset = $partdata->getCharset(); $attachment->description = $partdata->getDescription(); $attachment->contentid = $partdata->getContentId(); $attachment->filesize = $messagedata->getBodyPartSize($part); if (!empty($CFG->antiviruses)) { mtrace("--> Attempting virus scan of '{$attachment->filename}'"); // Store the file on disk - it will need to be virus scanned first. $itemid = rand(1, 999999999); $directory = make_temp_directory("/messageinbound/{$itemid}", false); $filepath = $directory . "/" . $attachment->filename; if (!($fp = fopen($filepath, "w"))) { // Unable to open the temporary file to write this to disk. mtrace("--> Unable to save the file to disk for virus scanning. Check file permissions."); throw new \core\message\inbound\processing_failed_exception('attachmentfilepermissionsfailed', 'tool_messageinbound'); } fwrite($fp, $attachment->content); fclose($fp); // Perform a virus scan now. try { \core\antivirus\manager::scan_file($filepath, $attachment->filename, true); } catch (\core\antivirus\scanner_exception $e) { mtrace("--> A virus was found in the attachment '{$attachment->filename}'."); $this->inform_attachment_virus(); return; } } return $attachment; }
/** * Merge a fetch object into this one. * * @param Horde_Imap_Client_Data_Fetch $data A fetch object. */ public function merge(Horde_Imap_Client_Data_Fetch $data) { $this->_data = array_replace_recursive($this->_data, $data->getRawData()); }
/** * Process a message again to add body and attachment data. * * @param Horde_Imap_Client_Data_Envelope $envelope The Envelope of the message * @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; }
public function getSize() { return $this->fetch->getSize(); }
public function testMerge() { $this->ob->setUid(1); $this->assertEquals(1, $this->ob->getUid()); $this->assertNull($this->ob->getSeq()); $ob2 = new Horde_Imap_Client_Data_Fetch($this->ob_class); $ob2->setUid(2); $ob2->setSeq(2); $this->ob->merge($ob2); $this->assertEquals(2, $this->ob->getUid()); $this->assertEquals(2, $this->ob->getSeq()); }