From 3b3cbdc82f78ee744b447308ad0025292d0c8ff5 Mon Sep 17 00:00:00 2001 From: Alexander Skvortsov <38059171+askvortsov1@users.noreply.github.com> Date: Tue, 20 Apr 2021 14:51:01 -0400 Subject: [PATCH] Fix conflicts with other extension visibility scoping (#26) Wrapping all `wheres` in an `orWhere` ensures that there's no conflict. See https://github.com/flarum/core/issues/2798, https://github.com/flarum/docs/pull/200 --- .../ScopePrivateDiscussionVisibility.php | 29 +++++++++++-------- .../src/Access/ScopePrivatePostVisibility.php | 25 +++++++++------- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/extensions/approval/src/Access/ScopePrivateDiscussionVisibility.php b/extensions/approval/src/Access/ScopePrivateDiscussionVisibility.php index f88c07986..8f63c01e6 100644 --- a/extensions/approval/src/Access/ScopePrivateDiscussionVisibility.php +++ b/extensions/approval/src/Access/ScopePrivateDiscussionVisibility.php @@ -20,18 +20,23 @@ class ScopePrivateDiscussionVisibility */ public function __invoke(User $actor, Builder $query) { - // Show empty/private discussions if they require approval and they are - // authored by the current user, or the current user has permission to - // approve posts. - $query->where('discussions.is_approved', 0); + // All statements need to be wrapped in an orWhere, since we're adding a + // subset of private discussions that should be visible, not restricting the visible + // set. + $query->orWhere(function ($query) use ($actor) { + // Show empty/private discussions if they require approval and they are + // authored by the current user, or the current user has permission to + // approve posts. + $query->where('discussions.is_approved', 0); - if (! $actor->hasPermission('discussion.approvePosts')) { - $query->where(function (Builder $query) use ($actor) { - $query->where('discussions.user_id', $actor->id) - ->orWhere(function ($query) use ($actor) { - $query->whereVisibleTo($actor, 'approvePosts'); - }); - }); - } + if (! $actor->hasPermission('discussion.approvePosts')) { + $query->where(function (Builder $query) use ($actor) { + $query->where('discussions.user_id', $actor->id) + ->orWhere(function ($query) use ($actor) { + $query->whereVisibleTo($actor, 'approvePosts'); + }); + }); + } + }); } } diff --git a/extensions/approval/src/Access/ScopePrivatePostVisibility.php b/extensions/approval/src/Access/ScopePrivatePostVisibility.php index 2557d0599..070cb744f 100644 --- a/extensions/approval/src/Access/ScopePrivatePostVisibility.php +++ b/extensions/approval/src/Access/ScopePrivatePostVisibility.php @@ -21,17 +21,22 @@ class ScopePrivatePostVisibility */ public function __invoke(User $actor, Builder $query) { - // Show private posts if they require approval and they are - // authored by the current user, or the current user has permission to - // approve posts. - $query->where('posts.is_approved', 0); + // All statements need to be wrapped in an orWhere, since we're adding a + // subset of private posts that should be visible, not restricting the visible + // set. + $query->orWhere(function ($query) use ($actor) { + // Show private posts if they require approval and they are + // authored by the current user, or the current user has permission to + // approve posts. + $query->where('posts.is_approved', 0); - if (! $actor->hasPermission('discussion.approvePosts')) { - $query->where(function (Builder $query) use ($actor) { - $query->where('posts.user_id', $actor->id) - ->orWhereExists($this->discussionWhereCanApprovePosts($actor)); - }); - } + if (! $actor->hasPermission('discussion.approvePosts')) { + $query->where(function (Builder $query) use ($actor) { + $query->where('posts.user_id', $actor->id) + ->orWhereExists($this->discussionWhereCanApprovePosts($actor)); + }); + } + }); } private function discussionWhereCanApprovePosts(User $actor)