Skip to content

Commit 3030a37

Browse files
committed
added support for mailables
1 parent 8b76c76 commit 3030a37

File tree

7 files changed

+234
-13
lines changed

7 files changed

+234
-13
lines changed

composer.json

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,6 @@
88
"email": "info@marickvantuil.nl"
99
}
1010
],
11-
"require": {
12-
"illuminate/database": "^5.2",
13-
"illuminate/console": "^5.2",
14-
"illuminate/validation": "^5.2"
15-
},
1611
"autoload": {
1712
"psr-4": {
1813
"Buildcode\\LaravelDatabaseEmails\\": "src/"
@@ -31,8 +26,12 @@
3126
}
3227
},
3328
"require-dev": {
34-
"orchestra/testbench": "~3.4",
35-
"phpunit/phpunit": "^5.7",
36-
"orchestra/database": "~3.4"
29+
"illuminate/database": "^5.5",
30+
"illuminate/console": "^5.5",
31+
"illuminate/validation": "^5.5",
32+
"orchestra/testbench": "^3.5",
33+
"orchestra/database": "^3.5",
34+
"phpunit/phpunit": "^6.0",
35+
"mockery/mockery": "^1.0"
3736
}
3837
}

src/EmailComposer.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace Buildcode\LaravelDatabaseEmails;
44

5+
use Illuminate\Mail\Mailable;
6+
57
class EmailComposer
68
{
79
/**
@@ -45,7 +47,7 @@ public function getEmail()
4547
* @param mixed $value
4648
* @return static
4749
*/
48-
protected function setData($key, $value)
50+
public function setData($key, $value)
4951
{
5052
$this->data[$key] = $value;
5153

@@ -175,6 +177,21 @@ public function later($scheduledAt)
175177
return $this->send();
176178
}
177179

180+
/**
181+
* Set the Mailable.
182+
*
183+
* @param Mailable $mailable
184+
* @return static
185+
*/
186+
public function mailable(Mailable $mailable)
187+
{
188+
$this->setData('mailable', $mailable);
189+
190+
(new MailableReader)->read($this);
191+
192+
return $this;
193+
}
194+
178195
/**
179196
* Send the e-mail.
180197
*

src/Encrypter.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ private function encryptSubject(EmailComposer $composer)
6969
*/
7070
private function encryptVariables(EmailComposer $composer)
7171
{
72+
if (!$composer->hasData('variables')) {
73+
return;
74+
}
75+
7276
$email = $composer->getEmail();
7377

7478
$email->fill([

src/MailableReader.php

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<?php
2+
3+
namespace Buildcode\LaravelDatabaseEmails;
4+
5+
use Exception;
6+
use Illuminate\Mail\Mailable;
7+
8+
class MailableReader
9+
{
10+
/**
11+
* Read the mailable and pass the data to the email composer.
12+
*
13+
* @param EmailComposer $composer
14+
*/
15+
public function read(EmailComposer $composer)
16+
{
17+
$this->readRecipient($composer);
18+
19+
$this->readCc($composer);
20+
21+
$this->readBcc($composer);
22+
23+
$this->readSubject($composer);
24+
25+
$this->readBody($composer);
26+
}
27+
28+
/**
29+
* Convert the mailable addresses array into a array with only e-mails.
30+
*
31+
* @param string $from
32+
* @return array
33+
*/
34+
private function convertMailableAddresses($from)
35+
{
36+
return collect($from)->map(function ($recipient) {
37+
return $recipient['address'];
38+
})->toArray();
39+
}
40+
41+
/**
42+
* Read the mailable recipient to the email composer.
43+
*
44+
* @param EmailComposer $composer
45+
*/
46+
private function readRecipient(EmailComposer $composer)
47+
{
48+
$to = $this->convertMailableAddresses(
49+
$composer->getData('mailable')->to
50+
);
51+
52+
$composer->recipient($to);
53+
}
54+
55+
/**
56+
* Read the mailable cc to the email composer.
57+
*
58+
* @param EmailComposer $composer
59+
*/
60+
private function readCc(EmailComposer $composer)
61+
{
62+
$cc = $this->convertMailableAddresses(
63+
$composer->getData('mailable')->cc
64+
);
65+
66+
$composer->cc($cc);
67+
}
68+
69+
/**
70+
* Read the mailable bcc to the email composer.
71+
*
72+
* @param EmailComposer $composer
73+
*/
74+
private function readBcc(EmailComposer $composer)
75+
{
76+
$bcc = $this->convertMailableAddresses(
77+
$composer->getData('mailable')->bcc
78+
);
79+
80+
$composer->bcc($bcc);
81+
}
82+
83+
/**
84+
* Read the mailable subject to the email composer.
85+
*
86+
* @param EmailComposer $composer
87+
*/
88+
private function readSubject(EmailComposer $composer)
89+
{
90+
$composer->subject($composer->getData('mailable')->subject);
91+
}
92+
93+
/**
94+
* Read the mailable body to the email composer.
95+
*
96+
* @param EmailComposer $composer
97+
* @throws Exception
98+
*/
99+
private function readBody(EmailComposer $composer)
100+
{
101+
if (app()->version() < '5.5') {
102+
throw new Exception('Mailables cannot be read by Laravel 5.4 and below. Sorry.');
103+
}
104+
105+
$composer->setData('view', '');
106+
107+
$composer->setData('body', $composer->getData('mailable')->render());
108+
}
109+
}

src/Preparer.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,17 @@ private function prepareVariables(EmailComposer $composer)
151151
*/
152152
private function prepareBody(EmailComposer $composer)
153153
{
154-
$composer->getEmail()->fill([
155-
'body' => view(
154+
// If the body was predefined (by for example a mailable), use that.
155+
if ($composer->hasData('body')) {
156+
$body = $composer->getData('body');
157+
} else {
158+
$body = view(
156159
$composer->getData('view'),
157160
$composer->hasData('variables') ? $composer->getData('variables') : []
158-
)->render(),
159-
]);
161+
)->render();
162+
}
163+
164+
$composer->getEmail()->fill(compact('body'));
160165
}
161166

162167
/**

src/Validator.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ private function validateSubject(EmailComposer $composer)
133133
*/
134134
private function validateView(EmailComposer $composer)
135135
{
136+
if ($composer->hasData('mailable')) {
137+
return;
138+
}
139+
136140
if (!$composer->hasData('view')) {
137141
throw new InvalidArgumentException('No view specified');
138142
}

tests/MailableReaderTest.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
namespace Tests;
4+
5+
use Buildcode\LaravelDatabaseEmails\Email;
6+
use Illuminate\Mail\Mailable;
7+
8+
class MailableReaderTest extends TestCase
9+
{
10+
/** @test */
11+
function it_extracts_the_recipient()
12+
{
13+
$composer = Email::compose()
14+
->mailable(new TestMailable());
15+
16+
$this->assertEquals(['john@doe.com'], $composer->getData('recipient'));
17+
18+
$composer = Email::compose()
19+
->mailable(
20+
(new TestMailable())->to(['jane@doe.com'])
21+
);
22+
23+
$this->assertEquals(['john@doe.com', 'jane@doe.com'], $composer->getData('recipient'));
24+
}
25+
26+
/** @test */
27+
function it_extracts_cc_addresses()
28+
{
29+
$composer = Email::compose()->mailable(new TestMailable());
30+
31+
$this->assertEquals(['john+cc@doe.com', 'john+cc2@doe.com'], $composer->getData('cc'));
32+
}
33+
34+
/** @test */
35+
function it_extracts_bcc_addresses()
36+
{
37+
$composer = Email::compose()->mailable(new TestMailable());
38+
39+
$this->assertEquals(['john+bcc@doe.com', 'john+bcc2@doe.com'], $composer->getData('bcc'));
40+
}
41+
42+
/** @test */
43+
function it_extracts_the_subject()
44+
{
45+
$composer = Email::compose()->mailable(new TestMailable());
46+
47+
$this->assertEquals('Your order has shipped!', $composer->getData('subject'));
48+
}
49+
50+
/** @test */
51+
function it_extracts_the_body()
52+
{
53+
$composer = Email::compose()->mailable(new TestMailable());
54+
55+
$this->assertEquals("Name: John Doe\n", $composer->getData('body'));
56+
}
57+
}
58+
59+
class TestMailable extends Mailable
60+
{
61+
/**
62+
* Create a new message instance.
63+
*
64+
* @return void
65+
*/
66+
public function __construct()
67+
{
68+
$this->to('john@doe.com')
69+
->cc(['john+cc@doe.com', 'john+cc2@doe.com'])
70+
->bcc(['john+bcc@doe.com', 'john+bcc2@doe.com'])
71+
->subject('Your order has shipped!');
72+
}
73+
74+
/**
75+
* Build the message.
76+
*
77+
* @return $this
78+
*/
79+
public function build()
80+
{
81+
return $this->view('tests::dummy', ['name' => 'John Doe']);
82+
}
83+
}

0 commit comments

Comments
 (0)