diff --git a/framework/core/src/Api/ApiServiceProvider.php b/framework/core/src/Api/ApiServiceProvider.php index 83b74f1ce..aa2e53eae 100644 --- a/framework/core/src/Api/ApiServiceProvider.php +++ b/framework/core/src/Api/ApiServiceProvider.php @@ -75,6 +75,12 @@ class ApiServiceProvider extends AbstractServiceProvider return $pipe; }); + + $this->app->singleton('flarum.api.notification_serializers', function () { + return [ + 'discussionRenamed' => BasicDiscussionSerializer::class + ]; + }); } /** @@ -82,7 +88,7 @@ class ApiServiceProvider extends AbstractServiceProvider */ public function boot() { - $this->registerNotificationSerializers(); + $this->setNotificationSerializers(); AbstractSerializeController::setContainer($this->app); AbstractSerializeController::setEventDispatcher($events = $this->app->make('events')); @@ -94,13 +100,12 @@ class ApiServiceProvider extends AbstractServiceProvider /** * Register notification serializers. */ - protected function registerNotificationSerializers() + protected function setNotificationSerializers() { $blueprints = []; - $serializers = [ - 'discussionRenamed' => BasicDiscussionSerializer::class - ]; + $serializers = $this->app->make('flarum.api.notification_serializers'); + // Deprecated in beta 15, remove in beta 16 $this->app->make('events')->dispatch( new ConfigureNotificationTypes($blueprints, $serializers) ); diff --git a/framework/core/src/Event/ConfigureNotificationTypes.php b/framework/core/src/Event/ConfigureNotificationTypes.php index bca7296ac..89185b916 100644 --- a/framework/core/src/Event/ConfigureNotificationTypes.php +++ b/framework/core/src/Event/ConfigureNotificationTypes.php @@ -13,6 +13,9 @@ use Flarum\Notification\Blueprint\BlueprintInterface; use InvalidArgumentException; use ReflectionClass; +/** + * @deprecated in beta 15, removed in beta 16 + */ class ConfigureNotificationTypes { /** diff --git a/framework/core/src/Extend/Notification.php b/framework/core/src/Extend/Notification.php new file mode 100644 index 000000000..ad91e18bb --- /dev/null +++ b/framework/core/src/Extend/Notification.php @@ -0,0 +1,38 @@ +blueprints[$blueprint] = $channelsEnabledByDefault; + $this->serializers[$blueprint::getType()] = $serializer; + + return $this; + } + + public function extend(Container $container, Extension $extension = null) + { + $container->extend('flarum.notification.blueprints', function ($existingBlueprints) { + return array_merge($existingBlueprints, $this->blueprints); + }); + + $container->extend('flarum.api.notification_serializers', function ($existingSerializers) { + return array_merge($existingSerializers, $this->serializers); + }); + } +} diff --git a/framework/core/src/Notification/NotificationServiceProvider.php b/framework/core/src/Notification/NotificationServiceProvider.php index 3715cb3a5..c7cca3217 100644 --- a/framework/core/src/Notification/NotificationServiceProvider.php +++ b/framework/core/src/Notification/NotificationServiceProvider.php @@ -17,46 +17,62 @@ use ReflectionClass; class NotificationServiceProvider extends AbstractServiceProvider { + /** + * {@inheritdoc} + */ + public function register() + { + $this->app->singleton('flarum.notification.blueprints', function () { + return [ + DiscussionRenamedBlueprint::class => ['alert'] + ]; + }); + } + /** * {@inheritdoc} */ public function boot() { - $this->registerNotificationTypes(); + $this->setNotificationTypes(); } /** * Register notification types. */ - public function registerNotificationTypes() + protected function setNotificationTypes() { - $blueprints = [ - DiscussionRenamedBlueprint::class => ['alert'] - ]; + $blueprints = $this->app->make('flarum.notification.blueprints'); + // Deprecated in beta 15, remove in beta 16 $this->app->make('events')->dispatch( new ConfigureNotificationTypes($blueprints) ); - foreach ($blueprints as $blueprint => $enabled) { - Notification::setSubjectModel( - $type = $blueprint::getType(), - $blueprint::getSubjectModel() - ); + foreach ($blueprints as $blueprint => $channelsEnabledByDefault) { + $this->addType($blueprint, $channelsEnabledByDefault); + } + } + protected function addType(string $blueprint, array $channelsEnabledByDefault) + { + Notification::setSubjectModel( + $type = $blueprint::getType(), + $blueprint::getSubjectModel() + ); + + User::addPreference( + User::getNotificationPreferenceKey($type, 'alert'), + 'boolval', + in_array('alert', $channelsEnabledByDefault) + ); + + if ((new ReflectionClass($blueprint))->implementsInterface(MailableInterface::class)) { User::addPreference( - User::getNotificationPreferenceKey($type, 'alert'), + User::getNotificationPreferenceKey($type, 'email'), 'boolval', - in_array('alert', $enabled) + in_array('email', $channelsEnabledByDefault) ); - - if ((new ReflectionClass($blueprint))->implementsInterface(MailableInterface::class)) { - User::addPreference( - User::getNotificationPreferenceKey($type, 'email'), - 'boolval', - in_array('email', $enabled) - ); - } } } } diff --git a/framework/core/tests/integration/extenders/NotificationTest.php b/framework/core/tests/integration/extenders/NotificationTest.php new file mode 100644 index 000000000..03388e529 --- /dev/null +++ b/framework/core/tests/integration/extenders/NotificationTest.php @@ -0,0 +1,68 @@ +assertArrayNotHasKey('customNotificationType', Notification::getSubjectModels()); + } + + /** + * @test + */ + public function notification_type_exists_if_added() + { + $this->extend((new Extend\Notification)->type( + CustomNotificationType::class, + 'customNotificationTypeSerializer' + )); + + $this->app(); + + $this->assertArrayHasKey('customNotificationType', Notification::getSubjectModels()); + } +} + +class CustomNotificationType implements BlueprintInterface +{ + public function getFromUser() + { + // ... + } + + public function getSubject() + { + // ... + } + + public function getData() + { + // ... + } + + public static function getType() + { + return 'customNotificationType'; + } + + public static function getSubjectModel() + { + return 'customNotificationTypeSubjectModel'; + } +}