/** * test line end encoding of Zend_Mime_Part / Smtp Protocol */ public function testSendWithWrongLineEnd() { $config = TestServer::getInstance()->getConfig(); $mailDomain = $config->maildomain ? $config->maildomain : 'tine20.org'; // build message with wrong line end rfc822 part $mail = new Tinebase_Mail('utf-8'); $mail->setBodyText('testmail' . "\r\n" . "\r\n"); $mail->setFrom('unittest@' . $mailDomain, 'unittest'); $mail->setSubject('line end test'); $mail->addTo('unittest@' . $mailDomain); $mail->addHeader('X-Tine20TestMessage', 'lineend'); // replace EOLs $content = file_get_contents(dirname(dirname(__FILE__)) . '/files/text_plain.eml'); $content = preg_replace("/\\x0a/", "\r\n", $content); $stream = fopen("php://temp", 'r+'); fputs($stream, $content); rewind($stream); $attachment = new Zend_Mime_Part($stream); $attachment->type = Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822; $attachment->encoding = null; $attachment->charset = 'ISO-8859-1'; $attachment->filename = 'attach.eml'; $attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT; $mail->addAttachment($attachment); $smtpConfig = $this->_account->getSmtpConfig(); $transport = new Felamimail_Transport($smtpConfig['hostname'], $smtpConfig); $mail->send($transport); $smtpLog = $transport->getConnection()->getLog(); $badLineEndCount = preg_match_all("/\\x0d\\x0d\\x0a/", $smtpLog, $matches); $this->assertEquals(0, $badLineEndCount); $badLineEndCount = preg_match_all("/\\x0d/", $smtpLog, $matches); $this->assertTrue(preg_match_all("/\\x0d/", $smtpLog, $matches) > 70, 'unix line ends are missing'); }
/** * add attachments to mail * * @param Tinebase_Mail $_mail * @param Felamimail_Model_Message $_message * @throws Felamimail_Exception_IMAP */ protected function _addAttachments(Tinebase_Mail $_mail, Felamimail_Model_Message $_message) { if (!isset($_message->attachments) || empty($_message->attachments)) { return; } $maxAttachmentSize = $this->_getMaxAttachmentSize(); $size = 0; $tempFileBackend = Tinebase_TempFile::getInstance(); foreach ($_message->attachments as $attachment) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Adding attachment: ' . (is_object($attachment) ? print_r($attachment->toArray(), TRUE) : print_r($attachment, TRUE))); } if (isset($attachment['type']) && $attachment['type'] == Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822 && $_message->original_id instanceof Felamimail_Model_Message) { $part = $this->getMessagePart($_message->original_id, $_message->original_part_id ? $_message->original_part_id : NULL); $part->decodeContent(); $name = $attachment['name'] . '.eml'; $type = $attachment['type']; if (!empty($attachment['size'])) { $size += $attachment['size']; } } else { $tempFile = $attachment instanceof Tinebase_Model_TempFile ? $attachment : (isset($attachment['tempFile']) || array_key_exists('tempFile', $attachment) ? $tempFileBackend->get($attachment['tempFile']['id']) : NULL); if ($tempFile === NULL) { continue; } if (!$tempFile->path) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find attachment.'); continue; } // get contents from uploaded file $stream = fopen($tempFile->path, 'r'); $part = new Zend_Mime_Part($stream); // RFC822 attachments are not encoded, set all others to ENCODING_BASE64 $part->encoding = $tempFile->type == Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822 ? null : Zend_Mime::ENCODING_BASE64; $name = $tempFile->name; $type = $tempFile->type; if (!empty($tempFile->size)) { $size += $tempFile->size; } } $part->setTypeAndDispositionForAttachment($type, $name); if ($size > $maxAttachmentSize) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Current attachment size: ' . Tinebase_Helper::convertToMegabytes($size) . ' MB / allowed size: ' . Tinebase_Helper::convertToMegabytes($maxAttachmentSize) . ' MB'); } throw new Felamimail_Exception_IMAP('Maximum attachment size exceeded. Please remove one or more attachments.'); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adding attachment ' . $part->type); } $_mail->addAttachment($part); } }
/** * send a notification as email * * @param Tinebase_Model_FullUser $_updater * @param Addressbook_Model_Contact $_recipient * @param string $_subject the subject * @param string $_messagePlain the message as plain text * @param string $_messageHtml the message as html * @param string|array $_attachments */ public function send($_updater, Addressbook_Model_Contact $_recipient, $_subject, $_messagePlain, $_messageHtml = NULL, $_attachments = NULL) { // create mail object $mail = new Tinebase_Mail('UTF-8'); // this seems to break some subjects, removing it for the moment // -> see 0004070: sometimes we can't decode message subjects (calendar notifications?) //$mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64); $mail->setSubject($_subject); $mail->setBodyText($_messagePlain); if ($_messageHtml !== NULL) { $mail->setBodyHtml($_messageHtml); } // add header to identify mails sent by notification service / don't reply to this mail, dear autoresponder ... :) $mail->addHeader('X-Tine20-Type', 'Notification'); $mail->addHeader('Precedence', 'bulk'); $mail->addHeader('User-Agent', Tinebase_Core::getTineUserAgent('Notification Service')); if (empty($this->_fromAddress)) { Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . ' No notification service address set. Could not send notification.'); return; } if ($_updater !== NULL && !empty($_updater->accountEmailAddress)) { $mail->setFrom($_updater->accountEmailAddress, $_updater->accountFullName); $mail->setSender($this->_fromAddress, $this->_fromName); } else { $mail->setFrom($this->_fromAddress, $this->_fromName); } // attachments if (is_array($_attachments)) { $attachments =& $_attachments; } elseif (is_string($_attachments)) { $attachments = array(&$_attachments); } else { $attachments = array(); } foreach ($attachments as $attachment) { if ($attachment instanceof Zend_Mime_Part) { $mail->addAttachment($attachment); } else { if (isset($attachment['filename'])) { $mail->createAttachment($attachment['rawdata'], Zend_Mime::TYPE_OCTETSTREAM, Zend_Mime::DISPOSITION_ATTACHMENT, Zend_Mime::ENCODING_BASE64, $attachment['filename']); } else { $mail->createAttachment($attachment); } } } // send if (!empty($_recipient->email)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Send notification email to ' . $_recipient->email); } $mail->addTo($_recipient->email, $_recipient->n_fn); Tinebase_Smtp::getInstance()->sendMessage($mail); } else { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . ' Not sending notification email to ' . $_recipient->n_fn . '. No email address available.'); } }
/** * add attachments to mail * * @param Tinebase_Mail $_mail * @param Felamimail_Model_Message $_message * @throws Felamimail_Exception_IMAP */ protected function _addAttachments(Tinebase_Mail $_mail, Felamimail_Model_Message $_message) { if (!isset($_message->attachments) || empty($_message->attachments)) { return; } $maxAttachmentSize = $this->_getMaxAttachmentSize(); $totalSize = 0; foreach ($_message->attachments as $attachment) { if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) { Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Adding attachment: ' . (is_object($attachment) ? print_r($attachment->toArray(), TRUE) : print_r($attachment, TRUE))); } if (isset($attachment['type']) && $attachment['type'] == Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822 && $_message->original_id instanceof Felamimail_Model_Message) { $part = $this->_getRfc822Attachment($attachment, $_message); } else { if ($attachment instanceof Tinebase_Model_TempFile || isset($attachment['tempFile'])) { $part = $this->_getTempFileAttachment($attachment); } else { $part = $this->_getMessagePartAttachment($attachment); } } if (!$part || empty($attachment['type'])) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Skipping attachment ' . print_r($attachment, true)); } continue; } $part->setTypeAndDispositionForAttachment($attachment['type'], $attachment['name']); if (!empty($attachment['size'])) { $totalSize += $attachment['size']; } if ($totalSize > $maxAttachmentSize) { if (Tinebase_Core::isLogLevel(Zend_Log::NOTICE)) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Current attachment size: ' . Tinebase_Helper::convertToMegabytes($totalSize) . ' MB / allowed size: ' . Tinebase_Helper::convertToMegabytes($maxAttachmentSize) . ' MB'); } throw new Felamimail_Exception_IMAP('Maximum attachment size exceeded. Please remove one or more attachments.'); } if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adding attachment ' . $part->type); } $_mail->addAttachment($part); } }
/** * add attachments to mail * * @param Tinebase_Mail $_mail * @param Felamimail_Model_Message $_message */ protected function _addAttachments(Tinebase_Mail $_mail, Felamimail_Model_Message $_message) { if (isset($_message->attachments)) { $size = 0; $tempFileBackend = Tinebase_TempFile::getInstance(); foreach ($_message->attachments as $attachment) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Adding attachment: ' . print_r($attachment, TRUE)); } if ($attachment['type'] == Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822 && $_message->original_id instanceof Felamimail_Model_Message) { $part = $this->getMessagePart($_message->original_id, $_message->original_part_id ? $_message->original_part_id : NULL); $part->decodeContent(); $name = $attachment['name'] . '.eml'; $type = $attachment['type']; } else { $tempFile = $attachment instanceof Tinebase_Model_TempFile ? $attachment : (array_key_exists('tempFile', $attachment) ? $tempFileBackend->get($attachment['tempFile']['id']) : NULL); if ($tempFile === NULL) { continue; } if (!$tempFile->path) { Tinebase_Core::getLogger()->notice(__METHOD__ . '::' . __LINE__ . ' Could not find attachment.'); continue; } // get contents from uploaded file $stream = fopen($tempFile->path, 'r'); $part = new Zend_Mime_Part($stream); // RFC822 attachments are not encoded, set all others to ENCODING_BASE64 $part->encoding = $tempFile->type == Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822 ? null : Zend_Mime::ENCODING_BASE64; $name = $tempFile->name; $type = $tempFile->type; } $part->disposition = Zend_Mime::DISPOSITION_ATTACHMENT; $part->filename = $name; $part->type = $type . '; name="' . $name . '"'; $_mail->addAttachment($part); } } }
/** * test line end encoding of Zend_Mime_Part / Smtp Protocol */ public function testSendWithWrongLineEnd() { $this->markTestSkipped('FIXME: 0011688: fix line end encoding in attachments'); // build message with wrong line end rfc822 part $mail = new Tinebase_Mail('utf-8'); $mail->setBodyText('testmail' . "\r\n" . "\r\n"); $mail->setFrom($this->_getEmailAddress(), 'unittest'); $mail->setSubject('line end test'); $mail->addTo($this->_getEmailAddress()); $mail->addHeader('X-Tine20TestMessage', 'lineend'); // replace EOLs $content = file_get_contents(dirname(dirname(__FILE__)) . '/files/text_plain.eml'); $content = preg_replace("/\\x0a/", "\r\n", $content); $stream = fopen("php://temp", 'r+'); fputs($stream, $content); rewind($stream); $attachment = new Zend_Mime_Part($stream); $attachment->type = Felamimail_Model_Message::CONTENT_TYPE_MESSAGE_RFC822; $attachment->encoding = null; $attachment->charset = 'ISO-8859-1'; $attachment->filename = 'attach.eml'; $attachment->disposition = Zend_Mime::DISPOSITION_ATTACHMENT; $mail->addAttachment($attachment); $smtpConfig = $this->_account->getSmtpConfig(); $transport = new Felamimail_Transport($smtpConfig['hostname'], $smtpConfig); Zend_Mail_Protocol_Abstract::$loggingEnabled = true; $mail->send($transport); Zend_Mail_Protocol_Abstract::$loggingEnabled = false; $smtpLog = $transport->getConnection()->getLog(); $badLineEndCount = preg_match_all("/\\x0d\\x0d\\x0a/", $smtpLog, $matches); $this->assertEquals(0, $badLineEndCount); $unixLineEndCount = preg_match_all("/\\x0d/", $smtpLog, $matches); $this->assertTrue($unixLineEndCount > 70, 'unix line ends are missing (got ' . $unixLineEndCount . ' unix line ends)'); }