diff --git a/framework/core/src/Notification/Driver/GroupableNotificationDriverInterface.php b/framework/core/src/Notification/Driver/GroupableNotificationDriverInterface.php new file mode 100644 index 000000000..0e7921e3e --- /dev/null +++ b/framework/core/src/Notification/Driver/GroupableNotificationDriverInterface.php @@ -0,0 +1,16 @@ +blueprint = $blueprint; + $this->driver = $driver; + $this->user = $user; + } + + public function handle() + { + + } + + public function middleware() + { + return [ + (new WithoutOverlapping('delayed-blueprint-grouping:' . $this->user->id))->dontRelease() + ]; + } +} diff --git a/framework/core/src/Notification/NotificationSyncer.php b/framework/core/src/Notification/NotificationSyncer.php index 18d845a8d..564199bea 100644 --- a/framework/core/src/Notification/NotificationSyncer.php +++ b/framework/core/src/Notification/NotificationSyncer.php @@ -10,8 +10,11 @@ namespace Flarum\Notification; use Flarum\Notification\Blueprint\BlueprintInterface; +use Flarum\Notification\Driver\GroupableNotificationDriverInterface; use Flarum\Notification\Driver\NotificationDriverInterface; +use Flarum\Notification\Job\DelayedBlueprintGroupingJob; use Flarum\User\User; +use Illuminate\Contracts\Queue\Queue; /** * The Notification Syncer commits notification blueprints to the database, and @@ -47,6 +50,13 @@ class NotificationSyncer */ protected static $beforeSendingCallbacks = []; + private Queue $queue; + + public function __construct(Queue $queue) + { + $this->queue = $queue; + } + /** * Sync a notification so that it is visible to the specified users, and not * visible to anyone else. If it is being made visible for the first time, @@ -107,7 +117,21 @@ class NotificationSyncer // didn't have a record in the database). As both operations can be // intensive on resources (database and mail server), we queue them. foreach (static::getNotificationDrivers() as $driverName => $driver) { - $driver->send($blueprint, $newRecipients); + if ($driver instanceof GroupableNotificationDriverInterface) { + $delay = $driver->blueprintGroupingDelay(); + + foreach($newRecipients as $recipient) { + $job = new DelayedBlueprintGroupingJob( + $blueprint, + $recipient, + $driver + ); + + $this->queue->later($delay, $job); + } + } else { + $driver->send($blueprint, $newRecipients); + } } }