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;
|
||||
|
||||
@ -6,24 +6,34 @@ use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\Methods\Common\BlacklistCheck;
|
||||
use MailPoet\Mailer\Methods\ErrorMappers\AmazonSESMapper;
|
||||
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;
|
||||
/** @var string */
|
||||
public $awsSecretKey;
|
||||
/** @var string */
|
||||
public $awsRegion;
|
||||
/** @var string */
|
||||
public $awsEndpoint;
|
||||
/** @var string */
|
||||
public $awsSigningAlgorithm;
|
||||
/** @var string */
|
||||
public $awsService;
|
||||
/** @var string */
|
||||
public $awsTerminationString;
|
||||
/** @var string */
|
||||
public $hashAlgorithm;
|
||||
/** @var string */
|
||||
public $url;
|
||||
public $sender;
|
||||
public $replyTo;
|
||||
public $returnPath;
|
||||
public $message;
|
||||
/** @var string */
|
||||
public $rawMessage;
|
||||
/** @var string */
|
||||
public $date;
|
||||
/** @var string */
|
||||
public $dateWithoutTime;
|
||||
/** @var string[] */
|
||||
private $availableRegions = [
|
||||
'US East (N. Virginia)' => 'us-east-1',
|
||||
'US East (Ohio)' => 'us-east-2',
|
||||
@ -51,14 +61,10 @@ class AmazonSES implements MailerMethod {
|
||||
'South America (Sao Paulo)' => 'sa-east-1',
|
||||
'AWS GovCloud (US)' => 'us-gov-west-1',
|
||||
];
|
||||
|
||||
/** @var AmazonSESMapper */
|
||||
private $errorMapper;
|
||||
|
||||
/** @var BlacklistCheck */
|
||||
private $blacklist;
|
||||
|
||||
private $wp;
|
||||
protected $errorMapper;
|
||||
/** @var WPFunctions */
|
||||
protected $wp;
|
||||
|
||||
public function __construct(
|
||||
$region,
|
||||
@ -89,6 +95,7 @@ class AmazonSES implements MailerMethod {
|
||||
$this->errorMapper = $errorMapper;
|
||||
$this->wp = new WPFunctions();
|
||||
$this->blacklist = new BlacklistCheck();
|
||||
$this->mailer = $this->buildMailer();
|
||||
}
|
||||
|
||||
public function send($newsletter, $subscriber, $extraParams = []): array {
|
||||
@ -117,57 +124,26 @@ class AmazonSES implements MailerMethod {
|
||||
return Mailer::formatMailerSendSuccessResult();
|
||||
}
|
||||
|
||||
public function buildMailer(): PHPMailer {
|
||||
return new PHPMailer(true);
|
||||
}
|
||||
|
||||
public function getBody($newsletter, $subscriber, $extraParams = []) {
|
||||
$this->message = $this->createMessage($newsletter, $subscriber, $extraParams);
|
||||
$body = [
|
||||
/* Configure mailer and call preSend() method to prepare message */
|
||||
$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',
|
||||
'Version' => '2010-12-01',
|
||||
'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 = []) {
|
||||
$message = (new Swift_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 encodeMessage(string $message) {
|
||||
return base64_encode($message);
|
||||
}
|
||||
|
||||
public function request($newsletter, $subscriber, $extraParams = []) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Mailer\Methods\ErrorMappers;
|
||||
|
||||
@ -6,7 +6,6 @@ use MailPoet\Mailer\Mailer;
|
||||
use MailPoet\Mailer\MailerError;
|
||||
use MailPoet\Mailer\SubscriberError;
|
||||
use MailPoet\WP\Functions as WPFunctions;
|
||||
use MailPoetVendor\Swift_RfcComplianceException;
|
||||
|
||||
class AmazonSESMapper {
|
||||
use BlacklistErrorMapperTrait;
|
||||
@ -16,7 +15,7 @@ class AmazonSESMapper {
|
||||
|
||||
public function getErrorFromException(\Exception $e, $subscriber) {
|
||||
$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;
|
||||
}
|
||||
$subscriberErrors = [new SubscriberError($subscriber, null)];
|
||||
|
@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php declare(strict_types = 1);
|
||||
|
||||
namespace MailPoet\Test\Mailer\Methods;
|
||||
|
||||
@ -102,34 +102,40 @@ class AmazonSESTest extends \MailPoetTest {
|
||||
expect($body['Version'])->equals('2010-12-01');
|
||||
expect($body['Source'])->equals($this->sender['from_name_email']);
|
||||
expect($body['RawMessage.Data'])
|
||||
->equals($this->mailer->encodeMessage($this->mailer->message));
|
||||
->equals($this->mailer->encodeMessage($this->mailer->rawMessage));
|
||||
}
|
||||
|
||||
public function testItCanCreateMessage() {
|
||||
$message = $this->mailer
|
||||
->createMessage($this->newsletter, $this->subscriber, $this->extraParams);
|
||||
expect($message->getTo())
|
||||
->equals(['blackhole@mailpoet.com' => 'Recipient']);
|
||||
expect($message->getFrom())
|
||||
->equals([$this->sender['from_email'] => $this->sender['from_name']]);
|
||||
expect($message->getSender())
|
||||
->equals([$this->sender['from_email'] => null]);
|
||||
expect($message->getReplyTo())
|
||||
->equals([$this->replyTo['reply_to_email'] => $this->replyTo['reply_to_name']]);
|
||||
expect($message->getSubject())
|
||||
->equals($this->newsletter['subject']);
|
||||
expect($message->getBody())
|
||||
->equals($this->newsletter['body']['html']);
|
||||
expect($message->getChildren()[0]->getContentType())
|
||||
->equals('text/plain');
|
||||
expect($message->getHeaders()->get('List-Unsubscribe')->getValue())
|
||||
->equals('<' . $this->extraParams['unsubscribe_url'] . '>');
|
||||
$mailer = $this->mailer->configureMailerWithMessage($this->newsletter, $this->subscriber, $this->extraParams);
|
||||
expect($mailer->CharSet)->equals('UTF-8'); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
expect($mailer->getToAddresses())->equals([[
|
||||
'blackhole@mailpoet.com',
|
||||
'Recipient',
|
||||
]]);
|
||||
expect($mailer->getAllRecipientAddresses())->equals(['blackhole@mailpoet.com' => true]);
|
||||
expect($mailer->From)->equals($this->sender['from_email']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
expect($mailer->FromName)->equals($this->sender['from_name']); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
expect($mailer->getReplyToAddresses())->equals([
|
||||
$this->replyTo['reply_to_email'] => [
|
||||
$this->replyTo['reply_to_email'],
|
||||
$this->replyTo['reply_to_name'],
|
||||
],
|
||||
]);
|
||||
expect($mailer->Sender)->equals($this->returnPath); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
expect($mailer->ContentType)->equals('text/html'); // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
|
||||
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() {
|
||||
$request = $this->mailer->request($this->newsletter, $this->subscriber);
|
||||
// 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);
|
||||
// substitute the message to synchronize hashes
|
||||
$body['RawMessage.Data'] = $rawMessage;
|
||||
@ -230,7 +236,7 @@ class AmazonSESTest extends \MailPoetTest {
|
||||
);
|
||||
expect($result['response'])->false();
|
||||
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() {
|
||||
|
Reference in New Issue
Block a user