1
0
mirror of https://github.com/flarum/core.git synced 2025-07-20 00:01:17 +02:00

Add Notification extender beforeSending method (#2533)

This commit is contained in:
Sami Mazouz
2021-01-19 20:40:19 +01:00
committed by GitHub
parent c12bf937f5
commit 88ef99b13c
3 changed files with 83 additions and 4 deletions

View File

@@ -10,6 +10,8 @@
namespace Flarum\Extend; namespace Flarum\Extend;
use Flarum\Extension\Extension; use Flarum\Extension\Extension;
use Flarum\Foundation\ContainerUtil;
use Flarum\Notification\NotificationSyncer;
use Illuminate\Contracts\Container\Container; use Illuminate\Contracts\Container\Container;
class Notification implements ExtenderInterface class Notification implements ExtenderInterface
@@ -18,6 +20,7 @@ class Notification implements ExtenderInterface
private $serializers = []; private $serializers = [];
private $drivers = []; private $drivers = [];
private $typesEnabledByDefault = []; private $typesEnabledByDefault = [];
private $beforeSendingCallbacks = [];
/** /**
* @param string $blueprint The ::class attribute of the blueprint class. * @param string $blueprint The ::class attribute of the blueprint class.
@@ -51,6 +54,17 @@ class Notification implements ExtenderInterface
return $this; 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) public function extend(Container $container, Extension $extension = null)
{ {
$container->extend('flarum.notification.blueprints', function ($existingBlueprints) { $container->extend('flarum.notification.blueprints', function ($existingBlueprints) {
@@ -74,5 +88,9 @@ class Notification implements ExtenderInterface
$container->extend('flarum.notification.drivers', function ($existingDrivers) { $container->extend('flarum.notification.drivers', function ($existingDrivers) {
return array_merge($existingDrivers, $this->drivers); return array_merge($existingDrivers, $this->drivers);
}); });
foreach ($this->beforeSendingCallbacks as $callback) {
NotificationSyncer::beforeSending(ContainerUtil::wrapCallback($callback, $container));
}
} }
} }

View File

@@ -43,6 +43,11 @@ class NotificationSyncer
*/ */
protected static $notificationDrivers = []; protected static $notificationDrivers = [];
/**
* @var array
*/
protected static $beforeSendingCallbacks = [];
/** /**
* Sync a notification so that it is visible to the specified users, and not * 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, * visible to anyone else. If it is being made visible for the first time,
@@ -94,6 +99,10 @@ class NotificationSyncer
$this->setDeleted($toUndelete, false); $this->setDeleted($toUndelete, false);
} }
foreach (static::$beforeSendingCallbacks as $callback) {
$newRecipients = $callback($blueprint, $newRecipients);
}
// Create a notification record, and send an email, for all users // Create a notification record, and send an email, for all users
// receiving this notification for the first time (we know because they // receiving this notification for the first time (we know because they
// didn't have a record in the database). As both operations can be // didn't have a record in the database). As both operations can be
@@ -176,4 +185,12 @@ class NotificationSyncer
{ {
return static::$notificationDrivers; return static::$notificationDrivers;
} }
/**
* @param callable|string $callback
*/
public static function beforeSending($callback): void
{
static::$beforeSendingCallbacks[] = $callback;
}
} }

View File

@@ -14,10 +14,14 @@ use Flarum\Notification\Blueprint\BlueprintInterface;
use Flarum\Notification\Driver\NotificationDriverInterface; use Flarum\Notification\Driver\NotificationDriverInterface;
use Flarum\Notification\Notification; use Flarum\Notification\Notification;
use Flarum\Notification\NotificationSyncer; use Flarum\Notification\NotificationSyncer;
use Flarum\Tests\integration\RetrievesAuthorizedUsers;
use Flarum\Tests\integration\TestCase; use Flarum\Tests\integration\TestCase;
use Flarum\User\User;
class NotificationTest extends TestCase class NotificationTest extends TestCase
{ {
use RetrievesAuthorizedUsers;
/** /**
* @test * @test
*/ */
@@ -119,23 +123,61 @@ class NotificationTest extends TestCase
$this->assertContains('secondCustomDriver', $blueprints[SecondCustomNotificationType::class]); $this->assertContains('secondCustomDriver', $blueprints[SecondCustomNotificationType::class]);
$this->assertEmpty($blueprints[ThirdCustomNotificationType::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 class CustomNotificationType implements BlueprintInterface
{ {
public function getFromUser() public function getFromUser()
{ {
// ... return null;
} }
public function getSubject() public function getSubject()
{ {
// ... return null;
} }
public function getData() public function getData()
{ {
// ... return [];
} }
public static function getType() public static function getType()
@@ -169,7 +211,9 @@ class CustomNotificationDriver implements NotificationDriverInterface
{ {
public function send(BlueprintInterface $blueprint, array $users): void public function send(BlueprintInterface $blueprint, array $users): void
{ {
// ... foreach ($users as $user) {
$user->username = 'potato';
}
} }
public function registerType(string $blueprintClass, array $driversEnabledByDefault): void public function registerType(string $blueprintClass, array $driversEnabledByDefault): void