mirror of
https://github.com/flarum/framework.git
synced 2025-03-15 00:05:12 +08:00
Add Notification extender beforeSending method (#2533)
This commit is contained in:
parent
89e821e70f
commit
927ea4eec5
@ -10,6 +10,8 @@
|
||||
namespace Flarum\Extend;
|
||||
|
||||
use Flarum\Extension\Extension;
|
||||
use Flarum\Foundation\ContainerUtil;
|
||||
use Flarum\Notification\NotificationSyncer;
|
||||
use Illuminate\Contracts\Container\Container;
|
||||
|
||||
class Notification implements ExtenderInterface
|
||||
@ -18,6 +20,7 @@ class Notification implements ExtenderInterface
|
||||
private $serializers = [];
|
||||
private $drivers = [];
|
||||
private $typesEnabledByDefault = [];
|
||||
private $beforeSendingCallbacks = [];
|
||||
|
||||
/**
|
||||
* @param string $blueprint The ::class attribute of the blueprint class.
|
||||
@ -51,6 +54,17 @@ class Notification implements ExtenderInterface
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|string $callback
|
||||
* @return self
|
||||
*/
|
||||
public function beforeSending($callback)
|
||||
{
|
||||
$this->beforeSendingCallbacks[] = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function extend(Container $container, Extension $extension = null)
|
||||
{
|
||||
$container->extend('flarum.notification.blueprints', function ($existingBlueprints) {
|
||||
@ -74,5 +88,9 @@ class Notification implements ExtenderInterface
|
||||
$container->extend('flarum.notification.drivers', function ($existingDrivers) {
|
||||
return array_merge($existingDrivers, $this->drivers);
|
||||
});
|
||||
|
||||
foreach ($this->beforeSendingCallbacks as $callback) {
|
||||
NotificationSyncer::beforeSending(ContainerUtil::wrapCallback($callback, $container));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,11 @@ class NotificationSyncer
|
||||
*/
|
||||
protected static $notificationDrivers = [];
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $beforeSendingCallbacks = [];
|
||||
|
||||
/**
|
||||
* 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,
|
||||
@ -94,6 +99,10 @@ class NotificationSyncer
|
||||
$this->setDeleted($toUndelete, false);
|
||||
}
|
||||
|
||||
foreach (static::$beforeSendingCallbacks as $callback) {
|
||||
$newRecipients = $callback($blueprint, $newRecipients);
|
||||
}
|
||||
|
||||
// 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). As both operations can be
|
||||
@ -176,4 +185,12 @@ class NotificationSyncer
|
||||
{
|
||||
return static::$notificationDrivers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param callable|string $callback
|
||||
*/
|
||||
public static function beforeSending($callback): void
|
||||
{
|
||||
static::$beforeSendingCallbacks[] = $callback;
|
||||
}
|
||||
}
|
||||
|
@ -14,10 +14,14 @@ use Flarum\Notification\Blueprint\BlueprintInterface;
|
||||
use Flarum\Notification\Driver\NotificationDriverInterface;
|
||||
use Flarum\Notification\Notification;
|
||||
use Flarum\Notification\NotificationSyncer;
|
||||
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
|
||||
use Flarum\Tests\integration\TestCase;
|
||||
use Flarum\User\User;
|
||||
|
||||
class NotificationTest extends TestCase
|
||||
{
|
||||
use RetrievesAuthorizedUsers;
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
@ -119,23 +123,61 @@ class NotificationTest extends TestCase
|
||||
$this->assertContains('secondCustomDriver', $blueprints[SecondCustomNotificationType::class]);
|
||||
$this->assertEmpty($blueprints[ThirdCustomNotificationType::class]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function notification_before_sending_callback_works_if_added()
|
||||
{
|
||||
$this->extend(
|
||||
(new Extend\Notification)
|
||||
->type(CustomNotificationType::class, 'customNotificationTypeSerializer')
|
||||
->driver('customNotificationDriver', CustomNotificationDriver::class)
|
||||
->beforeSending(function ($blueprint, $users) {
|
||||
if ($blueprint instanceof CustomNotificationType) {
|
||||
unset($users[1]);
|
||||
}
|
||||
|
||||
return $users;
|
||||
})
|
||||
);
|
||||
|
||||
$this->prepareDatabase([
|
||||
'users' => [
|
||||
$this->adminUser(),
|
||||
$this->normalUser(),
|
||||
['id' => 3, 'username' => 'hani']
|
||||
],
|
||||
]);
|
||||
|
||||
$this->app();
|
||||
|
||||
$users = User::whereIn('id', [1, 2, 3])->get()->all();
|
||||
|
||||
$notificationSyncer = $this->app()->getContainer()->make(NotificationSyncer::class);
|
||||
$notificationSyncer->sync(new CustomNotificationType(), $users);
|
||||
|
||||
$this->assertEquals('potato', $users[0]->username);
|
||||
$this->assertEquals('normal', $users[1]->username);
|
||||
$this->assertEquals('potato', $users[2]->username);
|
||||
}
|
||||
}
|
||||
|
||||
class CustomNotificationType implements BlueprintInterface
|
||||
{
|
||||
public function getFromUser()
|
||||
{
|
||||
// ...
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getSubject()
|
||||
{
|
||||
// ...
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getData()
|
||||
{
|
||||
// ...
|
||||
return [];
|
||||
}
|
||||
|
||||
public static function getType()
|
||||
@ -169,7 +211,9 @@ class CustomNotificationDriver implements NotificationDriverInterface
|
||||
{
|
||||
public function send(BlueprintInterface $blueprint, array $users): void
|
||||
{
|
||||
// ...
|
||||
foreach ($users as $user) {
|
||||
$user->username = 'potato';
|
||||
}
|
||||
}
|
||||
|
||||
public function registerType(string $blueprintClass, array $driversEnabledByDefault): void
|
||||
|
Loading…
x
Reference in New Issue
Block a user