/**
  *
  * @param array $source
  * @param resource | string $inputStream
  * @param string $flag
  * @throws Zend_Mail_Protocol_Exception
  */
 public function parseAndSendMessage($source, $inputStream, $flag = NULL)
 {
     $originalMessage = $this->getCompleteMessage($source['itemId'], null, false);
     $user = Tinebase_Core::getUser();
     if (!is_resource($inputStream)) {
         $stream = fopen("php://temp", 'r+');
         fwrite($stream, $inputStream);
         $inputStream = $stream;
         rewind($inputStream);
     }
     $incomingMessage = new Zend_Mail_Message(array('file' => $inputStream));
     $headers = $incomingMessage->getHeaders();
     $body = $headers['content-transfer-encoding'] == 'base64' ? base64_decode($incomingMessage->getContent()) : $incomingMessage->getContent();
     $isTextPlain = strpos($headers['content-type'], 'text/plain');
     $bodyLines = preg_split('/\\r\\n|\\r|\\n/', $body);
     $body = '';
     if ($isTextPlain !== false) {
         foreach ($bodyLines as &$line) {
             $body .= htmlentities($line) . '<br>';
         }
     } else {
         foreach ($bodyLines as &$line) {
             $body .= $line . '<br>';
         }
     }
     $body = '<div>' . $body . '</div>';
     $bodyOrigin = $originalMessage['body'];
     preg_match("/<body[^>]*>(.*?)<\\/body>/is", $bodyOrigin, $matches);
     $bodyOrigin = count($matches) > 1 ? $matches[1] : $bodyOrigin;
     $body .= '<div>' . $bodyOrigin . '</div>';
     $attachments = array();
     foreach ($originalMessage['attachments'] as &$att) {
         try {
             $att['name'] = $att['filename'];
             $att['type'] = $att['content-type'];
         } catch (Exception $e) {
         }
         array_push($attachments, $att);
     }
     $recordData = array();
     $recordData['note'] = '';
     $recordData['content_type'] = 'text/html';
     $recordData['account_id'] = $originalMessage->account_id;
     $recordData['to'] = is_array($headers['to']) ? $headers['to'] : array($headers['to']);
     $recordData['cc'] = array();
     $recordData['bcc'] = array();
     $recordData['subject'] = $headers['subject'];
     $recordData['body'] = $body;
     //$recordData['flags'] = array_merge($incomingMessage->getFlags(), $originalMessage['flags']);
     $recordData['flags'] = $flag != NULL ? $flag : '';
     $recordData['original_id'] = $source['itemId'];
     $recordData['embedded_images'] = array();
     $recordData['attachments'] = $attachments;
     $recordData['from_email'] = $user->accountEmailAddress;
     $recordData['from_name'] = $user->accountFullName;
     $recordData['customfields'] = array();
     $message = new Expressomail_Model_Message();
     $message->setFromJsonInUsersTimezone($recordData);
     try {
         Expressomail_Controller_Message_Send::getInstance()->sendMessage($message);
     } catch (Zend_Mail_Protocol_Exception $zmpe) {
         Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not send message: ' . $zmpe->getMessage());
         throw $zmpe;
     }
 }
 /**
  * set headers
  * 
  * @param Zend_Mail_Message $_zmm
  * @return Zend_Mail Provides fluent interface
  */
 public function setHeadersFromZMM(Zend_Mail_Message $_zmm)
 {
     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 = self::parseAdresslist($value);
                     foreach ($addresses as $address) {
                         $this->addBcc($address['address'], $address['name']);
                     }
                     break;
                 case 'cc':
                     $addresses = self::parseAdresslist($value);
                     foreach ($addresses as $address) {
                         $this->addCc($address['address'], $address['name']);
                     }
                     break;
                 case 'date':
                     try {
                         $this->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);
                         }
                         $this->setDate();
                     }
                     break;
                 case 'from':
                     $addresses = self::parseAdresslist($value);
                     foreach ($addresses as $address) {
                         $this->setFrom($address['address'], $address['name']);
                     }
                     break;
                 case 'message-id':
                     $this->setMessageId($value);
                     break;
                 case 'return-path':
                     $this->setReturnPath($value);
                     break;
                 case 'subject':
                     $this->setSubject($value);
                     break;
                 case 'to':
                     $addresses = self::parseAdresslist($value);
                     foreach ($addresses as $address) {
                         $this->addTo($address['address'], $address['name']);
                     }
                     break;
                 default:
                     $this->addHeader($header, $value);
                     break;
             }
         }
     }
     return $this;
 }
예제 #3
0
 public function testEmptyMessage()
 {
     $message = new Zend_Mail_Message(array());
     $this->assertEquals(array(), $message->getHeaders());
     $message = new Zend_Mail_Message(array());
     $subject = null;
     try {
         $subject = $message->subject;
     } catch (Zend_Exception $e) {
         // ok
     }
     if ($subject) {
         $this->fail('no exception raised while getting header from empty message');
     }
     $message = new Zend_Mail_Message(array());
     $part = null;
     try {
         $part = $message->getPart(1);
     } catch (Zend_Exception $e) {
         // ok
     }
     if ($part) {
         $this->fail('no exception raised while getting part from empty message');
     }
     $message = new Zend_Mail_Message(array());
     $this->assertTrue($message->countParts() == 0);
 }
 /**
  * create Felamimail message from Zend_Mail_Message
  * 
  * @param Zend_Mail_Message $_zendMailMessage
  * @return Felamimail_Model_Message
  */
 public static function createMessageFromZendMailMessage(Zend_Mail_Message $_zendMailMessage)
 {
     $message = new Felamimail_Model_Message();
     foreach ($_zendMailMessage->getHeaders() as $headerName => $headerValue) {
         switch ($headerName) {
             case 'subject':
                 $message->{$headerName} = $headerValue;
                 break;
             case 'from':
                 // do nothing
                 break;
             case 'to':
             case 'bcc':
             case 'cc':
                 $receipients = array();
                 $addresses = Tinebase_Mail::parseAdresslist($headerValue);
                 foreach ($addresses as $address) {
                     $receipients[] = $address['address'];
                 }
                 $message->{$headerName} = $receipients;
                 break;
         }
     }
     $contentType = $_zendMailMessage->getHeaderField('content-type', 0);
     $message->content_type = $contentType;
     // @todo convert to utf-8 if needed
     $charset = $_zendMailMessage->getHeaderField('content-type', 'charset');
     $encoding = $_zendMailMessage->getHeaderField('content-transfer-encoding');
     switch ($encoding) {
         case Zend_Mime::ENCODING_QUOTEDPRINTABLE:
             $message->body = quoted_printable_decode($_zendMailMessage->getContent());
             break;
         case Zend_Mime::ENCODING_BASE64:
             $message->body = base64_decode($_zendMailMessage->getContent());
             break;
         default:
             $message->body = $_zendMailMessage->getContent();
             break;
     }
     return $message;
 }
 /**
  * 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;
 }
 /**
  * Статический метод производящий декодировку письма
  *
  * @param  string $input полный оригинальный текст email с заголовками
  * @return array|false, в случае неверного формата входящих данных (отсутствует заголовок или часть заголовка)
  */
 public static function getEmailData($input)
 {
     // подключить ZF autoloader
     ProjectConfiguration::registerZend();
     $message = new Zend_Mail_Message(array('raw' => $input));
     $headers = $message->getHeaders();
     if (!count($headers)) {
         return false;
     }
     if (!isset($headers['subject']) || !isset($headers['from']) || !isset($headers['to'])) {
         return false;
     }
     // выдергиваем текстовое тело письма, если можем
     $body = null;
     if ($message->isMultipart()) {
         foreach (new RecursiveIteratorIterator($message) as $part) {
             try {
                 if (strtok($part->contentType, ';') == 'text/plain') {
                     $body = trim($part);
                     $partHeaders = $part->getHeaders();
                     break;
                 }
             } catch (Zend_Mail_Exception $e) {
             }
         }
         // в письме нет текстового варианта
         // FIXME как-то по человечески обрабатывать
         if (!$body) {
             throw new Exception();
         }
     } else {
         $body = trim($message->getContent());
         $partHeaders = $message->getHeaders();
     }
     if (isset($partHeaders['content-transfer-encoding'])) {
         switch ($partHeaders['content-transfer-encoding']) {
             // FIXME хз нужно ли нам оно, на локалке не стоит imap_*
             //       м.б. есть альтернативные варианты
             /*
             case '7bit':
                 break;
             case '8bit':
                 $body = quoted_printable_decode(imap_8bit($body));
                 break;
             case 'binary':
                 $body = imap_base64(imap_binary($body));
                 break;
             case 'base64':
                 $body = imap_base64($body);
                 break;
             */
             case 'quoted-printable':
                 $body = quoted_printable_decode($body);
                 break;
             case 'base64':
                 $body = base64_decode($body);
                 break;
         }
     }
     if (isset($partHeaders['content-type']) && preg_match("/^(?:.+?);\\scharset=(.+)\$/", $partHeaders['content-type'], $matches)) {
         $charset = trim($matches['1']);
         if (!preg_match("/^(utf-8|utf8)\$/i", $charset)) {
             $body = iconv($charset, "UTF-8//IGNORE", $body);
         }
     }
     $data = array('from' => self::_cleanEmail($headers['from']), 'to' => self::_cleanEmail($headers['to']), 'subject' => $headers['subject'], 'body' => $body);
     return $data;
 }
예제 #7
0
 /**
  * @param Zend_Mail_Message $message
  *
  * @return array('filename' => $filename, 'content' => $content) | false
  */
 protected function _getMessageAttachment($message)
 {
     $data = array();
     // Get first flat part
     if ($message->isMultipart()) {
         $parts = $message;
         foreach (new RecursiveIteratorIterator($parts) as $part) {
             $attach = $this->_getMessageAttachment($part);
             if ($attach) {
                 $data[] = $attach;
             }
         }
     } else {
         $headers = $message->getHeaders();
         $isAttachment = null;
         foreach ($headers as $value) {
             if (is_array($value)) {
                 $value = implode(";", $value);
             }
             if ($isAttachment = preg_match('/(name|filename)="{0,1}([^;\\"]*)"{0,1}/si', $value, $matches)) {
                 break;
             }
         }
         if ($isAttachment) {
             $filename = $matches[2];
             $encodedContent = $message->getContent();
             // Decoding transfer-encoding
             switch ($transferEncoding = @$headers['content-transfer-encoding']) {
                 case Zend_Mime::ENCODING_QUOTEDPRINTABLE:
                     $content = quoted_printable_decode($encodedContent);
                     break;
                 case Zend_Mime::ENCODING_BASE64:
                     $content = base64_decode($encodedContent);
                     break;
                 default:
                     $content = $encodedContent;
             }
             $filename = iconv_mime_decode($filename, ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8');
             return array('filename' => $filename, 'content' => $content);
         }
         return false;
     }
     return $data;
 }