Scope Report and empty discussion visibility by tag

This commit is contained in:
Toby Zerner 2015-09-04 11:34:23 +09:30
parent 0477cc0346
commit 5e725839b0
3 changed files with 52 additions and 5 deletions

View File

@ -1,9 +1,11 @@
<?php namespace Flarum\Tags\Listeners;
use Flarum\Events\ScopeModelVisibility;
use Flarum\Events\ScopeEmptyDiscussionVisibility;
use Flarum\Events\ModelAllow;
use Flarum\Core\Discussions\Discussion;
use Flarum\Tags\Tag;
use Flarum\Reports\Report;
use Illuminate\Database\Query\Expression;
class ConfigureDiscussionPermissions
@ -11,6 +13,7 @@ class ConfigureDiscussionPermissions
public function subscribe($events)
{
$events->listen(ScopeModelVisibility::class, [$this, 'scopeDiscussionVisibility']);
$events->listen(ScopeEmptyDiscussionVisibility::class, [$this, 'scopeEmptyDiscussionVisibility']);
$events->listen(ModelAllow::class, [$this, 'allowDiscussionPermissions']);
}
@ -19,12 +22,35 @@ class ConfigureDiscussionPermissions
// Hide discussions which have tags that the user is not allowed to see.
if ($event->model instanceof Discussion) {
$event->query->whereNotExists(function ($query) use ($event) {
return $query->select(app('flarum.db')->raw(1))
return $query->select(new Expression(1))
->from('discussions_tags')
->whereIn('tag_id', Tag::getNotVisibleTo($event->actor))
->whereIn('tag_id', Tag::getIdsWhereCannot($event->actor, 'view'))
->where('discussions.id', new Expression('discussion_id'));
});
}
if ($event->model instanceof Report) {
$event->query
->select('reports.*')
->leftJoin('posts', 'posts.id', '=', 'reports.post_id')
->leftJoin('discussions', 'discussions.id', '=', 'posts.discussion_id')
->whereNotExists(function ($query) use ($event) {
return $query->select(new Expression(1))
->from('discussions_tags')
->whereIn('tag_id', Tag::getIdsWhereCannot($event->actor, 'discussion.viewReports'))
->where('discussions.id', new Expression('discussion_id'));
});
}
}
public function scopeEmptyDiscussionVisibility(ScopeEmptyDiscussionVisibility $event)
{
$event->query->orWhereExists(function ($query) use ($event) {
return $query->select(new Expression(1))
->from('discussions_tags')
->whereIn('tag_id', Tag::getIdsWhereCan($event->actor, 'discussion.editPosts'))
->where('discussions.id', new Expression('discussion_id'));
});
}
public function allowDiscussionPermissions(ModelAllow $event)

View File

@ -15,7 +15,7 @@ class ConfigureTagPermissions
public function scopeTagVisibility(ScopeModelVisibility $event)
{
if ($event->model instanceof Tag) {
$event->query->whereNotIn('id', Tag::getNotVisibleTo($event->actor));
$event->query->whereNotIn('id', Tag::getIdsWhereCannot($event->actor, 'view'));
}
}

View File

@ -104,7 +104,7 @@ class Tag extends Model
return $this;
}
public static function getNotVisibleTo($user)
public static function getIdsWhereCan($user, $permission)
{
static $tags;
@ -113,9 +113,30 @@ class Tag extends Model
}
$ids = [];
$hasGlobalPermission = $user->hasPermission($permission);
foreach ($tags as $tag) {
if ($tag->is_restricted && ! $user->hasPermission('tag' . $tag->id . '.view')) {
if (($hasGlobalPermission && ! $tag->is_restricted) || $user->hasPermission('tag' . $tag->id . '.' . $permission)) {
$ids[] = $tag->id;
}
}
return $ids;
}
public static function getIdsWhereCannot($user, $permission)
{
static $tags;
if (! $tags) {
$tags = static::all();
}
$ids = [];
$hasGlobalPermission = $user->hasPermission($permission);
foreach ($tags as $tag) {
if (($tag->is_restricted || ! $hasGlobalPermission) && ! $user->hasPermission('tag' . $tag->id . '.' . $permission)) {
$ids[] = $tag->id;
}
}