Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restore full Laravel Mailer behavior #45

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
eedb420
Restore full Laravel Mailer behavior
mjauvin Dec 13, 2020
f56c617
add Mailer tests
mjauvin Dec 14, 2020
7a935be
minor tweaks; add plethora of tests
mjauvin Dec 14, 2020
018b0b2
add a few comments
mjauvin Dec 14, 2020
7ba918d
single line assignment
mjauvin Dec 14, 2020
d88f893
no new line for else block
mjauvin Dec 14, 2020
6bf22a6
simplify setUp()
mjauvin Dec 14, 2020
96ecbb0
tidyup tests a bit
mjauvin Dec 14, 2020
5a93411
missed one
mjauvin Dec 14, 2020
b9d976c
update return type
mjauvin Dec 17, 2020
8ce5c35
use verbose code
mjauvin Dec 17, 2020
7a823e3
Apply suggestions from code review
mjauvin Dec 17, 2020
0fb2bcd
use !is_null() instead of isset()
mjauvin Feb 4, 2021
3ee9045
add default argument values
mjauvin Feb 5, 2021
afb978c
add missing spaces around =
mjauvin Feb 5, 2021
9dfee03
Merge branch 'develop' into restore-laravel-mailer-behavior
mjauvin Mar 17, 2021
d386a41
Add version.yaml processor, update versioning to use this processor
bennothommo Mar 25, 2021
b736df2
Tweaks to version/update unit tests
bennothommo Mar 25, 2021
ec3d477
bail out if the view is not a string template name
mjauvin Mar 25, 2021
925d882
Merge branch 'develop' into restore-laravel-mailer-behavior
mjauvin Mar 25, 2021
a769cd2
Merge branch 'wip/version-yaml-processing' into restore-laravel-maile…
mjauvin Mar 25, 2021
d2f3acf
only work with string template names
mjauvin Mar 25, 2021
fea5826
Merge branch 'develop' into restore-laravel-mailer-behavior
LukeTowers Mar 28, 2021
008213e
Merge branch 'develop' into restore-laravel-mailer-behavior
mjauvin Mar 29, 2021
cfa410d
Merge branch 'develop' into restore-laravel-mailer-behavior
mjauvin Apr 9, 2021
2a007fb
Merge branch 'wip/1.2' into restore-laravel-mailer-behavior
mjauvin Mar 5, 2022
d0a0717
Merge branch 'wip/1.2' into restore-laravel-mailer-behavior
mjauvin Mar 18, 2022
ad9063c
fix tests
mjauvin Mar 18, 2022
0d76369
properly create new Message
mjauvin Mar 18, 2022
e564aa7
must use AbstractPart interface
mjauvin Mar 18, 2022
2fdef70
get content-type header
mjauvin Mar 18, 2022
0db3071
use getHeaders() instead
mjauvin Mar 18, 2022
d6df6d3
use Header::get
mjauvin Mar 18, 2022
1703596
compare body instead
mjauvin Mar 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions modules/system/ServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -357,9 +357,7 @@ protected function registerMailer()
* Override standard Mailer content with template
*/
Event::listen('mailer.beforeAddContent', function ($mailer, $message, $view, $data, $raw, $plain) {
$method = $raw === null ? 'addContentToMailer' : 'addRawContentToMailer';
$plainOnly = $view === null; // When "plain-text only" email is sent, $view is null, this sets the flag appropriately
return !MailManager::instance()->$method($message, $raw ?: $view ?: $plain, $data, $plainOnly);
return !MailManager::instance()->addContent($message, $view, $plain, $raw, $data);
});
}

Expand Down
108 changes: 88 additions & 20 deletions modules/system/classes/MailManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,15 @@ class MailManager
* Same as `addContentToMailer` except with raw content.
*
* @return bool
*
* @deprecated Use addContent() instead
*/
public function addRawContentToMailer($message, $content, $data)
{
$template = new MailTemplate;

$template->fillFromContent($content);
$text = new MailTemplate;
$text->fillFromContent($content);

$this->addContentToMailerInternal($message, $template, $data);
$this->addContentToMailerInternal($message, null, $text, $data);

return true;
}
Expand All @@ -73,6 +74,8 @@ public function addRawContentToMailer($message, $content, $data)
* @param array $data
* @param bool $plainOnly Add only plain text content to the message
* @return bool
*
* @deprecated Use addContent() instead
*/
public function addContentToMailer($message, $code, $data, $plainOnly = false)
{
Expand All @@ -92,21 +95,75 @@ public function addContentToMailer($message, $code, $data, $plainOnly = false)
return false;
}

$this->addContentToMailerInternal($message, $template, $data, $plainOnly);
$html = $text = $template;

if ($plainOnly) {
$html = null;
}
$this->addContentToMailerInternal($message, $html, $text, $data);

return true;
}

/**
* Internal method used to share logic between `addRawContentToMailer` and `addContentToMailer`
* Restore proper behavior in-line with Laravel Mailer
* Replaces both `addContentToMailer` and `addRawContentToMailer`
*
* @param \Illuminate\Mail\Message $message
* @param string $template
* @param string|null $view
* @param string|null $plain
* @param string|null $raw
* @param array $data
* @return bool
*/
public function addContent($message, $view = null, $plain = null, $raw = null, $data = [])
{
$html = $text = null;

// We only handle mail template names as a string, let the caller handle the content if we receive anything else

if (is_string($view)) {
if (isset($this->templateCache[$view])) {
$html = $this->templateCache[$view];
} else {
$this->templateCache[$view] = $html = MailTemplate::findOrMakeTemplate($view);
}
}

if (is_string($plain)) {
if (isset($this->templateCache[$plain])) {
$text = $this->templateCache[$plain];
} else {
$this->templateCache[$plain] = $text = MailTemplate::findOrMakeTemplate($plain);
}
}

// raw content will overwrite plain view content, as done in laravel
if (is_string($raw)) {
$text = new MailTemplate;
$text->fillFromContent($raw);
}

// bailout if we have no content
if (is_null($html) && is_null($text)) {
return false;
}

$this->addContentToMailerInternal($message, $html, $text, $data);

return true;
}

/**
* Internal method used to share logic between `addContent`, `addRawContentToMailer` and `addContentToMailer`
*
* @param \Illuminate\Mail\Message $message
* @param MailTemplate|null $html
* @param MailTemplate|null $text
* @param array $data
* @param bool $plainOnly Add only plain text content to the message
* @return void
*/
protected function addContentToMailerInternal($message, $template, $data, $plainOnly = false)
protected function addContentToMailerInternal($message, $html = null, $text = null, array $data = [])
{
/*
* Inject global view variables
Expand All @@ -122,28 +179,39 @@ protected function addContentToMailerInternal($message, $template, $data, $plain
$symfonyMessage = $message->getSymfonyMessage();

if (empty($symfonyMessage->getSubject())) {
$message->subject($this->renderTwig($template->subject, $data));
if ($html) {
$message->subject($this->renderTwig($html->subject, $data));
} else if ($text) {
$message->subject($this->renderTwig($text->subject, $data));
}
}

$data += [
'subject' => $symfonyMessage->getSubject()
];

if (!$plainOnly) {
/*
* HTML contents
*/
$html = $this->renderTemplate($template, $data);

$message->html($html);
/*
* HTML content
*/
if ($html) {
$message->setBody($this->renderTemplate($html, $data), 'text/html');
if (!$text && $html->content_text) {
$text = $html;
}
}

/*
* Text contents
* Text content
*/
$text = $this->renderTextTemplate($template, $data);
if ($text) {
$method = $html ? 'addPart' : 'setBody';
$message->{$method}($this->renderTextTemplate($text, $data), 'text/plain');
}

$message->text($text);
/*
* End twig transaction
*/
$this->stopTwig();
}

//
Expand Down
112 changes: 112 additions & 0 deletions tests/unit/system/classes/MailManagerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<?php

use Illuminate\Mail\Message;
use System\Classes\MailManager;
use System\Models\MailTemplate;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Part\TextPart;

class MailManagerTest extends PluginTestCase
{

public function setUp() : void
{
parent::setUp();

$this->message = new Message(new Email());

foreach (['html', 'plain'] as $view) {
$t = new MailTemplate();
$t->is_custom = true;
$t->code = "$view-view";
$t->subject = "$view view [{{ mode }}]";
$t->content_html = "my $view view content";
$t->description = "my $view view description";
$t->save();
}
}

//
// Tests
//

public function testAddContent_Html()
{
$plain = $raw = null;
$html = new TextPart('html-view', $subtype="html");
$data = ['mode' => 'test'];

$result = MailManager::instance()->addContent($this->message, $html, $plain, $raw, $data);
$symfonyMessage = $this->message->getSymfonyMessage();

$this->assertEquals($html, $symfonyMessage->getHtmlBody());
$this->assertEquals('html view [test]', $symfonyMessage->getSubject());
}

public function testAddContent_Plain()
{
$html = $raw = null;
$plain = new TextPart('plain-view');
$data = ['mode' => 'test'];

$result = MailManager::instance()->addContent($this->message, $html, $plain, $raw, $data);
$symfonyMessage = $this->message->getSymfonyMessage();

$this->assertTrue($result);
$this->assertEquals($plain, $symfonyMessage->getTextBody());
$this->assertEquals('plain view [test]', $symfonyMessage->getSubject());
}

public function testAddContent_Raw()
{
$html = $plain = null;
$raw = new TextPart('my raw content');
$data = ['mode' => 'test'];

$result = MailManager::instance()->addContent($this->message, $html, $plain, $raw, $data);
$symfonyMessage = $this->message->getSymfonyMessage();

$this->assertTrue($result);
$this->assertEquals('No subject', $symfonyMessage->getSubject());
$this->assertEquals($raw, $symfonyMessage->getBody());
}

public function testAddContent_Html_Plain()
{
$raw = null;
$html = new TextPart('html-view', $subtype="html");
$plain = new TextPart('plain-view');
$data = ['mode' => 'test'];

$result = MailManager::instance()->addContent($this->message, $html, $plain, $raw, $data);
$symfonyMessage = $this->message->getSymfonyMessage();
$parts = $symfonyMessage->getAttachments();

$this->assertTrue($result);
$this->assertEquals('html view [test]', $symfonyMessage->getSubject());
$this->assertEquals($html, $symfonyMessage->getHtmlBody());

$this->assertEquals(1, count($parts));
$this->assertEquals($plain, $symfonyMessage->getTextBody());
}

public function testAddContent_Html_Plain_Raw()
{
$html = new TextPart('html-view', $subtype="html");
$plain = new TextPart('plain-view');
$raw = new TextPart('my raw content');
$data = ['mode' => 'test'];

$result = MailManager::instance()->addContent($this->message, $html, $plain, $raw, $data);
$symfonyMessage = $this->message->getSymfonyMessage();
$parts = $symfonyMessage->getAttachments();

$this->assertTrue($result);
$this->assertEquals('html view [test]', $symfonyMessage->getSubject());
$this->assertEquals($html, $symfonyMessage->getHtmlBody());

$this->assertEquals(1, count($parts));
$this->assertEquals($plain, $symfonyMessage->getTextBody());
$this->assertEquals($raw, $symfonyMessage->getBody());
}
}