Fix reply-to address when sending WP e-mails

This commit makes sure that the reply-to set for WP e-mails is
preserved when MailPoet is used to send them. Before this change,
MailPoet would ignore whatever was set for the reply-to field for WP
e-mails and use the same address as the one used for the sender instead.

I'm not super happy with the solution proposed here. I couldn't find an
easy way to simple set the reply-to address in the Mailer class and that
is why I'm calling Mailer::init() inside WordPressMailer.

[MAILPOET-3707]
This commit is contained in:
Rodrigo Primo
2021-08-18 10:30:42 -03:00
committed by Veljko V
parent a53a680e8c
commit f8388c5497
2 changed files with 125 additions and 0 deletions

View File

@@ -51,7 +51,15 @@ class WordPressMailer extends \PHPMailer {
];
$sendWithMailer = function ($mailer) use ($email, $address, $extraParams) {
// we need to call Mailer::init() for every single WP e-mail to make sure reply-to is set
$replyTo = $this->getReplyToAddress();
$mailer->init(false, false, $replyTo);
$result = $mailer->send($email, $address, $extraParams);
// make sure Mailer::init() is called again to clear the reply-to address that was just set if Mailer is used in another context
$mailer->mailerInstance = null;
if (!$result['response']) {
throw new \Exception($result['error']->getMessage());
}
@@ -103,4 +111,25 @@ class WordPressMailer extends \PHPMailer {
}
return $result;
}
private function getReplyToAddress() {
$replyToAddress = false;
$addresses = $this->getReplyToAddresses();
if (!empty($addresses)) {
// only one reply-to address supported by \MailPoet\Mailer
$address = array_shift($addresses);
$replyToAddress = [];
if ($address[1]) {
$replyToAddress['name'] = $address[1];
}
if ($address[0]) {
$replyToAddress['address'] = $address[0];
}
}
return $replyToAddress;
}
}

View File

@@ -6,6 +6,7 @@ use MailPoet\Entities\SubscriberEntity;
use MailPoet\Mailer\Mailer;
use MailPoet\Mailer\MailerError;
use MailPoet\Mailer\MetaInfo;
use MailPoet\Settings\SettingsController;
use MailPoet\Subscribers\SubscribersRepository;
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
@@ -268,6 +269,101 @@ class WordpressMailerTest extends \MailPoetTest {
$wpMailer->send();
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItPreservesWPReplyTo() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->addReplyTo('reply-to@example.com', 'Reply To');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('reply-to@example.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Reply To', $mailer->replyTo['reply_to_name']);
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItSetsSenderAsReplyToWhenReplyToIsNotDefined() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('staff@mailinator.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Sender', $mailer->replyTo['reply_to_name']);
}
/*
* Test for issue https://mailpoet.atlassian.net/browse/MAILPOET-3707
*/
public function testItChangesReplyToEmailOnDifferentCalls() {
list($mailer, $fallbackMailer) = $this->getMailerInstancesForReplyToTests();
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->addReplyTo('reply-to@example.com', 'Reply To');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('reply-to@example.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Reply To', $mailer->replyTo['reply_to_name']);
$wpMailer = new WordPressMailer($mailer, $fallbackMailer, new MetaInfo, $this->subscribersRepository);
$wpMailer->addAddress('email@example.com', 'Full Name');
$wpMailer->From = 'email-from@example.com';
$wpMailer->Body = 'Body';
$wpMailer->send();
$mailer = $this->getPrivateProperty($wpMailer, 'mailer');
$this->assertEquals('staff@mailinator.com', $mailer->replyTo['reply_to_email']);
$this->assertEquals('Sender', $mailer->replyTo['reply_to_name']);
}
private function getMailerInstancesForReplyToTests() {
$settings = SettingsController::getInstance();
$settings->set(
'sender',
[
'name' => 'Sender',
'address' => 'staff@mailinator.com',
]
);
$mailer = new Mailer();
$fallbackMailer = $this->createMock(FallbackMailer::class);
$fallbackMailer->expects($this->never())->method('send');
return [
$mailer,
$fallbackMailer,
];
}
private function getPrivateProperty($object, $property) {
$reflectedClass = new \ReflectionClass($object);
$reflection = $reflectedClass->getProperty($property);
$reflection->setAccessible(true);
return $reflection->getValue($object);
}
public function _after() {
$this->subscribersRepository->truncate();
}