Skip to content

Commit 8ac224f

Browse files
[9.x] Fix mails with tags and metadata are not queuable (#41028)
* fix: mails with tags and metadata could not be queued * test: add test cases for tags en metadata for mail * fix: mail could have multiple tags * style: fix issues from style linter * formatting Co-authored-by: Taylor Otwell <[email protected]>
1 parent 8e15796 commit 8ac224f

File tree

5 files changed

+152
-15
lines changed

5 files changed

+152
-15
lines changed

src/Illuminate/Mail/Mailable.php

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,20 @@ class Mailable implements MailableContract, Renderable
136136
*/
137137
public $diskAttachments = [];
138138

139+
/**
140+
* The tags for the message.
141+
*
142+
* @var array
143+
*/
144+
protected $tags = [];
145+
146+
/**
147+
* The metadata for the message.
148+
*
149+
* @var array
150+
*/
151+
protected $metadata = [];
152+
139153
/**
140154
* The callbacks for the message.
141155
*
@@ -190,6 +204,8 @@ public function send($mailer)
190204
$this->buildFrom($message)
191205
->buildRecipients($message)
192206
->buildSubject($message)
207+
->buildTags($message)
208+
->buildMetadata($message)
193209
->runCallbacks($message)
194210
->buildAttachments($message);
195211
});
@@ -449,6 +465,40 @@ protected function buildDiskAttachments($message)
449465
}
450466
}
451467

468+
/**
469+
* Add all defined tags to the message.
470+
*
471+
* @param \Illuminate\Mail\Message $message
472+
* @return $this
473+
*/
474+
protected function buildTags($message)
475+
{
476+
if ($this->tags) {
477+
foreach ($this->tags as $tag) {
478+
$message->getHeaders()->add(new TagHeader($tag));
479+
}
480+
}
481+
482+
return $this;
483+
}
484+
485+
/**
486+
* Add all defined metadata to the message.
487+
*
488+
* @param \Illuminate\Mail\Message $message
489+
* @return $this
490+
*/
491+
protected function buildMetadata($message)
492+
{
493+
if ($this->metadata) {
494+
foreach ($this->metadata as $key => $value) {
495+
$message->getHeaders()->add(new MetadataHeader($key, $value));
496+
}
497+
}
498+
499+
return $this;
500+
}
501+
452502
/**
453503
* Run the callbacks for the message.
454504
*
@@ -884,9 +934,9 @@ public function attachData($data, $name, array $options = [])
884934
*/
885935
public function tag($value)
886936
{
887-
return $this->withSymfonyMessage(function (Email $message) use ($value) {
888-
$message->getHeaders()->add(new TagHeader($value));
889-
});
937+
array_push($this->tags, $value);
938+
939+
return $this;
890940
}
891941

892942
/**
@@ -898,9 +948,9 @@ public function tag($value)
898948
*/
899949
public function metadata($key, $value)
900950
{
901-
return $this->withSymfonyMessage(function (Email $message) use ($key, $value) {
902-
$message->getHeaders()->add(new MetadataHeader($key, $value));
903-
});
951+
$this->metadata[$key] = $value;
952+
953+
return $this;
904954
}
905955

906956
/**

src/Illuminate/Notifications/Channels/MailChannel.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use Illuminate\Notifications\Notification;
1010
use Illuminate\Support\Arr;
1111
use Illuminate\Support\Str;
12+
use Symfony\Component\Mailer\Header\MetadataHeader;
13+
use Symfony\Component\Mailer\Header\TagHeader;
1214

1315
class MailChannel
1416
{
@@ -144,6 +146,18 @@ protected function buildMessage($mailMessage, $notifiable, $notification, $messa
144146
$mailMessage->setPriority($message->priority);
145147
}
146148

149+
if ($message->tags) {
150+
foreach ($message->tags as $tag) {
151+
$mailMessage->getHeaders()->add(new TagHeader($tag));
152+
}
153+
}
154+
155+
if ($message->metadata) {
156+
foreach ($message->metadata as $key => $value) {
157+
$mailMessage->getHeaders()->add(new MetadataHeader($key, $value));
158+
}
159+
}
160+
147161
$this->runCallbacks($mailMessage, $message);
148162
}
149163

src/Illuminate/Notifications/Messages/MailMessage.php

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
use Illuminate\Contracts\Support\Renderable;
88
use Illuminate\Mail\Markdown;
99
use Illuminate\Support\Traits\Conditionable;
10-
use Symfony\Component\Mailer\Header\MetadataHeader;
11-
use Symfony\Component\Mailer\Header\TagHeader;
12-
use Symfony\Component\Mime\Email;
1310

1411
class MailMessage extends SimpleMessage implements Renderable
1512
{
@@ -85,6 +82,20 @@ class MailMessage extends SimpleMessage implements Renderable
8582
*/
8683
public $rawAttachments = [];
8784

85+
/**
86+
* The tags for the message.
87+
*
88+
* @var array
89+
*/
90+
public $tags = [];
91+
92+
/**
93+
* The metadata for the message.
94+
*
95+
* @var array
96+
*/
97+
public $metadata = [];
98+
8899
/**
89100
* Priority level of the message.
90101
*
@@ -264,9 +275,9 @@ public function attachData($data, $name, array $options = [])
264275
*/
265276
public function tag($value)
266277
{
267-
return $this->withSymfonyMessage(function (Email $message) use ($value) {
268-
$message->getHeaders()->add(new TagHeader($value));
269-
});
278+
array_push($this->tags, $value);
279+
280+
return $this;
270281
}
271282

272283
/**
@@ -278,9 +289,9 @@ public function tag($value)
278289
*/
279290
public function metadata($key, $value)
280291
{
281-
return $this->withSymfonyMessage(function (Email $message) use ($key, $value) {
282-
$message->getHeaders()->add(new MetadataHeader($key, $value));
283-
});
292+
$this->metadata[$key] = $value;
293+
294+
return $this;
284295
}
285296

286297
/**

tests/Mail/MailMailableTest.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,48 @@ public function testMailablePriorityGetsSent()
445445
$this->assertSame('[email protected]', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());
446446
$this->assertStringContainsString('X-Priority: 1 (Highest)', $sentMessage->toString());
447447
}
448+
449+
public function testMailableMetadataGetsSent()
450+
{
451+
$view = m::mock(Factory::class);
452+
453+
$mailer = new Mailer('array', $view, new ArrayTransport);
454+
455+
$mailable = new WelcomeMailableStub;
456+
$mailable->to('[email protected]');
457+
$mailable->from('[email protected]');
458+
$mailable->html('test content');
459+
460+
$mailable->metadata('origin', 'test-suite');
461+
$mailable->metadata('user_id', 1);
462+
463+
$sentMessage = $mailer->send($mailable);
464+
465+
$this->assertSame('[email protected]', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());
466+
$this->assertStringContainsString('X-Metadata-origin: test-suite', $sentMessage->toString());
467+
$this->assertStringContainsString('X-Metadata-user_id: 1', $sentMessage->toString());
468+
}
469+
470+
public function testMailableTagGetsSent()
471+
{
472+
$view = m::mock(Factory::class);
473+
474+
$mailer = new Mailer('array', $view, new ArrayTransport);
475+
476+
$mailable = new WelcomeMailableStub;
477+
$mailable->to('[email protected]');
478+
$mailable->from('[email protected]');
479+
$mailable->html('test content');
480+
481+
$mailable->tag('test');
482+
$mailable->tag('foo');
483+
484+
$sentMessage = $mailer->send($mailable);
485+
486+
$this->assertSame('[email protected]', $sentMessage->getEnvelope()->getRecipients()[0]->getAddress());
487+
$this->assertStringContainsString('X-Tag: test', $sentMessage->toString());
488+
$this->assertStringContainsString('X-Tag: foo', $sentMessage->toString());
489+
}
448490
}
449491

450492
class WelcomeMailableStub extends Mailable

tests/Notifications/NotificationMailMessageTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,26 @@ public function testReplyToIsSetCorrectly()
121121
$this->assertSame([['[email protected]', null], ['[email protected]', 'Test']], $message->replyTo);
122122
}
123123

124+
public function testMetadataIsSetCorrectly()
125+
{
126+
$message = new MailMessage;
127+
$message->metadata('origin', 'test-suite');
128+
$message->metadata('user_id', 1);
129+
130+
$this->assertArrayHasKey('origin', $message->metadata);
131+
$this->assertSame('test-suite', $message->metadata['origin']);
132+
$this->assertArrayHasKey('user_id', $message->metadata);
133+
$this->assertSame(1, $message->metadata['user_id']);
134+
}
135+
136+
public function testTagIsSetCorrectly()
137+
{
138+
$message = new MailMessage;
139+
$message->tag('test');
140+
141+
$this->assertContains('test', $message->tags);
142+
}
143+
124144
public function testCallbackIsSetCorrectly()
125145
{
126146
$callback = function () {

0 commit comments

Comments
 (0)