Bring back comment ordering. From: Damien Tournoud --- CHANGELOG.txt | 4 + modules/comment/comment.install | 13 ----- modules/comment/comment.module | 112 ++++++++++++++++++++++++++++----------- 3 files changed, 84 insertions(+), 45 deletions(-) diff --git CHANGELOG.txt CHANGELOG.txt index b2b64f6..56a40bf 100644 --- CHANGELOG.txt +++ CHANGELOG.txt @@ -21,8 +21,8 @@ Drupal 7.0, xxxx-xx-xx (development version) * Implemented drag-and-drop positioning for poll options. * Provided descriptions and human-readable names for user permissions. * Removed comment controls for users. - * Removed display order settings for comment module. Comment display - order can now be customised using the Views module. + * Removed display order settings for comment module. The underlying code is + still there, so contribution modules can tweak that display order. * Added additional features to the default install profile, and implemented a "slimmed down" install profile designed for developers. * Image toolkits are now provided by modules (rather than requiring a manual diff --git modules/comment/comment.install modules/comment/comment.install index df330a3..fe2d093 100644 --- modules/comment/comment.install +++ modules/comment/comment.install @@ -86,20 +86,9 @@ function comment_update_6003() { */ /** - * Remove comment settings for page ordering. - */ -function comment_update_7000() { - $types = node_get_types(); - foreach ($types as $type => $object) { - variable_del('comment_default_order' . $type); - } - return array(array('success' => TRUE, 'query' => 'Comment order settings removed.')); -} - -/** * Change comment status from published being 0 to being 1 */ -function comment_update_7001() { +function comment_update_7000() { $ret = array(); $ret[] = update_sql("UPDATE {comments} SET status = 3 WHERE status = 0"); $ret[] = update_sql("UPDATE {comments} SET status = 0 WHERE status = 1"); diff --git modules/comment/comment.module modules/comment/comment.module index fb1a193..5a318dc 100644 --- modules/comment/comment.module +++ modules/comment/comment.module @@ -41,6 +41,16 @@ define('COMMENT_MODE_THREADED_COLLAPSED', 3); define('COMMENT_MODE_THREADED_EXPANDED', 4); /** + * Comments are ordered by date - newest first. + */ +define('COMMENT_ORDER_NEWEST_FIRST', 1); + +/** + * Comments are ordered by date - oldest first. + */ +define('COMMENT_ORDER_OLDEST_FIRST', 2); + +/** * Anonymous posters cannot enter their contact information. */ define('COMMENT_ANONYMOUS_MAYNOT_CONTACT', 0); @@ -220,6 +230,7 @@ function comment_node_type($op, $info) { $settings = array( 'comment', 'comment_default_mode', + 'comment_default_order', 'comment_default_per_page', 'comment_anonymous', 'comment_subject_field', @@ -356,35 +367,57 @@ function comment_get_recent($number = 10) { function comment_new_page_count($num_comments, $new_replies, $node) { $comments_per_page = _comment_get_display_setting('comments_per_page', $node); $mode = _comment_get_display_setting('mode', $node); + $order = _comment_get_display_setting('sort', $node); $pagenum = NULL; $flat = in_array($mode, array(COMMENT_MODE_FLAT_COLLAPSED, COMMENT_MODE_FLAT_EXPANDED)); - if ($num_comments <= $comments_per_page) { - // Only one page of comments. + if ($num_comments <= $comments_per_page || ($flat && $order == COMMENT_ORDER_NEWEST_FIRST)) { + // Only one page of comments or flat forum and newest first. + // First new comment will always be on first page. $pageno = 0; } - elseif ($flat) { - // Flat comments. - $count = $num_comments - $new_replies; - $pageno = $count / $comments_per_page; - } else { - // Threaded comments. - // Find the first thread with a new comment. - $result = db_query_range('(SELECT thread - FROM {comments} - WHERE nid = :nid - AND status = 0 - ORDER BY timestamp DESC) - ORDER BY SUBSTRING(thread, 1, (LENGTH(thread) - 1))', array(':nid' => $node->nid), 0, $new_replies) - ->fetchField(); - $thread = substr($result, 0, -1); - $count = db_query('SELECT COUNT(*) FROM {comments} WHERE nid = :nid AND status = 0 AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array( - ':nid' => $node->nid, - ':thread' => $thread)) - ->fetchField(); - $pageno = $count / $comments_per_page; + if ($flat) { + // Flat comments and oldest first. + $count = $num_comments - $new_replies; + } + else { + // Threaded comments. See the documentation for comment_render(). + if ($order == COMMENT_ORDER_NEWEST_FIRST) { + // Newest first: find the last thread with a new comment. + // TODO: change that query when our query build will support subqueries. + $thread = db_query_range("(SELECT thread + FROM {comments} + WHERE nid = :nid + AND status = 0 + ORDER BY timestamp DESC + LIMIT $new_replies) + ORDER BY thread DESC", array(':nid' => $node->nid), 0, 1) + ->fetchField(); + $count = db_query('SELECT COUNT(*) FROM {comments} WHERE nid = :nid AND status = 0 AND thread > :thread', array( + ':nid' => $node->nid, + ':thread' => $thread)) + ->fetchField(); + } + else { + // Oldest first: find the first thread with a new comment. + // TODO: change that query when our query build will support subqueries. + $thread = db_query_range('(SELECT thread + FROM {comments} + WHERE nid = :nid + AND status = 0 + ORDER BY timestamp DESC + LIMIT $new_replies) + ORDER BY SUBSTRING(thread, 1, (LENGTH(thread) - 1))', array(':nid' => $node->nid), 0, 1) + ->fetchField(); + $thread = substr($thread, 0, -1); + $count = db_query('SELECT COUNT(*) FROM {comments} WHERE nid = :nid AND status = 0 AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < :thread', array( + ':nid' => $node->nid, + ':thread' => $thread)) + ->fetchField(); + } + } + $pageno = $count / $comments_per_page; } - if ($pageno >= 1) { $pagenum = "page=" . intval($pageno); } @@ -980,6 +1013,7 @@ function comment_render($node, $cid = 0) { } $mode = _comment_get_display_setting('mode', $node); + $order = _comment_get_display_setting('sort', $node); $comments_per_page = _comment_get_display_setting('comments_per_page', $node); if ($cid && is_numeric($cid)) { @@ -1019,14 +1053,25 @@ function comment_render($node, $cid = 0) { $query_count .= ' AND c.status = %d'; $query_args[] = COMMENT_PUBLISHED; } - if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) { - $query .= ' ORDER BY c.cid'; - } - else { - // See comment above. Analysis reveals that this doesn't cost too - // much. It scales much much better than having the whole comment - // structure. - $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))'; + + if ($order == COMMENT_ORDER_NEWEST_FIRST) { + if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) { + $query .= ' ORDER BY c.cid DESC'; + } + else { + $query .= ' ORDER BY c.thread DESC'; + } + } + elseif ($order == COMMENT_ORDER_OLDEST_FIRST) { + if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) { + $query .= ' ORDER BY c.cid'; + } + else { + // See comment above. Analysis reveals that this doesn't cost too + // much. It scales much much better than having the whole comment + // structure. + $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))'; + } } $query = db_rewrite_sql($query, 'c', 'cid'); @@ -1832,6 +1877,7 @@ function theme_comment_post_forbidden($node) { function template_preprocess_comment_wrapper(&$variables) { // Provide contextual information. $variables['display_mode'] = _comment_get_display_setting('mode', $variables['node']); + $variables['display_order'] = _comment_get_display_setting('sort', $variables['node']); $variables['template_files'][] = 'comment-wrapper-' . $variables['node']->type; } @@ -1887,6 +1933,10 @@ function _comment_get_display_setting($setting, $node) { $value = variable_get('comment_default_mode_' . $node->type, COMMENT_MODE_THREADED_EXPANDED); break; + case 'sort': + $value = variable_get('comment_default_order_' . $node->type, COMMENT_ORDER_OLDEST_FIRST); + break; + case 'comments_per_page': $value = variable_get('comment_default_per_page_' . $node->type, 50); }