diff --git a/externals/phpmailer/class.phpmailer-lite.php b/externals/phpmailer/class.phpmailer-lite.php --- a/externals/phpmailer/class.phpmailer-lite.php +++ b/externals/phpmailer/class.phpmailer-lite.php @@ -42,6 +42,103 @@ class PHPMailerLite { + public static function newFromMessage( + PhabricatorMailExternalMessage $message) { + + $mailer = new self($use_exceptions = true); + + // By default, PHPMailerLite sends one mail per recipient. We handle + // combining or separating To and Cc higher in the stack, so tell it to + // send mail exactly like we ask. + $mailer->SingleTo = false; + + $mailer->CharSet = 'utf-8'; + $mailer->Encoding = 'base64'; + + $subject = $message->getSubject(); + if ($subject !== null) { + $mailer->Subject = $subject; + } + + $from_address = $message->getFromAddress(); + if ($from_address) { + $mailer->SetFrom( + $from_address->getAddress(), + (string)$from_address->getDisplayName(), + $crazy_side_effects = false); + } + + $reply_address = $message->getReplyToAddress(); + if ($reply_address) { + $mailer->AddReplyTo( + $reply_address->getAddress(), + (string)$reply_address->getDisplayName()); + } + + $to_addresses = $message->getToAddresses(); + if ($to_addresses) { + foreach ($to_addresses as $address) { + $mailer->AddAddress( + $address->getAddress(), + (string)$address->getDisplayName()); + } + } + + $cc_addresses = $message->getCCAddresses(); + if ($cc_addresses) { + foreach ($cc_addresses as $address) { + $mailer->AddCC( + $address->getAddress(), + (string)$address->getDisplayName()); + } + } + + $headers = $message->getHeaders(); + if ($headers) { + $list = array(); + foreach ($headers as $header) { + $name = $header->getName(); + $value = $header->getValue(); + + if (phutil_utf8_strtolower($name) === 'message-id') { + $mailer->MessageID = $value; + } else { + $mailer->AddCustomHeader("{$name}: {$value}"); + } + } + } + + $attachments = $message->getAttachments(); + if ($attachments) { + foreach ($attachments as $attachment) { + $mailer->AddStringAttachment( + $attachment->getData(), + $attachment->getFilename(), + 'base64', + $attachment->getMimeType()); + } + } + + $text_body = $message->getTextBody(); + if ($text_body !== null) { + $mailer->Body = $text_body; + } + + $html_body = $message->getHTMLBody(); + if ($html_body !== null) { + $mailer->IsHTML(true); + $mailer->Body = $html_body; + if ($text_body !== null) { + $mailer->AltBody = $text_body; + } + } + + return $mailer; + } + + + + ///////////////////////////////////////////////// // PROPERTIES, PUBLIC ///////////////////////////////////////////////// diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php --- a/src/__phutil_library_map__.php +++ b/src/__phutil_library_map__.php @@ -9221,7 +9221,7 @@ 'PhabricatorMacroTransactionType' => 'PhabricatorModularTransactionType', 'PhabricatorMacroViewController' => 'PhabricatorMacroController', 'PhabricatorMailAdapter' => 'Phobject', - 'PhabricatorMailAmazonSESAdapter' => 'PhabricatorMailSendmailAdapter', + 'PhabricatorMailAmazonSESAdapter' => 'PhabricatorMailAdapter', 'PhabricatorMailAttachment' => 'Phobject', 'PhabricatorMailConfigTestCase' => 'PhabricatorTestCase', 'PhabricatorMailEmailEngine' => 'PhabricatorMailMessageEngine', diff --git a/src/applications/metamta/adapter/PhabricatorMailAdapter.php b/src/applications/metamta/adapter/PhabricatorMailAdapter.php --- a/src/applications/metamta/adapter/PhabricatorMailAdapter.php +++ b/src/applications/metamta/adapter/PhabricatorMailAdapter.php @@ -23,14 +23,8 @@ ->execute(); } - /* abstract */ public function getSupportedMessageTypes() { - throw new PhutilMethodNotImplementedException(); - } - - /* abstract */ public function sendMessage( - PhabricatorMailExternalMessage $message) { - throw new PhutilMethodNotImplementedException(); - } + abstract public function getSupportedMessageTypes(); + abstract public function sendMessage(PhabricatorMailExternalMessage $message); /** * Return true if this adapter supports setting a "Message-ID" when sending diff --git a/src/applications/metamta/adapter/PhabricatorMailAmazonSESAdapter.php b/src/applications/metamta/adapter/PhabricatorMailAmazonSESAdapter.php --- a/src/applications/metamta/adapter/PhabricatorMailAmazonSESAdapter.php +++ b/src/applications/metamta/adapter/PhabricatorMailAmazonSESAdapter.php @@ -1,21 +1,17 @@ mailer->Mailer = 'amazon-ses'; - $this->mailer->customMailer = $this; + public function getSupportedMessageTypes() { + return array( + PhabricatorMailEmailMessage::MESSAGETYPE, + ); } public function supportsMessageIDHeader() { - // Amazon SES will ignore any Message-ID we provide. return false; } @@ -26,7 +22,6 @@ 'access-key' => 'string', 'secret-key' => 'string', 'endpoint' => 'string', - 'encoding' => 'string', )); } @@ -35,10 +30,27 @@ 'access-key' => null, 'secret-key' => null, 'endpoint' => null, - 'encoding' => 'base64', ); } + /** + * @phutil-external-symbol class PHPMailerLite + */ + public function sendMessage(PhabricatorMailExternalMessage $message) { + $root = phutil_get_library_root('phabricator'); + $root = dirname($root); + require_once $root.'/externals/phpmailer/class.phpmailer-lite.php'; + + $mailer = PHPMailerLite::newFromMessage($message); + + $mailer->Mailer = 'amazon-ses'; + $mailer->customMailer = $this; + + $mailer->Send(); + } + + + /** * @phutil-external-symbol class SimpleEmailService */ diff --git a/src/applications/metamta/adapter/PhabricatorMailSendmailAdapter.php b/src/applications/metamta/adapter/PhabricatorMailSendmailAdapter.php --- a/src/applications/metamta/adapter/PhabricatorMailSendmailAdapter.php +++ b/src/applications/metamta/adapter/PhabricatorMailSendmailAdapter.php @@ -1,16 +1,20 @@ mailer = new PHPMailerLite($use_exceptions = true); - $this->mailer->CharSet = 'utf-8'; - - $encoding = $this->getOption('encoding'); - $this->mailer->Encoding = $encoding; - - // By default, PHPMailerLite sends one mail per recipient. We handle - // combining or separating To and Cc higher in the stack, so tell it to - // send mail exactly like we ask. - $this->mailer->SingleTo = false; - } - - public function supportsMessageIDHeader() { - return true; - } - - public function setFrom($email, $name = '') { - $this->mailer->SetFrom($email, $name, $crazy_side_effects = false); - return $this; - } - - public function addReplyTo($email, $name = '') { - $this->mailer->AddReplyTo($email, $name); - return $this; - } - - public function addTos(array $emails) { - foreach ($emails as $email) { - $this->mailer->AddAddress($email); - } - return $this; - } - - public function addCCs(array $emails) { - foreach ($emails as $email) { - $this->mailer->AddCC($email); - } - return $this; - } - - public function addAttachment($data, $filename, $mimetype) { - $this->mailer->AddStringAttachment( - $data, - $filename, - 'base64', - $mimetype); - return $this; - } - - public function addHeader($header_name, $header_value) { - if (strtolower($header_name) == 'message-id') { - $this->mailer->MessageID = $header_value; - } else { - $this->mailer->AddCustomHeader($header_name.': '.$header_value); - } - return $this; - } - - public function setBody($body) { - $this->mailer->Body = $body; - $this->mailer->IsHTML(false); - return $this; - } - - - /** - * Note: phpmailer-lite does NOT support sending messages with mixed version - * (plaintext and html). So for now lets just use HTML if it's available. - * @param $html - */ - public function setHTMLBody($html_body) { - $this->mailer->Body = $html_body; - $this->mailer->IsHTML(true); - return $this; - } - - public function setSubject($subject) { - $this->mailer->Subject = $subject; - return $this; - } - - public function hasValidRecipients() { - return true; - } - public function send() { - return $this->mailer->Send(); + $mailer = PHPMailerLite::newFromMessage($message); + $mailer->Send(); } }