mirror of
https://github.com/flarum/framework.git
synced 2024-11-26 18:33:40 +08:00
Merge pull request #1931 from flarum/dk/1869-queue-notifications
Notifications into the queue
This commit is contained in:
commit
f47a4879c4
|
@ -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,24 +22,35 @@ interface BlueprintInterface
|
|||
/**
|
||||
* Get the user that sent the notification.
|
||||
*
|
||||
* @return \Flarum\User\User|null
|
||||
* @deprecated Will be removed for beta.14
|
||||
* @return User|null
|
||||
*/
|
||||
public function getFromUser();
|
||||
|
||||
/**
|
||||
* Get the model that is the subject of this activity.
|
||||
*
|
||||
* @return \Flarum\Database\AbstractModel|null
|
||||
* @deprecated Will be removed for beta.14
|
||||
* @return AbstractModel|null
|
||||
*/
|
||||
public function getSubject();
|
||||
|
||||
/**
|
||||
* Get the data to be stored in the notification.
|
||||
*
|
||||
* @deprecated Will be removed for beta.14
|
||||
* @return array|null
|
||||
*/
|
||||
public function getData();
|
||||
|
||||
/**
|
||||
* Get the attributes that uniquely identify a notification, plus metadata.
|
||||
* TODO: Uncomment this for beta.14.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
//public function getAttributes(): array;
|
||||
|
||||
/**
|
||||
* Get the serialized type of this activity.
|
||||
*
|
||||
|
|
|
@ -51,6 +51,19 @@ class DiscussionRenamedBlueprint implements BlueprintInterface
|
|||
return ['postNumber' => (int) $this->post->number];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getAttributes(): array
|
||||
{
|
||||
return [
|
||||
'type' => static::getType(),
|
||||
'from_user_id' => $this->post->user ? $this->post->user->id : null,
|
||||
'subject_id' => $this->post->discussion ? $this->post->discussion->id : null,
|
||||
'data' => json_encode(['postNumber' => (int) $this->post->number]),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
|
36
framework/core/src/Notification/BlueprintBC.php
Normal file
36
framework/core/src/Notification/BlueprintBC.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<?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;
|
||||
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
|
||||
/**
|
||||
* A backwards compatibility layer for notification blueprints.
|
||||
*
|
||||
* Will be removed for Beta 14 in favor of BlueprintInterface::getAttributes().
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
class BlueprintBC
|
||||
{
|
||||
public static function getAttributes(BlueprintInterface $blueprint): array
|
||||
{
|
||||
if (method_exists($blueprint, 'getAttributes')) {
|
||||
return $blueprint->getAttributes();
|
||||
} else {
|
||||
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
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,7 +23,7 @@ class Sending
|
|||
/**
|
||||
* The users that the notification will be sent to.
|
||||
*
|
||||
* @var array
|
||||
* @var array|int[]
|
||||
*/
|
||||
public $users;
|
||||
|
||||
|
|
|
@ -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\Job;
|
||||
|
||||
use Flarum\Notification\MailableInterface;
|
||||
use Flarum\Notification\NotificationMailer;
|
||||
use Flarum\Queue\AbstractJob;
|
||||
use Flarum\User\User;
|
||||
|
||||
class SendEmailNotificationJob extends AbstractJob
|
||||
{
|
||||
/**
|
||||
* @var MailableInterface
|
||||
*/
|
||||
private $blueprint;
|
||||
|
||||
/**
|
||||
* @var User
|
||||
*/
|
||||
private $recipient;
|
||||
|
||||
public function __construct(MailableInterface $blueprint, User $recipient)
|
||||
{
|
||||
$this->blueprint = $blueprint;
|
||||
$this->recipient = $recipient;
|
||||
}
|
||||
|
||||
public function handle(NotificationMailer $mailer)
|
||||
{
|
||||
$mailer->send($this->blueprint, $this->recipient);
|
||||
}
|
||||
}
|
55
framework/core/src/Notification/Job/SendNotificationsJob.php
Normal file
55
framework/core/src/Notification/Job/SendNotificationsJob.php
Normal file
|
@ -0,0 +1,55 @@
|
|||
<?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\BlueprintBC;
|
||||
use Flarum\Notification\Event\Sending;
|
||||
use Flarum\Notification\Notification;
|
||||
use Flarum\Queue\AbstractJob;
|
||||
use Flarum\User\User;
|
||||
|
||||
class SendNotificationsJob extends AbstractJob
|
||||
{
|
||||
/**
|
||||
* @var BlueprintInterface
|
||||
*/
|
||||
private $blueprint;
|
||||
|
||||
/**
|
||||
* @var User[]
|
||||
*/
|
||||
private $recipients;
|
||||
|
||||
public function __construct(BlueprintInterface $blueprint, array $recipients = [])
|
||||
{
|
||||
$this->blueprint = $blueprint;
|
||||
$this->recipients = $recipients;
|
||||
}
|
||||
|
||||
public function handle()
|
||||
{
|
||||
$now = Carbon::now('utc')->toDateTimeString();
|
||||
|
||||
event(new Sending($this->blueprint, $this->recipients));
|
||||
|
||||
$attributes = BlueprintBC::getAttributes($this->blueprint);
|
||||
|
||||
Notification::insert(
|
||||
array_map(function (User $user) use ($attributes, $now) {
|
||||
return $attributes + [
|
||||
'user_id' => $user->id,
|
||||
'created_at' => $now
|
||||
];
|
||||
}, $this->recipients)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -9,10 +9,11 @@
|
|||
|
||||
namespace Flarum\Notification;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
use Flarum\Notification\Event\Sending;
|
||||
use Flarum\Notification\Job\SendEmailNotificationJob;
|
||||
use Flarum\Notification\Job\SendNotificationsJob;
|
||||
use Flarum\User\User;
|
||||
use Illuminate\Contracts\Queue\Queue;
|
||||
|
||||
/**
|
||||
* The Notification Syncer commits notification blueprints to the database, and
|
||||
|
@ -37,25 +38,13 @@ class NotificationSyncer
|
|||
protected static $sentTo = [];
|
||||
|
||||
/**
|
||||
* @var NotificationRepository
|
||||
* @var Queue
|
||||
*/
|
||||
protected $notifications;
|
||||
protected $queue;
|
||||
|
||||
/**
|
||||
* @var NotificationMailer
|
||||
*/
|
||||
protected $mailer;
|
||||
|
||||
/**
|
||||
* @param NotificationRepository $notifications
|
||||
* @param NotificationMailer $mailer
|
||||
*/
|
||||
public function __construct(
|
||||
NotificationRepository $notifications,
|
||||
NotificationMailer $mailer
|
||||
) {
|
||||
$this->notifications = $notifications;
|
||||
$this->mailer = $mailer;
|
||||
public function __construct(Queue $queue)
|
||||
{
|
||||
$this->queue = $queue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,7 +58,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function sync(Blueprint\BlueprintInterface $blueprint, array $users)
|
||||
{
|
||||
$attributes = $this->getAttributes($blueprint);
|
||||
$attributes = BlueprintBC::getAttributes($blueprint);
|
||||
|
||||
// Find all existing notification records in the database matching this
|
||||
// blueprint. We will begin by assuming that they all need to be
|
||||
|
@ -87,7 +76,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;
|
||||
});
|
||||
|
||||
|
@ -113,9 +102,14 @@ class NotificationSyncer
|
|||
|
||||
// Create a notification record, and send an email, for all users
|
||||
// receiving this notification for the first time (we know because they
|
||||
// didn't have a record in the database).
|
||||
// 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->sendNotifications($blueprint, $newRecipients);
|
||||
$this->queue->push(new SendNotificationsJob($blueprint, $newRecipients));
|
||||
}
|
||||
|
||||
if ($blueprint instanceof MailableInterface) {
|
||||
$this->mailNotifications($blueprint, $newRecipients);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +121,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function delete(BlueprintInterface $blueprint)
|
||||
{
|
||||
Notification::where($this->getAttributes($blueprint))->update(['is_deleted' => true]);
|
||||
Notification::where(BlueprintBC::getAttributes($blueprint))->update(['is_deleted' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -138,7 +132,7 @@ class NotificationSyncer
|
|||
*/
|
||||
public function restore(BlueprintInterface $blueprint)
|
||||
{
|
||||
Notification::where($this->getAttributes($blueprint))->update(['is_deleted' => false]);
|
||||
Notification::where(BlueprintBC::getAttributes($blueprint))->update(['is_deleted' => false]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -158,35 +152,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.
|
||||
*
|
||||
|
@ -197,7 +162,7 @@ class NotificationSyncer
|
|||
{
|
||||
foreach ($recipients as $user) {
|
||||
if ($user->shouldEmail($blueprint::getType())) {
|
||||
$this->mailer->send($blueprint, $user);
|
||||
$this->queue->push(new SendEmailNotificationJob($blueprint, $user));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,21 +177,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