/** * test conversion to plain text (blockquotes to quotes) / tests linebreaks, too */ public function testGetPlainTextBody() { $message = new Felamimail_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); }
/** * create new message for the cache * * @param array $_message * @param Felamimail_Model_Folder $_folder * @return Felamimail_Model_Message */ protected function _createModelMessage(array $_message, Felamimail_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']] = Felamimail_Controller_Folder::getInstance()->get($_message['folder_id'])); } else { return NULL; } } $message = new Felamimail_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' => Felamimail_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 = Felamimail_Controller_Message::getInstance()->getAttachments($message); $message->has_attachment = count($attachments) > 0 ? true : false; return $message; }
/** * set mail body * * @param Tinebase_Mail $_mail * @param Felamimail_Model_Message $_message */ protected function _setMailBody(Tinebase_Mail $_mail, Felamimail_Model_Message $_message) { if ($_message->content_type == Felamimail_Model_Message::CONTENT_TYPE_HTML) { $_mail->setBodyHtml(Felamimail_Message::addHtmlMarkup($_message->body)); 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)); } }
/** * save message in folder * * @param string $folderName * @param array $recordData * @return array */ public function saveMessageInFolder($folderName, $recordData) { $message = new Felamimail_Model_Message(); $message->setFromJsonInUsersTimezone($recordData); $result = Felamimail_Controller_Message_Send::getInstance()->saveMessageInFolder($folderName, $message); $result = $this->_recordToJson($result); return $result; }
/** * save message in tinebase cache * - only cache message headers if received during the last day * * @param Felamimail_Model_Message $_message * @param Felamimail_Model_Folder $_folder * @param array $_messageData * * @todo do we need the headers in the Tinebase cache? */ protected function _saveMessageInTinebaseCache(Felamimail_Model_Message $_message, Felamimail_Model_Folder $_folder, $_messageData) { if (!$_message->received->isLater(Tinebase_DateTime::now()->subDay(3))) { return; } $memory = function_exists('memory_get_peak_usage') ? memory_get_peak_usage(true) : memory_get_usage(true); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' caching message ' . $_message->getId() . ' / memory usage: ' . $memory / 1024 / 1024 . ' MBytes'); } if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' ' . print_r($_message->toArray(), TRUE)); } $cacheId = 'getMessageHeaders' . $_message->getId(); Tinebase_Core::getCache()->save($_messageData['header'], $cacheId, array('getMessageHeaders')); // prefetch body to cache if (Felamimail_Config::getInstance()->get(Felamimail_Config::CACHE_EMAIL_BODY, TRUE) && $_message->size < $this->_maxMessageSizeToCacheBody) { $account = Felamimail_Controller_Account::getInstance()->get($_folder->account_id); $mimeType = $account->display_format == Felamimail_Model_Account::DISPLAY_HTML || $account->display_format == Felamimail_Model_Account::DISPLAY_CONTENT_TYPE ? Zend_Mime::TYPE_HTML : Zend_Mime::TYPE_TEXT; Felamimail_Controller_Message::getInstance()->getMessageBody($_message, null, $mimeType, $account); } }
/** * get and decode message body * * @param Felamimail_Model_Message $_message * @param string $_partId * @param string $_contentType * @param Felamimail_Model_Account $_account * @return string * * @todo multipart_related messages should deliver inline images */ protected function _getAndDecodeMessageBody(Felamimail_Model_Message $_message, $_partId, $_contentType, $_account = NULL) { $structure = $_message->getPartStructure($_partId); if (empty($structure)) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Empty structure, could not find body parts of message ' . $_message->subject); } return ''; } $bodyParts = $_message->getBodyParts($structure, $_contentType); if (empty($bodyParts)) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find body parts of message ' . $_message->subject); } return ''; } $messageBody = ''; foreach ($bodyParts as $partId => $partStructure) { $bodyPart = $this->getMessagePart($_message, $partId, TRUE, $partStructure); $body = Tinebase_Mail::getDecodedContent($bodyPart, $partStructure); if ($partStructure['contentType'] != Zend_Mime::TYPE_TEXT) { $bodyCharCountBefore = strlen($body); $body = $this->_purifyBodyContent($body, $_message->getId()); $bodyCharCountAfter = strlen($body); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Purifying removed ' . ($bodyCharCountBefore - $bodyCharCountAfter) . ' / ' . $bodyCharCountBefore . ' characters.'); } if ($_message->text_partid && $bodyCharCountAfter < $bodyCharCountBefore / 10) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Purify may have removed (more than 9/10) too many chars, using alternative text message part.'); } $result = $this->_getAndDecodeMessageBody($_message, $_message->text_partid, Zend_Mime::TYPE_TEXT, $_account); return Felamimail_Message::convertContentType(Zend_Mime::TYPE_TEXT, Zend_Mime::TYPE_HTML, $result); } } if (!($_account !== NULL && $_account->display_format === Felamimail_Model_Account::DISPLAY_CONTENT_TYPE && $bodyPart->type == Zend_Mime::TYPE_TEXT)) { $body = Felamimail_Message::convertContentType($partStructure['contentType'], $_contentType, $body); if ($bodyPart->type == Zend_Mime::TYPE_TEXT && $_contentType == Zend_Mime::TYPE_HTML) { $body = Felamimail_Message::replaceUris($body); $body = Felamimail_Message::replaceEmails($body); } } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Do not convert ' . $bodyPart->type . ' part to ' . $_contentType); } } $body = Felamimail_Message::replaceTargets($body); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adding part ' . $partId . ' to message body.'); } $messageBody .= Tinebase_Core::filterInputForDatabase($body); } return $messageBody; }
public function inviteUsersToJoinToFelamimail($roomId, $moderator, $userName, $email) { $translation = Tinebase_Translation::getTranslation('Webconference'); $defaultEmailAccount = Tinebase_Core::getPreference("Felamimail")->{Felamimail_Preference::DEFAULTACCOUNT}; $url = Webconference_Controller_BigBlueButton::getInstance()->joinRoom($roomId, $moderator, $userName, $email)->bbbUrl->bbbUrl; $accountFullName = Tinebase_Core::getUser()->accountFullName; $messageHtml = sprintf($translation->_("The user %s is inviting you to a Webconference"), $accountFullName); $messageHtml .= "<br/><br/>"; $messageHtml .= "<div>"; $messageHtml .= "<span class=\"{$url}\" />"; $messageHtml .= "<span class=\"tinebase-webconference-link\">"; $messageHtml .= $translation->_("Log in to Webconference"); $messageHtml .= "</span>"; $messageHtml .= "</div>"; $recordData = array("note" => null, "content_type" => "text/html", "account_id" => $defaultEmailAccount, "to" => array($email), "cc" => array(), "bcc" => array(), "subject" => $translation->_("Invite User To Join Webconference"), "body" => $messageHtml, "attachments" => array(), "from_email" => Tinebase_Core::getUser()->accountEmailAddress, "customfields" => array()); $message = new Felamimail_Model_Message(); $message->setFromArray($recordData); try { $result = Felamimail_Controller_Message_Send::getInstance()->sendMessage($message); $result = $this->_recordToJson($result); } catch (Zend_Mail_Protocol_Exception $zmpe) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' Could not send message: ' . $zmpe->getMessage()); throw $zmpe; } return $result; }
/** * add flag to message * * @param Felamimail_Model_Message $_message * @param string $_flag */ public function addFlag($_message, $_flag) { if (empty($_flag)) { // nothing todo return; } $data = array('flag' => $_flag, 'message_id' => $_message->getId(), 'folder_id' => $_message->folder_id); $this->_db->insert($this->_tablePrefix . $this->_foreignTables['flags']['table'], $data); }
/** * check sieve backend capabilities * * @param Felamimail_Model_Sieve_Vacation $_vacation */ protected function _checkCapabilities(Felamimail_Model_Sieve_Vacation $_vacation) { $capabilities = $this->_backend->capability(); if (!in_array('mime', $capabilities['SIEVE'])) { unset($_vacation->mime); $_vacation->reason = Felamimail_Model_Message::convertHTMLToPlainTextWithQuotes($_vacation->reason); } if (preg_match('/cyrus/i', $capabilities['IMPLEMENTATION'])) { // cyrus does not support :from unset($_vacation->from); } }
/** * do substitutions in vacation message * * @param Felamimail_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(Felamimail_Model_Sieve_Vacation $vacation, $message) { $timezone = Tinebase_Core::getUserTimezone(); $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 ? Felamimail_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; }
/** * get and decode message body * * @param Felamimail_Model_Message $_message * @param string $_partId * @param string $_contentType * @param Felamimail_Model_Account $_account * @return string */ protected function _getAndDecodeMessageBody(Felamimail_Model_Message $_message, $_partId, $_contentType, $_account = NULL) { $structure = $_message->getPartStructure($_partId); $bodyParts = $_message->getBodyParts($structure, $_contentType); if (empty($bodyParts)) { return ''; } $messageBody = ''; foreach ($bodyParts as $partId => $partStructure) { $bodyPart = $this->getMessagePart($_message, $partId, TRUE); $body = $this->_getDecodedBodyContent($bodyPart, $partStructure); if ($partStructure['contentType'] != Zend_Mime::TYPE_TEXT) { $body = $this->_getDecodedBodyImages($_message->getId(), $body); $body = $this->_purifyBodyContent($body); } if (!($_account !== NULL && $_account->display_format === Felamimail_Model_Account::DISPLAY_CONTENT_TYPE && $bodyPart->type == Zend_Mime::TYPE_TEXT)) { $body = Felamimail_Message::convertContentType($partStructure['contentType'], $_contentType, $body); if ($bodyPart->type == Zend_Mime::TYPE_TEXT && $_contentType == Zend_Mime::TYPE_HTML) { $body = Felamimail_Message::replaceUriAndSpaces($body); $body = Felamimail_Message::replaceEmails($body); } } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Do not convert ' . $bodyPart->type . ' part to ' . $_contentType); } } $messageBody .= $body; } return $messageBody; }
/** * set mail body * * @param Tinebase_Mail $_mail * @param Felamimail_Model_Message $_message */ protected function _setMailBody(Tinebase_Mail $_mail, Felamimail_Model_Message $_message) { if ($_message->content_type == Felamimail_Model_Message::CONTENT_TYPE_HTML) { // checking embedded images $embeddedImages = $_mail->processEmbeddedImagesInHtmlBody($_message->body); // now checking embedded signature base64 image $base64Images = $_mail->processEmbeddedImageSignatureInHtmlBody($_message->body); if (count($embeddedImages) > 0) { $_message->body = str_ireplace('src="index.php?method=Felamimail.showTempImage&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" alt="[^\\"]+" src="data:image\\/jpeg;base64,[^"]+">/', '<img id="user-signature-image" src="cid:' . $signature_cid . '"/>', $_message->body); } $_mail->setBodyHtml(Felamimail_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 (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)); } }