mirror of
https://github.com/flarum/core.git
synced 2025-10-18 02:06:08 +02:00
Permission to rename/hide/edit one's own discussion/post is only granted if the user has permission to reply to the discussion. This makes sense if you think of these actions as forms of "replying" to a discussion. Fixes #1419 because suspended users do not have permission to reply to discussions, therefore they will not be granted these "own" permissions.
149 lines
4.3 KiB
PHP
149 lines
4.3 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of Flarum.
|
|
*
|
|
* (c) Toby Zerner <toby.zerner@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Flarum\Discussion;
|
|
|
|
use Flarum\Event\ScopeModelVisibility;
|
|
use Flarum\Settings\SettingsRepositoryInterface;
|
|
use Flarum\User\AbstractPolicy;
|
|
use Flarum\User\Gate;
|
|
use Flarum\User\User;
|
|
use Illuminate\Contracts\Events\Dispatcher;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class DiscussionPolicy extends AbstractPolicy
|
|
{
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
protected $model = Discussion::class;
|
|
|
|
/**
|
|
* @var SettingsRepositoryInterface
|
|
*/
|
|
protected $settings;
|
|
|
|
/**
|
|
* @var Gate
|
|
*/
|
|
protected $gate;
|
|
|
|
/**
|
|
* @var Dispatcher
|
|
*/
|
|
protected $events;
|
|
|
|
/**
|
|
* @param SettingsRepositoryInterface $settings
|
|
* @param Gate $gate
|
|
* @param Dispatcher $events
|
|
*/
|
|
public function __construct(SettingsRepositoryInterface $settings, Gate $gate, Dispatcher $events)
|
|
{
|
|
$this->settings = $settings;
|
|
$this->gate = $gate;
|
|
$this->events = $events;
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param string $ability
|
|
* @return bool|null
|
|
*/
|
|
public function can(User $actor, $ability)
|
|
{
|
|
if ($actor->hasPermission('discussion.'.$ability)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param Builder $query
|
|
*/
|
|
public function find(User $actor, Builder $query)
|
|
{
|
|
if ($actor->cannot('viewDiscussions')) {
|
|
$query->whereRaw('FALSE');
|
|
|
|
return;
|
|
}
|
|
|
|
// Hide private discussions by default.
|
|
$query->where(function ($query) use ($actor) {
|
|
$query->where('discussions.is_private', false)
|
|
->orWhere(function ($query) use ($actor) {
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility($query, $actor, 'viewPrivate')
|
|
);
|
|
});
|
|
});
|
|
|
|
// Hide hidden discussions, unless they are authored by the current
|
|
// user, or the current user has permission to view hidden discussions.
|
|
if (! $actor->hasPermission('discussion.hide')) {
|
|
$query->where(function ($query) use ($actor) {
|
|
$query->whereNull('discussions.hidden_at')
|
|
->orWhere('discussions.user_id', $actor->id)
|
|
->orWhere(function ($query) use ($actor) {
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility($query, $actor, 'hide')
|
|
);
|
|
});
|
|
});
|
|
}
|
|
|
|
// Hide discussions with no comments, unless they are authored by the
|
|
// current user, or the user is allowed to edit the discussion's posts.
|
|
if (! $actor->hasPermission('discussion.editPosts')) {
|
|
$query->where(function ($query) use ($actor) {
|
|
$query->where('discussions.comment_count', '>', 0)
|
|
->orWhere('discussions.user_id', $actor->id)
|
|
->orWhere(function ($query) use ($actor) {
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility($query, $actor, 'editPosts')
|
|
);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param \Flarum\Discussion\Discussion $discussion
|
|
* @return bool|null
|
|
*/
|
|
public function rename(User $actor, Discussion $discussion)
|
|
{
|
|
if ($discussion->user_id == $actor->id && $actor->can('reply', $discussion)) {
|
|
$allowRenaming = $this->settings->get('allow_renaming');
|
|
|
|
if ($allowRenaming === '-1'
|
|
|| ($allowRenaming === 'reply' && $discussion->participant_count <= 1)
|
|
|| ($discussion->created_at->diffInMinutes() < $allowRenaming)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param \Flarum\Discussion\Discussion $discussion
|
|
* @return bool|null
|
|
*/
|
|
public function hide(User $actor, Discussion $discussion)
|
|
{
|
|
if ($discussion->user_id == $actor->id && $discussion->participant_count <= 1 && $actor->can('reply', $discussion)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|