mirror of
https://github.com/OpenXE-org/OpenXE.git
synced 2024-11-16 04:57:15 +01:00
160 lines
5.6 KiB
PHP
160 lines
5.6 KiB
PHP
|
<?php
|
||
|
|
||
|
declare(strict_types=1);
|
||
|
|
||
|
namespace Xentral\Components\MailClient\Client;
|
||
|
|
||
|
use Laminas\Mail\Header\ContentType;
|
||
|
use Laminas\Mail\Header\MessageId;
|
||
|
use Laminas\Mail\Message;
|
||
|
use Laminas\Mime\Message as MimeMessage;
|
||
|
use Laminas\Mime\Mime;
|
||
|
use Laminas\Mime\Part;
|
||
|
use Xentral\Components\MailClient\Exception\InvalidArgumentException;
|
||
|
use Xentral\Components\MailClient\Exception\MessageFormatException;
|
||
|
use Xentral\Components\Mailer\Data\EmailMessage;
|
||
|
use Xentral\Components\Mailer\Data\EmailRecipient;
|
||
|
use Xentral\Components\Mailer\Data\FileAttachment;
|
||
|
use Xentral\Components\Mailer\Data\ImageAttachment;
|
||
|
use Xentral\Components\Mailer\Data\StringAttachment;
|
||
|
|
||
|
final class MimeMessageFormatter implements MimeMessageFormatterInterface
|
||
|
{
|
||
|
/**
|
||
|
* @param EmailMessage $email
|
||
|
* @param EmailRecipient $from
|
||
|
* @param string|null $messageId
|
||
|
*
|
||
|
* @throws MessageFormatException
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
public function formatMessage(EmailMessage $email, EmailRecipient $from, string $messageId = null): string
|
||
|
{
|
||
|
if ($messageId !== null && !preg_match('/^<.*@.*>$/', $messageId)) {
|
||
|
throw new InvalidArgumentException('message id must be RFC 5322 conform');
|
||
|
}
|
||
|
$message = new Message();
|
||
|
$message->setEncoding('UTF-8');
|
||
|
$message->addFrom($from->getEmail(), $from->getName());
|
||
|
foreach ($email->getRecipients() as $recipient) {
|
||
|
$message->addTo($recipient->getEmail(), $recipient->getName());
|
||
|
}
|
||
|
foreach ($email->getCcRecipients() as $recipient) {
|
||
|
$message->addCc($recipient->getEmail(), $recipient->getName());
|
||
|
}
|
||
|
foreach ($email->getBccRecipients() as $recipient) {
|
||
|
$message->addBcc($recipient->getEmail(), $recipient->getName());
|
||
|
}
|
||
|
$message->setSubject($email->getSubject());
|
||
|
$message->addReplyTo($from->getEmail(), $from->getName());
|
||
|
$idHeader = new MessageId();
|
||
|
$idHeader->setId($messageId);
|
||
|
$message->getHeaders()->addHeader($idHeader);
|
||
|
$body = $this->createMessageBody($email);
|
||
|
$message->setBody($body);
|
||
|
|
||
|
$contentType = null;
|
||
|
if (count($email->getAttachments()) > 0) {
|
||
|
$contentType = Mime::MULTIPART_RELATED;
|
||
|
}
|
||
|
if (count($email->getAttachments()) === 0 && $email->isHtml()) {
|
||
|
$contentType = Mime::MULTIPART_ALTERNATIVE;
|
||
|
}
|
||
|
if ($contentType !== null) {
|
||
|
/** @var ContentType $contentTypeHeader */
|
||
|
$contentTypeHeader = $message->getHeaders()->get('Content-Type');
|
||
|
$contentTypeHeader->setType($contentType);
|
||
|
}
|
||
|
|
||
|
return $message->toString();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param EmailMessage $email
|
||
|
*
|
||
|
* @return MimeMessage
|
||
|
*/
|
||
|
private function createMessageBody(EmailMessage $email): MimeMessage
|
||
|
{
|
||
|
$textParts = [];
|
||
|
if (!$email->isHtml()) {
|
||
|
$plainText = $email->getBody();
|
||
|
} else {
|
||
|
$plainText = $this->convertHtmlToPlainText($email->getBody());
|
||
|
}
|
||
|
$textPart = new Part(Mime::encode($plainText, Mime::ENCODING_8BIT));
|
||
|
$textPart->type = Mime::TYPE_TEXT;
|
||
|
$textPart->charset = 'ISO-8859-1';
|
||
|
$textPart->encoding = Mime::ENCODING_QUOTEDPRINTABLE;
|
||
|
if ($email->isHtml()) {
|
||
|
$htmlPart = new Part($email->getBody());
|
||
|
$htmlPart->type = Mime::TYPE_HTML;
|
||
|
$htmlPart->charset = 'ISO-8859-1';
|
||
|
$htmlPart->encoding = Mime::ENCODING_QUOTEDPRINTABLE;
|
||
|
$textParts[] = $htmlPart;
|
||
|
}
|
||
|
$textParts[] = $textPart;
|
||
|
$attachmentParts = [];
|
||
|
foreach ($email->getAttachments() as $attachment) {
|
||
|
$contentStream = null;
|
||
|
$disposition = null;
|
||
|
switch (get_class($attachment)) {
|
||
|
case FileAttachment::class:
|
||
|
$content = file_get_contents($attachment->getPath());
|
||
|
$disposition = Mime::DISPOSITION_ATTACHMENT;
|
||
|
break;
|
||
|
|
||
|
case StringAttachment::class:
|
||
|
/** @var StringAttachment $attachment */
|
||
|
$content = $attachment->getContent();
|
||
|
$disposition = Mime::DISPOSITION_ATTACHMENT;
|
||
|
break;
|
||
|
|
||
|
case ImageAttachment::class:
|
||
|
$content = file_get_contents($attachment->getPath());
|
||
|
$disposition = Mime::DISPOSITION_INLINE;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
throw new MessageFormatException(
|
||
|
sprintf('unrecognized attachment class "%s"', get_class($attachment))
|
||
|
);
|
||
|
}
|
||
|
$part = new Part($content);
|
||
|
$part->disposition = $disposition;
|
||
|
$part->type = $attachment->getType();
|
||
|
$part->filename = $attachment->getName();
|
||
|
$part->encoding = $attachment->getEncoding();
|
||
|
$attachmentParts[] = $part;
|
||
|
}
|
||
|
$attachmentParts = array_merge($textParts, $attachmentParts);
|
||
|
$body = new MimeMessage();
|
||
|
$body->setParts($attachmentParts);
|
||
|
|
||
|
return $body;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $html
|
||
|
*
|
||
|
* @return string
|
||
|
*/
|
||
|
private function convertHtmlToPlainText(string $html): string
|
||
|
{
|
||
|
return html_entity_decode(
|
||
|
trim(
|
||
|
strip_tags(
|
||
|
preg_replace(
|
||
|
'/<(head|title|style|script)[^>]*>.*?<\/\\1>/si',
|
||
|
'',
|
||
|
$html
|
||
|
)
|
||
|
)
|
||
|
),
|
||
|
ENT_QUOTES,
|
||
|
'iso-8859-1'
|
||
|
);
|
||
|
}
|
||
|
}
|