/**
  * test conversion to plain text (blockquotes to quotes) / tests linebreaks, too
  */
 public function testGetPlainTextBody()
 {
     $message = new Expressomail_Model_Message(array('body' => 'blabla<br/><blockquote class="felamimail-body-blockquote">lalülüüla<br/><br/><div>lala</div><br/><blockquote class="felamimail-body-blockquote">xyz</blockquote></blockquote><br/><br/>jojo<br/>' . 'lkjlhk<div><br></div><div><br><div>jjlöjlö</div><div><font face="arial"><br></font></div></div><div><font face="arial">Pickhuben 2-4, 20457 Hamburg</font></div>'));
     $result = $message->getPlainTextBody();
     //echo $result;
     $this->assertEquals("blabla\n" . "> lalülüüla\n" . "> \n" . "> lala\n" . "> \n" . "> > xyz\n" . "\n\n" . "jojo\n" . "lkjlhk\n\n\n" . "jjlöjlö\n\n" . "Pickhuben 2-4, 20457 Hamburg\n", $result);
 }
 /**
  *
  * @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 mail body
  *
  * @param Expressomail_mail $_mail
  * @param Expressomail_Model_Message $_message
  */
 protected function _setMailBody(Expressomail_mail $_mail, Expressomail_Model_Message $_message)
 {
     if ($_message->content_type == Expressomail_Model_Message::CONTENT_TYPE_HTML) {
         // checking embedded images
         $embeddedImages = $this->processEmbeddedImagesInHtmlBody($_message->body);
         // now checking embedded signature base64 image
         $base64Images = $this->processEmbeddedImageSignatureInHtmlBody($_message->body);
         //now checking embed images for reply/forward
         $embeddedImagesReply = $this->processEmbeddedImagesInHtmlBodyForReply($_message->body);
         $cid = array();
         if (count($embeddedImagesReply) > 0) {
             foreach ($embeddedImagesReply as $index => $embeddedImage) {
                 $cid[$index] = $_mail->createCid($embeddedImage['messageId']);
                 $_message->body = str_replace($embeddedImage['match'], 'src="cid:' . $cid[$index] . '"', $_message->body);
             }
         }
         if (count($embeddedImages) > 0) {
             $_message->body = str_ireplace('src="index.php?method=Expressomail.showTempImage&amp;tempImageId=', 'src="cid:', $_message->body);
         }
         if (count($base64Images) > 0) {
             // there should be only one image in the signature
             $signature_cid = $_mail->createCid($base64Images[0][1]);
             $_message->body = preg_replace('/<img id="?user-signature-image-?[0-9]*"? alt="?[^\\"]+"? src="data:image\\/jpeg;base64,[^"]+">/', '<img id="user-signature-image" src="cid:' . $signature_cid . '"/>', $_message->body);
         }
         $_mail->setBodyHtml(Expressomail_Message::addHtmlMarkup($_message->body));
         if (count($embeddedImages) > 0) {
             foreach ($embeddedImages as $embeddedImage) {
                 $file = Tinebase_Core::getTempDir() . '/' . $embeddedImage[1];
                 $image = file_get_contents($file);
                 $_mail->createHtmlRelatedAttachment($image, $embeddedImage[1], 'image/jpg', Zend_Mime::DISPOSITION_INLINE, Zend_Mime::ENCODING_BASE64, $embeddedImage[0]);
             }
         }
         if (count($base64Images) > 0) {
             // again, there should be only one image in the signature
             $image = base64_decode($base64Images[0][1]);
             $_mail->createHtmlRelatedAttachment($image, $signature_cid, 'image/jpg', Zend_Mime::DISPOSITION_INLINE, Zend_Mime::ENCODING_BASE64, $base64Images[0][0]);
         }
         if (count($embeddedImagesReply) > 0) {
             foreach ($embeddedImagesReply as $index => $embeddedImage) {
                 try {
                     $part = Expressomail_Controller_Message::getInstance()->getMessagePart($embeddedImage['messageId'], $embeddedImage['messagePart']);
                     $image = base64_decode(stream_get_contents($part->getRawStream()));
                     $_mail->createHtmlRelatedAttachment($image, $cid[$index], $part->type, Zend_Mime::DISPOSITION_INLINE, Zend_Mime::ENCODING_BASE64, $part->filename);
                 } catch (Exception $exc) {
                 }
             }
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
             Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $_mail->getBodyHtml(TRUE));
         }
     }
     $plainBodyText = $_message->getPlainTextBody();
     $_mail->setBodyText($plainBodyText);
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $_mail->getBodyText(TRUE));
     }
 }
 /**
  * Get multipart report notification message body
  *
  * @param Expressomail_Model_Message $_message
  * @return string Expressomail_Model_MessageDispositionNotificationPart->getHTMLFormatted $_mdnMessage
  */
 private function _getMultipartReportNotificationMessageBody(Expressomail_Model_Message $_message, $_partId, $_contentType, $_account = NULL)
 {
     $_structure = $_message->getPartStructure($_partId);
     $_bodyParts = $_message->getBodyParts($_structure, $_contentType);
     // test if we have all the parts
     if (empty($_bodyParts) || count($_bodyParts) < 2 || count($_bodyParts) > 3 || !isset($_bodyParts[2]['contentType']) && $_bodyParts[2]['contentType'] !== Expressomail_Model_Message::CONTENT_TYPE_MESSAGE_DISPOSITION_NOTIFICATION) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Malformed MDN Message.');
         return '';
     }
     // MDN message assembly needs 2 original message parts to handle
     //First is part 2 to get original message send data
     $_bodyPart = $this->getMessagePart($_message, 2, FALSE, $_structure);
     //Second is part 1 to get SIEVE automatic message data
     $_bodyPart2 = $this->getMessagePart($_message, 1, FALSE, $_structure);
     $_mdnMessage = new Expressomail_Model_MessageDispositionNotificationPart($this->_getDecodedBodyContent($_bodyPart, $_structure));
     $_mdnSieve = new Expressomail_Model_MessageDispositionNotificationPart($this->_getDecodedBodyContent($_bodyPart2, $_structure));
     $_userMessage = $_mdnSieve->getCustomMessage();
     //Put them together to assebly user friendly message
     return $_mdnMessage->getHTMLFormatted($_userMessage);
 }
 /**
  * do substitutions in vacation message
  * 
  * @param Expressomail_Model_Sieve_Vacation $vacation
  * @param string $message
  * @return string
  * 
  * @todo get locale from placeholder (i.e. endDate-_LOCALESTRING_)
  * @todo get field from placeholder (i.e. representation-_FIELDNAME_)
  * @todo use html templates?
  * @todo use ZF templates / phplib tpl files?
  */
 protected function _doMessageSubstitutions(Expressomail_Model_Sieve_Vacation $vacation, $message)
 {
     $timezone = Tinebase_Core::get(Tinebase_Core::USERTIMEZONE);
     $representatives = $vacation->contact_ids ? Addressbook_Controller_Contact::getInstance()->getMultiple($vacation->contact_ids) : array();
     if ($vacation->contact_ids && count($representatives) > 0) {
         // sort representatives
         $representativesArray = array();
         foreach ($vacation->contact_ids as $id) {
             $representativesArray[] = $representatives->getById($id);
         }
     }
     try {
         $ownContact = Addressbook_Controller_Contact::getInstance()->getContactByUserId(Tinebase_Core::getUser()->getId());
     } catch (Exception $e) {
         if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
             Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' ' . $e);
         }
         $ownContact = NULL;
     }
     $search = array('{startDate-en_US}', '{endDate-en_US}', '{startDate-de_DE}', '{endDate-de_DE}', '{representation-n_fn-1}', '{representation-n_fn-2}', '{representation-email-1}', '{representation-email-2}', '{representation-tel_work-1}', '{representation-tel_work-2}', '{owncontact-n_fn}', '{signature}');
     $replace = array(Tinebase_Translation::dateToStringInTzAndLocaleFormat($vacation->start_date, $timezone, new Zend_Locale('en_US'), 'date'), Tinebase_Translation::dateToStringInTzAndLocaleFormat($vacation->end_date, $timezone, new Zend_Locale('en_US'), 'date'), Tinebase_Translation::dateToStringInTzAndLocaleFormat($vacation->start_date, $timezone, new Zend_Locale('de_DE'), 'date'), Tinebase_Translation::dateToStringInTzAndLocaleFormat($vacation->end_date, $timezone, new Zend_Locale('de_DE'), 'date'), isset($representativesArray[0]) ? $representativesArray[0]->n_fn : 'unknown person', isset($representativesArray[1]) ? $representativesArray[1]->n_fn : 'unknown person', isset($representativesArray[0]) ? $representativesArray[0]->email : 'unknown email', isset($representativesArray[1]) ? $representativesArray[1]->email : 'unknown email', isset($representativesArray[0]) ? $representativesArray[0]->tel_work : 'unknown phone', isset($representativesArray[1]) ? $representativesArray[1]->tel_work : 'unknown phone', $ownContact ? $ownContact->n_fn : '', $vacation->signature ? Expressomail_Model_Message::convertHTMLToPlainTextWithQuotes(preg_replace("/\\r|\\n/", '', $vacation->signature)) : '');
     $result = str_replace($search, $replace, $message);
     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
         Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . $result);
     }
     return $result;
 }
 /**
  * create new message for the cache
  *
  * @param array $_message
  * @param Expressomail_Model_Folder $_folder
  * @return Expressomail_Model_Message
  */
 protected function _createModelMessage(array $_message, Expressomail_Model_Folder $_folder = NULL)
 {
     // Optimization!!!
     if ($_folder == NULL) {
         if (isset($_message['folder_id'])) {
             $_folder = array_key_exists($_message['folder_id'], $this->_folderMap) ? $this->_folderMap[$_message['folder_id']] : ($this->_folderMap[$_message['folder_id']] = Expressomail_Controller_Folder::getInstance()->get($_message['folder_id']));
         } else {
             return NULL;
         }
     }
     $message = new Expressomail_Model_Message(array('id' => self::createMessageId($_folder->account_id, $_folder->getId(), $_message['uid']), 'account_id' => $_folder->account_id, 'messageuid' => $_message['uid'], 'folder_id' => $_folder->getId(), 'timestamp' => Tinebase_DateTime::now(), 'received' => Expressomail_Message::convertDate($_message['received']), 'size' => $_message['size'], 'flags' => $_message['flags']), true);
     $message->parseStructure($_message['structure']);
     $message->parseHeaders($_message['header']);
     $message->fixToListModel();
     $message->parseBodyParts();
     $message->parseSmime($_message['structure']);
     $attachments = Expressomail_Controller_Message::getInstance()->getAttachments($message);
     $message->has_attachment = count($attachments) > 0 ? true : false;
     if ($message->content_type === Expressomail_Model_Message::CONTENT_TYPE_MULTIPART_REPORT) {
         $bodyParts = $message->getBodyParts($message->structure);
         foreach ($bodyParts as $partId => $partStructure) {
             if ($partStructure['contentType'] === Expressomail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822) {
                 $translate = Tinebase_Translation::getTranslation('Expressomail');
                 $partHeaders = Expressomail_Controller_Message::getInstance()->getMessageHeaders($message, $partId, true);
                 $message->subject = $partHeaders['subject'] . ' - ' . $translate->_($message->subject);
                 $message->from_name = $translate->_($message->from_name);
             }
         }
     }
     return $message;
 }
 /**
  * report message(s) as phishing
  *
  * @param  array $msgIds
  * @param  array $recordData
  * @return array
  */
 public function reportPhishing($msgIds, $recordData)
 {
     $message = new Expressomail_Model_Message();
     $message->setFromJsonInUsersTimezone($recordData);
     $zipFile = Expressomail_Controller_Message::getInstance()->zipMessages($msgIds);
     $message = Expressomail_Controller_Message::getInstance()->parsePhishingNotification($message, $zipFile);
     $message = Expressomail_Controller_Message_Send::getInstance()->sendMessage($message);
     $result = $this->_recordToJson($message);
     return $result;
 }
 /**
  * search message by header (X-Tine20TestMessage) and add it to cache
  *
  * @param string $_testHeaderValue
  * @param Expressomail_Model_Folder $_folder
  * @param boolean $assert
  * @param string $testHeader
  * @return Expressomail_Model_Message|NULL
  */
 public function searchAndCacheMessage($_testHeaderValue, $_folder = NULL, $assert = TRUE, $testHeader = 'X-Tine20TestMessage')
 {
     $folder = $_folder !== NULL ? $_folder : $this->_folder;
     $message = $this->_searchMessage($_testHeaderValue, $folder, $assert, $testHeader);
     if ($message === NULL && !$assert) {
         return NULL;
     }
     //        $cachedMessage = $this->_cache->addMessage($message, $folder);
     //        if ($cachedMessage === FALSE) {
     //            // try to add message again (it had a duplicate)
     //            $this->_cache->clear($folder);
     //            $cachedMessage = $this->_cache->addMessage($message, $folder);
     //        }
     //
     //        if ($assert) {
     //            $this->assertTrue($cachedMessage instanceof Expressomail_Model_Message, 'could not add message to cache');
     //        }
     //
     //        $this->_createdMessages->addRecord($cachedMessage);
     //
     //        return $cachedMessage;
     $expressoMessage = new Expressomail_Model_Message(array('account_id' => $_folder->account_id, 'messageuid' => $message['uid'], 'folder_id' => $_folder->getId(), 'timestamp' => Tinebase_DateTime::now(), 'received' => Expressomail_Message::convertDate($message['received']), 'size' => $message['size'], 'flags' => $message['flags']));
     $expressoMessage->parseStructure($message['structure']);
     $expressoMessage->parseHeaders($message['header']);
     $expressoMessage->parseBodyParts();
     $attachments = Expressomail_Controller_Message::getInstance()->getAttachments($expressoMessage);
     $expressoMessage->has_attachment = count($attachments) > 0 ? true : false;
     return $expressoMessage;
 }