Skip to content

Commit

Permalink
[10.x] Allow serialization of NotificationSent (#47375)
Browse files Browse the repository at this point in the history
* add base64 encoding when serializing SentMessage

* slim down expression

* adds test case

* Update MessageSent.php

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
cosmastech and taylorotwell authored Jun 13, 2023
1 parent e73478a commit 2577300
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 14 deletions.
22 changes: 8 additions & 14 deletions src/Illuminate/Mail/Events/MessageSent.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,14 +46,10 @@ public function __serialize()
{
$hasAttachments = collect($this->message->getAttachments())->isNotEmpty();

return $hasAttachments ? [
'sent' => base64_encode(serialize($this->sent)),
'data' => base64_encode(serialize($this->data)),
'hasAttachments' => true,
] : [
return [
'sent' => $this->sent,
'data' => $this->data,
'hasAttachments' => false,
'data' => $hasAttachments ? base64_encode(serialize($this->data)) : $this->data,
'hasAttachments' => $hasAttachments,
];
}

Expand All @@ -65,13 +61,11 @@ public function __serialize()
*/
public function __unserialize(array $data)
{
if (isset($data['hasAttachments']) && $data['hasAttachments'] === true) {
$this->sent = unserialize(base64_decode($data['sent']));
$this->data = unserialize(base64_decode($data['data']));
} else {
$this->sent = $data['sent'];
$this->data = $data['data'];
}
$this->sent = $data['sent'];

$this->data = (($data['hasAttachments'] ?? false) === true)
? unserialize(base64_decode($data['data']))
: $data['data'];
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/Illuminate/Mail/SentMessage.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,32 @@ public function __call($method, $parameters)
{
return $this->forwardCallTo($this->sentMessage, $method, $parameters);
}

/**
* Get the serializable representation of the object.
*
* @return array
*/
public function __serialize()
{
$hasAttachments = collect($this->sentMessage->getOriginalMessage()->getAttachments())->isNotEmpty();

return [
'hasAttachments' => $hasAttachments,
'sentMessage' => $hasAttachments ? base64_encode(serialize($this->sentMessage)) : $this->sentMessage,
];
}

/**
* Marshal the object from its serialized data.
*
* @param array $data
* @return void
*/
public function __unserialize(array $data)
{
$hasAttachments = ($data['hasAttachments'] ?? false) === true;

$this->sentMessage = $hasAttachments ? unserialize(base64_decode($data['sentMessage'])) : $data['sentMessage'];
}
}
Binary file added tests/Integration/Mail/Fixtures/blank_document.pdf
Binary file not shown.
78 changes: 78 additions & 0 deletions tests/Integration/Mail/SentMessageMailTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Illuminate\Tests\Integration\Mail;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notifiable;
use Illuminate\Notifications\Notification;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Schema;
use Orchestra\Testbench\TestCase;

class SentMessageMailTest extends TestCase
{
public function setUp(): void
{
parent::setUp();

Schema::create('sent_message_users', function (Blueprint $table) {
$table->increments('id');
});
}

public function testDispatchesNotificationSent()
{
$notificationWasSent = false;

$user = SentMessageUser::create();

Event::listen(
NotificationSent::class,
function(NotificationSent $notification) use (&$notificationWasSent, $user) {
$notificationWasSent = true;
/**
* Confirm that NotificationSent can be serialized/unserialized as
* will happen if the listener implements ShouldQueue.
*/
/** @var NotificationSent $afterSerialization */
$afterSerialization = unserialize(serialize($notification));

$this->assertTrue($user->is($afterSerialization->notifiable));

$this->assertEqualsCanonicalizing($notification->notification, $afterSerialization->notification);
});

$user->notify(new SentMessageMailNotification());

$this->assertTrue($notificationWasSent);
}
}

class SentMessageUser extends Model
{
use Notifiable;

public $timestamps = false;
}


class SentMessageMailNotification extends Notification
{
public function via(): array
{
return ['mail'];
}

public function toMail(object $notifiable): MailMessage
{
return (new MailMessage)
->line('Example notification with attachment.')
->attach(__DIR__ . '/Fixtures/blank_document.pdf', [
'as' => 'blank_document.pdf',
'mime' => 'application/pdf',
]);
}
}

0 comments on commit 2577300

Please sign in to comment.