Replace Swift_message with PHPMailer
[MAILPOET-4142]
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
namespace MailPoet\Mailer\Methods;
|
namespace MailPoet\Mailer\Methods;
|
||||||
|
|
||||||
@ -6,24 +6,34 @@ use MailPoet\Mailer\Mailer;
|
|||||||
use MailPoet\Mailer\Methods\Common\BlacklistCheck;
|
use MailPoet\Mailer\Methods\Common\BlacklistCheck;
|
||||||
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Swift_Message;
|
use PHPMailer\PHPMailer\PHPMailer;
|
||||||
|
|
||||||
class AmazonSES implements MailerMethod {
|
class AmazonSES extends PHPMailerMethod {
|
||||||
|
/** @var string */
|
||||||
public $awsAccessKey;
|
public $awsAccessKey;
|
||||||
|
/** @var string */
|
||||||
public $awsSecretKey;
|
public $awsSecretKey;
|
||||||
|
/** @var string */
|
||||||
public $awsRegion;
|
public $awsRegion;
|
||||||
|
/** @var string */
|
||||||
public $awsEndpoint;
|
public $awsEndpoint;
|
||||||
|
/** @var string */
|
||||||
public $awsSigningAlgorithm;
|
public $awsSigningAlgorithm;
|
||||||
|
/** @var string */
|
||||||
public $awsService;
|
public $awsService;
|
||||||
|
/** @var string */
|
||||||
public $awsTerminationString;
|
public $awsTerminationString;
|
||||||
|
/** @var string */
|
||||||
public $hashAlgorithm;
|
public $hashAlgorithm;
|
||||||
|
/** @var string */
|
||||||
public $url;
|
public $url;
|
||||||
public $sender;
|
/** @var string */
|
||||||
public $replyTo;
|
public $rawMessage;
|
||||||
public $returnPath;
|
/** @var string */
|
||||||
public $message;
|
|
||||||
public $date;
|
public $date;
|
||||||
|
/** @var string */
|
||||||
public $dateWithoutTime;
|
public $dateWithoutTime;
|
||||||
|
/** @var string[] */
|
||||||
private $availableRegions = [
|
private $availableRegions = [
|
||||||
'US East (N. Virginia)' => 'us-east-1',
|
'US East (N. Virginia)' => 'us-east-1',
|
||||||
'US East (Ohio)' => 'us-east-2',
|
'US East (Ohio)' => 'us-east-2',
|
||||||
@ -51,14 +61,10 @@ class AmazonSES implements MailerMethod {
|
|||||||
'South America (Sao Paulo)' => 'sa-east-1',
|
'South America (Sao Paulo)' => 'sa-east-1',
|
||||||
'AWS GovCloud (US)' => 'us-gov-west-1',
|
'AWS GovCloud (US)' => 'us-gov-west-1',
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var AmazonSESMapper */
|
/** @var AmazonSESMapper */
|
||||||
private $errorMapper;
|
protected $errorMapper;
|
||||||
|
/** @var WPFunctions */
|
||||||
/** @var BlacklistCheck */
|
protected $wp;
|
||||||
private $blacklist;
|
|
||||||
|
|
||||||
private $wp;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
$region,
|
$region,
|
||||||
@ -89,6 +95,7 @@ class AmazonSES implements MailerMethod {
|
|||||||
$this->errorMapper = $errorMapper;
|
$this->errorMapper = $errorMapper;
|
||||||
$this->wp = new WPFunctions();
|
$this->wp = new WPFunctions();
|
||||||
$this->blacklist = new BlacklistCheck();
|
$this->blacklist = new BlacklistCheck();
|
||||||
|
$this->mailer = $this->buildMailer();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function send($newsletter, $subscriber, $extraParams = []): array {
|
public function send($newsletter, $subscriber, $extraParams = []): array {
|
||||||
@ -117,57 +124,26 @@ class AmazonSES implements MailerMethod {
|
|||||||
return Mailer::formatMailerSendSuccessResult();
|
return Mailer::formatMailerSendSuccessResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function buildMailer(): PHPMailer {
|
||||||
|
return new PHPMailer(true);
|
||||||
|
}
|
||||||
|
|
||||||
public function getBody($newsletter, $subscriber, $extraParams = []) {
|
public function getBody($newsletter, $subscriber, $extraParams = []) {
|
||||||
$this->message = $this->createMessage($newsletter, $subscriber, $extraParams);
|
/* Configure mailer and call preSend() method to prepare message */
|
||||||
$body = [
|
$mailer = $this->configureMailerWithMessage($newsletter, $subscriber, $extraParams);
|
||||||
|
$mailer->preSend();
|
||||||
|
/* When message is prepared, we can get the raw message */
|
||||||
|
$this->rawMessage = $mailer->getSentMIMEMessage();
|
||||||
|
return [
|
||||||
'Action' => 'SendRawEmail',
|
'Action' => 'SendRawEmail',
|
||||||
'Version' => '2010-12-01',
|
'Version' => '2010-12-01',
|
||||||
'Source' => $this->sender['from_name_email'],
|
'Source' => $this->sender['from_name_email'],
|
||||||
'RawMessage.Data' => $this->encodeMessage($this->message),
|
'RawMessage.Data' => $this->encodeMessage($this->rawMessage),
|
||||||
];
|
];
|
||||||
return $body;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function createMessage($newsletter, $subscriber, $extraParams = []) {
|
public function encodeMessage(string $message) {
|
||||||
$message = (new Swift_Message())
|
return base64_encode($message);
|
||||||
->setTo($this->processSubscriber($subscriber))
|
|
||||||
->setFrom([
|
|
||||||
$this->sender['from_email'] => $this->sender['from_name'],
|
|
||||||
])
|
|
||||||
->setSender($this->sender['from_email'])
|
|
||||||
->setReplyTo([
|
|
||||||
$this->replyTo['reply_to_email'] => $this->replyTo['reply_to_name'],
|
|
||||||
])
|
|
||||||
->setReturnPath($this->returnPath)
|
|
||||||
->setSubject($newsletter['subject']);
|
|
||||||
if (!empty($extraParams['unsubscribe_url'])) {
|
|
||||||
$headers = $message->getHeaders();
|
|
||||||
$headers->addTextHeader('List-Unsubscribe', '<' . $extraParams['unsubscribe_url'] . '>');
|
|
||||||
}
|
|
||||||
if (!empty($newsletter['body']['html'])) {
|
|
||||||
$message = $message->setBody($newsletter['body']['html'], 'text/html');
|
|
||||||
}
|
|
||||||
if (!empty($newsletter['body']['text'])) {
|
|
||||||
$message = $message->addPart($newsletter['body']['text'], 'text/plain');
|
|
||||||
}
|
|
||||||
return $message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function encodeMessage(Swift_Message $message) {
|
|
||||||
return base64_encode($message->toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
public function processSubscriber($subscriber) {
|
|
||||||
preg_match('!(?P<name>.*?)\s<(?P<email>.*?)>!', $subscriber, $subscriberData);
|
|
||||||
if (!isset($subscriberData['email'])) {
|
|
||||||
$subscriberData = [
|
|
||||||
'email' => $subscriber,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
return [
|
|
||||||
$subscriberData['email'] =>
|
|
||||||
(isset($subscriberData['name'])) ? $subscriberData['name'] : '',
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function request($newsletter, $subscriber, $extraParams = []) {
|
public function request($newsletter, $subscriber, $extraParams = []) {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||||
|
|
||||||
@ -6,7 +6,6 @@ use MailPoet\Mailer\Mailer;
|
|||||||
use MailPoet\Mailer\MailerError;
|
use MailPoet\Mailer\MailerError;
|
||||||
use MailPoet\Mailer\SubscriberError;
|
use MailPoet\Mailer\SubscriberError;
|
||||||
use MailPoet\WP\Functions as WPFunctions;
|
use MailPoet\WP\Functions as WPFunctions;
|
||||||
use MailPoetVendor\Swift_RfcComplianceException;
|
|
||||||
|
|
||||||
class AmazonSESMapper {
|
class AmazonSESMapper {
|
||||||
use BlacklistErrorMapperTrait;
|
use BlacklistErrorMapperTrait;
|
||||||
@ -16,7 +15,7 @@ class AmazonSESMapper {
|
|||||||
|
|
||||||
public function getErrorFromException(\Exception $e, $subscriber) {
|
public function getErrorFromException(\Exception $e, $subscriber) {
|
||||||
$level = MailerError::LEVEL_HARD;
|
$level = MailerError::LEVEL_HARD;
|
||||||
if ($e instanceof Swift_RfcComplianceException) {
|
if (strpos($e->getMessage(), 'Invalid address') !== false && strpos($e->getMessage(), '(to):') !== false) {
|
||||||
$level = MailerError::LEVEL_SOFT;
|
$level = MailerError::LEVEL_SOFT;
|
||||||
}
|
}
|
||||||
$subscriberErrors = [new SubscriberError($subscriber, null)];
|
$subscriberErrors = [new SubscriberError($subscriber, null)];
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
<?php
|
<?php declare(strict_types = 1);
|
||||||
|
|
||||||
namespace MailPoet\Test\Mailer\Methods;
|
namespace MailPoet\Test\Mailer\Methods;
|
||||||
|
|
||||||
@ -102,34 +102,40 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
expect($body['Version'])->equals('2010-12-01');
|
expect($body['Version'])->equals('2010-12-01');
|
||||||
expect($body['Source'])->equals($this->sender['from_name_email']);
|
expect($body['Source'])->equals($this->sender['from_name_email']);
|
||||||
expect($body['RawMessage.Data'])
|
expect($body['RawMessage.Data'])
|
||||||
->equals($this->mailer->encodeMessage($this->mailer->message));
|
->equals($this->mailer->encodeMessage($this->mailer->rawMessage));
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanCreateMessage() {
|
public function testItCanCreateMessage() {
|
||||||
$message = $this->mailer
|
$mailer = $this->mailer->configureMailerWithMessage($this->newsletter, $this->subscriber, $this->extraParams);
|
||||||
->createMessage($this->newsletter, $this->subscriber, $this->extraParams);
|
expect($mailer->CharSet)->equals('UTF-8'); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
expect($message->getTo())
|
expect($mailer->getToAddresses())->equals([[
|
||||||
->equals(['blackhole@mailpoet.com' => 'Recipient']);
|
'blackhole@mailpoet.com',
|
||||||
expect($message->getFrom())
|
'Recipient',
|
||||||
->equals([$this->sender['from_email'] => $this->sender['from_name']]);
|
]]);
|
||||||
expect($message->getSender())
|
expect($mailer->getAllRecipientAddresses())->equals(['blackhole@mailpoet.com' => true]);
|
||||||
->equals([$this->sender['from_email'] => null]);
|
expect($mailer->From)->equals($this->sender['from_email']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
expect($message->getReplyTo())
|
expect($mailer->FromName)->equals($this->sender['from_name']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
->equals([$this->replyTo['reply_to_email'] => $this->replyTo['reply_to_name']]);
|
expect($mailer->getReplyToAddresses())->equals([
|
||||||
expect($message->getSubject())
|
$this->replyTo['reply_to_email'] => [
|
||||||
->equals($this->newsletter['subject']);
|
$this->replyTo['reply_to_email'],
|
||||||
expect($message->getBody())
|
$this->replyTo['reply_to_name'],
|
||||||
->equals($this->newsletter['body']['html']);
|
],
|
||||||
expect($message->getChildren()[0]->getContentType())
|
]);
|
||||||
->equals('text/plain');
|
expect($mailer->Sender)->equals($this->returnPath); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
expect($message->getHeaders()->get('List-Unsubscribe')->getValue())
|
expect($mailer->ContentType)->equals('text/html'); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
->equals('<' . $this->extraParams['unsubscribe_url'] . '>');
|
expect($mailer->Subject)->equals($this->newsletter['subject']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
|
expect($mailer->Body)->equals($this->newsletter['body']['html']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
|
expect($mailer->AltBody)->equals($this->newsletter['body']['text']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||||
|
expect($mailer->getCustomHeaders())->equals([[
|
||||||
|
'List-Unsubscribe',
|
||||||
|
'<http://www.mailpoet.com>',
|
||||||
|
]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItCanCreateRequest() {
|
public function testItCanCreateRequest() {
|
||||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||||
// preserve the original message
|
// preserve the original message
|
||||||
$rawMessage = $this->mailer->encodeMessage($this->mailer->message);
|
$rawMessage = $this->mailer->encodeMessage($this->mailer->rawMessage);
|
||||||
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
$body = $this->mailer->getBody($this->newsletter, $this->subscriber);
|
||||||
// substitute the message to synchronize hashes
|
// substitute the message to synchronize hashes
|
||||||
$body['RawMessage.Data'] = $rawMessage;
|
$body['RawMessage.Data'] = $rawMessage;
|
||||||
@ -230,7 +236,7 @@ class AmazonSESTest extends \MailPoetTest {
|
|||||||
);
|
);
|
||||||
expect($result['response'])->false();
|
expect($result['response'])->false();
|
||||||
expect($result['error'])->isInstanceOf(MailerError::class);
|
expect($result['error'])->isInstanceOf(MailerError::class);
|
||||||
expect($result['error']->getMessage())->stringContainsString('does not comply with RFC 2822');
|
expect($result['error']->getMessage())->stringContainsString('Invalid address');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testItChecksBlacklistBeforeSending() {
|
public function testItChecksBlacklistBeforeSending() {
|
||||||
|
Reference in New Issue
Block a user