From de312e5bb5388de34fd06dd6e43fa99f7f3455f6 Mon Sep 17 00:00:00 2001 From: Teddy FRANCFORT Date: Mon, 18 Sep 2023 14:00:55 +0200 Subject: [PATCH] [10.x] Add DatabaseChannel::requireDatabaseType() method --- .../Channels/DatabaseChannel.php | 44 +++++++++++++++++-- ...tabaseTypeNotificationMissingException.php | 25 +++++++++++ .../NotificationDatabaseChannelTest.php | 26 +++++++++++ 3 files changed, 92 insertions(+), 3 deletions(-) create mode 100644 src/Illuminate/Notifications/Exceptions/DatabaseTypeNotificationMissingException.php diff --git a/src/Illuminate/Notifications/Channels/DatabaseChannel.php b/src/Illuminate/Notifications/Channels/DatabaseChannel.php index 8b3167b01508..4f31e36d0875 100644 --- a/src/Illuminate/Notifications/Channels/DatabaseChannel.php +++ b/src/Illuminate/Notifications/Channels/DatabaseChannel.php @@ -2,11 +2,19 @@ namespace Illuminate\Notifications\Channels; +use Illuminate\Notifications\Exceptions\DatabaseTypeNotificationMissingException; use Illuminate\Notifications\Notification; use RuntimeException; class DatabaseChannel { + /** + * Prevents database notification without a database type. + * + * @var bool + */ + protected static $requireDatabaseType = false; + /** * Send the given notification. * @@ -32,14 +40,28 @@ protected function buildPayload($notifiable, Notification $notification) { return [ 'id' => $notification->id, - 'type' => method_exists($notification, 'databaseType') - ? $notification->databaseType($notifiable) - : get_class($notification), + 'type' => $this->getDatabaseType($notifiable, $notification), 'data' => $this->getData($notifiable, $notification), 'read_at' => null, ]; } + /** + * Return the database type. + */ + protected function getDatabaseType(mixed $notifiable, Notification $notification): string + { + if (method_exists($notification, 'databaseType')) { + return $notification->databaseType($notifiable); + } + + if (static::requiresDatabaseType()) { + throw new DatabaseTypeNotificationMissingException($notification); + } + + return get_class($notification); + } + /** * Get the data for the notification. * @@ -62,4 +84,20 @@ protected function getData($notifiable, Notification $notification) throw new RuntimeException('Notification is missing toDatabase / toArray method.'); } + + /** + * Prevent database notification from being used without database type. + */ + public static function requireDatabaseType(bool $requireDatabaseType = true): void + { + static::$requireDatabaseType = $requireDatabaseType; + } + + /** + * Determine if database notification require database type. + */ + public static function requiresDatabaseType(): bool + { + return static::$requireDatabaseType; + } } diff --git a/src/Illuminate/Notifications/Exceptions/DatabaseTypeNotificationMissingException.php b/src/Illuminate/Notifications/Exceptions/DatabaseTypeNotificationMissingException.php new file mode 100644 index 000000000000..f7d9aca210b0 --- /dev/null +++ b/src/Illuminate/Notifications/Exceptions/DatabaseTypeNotificationMissingException.php @@ -0,0 +1,25 @@ +notification = $notification; + } +} diff --git a/tests/Notifications/NotificationDatabaseChannelTest.php b/tests/Notifications/NotificationDatabaseChannelTest.php index d10722693ab6..208e6bc021b3 100644 --- a/tests/Notifications/NotificationDatabaseChannelTest.php +++ b/tests/Notifications/NotificationDatabaseChannelTest.php @@ -3,6 +3,7 @@ namespace Illuminate\Tests\Notifications; use Illuminate\Notifications\Channels\DatabaseChannel; +use Illuminate\Notifications\Exceptions\DatabaseTypeNotificationMissingException; use Illuminate\Notifications\Messages\DatabaseMessage; use Illuminate\Notifications\Notification; use Mockery as m; @@ -67,6 +68,31 @@ public function testCustomizeTypeIsSentToDatabase() $channel = new ExtendedDatabaseChannel; $channel->send($notifiable, $notification); } + + public function testRequireDatabaseTypeThrowsAnExceptionWhenEnabled() + { + DatabaseChannel::requireDatabaseType(); + $notification = new NotificationDatabaseChannelTestNotification; + $notifiable = m::mock(); + + $notifiable->shouldReceive('routeNotificationFor->create'); + $this->expectException(DatabaseTypeNotificationMissingException::class); + + $channel = new DatabaseChannel; + $channel->send($notifiable, $notification); + } + + public function testRequireDatabaseTypeDoesNotThrowAnExceptionWhenDisabled() + { + DatabaseChannel::requireDatabaseType(false); + $notification = new NotificationDatabaseChannelTestNotification; + $notifiable = m::mock(); + + $notifiable->shouldReceive('routeNotificationFor->create'); + + $channel = new DatabaseChannel; + $channel->send($notifiable, $notification); + } } class NotificationDatabaseChannelTestNotification extends Notification