mirror of
https://github.com/flarum/framework.git
synced 2024-11-30 05:13:37 +08:00
Notifications into the queue
Forces notifications into a dedicated SendNotificationsJob and passed to the queue. - One static method re-used in the job ::getAttributes, is that okay or use a trait? - Do we want to use this solution and refactor into a better Hub after stable, postpone this implementation or use it in b11?
This commit is contained in:
parent
20bc1e50fc
commit
8cdcb25fcc
|
@ -0,0 +1,23 @@
|
|||
<?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\Blueprint;
|
||||
|
||||
abstract class AbstractBlueprint implements BlueprintInterface
|
||||
{
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return [
|
||||
'type' => static::getType(),
|
||||
'from_user_id' => ($fromUser = $this->getFromUser()) ? $fromUser->id : null,
|
||||
'subject_id' => ($subject = $this->getSubject()) ? $subject->getKey() : null,
|
||||
'data' => ($data = $this->getData()) ? json_encode($data) : null
|
||||
];
|
||||
}
|
||||
}
|
|
@ -9,6 +9,9 @@
|
|||
|
||||
namespace Flarum\Notification\Blueprint;
|
||||
|
||||
use Flarum\Database\AbstractModel;
|
||||
use Flarum\User\User;
|
||||
|
||||
/**
|
||||
* A notification BlueprintInterface, when instantiated, represents a notification about
|
||||
* something. The blueprint is used by the NotificationSyncer to commit the
|
||||
|
@ -19,14 +22,14 @@ interface BlueprintInterface
|
|||
/**
|
||||
* Get the user that sent the notification.
|
||||
*
|
||||
* @return \Flarum\User\User|null
|
||||
* @return User|null
|
||||
*/
|
||||
public function getFromUser();
|
||||
|
||||
/**
|
||||
* Get the model that is the subject of this activity.
|
||||
*
|
||||
* @return \Flarum\Database\AbstractModel|null
|
||||
* @return AbstractModel|null
|
||||
*/
|
||||
public function getSubject();
|
||||
|
||||
|
|
39
framework/core/src/Notification/Event/Notifying.php
Normal file
39
framework/core/src/Notification/Event/Notifying.php
Normal file
|
@ -0,0 +1,39 @@
|
|||
<?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\Event;
|
||||
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
|
||||
class Notifying
|
||||
{
|
||||
/**
|
||||
* The blueprint for the notification.
|
||||
*
|
||||
* @var BlueprintInterface
|
||||
*/
|
||||
public $blueprint;
|
||||
|
||||
/**
|
||||
* The users that the notification will be sent to.
|
||||
*
|
||||
* @var array|int[]
|
||||
*/
|
||||
public $users;
|
||||
|
||||
/**
|
||||
* @param \Flarum\Notification\Blueprint\BlueprintInterface $blueprint
|
||||
* @param \Flarum\User\User[] $users
|
||||
*/
|
||||
public function __construct(BlueprintInterface $blueprint, array &$users)
|
||||
{
|
||||
$this->blueprint = $blueprint;
|
||||
$this->users = &$users;
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ class Sending
|
|||
/**
|
||||
* The users that the notification will be sent to.
|
||||
*
|
||||
* @var array
|
||||
* @var array|int[]
|
||||
*/
|
||||
public $users;
|
||||
|
||||
|
|
73
framework/core/src/Notification/Job/SendNotificationsJob.php
Normal file
73
framework/core/src/Notification/Job/SendNotificationsJob.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<?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\Job;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
use Flarum\Notification\Event\Notifying;
|
||||
use Flarum\Notification\Event\Sending;
|
||||
use Flarum\Notification\MailableInterface;
|
||||
use Flarum\Notification\Notification;
|
||||
use Flarum\Notification\NotificationMailer;
|
||||
use Flarum\Queue\AbstractJob;
|
||||
use Flarum\User\User;
|
||||
|
||||
class SendNotificationsJob extends AbstractJob
|
||||
{
|
||||
/**
|
||||
* @var BlueprintInterface
|
||||
*/
|
||||
private $blueprint;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $recipientIds;
|
||||
|
||||
public function __construct(BlueprintInterface $blueprint, array $recipientIds = [])
|
||||
{
|
||||
$this->blueprint = $blueprint;
|
||||
$this->recipientIds = $recipientIds;
|
||||
}
|
||||
|
||||
public function handle(NotificationMailer $mailer)
|
||||
{
|
||||
$now = Carbon::now('utc')->toDateTimeString();
|
||||
$recipients = $this->recipientIds;
|
||||
|
||||
event(new Sending($this->blueprint, $recipients));
|
||||
|
||||
$attributes = $this->blueprint->getAttributes();
|
||||
|
||||
Notification::insert(
|
||||
array_map(function (User $user) use ($attributes, $now) {
|
||||
return $attributes + [
|
||||
'user_id' => $user->id,
|
||||
'created_at' => $now
|
||||
];
|
||||
}, $recipients)
|
||||
);
|
||||
|
||||
event(new Notifying($this->blueprint, $recipients));
|
||||
|
||||
if ($this->blueprint instanceof MailableInterface) {
|
||||
$this->email($mailer, $this->blueprint, $recipients);
|
||||
}
|
||||
}
|
||||
|
||||
protected function email(NotificationMailer $mailer, MailableInterface $blueprint, array $recipients)
|
||||
{
|
||||
foreach ($recipients as $user) {
|
||||
if ($user->shouldEmail($blueprint::getType())) {
|
||||
$mailer->send($blueprint, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,10 +9,10 @@
|
|||
|
||||
namespace Flarum\Notification;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
use Flarum\Notification\Event\Sending;
|
||||
use Flarum\Notification\Job\SendNotificationsJob;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Queue\Queue;
|
||||
|
||||
/**
|
||||
* The Notification Syncer commits notification blueprints to the database, and
|
||||
|
@ -42,20 +42,16 @@ class NotificationSyncer
|
|||
protected $notifications;
|
||||
|
||||
/**
|
||||
* @var NotificationMailer
|
||||
* @var Queue
|
||||
*/
|
||||
protected $mailer;
|
||||
protected $queue;
|
||||
|
||||
/**
|
||||
* @param NotificationRepository $notifications
|
||||
* @param NotificationMailer $mailer
|
||||
*/
|
||||
public function __construct(
|
||||
NotificationRepository $notifications,
|
||||
NotificationMailer $mailer
|
||||
Queue $queue
|
||||
) {
|
||||
$this->notifications = $notifications;
|
||||
$this->mailer = $mailer;
|
||||
$this->queue = $queue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +65,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function sync(Blueprint\BlueprintInterface $blueprint, array $users)
|
||||
{
|
||||
$attributes = $this->getAttributes($blueprint);
|
||||
$attributes = $blueprint->getAttributes();
|
||||
|
||||
// Find all existing notification records in the database matching this
|
||||
// blueprint. We will begin by assuming that they all need to be
|
||||
|
@ -87,7 +83,7 @@ class NotificationSyncer
|
|||
continue;
|
||||
}
|
||||
|
||||
$existing = $toDelete->first(function ($notification, $i) use ($user) {
|
||||
$existing = $toDelete->first(function ($notification) use ($user) {
|
||||
return $notification->user_id === $user->id;
|
||||
});
|
||||
|
||||
|
@ -115,7 +111,7 @@ class NotificationSyncer
|
|||
// receiving this notification for the first time (we know because they
|
||||
// didn't have a record in the database).
|
||||
if (count($newRecipients)) {
|
||||
$this->sendNotifications($blueprint, $newRecipients);
|
||||
$this->queue->push(new SendNotificationsJob($blueprint, $newRecipients));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +123,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function delete(BlueprintInterface $blueprint)
|
||||
{
|
||||
Notification::where($this->getAttributes($blueprint))->update(['is_deleted' => true]);
|
||||
Notification::where($blueprint->getAttributes())->update(['is_deleted' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +134,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function restore(BlueprintInterface $blueprint)
|
||||
{
|
||||
Notification::where($this->getAttributes($blueprint))->update(['is_deleted' => false]);
|
||||
Notification::where($blueprint->getAttributes())->update(['is_deleted' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,50 +154,6 @@ class NotificationSyncer
|
|||
static::$onePerUser = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a notification record and send an email (depending on user
|
||||
* preference) from a blueprint to a list of recipients.
|
||||
*
|
||||
* @param \Flarum\Notification\Blueprint\BlueprintInterface $blueprint
|
||||
* @param User[] $recipients
|
||||
*/
|
||||
protected function sendNotifications(Blueprint\BlueprintInterface $blueprint, array $recipients)
|
||||
{
|
||||
$now = Carbon::now('utc')->toDateTimeString();
|
||||
|
||||
event(new Sending($blueprint, $recipients));
|
||||
|
||||
$attributes = $this->getAttributes($blueprint);
|
||||
|
||||
Notification::insert(
|
||||
array_map(function (User $user) use ($attributes, $now) {
|
||||
return $attributes + [
|
||||
'user_id' => $user->id,
|
||||
'created_at' => $now
|
||||
];
|
||||
}, $recipients)
|
||||
);
|
||||
|
||||
if ($blueprint instanceof MailableInterface) {
|
||||
$this->mailNotifications($blueprint, $recipients);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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->mailer->send($blueprint, $user);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the deleted status of a list of notification records.
|
||||
*
|
||||
|
@ -212,21 +164,4 @@ class NotificationSyncer
|
|||
{
|
||||
Notification::whereIn('id', $ids)->update(['is_deleted' => $isDeleted]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an array of attributes to be stored in a notification record in
|
||||
* the database, given a notification blueprint.
|
||||
*
|
||||
* @param \Flarum\Notification\Blueprint\BlueprintInterface $blueprint
|
||||
* @return array
|
||||
*/
|
||||
protected function getAttributes(Blueprint\BlueprintInterface $blueprint)
|
||||
{
|
||||
return [
|
||||
'type' => $blueprint::getType(),
|
||||
'from_user_id' => ($fromUser = $blueprint->getFromUser()) ? $fromUser->id : null,
|
||||
'subject_id' => ($subject = $blueprint->getSubject()) ? $subject->id : null,
|
||||
'data' => ($data = $blueprint->getData()) ? json_encode($data) : null
|
||||
];
|
||||
}
|
||||
}
|
||||
|
|
22
framework/core/src/Queue/AbstractJob.php
Normal file
22
framework/core/src/Queue/AbstractJob.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?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\Queue;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Queue\InteractsWithQueue;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
|
||||
class AbstractJob implements ShouldQueue
|
||||
{
|
||||
use InteractsWithQueue;
|
||||
use Queueable;
|
||||
use SerializesModels;
|
||||
}
|
Loading…
Reference in New Issue
Block a user