Index: modules/tracker/tracker.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v
retrieving revision 1.143.2.2
diff -u -r1.143.2.2 tracker.module
--- modules/tracker/tracker.module 26 Jul 2007 19:16:50 -0000 1.143.2.2
+++ modules/tracker/tracker.module 27 Jul 2007 13:51:30 -0000
@@ -101,7 +101,7 @@
if ($new = comment_num_new($node->nid)) {
$comments .= '
';
- $comments .= l(format_plural($new, '1 new', '@count new'), "node/$node->nid", NULL, NULL, 'new');
+ $comments .= l(format_plural($new, '1 new', '@count new'), "node/$node->nid", NULL, comment_page_new_query($node->nid), 'new');
}
}
Index: modules/forum/forum.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v
retrieving revision 1.375.2.5
diff -u -r1.375.2.5 forum.module
--- modules/forum/forum.module 31 May 2007 05:58:17 -0000 1.375.2.5
+++ modules/forum/forum.module 27 Jul 2007 13:51:30 -0000
@@ -1001,7 +1001,7 @@
$rows[] = array(
array('data' => theme('forum_icon', $topic->new, $topic->num_comments, $topic->comment_mode, $topic->sticky), 'class' => 'icon'),
array('data' => l($topic->title, "node/$topic->nid"), 'class' => 'topic'),
- array('data' => $topic->num_comments . ($topic->new_replies ? '
'. l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, NULL, 'new') : ''), 'class' => 'replies'),
+ array('data' => $topic->num_comments . ($topic->new_replies ? '
'. l(format_plural($topic->new_replies, '1 new', '@count new'), "node/$topic->nid", NULL, comment_page_new_query($topic->nid), 'new') : ''), 'class' => 'replies'),
array('data' => _forum_format($topic), 'class' => 'created'),
array('data' => _forum_format(isset($topic->last_reply) ? $topic->last_reply : NULL), 'class' => 'last-reply')
);
Index: modules/comment/comment.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v
retrieving revision 1.520.2.6
diff -u -r1.520.2.6 comment.module
--- modules/comment/comment.module 26 Jul 2007 19:16:45 -0000 1.520.2.6
+++ modules/comment/comment.module 27 Jul 2007 13:51:25 -0000
@@ -249,19 +249,22 @@
// Select the $number nodes (visible to the current user) with the most
// recent comments. This is efficient due to the index on
// last_comment_timestamp.
- $result = db_query_range(db_rewrite_sql("SELECT nc.nid FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
+ $result = db_query_range(db_rewrite_sql("SELECT nc.nid, nc.comment_count FROM {node_comment_statistics} nc WHERE nc.comment_count > 0 ORDER BY nc.last_comment_timestamp DESC", 'nc'), 0, $number);
$nids = array();
+ $comment_counts = array();
while ($row = db_fetch_object($result)) {
$nids[] = $row->nid;
+ $comment_counts[$row->nid] = $row->comment_count;
}
$comments = array();
if (!empty($nids)) {
// From among the comments on the nodes selected in the first query,
// find the $number most recent comments.
- $result = db_query_range('SELECT c.nid, c.subject, c.cid, c.timestamp FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.timestamp DESC', COMMENT_PUBLISHED, 0, $number);
+ $result = db_query_range('SELECT c.nid, c.subject, c.cid, c.timestamp, c.thread FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid WHERE c.nid IN ('. implode(',', $nids) .') AND n.status = 1 AND c.status = %d ORDER BY c.timestamp DESC', COMMENT_PUBLISHED, 0, $number);
while ($comment = db_fetch_object($result)) {
+ $comment->comment_count = $comment_counts[$comment->nid];
$comments[] = $comment;
}
}
@@ -278,7 +281,7 @@
function theme_comment_block() {
$items = array();
foreach (comment_get_recent() as $comment) {
- $items[] = l($comment->subject, 'node/'. $comment->nid, NULL, NULL, 'comment-'. $comment->cid) .'
'. t('@time ago', array('@time' => format_interval(time() - $comment->timestamp)));
+ $items[] = l($comment->subject, 'node/'. $comment->nid, NULL, comment_page_query($comment), 'comment-'. $comment->cid) .'
'. t('@time ago', array('@time' => format_interval(time() - $comment->timestamp)));
}
if ($items) {
return theme('item_list', $items);
@@ -313,6 +316,7 @@
$links['comment_new_comments'] = array(
'title' => format_plural($new, '1 new comment', '@count new comments'),
'href' => "node/$node->nid",
+ 'query' => comment_page_new_query($node->nid),
'attributes' => array('title' => t('Jump to the first new comment of this posting.')),
'fragment' => 'new'
);
@@ -1321,13 +1325,22 @@
return db_fetch_object(db_query('SELECT * FROM {comments} WHERE cid = %d', $cid));
}
-function comment_num_all($nid) {
+/**
+ * get number of comments for specified node
+ */
+function comment_num_all($nid, $include_not_published = FALSE) {
static $cache;
-
- if (!isset($cache[$nid])) {
- $cache[$nid] = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $nid));
+ $key = $include_not_published ? 'published_unpublished' : 'published';
+
+ if (!isset($cache[$nid][$key])) {
+ if ($include_not_published || user_access('administer comments')) {
+ $cache[$nid] = db_fetch_array(db_query('SELECT COUNT(*) AS published_unpublished, ncs.comment_count AS published FROM {comments} c INNER JOIN {node_comment_statistics} ncs ON ncs.nid = c.nid WHERE c.nid = %d GROUP BY c.nid, ncs.comment_count', $nid));
+ }
+ else {
+ $cache[$nid][$key] = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $nid));
+ }
}
- return $cache[$nid];
+ return $cache[$nid][$key];
}
function comment_num_replies($pid) {
@@ -1348,25 +1361,7 @@
* to node)
*/
function comment_num_new($nid, $timestamp = 0) {
- global $user;
-
- if ($user->uid) {
- // Retrieve the timestamp at which the current user last viewed the
- // specified node.
- if (!$timestamp) {
- $timestamp = node_last_viewed($nid);
- }
- $timestamp = ($timestamp > NODE_NEW_LIMIT ? $timestamp : NODE_NEW_LIMIT);
-
- // Use the timestamp to retrieve the number of new comments.
- $result = db_result(db_query('SELECT COUNT(c.cid) FROM {node} n INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = %d AND timestamp > %d AND c.status = %d', $nid, $timestamp, COMMENT_PUBLISHED));
-
- return $result;
- }
- else {
- return 0;
- }
-
+ return _comment_new_comments($nid, 'num', $timestamp);
}
function comment_validate($edit) {
@@ -1672,7 +1667,8 @@
function comment_form_submit($form_id, $form_values) {
$form_values = _comment_form_submit($form_values);
if ($cid = comment_save($form_values)) {
- return array('node/'. $form_values['nid'], NULL, "comment-$cid");
+ $comment = db_fetch_object(db_query('SELECT c.cid, c.nid, c.timestamp, c.thread, ncs.comment_count FROM {comments} c INNER JOIN {node_comment_statistics} ncs ON ncs.nid = c.nid WHERE cid = %d', $cid));
+ return array('node/'. $form_values['nid'], comment_page_query($comment), "comment-$cid");
}
}
@@ -1939,6 +1935,130 @@
}
/**
+ * Return an URL query string that points to the page the comment is on.
+ * Used in links to comments (e.g. 'recent comments' block).
+ *
+ * @param $comment
+ * A comment object.
+ * Required fields: 'nid', 'timestamp', 'thread'
+ * Optional field: 'comment_count' (to save a db query get this field by
+ * doing a JOIN of the node_comment_statistics on the comments table)
+ */
+function comment_page_query($comment) {
+ $page = _comment_page($comment);
+ return $page ? "page=$page" : NULL;
+}
+
+/**
+ * Return an URL query string that points to the page the node's first new
+ * comment is on. Used in links to new comments ('# new' links).
+ *
+ * @param $nid
+ * A node ID.
+ */
+function comment_page_new_query($nid) {
+ $comments_per_page = _comment_get_display_setting('comments_per_page');
+ $comments_num = comment_num_all($nid, user_access('administer comments'));
+ if ($comments_num <= $comments_per_page) {
+ // one page of comments only
+ return NULL;
+ }
+ else {
+ // get the node's first new comment
+ $cid = _comment_new_comments($nid, 'first');
+ $comment = db_fetch_object(db_query('SELECT nid, timestamp, thread FROM {comments} WHERE cid = %d', $cid));
+ return comment_page_query($comment);
+ }
+}
+
+/**
+ * Return the page a comment is on
+ */
+function _comment_page($comment) {
+ $comments_per_page = _comment_get_display_setting('comments_per_page');
+ if (user_access('administer comments')) {
+ // For users with 'administer comments' permission
+ // we have to count published and unpublished comments.
+ $comments_num = comment_num_all($comment->nid, TRUE);
+ }
+ else {
+ $comments_num = isset($comment->comment_count) ? $comment->comment_count : comment_num_all($comment->nid);
+ }
+ if ($comments_num <= $comments_per_page) {
+ // one page of comments only
+ return 0;
+ }
+ else {
+ // Build the database query that retrieves the comment's position
+ // This follows the same sheme as in comment_render().
+ // See comments there for an explanation.
+ $query = 'SELECT COUNT(*) FROM {comments} WHERE nid = %d';
+ $query_args = array($comment->nid);
+
+ if (!user_access('administer comments')) {
+ $query .= ' AND status = %d';
+ $query_args[] = COMMENT_PUBLISHED;
+ }
+
+ $mode = _comment_get_display_setting('mode');
+ $order = _comment_get_display_setting('sort');
+ if ($order == COMMENT_ORDER_NEWEST_FIRST) {
+ if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
+ $query .= ' AND timestamp > %d';
+ $query_args[] = $comment->timestamp;
+ }
+ else {
+ $query .= " AND thread > '%s'";
+ $query_args[] = $comment->thread;
+ }
+ }
+ else if ($order == COMMENT_ORDER_OLDEST_FIRST) {
+ if ($mode == COMMENT_MODE_FLAT_COLLAPSED || $mode == COMMENT_MODE_FLAT_EXPANDED) {
+ $query .= ' AND timestamp < %d';
+ $query_args[] = $comment->timestamp;
+ }
+ else {
+ $query .= " AND SUBSTRING(thread, 1, (LENGTH(thread) - 1)) < '%s'";
+ $query_args[] = substr($comment->thread, 0, -1);
+ }
+ }
+
+ $count = db_result(db_query($query, $query_args));
+ return floor($count / $comments_per_page);
+ }
+}
+
+/**
+ * Return the specified node's number of new comments ($key = 'num')
+ * or the first new comment ($key = 'first') for the current user
+ */
+function _comment_new_comments($nid, $key, $timestamp = 0) {
+ global $user;
+ static $cache = array();
+
+ if ($user->uid) {
+ if (!isset($cache[$nid])) {
+ // Retrieve the timestamp at which the current user last viewed the
+ // specified node.
+ if (!$timestamp) {
+ $timestamp = node_last_viewed($nid);
+ }
+ $timestamp = ($timestamp > NODE_NEW_LIMIT ? $timestamp : NODE_NEW_LIMIT);
+
+ // Use the timestamp to retrieve the number of new comments
+ // and the first new comment
+ $result = db_query('SELECT COUNT(cid) AS num, MIN(cid) AS first FROM {comments} WHERE nid = %d AND timestamp > %d AND status = %d', $nid, $timestamp, COMMENT_PUBLISHED);
+ $cache[$nid] = db_fetch_array($result);
+ }
+ return $cache[$nid][$key];
+ }
+ else {
+ return NULL;
+ }
+
+}
+
+/**
* Updates the comment statistics for a given node. This should be called any
* time a comment is added, deleted, or updated.
*