/** * @param EditPost $command * @return \Flarum\Core\Post * @throws \Flarum\Core\Exception\PermissionDeniedException */ public function handle(EditPost $command) { $actor = $command->actor; $data = $command->data; $post = $this->posts->findOrFail($command->postId, $actor); if ($post instanceof CommentPost) { $attributes = array_get($data, 'attributes', []); if (isset($attributes['content'])) { $this->assertCan($actor, 'edit', $post); $post->revise($attributes['content'], $actor); } if (isset($attributes['isHidden'])) { $this->assertCan($actor, 'edit', $post); if ($attributes['isHidden']) { $post->hide($actor); } else { $post->restore(); } } } $this->events->fire(new PostWillBeSaved($post, $actor, $data)); $this->validator->assertValid($post->getDirty()); $post->save(); $this->dispatchEventsFor($post, $actor); return $post; }
/** * @param DeleteModeratorNotes $command * * @return ModeratorNotes */ public function handle(DeleteModeratorNotes $command) { $actor = $command->actor; $post = $this->posts->findOrFail($command->postId, $actor); $this->assertCan($actor, 'viewModeratorNotes', $post->discussion); $this->events->fire(new ModeratorNotesWillBeDeleted($post, $actor, $command->data)); $post->moderatorNotes()->delete(); return $post; }
/** * @param DeletePost $command * @return \Flarum\Core\Post * @throws PermissionDeniedException */ public function handle(DeletePost $command) { $actor = $command->actor; $post = $this->posts->findOrFail($command->postId, $actor); $this->assertCan($actor, 'delete', $post); $this->events->fire(new PostWillBeDeleted($post, $actor, $command->data)); $post->delete(); $this->dispatchEventsFor($post, $actor); return $post; }
/** * Apply visibility permissions to API data. * * Each post in an API document has a relationship with posts that have * mentioned it (mentionedBy). This listener will manually filter these * additional posts so that the user can't see any posts which they don't * have access to. * * @param PrepareApiData $event */ public function filterVisiblePosts(PrepareApiData $event) { // Firstly we gather a list of posts contained within the API document. // This will vary according to the API endpoint that is being accessed. if ($event->isController(ShowDiscussionController::class)) { $posts = $event->data->posts; } elseif ($event->isController(ShowPostController::class)) { $posts = [$event->data]; } elseif ($event->isController(ListPostsController::class)) { $posts = $event->data; } if (isset($posts)) { $posts = array_filter((array) $posts, 'is_object'); $ids = []; // Once we have the posts, construct a list of the IDs of all of // the posts that they have been mentioned in. We can then filter // this list of IDs to weed out all of the ones which the user is // not meant to see. foreach ($posts as $post) { $ids = array_merge($ids, $post->mentionedBy->pluck('id')->all()); } $ids = $this->posts->filterVisibleIds($ids, $event->actor); // Finally, go back through each of the posts and filter out any // of the posts in the relationship data that we now know are // invisible to the user. foreach ($posts as $post) { $post->setRelation('mentionedBy', $post->mentionedBy->filter(function ($post) use($ids) { return array_search($post->id, $ids) !== false; })); } } }
/** * @param ServerRequestInterface $request * @param array $where * @return \Illuminate\Database\Eloquent\Collection * @throws InvalidParameterException */ private function getPosts(ServerRequestInterface $request, array $where) { $queryParams = $request->getQueryParams(); $actor = $request->getAttribute('actor'); $sort = $this->extractSort($request); $limit = $this->extractLimit($request); if (($near = array_get($queryParams, 'page.near')) > 1) { if (count($where) > 1 || !isset($where['discussion_id']) || $sort) { throw new InvalidParameterException('You can only use page[near] with ' . 'filter[discussion] and the default sort order'); } $offset = $this->posts->getIndexForNumber($where['discussion_id'], $near, $actor); $offset = max(0, $offset - $limit / 2); } else { $offset = $this->extractOffset($request); } return $this->posts->findWhere($where, $actor, $sort, $limit, $offset); }
/** * @param CreateFlag $command * @return Flag * @throws InvalidParameterException */ public function handle(CreateFlag $command) { $actor = $command->actor; $data = $command->data; $postId = array_get($data, 'relationships.post.data.id'); $post = $this->posts->findOrFail($postId, $actor); if (!$post instanceof CommentPost) { throw new InvalidParameterException(); } $this->assertCan($actor, 'flag', $post); Flag::unguard(); $flag = Flag::firstOrNew(['post_id' => $post->id, 'user_id' => $actor->id]); $flag->post_id = $post->id; $flag->user_id = $actor->id; $flag->type = 'user'; $flag->reason = array_get($data, 'attributes.reason'); $flag->reason_detail = array_get($data, 'attributes.reasonDetail'); $flag->time = time(); $flag->save(); return $flag; }
/** * @param ServerRequestInterface $request * @param Discussion$discussion * @param int $limit * @return int */ private function getPostsOffset(ServerRequestInterface $request, Discussion $discussion, $limit) { $queryParams = $request->getQueryParams(); $actor = $request->getAttribute('actor'); if (($near = array_get($queryParams, 'page.near')) > 1) { $offset = $this->posts->getIndexForNumber($discussion->id, $near, $actor); $offset = max(0, $offset - $limit / 2); } else { $offset = $this->extractOffset($request); } return $offset; }
/** * Load relevant posts onto each discussion using information from the * search. * * @param Collection $discussions * @param DiscussionSearch $search */ protected function loadRelevantPosts(Collection $discussions, DiscussionSearch $search) { $postIds = []; foreach ($search->getRelevantPostIds() as $relevantPostIds) { $postIds = array_merge($postIds, array_slice($relevantPostIds, 0, 2)); } $posts = $postIds ? $this->posts->findByIds($postIds, $search->getActor())->load('user')->all() : []; foreach ($discussions as $discussion) { $discussion->relevantPosts = array_filter($posts, function ($post) use($discussion) { return $post->discussion_id == $discussion->id; }); } }
/** * @param ServerRequestInterface $request * @return array * @throws InvalidParameterException */ private function getPostIds(ServerRequestInterface $request) { $filter = $this->extractFilter($request); $sort = $this->extractSort($request); $limit = $this->extractLimit($request); $offset = $this->extractOffset($request); $query = $this->posts->query(); $this->applyFilters($query, $filter); $query->skip($offset)->take($limit); foreach ((array) $sort as $field => $order) { $query->orderBy($field, $order); } return $query->lists('id')->all(); }
/** * {@inheritdoc} */ protected function data(ServerRequestInterface $request, Document $document) { return $this->posts->findOrFail(array_get($request->getQueryParams(), 'id'), $request->getAttribute('actor')); }