Skip to content

Instantly share code, notes, and snippets.

@guweigang
Last active April 21, 2017 05:16
Show Gist options
  • Save guweigang/675a8e995d981de0db08eb48bd92765f to your computer and use it in GitHub Desktop.
Save guweigang/675a8e995d981de0db08eb48bd92765f to your computer and use it in GitHub Desktop.
Postmark Transport for flarum software

Tutorial

  • Thanks to https://github.com/wildbit/swiftmailer-postmark
  • Add PostmarkTransport.php which locate in "flarum/vendor/illuminate/mail/Transport/" and Modify TransportManager.php which locate in "flarum/vendor/illuminate/mail/"
  • In your administration, in email block, setting like this:
    1. Driver: postmark
    2. Encryption: Your-postmark-server-token
    3. Sender: email in Postmark Sender Signatures List

vimdiff

http://bullsoft-static.oss-cn-beijing.aliyuncs.com/plus/image/illuminate_mail_TransportManager_vimdiff.png

VimDiff

<?php
namespace Illuminate\Mail\Transport;
use Swift_Events_EventListener;
use GuzzleHttp\ClientInterface;
use Swift_Mime_Message;
use Swift_Transport;
class PostmarkTransport implements Swift_Transport {
protected $client = null;
protected $version = "Unknown PHP version";
protected $os = "Unknown OS";
/**
* The Postmark Server Token key.
*
* @var string
*/
protected $serverToken;
/**
* Create a new Postmark transport instance.
*
* @param string $serverToken The API token for the server from which you will send mail.
* @return void
*/
public function __construct(ClientInterface $client, $serverToken) {
$this->client = $client;
$this->serverToken = $serverToken;
$this->version = phpversion();
$this->os = PHP_OS;
}
/**
* {@inheritdoc}
*/
public function isStarted() {
return true;
}
/**
* {@inheritdoc}
*/
public function start() {
return true;
}
/**
* {@inheritdoc}
*/
public function stop() {
return true;
}
/**
* {@inheritdoc}
*/
public function send(Swift_Mime_Message $message, &$failedRecipients = null) {
$client = $this->getHttpClient();
$v = $this->version;
$o = $this->os;
return $client->request('POST','https://api.postmarkapp.com/email', [
'headers' => [
'X-Postmark-Server-Token' => $this->serverToken,
'Content-Type' => 'application/json',
'User-Agent' => "swiftmailer-postmark (PHP Version: $v, OS: $o)",
],
'json' => $this->getMessagePayload($message),
'http_errors' => false,
]);
}
/**
* Convert email dictionary with emails and names
* to array of emails with names.
*
* @param array $emails
* @return array
*/
private function convertEmailsArray(array $emails) {
$convertedEmails = array();
foreach ($emails as $email => $name) {
$convertedEmails[] = $name
? '"' . str_replace('"', '\\"', $name) . "\" <{$email}>"
: $email;
}
return $convertedEmails;
}
/**
* Gets MIME parts that match the message type.
* Excludes parts of type \Swift_Mime_Attachment as those
* are handled later.
*
* @param Swift_Mime_Message $message
* @param string $mimeType
* @return Swift_Mime_MimePart
*/
private function getMIMEPart(\Swift_Mime_Message $message, $mimeType) {
foreach ($message->getChildren() as $part) {
if (strpos($part->getContentType(), $mimeType) === 0 && !($part instanceof \Swift_Mime_Attachment)) {
return $part;
}
}
}
/**
* Convert a Swift Mime Message to a Postmark Payload.
*
* @param Swift_Mime_Message $message
* @return object
*/
private function getMessagePayload(Swift_Mime_Message $message) {
$payload = [];
$this->processRecipients($payload, $message);
$this->processMessageParts($payload, $message);
if ($message->getHeaders()) {
$this->processHeaders($payload, $message);
}
return $payload;
}
/**
* Applies the recipients of the message into the API Payload.
*
* @param array $payload
* @param Swift_Mime_Message $message
* @return object
*/
private function processRecipients(&$payload, $message) {
$payload['From'] = join(',', $this->convertEmailsArray($message->getFrom()));
//$payload['From'] = '[email protected]';
$payload['To'] = join(',', $this->convertEmailsArray($message->getTo()));
$payload['Subject'] = $message->getSubject();
if ($cc = $message->getCc()) {
$payload['Cc'] = join(',', $this->convertEmailsArray($cc));
}
if ($reply_to = $message->getReplyTo()) {
$payload['ReplyTo'] = join(',', $this->convertEmailsArray($reply_to));
}
if ($bcc = $message->getBcc()) {
$payload['Bcc'] = join(',', $this->convertEmailsArray($bcc));
}
}
/**
* Applies the message parts and attachments
* into the API Payload.
*
* @param array $payload
* @param Swift_Mime_Message $message
* @return object
*/
private function processMessageParts(&$payload, $message) {
//Get the primary message.
switch ($message->getContentType()) {
case 'text/html':
case 'multipart/alternative':
case 'multipart/mixed':
$payload['HtmlBody'] = $message->getBody();
break;
default:
$payload['TextBody'] = $message->getBody();
break;
}
// Provide an alternate view from the secondary parts.
if ($plain = $this->getMIMEPart($message, 'text/plain')) {
$payload['TextBody'] = $plain->getBody();
}
if ($html = $this->getMIMEPart($message, 'text/html')) {
$payload['HtmlBody'] = $html->getBody();
}
if ($message->getChildren()) {
$payload['Attachments'] = array();
foreach ($message->getChildren() as $attachment) {
if (is_object($attachment) and $attachment instanceof \Swift_Mime_Attachment) {
$a = array(
'Name' => $attachment->getFilename(),
'Content' => base64_encode($attachment->getBody()),
'ContentType' => $attachment->getContentType()
);
if($attachment->getDisposition() != 'attachment' && $attachment->getId() != NULL) {
$a['ContentID'] = 'cid:'.$attachment->getId();
}
$payload['Attachments'][] = $a;
}
}
}
}
/**
* Applies the headers into the API Payload.
*
* @param array $payload
* @param Swift_Mime_Message $message
* @return object
*/
private function processHeaders(&$payload, $message) {
$headers = [];
foreach ($message->getHeaders()->getAll() as $key => $value) {
$fieldName = $value->getFieldName();
$excludedHeaders = ['Subject', 'Content-Type', 'MIME-Version', 'Date'];
if (!in_array($fieldName, $excludedHeaders)) {
if ($value instanceof \Swift_Mime_Headers_UnstructuredHeader ||
$value instanceof \Swift_Mime_Headers_OpenDKIMHeader) {
if($fieldName != 'X-PM-Tag'){
array_push($headers, [
"Name" => $fieldName,
"Value" => $value->getValue(),
]);
}else{
$payload["Tag"] = $value->getValue();
}
} else if ($value instanceof \Swift_Mime_Headers_DateHeader ||
$value instanceof \Swift_Mime_Headers_IdentificationHeader ||
$value instanceof \Swift_Mime_Headers_ParameterizedHeader ||
$value instanceof \Swift_Mime_Headers_PathHeader) {
array_push($headers, [
"Name" => $fieldName,
"Value" => $value->getFieldBody(),
]);
if ($value->getFieldName() == 'Message-ID') {
array_push($headers, [
"Name" => 'X-PM-KeepID',
"Value" => 'true',
]);
}
}
}
}
$payload['Headers'] = $headers;
}
/**
* {@inheritdoc}
*/
public function registerPlugin(Swift_Events_EventListener $plugin) {
//
}
/**
* Get a new HTTP client instance.
*
* @return \GuzzleHttp\Client
*/
protected function getHttpClient() {
return $this->client;
}
/**
* Get the API key being used by the transport.
*
* @return string
*/
public function getServerToken() {
return $this->serverToken;
}
/**
* Set the API Server Token being used by the transport.
*
* @param string $serverToken
* @return void
*/
public function setServerToken($serverToken) {
return $this->serverToken = $serverToken;
}
}
13d12
< use Illuminate\Mail\Transport\PostmarkTransport;
126,134d124
<
< protected function createPostmarkDriver()
< {
< $client = new HttpClient();
< $config = $this->app['config']->get('mail', []);
< $token = $config['encryption'];
< return new PostmarkTransport($client, $token);
< }
<
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment