public function testSplitHeaderFieldReturnsArrayWithFirstName() { $boundary = "----=_Alternative_1211565553483705f1280701.15526894A"; $header = "Content-Type: multipart/alternative; " . "boundary=\"{$boundary}\""; $split = Zend_Mime_Decode::splitHeaderField($header, null, 'content-type'); $this->assertEquals(2, count($split)); $this->assertTrue(isset($split['content-type']), "'content-type' element is set"); $this->assertEquals($boundary, $split['boundary']); }
/** * Public constructor * * @param string $rawMessage full message with or without headers * @param array $headers optional headers already seperated from body */ public function __construct($rawMessage, $headers = null) { if ($headers) { if (is_array($headers)) { $this->_headers = $headers; $this->_content = $rawMessage; } else { Zend_Mime_Decode::splitMessage($headers, $this->_headers, $null); $this->_content = $rawMessage; } } else { Zend_Mime_Decode::splitMessage($rawMessage, $this->_headers, $this->_content); } }
/** * Wait for newsletter sign out mail * * @param array $userAccount */ public function checkNewsletterSignOutMail($userAccount) { /* Check for mail */ $newsletterUnsubscribeTemplateSubject = $this->__('Newsletter unsubscription success'); // replace markers with information from $userAccount $subject = $newsletterUnsubscribeTemplateSubject; foreach ($userAccount as $key => $value) { $subject = str_replace('###' . strtoupper($key) . '###', $value, $subject); } $idx = $this->waitForMailWhoseSubjectContains($subject); $message = $this->getStorage()->getMessage($idx); $content = Zend_Mime_Decode::decodeQuotedPrintable($message->getContent()); $this->getStorage()->removeMessage($idx); $this->getTest()->assertContains('unsubscription success', $content); }
public function testSplitMessage() { $header = 'Test: test'; $body = 'body'; $newlines = array("\r\n", "\n\r", "\n", "\r"); foreach ($newlines as $contentEOL) { foreach ($newlines as $decodeEOL) { $content = $header . $contentEOL . $contentEOL . $body; $decoded = Zend_Mime_Decode::splitMessage($content, $decoded_header, $decoded_body, $decodeEOL); $this->assertEquals(array('test' => 'test'), $decoded_header); $this->assertEquals($body, $decoded_body); } } }
public function testSpaceInFieldName() { $header = 'test; foo =bar; baz =42'; $this->assertEquals(Zend_Mime_Decode::splitHeaderField($header, 'foo'), 'bar'); $this->assertEquals(Zend_Mime_Decode::splitHeaderField($header, 'baz'), 42); }
/** * get content for mail whose content contains the given string and delete the mail then * * @param string $subjectContains * @param bool $useXPath * @param int $timeout * @param int $sleep * @return mixed string|DOMXPath */ public function getMailContent($subjectContains, $useXPath = false, $timeout = 100, $sleep = 10) { $idx = $this->waitForMailWhoseSubjectContains($subjectContains, $timeout, $sleep); $message = $this->getStorage()->getMessage($idx); $content = Zend_Mime_Decode::decodeQuotedPrintable($message->getContent()); $this->getTest()->assertNotEmpty($content); $this->getStorage()->removeMessage($idx); if ($useXPath) { preg_match('/<body.*<\\/body>/misU', $content, $match); $html = str_replace(array('<', '>'), array('<', '>'), htmlentities($match[0], ENT_NOQUOTES)); return new DOMXPath(DOMDocument::loadHTML($html)); } return $content; }
/** * Decodes a MIME encoded string and returns a Zend_Mime_Message object with * all the MIME parts set according to the given string * * @param string $message * @param string $boundary * @param string $EOL EOL string; defaults to {@link Zend_Mime::LINEEND} * @return Zend_Mime_Message */ public static function createFromMessage($message, $boundary, $EOL = Zend_Mime::LINEEND) { require_once 'Zend/Mime/Decode.php'; $parts = Zend_Mime_Decode::splitMessageStruct($message, $boundary, $EOL); $res = new self(); foreach ($parts as $part) { // now we build a new MimePart for the current Message Part: $newPart = new Zend_Mime_Part($part['body']); foreach ($part['header'] as $key => $value) { /** * @todo check for characterset and filename */ switch (strtolower($key)) { case 'content-type': $newPart->type = $value; break; case 'content-transfer-encoding': $newPart->encoding = $value; break; case 'content-id': $newPart->id = trim($value, '<>'); break; case 'content-disposition': $newPart->disposition = $value; break; case 'content-description': $newPart->description = $value; break; case 'content-location': $newPart->location = $value; break; case 'content-language': $newPart->language = $value; break; default: throw new Zend_Exception('Unknown header ignored for MimePart:' . $key); } } $res->addPart($newPart); } return $res; }
/** * Get a specific field from a header like content type or all fields as array * * If the header occurs more than once, only the value from the first header * is returned. * * Throws a Zend_Mail_Exception if the requested header does not exist. If * the specific header field does not exist, returns null. * * @param string $name name of header, like in getHeader() * @param string $wantedPart the wanted part, default is first, if null an array with all parts is returned * @param string $firstName key name for the first part * @return string|array wanted part or all parts as array($firstName => firstPart, partname => value) * @throws Zend_Exception, Zend_Mail_Exception */ public function getHeaderField($name, $wantedPart = 0, $firstName = 0) { return Zend_Mime_Decode::splitHeaderField(current($this->getHeader($name, 'array')), $wantedPart, $firstName); }
public function testSplitInvalidMessage() { try { Zend_Mime_Decode::splitMessageStruct("--xxx\n", 'xxx'); } catch (Zend_Exception $e) { return; // ok } $this->fail('no exception raised while decoding invalid message'); }
public function getRawContent($id, $part = null) { if ($part !== null) { // TODO: implement /** * @see Zend_Mail_Storage_Exception */ require_once PHP_LIBRARY_PATH . 'Zend/Mail/Storage/Exception.php'; throw new Zend_Mail_Storage_Exception('not implemented'); } $content = $this->_protocol->retrieve($id); // TODO: find a way to avoid decoding the headers Zend_Mime_Decode::splitMessage($content, $null, $body); return $body; }
protected function _processDeliveryStatus($deliveryStatus, $textContent, $originalContent) { $statusContent = preg_replace('#\\r?\\n\\r?\\n#', "\n", trim($deliveryStatus)); Zend_Mime_Decode::splitMessage($statusContent, $statusFields, $null); foreach ($statusFields as &$value) { if (is_array($value)) { $value = reset($value); } } if (!empty($statusFields['action'])) { $this->_action = strtolower($statusFields['action']); if ($this->_action == 'failed') { $this->_messageType = 'bounce'; } else { if ($this->_action == 'delayed') { $this->_messageType = 'delay'; } } } if (!empty($statusFields['status']) && preg_match('/(\\d\\.\\d\\.\\d)/', $statusFields['status'], $match)) { $this->_statusCode = $match[1]; } if (!empty($statusFields['diagnostic-code'])) { $this->_diagnosticInfo = preg_replace('#^.+;\\s*#U', '', $statusFields['diagnostic-code']); if (!$this->_statusCode || $this->isStatusCodeAmbiguous($this->_statusCode)) { if (preg_match('/(\\D|^)(\\d\\.\\d\\.\\d)(\\D|$)/', $this->_diagnosticInfo, $match)) { $this->_statusCode = $match[2]; } } } if ($this->_action == 'failed' && $this->_diagnosticInfo && $this->_isMailboxInvalid($this->_diagnosticInfo)) { $this->_statusCode = '5.1.1'; } else { if ($this->isStatusCodeAmbiguous($this->_statusCode) && $this->_diagnosticInfo && $this->_isMailboxQuotaExceeded($this->_diagnosticInfo)) { $this->_statusCode = '5.2.2'; } else { if ($this->_statusCode == '4.7.0' && $this->_isChallengeResponse($textContent) || $this->isStatusCodeAmbiguous($this->_statusCode) && $this->_diagnosticInfo && $this->_isChallengeResponse($this->_diagnosticInfo)) { $this->_messageType = 'challenge'; $this->_statusCode = null; $this->_action = null; } } } }
/** * get messages summary * * @param int $from * @param int|null $to * @return array with $this->_messageClass (Felamimail_Message) */ public function getSummary($from, $to = null, $_useUid = null, $_folderId = NULL) { $useUid = $_useUid === null ? $this->_useUid : (bool) $_useUid; $summary = $this->_protocol->fetch(array('UID', 'FLAGS', 'RFC822.HEADER', 'INTERNALDATE', 'RFC822.SIZE', 'BODYSTRUCTURE'), $from, $to, $useUid); // fetch returns a different structure when fetching one or multiple messages if ($to === null && ctype_digit("{$from}")) { $summary = array($from => $summary); } $messages = array(); foreach ($summary as $id => $data) { $header = $this->_fixHeader($data['RFC822.HEADER'], $id, $spaces); Zend_Mime_Decode::splitMessage($header, $header, $null); $structure = $this->parseStructure($data['BODYSTRUCTURE']); $flags = array(); foreach ($data['FLAGS'] as $flag) { $flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag; } if ($this->_useUid === true) { $key = $data['UID']; } else { $key = $id; } $messages[$key] = array('header' => $header, 'flags' => $flags, 'received' => $data['INTERNALDATE'], 'size' => $data['RFC822.SIZE'], 'structure' => $structure, 'uid' => $data['UID']); if (!empty($_folderId)) { $messages[$key]['folder_id'] = $_folderId; } } if ($to === null && ctype_digit("{$from}")) { // only one message requested return $messages[$from]; } else { // multiple messages requested return $messages; } }
/** * Parse an RFC-822 message * * this format is quite old and not used anymore but some old * devices may still send it * * @param string $message * @return array */ public static function decodeRFC822(&$message) { try { Zend_Mime_Decode::splitMessage(ltrim($message), $headers, $content); $contentType = isset($headers['content-type']) ? $headers['content-type'] : ''; if ($contentType) { $contentType = Zend_Mime_Decode::splitContentType($contentType); } if (isset($contentType['boundary'])) { $mimeParts = self::splitMessageStruct($content, $contentType['boundary']); } else { $mimeParts = array(); } $message = array('headers' => $headers, 'content' => $content, 'mime_parts' => $mimeParts, 'content_type' => $contentType); return true; } catch (Exception $e) { return false; } }
public function parseMessage($mail, $message, $i) { $response = array('message' => array('subject' => null, 'fromEmail' => null, 'message' => null, 'receiveDate' => null), 'attachments' => array()); // Get the UTC timestamp $timezone = date_default_timezone_get(); date_default_timezone_set('UTC'); $receiveDate = strtotime($message->date); date_default_timezone_set($timezone); // Get from $from = $message->from; $from = str_replace(array('<', '>'), '', $from); $from = explode(' ', $from); $from = array_pop($from); $response['message']['fromEmail'] = $from; // Get the message $messageBody = ''; $boundary = $message->getHeaderField('content-type', 'boundary'); if (stristr($message->contentType, 'text/')) { $messageBody = $mail->getRawContent($i); } else { if (stristr($message->contentType, 'multipart/')) { $messageParts = new Zend_Mail_Part(array('handler' => &$mail, 'id' => $i, 'headers' => $message->getHeaders())); // Get the messages's contents. When fetched it removes the // message $messageParts->getContent(); foreach ($messageParts as $partIndex => $part) { $attachment = array('ticketId' => null, 'replyId' => null, 'filename' => null, 'contentType' => null, 'content' => null); if ($partIndex === 1) { // Decode attachment's data $content = (string) $part; if ($part->headerExists('content-transfer-encoding') and $part->contentTransferEncoding === 'base64') { $content = base64_decode($content); } //-- If an email is set with html + attachment + text alternative, then zend doesn't pickup the sub boundary :( $sub_boundary = preg_match('([a-zA-Z0-9]{28})', $content, $sub_boundaries); if ($sub_boundary > 0) { $subparts = explode('--' . $sub_boundaries[0], $content); foreach ($subparts as $subpart) { if (stristr($subpart, 'text/html')) { $quoted = false; if (stristr($subpart, 'quoted-printable')) { $quoted = true; } $content = explode("\n\n", $subpart); array_shift($content); $content = implode("\n\n", $content); if ($quoted) { $content = Zend_Mime_Decode::decodeQuotedPrintable($content); // Gay ass word wrapping with hmtl is bad idea. $content = str_replace(array("=\n", '=3D'), array('', '='), $content); } } } } $content = nl2br($content); $messageBody = $content; } else { $attachment['contentType'] = $part->contentType; // Grab the filename $attachment['filename'] = $part->getHeaderField('content-type', 'name'); // Decode attachment's data $content = (string) $part; // TODO: Need to part before assuming it has a transfer encoding if ($part->contentTransferEncoding === 'base64') { $content = base64_decode($content); } // TODO: other encodings? $attachment['content'] = $content; array_push($response['attachments'], $attachment); } } } } $response['message']['subject'] = (string) $message->subject; $response['message']['fromDate'] = (string) $message->from; $response['message']['message'] = $messageBody; $response['message']['receiveDate'] = $receiveDate; return $response; }
/** * create Tinebase_Mail from Zend_Mail_Message * * @param Zend_Mail_Message $_zmm * @param string $_replyBody * @return Tinebase_Mail */ public static function createFromZMM(Zend_Mail_Message $_zmm, $_replyBody = null) { $contentStream = fopen("php://temp", 'r+'); if (preg_match('/application\\/(x\\-){0,1}pkcs7-mime/i', $_zmm->getHeader('content-type')) > 0) { $mp = new Zend_Mime_Part($_zmm->getContent()); } else { fputs($contentStream, $_zmm->getContent()); rewind($contentStream); $mp = new Zend_Mime_Part($contentStream); } if ($_zmm->headerExists('content-transfer-encoding')) { $mp->encoding = $_zmm->getHeader('content-transfer-encoding'); $mp->decodeContent(); } else { $mp->encoding = Zend_Mime::ENCODING_7BIT; } // append old body when no multipart/mixed if ($_replyBody !== null && $_zmm->headerExists('content-transfer-encoding')) { $mp = self::_appendReplyBody($mp, $_replyBody); $mp->encoding = $_zmm->getHeader('content-transfer-encoding'); } if ($_zmm->headerExists('content-type')) { $contentTypeHeader = Zend_Mime_Decode::splitHeaderField($_zmm->getHeader('content-type')); if ($mp->type = strtolower($contentTypeHeader[0]) === 'application/pkcs7-mime') { $mp->type = $_zmm->getHeader('content-type'); } else { $mp->type = $contentTypeHeader[0]; } if (isset($contentTypeHeader['boundary'])) { $mp->boundary = $contentTypeHeader['boundary']; } if (isset($contentTypeHeader['charset'])) { $mp->charset = $contentTypeHeader['charset']; } } else { $mp->type = Zend_Mime::TYPE_TEXT; } $result = new Expressomail_Mail('utf-8'); $result->setBodyText($mp); foreach ($_zmm->getHeaders() as $header => $values) { foreach ((array) $values as $value) { switch ($header) { case 'content-transfer-encoding': // these are implicitly set by Zend_Mail_Transport_Abstract::_getHeaders() // these are implicitly set by Zend_Mail_Transport_Abstract::_getHeaders() case 'content-type': case 'mime-version': // do nothing break; case 'bcc': $addresses = Expressomail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->addBcc($address['address'], $address['name']); } break; case 'cc': $addresses = Expressomail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->addCc($address['address'], $address['name']); } break; case 'date': try { $result->setDate($value); } catch (Zend_Mail_Exception $zme) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Could not set date: " . $value); } if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " " . $zme); } $result->setDate(); } break; case 'from': $addresses = Expressomail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->setFrom($address['address'], $address['name']); } break; case 'message-id': $result->setMessageId($value); break; case 'return-path': $result->setReturnPath($value); break; case 'subject': $result->setSubject($value); break; case 'to': $addresses = Expressomail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->addTo($address['address'], $address['name']); } break; default: $result->addHeader($header, $value); break; } } } return $result; }
/** * get message headers * * @param string|Expressomail_Model_Message $_messageId * @param boolean $_readOnly * @return array * @throws Expressomail_Exception_IMAPMessageNotFound */ public function getMessageHeaders($_messageId, $_partId = null, $_readOnly = false) { if (!$_messageId instanceof Expressomail_Model_Message) { $message = $this->_backend->get($_messageId); } else { $message = $_messageId; } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Fetching headers for message uid ' . $message->messageuid . ' (part:' . $_partId . ')'); } try { $imapBackend = $this->_getBackendAndSelectFolder($message->folder_id); } catch (Zend_Mail_Storage_Exception $zmse) { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getMessage()); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getTraceAsString()); } throw new Expressomail_Exception_IMAPMessageNotFound('Folder not found'); } if ($imapBackend === null) { throw new Expressomail_Exception('Failed to get imap backend'); } $section = $_partId === null ? 'HEADER' : $_partId . '.HEADER'; try { $rawHeaders = $imapBackend->getRawContent($message->messageuid, $section, $_readOnly); if (strtolower(mb_detect_encoding($rawHeaders)) == 'utf-8') { $rawHeaders = utf8_decode(imap_utf8($rawHeaders)); } } catch (Expressomail_Exception_IMAPMessageNotFound $feimnf) { $this->_backend->delete($message->getId()); throw $feimnf; } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Fetched Headers: ' . $rawHeaders); } Zend_Mime_Decode::splitMessage($rawHeaders, $headers, $null); return $headers; }
/** * get meta data (like contentype, charset, ...) from zmm and set it in zmp * * @param Zend_Mail_Message $zmm * @param Zend_Mime_Part $zmp */ protected static function _getMetaDataFromZMM(Zend_Mail_Message $zmm, Zend_Mime_Part $zmp) { if ($zmm->headerExists('content-transfer-encoding')) { $zmp->encoding = $zmm->getHeader('content-transfer-encoding'); } else { $zmp->encoding = Zend_Mime::ENCODING_7BIT; } if ($zmm->headerExists('content-type')) { $contentTypeHeader = Zend_Mime_Decode::splitHeaderField($zmm->getHeader('content-type')); $zmp->type = $contentTypeHeader[0]; if (isset($contentTypeHeader['boundary'])) { $zmp->boundary = $contentTypeHeader['boundary']; } if (isset($contentTypeHeader['charset'])) { $zmp->charset = $contentTypeHeader['charset']; } } else { $zmp->type = Zend_Mime::TYPE_TEXT; } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Encoding: ' . $zmp->encoding . ' / type: ' . $zmp->type . ' / charset: ' . $zmp->charset); } }
/** * get message headers * * @param string|Felamimail_Model_Message $_messageId * @param boolean $_readOnly * @return array * @throws Felamimail_Exception_IMAPMessageNotFound */ public function getMessageHeaders($_messageId, $_partId = null, $_readOnly = false) { if (!$_messageId instanceof Felamimail_Model_Message) { $message = $this->_backend->get($_messageId); } else { $message = $_messageId; } $cache = Tinebase_Core::get('cache'); $cacheId = 'getMessageHeaders' . $message->getId() . str_replace('.', '', $_partId); if ($cache->test($cacheId)) { return $cache->load($cacheId); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Fetching headers for message uid ' . $message->messageuid . ' (part:' . $_partId . ')'); } try { $imapBackend = $this->_getBackendAndSelectFolder($message->folder_id); } catch (Zend_Mail_Storage_Exception $zmse) { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getMessage()); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getTraceAsString()); } throw new Felamimail_Exception_IMAPMessageNotFound('Folder not found'); } if ($imapBackend === null) { throw new Felamimail_Exception('Failed to get imap backend'); } $section = $_partId === null ? 'HEADER' : $_partId . '.HEADER'; try { $rawHeaders = $imapBackend->getRawContent($message->messageuid, $section, $_readOnly); } catch (Felamimail_Exception_IMAPMessageNotFound $feimnf) { $this->_backend->delete($message->getId()); throw $feimnf; } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Fetched Headers: ' . $rawHeaders); } $headers = array(); $body = null; Zend_Mime_Decode::splitMessage($rawHeaders, $headers, $body); $cache->save($headers, $cacheId, array('getMessageHeaders'), 86400); return $headers; }
/** * @magentoDataFixture Magento/Wishlist/_files/wishlist.php */ public function testSendAction() { \Magento\TestFramework\Helper\Bootstrap::getInstance()->loadArea(\Magento\Framework\App\Area::AREA_FRONTEND); $request = ['form_key' => $this->_objectManager->get('Magento\\Framework\\Data\\Form\\FormKey')->getFormKey(), 'emails' => '*****@*****.**', 'message' => 'message', 'rss_url' => null]; $this->getRequest()->setPostValue($request); $this->_objectManager->get('Magento\\Framework\\Registry')->register('wishlist', $this->_objectManager->get('Magento\\Wishlist\\Model\\Wishlist')->loadByCustomerId(1)); $this->dispatch('wishlist/index/send'); /** @var \Magento\TestFramework\Mail\Template\TransportBuilderMock $transportBuilder */ $transportBuilder = $this->_objectManager->get('Magento\\TestFramework\\Mail\\Template\\TransportBuilderMock'); $actualResult = \Zend_Mime_Decode::decodeQuotedPrintable($transportBuilder->getSentMessage()->getBodyHtml()->getContent()); $this->assertStringMatchesFormat('%A' . $this->_customerViewHelper->getCustomerName($this->_customerSession->getCustomerDataObject()) . ' wants to share this Wish List%A', $actualResult); }
/** * Get all headers * * The returned headers are as saved internally. All names are lowercased. The value is a string or an array * if a header with the same name occurs more than once. * * @return array headers as array(name => value) */ public function getHeaders() { if ($this->_headers === null) { if (!$this->_mail) { $this->_headers = array(); } else { $part = $this->_mail->getRawHeader($this->_messageNum); Zend_Mime_Decode::splitMessage($part, $this->_headers, $null); } } return $this->_headers; }
public function getRawContent($id, $part = null) { if ($part !== null) { // TODO: implement throw new Zend_Mail_Storage_Exception('not implemented'); } $content = $this->_protocol->retrieve($id); // TODO: find a way to avoid decoding the headers Zend_Mime_Decode::splitMessage($content, $null, $body); return $body; }
public function testCaseInsensitiveField() { $header = 'test; fOO="this is a test"'; $this->assertEquals(Zend_Mime_Decode::splitHeaderField($header, 'Foo'), 'this is a test'); $this->assertEquals(Zend_Mime_Decode::splitHeaderField($header, 'bar'), null); }
/** * get messages summary * * @param int $from * @param int|null $to * @return array with $this->_messageClass (Felamimail_Message) */ public function getSummary($from, $to = null, $_useUid = null) { $useUid = $_useUid === null ? $this->_useUid : (bool) $_useUid; $summary = $this->_protocol->fetch(array('UID', 'FLAGS', 'RFC822.HEADER', 'INTERNALDATE', 'RFC822.SIZE', 'BODYSTRUCTURE'), $from, $to, $useUid); // sometimes ctype_digit($from) is false even if we got a single message, maybe mailserver dependend $singleMessage = $to === null && ctype_digit($from) || isset($summary['UID']); if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' to: ' . print_r($to, true) . ' from: ' . print_r($from, true) . ' ctype_digit(from): ' . (int) ctype_digit($from)); } // fetch returns a different structure when fetching one or multiple messages if ($singleMessage) { $summary = array($from => $summary); } $messages = array(); foreach ($summary as $id => $data) { if (!isset($data['RFC822.HEADER'])) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Message data invalid: ' . print_r($data, true) . print_r($summary, true)); } continue; } $header = $this->_fixHeader($data['RFC822.HEADER'], $id, $spaces); Zend_Mime_Decode::splitMessage($header, $header, $null); $structure = $this->parseStructure($data['BODYSTRUCTURE']); $flags = array(); foreach ($data['FLAGS'] as $flag) { $flags[] = isset(self::$_knownFlags[$flag]) ? self::$_knownFlags[$flag] : $flag; } if ($this->_useUid === true) { $key = $data['UID']; } else { $key = $id; } $messages[$key] = array('header' => $header, 'flags' => $flags, 'received' => $data['INTERNALDATE'], 'size' => $data['RFC822.SIZE'], 'structure' => $structure, 'uid' => $data['UID']); } if ($singleMessage) { return $messages[$from]; } else { // multiple messages requested return $messages; } }
/** * For mailgun api several additional options for mail sending are available * * decodes the Zend Zend_Mime::encodeQuotedPrintableHeader * * @see https://framework.zend.com/apidoc/1.9/Zend_Mime/Zend_Mime.html#methodencodeQuotedPrintable * * @param $str * @param string $charset * @return string */ protected function decodeZendQuotedPrintableHeader($str, $charset = 'utf-8') { $lines = explode(\Zend_Mime::LINEEND, $str); $result = ''; foreach ($lines as $line) { // matches lines that begins with "=?utf-8?Q?" and ends with "=?" if (preg_match('/^[ ]{0,1}=\\?' . preg_quote($charset) . '\\?Q\\?(.*)\\?=/', $line, $matches)) { $result .= \Zend_Mime_Decode::decodeQuotedPrintable($matches[1]); } else { $result .= \Zend_Mime_Decode::decodeQuotedPrintable($line); } } return $result; }
/** * Public constructor * * This handler supports the following params: * - file filename or open file handler with message content (required) * - startPos start position of message or part in file (default: current position) * - endPos end position of message or part in file (default: end of file) * * @param array $params full message with or without headers * @throws Zend_Mail_Exception */ public function __construct(array $params) { if (empty($params['file'])) { /** * @see Zend_Mail_Exception */ // require_once 'Zend/Mail/Exception.php'; throw new Zend_Mail_Exception('no file given in params'); } if (!is_resource($params['file'])) { $this->_fh = fopen($params['file'], 'r'); } else { $this->_fh = $params['file']; } if (!$this->_fh) { /** * @see Zend_Mail_Exception */ // require_once 'Zend/Mail/Exception.php'; throw new Zend_Mail_Exception('could not open file'); } if (isset($params['startPos'])) { fseek($this->_fh, $params['startPos']); } $header = ''; $endPos = isset($params['endPos']) ? $params['endPos'] : null; while (($endPos === null || ftell($this->_fh) < $endPos) && trim($line = fgets($this->_fh))) { $header .= $line; } Zend_Mime_Decode::splitMessage($header, $this->_headers, $null); $this->_contentPos[0] = ftell($this->_fh); if ($endPos !== null) { $this->_contentPos[1] = $endPos; } else { fseek($this->_fh, 0, SEEK_END); $this->_contentPos[1] = ftell($this->_fh); } if (!$this->isMultipart()) { return; } $boundary = $this->getHeaderField('content-type', 'boundary'); if (!$boundary) { /** * @see Zend_Mail_Exception */ // require_once 'Zend/Mail/Exception.php'; throw new Zend_Mail_Exception('no boundary found in content type to split message'); } $part = array(); $pos = $this->_contentPos[0]; fseek($this->_fh, $pos); while (!feof($this->_fh) && ($endPos === null || $pos < $endPos)) { $line = fgets($this->_fh); if ($line === false) { if (feof($this->_fh)) { break; } /** * @see Zend_Mail_Exception */ // require_once 'Zend/Mail/Exception.php'; throw new Zend_Mail_Exception('error reading file'); } $lastPos = $pos; $pos = ftell($this->_fh); $line = trim($line); if ($line == '--' . $boundary) { if ($part) { // not first part $part[1] = $lastPos; $this->_partPos[] = $part; } $part = array($pos); } else { if ($line == '--' . $boundary . '--') { $part[1] = $lastPos; $this->_partPos[] = $part; break; } } } $this->_countParts = count($this->_partPos); }
/** * recover html body and atachment data from rfc822 mime * * @param string $mime * @return array */ public function getHtmlBodyAndAttachmentData($mime, $onlyInline = FALSE) { //$filepath = '../tests/tine20/Expressomail/Frontend/files/mime/'; //$filename = microtime(); //file_put_contents($filepath.$filename.'.eml', $mime); preg_match('/.*boundary="(.*)"/', $mime, $matches); if (count($matches) === 0) { Zend_Mime_Decode::splitMessage($mime, $headers, $body); $body = base64_decode($body); if (strpos($headers['content-type'], 'text/plain') !== FALSE) { $body = $this->convertPlainTextToHtml($body); } $result = array('body' => $body); //file_put_contents($filename.'.json', json_encode($result)); return $result; } $struct = Zend_Mime_Decode::splitMessageStruct($mime, $matches[1]); $result = array(); $result['attachmentData'] = array(); $multipartContent = $this->getMultipartPart($struct, 'multipart'); if ($multipartContent) { preg_match('/.*boundary="(.*)"/', $multipartContent['header']['content-type'], $matches); $bodyBoundary = $matches[1]; $bodyStruct = Zend_Mime_Decode::splitMessageStruct($multipartContent['body'], $bodyBoundary); $bodyContent = $this->getMultipartPart($bodyStruct, 'text/html'); if ($bodyContent) { $bodyHtml = $this->extractBodyTagContent($bodyContent['body']); if (strpos($bodyContent['header']['content-transfer-encoding'], 'base64') !== FALSE) { $bodyHtml = base64_decode($bodyHtml); } } else { $bodyHtml = ''; } $result['attachmentData'] = $this->getAttachmentParts($bodyStruct, $onlyInline); } else { $bodyContent = $this->getMultipartPart($struct, 'text/html'); if ($bodyContent) { if (strpos($bodyContent['header']['content-transfer-encoding'], 'base64') !== FALSE) { $bodyHtml = base64_decode($bodyContent['body']); } else { $bodyHtml = $this->extractBodyTagContent($bodyContent['body']); } } else { $bodyContent = $this->getMultipartPart($struct, 'text'); $bodyHtml = $bodyContent['body']; if (strpos($bodyContent['header']['content-transfer-encoding'], 'base64') !== FALSE) { $bodyHtml = base64_decode($bodyHtml); } if (strpos($bodyContent['header']['content-type'], 'text/plain') !== FALSE) { $bodyHtml = $this->convertPlainTextToHtml($bodyHtml); } } } $result['body'] = quoted_printable_decode($bodyHtml); $result['attachmentData'] = array_merge($result['attachmentData'], $this->getAttachmentParts($struct, $onlyInline)); //$filepath = '../tests/tine20/Expressomail/Frontend/files/result/'; //file_put_contents($filepath.$filename.'.json', json_encode($result)); return $result; }