Skip to content

Commit

Permalink
[10.x] Add DatabaseChannel::requireDatabaseType() method
Browse files Browse the repository at this point in the history
  • Loading branch information
teddy-francfort committed Sep 18, 2023
1 parent f0d949b commit de312e5
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 3 deletions.
44 changes: 41 additions & 3 deletions src/Illuminate/Notifications/Channels/DatabaseChannel.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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.
*
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

namespace Illuminate\Notifications\Exceptions;

use Illuminate\Notifications\Notification;

class DatabaseTypeNotificationMissingException extends \RuntimeException
{
/**
* The name of the affected Notification.
*/
public Notification $notification;

/**
* Create a new exception instance.
*/
public function __construct(Notification $notification)
{
$class = get_class($notification);

parent::__construct("No database type defined for notification [{$class}].");

$this->notification = $notification;
}
}
26 changes: 26 additions & 0 deletions tests/Notifications/NotificationDatabaseChannelTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit de312e5

Please sign in to comment.