/** * Sets up the fixture. * This method is called before a test is executed. * * @access protected */ protected function setUp() { $this->_account = Expressomail_Controller_Account::getInstance()->search()->getFirstRecord(); $this->_controller = Expressomail_Controller_Message::getInstance(); $this->_imap = Expressomail_Backend_ImapFactory::factory($this->_account); $this->_folder = $this->getFolder($this->_testFolderName); $this->_imap->selectFolder($this->_testFolderName); $this->_createdMessages = new Tinebase_Record_RecordSet('Expressomail_Model_Message'); }
/** * parse headers and set 'date', 'from', 'to', 'cc', 'bcc', 'subject', 'sender' fields * * @param array $_headers * @return void */ public function parseHeaders(array $_headers) { // remove duplicate headers (which can't be set twice in real life) foreach (array('date', 'from', 'to', 'cc', 'bcc', 'subject', 'sender') as $field) { if (isset($_headers[$field]) && is_array($_headers[$field])) { $_headers[$field] = $_headers[$field][0]; } } $this->importance = isset($_headers['importance']) && strtolower($_headers['importance']) === 'high' ? true : false; $this->subject = isset($_headers['subject']) ? Expressomail_Message::convertText($_headers['subject']) : null; $this->reading_conf = array_key_exists('disposition-notification-to', $_headers) && $_headers['disposition-notification-to'] ? true : false; if (array_key_exists('date', $_headers)) { $this->sent = Expressomail_Message::convertDate($_headers['date']); } elseif (array_key_exists('resent-date', $_headers)) { $this->sent = Expressomail_Message::convertDate($_headers['resent-date']); } $punycodeConverter = Expressomail_Controller_Message::getInstance()->getPunycodeConverter(); foreach (array('to', 'cc', 'bcc', 'from', 'sender') as $field) { if (isset($_headers[$field])) { $value = Expressomail_Message::convertAddresses($_headers[$field], $punycodeConverter); switch ($field) { case 'from': $this->from_email = isset($value[0]) && array_key_exists('email', $value[0]) ? $value[0]['email'] : ''; $this->from_name = isset($value[0]) && array_key_exists('name', $value[0]) && !empty($value[0]['name']) ? $value[0]['name'] : $this->from_email; break; case 'sender': $this->sender = isset($value[0]) && array_key_exists('email', $value[0]) ? '<' . $value[0]['email'] . '>' : ''; if (isset($value[0]) && array_key_exists('name', $value[0]) && !empty($value[0]['name'])) { $this->sender = '"' . $value[0]['name'] . '" ' . $this->sender; } break; default: $this->{$field} = $value; } } } }
/** * zip message(s) * * @param array $msgIds * @return Object */ public function zipMessages($msgIds) { $zipArchive = new ZipArchive(); $tmpFile = tempnam(Tinebase_Core::getTempDir(), 'tine20_'); if ($zipArchive->open($tmpFile) === TRUE) { foreach ($msgIds as $msgId) { $part = Expressomail_Controller_Message::getInstance()->getRawMessage($msgId); $filename = $msgId . '.eml'; $zipArchive->addFromString($filename, $part); } $zipArchive->close(); } $zipFile = Tinebase_TempFile::getInstance()->createTempFile($tmpFile, "mensagem.zip"); return $zipFile; }
/** * download all attachments * * @param string $_messageId */ protected function _downloadAllAtachements($_messageId) { $oldMaxExcecutionTime = Tinebase_Core::setExecutionLifeTime(0); $ZIPfile = new ZipArchive(); $tmpFile = tempnam(Tinebase_Core::getTempDir(), 'tine20_'); if (strpos($_messageId, '_') !== false) { list($messageId, $partId) = explode('_', $_messageId); } else { $messageId = $_messageId; $partId = null; } if ($ZIPfile->open($tmpFile) === TRUE) { $attachments = Expressomail_Controller_Message::getInstance()->getAttachments($messageId, $partId); foreach ($attachments as $attachment) { $part = Expressomail_Controller_Message::getInstance()->getMessagePart($messageId, $attachment['partId']); $filename = is_null($part->filename) ? $attachment['filename'] : $part->filename; if ($part->encoding == Zend_Mime::ENCODING_BASE64) { $ZIPfile->addFromString(iconv("UTF-8", "ASCII//TRANSLIT", $filename), base64_decode(stream_get_contents($part->getRawStream()))); } else { $ZIPfile->addFromString(iconv("UTF-8", "ASCII//TRANSLIT", $filename), stream_get_contents($part->getRawStream())); } } $ZIPfile->close(); } $maxAge = 3600; header('Cache-Control: private, max-age=' . $maxAge); header("Expires: " . gmdate('D, d M Y H:i:s', Tinebase_DateTime::now()->addSecond($maxAge)->getTimestamp()) . " GMT"); // overwrite Pragma header from session header("Pragma: cache"); header('Content-Disposition: attachment; filename="mensagens.zip"'); header("Content-Type: application/zip"); $stream = fopen($tmpFile, 'r'); fpassthru($stream); fclose($stream); unlink($tmpFile); Tinebase_Core::setExecutionLifeTime($oldMaxExcecutionTime); exit; }
/** * set In-Reply-To and References headers * * @param Expressomail_Model_Message $message * * @see http://www.faqs.org/rfcs/rfc2822.html / Section 3.6.4. */ protected function _addReplyHeaders(Expressomail_Model_Message $message) { $originalHeaders = Expressomail_Controller_Message::getInstance()->getMessageHeaders($message->original_id); if (!isset($originalHeaders['message-id'])) { // no message-id -> skip this return; } $messageHeaders = is_array($message->headers) ? $message->headers : array(); $messageHeaders['In-Reply-To'] = $originalHeaders['message-id']; $references = ''; if (isset($originalHeaders['references'])) { $references = $originalHeaders['references'] . ' '; } else { if (isset($originalHeaders['in-reply-to'])) { $references = $originalHeaders['in-reply-to'] . ' '; } } $references .= $originalHeaders['message-id']; $messageHeaders['References'] = $references; $message->headers = $messageHeaders; }
/** * move messages to another email account * * @param Tinebase_Record_RecordSet $_messages * @param Expressomail_Model_Folder $_targetFolder */ protected function _moveMessagesToAnotherAccount(Tinebase_Record_RecordSet $_messages, Expressomail_Model_Folder $_targetFolder) { if (Tinebase_Core::isLogLevel(Zend_Log::INFO)) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Move ' . count($_messages) . ' message(s) to ' . $_targetFolder->globalname . ' in account ' . $_targetFolder->account_id); } foreach ($_messages as $message) { $part = Expressomail_Controller_Message::getInstance()->getMessagePart($message); $this->appendMessage($_targetFolder, $part->getRawStream(), $message->flags); } }
/** * used by the mail backend only. Used to update the folder cache * * @param string $_folderId */ public function updateCache($_folderId) { try { Expressomail_Controller_Message::getInstance()->updateCache($_folderId, 5); } catch (Exception $e) { if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " catched exception " . get_class($e)); } if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " " . $e->getMessage()); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " " . $e->getTraceAsString()); } } }
/** * test flag update */ public function testUpdateFlags() { $message = $this->_emailTestClass->messageTestHelper('multipart_mixed.eml', 'multipart/mixed'); // appended messages already have the SEEN flag $this->assertTrue(in_array(Zend_Mail_Storage::FLAG_SEEN, $message->flags), 'SEEN flag not found: ' . print_r($message->flags, TRUE)); // add another flag Expressomail_Controller_Message_Flags::getInstance()->addFlags($message, Zend_Mail_Storage::FLAG_ANSWERED); while (!isset($updatedFolder) || $updatedFolder->cache_status === Expressomail_Model_Folder::CACHE_STATUS_INCOMPLETE) { $updatedFolder = $this->_controller->updateCache($this->_folder, 30, 1); } // clear/add flag on imap $this->_imap->clearFlags($message->messageuid, array(Zend_Mail_Storage::FLAG_SEEN)); $flagsToAdd = array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT, Zend_Mail_Storage::FLAG_PASSED); try { $this->_imap->addFlags($message->messageuid, $flagsToAdd); } catch (Zend_Mail_Storage_Exception $zmse) { // some imap servers (dbmail, ...) do not support PASSED flag if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . $zmse->getMessage()); } $this->_imap->addFlags($message->messageuid, array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT)); } $this->_controller->updateFlags($updatedFolder); $cachedMessage = Expressomail_Controller_Message::getInstance()->get($message->getId()); $this->assertTrue(!in_array(Zend_Mail_Storage::FLAG_SEEN, $cachedMessage->flags), 'SEEN flag found: ' . print_r($cachedMessage->flags, TRUE)); $expectedFlags = array(Zend_Mail_Storage::FLAG_FLAGGED, Zend_Mail_Storage::FLAG_DRAFT, Zend_Mail_Storage::FLAG_ANSWERED); $this->assertEquals(3, count($cachedMessage->flags), 'found too many flags: ' . print_r($cachedMessage->flags, TRUE)); foreach ($expectedFlags as $expectedFlag) { $this->assertTrue(in_array($expectedFlag, $cachedMessage->flags), $expectedFlag . ' flag not found: ' . print_r($cachedMessage->flags, TRUE)); } $this->_controller->updateFlags($updatedFolder); $cachedMessageAgain = Expressomail_Controller_Message::getInstance()->get($message->getId()); // cached message should not have been updated again $this->assertEquals($cachedMessage->timestamp->__toString(), $cachedMessageAgain->timestamp->__toString()); }
/** * 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; }
/** * update flags * - use session/writeClose to allow following requests * * @param string $folderId id of active folder * @param integer $time update time in seconds * @return array */ public function updateFlags($folderId, $time) { // close session to allow other requests Expressomail_Session::getSessionNamespace()->lock(); $folder = Expressomail_Controller_Message::getInstance()->updateFlags($folderId, $time); return $this->_recordToJson($folder); }
/** * 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; }