diff --git a/core/modules/forum/forum.install b/core/modules/forum/forum.install index 4a16a8939a..c4bddebaf3 100644 --- a/core/modules/forum/forum.install +++ b/core/modules/forum/forum.install @@ -5,6 +5,7 @@ * Install, update, and uninstall functions for the Forum module. */ +use Drupal\Core\Database\Database; use Drupal\field\Entity\FieldStorageConfig; use Drupal\taxonomy\Entity\Term; @@ -158,6 +159,7 @@ function forum_schema() { 'forum_topics' => ['nid', 'tid', 'sticky', 'last_comment_timestamp'], 'created' => ['created'], 'last_comment_timestamp' => ['last_comment_timestamp'], + 'tid' => ['tid'], ], 'foreign keys' => [ 'tracked_node' => [ @@ -175,3 +177,82 @@ function forum_schema() { return $schema; } + +/** + * Add cid field and index on tid to forum_index table. + */ +function forum_update_8400() { + $schema = Database::getConnection()->schema(); + $spec = [ + 'description' => 'Maintains denormalized information about node/term relationships.', + 'fields' => [ + 'nid' => [ + 'description' => 'The {node}.nid this record tracks.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'title' => [ + 'description' => 'The node title.', + 'type' => 'varchar', + 'length' => 255, + 'not null' => TRUE, + 'default' => '', + ], + 'tid' => [ + 'description' => 'The term ID.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'sticky' => [ + 'description' => 'Boolean indicating whether the node is sticky.', + 'type' => 'int', + 'not null' => FALSE, + 'default' => 0, + 'size' => 'tiny', + ], + 'created' => [ + 'description' => 'The Unix timestamp when the node was created.', + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + ], + 'last_comment_timestamp' => [ + 'type' => 'int', + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The Unix timestamp of the last comment that was posted within this node, from {comment}.timestamp.', + ], + 'comment_count' => [ + 'type' => 'int', + 'unsigned' => TRUE, + 'not null' => TRUE, + 'default' => 0, + 'description' => 'The total number of comments on this node.', + ], + ], + 'indexes' => [ + 'forum_topics' => ['nid', 'tid', 'sticky', 'last_comment_timestamp'], + 'created' => ['created'], + 'last_comment_timestamp' => ['last_comment_timestamp'], + 'tid' => ['tid'], + ], + 'foreign keys' => [ + 'tracked_node' => [ + 'table' => 'node', + 'columns' => ['nid' => 'nid'], + ], + 'term' => [ + 'table' => 'taxonomy_term_data', + 'columns' => [ + 'tid' => 'tid', + ], + ], + ], + ]; + $schema->addIndex('forum_index', 'tid', ['tid'], $spec); +} diff --git a/core/modules/forum/src/ForumIndexStorage.php b/core/modules/forum/src/ForumIndexStorage.php index 79945746c1..d6c092e031 100644 --- a/core/modules/forum/src/ForumIndexStorage.php +++ b/core/modules/forum/src/ForumIndexStorage.php @@ -91,7 +91,7 @@ public function update(NodeInterface $node) { */ public function updateIndex(NodeInterface $node) { $nid = $node->id(); - $count = $this->database->query("SELECT COUNT(cid) FROM {comment_field_data} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_name = 'comment_forum' AND c.entity_type = 'node' AND c.status = :status AND c.default_langcode = 1", [ + $count = $this->database->query("SELECT COUNT(c.cid) FROM {comment_field_data} c INNER JOIN {forum_index} i ON c.entity_id = i.nid WHERE c.entity_id = :nid AND c.field_name = 'comment_forum' AND c.entity_type = 'node' AND c.status = :status AND c.default_langcode = 1", [ ':nid' => $nid, ':status' => CommentInterface::PUBLISHED, ])->fetchField(); diff --git a/core/modules/forum/src/ForumManager.php b/core/modules/forum/src/ForumManager.php index 05cd860760..9ae35ea438 100644 --- a/core/modules/forum/src/ForumManager.php +++ b/core/modules/forum/src/ForumManager.php @@ -333,16 +333,16 @@ protected function getLastPost($tid) { return $this->lastPostData[$tid]; } // Query "Last Post" information for this forum. - $query = $this->connection->select('node_field_data', 'n'); - $query->join('forum', 'f', 'n.vid = f.vid AND f.tid = :tid', [':tid' => $tid]); - $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); + $query = $this->connection->select('node', 'n'); + $query->join('forum_index', 'f', 'n.nid = f.nid'); + $query->join('comment_entity_statistics', 'ces', "f.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); $query->join('users_field_data', 'u', 'ces.last_comment_uid = u.uid AND u.default_langcode = 1'); - $query->addExpression('CASE ces.last_comment_uid WHEN 0 THEN ces.last_comment_name ELSE u.name END', 'last_comment_name'); + $query->addExpression('COALESCE(ces.last_comment_name, u.name)', 'last_comment_name'); $topic = $query ->fields('ces', ['last_comment_timestamp', 'last_comment_uid']) - ->condition('n.status', 1) - ->orderBy('last_comment_timestamp', 'DESC') + ->condition('f.tid', $tid) + ->orderBy('f.last_comment_timestamp', 'DESC') ->range(0, 1) ->addTag('node_access') ->execute() @@ -372,16 +372,14 @@ protected function getLastPost($tid) { protected function getForumStatistics($tid) { if (empty($this->forumStatistics)) { // Prime the statistics. - $query = $this->connection->select('node_field_data', 'n'); - $query->join('comment_entity_statistics', 'ces', "n.nid = ces.entity_id AND ces.field_name = 'comment_forum' AND ces.entity_type = 'node'"); - $query->join('forum', 'f', 'n.vid = f.vid'); - $query->addExpression('COUNT(n.nid)', 'topic_count'); - $query->addExpression('SUM(ces.comment_count)', 'comment_count'); + $query = $this->connection->select('node', 'n'); + $query->join('forum_index', 'f', 'n.nid = f.nid'); + $query->addExpression('COUNT(f.nid)', 'topic_count'); + $query->addExpression('SUM(f.comment_count)', 'comment_count'); $this->forumStatistics = $query ->fields('f', ['tid']) - ->condition('n.status', 1) - ->condition('n.default_langcode', 1) ->groupBy('tid') + ->orderBy('NULL') ->addTag('node_access') ->execute() ->fetchAllAssoc('tid');