/** * get decoded body content * * @param Zend_Mime_Part $_bodyPart * @param array $partStructure * @return string * * @todo reduce complexity */ protected function _getDecodedBodyContent(Zend_Mime_Part $_bodyPart, $_partStructure) { $rawBody = stream_get_contents($_bodyPart->getRawStream()); $_bodyPart->resetStream(); $charset = $this->_appendCharsetFilter($_bodyPart, $_partStructure); // need to set error handler because stream_get_contents just throws a E_WARNING set_error_handler('Expressomail_Controller_Message::decodingErrorHandler', E_WARNING); try { $body = $_bodyPart->getDecodedContent(); unset($rawBody); restore_error_handler(); } catch (Expressomail_Exception $e) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . " Decoding of " . $_bodyPart->encoding . '/' . $_partStructure['encoding'] . ' encoded message failed: ' . $e->getMessage()); // trying to fix decoding problems restore_error_handler(); $_bodyPart->resetStream(); if ($_bodyPart->encoding == Zend_Mime::ENCODING_QUOTEDPRINTABLE) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Trying workaround for http://bugs.php.net/50363.'); } // '=0A' is a invalid UTF8 character so we need to remove ir defore the quoted_printable_decode $body = str_ireplace('=0A', '', $rawBody); $body = quoted_printable_decode($body); $body = mb_convert_encoding($body, $charset, 'UTF-8'); $body = iconv($charset, 'utf-8', $body); } else { unset($rawBody); if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Try again with fallback encoding.'); } $_bodyPart->appendDecodeFilter($this->_getDecodeFilter()); set_error_handler('Expressomail_Controller_Message::decodingErrorHandler', E_WARNING); try { $body = $_bodyPart->getDecodedContent(); restore_error_handler(); } catch (Expressomail_Exception $e) { restore_error_handler(); if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Fallback encoding failed. Trying base64_decode().'); } $_bodyPart->resetStream(); $body = base64_decode(stream_get_contents($_bodyPart->getRawStream())); $body = iconv($charset, 'utf-8', $body); } } } return $body; }
/** * 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+'); 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')) { $contentStream = fopen("php://temp", 'r+'); stream_copy_to_stream($mp->getRawStream(), $contentStream); fputs($contentStream, $_replyBody); rewind($contentStream); // create decoded stream $mp = new Zend_Mime_Part($contentStream); $mp->encoding = $_zmm->getHeader('content-transfer-encoding'); } if ($_zmm->headerExists('content-type')) { $contentTypeHeader = Zend_Mime_Decode::splitHeaderField($_zmm->getHeader('content-type')); $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 Tinebase_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 = Felamimail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->addBcc($address['address'], $address['name']); } break; case 'cc': $addresses = Felamimail_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 = Felamimail_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 = Felamimail_Message::parseAdresslist($value); foreach ($addresses as $address) { $result->addTo($address['address'], $address['name']); } break; default: $result->addHeader($header, $value); break; } } } return $result; }