diff --git a/mailpoet/lib/Mailer/Methods/AmazonSES.php b/mailpoet/lib/Mailer/Methods/AmazonSES.php index d5fb640ce0..d9bf9fa34b 100644 --- a/mailpoet/lib/Mailer/Methods/AmazonSES.php +++ b/mailpoet/lib/Mailer/Methods/AmazonSES.php @@ -1,4 +1,4 @@ - '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.*?)\s<(?P.*?)>!', $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 = []) { diff --git a/mailpoet/lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php b/mailpoet/lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php index a9ddd1e4cd..abc4aca3fd 100644 --- a/mailpoet/lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php +++ b/mailpoet/lib/Mailer/Methods/ErrorMappers/AmazonSESMapper.php @@ -1,4 +1,4 @@ -getMessage(), 'Invalid address') !== false && strpos($e->getMessage(), '(to):') !== false) { $level = MailerError::LEVEL_SOFT; } $subscriberErrors = [new SubscriberError($subscriber, null)]; diff --git a/mailpoet/tests/integration/Mailer/Methods/AmazonSESTest.php b/mailpoet/tests/integration/Mailer/Methods/AmazonSESTest.php index b87ec32bf3..ac2ba7d008 100644 --- a/mailpoet/tests/integration/Mailer/Methods/AmazonSESTest.php +++ b/mailpoet/tests/integration/Mailer/Methods/AmazonSESTest.php @@ -1,4 +1,4 @@ -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', + '', + ]]); } 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() {