From 2be90d1caf60361b2ef9ad4d7e1669cb6e352388 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Sun, 17 May 2015 10:19:54 +0930 Subject: [PATCH] New object-based extension APIs --- .../core/src/Core/CoreServiceProvider.php | 17 +++-- .../NotificationServiceProvider.php | 5 +- framework/core/src/Extend/ApiInclude.php | 35 +++++++++ .../core/src/Extend/DiscussionGambit.php | 20 +++++ .../core/src/Extend/EventSubscribers.php | 20 +++++ .../core/src/Extend/ExtenderInterface.php | 8 ++ framework/core/src/Extend/Formatter.php | 24 ++++++ framework/core/src/Extend/ForumAssets.php | 20 +++++ .../core/src/Extend/NotificationType.php | 40 ++++++++++ framework/core/src/Extend/Permission.php | 19 +++++ framework/core/src/Extend/PostType.php | 19 +++++ framework/core/src/Extend/Relationship.php | 38 ++++++++++ .../core/src/Extend/SerializeAttributes.php | 26 +++++++ .../core/src/Extend/SerializeRelationship.php | 36 +++++++++ .../core/src/Support/ServiceProvider.php | 76 +------------------ 15 files changed, 322 insertions(+), 81 deletions(-) create mode 100644 framework/core/src/Extend/ApiInclude.php create mode 100644 framework/core/src/Extend/DiscussionGambit.php create mode 100644 framework/core/src/Extend/EventSubscribers.php create mode 100644 framework/core/src/Extend/ExtenderInterface.php create mode 100644 framework/core/src/Extend/Formatter.php create mode 100644 framework/core/src/Extend/ForumAssets.php create mode 100644 framework/core/src/Extend/NotificationType.php create mode 100644 framework/core/src/Extend/Permission.php create mode 100644 framework/core/src/Extend/PostType.php create mode 100644 framework/core/src/Extend/Relationship.php create mode 100644 framework/core/src/Extend/SerializeAttributes.php create mode 100644 framework/core/src/Extend/SerializeRelationship.php diff --git a/framework/core/src/Core/CoreServiceProvider.php b/framework/core/src/Core/CoreServiceProvider.php index 9ab64507f..f5cedf678 100644 --- a/framework/core/src/Core/CoreServiceProvider.php +++ b/framework/core/src/Core/CoreServiceProvider.php @@ -15,6 +15,7 @@ use Flarum\Core\Search\GambitManager; use League\Flysystem\Adapter\Local; use Flarum\Core\Events\RegisterDiscussionGambits; use Flarum\Core\Events\RegisterUserGambits; +use Flarum\Extend\Permission; class CoreServiceProvider extends ServiceProvider { @@ -138,13 +139,15 @@ class CoreServiceProvider extends ServiceProvider public function registerPermissions() { - $this->permission('forum.view'); - $this->permission('forum.startDiscussion'); - $this->permission('discussion.rename'); - $this->permission('discussion.delete'); - $this->permission('discussion.reply'); - $this->permission('post.edit'); - $this->permission('post.delete'); + $this->extend( + new Permission('forum.view'), + new Permission('forum.startDiscussion'), + new Permission('discussion.rename'), + new Permission('discussion.delete'), + new Permission('discussion.reply'), + new Permission('post.edit'), + new Permission('post.delete') + ); Forum::grantPermission(function ($grant, $user, $permission) { return $user->hasPermission('forum.'.$permission); diff --git a/framework/core/src/Core/Notifications/NotificationServiceProvider.php b/framework/core/src/Core/Notifications/NotificationServiceProvider.php index 964c57cc7..918ab2dbc 100644 --- a/framework/core/src/Core/Notifications/NotificationServiceProvider.php +++ b/framework/core/src/Core/Notifications/NotificationServiceProvider.php @@ -4,6 +4,7 @@ use Flarum\Support\ServiceProvider; use Flarum\Core\Models\User; use Flarum\Core\Notifications\Notifier; use Illuminate\Contracts\Events\Dispatcher; +use Flarum\Extend\NotificationType; class NotificationServiceProvider extends ServiceProvider { @@ -19,7 +20,9 @@ class NotificationServiceProvider extends ServiceProvider $notifier->registerMethod('alert', 'Flarum\Core\Notifications\Senders\NotificationAlerter'); $notifier->registerMethod('email', 'Flarum\Core\Notifications\Senders\NotificationEmailer'); - $this->notificationType('Flarum\Core\Notifications\Types\DiscussionRenamedNotification', ['alert' => true]); + $this->extend( + (new NotificationType('Flarum\Core\Notifications\Types\DiscussionRenamedNotification'))->enableByDefault('alert') + ); } public function register() diff --git a/framework/core/src/Extend/ApiInclude.php b/framework/core/src/Extend/ApiInclude.php new file mode 100644 index 000000000..5a1f21ced --- /dev/null +++ b/framework/core/src/Extend/ApiInclude.php @@ -0,0 +1,35 @@ +actions = $actions; + $this->relationships = $relationships; + $this->status = $status; + } + + public function extend(Application $app) + { + foreach ((array) $this->actions as $action) { + $parts = explode('.', $action); + $class = 'Flarum\Api\Actions\\'.ucfirst($parts[0]).'\\'.ucfirst($parts[1]).'Action'; + + foreach ((array) $this->relationships as $relationship) { + if (is_null($this->status)) { + unset($class::$include[$relationship]); + } else { + $class::$include[$relationship] = $this->status; + } + } + } + } +} diff --git a/framework/core/src/Extend/DiscussionGambit.php b/framework/core/src/Extend/DiscussionGambit.php new file mode 100644 index 000000000..e345409d2 --- /dev/null +++ b/framework/core/src/Extend/DiscussionGambit.php @@ -0,0 +1,20 @@ +class = $class; + } + + public function extend(Application $app) + { + $app['events']->listen('Flarum\Core\Events\RegisterDiscussionGambits', function ($event) { + $event->gambits->add($this->class); + }); + } +} diff --git a/framework/core/src/Extend/EventSubscribers.php b/framework/core/src/Extend/EventSubscribers.php new file mode 100644 index 000000000..4fdb95a28 --- /dev/null +++ b/framework/core/src/Extend/EventSubscribers.php @@ -0,0 +1,20 @@ +subscribers = $subscribers; + } + + public function extend(Application $app) + { + foreach ((array) $this->subscribers as $subscriber) { + $app['events']->subscribe($subscriber); + } + } +} diff --git a/framework/core/src/Extend/ExtenderInterface.php b/framework/core/src/Extend/ExtenderInterface.php new file mode 100644 index 000000000..0204c1520 --- /dev/null +++ b/framework/core/src/Extend/ExtenderInterface.php @@ -0,0 +1,8 @@ +name = $name; + $this->class = $class; + $this->priority = $priority; + } + + public function extend(Application $app) + { + $app['flarum.formatter']->add($this->name, $this->class, $this->priority); + } +} diff --git a/framework/core/src/Extend/ForumAssets.php b/framework/core/src/Extend/ForumAssets.php new file mode 100644 index 000000000..20fb0a260 --- /dev/null +++ b/framework/core/src/Extend/ForumAssets.php @@ -0,0 +1,20 @@ +files = $files; + } + + public function extend(Application $app) + { + $app['events']->listen('Flarum\Forum\Events\RenderView', function ($event) { + $event->assets->addFile($this->files); + }); + } +} diff --git a/framework/core/src/Extend/NotificationType.php b/framework/core/src/Extend/NotificationType.php new file mode 100644 index 000000000..89b91467d --- /dev/null +++ b/framework/core/src/Extend/NotificationType.php @@ -0,0 +1,40 @@ +class = $class; + } + + public function enableByDefault($method) + { + $this->enabled[] = $method; + + return $this; + } + + public function extend(Application $app) + { + $notifier = $app['flarum.notifier']; + $class = $this->class; + + $notifier->registerType($class); + + Notification::registerType($class); + + foreach ($notifier->getMethods() as $method => $sender) { + if ($sender::compatibleWith($class)) { + User::registerPreference(User::notificationPreferenceKey($class::getType(), $method), 'boolval', isset($this->enabled[$method])); + } + } + } +} diff --git a/framework/core/src/Extend/Permission.php b/framework/core/src/Extend/Permission.php new file mode 100644 index 000000000..d6a82efb7 --- /dev/null +++ b/framework/core/src/Extend/Permission.php @@ -0,0 +1,19 @@ +permission = $permission; + } + + public function extend(Application $app) + { + PermissionModel::addPermission($this->permission); + } +} diff --git a/framework/core/src/Extend/PostType.php b/framework/core/src/Extend/PostType.php new file mode 100644 index 000000000..df77ccb78 --- /dev/null +++ b/framework/core/src/Extend/PostType.php @@ -0,0 +1,19 @@ +class = $class; + } + + public function extend(Application $app) + { + Post::addType($this->class); + } +} diff --git a/framework/core/src/Extend/Relationship.php b/framework/core/src/Extend/Relationship.php new file mode 100644 index 000000000..895901f42 --- /dev/null +++ b/framework/core/src/Extend/Relationship.php @@ -0,0 +1,38 @@ +parent = $parent; + $this->type = $type; + $this->name = $name; + $this->child = $child; + } + + public function extend(Application $app) + { + $parent = $this->parent; + + $parent::addRelationship($this->name, function ($model) { + if ($this->type instanceof Closure) { + return $this->type($model); + } elseif ($this->type === 'belongsTo') { + return $model->belongsTo($this->child, null, null, $this->name); + } else { + // @todo + } + }); + } +} diff --git a/framework/core/src/Extend/SerializeAttributes.php b/framework/core/src/Extend/SerializeAttributes.php new file mode 100644 index 000000000..7e118f6f9 --- /dev/null +++ b/framework/core/src/Extend/SerializeAttributes.php @@ -0,0 +1,26 @@ +serializer = $serializer; + $this->callback = $callback; + } + + public function extend(Application $app) + { + $app['events']->listen('Flarum\Api\Events\SerializeAttributes', function ($event) { + if ($event->serializer instanceof $this->serializer) { + call_user_func($this->callback, $event->attributes, $event->model, $event->serializer); + } + }); + } +} diff --git a/framework/core/src/Extend/SerializeRelationship.php b/framework/core/src/Extend/SerializeRelationship.php new file mode 100644 index 000000000..e5c94a255 --- /dev/null +++ b/framework/core/src/Extend/SerializeRelationship.php @@ -0,0 +1,36 @@ +parent = $parent; + $this->type = $type; + $this->name = $name; + $this->child = $child; + } + + public function extend(Application $app) + { + $parent = $this->parent; + + $parent::addRelationship($this->name, function ($serializer) { + if ($this->type instanceof Closure) { + return $this->type(); + } else { + return $serializer->{$this->type}($this->child, $this->name); + } + }); + } +} diff --git a/framework/core/src/Support/ServiceProvider.php b/framework/core/src/Support/ServiceProvider.php index 831ab123a..55e1071f4 100644 --- a/framework/core/src/Support/ServiceProvider.php +++ b/framework/core/src/Support/ServiceProvider.php @@ -20,80 +20,10 @@ class ServiceProvider extends IlluminateServiceProvider // } - protected function forumAssets($assets) + public function extend() { - $this->app['events']->listen('Flarum\Forum\Events\RenderView', function ($event) use ($assets) { - $event->assets->addFile($assets); - }); - } - - protected function postType($class) - { - Post::addType($class); - } - - protected function discussionGambit($class) - { - $this->app['events']->listen('Flarum\Core\Events\RegisterDiscussionGambits', function ($event) use ($class) { - $event->gambits->add($class); - }); - } - - protected function formatter($name, $class, $priority = 0) - { - $this->app['flarum.formatter']->add($name, $class, $priority); - } - - protected function notificationType($class, $defaultPreferences = []) - { - $notifier = $this->app['flarum.notifier']; - - $notifier->registerType($class); - - Notification::registerType($class); - - foreach ($notifier->getMethods() as $method => $sender) { - if ($sender::compatibleWith($class)) { - User::registerPreference(User::notificationPreferenceKey($class::getType(), $method), 'boolval', array_get($defaultPreferences, $method, false)); - } + foreach (func_get_args() as $extender) { + $extender->extend($this->app); } } - - protected function relationship($parent, $type, $name, $child = null) - { - $parent::addRelationship($name, function ($model) use ($type, $name, $child) { - if ($type instanceof Closure) { - return $type($model); - } elseif ($type === 'belongsTo') { - return $model->belongsTo($child, null, null, $name); - } else { - // @todo - } - }); - } - - protected function serializeRelationship($parent, $type, $name, $child = null) - { - $parent::addRelationship($name, function ($serializer) use ($type, $name, $child) { - if ($type instanceof Closure) { - return $type(); - } else { - return $serializer->$type($child, $name); - } - }); - } - - protected function serializeAttributes($serializer, Closure $callback) - { - $this->app['events']->listen('Flarum\Api\Events\SerializeAttributes', function ($event) use ($serializer, $callback) { - if ($event->serializer instanceof $serializer) { - $callback($event->attributes, $event->model, $event->serializer); - } - }); - } - - protected function permission($permission) - { - Permission::addPermission($permission); - } }