mirror of
https://github.com/flarum/core.git
synced 2025-10-23 20:56:05 +02:00
A post can only be seen if the discussion in which it resides can be seen. The logic for this belongs in the policy, not the model.
132 lines
4.1 KiB
PHP
132 lines
4.1 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\Post;
|
|
|
|
use Carbon\Carbon;
|
|
use Flarum\Discussion\Discussion;
|
|
use Flarum\Event\ScopeModelVisibility;
|
|
use Flarum\Settings\SettingsRepositoryInterface;
|
|
use Flarum\User\AbstractPolicy;
|
|
use Flarum\User\User;
|
|
use Illuminate\Contracts\Events\Dispatcher;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
|
|
class PostPolicy extends AbstractPolicy
|
|
{
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
protected $model = Post::class;
|
|
|
|
/**
|
|
* @var SettingsRepositoryInterface
|
|
*/
|
|
protected $settings;
|
|
|
|
/**
|
|
* @var Dispatcher
|
|
*/
|
|
protected $events;
|
|
|
|
/**
|
|
* @param SettingsRepositoryInterface $settings
|
|
* @param Dispatcher $events
|
|
*/
|
|
public function __construct(SettingsRepositoryInterface $settings, Dispatcher $events)
|
|
{
|
|
$this->settings = $settings;
|
|
$this->events = $events;
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param string $ability
|
|
* @param \Flarum\Post\Post $post
|
|
* @return bool|null
|
|
*/
|
|
public function can(User $actor, $ability, Post $post)
|
|
{
|
|
if ($actor->can($ability.'Posts', $post->discussion)) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param Builder $query
|
|
*/
|
|
public function find(User $actor, $query)
|
|
{
|
|
// Make sure the post's discussion is visible as well.
|
|
$query->whereExists(function ($query) use ($actor) {
|
|
$query->selectRaw('1')
|
|
->from('discussions')
|
|
->whereColumn('discussions.id', 'posts.discussion_id');
|
|
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility(Discussion::query()->setQuery($query), $actor, 'view')
|
|
);
|
|
});
|
|
|
|
// Hide private posts by default.
|
|
$query->where(function ($query) use ($actor) {
|
|
$query->where('posts.is_private', false)
|
|
->orWhere(function ($query) use ($actor) {
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility($query, $actor, 'viewPrivate')
|
|
);
|
|
});
|
|
});
|
|
|
|
// Hide hidden posts, unless they are authored by the current user, or
|
|
// the current user has permission to view hidden posts in the
|
|
// discussion.
|
|
if (! $actor->hasPermission('discussion.hidePosts')) {
|
|
$query->where(function ($query) use ($actor) {
|
|
$query->whereNull('posts.hidden_at')
|
|
->orWhere('posts.user_id', $actor->id)
|
|
->orWhereExists(function ($query) use ($actor) {
|
|
$query->selectRaw('1')
|
|
->from('discussions')
|
|
->whereColumn('discussions.id', 'posts.discussion_id')
|
|
->where(function ($query) use ($actor) {
|
|
$this->events->dispatch(
|
|
new ScopeModelVisibility(Discussion::query()->setQuery($query), $actor, 'hidePosts')
|
|
);
|
|
});
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param User $actor
|
|
* @param Post $post
|
|
* @return bool|null
|
|
*/
|
|
public function edit(User $actor, Post $post)
|
|
{
|
|
// A post is allowed to be edited if the user has permission to moderate
|
|
// the discussion which it's in, or if they are the author and the post
|
|
// hasn't been deleted by someone else.
|
|
if ($post->user_id == $actor->id && (! $post->hidden_at || $post->hidden_user_id == $actor->id) && $actor->can('reply', $post->discussion)) {
|
|
$allowEditing = $this->settings->get('allow_post_editing');
|
|
|
|
if ($allowEditing === '-1'
|
|
|| ($allowEditing === 'reply' && $post->number >= $post->discussion->last_post_number)
|
|
|| ($post->created_at->diffInMinutes(new Carbon) < $allowEditing)) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
}
|