* * 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) { // 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)) { $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; } } } }