@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update the SMTP (PHPMailer) adapter for the new mail API; remove "encoding" and "mailer"

Summary:
Ref T920. Ref T12404.

- Update to the new "$message" API.
- Remove "encoding". I believe "base64" is always the best value for this since we stopped seeing issues once we changed the default.
- Remove "mailer". This is a legacy option that makes little sense given how configuration now works.
- Rename to "SMTP". This doesn't affect users anymore since this mailer has been configured as `smtp` for about a year.
- This does NOT add a timeout since the SMTP code is inside PHPMailer (see T12404).

Test Plan: Sent messages with many mail features via GMail SMTP and SendGrid SMTP.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T12404, T920

Differential Revision: https://secure.phabricator.com/D19961

+161 -157
+5 -5
src/__phutil_library_map__.php
··· 3417 3417 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingSelfEmailHeraldAction.php', 3418 3418 'PhabricatorMailOutboundRoutingSelfNotificationHeraldAction' => 'applications/metamta/herald/PhabricatorMailOutboundRoutingSelfNotificationHeraldAction.php', 3419 3419 'PhabricatorMailOutboundStatus' => 'applications/metamta/constants/PhabricatorMailOutboundStatus.php', 3420 - 'PhabricatorMailPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailPHPMailerAdapter.php', 3421 - 'PhabricatorMailPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailPHPMailerLiteAdapter.php', 3422 3420 'PhabricatorMailPostmarkAdapter' => 'applications/metamta/adapter/PhabricatorMailPostmarkAdapter.php', 3423 3421 'PhabricatorMailPropertiesDestructionEngineExtension' => 'applications/metamta/engineextension/PhabricatorMailPropertiesDestructionEngineExtension.php', 3424 3422 'PhabricatorMailReceiver' => 'applications/metamta/receiver/PhabricatorMailReceiver.php', 3425 3423 'PhabricatorMailReceiverTestCase' => 'applications/metamta/receiver/__tests__/PhabricatorMailReceiverTestCase.php', 3426 3424 'PhabricatorMailReplyHandler' => 'applications/metamta/replyhandler/PhabricatorMailReplyHandler.php', 3427 3425 'PhabricatorMailRoutingRule' => 'applications/metamta/constants/PhabricatorMailRoutingRule.php', 3426 + 'PhabricatorMailSMTPAdapter' => 'applications/metamta/adapter/PhabricatorMailSMTPAdapter.php', 3428 3427 'PhabricatorMailSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailSendGridAdapter.php', 3428 + 'PhabricatorMailSendmailAdapter' => 'applications/metamta/adapter/PhabricatorMailSendmailAdapter.php', 3429 3429 'PhabricatorMailSetupCheck' => 'applications/config/check/PhabricatorMailSetupCheck.php', 3430 3430 'PhabricatorMailStamp' => 'applications/metamta/stamp/PhabricatorMailStamp.php', 3431 3431 'PhabricatorMailTarget' => 'applications/metamta/replyhandler/PhabricatorMailTarget.php', ··· 9222 9222 'PhabricatorMacroTransactionType' => 'PhabricatorModularTransactionType', 9223 9223 'PhabricatorMacroViewController' => 'PhabricatorMacroController', 9224 9224 'PhabricatorMailAdapter' => 'Phobject', 9225 - 'PhabricatorMailAmazonSESAdapter' => 'PhabricatorMailPHPMailerLiteAdapter', 9225 + 'PhabricatorMailAmazonSESAdapter' => 'PhabricatorMailSendmailAdapter', 9226 9226 'PhabricatorMailAttachment' => 'Phobject', 9227 9227 'PhabricatorMailConfigTestCase' => 'PhabricatorTestCase', 9228 9228 'PhabricatorMailEmailEngine' => 'PhabricatorMailMessageEngine', ··· 9251 9251 'PhabricatorMailOutboundRoutingSelfEmailHeraldAction' => 'PhabricatorMailOutboundRoutingHeraldAction', 9252 9252 'PhabricatorMailOutboundRoutingSelfNotificationHeraldAction' => 'PhabricatorMailOutboundRoutingHeraldAction', 9253 9253 'PhabricatorMailOutboundStatus' => 'Phobject', 9254 - 'PhabricatorMailPHPMailerAdapter' => 'PhabricatorMailAdapter', 9255 - 'PhabricatorMailPHPMailerLiteAdapter' => 'PhabricatorMailAdapter', 9256 9254 'PhabricatorMailPostmarkAdapter' => 'PhabricatorMailAdapter', 9257 9255 'PhabricatorMailPropertiesDestructionEngineExtension' => 'PhabricatorDestructionEngineExtension', 9258 9256 'PhabricatorMailReceiver' => 'Phobject', 9259 9257 'PhabricatorMailReceiverTestCase' => 'PhabricatorTestCase', 9260 9258 'PhabricatorMailReplyHandler' => 'Phobject', 9261 9259 'PhabricatorMailRoutingRule' => 'Phobject', 9260 + 'PhabricatorMailSMTPAdapter' => 'PhabricatorMailAdapter', 9262 9261 'PhabricatorMailSendGridAdapter' => 'PhabricatorMailAdapter', 9262 + 'PhabricatorMailSendmailAdapter' => 'PhabricatorMailAdapter', 9263 9263 'PhabricatorMailSetupCheck' => 'PhabricatorSetupCheck', 9264 9264 'PhabricatorMailStamp' => 'Phobject', 9265 9265 'PhabricatorMailTarget' => 'Phobject',
+1 -1
src/applications/metamta/adapter/PhabricatorMailAmazonSESAdapter.php
··· 1 1 <?php 2 2 3 3 final class PhabricatorMailAmazonSESAdapter 4 - extends PhabricatorMailPHPMailerLiteAdapter { 4 + extends PhabricatorMailSendmailAdapter { 5 5 6 6 const ADAPTERTYPE = 'ses'; 7 7
-150
src/applications/metamta/adapter/PhabricatorMailPHPMailerAdapter.php
··· 1 - <?php 2 - 3 - final class PhabricatorMailPHPMailerAdapter 4 - extends PhabricatorMailAdapter { 5 - 6 - const ADAPTERTYPE = 'smtp'; 7 - 8 - private $mailer; 9 - 10 - protected function validateOptions(array $options) { 11 - PhutilTypeSpec::checkMap( 12 - $options, 13 - array( 14 - 'host' => 'string|null', 15 - 'port' => 'int', 16 - 'user' => 'string|null', 17 - 'password' => 'string|null', 18 - 'protocol' => 'string|null', 19 - 'encoding' => 'string', 20 - 'mailer' => 'string', 21 - )); 22 - } 23 - 24 - public function newDefaultOptions() { 25 - return array( 26 - 'host' => null, 27 - 'port' => 25, 28 - 'user' => null, 29 - 'password' => null, 30 - 'protocol' => null, 31 - 'encoding' => 'base64', 32 - 'mailer' => 'smtp', 33 - ); 34 - } 35 - 36 - /** 37 - * @phutil-external-symbol class PHPMailer 38 - */ 39 - public function prepareForSend() { 40 - $root = phutil_get_library_root('phabricator'); 41 - $root = dirname($root); 42 - require_once $root.'/externals/phpmailer/class.phpmailer.php'; 43 - $this->mailer = new PHPMailer($use_exceptions = true); 44 - $this->mailer->CharSet = 'utf-8'; 45 - 46 - $encoding = $this->getOption('encoding'); 47 - $this->mailer->Encoding = $encoding; 48 - 49 - // By default, PHPMailer sends one mail per recipient. We handle 50 - // combining or separating To and Cc higher in the stack, so tell it to 51 - // send mail exactly like we ask. 52 - $this->mailer->SingleTo = false; 53 - 54 - $mailer = $this->getOption('mailer'); 55 - if ($mailer == 'smtp') { 56 - $this->mailer->IsSMTP(); 57 - $this->mailer->Host = $this->getOption('host'); 58 - $this->mailer->Port = $this->getOption('port'); 59 - $user = $this->getOption('user'); 60 - if ($user) { 61 - $this->mailer->SMTPAuth = true; 62 - $this->mailer->Username = $user; 63 - $this->mailer->Password = $this->getOption('password'); 64 - } 65 - 66 - $protocol = $this->getOption('protocol'); 67 - if ($protocol) { 68 - $protocol = phutil_utf8_strtolower($protocol); 69 - $this->mailer->SMTPSecure = $protocol; 70 - } 71 - } else if ($mailer == 'sendmail') { 72 - $this->mailer->IsSendmail(); 73 - } else { 74 - // Do nothing, by default PHPMailer send message using PHP mail() 75 - // function. 76 - } 77 - } 78 - 79 - public function supportsMessageIDHeader() { 80 - return true; 81 - } 82 - 83 - public function setFrom($email, $name = '') { 84 - $this->mailer->SetFrom($email, $name, $crazy_side_effects = false); 85 - return $this; 86 - } 87 - 88 - public function addReplyTo($email, $name = '') { 89 - $this->mailer->AddReplyTo($email, $name); 90 - return $this; 91 - } 92 - 93 - public function addTos(array $emails) { 94 - foreach ($emails as $email) { 95 - $this->mailer->AddAddress($email); 96 - } 97 - return $this; 98 - } 99 - 100 - public function addCCs(array $emails) { 101 - foreach ($emails as $email) { 102 - $this->mailer->AddCC($email); 103 - } 104 - return $this; 105 - } 106 - 107 - public function addAttachment($data, $filename, $mimetype) { 108 - $this->mailer->AddStringAttachment( 109 - $data, 110 - $filename, 111 - 'base64', 112 - $mimetype); 113 - return $this; 114 - } 115 - 116 - public function addHeader($header_name, $header_value) { 117 - if (strtolower($header_name) == 'message-id') { 118 - $this->mailer->MessageID = $header_value; 119 - } else { 120 - $this->mailer->AddCustomHeader($header_name.': '.$header_value); 121 - } 122 - return $this; 123 - } 124 - 125 - public function setBody($body) { 126 - $this->mailer->IsHTML(false); 127 - $this->mailer->Body = $body; 128 - return $this; 129 - } 130 - 131 - public function setHTMLBody($html_body) { 132 - $this->mailer->IsHTML(true); 133 - $this->mailer->Body = $html_body; 134 - return $this; 135 - } 136 - 137 - public function setSubject($subject) { 138 - $this->mailer->Subject = $subject; 139 - return $this; 140 - } 141 - 142 - public function hasValidRecipients() { 143 - return true; 144 - } 145 - 146 - public function send() { 147 - return $this->mailer->Send(); 148 - } 149 - 150 - }
+1 -1
src/applications/metamta/adapter/PhabricatorMailPHPMailerLiteAdapter.php src/applications/metamta/adapter/PhabricatorMailSendmailAdapter.php
··· 5 5 * 6 6 * @concrete-extensible 7 7 */ 8 - class PhabricatorMailPHPMailerLiteAdapter 8 + class PhabricatorMailSendmailAdapter 9 9 extends PhabricatorMailAdapter { 10 10 11 11 const ADAPTERTYPE = 'sendmail';
+154
src/applications/metamta/adapter/PhabricatorMailSMTPAdapter.php
··· 1 + <?php 2 + 3 + final class PhabricatorMailSMTPAdapter 4 + extends PhabricatorMailAdapter { 5 + 6 + const ADAPTERTYPE = 'smtp'; 7 + 8 + public function getSupportedMessageTypes() { 9 + return array( 10 + PhabricatorMailEmailMessage::MESSAGETYPE, 11 + ); 12 + } 13 + 14 + public function supportsMessageIDHeader() { 15 + return true; 16 + } 17 + 18 + protected function validateOptions(array $options) { 19 + PhutilTypeSpec::checkMap( 20 + $options, 21 + array( 22 + 'host' => 'string|null', 23 + 'port' => 'int', 24 + 'user' => 'string|null', 25 + 'password' => 'string|null', 26 + 'protocol' => 'string|null', 27 + )); 28 + } 29 + 30 + public function newDefaultOptions() { 31 + return array( 32 + 'host' => null, 33 + 'port' => 25, 34 + 'user' => null, 35 + 'password' => null, 36 + 'protocol' => null, 37 + ); 38 + } 39 + 40 + /** 41 + * @phutil-external-symbol class PHPMailer 42 + */ 43 + public function sendMessage(PhabricatorMailExternalMessage $message) { 44 + $root = phutil_get_library_root('phabricator'); 45 + $root = dirname($root); 46 + require_once $root.'/externals/phpmailer/class.phpmailer.php'; 47 + $smtp = new PHPMailer($use_exceptions = true); 48 + 49 + $smtp->CharSet = 'utf-8'; 50 + $smtp->Encoding = 'base64'; 51 + 52 + // By default, PHPMailer sends one mail per recipient. We handle 53 + // combining or separating To and Cc higher in the stack, so tell it to 54 + // send mail exactly like we ask. 55 + $smtp->SingleTo = false; 56 + 57 + $smtp->IsSMTP(); 58 + $smtp->Host = $this->getOption('host'); 59 + $smtp->Port = $this->getOption('port'); 60 + $user = $this->getOption('user'); 61 + if (strlen($user)) { 62 + $smtp->SMTPAuth = true; 63 + $smtp->Username = $user; 64 + $smtp->Password = $this->getOption('password'); 65 + } 66 + 67 + $protocol = $this->getOption('protocol'); 68 + if ($protocol) { 69 + $protocol = phutil_utf8_strtolower($protocol); 70 + $smtp->SMTPSecure = $protocol; 71 + } 72 + 73 + $subject = $message->getSubject(); 74 + if ($subject !== null) { 75 + $smtp->Subject = $subject; 76 + } 77 + 78 + $from_address = $message->getFromAddress(); 79 + if ($from_address) { 80 + $smtp->SetFrom( 81 + $from_address->getAddress(), 82 + (string)$from_address->getDisplayName(), 83 + $crazy_side_effects = false); 84 + } 85 + 86 + $reply_address = $message->getReplyToAddress(); 87 + if ($reply_address) { 88 + $smtp->AddReplyTo( 89 + $reply_address->getAddress(), 90 + (string)$reply_address->getDisplayName()); 91 + } 92 + 93 + $to_addresses = $message->getToAddresses(); 94 + if ($to_addresses) { 95 + foreach ($to_addresses as $address) { 96 + $smtp->AddAddress( 97 + $address->getAddress(), 98 + (string)$address->getDisplayName()); 99 + } 100 + } 101 + 102 + $cc_addresses = $message->getCCAddresses(); 103 + if ($cc_addresses) { 104 + foreach ($cc_addresses as $address) { 105 + $smtp->AddCC( 106 + $address->getAddress(), 107 + (string)$address->getDisplayName()); 108 + } 109 + } 110 + 111 + $headers = $message->getHeaders(); 112 + if ($headers) { 113 + $list = array(); 114 + foreach ($headers as $header) { 115 + $name = $header->getName(); 116 + $value = $header->getValue(); 117 + 118 + if (phutil_utf8_strtolower($name) === 'message-id') { 119 + $smtp->MessageID = $value; 120 + } else { 121 + $smtp->AddCustomHeader("{$name}: {$value}"); 122 + } 123 + } 124 + } 125 + 126 + $text_body = $message->getTextBody(); 127 + if ($text_body !== null) { 128 + $smtp->Body = $text_body; 129 + } 130 + 131 + $html_body = $message->getHTMLBody(); 132 + if ($html_body !== null) { 133 + $smtp->IsHTML(true); 134 + $smtp->Body = $html_body; 135 + if ($text_body !== null) { 136 + $smtp->AltBody = $text_body; 137 + } 138 + } 139 + 140 + $attachments = $message->getAttachments(); 141 + if ($attachments) { 142 + foreach ($attachments as $attachment) { 143 + $smtp->AddStringAttachment( 144 + $attachment->getData(), 145 + $attachment->getFilename(), 146 + 'base64', 147 + $attachment->getMimeType()); 148 + } 149 + } 150 + 151 + $smtp->Send(); 152 + } 153 + 154 + }