1
0
mirror of https://github.com/flarum/core.git synced 2025-10-12 23:44:27 +02:00

Add Notification Channel Extender (#2432)

This commit is contained in:
Sami Mazouz
2020-11-05 18:09:06 +01:00
committed by GitHub
parent 87c258b2f8
commit f0e77a5789
9 changed files with 371 additions and 52 deletions

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Notification\Driver;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Notification\Job\SendNotificationsJob;
use Flarum\User\User;
use Illuminate\Contracts\Queue\Queue;
class AlertNotificationDriver implements NotificationDriverInterface
{
/**
* @var Queue
*/
private $queue;
public function __construct(Queue $queue)
{
$this->queue = $queue;
}
/**
* {@inheritDoc}
*/
public function send(BlueprintInterface $blueprint, array $users): void
{
if (count($users)) {
$this->queue->push(new SendNotificationsJob($blueprint, $users));
}
}
/**
* {@inheritdoc}
*/
public function registerType(string $blueprintClass, array $driversEnabledByDefault): void
{
User::addPreference(
User::getNotificationPreferenceKey($blueprintClass::getType(), 'alert'),
'boolval',
in_array('alert', $driversEnabledByDefault)
);
}
}

View File

@@ -0,0 +1,69 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Notification\Driver;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Notification\Job\SendEmailNotificationJob;
use Flarum\Notification\MailableInterface;
use Flarum\User\User;
use Illuminate\Contracts\Queue\Queue;
use ReflectionClass;
class EmailNotificationDriver implements NotificationDriverInterface
{
/**
* @var Queue
*/
private $queue;
public function __construct(Queue $queue)
{
$this->queue = $queue;
}
/**
* {@inheritDoc}
*/
public function send(BlueprintInterface $blueprint, array $users): void
{
if ($blueprint instanceof MailableInterface) {
$this->mailNotifications($blueprint, $users);
}
}
/**
* Mail a notification to a list of users.
*
* @param MailableInterface $blueprint
* @param User[] $recipients
*/
protected function mailNotifications(MailableInterface $blueprint, array $recipients)
{
foreach ($recipients as $user) {
if ($user->shouldEmail($blueprint::getType())) {
$this->queue->push(new SendEmailNotificationJob($blueprint, $user));
}
}
}
/**
* {@inheritdoc}
*/
public function registerType(string $blueprintClass, array $driversEnabledByDefault): void
{
if ((new ReflectionClass($blueprintClass))->implementsInterface(MailableInterface::class)) {
User::addPreference(
User::getNotificationPreferenceKey($blueprintClass::getType(), 'email'),
'boolval',
in_array('email', $driversEnabledByDefault)
);
}
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Flarum.
*
* For detailed copyright and license information, please view the
* LICENSE file that was distributed with this source code.
*/
namespace Flarum\Notification\Driver;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\User\User;
interface NotificationDriverInterface
{
/**
* Conditionally sends a notification to users, generally using a queue.
*
* @param BlueprintInterface $blueprint
* @param User[] $users
* @return void
*/
public function send(BlueprintInterface $blueprint, array $users): void;
/**
* Logic for registering a notification type, generally used for adding a user preference.
*
* @param string $blueprintClass
* @param array $driversEnabledByDefault
* @return void
*/
public function registerType(string $blueprintClass, array $driversEnabledByDefault): void;
}

View File

@@ -11,6 +11,9 @@ namespace Flarum\Notification\Event;
use Flarum\Notification\Blueprint\BlueprintInterface;
/**
* @deprecated in beta 15, removed in beta 16
*/
class Sending
{
/**

View File

@@ -10,7 +10,6 @@
namespace Flarum\Notification\Job;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Notification\Event\Sending;
use Flarum\Notification\Notification;
use Flarum\Queue\AbstractJob;
use Flarum\User\User;
@@ -35,8 +34,6 @@ class SendNotificationsJob extends AbstractJob
public function handle()
{
event(new Sending($this->blueprint, $this->recipients));
Notification::notify($this->recipients, $this->blueprint);
}
}

View File

@@ -12,8 +12,6 @@ namespace Flarum\Notification;
use Flarum\Event\ConfigureNotificationTypes;
use Flarum\Foundation\AbstractServiceProvider;
use Flarum\Notification\Blueprint\DiscussionRenamedBlueprint;
use Flarum\User\User;
use ReflectionClass;
class NotificationServiceProvider extends AbstractServiceProvider
{
@@ -22,6 +20,13 @@ class NotificationServiceProvider extends AbstractServiceProvider
*/
public function register()
{
$this->app->singleton('flarum.notification.drivers', function () {
return [
'alert' => Driver\AlertNotificationDriver::class,
'email' => Driver\EmailNotificationDriver::class,
];
});
$this->app->singleton('flarum.notification.blueprints', function () {
return [
DiscussionRenamedBlueprint::class => ['alert']
@@ -34,9 +39,20 @@ class NotificationServiceProvider extends AbstractServiceProvider
*/
public function boot()
{
$this->setNotificationDrivers();
$this->setNotificationTypes();
}
/**
* Register notification drivers.
*/
protected function setNotificationDrivers()
{
foreach ($this->app->make('flarum.notification.drivers') as $driverName => $driver) {
NotificationSyncer::addNotificationDriver($driverName, $this->app->make($driver));
}
}
/**
* Register notification types.
*/
@@ -49,29 +65,22 @@ class NotificationServiceProvider extends AbstractServiceProvider
new ConfigureNotificationTypes($blueprints)
);
foreach ($blueprints as $blueprint => $channelsEnabledByDefault) {
$this->addType($blueprint, $channelsEnabledByDefault);
foreach ($blueprints as $blueprint => $driversEnabledByDefault) {
$this->addType($blueprint, $driversEnabledByDefault);
}
}
protected function addType(string $blueprint, array $channelsEnabledByDefault)
protected function addType(string $blueprint, array $driversEnabledByDefault)
{
Notification::setSubjectModel(
$type = $blueprint::getType(),
$blueprint::getSubjectModel()
);
User::addPreference(
User::getNotificationPreferenceKey($type, 'alert'),
'boolval',
in_array('alert', $channelsEnabledByDefault)
);
if ((new ReflectionClass($blueprint))->implementsInterface(MailableInterface::class)) {
User::addPreference(
User::getNotificationPreferenceKey($type, 'email'),
'boolval',
in_array('email', $channelsEnabledByDefault)
foreach (NotificationSyncer::getNotificationDrivers() as $driverName => $driver) {
$driver->registerType(
$blueprint,
$driversEnabledByDefault
);
}
}

View File

@@ -10,10 +10,9 @@
namespace Flarum\Notification;
use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Notification\Job\SendEmailNotificationJob;
use Flarum\Notification\Job\SendNotificationsJob;
use Flarum\Notification\Driver\NotificationDriverInterface;
use Flarum\Notification\Event\Sending;
use Flarum\User\User;
use Illuminate\Contracts\Queue\Queue;
/**
* The Notification Syncer commits notification blueprints to the database, and
@@ -38,14 +37,11 @@ class NotificationSyncer
protected static $sentTo = [];
/**
* @var Queue
* A map of notification drivers.
*
* @var NotificationDriverInterface[]
*/
protected $queue;
public function __construct(Queue $queue)
{
$this->queue = $queue;
}
protected static $notificationDrivers = [];
/**
* Sync a notification so that it is visible to the specified users, and not
@@ -102,12 +98,13 @@ class NotificationSyncer
// receiving this notification for the first time (we know because they
// didn't have a record in the database). As both operations can be
// intensive on resources (database and mail server), we queue them.
if (count($newRecipients)) {
$this->queue->push(new SendNotificationsJob($blueprint, $newRecipients));
foreach (static::getNotificationDrivers() as $driverName => $driver) {
$driver->send($blueprint, $newRecipients);
}
if ($blueprint instanceof MailableInterface) {
$this->mailNotifications($blueprint, $newRecipients);
if (count($newRecipients)) {
// Deprecated in beta 15, removed in beta 16
event(new Sending($blueprint, $newRecipients));
}
}
@@ -150,21 +147,6 @@ class NotificationSyncer
static::$onePerUser = false;
}
/**
* Mail a notification to a list of users.
*
* @param MailableInterface $blueprint
* @param User[] $recipients
*/
protected function mailNotifications(MailableInterface $blueprint, array $recipients)
{
foreach ($recipients as $user) {
if ($user->shouldEmail($blueprint::getType())) {
$this->queue->push(new SendEmailNotificationJob($blueprint, $user));
}
}
}
/**
* Set the deleted status of a list of notification records.
*
@@ -175,4 +157,23 @@ class NotificationSyncer
{
Notification::whereIn('id', $ids)->update(['is_deleted' => $isDeleted]);
}
/**
* Adds a notification driver to the list.
*
* @param string $driverName
* @param NotificationDriverInterface $driver
*/
public static function addNotificationDriver(string $driverName, NotificationDriverInterface $driver)
{
static::$notificationDrivers[$driverName] = $driver;
}
/**
* @return NotificationDriverInterface[]
*/
public static function getNotificationDrivers(): array
{
return static::$notificationDrivers;
}
}