Inheritance: extends Flarum\Database\AbstractModel, use trait Flarum\Core\Support\EventGeneratorTrait, use trait Flarum\Core\Support\ScopeVisibilityTrait
 /**
  * @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] : []);
     }
 }
Beispiel #2
0
 /**
  * @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;
 }
Beispiel #3
0
 /**
  * {@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));
         }
     }
 }
Beispiel #5
0
 /**
  * @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();
 }
Beispiel #7
0
 /**
  * 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();
 }
Beispiel #8
0
 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();
 }
Beispiel #9
0
 /**
  * @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);
 }