You are here

public function ForumManager::getTopics in Drupal 9

Same name and namespace in other branches
  1. 8 core/modules/forum/src/ForumManager.php \Drupal\forum\ForumManager::getTopics()

Gets list of forum topics.

Parameters

int $tid: Term ID.

\Drupal\Core\Session\AccountInterface $account: Account to fetch topics for.

Return value

array Array with keys 'topics' and 'header'.

Overrides ForumManagerInterface::getTopics

File

core/modules/forum/src/ForumManager.php, line 146

Class

ForumManager
Provides forum manager service.

Namespace

Drupal\forum

Code

public function getTopics($tid, AccountInterface $account) {
  $config = $this->configFactory
    ->get('forum.settings');
  $forum_per_page = $config
    ->get('topics.page_limit');
  $sortby = $config
    ->get('topics.order');
  $header = [
    [
      'data' => $this
        ->t('Topic'),
      'field' => 'f.title',
    ],
    [
      'data' => $this
        ->t('Replies'),
      'field' => 'f.comment_count',
    ],
    [
      'data' => $this
        ->t('Last reply'),
      'field' => 'f.last_comment_timestamp',
    ],
  ];
  $order = $this
    ->getTopicOrder($sortby);
  for ($i = 0; $i < count($header); $i++) {
    if ($header[$i]['field'] == $order['field']) {
      $header[$i]['sort'] = $order['sort'];
    }
  }
  $query = $this->connection
    ->select('forum_index', 'f')
    ->extend(PagerSelectExtender::class)
    ->extend(TableSortExtender::class);
  $query
    ->fields('f');
  $query
    ->condition('f.tid', $tid)
    ->addTag('node_access')
    ->addMetaData('base_table', 'forum_index')
    ->orderBy('f.sticky', 'DESC')
    ->orderByHeader($header)
    ->limit($forum_per_page);
  $count_query = $this->connection
    ->select('forum_index', 'f');
  $count_query
    ->condition('f.tid', $tid);
  $count_query
    ->addExpression('COUNT(*)');
  $count_query
    ->addTag('node_access');
  $count_query
    ->addMetaData('base_table', 'forum_index');
  $query
    ->setCountQuery($count_query);
  $result = $query
    ->execute();
  $nids = [];
  foreach ($result as $record) {
    $nids[] = $record->nid;
  }
  if ($nids) {
    $nodes = $this->entityTypeManager
      ->getStorage('node')
      ->loadMultiple($nids);
    $query = $this->connection
      ->select('node_field_data', 'n')
      ->extend(TableSortExtender::class);
    $query
      ->fields('n', [
      'nid',
    ]);
    $query
      ->join('comment_entity_statistics', 'ces', "[n].[nid] = [ces].[entity_id] AND [ces].[field_name] = 'comment_forum' AND [ces].[entity_type] = 'node'");
    $query
      ->fields('ces', [
      'cid',
      'last_comment_uid',
      'last_comment_timestamp',
      'comment_count',
    ]);
    $query
      ->join('forum_index', 'f', '[f].[nid] = [n].[nid]');
    $query
      ->addField('f', 'tid', 'forum_tid');
    $query
      ->join('users_field_data', 'u', '[n].[uid] = [u].[uid] AND [u].[default_langcode] = 1');
    $query
      ->addField('u', 'name');
    $query
      ->join('users_field_data', 'u2', '[ces].[last_comment_uid] = [u2].[uid] AND [u].[default_langcode] = 1');
    $query
      ->addExpression('CASE [ces].[last_comment_uid] WHEN 0 THEN [ces].[last_comment_name] ELSE [u2].[name] END', 'last_comment_name');
    $query
      ->orderBy('f.sticky', 'DESC')
      ->orderByHeader($header)
      ->condition('n.nid', $nids, 'IN')
      ->condition('n.default_langcode', 1);
    $result = [];
    foreach ($query
      ->execute() as $row) {
      $topic = $nodes[$row->nid];
      $topic->comment_mode = $topic->comment_forum->status;
      foreach ($row as $key => $value) {
        $topic->{$key} = $value;
      }
      $result[] = $topic;
    }
  }
  else {
    $result = [];
  }
  $topics = [];
  $first_new_found = FALSE;
  foreach ($result as $topic) {
    if ($account
      ->isAuthenticated()) {

      // A forum is new if the topic is new, or if there are new comments since
      // the user's last visit.
      if ($topic->forum_tid != $tid) {
        $topic->new = 0;
      }
      else {
        $history = $this
          ->lastVisit($topic
          ->id(), $account);
        $topic->new_replies = $this->commentManager
          ->getCountNewComments($topic, 'comment_forum', $history);
        $topic->new = $topic->new_replies || $topic->last_comment_timestamp > $history;
      }
    }
    else {

      // Do not track "new replies" status for topics if the user is anonymous.
      $topic->new_replies = 0;
      $topic->new = 0;
    }

    // Make sure only one topic is indicated as the first new topic.
    $topic->first_new = FALSE;
    if ($topic->new != 0 && !$first_new_found) {
      $topic->first_new = TRUE;
      $first_new_found = TRUE;
    }
    if ($topic->comment_count > 0) {
      $last_reply = new \stdClass();
      $last_reply->created = $topic->last_comment_timestamp;
      $last_reply->name = $topic->last_comment_name;
      $last_reply->uid = $topic->last_comment_uid;
      $topic->last_reply = $last_reply;
    }
    $topics[$topic
      ->id()] = $topic;
  }
  return [
    'topics' => $topics,
    'header' => $header,
  ];
}