diff --git a/modules/comment/comment.module b/modules/comment/comment.module index d04755db261..18e0e67d09a 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -423,19 +423,35 @@ function comment_new_page_count($num_comments, $new_replies, $node) { $pageno = $count / $comments_per_page; } else { - // Threaded comments. - // Find the first thread with a new comment. - $result = db_query_range('SELECT thread FROM (SELECT thread - FROM {comment} - WHERE nid = :nid - AND status = 0 - ORDER BY changed DESC) AS thread - ORDER BY SUBSTRING(thread, 1, (LENGTH(thread) - 1))', 0, $new_replies, array(':nid' => $node->nid))->fetchField(); - $thread = substr($result, 0, -1); - $count = db_query('SELECT COUNT(*) FROM {comment} WHERE nid = :nid AND status = 0 AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array( + // Threaded comments: we build a query with a subquery to find the first + // thread with a new comment. + + // 1. Find all the threads with a new comment. + $unread_threads_query = db_select('comment') + ->fields('comment', array('thread')) + ->condition('nid', $node->nid) + ->condition('status', COMMENT_PUBLISHED) + ->orderBy('changed', 'DESC') + ->range(0, $new_replies); + + // 2. Find the first thread. + $first_thread = db_select($unread_threads_query, 'thread') + ->fields('thread', array('thread')) + ->orderBy('SUBSTRING(thread, 1, (LENGTH(thread) - 1))') + ->range(0, 1) + ->execute() + ->fetchField(); + + // Remove the final '/'. + $first_thread = substr($first_thread, 0, -1); + + // Find the number of the first comment of the first unread thread. + $count = db_query('SELECT COUNT(*) FROM {comment} WHERE nid = :nid AND status = :status AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array( + ':status' => COMMENT_PUBLISHED, ':nid' => $node->nid, - ':thread' => $thread, + ':thread' => $first_thread, ))->fetchField(); + $pageno = $count / $comments_per_page; } diff --git a/modules/comment/comment.test b/modules/comment/comment.test index 60c4b3142e3..6fd91907f85 100644 --- a/modules/comment/comment.test +++ b/modules/comment/comment.test @@ -763,6 +763,85 @@ class CommentPagerTest extends CommentHelperCase { return $this->assertIdentical($expected_cids, $result_order, t('Comment order: expected @expected, returned @returned.', array('@expected' => implode(',', $expected_cids), '@returned' => implode(',', $result_order)))); } + + /** + * Test comment_new_page_count(). + */ + function testCommentNewPageIndicator() { + $this->drupalLogin($this->admin_user); + + // Set comment variables. + $this->setCommentForm(TRUE); + $this->setCommentSubject(TRUE); + $this->setCommentPreview(FALSE); + + // Set comments to one per page so that we are able to test paging without + // needing to insert large numbers of comments. + $this->setCommentsPerPage(1); + + // Create a node and three comments. + $node = $this->drupalCreateNode(array('type' => 'article', 'promote' => 1)); + $comments = array(); + $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); + $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); + $comments[] = $this->postComment($node, $this->randomName(), $this->randomName(), TRUE); + + // Post a reply to the second comment. + $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[1]->id); + $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); + + // Post a reply to the first comment. + $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[0]->id); + $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); + + // Post a reply to the last comment. + $this->drupalGet('comment/reply/' . $node->nid . '/' . $comments[2]->id); + $comments[] = $this->postComment(NULL, $this->randomName(), $this->randomName(), TRUE); + + // At this point, the comment tree is: + // - 0 + // - 4 + // - 1 + // - 3 + // - 2 + // - 5 + + $this->setCommentSettings('comment_default_mode', COMMENT_MODE_FLAT, t('Comment paging changed.')); + + $expected_pages = array( + 1 => 5, // Page of comment 5 + 2 => 4, // Page of comment 4 + 3 => 3, // Page of comment 3 + 4 => 2, // Page of comment 2 + 5 => 1, // Page of comment 1 + 6 => 0, // Page of comment 0 + ); + + $node = node_load($node->nid); + foreach ($expected_pages as $new_replies => $expected_page) { + $returned = comment_new_page_count($node->comment_count, $new_replies, $node); + $returned_page = is_array($returned) ? $returned['page'] : 0; + $this->assertIdentical($expected_page, $returned_page, t('Flat mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page))); + } + + $this->setCommentSettings('comment_default_mode', COMMENT_MODE_THREADED, t('Switched to threaded mode.')); + + $expected_pages = array( + 1 => 5, // Page of comment 5 + 2 => 1, // Page of comment 4 + 3 => 1, // Page of comment 4 + 4 => 1, // Page of comment 4 + 5 => 1, // Page of comment 4 + 6 => 0, // Page of comment 0 + ); + + $node = node_load($node->nid); + foreach ($expected_pages as $new_replies => $expected_page) { + $returned = comment_new_page_count($node->comment_count, $new_replies, $node); + $returned_page = is_array($returned) ? $returned['page'] : 0; + $this->assertEqual($expected_page, $returned_page, t('Threaded mode, @new replies: expected page @expected, returned page @returned.', array('@new' => $new_replies, '@expected' => $expected_page, '@returned' => $returned_page))); + } + } } class CommentApprovalTest extends CommentHelperCase {