149 lines
4.9 KiB
PHP
149 lines
4.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/mail/transport/PHPMailerTransport.php
|
|
*
|
|
* Copyright (c) 2014-2022 Simon Fraser University
|
|
* Copyright (c) 2000-2022 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class PHPMailerTransport.php
|
|
*
|
|
* @brief Transport/adapter to send with PHPMailer
|
|
*/
|
|
|
|
namespace PKP\mail\transport;
|
|
|
|
use APP\core\Application;
|
|
use Exception;
|
|
use PHPMailer\PHPMailer\PHPMailer;
|
|
use PKP\core\PKPString;
|
|
use ReflectionObject;
|
|
use Symfony\Component\Mailer\Envelope;
|
|
use Symfony\Component\Mailer\SentMessage;
|
|
use Symfony\Component\Mailer\Transport\TransportInterface;
|
|
use Symfony\Component\Mime\Email;
|
|
use Symfony\Component\Mime\RawMessage;
|
|
|
|
class PHPMailerTransport implements TransportInterface
|
|
{
|
|
public const MAIL_WRAP = 76;
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function send(RawMessage $symfonyMessage, Envelope $envelope = null): ?SentMessage
|
|
{
|
|
if (!($symfonyMessage instanceof Email)) {
|
|
throw new Exception('Can\'t send raw message with phpmailer');
|
|
}
|
|
|
|
$phpmailerMessage = $this->getPHPMailerMessage($symfonyMessage);
|
|
try {
|
|
$success = $phpmailerMessage->Send();
|
|
if (!$success) {
|
|
error_log($phpmailerMessage->ErrorInfo);
|
|
return null;
|
|
}
|
|
} catch (Exception $e) {
|
|
error_log($phpmailerMessage->ErrorInfo);
|
|
return null;
|
|
}
|
|
|
|
return new SentMessage($symfonyMessage, $envelope ?? Envelope::create($symfonyMessage));
|
|
}
|
|
|
|
public function __toString(): string
|
|
{
|
|
return 'phpmailer';
|
|
}
|
|
|
|
/**
|
|
* We won't send symfony message; transfer data to PHPMailer to send with mail()
|
|
*
|
|
* @throws Exception
|
|
*/
|
|
protected function getPHPMailerMessage(Email $symfonyMessage): PHPMailer
|
|
{
|
|
$mailer = new PHPMailer();
|
|
$mailer->isMail();
|
|
$mailer->IsHTML();
|
|
$mailer->Encoding = PHPMailer::ENCODING_BASE64;
|
|
$mailer->CharSet = $symfonyMessage->getHtmlCharset() ?? 'utf-8';
|
|
$mailer->XMailer = 'Public Knowledge Project Suite v3';
|
|
$mailer->WordWrap = static::MAIL_WRAP;
|
|
|
|
$request = Application::get()->getRequest();
|
|
$fromAddresses = $symfonyMessage->getFrom();
|
|
if (!empty($fromAddresses)) {
|
|
$f = array_shift($fromAddresses);
|
|
if (!empty($fromAddresses)) {
|
|
throw new Exception('Can\'t set multiple From email field value with PHPMailer');
|
|
}
|
|
$mailer->setFrom($f->getAddress(), $f->getName());
|
|
}
|
|
// Set the envelope sender (RFC5321.MailFrom)
|
|
if (($s = $symfonyMessage->getSender()) != null) {
|
|
$mailer->Sender = $s->toString();
|
|
}
|
|
foreach ($symfonyMessage->getReplyTo() as $r) {
|
|
$mailer->addReplyTo($r->getAddress(), $r->getName());
|
|
}
|
|
foreach ($symfonyMessage->getTo() as $recipientInfo) {
|
|
$mailer->addAddress($recipientInfo->getAddress(), $recipientInfo->getName());
|
|
}
|
|
foreach ($symfonyMessage->getCc() as $ccInfo) {
|
|
$mailer->addCC($ccInfo->getAddress(), $ccInfo->getName());
|
|
}
|
|
foreach ($symfonyMessage->getBcc() as $bccInfo) {
|
|
$mailer->addBCC($bccInfo->getAddress(), $bccInfo->getName());
|
|
}
|
|
$mailer->Subject = $symfonyMessage->getSubject();
|
|
$mailer->Body = $symfonyMessage->getHtmlBody();
|
|
$mailer->AltBody = PKPString::html2text($symfonyMessage->getHtmlBody());
|
|
|
|
$remoteAddr = $mailer->secureHeader($request->getRemoteAddr());
|
|
if ($remoteAddr != '') {
|
|
$mailer->addCustomHeader("X-Originating-IP: {$remoteAddr}");
|
|
}
|
|
|
|
foreach ($this->getAttachments($symfonyMessage) as $attachmentInfo) {
|
|
$mailer->addStringAttachment(
|
|
$attachmentInfo['body'],
|
|
$attachmentInfo['filename'],
|
|
PHPMailer::ENCODING_BASE64,
|
|
$attachmentInfo['mediaType'] . '/' . $attachmentInfo['subtype']
|
|
);
|
|
}
|
|
|
|
return $mailer;
|
|
}
|
|
|
|
/**
|
|
* Retrieve Symfony Message's assignments
|
|
*/
|
|
protected function getAttachments(Email $message): array
|
|
{
|
|
$attachments = [];
|
|
foreach ($message->getAttachments() as $dataPart) {
|
|
$reflection = new ReflectionObject($dataPart);
|
|
$attachment = [];
|
|
foreach ($reflection->getProperties() as $property) {
|
|
switch ($property->getName()) {
|
|
case 'filename':
|
|
case 'mediaType':
|
|
$property->setAccessible(true);
|
|
$attachment[$property->getName()] = $property->getValue($dataPart);
|
|
break;
|
|
}
|
|
}
|
|
|
|
$attachment['subtype'] = $dataPart->getMediaSubtype();
|
|
$attachment['body'] = $dataPart->getBody();
|
|
$attachments[] = $attachment;
|
|
}
|
|
|
|
return $attachments;
|
|
}
|
|
}
|