From 0661371180cd85c532c09a3ecfba5654b03d9011 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Fri, 4 Sep 2015 12:22:27 +0930 Subject: [PATCH] Improve some post/discussion permission logic - Allow users to see their own posts, even if they have been hidden by someone else - Don't require hiding a post to be necessarily attributed to a user - Hide discussions with zero posts, unless the user can edit posts, or they are the discussion author --- .../DiscussionsServiceProvider.php | 15 +++++++ framework/core/src/Core/Posts/CommentPost.php | 4 +- .../src/Core/Posts/PostsServiceProvider.php | 8 ++-- .../Events/ScopeEmptyDiscussionVisibility.php | 40 +++++++++++++++++++ 4 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 framework/core/src/Events/ScopeEmptyDiscussionVisibility.php diff --git a/framework/core/src/Core/Discussions/DiscussionsServiceProvider.php b/framework/core/src/Core/Discussions/DiscussionsServiceProvider.php index d128eefab..dc7f2c532 100644 --- a/framework/core/src/Core/Discussions/DiscussionsServiceProvider.php +++ b/framework/core/src/Core/Discussions/DiscussionsServiceProvider.php @@ -13,7 +13,9 @@ namespace Flarum\Core\Discussions; use Flarum\Core\Search\GambitManager; use Flarum\Core\Users\User; use Flarum\Events\ModelAllow; +use Flarum\Events\ScopeModelVisibility; use Flarum\Events\RegisterDiscussionGambits; +use Flarum\Events\ScopeEmptyDiscussionVisibility; use Flarum\Support\ServiceProvider; use Flarum\Extend; use Illuminate\Contracts\Container\Container; @@ -53,6 +55,19 @@ class DiscussionsServiceProvider extends ServiceProvider } } }); + + $events->listen(ScopeModelVisibility::class, function (ScopeModelVisibility $event) { + if ($event->model instanceof Discussion) { + if (! $event->actor->hasPermission('discussion.editPosts')) { + $event->query->where(function ($query) use ($event) { + $query->where('comments_count', '>', '0') + ->orWhere('start_user_id', $event->actor->id); + + event(new ScopeEmptyDiscussionVisibility($query, $event->actor)); + }); + } + } + }); } /** diff --git a/framework/core/src/Core/Posts/CommentPost.php b/framework/core/src/Core/Posts/CommentPost.php index eb55b6cec..580be793a 100755 --- a/framework/core/src/Core/Posts/CommentPost.php +++ b/framework/core/src/Core/Posts/CommentPost.php @@ -87,7 +87,7 @@ class CommentPost extends Post * @param User $actor * @return $this */ - public function hide(User $actor) + public function hide(User $actor = null) { if ($this->number == 1) { throw new DomainException('Cannot hide the first post of a discussion'); @@ -95,7 +95,7 @@ class CommentPost extends Post if (! $this->hide_time) { $this->hide_time = time(); - $this->hide_user_id = $actor->id; + $this->hide_user_id = $actor ? $actor->id : null; $this->raise(new PostWasHidden($this)); } diff --git a/framework/core/src/Core/Posts/PostsServiceProvider.php b/framework/core/src/Core/Posts/PostsServiceProvider.php index d55ccdc67..1b18706aa 100644 --- a/framework/core/src/Core/Posts/PostsServiceProvider.php +++ b/framework/core/src/Core/Posts/PostsServiceProvider.php @@ -44,7 +44,7 @@ class PostsServiceProvider extends ServiceProvider $actor = $event->actor; if ($action === 'view' && - (! $post->hide_user_id || $post->hide_user_id == $actor->id || $post->can($actor, 'edit'))) { + (! $post->hide_time || $post->user_id == $actor->id || $post->can($actor, 'edit'))) { return true; } @@ -55,7 +55,7 @@ class PostsServiceProvider extends ServiceProvider if ($post->discussion->can($actor, 'editPosts')) { return true; } - if ($post->user_id == $actor->id && (! $post->hide_user_id || $post->hide_user_id == $actor->id)) { + if ($post->user_id == $actor->id && (! $post->hide_time || $post->hide_user_id == $actor->id)) { $allowEditing = $settings->get('allow_post_editing'); if ($allowEditing === '-1' || @@ -80,8 +80,8 @@ class PostsServiceProvider extends ServiceProvider if (! $event->discussion->can($user, 'editPosts')) { $event->query->where(function ($query) use ($user) { - $query->whereNull('hide_user_id') - ->orWhere('hide_user_id', $user->id); + $query->whereNull('hide_time') + ->orWhere('user_id', $user->id); }); } }); diff --git a/framework/core/src/Events/ScopeEmptyDiscussionVisibility.php b/framework/core/src/Events/ScopeEmptyDiscussionVisibility.php new file mode 100644 index 000000000..1f0299e25 --- /dev/null +++ b/framework/core/src/Events/ScopeEmptyDiscussionVisibility.php @@ -0,0 +1,40 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Flarum\Events; + +use Flarum\Core\Users\User; +use Illuminate\Database\Eloquent\Builder; + +/** + * The `ScopeEmptyDiscussionVisibility` event + */ +class ScopeEmptyDiscussionVisibility +{ + /** + * @var Builder + */ + public $query; + + /** + * @var User + */ + public $actor; + + /** + * @param Builder $query + * @param User $actor + */ + public function __construct(Builder $query, User $actor) + { + $this->query = $query; + $this->actor = $actor; + } +}