/** * @param Discussion $discussion * @param User $user * @param $isLocked */ protected function lockedChanged(Discussion $discussion, User $user, $isLocked) { $post = DiscussionLockedPost::reply($discussion->id, $user->id, $isLocked); $post = $discussion->mergePost($post); if ($discussion->start_user_id !== $user->id) { $notification = new DiscussionLockedBlueprint($post); $this->notifications->sync($notification, $post->exists ? [$discussion->startUser] : []); } }
/** * @param StartDiscussion $command * @return mixed * @throws Exception */ public function handle(StartDiscussion $command) { $actor = $command->actor; $data = $command->data; $this->assertCan($actor, 'startDiscussion'); // Create a new Discussion entity, persist it, and dispatch domain // events. Before persistence, though, fire an event to give plugins // an opportunity to alter the discussion entity based on data in the // command they may have passed through in the controller. $discussion = Discussion::start(array_get($data, 'attributes.title'), $actor); $this->events->fire(new DiscussionWillBeSaved($discussion, $actor, $data)); $this->validator->assertValid($discussion->getAttributes()); $discussion->save(); // Now that the discussion has been created, we can add the first post. // We will do this by running the PostReply command. try { $post = $this->bus->dispatch(new PostReply($discussion->id, $actor, $data)); } catch (Exception $e) { $discussion->delete(); throw $e; } // Before we dispatch events, refresh our discussion instance's // attributes as posting the reply will have changed some of them (e.g. // last_time.) $discussion->setRawAttributes($post->discussion->getAttributes(), true); $discussion->setStartPost($post); $discussion->setLastPost($post); $this->dispatchEventsFor($discussion, $actor); $discussion->save(); return $discussion; }
/** * {@inheritdoc} */ protected function getDefaultAttributes($discussion) { $gate = $this->gate->forUser($this->actor); $attributes = parent::getDefaultAttributes($discussion) + ['commentsCount' => (int) $discussion->comments_count, 'participantsCount' => (int) $discussion->participants_count, 'startTime' => $this->formatDate($discussion->start_time), 'lastTime' => $this->formatDate($discussion->last_time), 'lastPostNumber' => (int) $discussion->last_post_number, 'canReply' => $gate->allows('reply', $discussion), 'canRename' => $gate->allows('rename', $discussion), 'canDelete' => $gate->allows('delete', $discussion), 'canHide' => $gate->allows('hide', $discussion)]; if ($discussion->hide_time) { $attributes['isHidden'] = true; $attributes['hideTime'] = $this->formatDate($discussion->hide_time); } Discussion::setStateUser($this->actor); if ($state = $discussion->state) { $attributes += ['readTime' => $this->formatDate($state->read_time), 'readNumber' => (int) $state->read_number]; } return $attributes; }
/** * @param \Flarum\Core\Notification[] $notifications */ private function loadSubjectDiscussions(array $notifications) { $ids = []; foreach ($notifications as $notification) { if ($notification->subject && $notification->subject->discussion_id) { $ids[] = $notification->subject->discussion_id; } } $discussions = Discussion::find(array_unique($ids)); foreach ($notifications as $notification) { if ($notification->subject && $notification->subject->discussion_id) { $notification->subject->setRelation('discussion', $discussions->find($notification->subject->discussion_id)); } } }
/** * @param $postIds * @param User $actor * @return mixed */ protected function getDiscussionsForPosts($postIds, User $actor) { return Discussion::query()->select('discussions.*')->join('posts', 'posts.discussion_id', '=', 'discussions.id')->whereIn('posts.id', $postIds)->groupBy('discussions.id')->whereVisibleTo($actor)->get(); }
/** * @param Discussion $discussion * @param User $actor * @param int $offset * @param int $limit * @param array $include * @return mixed */ private function loadPosts($discussion, $actor, $offset, $limit, array $include) { $query = $discussion->postsVisibleTo($actor); $query->orderBy('time')->skip($offset)->take($limit)->with($include); return $query->get()->all(); }
/** * Get the IDs of discussions which a user has read completely. * * @param User $user * @return array */ public function getReadIds(User $user) { return Discussion::leftJoin('users_discussions', 'users_discussions.discussion_id', '=', 'discussions.id')->where('user_id', $user->id)->where('read_number', '>=', new Expression('last_post_number'))->lists('id')->all(); }
protected function getDiscussionsForPosts($postIds, User $actor) { return Discussion::whereIn('id', function ($query) use($postIds) { $query->select('discussion_id')->from('posts')->whereIn('id', $postIds); })->whereVisibleTo($actor)->get(); }
/** * @param SearchCriteria $criteria * @param int|null $limit * @param int $offset * @param array $load An array of relationships to load on the results. * @return SearchResults */ public function search(SearchCriteria $criteria, $limit = null, $offset = 0, array $load = []) { $actor = $criteria->actor; $query = $this->discussions->query()->whereVisibleTo($actor); // Construct an object which represents this search for discussions. // Apply gambits to it, sort, and paging criteria. Also give extensions // an opportunity to modify it. $search = new DiscussionSearch($query->getQuery(), $actor); $this->gambits->apply($search, $criteria->query); $this->applySort($search, $criteria->sort); $this->applyOffset($search, $offset); $this->applyLimit($search, $limit + 1); // TODO: inject dispatcher event(new ConfigureDiscussionSearch($search, $criteria)); // Execute the search query and retrieve the results. We get one more // results than the user asked for, so that we can say if there are more // results. If there are, we will get rid of that extra result. $discussions = $query->get(); $areMoreResults = $limit > 0 && $discussions->count() > $limit; if ($areMoreResults) { $discussions->pop(); } // The relevant posts relationship isn't a typical Eloquent // relationship; rather, we need to extract that information from our // search object. We will delegate that task and prevent Eloquent // from trying to load it. if (in_array('relevantPosts', $load)) { $this->loadRelevantPosts($discussions, $search); $load = array_diff($load, ['relevantPosts', 'relevantPosts.discussion', 'relevantPosts.user']); } Discussion::setStateUser($actor); $discussions->load($load); return new SearchResults($discussions, $areMoreResults); }
/** * Refreshes count and last Post for the discussion. * * @param Discussion $discussion */ protected function refreshDiscussion(Discussion $discussion) { $discussion->refreshLastPost(); $discussion->refreshCommentsCount(); $discussion->refreshParticipantsCount(); // Persist the new statistics. $discussion->save(); return Discussion::find($discussion->id); }
/** * @param Discussion $discussion * @param User $user * @param bool $isSticky */ protected function stickyChanged(Discussion $discussion, User $user, $isSticky) { $post = DiscussionStickiedPost::reply($discussion->id, $user->id, $isSticky); $discussion->mergePost($post); }