Files
piratepoet/mailpoet/lib/Mailer/WordPress/WordPressMailer.php
Rodrigo Primo 5a85390655 Replace remaining calls to utf8_encode() with mb_convert_encoding()
In the previous commit, I removed all calls to the deprecated
utf8_encode() that seemed safe to remove. In this commit, I'm replacing
the calls to this function that I'm not sure if are same to remove or
not with mb_convert_encoding().

mb_convert_encoding() requires the extension mbstring to be enabled. It
should be enabled on most PHP install but not all. We are already using
mbstring functions in our code base and we provide a polyfill for PHP
installs where the extension is not enabled
(62bb75ed91/mailpoet/prefixer/composer.json (L25)).
So it should be safe to use it.

[MAILPOET-4865]
2023-04-28 10:26:03 +02:00

127 lines
4.3 KiB
PHP

<?php // phpcs:ignore SlevomatCodingStandard.TypeHints.DeclareStrictTypes.DeclareStrictTypesMissing
namespace MailPoet\Mailer\WordPress;
use MailPoet\Mailer\MailerFactory;
use MailPoet\Mailer\MetaInfo;
use MailPoet\Subscribers\SubscribersRepository;
use MailPoetVendor\Html2Text\Html2Text;
use PHPMailer\PHPMailer\Exception as PHPMailerException;
use PHPMailer\PHPMailer\PHPMailer;
PHPMailerLoader::load();
class WordPressMailer extends PHPMailer {
/** @var MailerFactory */
private $mailerFactory;
/** @var MetaInfo */
private $mailerMetaInfo;
/** @var SubscribersRepository */
private $subscribersRepository;
public function __construct(
MailerFactory $mailerFactory,
MetaInfo $mailerMetaInfo,
SubscribersRepository $subscribersRepository
) {
parent::__construct(true);
$this->mailerFactory = $mailerFactory;
$this->mailerMetaInfo = $mailerMetaInfo;
$this->subscribersRepository = $subscribersRepository;
}
public function send() {
// We need this so that the PHPMailer class will correctly prepare all the headers.
$originalMailer = $this->Mailer; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
$this->Mailer = 'mail'; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
// Prepare everything (including the message) for sending.
$this->preSend();
$email = $this->getEmail();
$address = $this->formatAddress($this->getToAddresses());
$subscriber = $this->subscribersRepository->findOneBy(['email' => $address]);
$extraParams = [
'meta' => $this->mailerMetaInfo->getWordPressTransactionalMetaInfo($subscriber),
];
try {
// we need to build fresh mailer for every single WP e-mail to make sure reply-to is set
$replyTo = $this->getReplyToAddress();
$mailer = $this->mailerFactory->buildMailer(null, null, $replyTo);
$result = $mailer->send($email, $address, $extraParams);
if (!$result['response']) {
throw new \Exception($result['error']->getMessage());
}
} catch (\Exception $ePrimary) {
// In case the sending using MailPoet's mailer fails continue with sending using original parent PHPMailer::sent method.
// But if anything fails we still want tho throw the error from the primary MailPoet mailer.
try {
// Restore original settings for mailer. Some sites may use SMTP and we needed to reset it to mail
$this->Mailer = $originalMailer; // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
return parent::send();
} catch (\Exception $eFallback) {
throw new PHPMailerException($ePrimary->getMessage(), $ePrimary->getCode(), $ePrimary);
}
}
return true;
}
private function getEmail() {
// phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
$email = [
'subject' => $this->Subject,
'body' => [],
];
if (strpos($this->ContentType, 'text/plain') === 0) {
$email['body']['text'] = $this->Body;
} elseif (strpos($this->ContentType, 'text/html') === 0) {
$text = @Html2Text::convert(strtolower($this->CharSet) === 'utf-8' ? $this->Body : mb_convert_encoding($this->Body, 'UTF-8', mb_list_encodings()));
$email['body']['text'] = $text;
$email['body']['html'] = $this->Body;
} elseif (strpos($this->ContentType, 'multipart/alternative') === 0) {
$email['body']['text'] = $this->AltBody;
$email['body']['html'] = $this->Body;
} else {
throw new PHPMailerException('Unsupported email content type has been used. Please use only text or HTML emails.');
}
return $email;
// phpcs:enable
}
private function formatAddress($wordpressAddress) {
$data = $wordpressAddress[0];
$result = [
'address' => $data[0],
];
if (!empty($data[1])) {
$result['full_name'] = $data[1];
}
return $result;
}
private function getReplyToAddress(): ?array {
$replyToAddress = null;
$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;
}
}