From 00e34a836f232817c94e78d2f6d578a5fc5e2919 Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Tue, 8 Dec 2020 17:43:56 +0100 Subject: [PATCH] Use new extenders (#34) --- extend.php | 47 +++++++-- src/AddCanFlagAttribute.php | 46 ++++++++ src/AddFlagsApiAttributes.php | 52 +++++++++ src/AddNewFlagCountAttribute.php | 36 +++++++ src/Listener/AddFlagsApiAttributes.php | 90 ---------------- src/Listener/AddPostFlagsRelationship.php | 123 ---------------------- src/Listener/DeleteFlags.php | 23 ++++ src/PrepareFlagsApiData.php | 63 +++++++++++ 8 files changed, 260 insertions(+), 220 deletions(-) create mode 100644 src/AddCanFlagAttribute.php create mode 100755 src/AddFlagsApiAttributes.php create mode 100644 src/AddNewFlagCountAttribute.php delete mode 100755 src/Listener/AddFlagsApiAttributes.php delete mode 100755 src/Listener/AddPostFlagsRelationship.php create mode 100644 src/Listener/DeleteFlags.php create mode 100755 src/PrepareFlagsApiData.php diff --git a/extend.php b/extend.php index 53c460e..8f1b835 100644 --- a/extend.php +++ b/extend.php @@ -7,17 +7,28 @@ * LICENSE file that was distributed with this source code. */ -use Flarum\Api\Event\Serializing; +use Flarum\Api\Controller\AbstractSerializeController; +use Flarum\Api\Controller\ListPostsController; +use Flarum\Api\Controller\ShowDiscussionController; +use Flarum\Api\Controller\ShowPostController; +use Flarum\Api\Serializer\CurrentUserSerializer; +use Flarum\Api\Serializer\ForumSerializer; +use Flarum\Api\Serializer\PostSerializer; use Flarum\Extend; +use Flarum\Flags\AddCanFlagAttribute; +use Flarum\Flags\AddFlagsApiAttributes; +use Flarum\Flags\AddNewFlagCountAttribute; use Flarum\Flags\Api\Controller\CreateFlagController; use Flarum\Flags\Api\Controller\DeleteFlagsController; use Flarum\Flags\Api\Controller\ListFlagsController; +use Flarum\Flags\Api\Serializer\FlagSerializer; use Flarum\Flags\Flag; use Flarum\Flags\Listener; +use Flarum\Flags\PrepareFlagsApiData; use Flarum\Forum\Content\AssertRegistered; +use Flarum\Post\Event\Deleted; use Flarum\Post\Post; use Flarum\User\User; -use Illuminate\Contracts\Events\Dispatcher; return [ (new Extend\Frontend('forum')) @@ -39,11 +50,33 @@ (new Extend\Model(Post::class)) ->hasMany('flags', Flag::class, 'post_id'), - new Extend\Locales(__DIR__.'/locale'), + (new Extend\ApiSerializer(PostSerializer::class)) + ->hasMany('flags', FlagSerializer::class) + ->attribute('canFlag', AddCanFlagAttribute::class), + + (new Extend\ApiSerializer(CurrentUserSerializer::class)) + ->attribute('newFlagCount', AddNewFlagCountAttribute::class), + + (new Extend\ApiSerializer(ForumSerializer::class)) + ->mutate(AddFlagsApiAttributes::class), + + (new Extend\ApiController(ShowDiscussionController::class)) + ->addInclude(['posts.flags', 'posts.flags.user']), + + (new Extend\ApiController(ListPostsController::class)) + ->addInclude(['flags', 'flags.user']), - function (Dispatcher $events) { - $events->listen(Serializing::class, Listener\AddFlagsApiAttributes::class); + (new Extend\ApiController(ShowPostController::class)) + ->addInclude(['flags', 'flags.user']), - $events->subscribe(Listener\AddPostFlagsRelationship::class); - }, + (new Extend\ApiController(AbstractSerializeController::class)) + ->prepareDataForSerialization(PrepareFlagsApiData::class), + + (new Extend\Settings()) + ->serializeToForum('guidelinesUrl', 'flarum-flags.guidelines_url'), + + (new Extend\Event()) + ->listen(Deleted::class, Listener\DeleteFlags::class), + + new Extend\Locales(__DIR__.'/locale'), ]; diff --git a/src/AddCanFlagAttribute.php b/src/AddCanFlagAttribute.php new file mode 100644 index 0000000..da354da --- /dev/null +++ b/src/AddCanFlagAttribute.php @@ -0,0 +1,46 @@ +settings = $settings; + } + + public function __invoke(PostSerializer $serializer, Post $post) + { + return $serializer->getActor()->can('flag', $post) && $this->checkFlagOwnPostSetting($serializer->getActor(), $post); + } + + protected function checkFlagOwnPostSetting(User $actor, Post $post): bool + { + if ($actor->id === $post->user_id) { + // If $actor is the post author, check to see if the setting is enabled + return (bool) $this->settings->get('flarum-flags.can_flag_own'); + } + // $actor is not the post author + return true; + } +} diff --git a/src/AddFlagsApiAttributes.php b/src/AddFlagsApiAttributes.php new file mode 100755 index 0000000..c687bd0 --- /dev/null +++ b/src/AddFlagsApiAttributes.php @@ -0,0 +1,52 @@ +settings = $settings; + } + + public function __invoke(ForumSerializer $serializer) + { + $attributes = [ + 'canViewFlags' => $serializer->getActor()->hasPermissionLike('discussion.viewFlags') + ]; + + if ($attributes['canViewFlags']) { + $attributes['flagCount'] = (int) $this->getFlagCount($serializer->getActor()); + } + + return $attributes; + } + + /** + * @param User $actor + * @return int + */ + protected function getFlagCount(User $actor) + { + return Flag::whereVisibleTo($actor)->distinct()->count('flags.post_id'); + } +} diff --git a/src/AddNewFlagCountAttribute.php b/src/AddNewFlagCountAttribute.php new file mode 100644 index 0000000..b7f6501 --- /dev/null +++ b/src/AddNewFlagCountAttribute.php @@ -0,0 +1,36 @@ +getNewFlagCount($user); + } + + /** + * @param User $actor + * @return int + */ + protected function getNewFlagCount(User $actor) + { + $query = Flag::whereVisibleTo($actor); + + if ($time = $actor->read_flags_at) { + $query->where('flags.created_at', '>', $time); + } + + return $query->distinct()->count('flags.post_id'); + } +} diff --git a/src/Listener/AddFlagsApiAttributes.php b/src/Listener/AddFlagsApiAttributes.php deleted file mode 100755 index 6fbab4b..0000000 --- a/src/Listener/AddFlagsApiAttributes.php +++ /dev/null @@ -1,90 +0,0 @@ -settings = $settings; - } - - public function handle(Serializing $event) - { - if ($event->isSerializer(ForumSerializer::class)) { - $event->attributes['canViewFlags'] = $event->actor->hasPermissionLike('discussion.viewFlags'); - - if ($event->attributes['canViewFlags']) { - $event->attributes['flagCount'] = (int) $this->getFlagCount($event->actor); - } - - $event->attributes['guidelinesUrl'] = $this->settings->get('flarum-flags.guidelines_url'); - } - - if ($event->isSerializer(CurrentUserSerializer::class)) { - $event->attributes['newFlagCount'] = (int) $this->getNewFlagCount($event->model); - } - - if ($event->isSerializer(PostSerializer::class)) { - $event->attributes['canFlag'] = $event->actor->can('flag', $event->model) && $this->checkFlagOwnPostSetting($event->actor, $event->model); - } - } - - /** - * @param User $actor - * @return int - */ - protected function getFlagCount(User $actor) - { - return Flag::whereVisibleTo($actor)->distinct()->count('flags.post_id'); - } - - /** - * @param User $actor - * @return int - */ - protected function getNewFlagCount(User $actor) - { - $query = Flag::whereVisibleTo($actor); - - if ($time = $actor->read_flags_at) { - $query->where('flags.created_at', '>', $time); - } - - return $query->distinct()->count('flags.post_id'); - } - - protected function checkFlagOwnPostSetting(User $actor, Post $post): bool - { - if ($actor->id === $post->user_id) { - // If $actor is the post author, check to see if the setting is enabled - return (bool) $this->settings->get('flarum-flags.can_flag_own'); - } - // $actor is not the post author - return true; - } -} diff --git a/src/Listener/AddPostFlagsRelationship.php b/src/Listener/AddPostFlagsRelationship.php deleted file mode 100755 index 70a775f..0000000 --- a/src/Listener/AddPostFlagsRelationship.php +++ /dev/null @@ -1,123 +0,0 @@ -listen(Deleted::class, [$this, 'postWasDeleted']); - $events->listen(GetApiRelationship::class, [$this, 'getApiRelationship']); - $events->listen(WillGetData::class, [$this, 'includeFlagsRelationship']); - $events->listen(WillSerializeData::class, [$this, 'prepareApiData']); - } - - /** - * @param Deleted $event - */ - public function postWasDeleted(Deleted $event) - { - $event->post->flags()->delete(); - } - - /** - * @param GetApiRelationship $event - * @return \Tobscure\JsonApi\Relationship|null - */ - public function getApiRelationship(GetApiRelationship $event) - { - if ($event->isRelationship(PostSerializer::class, 'flags')) { - return $event->serializer->hasMany($event->model, FlagSerializer::class, 'flags'); - } - } - - /** - * @param WillGetData $event - */ - public function includeFlagsRelationship(WillGetData $event) - { - if ($event->isController(Controller\ShowDiscussionController::class)) { - $event->addInclude([ - 'posts.flags', - 'posts.flags.user' - ]); - } - - if ($event->isController(Controller\ListPostsController::class) - || $event->isController(Controller\ShowPostController::class)) { - $event->addInclude([ - 'flags', - 'flags.user' - ]); - } - } - - /** - * @param WillSerializeData $event - */ - public function prepareApiData(WillSerializeData $event) - { - // For any API action that allows the 'flags' relationship to be - // included, we need to preload this relationship onto the data (Post - // models) so that we can selectively expose only the flags that the - // user has permission to view. - if ($event->isController(Controller\ShowDiscussionController::class)) { - if ($event->data->relationLoaded('posts')) { - $posts = $event->data->getRelation('posts'); - } - } - - if ($event->isController(Controller\ListPostsController::class)) { - $posts = $event->data->all(); - } - - if ($event->isController(Controller\ShowPostController::class)) { - $posts = [$event->data]; - } - - if ($event->isController(CreateFlagController::class)) { - $posts = [$event->data->post]; - } - - if (isset($posts)) { - $actor = $event->request->getAttribute('actor'); - $postsWithPermission = []; - - foreach ($posts as $post) { - if (is_object($post)) { - $post->setRelation('flags', null); - - if ($actor->can('viewFlags', $post->discussion)) { - $postsWithPermission[] = $post; - } - } - } - - if (count($postsWithPermission)) { - (new Collection($postsWithPermission)) - ->load('flags', 'flags.user'); - } - } - } -} diff --git a/src/Listener/DeleteFlags.php b/src/Listener/DeleteFlags.php new file mode 100644 index 0000000..b959f99 --- /dev/null +++ b/src/Listener/DeleteFlags.php @@ -0,0 +1,23 @@ +post->flags()->delete(); + } +} diff --git a/src/PrepareFlagsApiData.php b/src/PrepareFlagsApiData.php new file mode 100755 index 0000000..6934b23 --- /dev/null +++ b/src/PrepareFlagsApiData.php @@ -0,0 +1,63 @@ +relationLoaded('posts')) { + $posts = $data->getRelation('posts'); + } + } + + if ($controller instanceof Controller\ListPostsController) { + $posts = $data->all(); + } + + if ($controller instanceof Controller\ShowPostController) { + $posts = [$data]; + } + + if ($controller instanceof CreateFlagController) { + $posts = [$data->post]; + } + + if (isset($posts)) { + $actor = $request->getAttribute('actor'); + $postsWithPermission = []; + + foreach ($posts as $post) { + if (is_object($post)) { + $post->setRelation('flags', null); + + if ($actor->can('viewFlags', $post->discussion)) { + $postsWithPermission[] = $post; + } + } + } + + if (count($postsWithPermission)) { + (new Collection($postsWithPermission)) + ->load('flags', 'flags.user'); + } + } + } +}