Replace Swift_message with PHPMailer

[MAILPOET-4142]
This commit is contained in:
Jan Lysý
2022-05-11 09:37:00 +02:00
committed by Veljko V
parent d7582ede37
commit 0186ddee35
3 changed files with 64 additions and 83 deletions

View File

@ -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 = []) {

View File

@ -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)];

View File

@ -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() {