mirror of
https://github.com/flarum/core.git
synced 2025-10-18 18:26:07 +02:00
More powerful/extensible notifications
- Notifications can be delivered in multiple ways (alert, email) - Different notification types can implement interfaces to allow themselves to be delivered in these various ways - User preferences for each notification type/method combination are automatically registered
This commit is contained in:
35
src/Core/Notifications/NotificationServiceProvider.php
Normal file
35
src/Core/Notifications/NotificationServiceProvider.php
Normal file
@@ -0,0 +1,35 @@
|
||||
<?php namespace Flarum\Core\Notifications;
|
||||
|
||||
use Illuminate\Contracts\Events\Dispatcher;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
class NotificationServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* Bootstrap the application events.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function boot(Dispatcher $events)
|
||||
{
|
||||
$notifier = app('Flarum\Core\Notifications\Notifier');
|
||||
|
||||
$notifier->registerMethod('alert', 'Flarum\Core\Notifications\Senders\NotificationAlerter');
|
||||
$notifier->registerMethod('email', 'Flarum\Core\Notifications\Senders\NotificationEmailer');
|
||||
|
||||
$notifier->registerType('Flarum\Core\Notifications\Types\DiscussionRenamedNotification', ['alert' => true]);
|
||||
|
||||
$events->subscribe('Flarum\Core\Handlers\Events\DiscussionRenamedNotifier');
|
||||
}
|
||||
|
||||
public function register()
|
||||
{
|
||||
$this->app->bind(
|
||||
'Flarum\Core\Repositories\NotificationRepositoryInterface',
|
||||
'Flarum\Core\Repositories\EloquentNotificationRepository'
|
||||
);
|
||||
|
||||
$this->app->singleton('Flarum\Core\Notifications\Notifier');
|
||||
}
|
||||
}
|
59
src/Core/Notifications/Notifier.php
Normal file
59
src/Core/Notifications/Notifier.php
Normal file
@@ -0,0 +1,59 @@
|
||||
<?php namespace Flarum\Core\Notifications;
|
||||
|
||||
use Flarum\Core\Notifications\Types\Notification;
|
||||
use Flarum\Core\Models\Notification as NotificationModel;
|
||||
use Flarum\Core\Models\User;
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
class Notifier
|
||||
{
|
||||
protected $methods = [];
|
||||
|
||||
protected $types = [];
|
||||
|
||||
protected $container;
|
||||
|
||||
public function __construct(Container $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
public function send(Notification $notification)
|
||||
{
|
||||
foreach ($this->methods as $method => $sender) {
|
||||
$sender = $this->container->make($sender);
|
||||
if ($notification->getRecipient()->shouldNotify($notification::getType(), $method) && $sender->compatibleWith($notification)) {
|
||||
$sender->send($notification);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function registerMethod($name, $class)
|
||||
{
|
||||
$this->methods[$name] = $class;
|
||||
}
|
||||
|
||||
public function registerType($class, $defaultPreferences = [])
|
||||
{
|
||||
$this->types[] = $class;
|
||||
|
||||
NotificationModel::registerType($class);
|
||||
|
||||
foreach ($this->methods as $method => $sender) {
|
||||
$sender = $this->container->make($sender);
|
||||
if ($sender->compatibleWith($class)) {
|
||||
User::registerPreference(User::notificationPreferenceKey($class::getType(), $method), 'boolval', array_get($defaultPreferences, $method, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function getMethods()
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
|
||||
public function getTypes()
|
||||
{
|
||||
return $this->types;
|
||||
}
|
||||
}
|
25
src/Core/Notifications/Senders/NotificationAlerter.php
Normal file
25
src/Core/Notifications/Senders/NotificationAlerter.php
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php namespace Flarum\Core\Notifications\Senders;
|
||||
|
||||
use Flarum\Core\Notifications\Types\Notification;
|
||||
use Flarum\Core\Models\Notification as NotificationModel;
|
||||
use ReflectionClass;
|
||||
|
||||
class NotificationAlerter implements NotificationSender
|
||||
{
|
||||
public function send(Notification $notification)
|
||||
{
|
||||
$model = NotificationModel::alert(
|
||||
$notification->getRecipient()->id,
|
||||
$notification::getType(),
|
||||
$notification->getSender()->id,
|
||||
$notification->getSubject()->id,
|
||||
$notification->getAlertData()
|
||||
);
|
||||
$model->save();
|
||||
}
|
||||
|
||||
public function compatibleWith($className)
|
||||
{
|
||||
return (new ReflectionClass($className))->implementsInterface('Flarum\Core\Notifications\Types\AlertableNotification');
|
||||
}
|
||||
}
|
29
src/Core/Notifications/Senders/NotificationEmailer.php
Normal file
29
src/Core/Notifications/Senders/NotificationEmailer.php
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php namespace Flarum\Core\Notifications\Senders;
|
||||
|
||||
use Flarum\Core\Notifications\Types\Notification;
|
||||
use Flarum\Core\Models\Forum;
|
||||
use Illuminate\Mail\Mailer;
|
||||
use ReflectionClass;
|
||||
|
||||
class NotificationEmailer implements NotificationSender
|
||||
{
|
||||
public function __construct(Mailer $mailer, Forum $forum)
|
||||
{
|
||||
$this->mailer = $mailer;
|
||||
$this->forum = $forum;
|
||||
}
|
||||
|
||||
public function send(Notification $notification)
|
||||
{
|
||||
$this->mailer->send($notification->getEmailView(), ['notification' => $notification], function ($message) use ($notification) {
|
||||
$recipient = $notification->getRecipient();
|
||||
$message->to($recipient->email, $recipient->username)
|
||||
->subject('['.$this->forum->title.'] '.$notification->getEmailSubject());
|
||||
});
|
||||
}
|
||||
|
||||
public function compatibleWith($class)
|
||||
{
|
||||
return (new ReflectionClass($class))->implementsInterface('Flarum\Core\Notifications\Types\EmailableNotification');
|
||||
}
|
||||
}
|
10
src/Core/Notifications/Senders/NotificationSender.php
Normal file
10
src/Core/Notifications/Senders/NotificationSender.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php namespace Flarum\Core\Notifications\Senders;
|
||||
|
||||
use Flarum\Core\Notifications\Types\Notification;
|
||||
|
||||
interface NotificationSender
|
||||
{
|
||||
public function send(Notification $notification);
|
||||
|
||||
public function compatibleWith($class);
|
||||
}
|
8
src/Core/Notifications/Types/AlertableNotification.php
Normal file
8
src/Core/Notifications/Types/AlertableNotification.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php namespace Flarum\Core\Notifications\Types;
|
||||
|
||||
interface AlertableNotification
|
||||
{
|
||||
public function getAlertData();
|
||||
|
||||
public static function getType();
|
||||
}
|
@@ -0,0 +1,42 @@
|
||||
<?php namespace Flarum\Core\Notifications\Types;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
use Flarum\Core\Models\DiscussionRenamedPost;
|
||||
|
||||
class DiscussionRenamedNotification extends Notification implements AlertableNotification
|
||||
{
|
||||
public $post;
|
||||
|
||||
public $oldTitle;
|
||||
|
||||
public function __construct(User $recipient, User $sender, DiscussionRenamedPost $post, $oldTitle)
|
||||
{
|
||||
$this->post = $post;
|
||||
$this->oldTitle = $oldTitle;
|
||||
|
||||
parent::__construct($recipient, $sender);
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
return $this->post->discussion;
|
||||
}
|
||||
|
||||
public function getAlertData()
|
||||
{
|
||||
return [
|
||||
'number' => $this->post->number,
|
||||
'oldTitle' => $this->oldTitle
|
||||
];
|
||||
}
|
||||
|
||||
public static function getType()
|
||||
{
|
||||
return 'discussionRenamed';
|
||||
}
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return 'Flarum\Core\Models\Discussion';
|
||||
}
|
||||
}
|
8
src/Core/Notifications/Types/EmailableNotification.php
Normal file
8
src/Core/Notifications/Types/EmailableNotification.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php namespace Flarum\Core\Notifications\Types;
|
||||
|
||||
interface EmailableNotification
|
||||
{
|
||||
public function getEmailView();
|
||||
|
||||
public function getEmailSubject();
|
||||
}
|
36
src/Core/Notifications/Types/Notification.php
Normal file
36
src/Core/Notifications/Types/Notification.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php namespace Flarum\Core\Notifications\Types;
|
||||
|
||||
use Flarum\Core\Models\User;
|
||||
|
||||
abstract class Notification
|
||||
{
|
||||
protected $recipient;
|
||||
|
||||
protected $sender;
|
||||
|
||||
public function __construct(User $recipient, User $sender)
|
||||
{
|
||||
$this->recipient = $recipient;
|
||||
$this->sender = $sender;
|
||||
}
|
||||
|
||||
public function getRecipient()
|
||||
{
|
||||
return $this->recipient;
|
||||
}
|
||||
|
||||
public function getSender()
|
||||
{
|
||||
return $this->sender;
|
||||
}
|
||||
|
||||
public static function getType()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public static function getSubjectModel()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user