@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.

Add a Postmark mail adapter so it can be configured as an outbound mailer

Summary: Depends on D19007. Ref T12677.

Test Plan: Used `bin/mail send-test ... --mailer postmark` to deliver some mail via Postmark.

Reviewers: amckinley

Reviewed By: amckinley

Maniphest Tasks: T12677

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

+165
+2
src/__phutil_library_map__.php
··· 3188 3188 'PhabricatorMailImplementationMailgunAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationMailgunAdapter.php', 3189 3189 'PhabricatorMailImplementationPHPMailerAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerAdapter.php', 3190 3190 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPHPMailerLiteAdapter.php', 3191 + 'PhabricatorMailImplementationPostmarkAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php', 3191 3192 'PhabricatorMailImplementationSendGridAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationSendGridAdapter.php', 3192 3193 'PhabricatorMailImplementationTestAdapter' => 'applications/metamta/adapter/PhabricatorMailImplementationTestAdapter.php', 3193 3194 'PhabricatorMailManagementListInboundWorkflow' => 'applications/metamta/management/PhabricatorMailManagementListInboundWorkflow.php', ··· 8691 8692 'PhabricatorMailImplementationMailgunAdapter' => 'PhabricatorMailImplementationAdapter', 8692 8693 'PhabricatorMailImplementationPHPMailerAdapter' => 'PhabricatorMailImplementationAdapter', 8693 8694 'PhabricatorMailImplementationPHPMailerLiteAdapter' => 'PhabricatorMailImplementationAdapter', 8695 + 'PhabricatorMailImplementationPostmarkAdapter' => 'PhabricatorMailImplementationAdapter', 8694 8696 'PhabricatorMailImplementationSendGridAdapter' => 'PhabricatorMailImplementationAdapter', 8695 8697 'PhabricatorMailImplementationTestAdapter' => 'PhabricatorMailImplementationAdapter', 8696 8698 'PhabricatorMailManagementListInboundWorkflow' => 'PhabricatorMailManagementWorkflow',
+9
src/applications/metamta/adapter/PhabricatorMailImplementationAdapter.php
··· 94 94 return; 95 95 } 96 96 97 + protected function renderAddress($email, $name = null) { 98 + if (strlen($name)) { 99 + // TODO: This needs to be escaped correctly. 100 + return "{$name} <{$email}>"; 101 + } else { 102 + return $email; 103 + } 104 + } 105 + 97 106 }
+112
src/applications/metamta/adapter/PhabricatorMailImplementationPostmarkAdapter.php
··· 1 + <?php 2 + 3 + final class PhabricatorMailImplementationPostmarkAdapter 4 + extends PhabricatorMailImplementationAdapter { 5 + 6 + const ADAPTERTYPE = 'postmark'; 7 + 8 + private $parameters = array(); 9 + 10 + public function setFrom($email, $name = '') { 11 + $this->parameters['From'] = $this->renderAddress($email, $name); 12 + return $this; 13 + } 14 + 15 + public function addReplyTo($email, $name = '') { 16 + $this->parameters['ReplyTo'] = $this->renderAddress($email, $name); 17 + return $this; 18 + } 19 + 20 + public function addTos(array $emails) { 21 + foreach ($emails as $email) { 22 + $this->parameters['To'][] = $email; 23 + } 24 + return $this; 25 + } 26 + 27 + public function addCCs(array $emails) { 28 + foreach ($emails as $email) { 29 + $this->parameters['Cc'][] = $email; 30 + } 31 + return $this; 32 + } 33 + 34 + public function addAttachment($data, $filename, $mimetype) { 35 + $this->parameters['Attachments'][] = array( 36 + 'Name' => $filename, 37 + 'ContentType' => $mimetype, 38 + 'Content' => base64_encode($data), 39 + ); 40 + 41 + return $this; 42 + } 43 + 44 + public function addHeader($header_name, $header_value) { 45 + $this->parameters['Headers'][] = array( 46 + 'Name' => $header_name, 47 + 'Value' => $header_value, 48 + ); 49 + return $this; 50 + } 51 + 52 + public function setBody($body) { 53 + $this->parameters['TextBody'] = $body; 54 + return $this; 55 + } 56 + 57 + public function setHTMLBody($html_body) { 58 + $this->parameters['HtmlBody'] = $html_body; 59 + return $this; 60 + } 61 + 62 + public function setSubject($subject) { 63 + $this->parameters['Subject'] = $subject; 64 + return $this; 65 + } 66 + 67 + public function supportsMessageIDHeader() { 68 + return true; 69 + } 70 + 71 + protected function validateOptions(array $options) { 72 + PhutilTypeSpec::checkMap( 73 + $options, 74 + array( 75 + 'access-token' => 'string', 76 + )); 77 + } 78 + 79 + public function newDefaultOptions() { 80 + return array( 81 + 'access-token' => null, 82 + ); 83 + } 84 + 85 + public function newLegacyOptions() { 86 + return array(); 87 + } 88 + 89 + public function send() { 90 + $access_token = $this->getOption('access-token'); 91 + 92 + $parameters = $this->parameters; 93 + $flatten = array( 94 + 'To', 95 + 'Cc', 96 + ); 97 + 98 + foreach ($flatten as $key) { 99 + if (isset($parameters[$key])) { 100 + $parameters[$key] = implode(', ', $parameters[$key]); 101 + } 102 + } 103 + 104 + id(new PhutilPostmarkFuture()) 105 + ->setAccessToken($access_token) 106 + ->setMethod('email', $parameters) 107 + ->resolve(); 108 + 109 + return true; 110 + } 111 + 112 + }
+20
src/applications/metamta/management/PhabricatorMailManagementSendTestWorkflow.php
··· 48 48 'repeat' => true, 49 49 ), 50 50 array( 51 + 'name' => 'mailer', 52 + 'param' => 'key', 53 + 'help' => pht('Send with a specific configured mailer.'), 54 + ), 55 + array( 51 56 'name' => 'html', 52 57 'help' => pht('Send as HTML mail.'), 53 58 ), ··· 159 164 160 165 if ($from) { 161 166 $mail->setFrom($from->getPHID()); 167 + } 168 + 169 + $mailer_key = $args->getArg('mailer'); 170 + if ($mailer_key !== null) { 171 + $mailers = PhabricatorMetaMTAMail::newMailers(); 172 + $mailers = mpull($mailers, null, 'getKey'); 173 + if (!isset($mailers[$mailer_key])) { 174 + throw new PhutilArgumentUsageException( 175 + pht( 176 + 'Mailer key ("%s") is not configured. Available keys are: %s.', 177 + $mailer_key, 178 + implode(', ', array_keys($mailers)))); 179 + } 180 + 181 + $mail->setTryMailers(array($mailer_key)); 162 182 } 163 183 164 184 foreach ($attach as $attachment) {
+10
src/applications/metamta/storage/PhabricatorMetaMTAMail.php
··· 319 319 return $this->getParam('mailer.key'); 320 320 } 321 321 322 + public function setTryMailers(array $mailers) { 323 + return $this->setParam('mailers.try', $mailers); 324 + } 325 + 322 326 public function setHTMLBody($html) { 323 327 $this->setParam('html-body', $html); 324 328 return $this; ··· 468 472 } 469 473 470 474 $mailers = self::newMailers(); 475 + 476 + $try_mailers = $this->getParam('mailers.try'); 477 + if ($try_mailers) { 478 + $mailers = mpull($mailers, null, 'getKey'); 479 + $mailers = array_select_keys($mailers, $try_mailers); 480 + } 471 481 472 482 return $this->sendWithMailers($mailers); 473 483 }
+12
src/docs/user/configuration/configuring_outbound_email.diviner
··· 12 12 | Send Mail With | Setup | Cost | Inbound | Notes | 13 13 |---------|-------|------|---------|-------| 14 14 | Mailgun | Easy | Cheap | Yes | Recommended | 15 + | Postmark | Easy | Cheap | Yes | Recommended | 15 16 | Amazon SES | Easy | Cheap | No | Recommended | 16 17 | SendGrid | Medium | Cheap | Yes | Discouraged | 17 18 | External SMTP | Medium | Varies | No | Gmail, etc. | ··· 145 146 146 147 - `api-key`: Required string. Your Mailgun API key. 147 148 - `domain`: Required string. Your Mailgun domain. 149 + 150 + 151 + Mailer: Postmark 152 + ================ 153 + 154 + Postmark is a third-party email delivery serivice. You can learn more at 155 + <https://www.postmarkapp.com/>. 156 + 157 + To use this mailer, set `type` to `postmark`, then configure these `options`: 158 + 159 + - `access-token`: Required string. Your Postmark access token. 148 160 149 161 150 162 Mailer: Amazon SES