Skip to content
Snippets Groups Projects
Commit 9f40ca7b authored by Demian Katz's avatar Demian Katz Committed by Robert Lange
Browse files

allow multipart messages in mails (#1610)


Co-authored-by: default avatarRobert Lange <robert.lange@uni-leipzig.de>
parent cd766e4f
No related merge requests found
......@@ -32,6 +32,9 @@ use Laminas\Mail\AddressList;
use Laminas\Mail\Header\ContentType;
use Laminas\Mail\Message;
use Laminas\Mail\Transport\TransportInterface;
use Laminas\Mime\Message as MimeMessage;
use Laminas\Mime\Mime;
use Laminas\Mime\Part as MimePart;
use VuFind\Exception\Mail as MailException;
/**
......@@ -89,17 +92,16 @@ class Mailer implements \VuFind\I18n\Translator\TranslatorAwareInterface
}
/**
* Get a blank email message object.
* Get a text email message object.
*
* @return Message
*/
public function getNewMessage()
{
$message = new Message();
$message->setEncoding('UTF-8');
$message = $this->getNewBlankMessage();
$headers = $message->getHeaders();
$ctype = new ContentType();
$ctype->setType('text/plain');
$ctype->setType(Mime::TYPE_TEXT);
$ctype->addParameter('charset', 'UTF-8');
$headers->addHeader($ctype);
return $message;
......@@ -120,6 +122,18 @@ class Mailer implements \VuFind\I18n\Translator\TranslatorAwareInterface
return $this;
}
/**
* Get a blank email message object.
*
* @return Message
*/
public function getNewBlankMessage()
{
$message = new Message();
$message->setEncoding('UTF-8');
return $message;
}
/**
* Set the mail transport object.
*
......@@ -152,6 +166,47 @@ class Mailer implements \VuFind\I18n\Translator\TranslatorAwareInterface
return $list;
}
/**
* Constructs a {@see MimeMessage} body from given text and html content.
*
* @param string|null $text Mail content used for plain text part
* @param string|null $html Mail content used for html part
*
* @return MimeMessage
*/
public function buildMultipartBody(
string $text = null,
string $html = null
): MimeMessage {
$parts = new MimeMessage();
if ($text) {
$textPart = new MimePart($text);
$textPart->setType(Mime::TYPE_TEXT);
$textPart->setCharset('utf-8');
$textPart->setEncoding(Mime::ENCODING_QUOTEDPRINTABLE);
$parts->addPart($textPart);
}
if ($html) {
$htmlPart = new MimePart($html);
$htmlPart->setType(Mime::TYPE_HTML);
$htmlPart->setCharset('utf-8');
$htmlPart->setEncoding(Mime::ENCODING_QUOTEDPRINTABLE);
$parts->addPart($htmlPart);
}
$alternativePart = new MimePart($parts->generateMessage());
$alternativePart->setType('multipart/alternative');
$alternativePart->setBoundary($parts->getMime()->boundary());
$alternativePart->setCharset('utf-8');
$body = new MimeMessage();
$body->setParts([$alternativePart]);
return $body;
}
/**
* Send an email message.
*
......@@ -159,7 +214,7 @@ class Mailer implements \VuFind\I18n\Translator\TranslatorAwareInterface
* delimited list)
* @param string|Address $from Sender name and email address
* @param string $subject Subject line for message
* @param string $body Message body
* @param string|MimeMessage $body Message body
* @param string $cc CC recipient (null for none)
* @param string|Address|AddressList $replyTo Reply-To address (or delimited
* list, null for none)
......@@ -220,8 +275,10 @@ class Mailer implements \VuFind\I18n\Translator\TranslatorAwareInterface
// Convert all exceptions thrown by mailer into MailException objects:
try {
// Send message
$message = $this->getNewMessage()
->addFrom($from)
$message = $body instanceof MimeMessage
? $this->getNewBlankMessage()
: $this->getNewMessage();
$message->addFrom($from)
->addTo($recipients)
->setBody($body)
->setSubject($subject);
......
......@@ -426,6 +426,33 @@ class MailerTest extends \VuFindTest\Unit\TestCase
$mailer = new Mailer($transport);
$mailer->resetConnection();
}
/**
* Test sending an email using with text part and html part and multipart content type.
*
* @return void
* @throws \VuFind\Exception\Mail
*/
public function testSendMimeMessageWithMultipartAlternativeContentType()
{
$this->html = '<!DOCTYPE html><head><title>html</title></head><body>html body part</body></html>';
$this->text = 'this is the text part';
$callback = function ($message) {
$fromString = $message->getFrom()->current()->toString();
return '<to@example.com>' == $message->getTo()->current()->toString()
&& 'Sender TextName <from@example.com>' == $fromString
&& 'subject' == $message->getSubject()
&& 0 <= strpos($message->getBody()->getParts()[0]->getContent(), $this->html)
&& 0 <= strpos($message->getBody()->getParts()[0]->getContent(), $this->text)
&& 'multipart/alternative' == $message->getHeaders()->get('Content-Type')->getType();
};
$transport = $this->createMock(\Laminas\Mail\Transport\TransportInterface::class);
$transport->expects($this->once())->method('send')->with($this->callback($callback));
$address = new Address('from@example.com', 'Sender TextName');
$mailer = new Mailer($transport);
$body = $mailer->buildMultipartBody($this->text, $this->html);
$mailer->send('to@example.com', $address, 'subject', $body);
}
}
class MockEmailRenderer extends \Laminas\View\Renderer\PhpRenderer
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment