--- ./database/database.mysql 2004/03/14 17:07:31 1.1.1.1
+++ ./database/database.mysql 2004/03/14 17:12:39
@@ -133,6 +133,17 @@
) TYPE=MyISAM;
--
+-- Table structure for table `comments_history`
+--
+
+CREATE TABLE comments_history (
+ uid int(10) NOT NULL default '0',
+ min_cid int(10) NOT NULL default '0',
+ max_cid int(10) NOT NULL default '0',
+ KEY (uid)
+) TYPE=MyISAM;
+
+--
-- Table structure for table 'directory'
--
--- ./modules/forum.module 2004/03/14 17:07:31 1.1.1.1
+++ ./modules/forum.module 2004/03/14 20:36:19
@@ -308,14 +312,42 @@
return db_result(db_query("SELECT COUNT(*) AS count FROM {comments} c INNER JOIN {node} n ON n.nid = c.nid INNER JOIN {forum} f ON n.nid = f.nid WHERE f.tid = %d AND n.nid = f.nid AND n.nid = c.nid AND n.status = 1 AND c.status = 0 AND n.type = 'forum'", $term));
}
-function _forum_topics_read($term, $uid) {
- // Calculate the number of topics the user has read. Assume all entries older
- // than NODE_NEW_LIMIT are read, and include the recent posts that user has
- // read.
- $ancient = db_result(db_query('SELECT COUNT(*) FROM {forum} f INNER JOIN {node} n ON f.nid = n.nid WHERE f.tid = %d AND n.status = 1 AND n.created <= %d AND f.shadow = 0', $term, NODE_NEW_LIMIT));
- $recent = db_result(db_query('SELECT COUNT(*) FROM {forum} f INNER JOIN {node} n ON f.nid = n.nid INNER JOIN {history} h ON n.nid = h.nid WHERE n.status = 1 AND f.tid = %d AND h.uid = %d AND n.created > %d AND f.shadow = 0', $term, $uid, NODE_NEW_LIMIT));
+function _forum_topics_unread($term, $uid) {
+ // Find the unread topics in each forum, or in only the specified
+ // forum if one is specified. The unread topics must have been
+ // created since NODE_NEW_LIMIT or have unread comments created
+ // since NODE_NEW_LIMIT and and must not have been marked read in
+ // the history table. Return a nested array of tids, nids and
+ // timestamps (indicating how new the topic should be considered).
+
+ // First find new topics
- return $ancient + $recent;
+ $query_string = 'SELECT f.tid, f.nid, n.created FROM {forum} f INNER JOIN {node} n ON f.nid = n.nid LEFT JOIN {history} h ON n.nid = h.nid AND h.uid = %d WHERE n.status = 1 AND h.uid IS NULL AND n.created > %d AND f.shadow = 0';
+ if ($term) {
+ $query_string .= ' AND f.tid = %d';
+ }
+ $result = db_query($query_string, $uid, NODE_NEW_LIMIT, $term);
+
+ while ($obj = db_fetch_object($result)) {
+ $unread[$obj->tid][$obj->nid] = $obj->created;
+ }
+
+ // Now find topics with new comments
+
+ $query_string = 'SELECT f.tid, c.nid, c.timestamp FROM {comments} c LEFT JOIN {comments_history} h ON h.uid = %d AND c.cid >= h.min_cid AND c.cid <= h.max_cid';
+ if ($term) {
+ $query_string .= sprintf(' AND f.tid = %d', $term);
+ }
+ $query_string .= ' INNER JOIN {forum} f ON c.nid = f.nid WHERE c.status = 0 AND h.min_cid IS NULL AND f.shadow = 0 and c.timestamp > %d GROUP BY tid, nid';
+ $result = db_query($query_string, $uid, NODE_NEW_LIMIT);
+
+ while ($obj = db_fetch_object($result)) {
+ if (! $unread[$obj->tid][$obj->nid]) {
+ $unread[$obj->tid][$obj->nid] = $obj->timestamp;
+ }
+ }
+
+ return $unread ? $unread : array();
}
function _forum_last_post($term) {
@@ -370,7 +402,7 @@
$topic->new = 0;
}
else {
- $topic->new_replies = db_result(db_query('SELECT COUNT(c.nid) FROM {node} n INNER JOIN {comments} c ON n.nid = c.nid WHERE n.nid = %d AND n.status = 1 AND c.status = 0 AND c.timestamp > %d', $topic->nid, $history));
+ $topic->new_replies = comment_num_new($topic->nid);
$topic->new = $topic->new_replies || ($topic->timestamp > $history);
}
}
@@ -387,16 +419,22 @@
return $topics;
}
-function _forum_new($tid) {
+function _forum_new($tid, $exclude = 0) {
global $user;
- $result = db_query("SELECT n.nid FROM {node} n, {history} h, {forum} f WHERE n.type = 'forum' AND n.status = 1 AND h.nid = n.nid AND f.nid = h.nid AND f.tid = %d AND h.uid = %d", $tid, $user->uid);
- while ($r = db_fetch_object($result)) {
- $read[] = $r->nid;
- }
+ $read = _forum_topics_unread($tid, $user->uid);
+ $read = $read[$tid];
- $nid = db_result(db_query_range("SELECT n.nid FROM {node} n INNER JOIN {forum} f ON n.nid = f.nid WHERE n.type = 'forum' AND f.nid = n.nid AND n.status = 1 AND f.tid = %d ". ($read ? "AND NOT (n.nid IN (". implode(',', $read) .")) " : '') ."ORDER BY created", $tid, 0, 1));
+ if ($read) {
+ asort($read, SORT_NUMERIC);
+
+ foreach ($read as $nid => $timestamp) {
+ if (! $exclude || ($nid != $exclude)) {
+ return $nid;
+ }
+ }
+ }
- return $nid ? $nid : 0;
+ return 0;
}
function forum_page() {
@@ -513,6 +551,10 @@
$header = array(t('Forum'), t('Topics'), t('Posts'), t('Last post'));
+ if ($user->uid) {
+ $unread = _forum_topics_unread(0, $user->uid);
+ }
+
foreach ($forums as $forum) {
if ($forum->container) {
$description = "
depth * 30) ."px;\">\n";
@@ -526,13 +568,13 @@
$rows[] = array(array('data' => $description, 'class' => 'container', 'colspan' => 4));
}
else {
- $forum->old_topics = _forum_topics_read($forum->tid, $user->uid);
if ($user->uid) {
- $new_topics = $forum->num_topics - $forum->old_topics;
+ $new_topics = count($unread[$forum->tid]);
}
else {
$new_topics = 0;
}
+ $forum->old_topics = $forum->num_topics - $new_topics;
$links = array();
--- ./modules/comment.module 2004/03/14 17:07:31 1.1.1.1
+++ ./modules/comment.module 2004/03/15 01:13:37
@@ -644,7 +654,7 @@
*/
if ($order == 1) {
- if ($mode == 1 || $mode == 2) {
+ if ($mode == 1 || $mode == 2 || $mode == 5) {
$query .= " ORDER BY c.timestamp DESC";
}
else {
@@ -652,7 +662,7 @@
}
}
else if ($order == 2) {
- if ($mode == 1 || $mode == 2) {
+ if ($mode == 1 || $mode == 2 || $mode == 5) {
$query .= " ORDER BY c.timestamp";
}
else {
@@ -684,6 +694,7 @@
while ($comment = db_fetch_object($result)) {
$comment = drupal_unpack($comment);
+ $comment->new = comment_is_new($comment->cid);
$comment->depth = count(explode(".", $comment->thread)) - 1;
if ($mode == 1) {
@@ -692,12 +703,18 @@
else if ($mode == 2) {
$output .= theme("comment_flat_expanded", $comment, $threshold_min);
}
+ else if ($mode == 5) {
+ $output .= theme("comment_flat_new_expanded", $comment, $threshold_min);
+ }
else if ($mode == 3) {
$output .= theme("comment_thread_min", $comment, $threshold_min);
}
else if ($mode == 4) {
$output .= theme("comment_thread_max", $comment, $threshold_min);
}
+ else if ($mode == 6) {
+ $output .= theme("comment_thread_new_max", $comment, $threshold_min);
+ }
}
/*
@@ -984,7 +1006,7 @@
$result = pager_query($sql, 50);
while ($comment = db_fetch_object($result)) {
- $rows[] = array(l($comment->subject, "node/view/$comment->nid/$comment->cid", array("title" => htmlspecialchars(substr($comment->comment, 0, 128))), NULL, "comment-$comment->cid") ." ". (node_is_new($comment->nid, $comment->timestamp) ? theme("mark") : ""), format_name($comment), ($comment->status == 0 ? t("published") : t("not published")) ."
". format_date($comment->timestamp, "small") ." | ". l(t("edit comment"), "admin/comment/edit/$comment->cid"), l(t("delete comment"), "admin/comment/delete/$comment->cid"));
+ $rows[] = array(l($comment->subject, "node/view/$comment->nid/$comment->cid", array("title" => htmlspecialchars(substr($comment->comment, 0, 128))), NULL, "comment-$comment->cid") ." ". (comment_is_new($comment->cid) ? theme("mark") : ""), format_name($comment), ($comment->status == 0 ? t("published") : t("not published")) ." | ". format_date($comment->timestamp, "small") ." | ". l(t("edit comment"), "admin/comment/edit/$comment->cid"), l(t("delete comment"), "admin/comment/delete/$comment->cid"));
}
if ($pager = theme("pager", NULL, 50, 0, tablesort_pager())) {
@@ -1273,8 +1295,10 @@
** Switch to folded/unfolded view of the comment
*/
$output = "";
- if (node_is_new($comment->nid, $comment->timestamp)) {
- $comment->new = 1;
+ if (! isset($comment->new)) {
+ $comment->new = comment_is_new($comment->cid);
+ }
+ if ($comment->new) {
$output .= "\n";
}
@@ -1283,6 +1307,7 @@
if ($visible) {
$comment->comment = check_output($comment->comment);
$output .= theme("comment", $comment, $links);
+ comment_tag_new($comment->cid);
}
else {
$output .= theme("comment_folded", $comment);
@@ -1394,7 +1419,8 @@
$output .= " ". check_output($comment->comment) ." ";
$output .= "$links ";
$output .= "";
+ comment_tag_new($comment->cid);
return $output;
}
function theme_comment_folded($comment) {
@@ -1408,8 +1438,14 @@
return "";
}
-function theme_comment_flat_expanded($comment, $threshold) {
- return theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 0)), comment_visible($comment, $threshold));
+function theme_comment_flat_expanded($comment, $threshold, $check_new = 0) {
+ $expand = comment_visible($comment, $threshold) &&
+ ($check_new ? $comment->new : 1);
+ return theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 0)), $expand);
+}
+
+function theme_comment_flat_new_expanded($comment, $threshold) {
+ return theme_comment_flat_expanded($comment, $treshold, 1);
}
function theme_comment_thread_min($comment, $threshold, $pid = 0) {
@@ -1421,13 +1457,16 @@
return $output;
}
-function theme_comment_thread_max($comment, $threshold, $level = 0) {
+function theme_comment_thread_max($comment, $threshold, $level = 0, $check_new = 0) {
$output = "";
if ($comment->depth) {
$output .= "depth * 25) ."px;\">\n";
}
- $output .= theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 0)), comment_visible($comment, $threshold));
+ $expand = comment_visible($comment, $threshold) &&
+ ($check_new ? $comment->new : 1);
+
+ $output .= theme("comment_view", $comment, theme('links', module_invoke_all('link', 'comment', $comment, 0)), $expand);
if ($comment->depth) {
$output .= " \n";
@@ -1435,6 +1474,10 @@
return $output;
}
+function theme_comment_thread_new_max($comment, $threshold, $level = 0) {
+ return theme_comment_thread_max($comment, $threshold, $level, 1);
+}
+
function theme_comment_post_forbidden() {
global $user;
if ($user->uid) {
@@ -1537,40 +1580,6 @@
return $cache[$pid];
}
-/**
- * get number of new comments for current user and specified node
- *
- * @param $nid node-id to count comments for
- * @param $timestamp time to count from (defaults to time of last user access
- * 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);
- }
-
- /*
- ** 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 = 0", $nid, $timestamp));
-
- return $result;
- }
- else {
- return 0;
- }
-
-}
-
function comment_user_can_moderate($node) {
global $user;
return (user_access("moderate comments"));
@@ -1669,7 +1678,7 @@
** is not initialized yet when the comment module is loaded.
*/
- return array(1 => t("Flat list - collapsed"), 2 => t("Flat list - expanded"), 3 => t("Threaded list - collapsed"), 4 => t("Threaded list - expanded"));
+ return array(1 => t("Flat list - collapsed"), 2 => t("Flat list - expanded"), 5 => t("Flat list - new expanded"), 3 => t("Threaded list - collapsed"), 4 => t("Threaded list - expanded"), 6 => t("Threaded list - new expanded"));
}
function _comment_get_orders() {
@@ -1680,6 +1689,106 @@
return array(1 => t("Date - newest first"), 2 => t("Date - oldest first"));
}
+function comment_tag_new($cid) {
+ global $user;
+
+ if (! $user->uid) {
+ return;
+ }
+
+ $result = db_query("SELECT uid FROM {comments_history} WHERE uid = %d AND min_cid <= %d and max_cid >= %d", $user->uid, $cid, $cid);
+ if (db_fetch_object($result)) {
+ return;
+ }
+
+ db_query("UPDATE {comments_history} SET min_cid = %d where uid = %d AND min_cid = %d", $cid, $user->uid, $cid + 1);
+ if (db_affected_rows()) {
+ return;
+ }
+
+ db_query("UPDATE {comments_history} SET max_cid = %d where uid = %d AND max_cid = %d", $cid, $user->uid, $cid - 1);
+ if (db_affected_rows()) {
+ return;
+ }
+
+ db_query("INSERT INTO {comments_history} (uid, min_cid, max_cid) VALUES (%d, %d, %d)", $user->uid, $cid, $cid);
+}
+
+function comment_is_new($cid) {
+ global $user;
+
+ if (! $user->uid) {
+ return false;
+ }
+
+ $result = db_query("SELECT * FROM {comments_history} where uid = %d and min_cid <= %d and max_cid >= %d", $user->uid, $cid, $cid);
+ if (db_fetch_object($result)) {
+ return false;
+ }
+
+ return true;
+}
+
+function comment_num_new($nid) {
+ global $user;
+
+ if (! $user->uid) {
+ return 0;
+ }
+
+ $result = db_result(db_query("SELECT COUNT(c.cid) FROM {comments} c LEFT JOIN {comments_history} h ON h.uid = %d AND c.cid >= h.min_cid AND c.cid <= h.max_cid WHERE c.nid = %d AND c.status = 0 AND h.min_cid IS NULL", $user->uid, $nid));
+
+ return $result;
+}
+
+function comment_cron() {
+ $earliest = db_result(db_query('SELECT MIN(c.cid) FROM {comments} c WHERE c.timestamp > %d', NODE_NEW_LIMIT));
+ db_query('DELETE FROM {comments} WHERE max_cid < %d', $earliest);
+
+ $rows = db_query("SELECT * FROM {comments_history} ORDER BY uid, min_cid");
+
+ if (! ($row = db_fetch_object($rows))) {
+ return;
+ }
+
+ $uid = $row->uid;
+ $min = $row->min_cid;
+ $max = $row->max_cid;
+ $updating = false;
+
+ while ($row = db_fetch_object($rows)) {
+ if ($row->uid == $uid && $row->min_cid <= $max + 1) {
+ $updating = true;
+ $max = max($max, $row->max_cid);
+ continue;
+ }
+ if ($updating) {
+ $updates[] = array($uid, $min, $max);
+ }
+ $uid = $row->uid;
+ $min = $row->min_cid;
+ $max = $row->max_cid;
+ $updating = false;
+ }
+
+ if ($updating) {
+ $updates[] = array($uid, $min, $max);
+ }
+
+ if (! $updates) {
+ return;
+ }
+
+ foreach ($updates as $update) {
+ $uid = $update[0];
+ $min = $update[1];
+ $max = $update[2];
+
+ db_query("INSERT INTO {comments_history} (uid, min_cid, max_cid) values (%d, %d, %d)", $uid, $min, $max);
+ db_query("DELETE FROM {comments_history} WHERE uid = %d AND (min_cid > %d and max_cid < %d) OR (min_cid = %d and max_cid < %d) OR (min_cid > %d AND max_cid = %d)", $uid, $min, $max, $min, $max, $min, $max);
+ }
+}
+
function _comment_per_page() {
return drupal_map_assoc(array(10, 30, 50, 70, 90));
}
|