? i148849_2.patch ? sites/all/modules ? sites/default/settings.php Index: modules/comment/comment.module =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.module,v retrieving revision 1.570 diff -u -p -r1.570 comment.module --- modules/comment/comment.module 30 Jul 2007 21:27:34 -0000 1.570 +++ modules/comment/comment.module 5 Aug 2007 14:05:00 -0000 @@ -282,8 +282,7 @@ function comment_block($op = 'list', $de /** * Find a number of recent comments. This is done in two steps. * 1. Find the n (specified by $number) nodes that have the most recent - * comments. This is done by querying node_comment_statistics which has - * an index on last_comment_timestamp, and is thus a fast query. + * comments. * 2. Loading the information from the comments table based on the nids found * in step 1. * @@ -295,8 +294,10 @@ function comment_block($op = 'list', $de function comment_get_recent($number = 10) { // 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); + // last_activity. + + // TODO: Rewrite to only retrieve *comments* and not just activity + $result = db_query_range(db_rewrite_sql("SELECT n.nid FROM {node} n WHERE n.comment_count > 0 ORDER BY n.last_activity DESC", 'nc'), 0, $number); $nids = array(); while ($row = db_fetch_object($result)) { @@ -451,9 +452,6 @@ function comment_form_alter(&$form, $for */ function comment_nodeapi(&$node, $op, $arg = 0) { switch ($op) { - case 'load': - return db_fetch_array(db_query("SELECT last_comment_timestamp, last_comment_name, comment_count FROM {node_comment_statistics} WHERE nid = %d", $node->nid)); - break; case 'prepare': if (!isset($node->comment)) { @@ -461,13 +459,8 @@ function comment_nodeapi(&$node, $op, $a } break; - case 'insert': - db_query('INSERT INTO {node_comment_statistics} (nid, last_comment_timestamp, last_comment_name, last_comment_uid, comment_count) VALUES (%d, %d, NULL, %d, 0)', $node->nid, $node->changed, $node->uid); - break; - case 'delete': db_query('DELETE FROM {comments} WHERE nid = %d', $node->nid); - db_query('DELETE FROM {node_comment_statistics} WHERE nid = %d', $node->nid); break; case 'update index': @@ -479,7 +472,7 @@ function comment_nodeapi(&$node, $op, $a return $text; case 'search result': - $comments = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $node->nid)); + $comments = db_result(db_query('SELECT comment_count FROM {node} WHERE nid = %d', $node->nid)); return format_plural($comments, '1 comment', '@count comments'); case 'rss item': @@ -498,7 +491,6 @@ function comment_nodeapi(&$node, $op, $a function comment_user($type, $edit, &$user, $category = NULL) { if ($type == 'delete') { db_query('UPDATE {comments} SET uid = 0 WHERE uid = %d', $user->uid); - db_query('UPDATE {node_comment_statistics} SET last_comment_uid = 0 WHERE last_comment_uid = %d', $user->uid); } } @@ -965,7 +957,6 @@ function comment_render($node, $cid = 0) $query_args[] = COMMENT_PUBLISHED; } - $query = db_rewrite_sql($query, 'c', 'cid'); $result = db_query($query, $query_args); if ($comment = db_fetch_object($result)) { @@ -1011,8 +1002,6 @@ function comment_render($node, $cid = 0) $query .= ' ORDER BY SUBSTRING(c.thread, 1, (LENGTH(c.thread) - 1))'; } } - $query = db_rewrite_sql($query, 'c', 'cid'); - $query_count = db_rewrite_sql($query_count, 'c', 'cid'); // Start a form, for use with comment control. $result = pager_query($query, $comments_per_page, 0, $query_count, $query_args); @@ -1334,7 +1323,7 @@ function comment_num_all($nid) { static $cache; if (!isset($cache[$nid])) { - $cache[$nid] = db_result(db_query('SELECT comment_count FROM {node_comment_statistics} WHERE nid = %d', $nid)); + $cache[$nid] = db_result(db_query('SELECT COUNT(*) AS comment_count FROM {comments} WHERE nid = %d', $nid)); } return $cache[$nid]; } @@ -1343,7 +1332,7 @@ function comment_num_replies($pid) { static $cache; if (!isset($cache[$pid])) { - $cache[$pid] = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE pid = %d AND status = %d', $pid, COMMENT_PUBLISHED)); + $cache[$pid] = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE pid = %d AND status = %d', $pid, COMMENT_PUBLISHED)); } return $cache[$pid]; @@ -1368,7 +1357,7 @@ function comment_num_new($nid, $timestam $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)); + $result = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d AND timestamp > %d AND status = %d', $nid, $timestamp, COMMENT_PUBLISHED)); return $result; } @@ -2005,29 +1994,12 @@ function _comment_get_display_setting($s } /** - * Updates the comment statistics for a given node. This should be called any - * time a comment is added, deleted, or updated. - * - * The following fields are contained in the node_comment_statistics table. - * - last_comment_timestamp: the timestamp of the last comment for this node or the node create stamp if no comments exist for the node. - * - last_comment_name: the name of the anonymous poster for the last comment - * - last_comment_uid: the uid of the poster for the last comment for this node or the node authors uid if no comments exists for the node. - * - comment_count: the total number of approved/published comments on this node. + * Implementation of hook_activity(). */ -function _comment_update_node_statistics($nid) { - $count = db_result(db_query('SELECT COUNT(cid) FROM {comments} WHERE nid = %d AND status = %d', $nid, COMMENT_PUBLISHED)); - - // comments exist - if ($count > 0) { - $last_reply = db_fetch_object(db_query_range('SELECT cid, name, timestamp, uid FROM {comments} WHERE nid = %d AND status = %d ORDER BY cid DESC', $nid, COMMENT_PUBLISHED, 0, 1)); - db_query("UPDATE {node_comment_statistics} SET comment_count = %d, last_comment_timestamp = %d, last_comment_name = '%s', last_comment_uid = %d WHERE nid = %d", $count, $last_reply->timestamp, $last_reply->uid ? '' : $last_reply->name, $last_reply->uid, $nid); - } - - // no comments - else { - $node = db_fetch_object(db_query("SELECT uid, created FROM {node} WHERE nid = %d", $nid)); - db_query("UPDATE {node_comment_statistics} SET comment_count = 0, last_comment_timestamp = %d, last_comment_name = '', last_comment_uid = %d WHERE nid = %d", $node->created, $node->uid, $nid); - } +function comment_activity($node) { + $activity = db_fetch_array(db_query_range('SELECT timestamp, uid FROM {comments} WHERE nid = %d ORDER BY timestamp DESC', $node->nid, 0, 1)); + $activity['count'] = db_result(db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d', $node->nid)); + return $activity; } /** @@ -2055,7 +2027,6 @@ function comment_invoke_comment(&$commen return $return; } - /** * Generate vancode. * @@ -2185,3 +2156,25 @@ function comment_unpublish_by_keyword_ac } } } + +/** + * Implementation of hook_user_activity(). + */ +function comment_user_activity($node, $uid) { + $count = db_query('SELECT COUNT(*) FROM {comments} WHERE nid = %d AND uid = %d', $node->nid, $uid); + return ($count > 0); +} + +/** + * Implementation of hook_node_activity(). + */ +function comment_node_activity($node) { + $res = db_query_range('SELECT uid, timestamp FROM {comments} WHERE nid = %d ORDER BY timestamp DESC', 0, 1); + if ($comment = db_fetch_object($res)) { + return array( + 'timestamp' => $comment->timestamp, + 'uid' => $comment->uid, + ); + } + return FALSE; +} Index: modules/comment/comment.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/comment/comment.schema,v retrieving revision 1.4 diff -u -p -r1.4 comment.schema --- modules/comment/comment.schema 30 Jul 2007 21:27:34 -0000 1.4 +++ modules/comment/comment.schema 5 Aug 2007 14:05:00 -0000 @@ -26,17 +26,5 @@ function comment_schema() { 'primary key' => array('cid'), ); - $schema['node_comment_statistics'] = array( - 'fields' => array( - 'nid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), - 'last_comment_timestamp' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'last_comment_name' => array('type' => 'varchar', 'length' => 60, 'not null' => FALSE), - 'last_comment_uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'comment_count' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0) - ), - 'indexes' => array('node_comment_timestamp' => array('last_comment_timestamp')), - 'primary key' => array('nid'), - ); - return $schema; } Index: modules/forum/forum.module =================================================================== RCS file: /cvs/drupal/drupal/modules/forum/forum.module,v retrieving revision 1.412 diff -u -p -r1.412 forum.module --- modules/forum/forum.module 3 Aug 2007 06:07:52 -0000 1.412 +++ modules/forum/forum.module 5 Aug 2007 14:05:01 -0000 @@ -373,7 +373,7 @@ function forum_block($op = 'list', $delt switch ($delta) { case 0: $title = t('Active forum topics'); - $sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {term_node} tn ON tn.nid = n.nid INNER JOIN {term_data} td ON td.tid = tn.tid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND td.vid = %d ORDER BY l.last_comment_timestamp DESC"); + $sql = db_rewrite_sql("SELECT n.nid, n.title, n.comment_count, n.last_activity FROM {node} n WHERE n.status = 1 AND n.type = 'forum' ORDER BY n.last_activity DESC"); $result = db_query_range($sql, variable_get('forum_nav_vocabulary', ''), 0, variable_get('forum_block_num_0', '5')); if (db_num_rows($result)) { $content = node_title_list($result); @@ -382,7 +382,7 @@ function forum_block($op = 'list', $delt case 1: $title = t('New forum topics'); - $sql = db_rewrite_sql("SELECT n.nid, n.title, l.comment_count FROM {node} n INNER JOIN {term_node} tn ON tn.nid = n.nid INNER JOIN {term_data} td ON td.tid = tn.tid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 AND td.vid = %d ORDER BY n.nid DESC"); + $sql = db_rewrite_sql("SELECT n.nid, n.title, n.comment_count FROM {node} n WHERE n.type = 'forum' AND n.status = 1 ORDER BY n.nid DESC"); $result = db_query_range($sql, variable_get('forum_nav_vocabulary', ''), 0, variable_get('forum_block_num_1', '5')); if (db_num_rows($result)) { $content = node_title_list($result); @@ -461,7 +461,7 @@ function forum_get_forums($tid = 0) { $counts = array(); - $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(l.comment_count) AS comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 GROUP BY r.tid"; + $sql = "SELECT r.tid, COUNT(n.nid) AS topic_count, SUM(n.comment_count) AS comment_count FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid WHERE n.status = 1 GROUP BY r.tid"; $sql = db_rewrite_sql($sql); $_counts = db_query($sql); while ($count = db_fetch_object($_counts)) { @@ -483,18 +483,15 @@ function forum_get_forums($tid = 0) { $forum->num_posts = 0; } - // This query does not use full ANSI syntax since MySQL 3.x does not support - // table1 INNER JOIN table2 INNER JOIN table3 ON table2_criteria ON table3_criteria - // used to join node_comment_statistics to users. - $sql = "SELECT ncs.last_comment_timestamp, IF (ncs.last_comment_uid != 0, u2.name, ncs.last_comment_name) AS last_comment_name, ncs.last_comment_uid FROM {node} n INNER JOIN {users} u1 ON n.uid = u1.uid INNER JOIN {term_node} tn ON n.nid = tn.nid INNER JOIN {node_comment_statistics} ncs ON n.nid = ncs.nid INNER JOIN {users} u2 ON ncs.last_comment_uid=u2.uid WHERE n.status = 1 AND tn.tid = %d ORDER BY ncs.last_comment_timestamp DESC"; + $sql = "SELECT n.last_activity, lau.name AS last_activity_name, n.last_activity_uid FROM {node} n INNER JOIN {users} lau ON n.last_activity_uid = lau.uid INNER JOIN {term_node} tn ON n.nid = tn.nid WHERE n.status = 1 AND tn.tid = %d ORDER BY n.last_activity DESC"; $sql = db_rewrite_sql($sql); $topic = db_fetch_object(db_query_range($sql, $forum->tid, 0, 1)); $last_post = new stdClass(); - if (!empty($topic->last_comment_timestamp)) { - $last_post->timestamp = $topic->last_comment_timestamp; - $last_post->name = $topic->last_comment_name; - $last_post->uid = $topic->last_comment_uid; + if (!empty($topic->last_activity)) { + $last_post->timestamp = $topic->last_activity; + $last_post->name = $topic->last_activity_name; + $last_post->uid = $topic->last_activity_uid; } $forum->last_post = $last_post; @@ -519,10 +516,10 @@ function forum_get_topics($tid, $sortby, $forum_topic_list_header = array( array('data' => ' ', 'field' => NULL), - array('data' => t('Topic'), 'field' => 'n.title'), - array('data' => t('Replies'), 'field' => 'l.comment_count'), + array('data' => t('Topic'), 'field' => 'n.title'), // Slow but uncommon + array('data' => t('Replies'), 'field' => 'n.activity_count'), array('data' => t('Created'), 'field' => 'n.created'), - array('data' => t('Last reply'), 'field' => 'l.last_comment_timestamp'), + array('data' => t('Last reply'), 'field' => 'n.last_activity'), ); $order = _forum_get_topic_order($sortby); @@ -534,9 +531,9 @@ function forum_get_topics($tid, $sortby, $term = taxonomy_get_term($tid); - $sql = db_rewrite_sql("SELECT n.nid, r.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, l.last_comment_timestamp, IF(l.last_comment_uid != 0, cu.name, l.last_comment_name) AS last_comment_name, l.last_comment_uid, l.comment_count AS num_comments FROM {node_comment_statistics} l, {users} cu, {term_node} r, {users} u, {node} n WHERE n.status = 1 AND l.last_comment_uid = cu.uid AND n.nid = l.nid AND n.nid = r.nid AND r.tid = %d AND n.uid = u.uid AND n.vid = r.vid"); + $sql = db_rewrite_sql("SELECT n.nid, f.tid, n.title, n.sticky, u.name, u.uid, n.created AS timestamp, n.comment AS comment_mode, n.last_activity, lau.name AS last_activity_name, n.last_activity_uid, n.comment_count AS num_comments FROM {node} n INNER JOIN {users} lau ON n.last_activity_uid = lau.uid INNER JOIN {term_node} r ON n.nid = r.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND r.tid = %d"); $sql .= tablesort_sql($forum_topic_list_header, 'n.sticky DESC,'); - $sql .= ', n.created DESC'; // Always add a secondary sort order so that the news forum topics are on top. + $sql .= ', n.created DESC'; // Always add a secondary sort order so that the new forum topics are on top. $sql_count = db_rewrite_sql("SELECT COUNT(n.nid) FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1"); @@ -550,7 +547,7 @@ function forum_get_topics($tid, $sortby, } else { $history = _forum_user_last_visit($topic->nid); - $topic->new_replies = comment_num_new($topic->nid, $history); + $topic->new_replies = node_activity_num_new($topic->nid, $history); $topic->new = $topic->new_replies || ($topic->timestamp > $history); } } @@ -562,9 +559,9 @@ function forum_get_topics($tid, $sortby, if ($topic->num_comments > 0) { $last_reply = new stdClass(); - $last_reply->timestamp = $topic->last_comment_timestamp; - $last_reply->name = $topic->last_comment_name; - $last_reply->uid = $topic->last_comment_uid; + $last_reply->timestamp = $topic->last_activity; + $last_reply->name = $topic->last_activity_name; + $last_reply->uid = $topic->last_activity_uid; $topic->last_reply = $last_reply; } $topics[] = $topic; @@ -835,7 +832,7 @@ function template_preprocess_forum_topic $output = ''; // get previous and next topic - $sql = "SELECT n.nid, n.title, n.sticky, l.comment_count, l.last_comment_timestamp FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1)); + $sql = "SELECT n.nid, n.title, n.sticky, n.comment_count, n.last_activity FROM {node} n INNER JOIN {term_node} r ON n.nid = r.nid AND r.tid = %d WHERE n.status = 1 ORDER BY n.sticky DESC, ". _forum_get_topic_order_sql(variable_get('forum_order', 1)); $result = db_query(db_rewrite_sql($sql), isset($variables['node']->tid) ? $variables['node']->tid : 0); $stop = $variables['prev'] = $variables['next'] = 0; @@ -876,7 +873,7 @@ function _forum_user_last_visit($nid) { static $history = array(); if (empty($history)) { - $result = db_query('SELECT nid, timestamp FROM {history} WHERE uid = %d', $user->uid); + $result = db_query('SELECT nid, timestamp FROM {node_user_view} WHERE uid = %d', $user->uid); while ($t = db_fetch_object($result)) { $history[$t->nid] = $t->timestamp > NODE_NEW_LIMIT ? $t->timestamp : NODE_NEW_LIMIT; } @@ -887,16 +884,16 @@ function _forum_user_last_visit($nid) { function _forum_get_topic_order($sortby) { switch ($sortby) { case 1: - return array('field' => 'l.last_comment_timestamp', 'sort' => 'desc'); + return array('field' => 'n.last_activity', 'sort' => 'desc'); break; case 2: - return array('field' => 'l.last_comment_timestamp', 'sort' => 'asc'); + return array('field' => 'n.last_activity', 'sort' => 'asc'); break; case 3: - return array('field' => 'l.comment_count', 'sort' => 'desc'); + return array('field' => 'n.activity_count', 'sort' => 'desc'); break; case 4: - return array('field' => 'l.comment_count', 'sort' => 'asc'); + return array('field' => 'n.activity_count', 'sort' => 'asc'); break; } } Index: modules/node/node.module =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.module,v retrieving revision 1.865 diff -u -p -r1.865 node.module --- modules/node/node.module 2 Aug 2007 20:08:52 -0000 1.865 +++ modules/node/node.module 5 Aug 2007 14:05:05 -0000 @@ -61,10 +61,6 @@ function node_help($path, $arg) { */ function node_theme() { return array( - 'node' => array( - 'arguments' => array('node' => NULL, 'teaser' => FALSE, 'page' => FALSE), - 'file' => 'node', - ), 'node_list' => array( 'arguments' => array('items' => NULL, 'title' => NULL), ), @@ -106,7 +102,7 @@ function node_cron() { * Gather a listing of links to nodes. * * @param $result - * A DB result object from a query to fetch node objects. If your query joins the node_comment_statistics table so that the comment_count field is available, a title attribute will be added to show the number of comments. + * A DB result object from a query to fetch node objects. A title attribute is added to show the number of comments. * @param $title * A heading for the resulting list. * @@ -115,7 +111,7 @@ function node_cron() { */ function node_title_list($result, $title = NULL) { while ($node = db_fetch_object($result)) { - $items[] = l($node->title, 'node/'. $node->nid, !empty($node->comment_count) ? array('title' => format_plural($node->comment_count, '1 comment', '@count comments')) : array()); + $items[] = l($node->title, 'node/'. $node->nid, array('title' => format_plural($node->comment_count, '1 comment', '@count comments'))); } return theme('node_list', $items, $title); @@ -136,10 +132,10 @@ function node_tag_new($nid) { if ($user->uid) { if (node_last_viewed($nid)) { - db_query('UPDATE {history} SET timestamp = %d WHERE uid = %d AND nid = %d', time(), $user->uid, $nid); + db_query('UPDATE {node_user_view} SET timestamp = %d, activity_count = %d WHERE uid = %d AND nid = %d', time(), $user->uid, $nid); } else { - @db_query('INSERT INTO {history} (uid, nid, timestamp) VALUES (%d, %d, %d)', $user->uid, $nid, time()); + @db_query('INSERT INTO {node_user_view} (uid, nid, timestamp) VALUES (%d, %d, %d)', $user->uid, $nid, time()); } } } @@ -153,7 +149,7 @@ function node_last_viewed($nid) { static $history; if (!isset($history[$nid])) { - $history[$nid] = db_fetch_object(db_query("SELECT timestamp FROM {history} WHERE uid = %d AND nid = %d", $user->uid, $nid)); + $history[$nid] = db_fetch_object(db_query("SELECT timestamp FROM {node_user_view} WHERE uid = %d AND nid = %d", $user->uid, $nid)); } return (isset($history[$nid]->timestamp) ? $history[$nid]->timestamp : 0); @@ -709,12 +705,14 @@ function node_save(&$node) { 'title' => $node->title, 'type' => $node->type, 'uid' => $node->uid, 'status' => $node->status, 'language' => $node->language, 'created' => $node->created, 'changed' => $node->changed, 'comment' => $node->comment, - 'promote' => $node->promote, 'sticky' => $node->sticky); + 'promote' => $node->promote, 'sticky' => $node->sticky, + 'last_activity' => $node->changed); $node_table_types = array( 'title' => "'%s'", 'type' => "'%s'", 'uid' => '%d', 'status' => '%d', 'language' => "'%s'",'created' => '%d', 'changed' => '%d', 'comment' => '%d', - 'promote' => '%d', 'sticky' => '%d'); + 'promote' => '%d', 'sticky' => '%d', + 'last_activity' => '%d'); $update_node = TRUE; //Generate the node table query and the //the node_revisions table query @@ -924,9 +922,8 @@ function node_search($op = 'search', $ke case 'status': $last = variable_get('node_cron_last', 0); - $last_nid = variable_get('node_cron_last_nid', 0); $total = db_result(db_query('SELECT COUNT(*) FROM {node} WHERE status = 1')); - $remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.created, n.changed, c.last_comment_timestamp) = %d AND n.nid > %d ) OR (n.created > %d OR n.changed > %d OR c.last_comment_timestamp > %d))', $last, $last_nid, $last, $last, $last)); + $remaining = db_result(db_query('SELECT COUNT(*) FROM {node} n WHERE n.status = 1 AND n.last_activity >= %d', $last)); return array('remaining' => $remaining, 'total' => $total); case 'admin': @@ -984,8 +981,8 @@ function node_search($op = 'search', $ke $ranking = array(); $arguments2 = array(); $join2 = ''; - // Used to avoid joining on node_comment_statistics twice - $stats_join = FALSE; + // Used to avoid joining on node twice + $node_join = FALSE; $total = 0; if ($weight = (int)variable_get('node_rank_relevance', 5)) { // Average relevance values hover around 0.15 @@ -995,11 +992,11 @@ function node_search($op = 'search', $ke } if ($weight = (int)variable_get('node_rank_recent', 5)) { // Exponential decay with half-life of 6 months, starting at last indexed node - $ranking[] = '%d * POW(2, (GREATEST(n.created, n.changed, c.last_comment_timestamp) - %d) * 6.43e-8)'; + $ranking[] = '%d * POW(2, (n.last_activity - %d) * 6.43e-8)'; $arguments2[] = $weight; $arguments2[] = (int)variable_get('node_cron_last', 0); - $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; - $stats_join = TRUE; + $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid'; + $node_join = TRUE; $total += $weight; } if (module_exists('comment') && $weight = (int)variable_get('node_rank_comments', 5)) { @@ -1008,8 +1005,9 @@ function node_search($op = 'search', $ke $ranking[] = '%d * (2.0 - 2.0 / (1.0 + c.comment_count * %f))'; $arguments2[] = $weight; $arguments2[] = $scale; - if (!$stats_join) { - $join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid'; + if (!$node_join) { + $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid'; + $node_join = TRUE; } $total += $weight; } @@ -1020,7 +1018,10 @@ function node_search($op = 'search', $ke $ranking[] = '%d * (2.0 - 2.0 / (1.0 + nc.totalcount * %f))'; $arguments2[] = $weight; $arguments2[] = $scale; - $join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid'; + if (!$node_join) { + $join2 .= ' INNER JOIN {node} n ON n.nid = i.sid'; + $node_join = TRUE; + } $total += $weight; } $select2 = (count($ranking) ? implode(' + ', $ranking) : 'i.relevance') .' AS score'; @@ -1064,6 +1065,7 @@ function node_user($op, &$edit, &$user) if ($op == 'delete') { db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $user->uid); db_query('UPDATE {node_revisions} SET uid = 0 WHERE uid = %d', $user->uid); + db_query('UPDATE {node} SET last_activity_uid = 0 WHERE last_activity_uid = %d', $user->uid); } } @@ -2597,10 +2599,10 @@ function node_update_index() { $limit = (int)variable_get('search_cron_limit', 100); // Store the maximum possible comments per thread (used for ranking by reply count) - variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node_comment_statistics}')))); - variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node_counter}')))); + variable_set('node_cron_comments_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(comment_count) FROM {node}')))); + variable_set('node_cron_views_scale', 1.0 / max(1, db_result(db_query('SELECT MAX(totalcount) FROM {node}')))); - $result = db_query_range('SELECT GREATEST(IF(c.last_comment_timestamp IS NULL, 0, c.last_comment_timestamp), n.changed) as last_change, n.nid FROM {node} n LEFT JOIN {node_comment_statistics} c ON n.nid = c.nid WHERE n.status = 1 AND ((GREATEST(n.changed, c.last_comment_timestamp) = %d AND n.nid > %d) OR (n.changed > %d OR c.last_comment_timestamp > %d)) ORDER BY GREATEST(n.changed, c.last_comment_timestamp) ASC, n.nid ASC', $last, $last_nid, $last, $last, $last, 0, $limit); + $result = db_query_range('SELECT n.last_activity, n.nid FROM {node} n WHERE n.status = 1 AND ((n.last_activity = %d AND n.nid > %d) OR n.last_activity > %d) ORDER BY n.last_activity ASC, n.nid ASC', $last, $last_nid, $last, 0, $limit); while ($node = db_fetch_object($result)) { $last_change = $node->last_change; @@ -2696,6 +2698,79 @@ function node_form_alter(&$form, $form_s } /** + * Update the latest activity timestamp and uid for a node. + * + * @param $node + * The node object which is being updated. + * @param $uid + * The uid whose activity is either being recorded or removed. + */ +function node_update_activity(&$node, $uid) { + $last_activity_uid = $node->uid; + $last_activity = max($node->changed, $node->created); + $activity_count = 0; + + // Determine the lastest activity's $timestamp and $uid + $activities = module_invoke_all('node_activity', $node); + foreach($activities as $activity) { + if ($activity && $activity['timestamp'] > $last_activity) { + $last_activity = $activity['timestamp']; + $last_activity_uid = $activity['uid']; + $activity_count += $activity['count']; + } + } + + // Update the $node activity record + if ($last_activity != $node->last_activity || $last_activity_uid != $node->last_activity_uid || $activity_count != $node->activity_count) { + db_query('UPDATE {node} SET last_activity = %d, last_activity_uid = %d, activity_count = %d WHERE nid = %d', $last_activity, $last_activity_uid, $activity_count, $node->nid); + $node->last_activity = $last_activity; + $node->last_activity_uid = $last_activity_uid; + $node->activity_count = $activity_count; + } + + // Determine if the given $uid has performed activity on $node + $participation_possibilities = module_invoke_all('user_activity', $node, $uid); + $participant = ($uid == $node->uid); + + if (!$participant) { + foreach ($participation_possibilities as $participation_possibility) { + if ($participation_possibility) { + $participant = TRUE; + break; + } + } + } + + // Update the participation record + db_query('DELETE FROM {node_user_activity} WHERE nid = %d AND uid = %d', $node->nid, $uid); + if ($participant) { + db_query('INSERT INTO {node_user_activity} (nid, uid, last_activity) VALUES (%d, %d, %d)', $node->nid, $uid, $timestamp); + } + db_query('UPDATE {node_user_activity} SET last_activity = %d WHERE nid = %d', $timestamp, $node->nid); + + // Notify other modules that the node has an updated activity record + module_invoke_all('node_activity_updated', $node); +} + +/** + * Get number of new activites (like comments) for current user and specified node + * + * @param $nid to count activities for + */ +function node_activity_num_new($nid) { + global $user; + + $seen = db_result(db_query('SELECT activity_count FROM {node_user_view} WHERE nid = %d AND uid = %d', $nid, $user->uid)); + $total = db_result(db_query('SELECT activity_count FROM {node} WHERE nid = %d', $nid)); + + if ($total - $seen > 0) { + return $total - $seen; + } + + return 0; +} + +/** * Form API callback for the search form. Registered in node_form_alter(). */ function node_search_validate($form, &$form_state) { @@ -3149,7 +3224,6 @@ function node_content_form($node, $form_ '#title' => check_plain($type->title_label), '#required' => TRUE, '#default_value' => $node->title, - '#maxlength' => 255, '#weight' => -5, ); } Index: modules/node/node.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/node/node.schema,v retrieving revision 1.4 diff -u -p -r1.4 node.schema --- modules/node/node.schema 3 Jul 2007 19:42:14 -0000 1.4 +++ modules/node/node.schema 5 Aug 2007 14:05:05 -0000 @@ -1,5 +1,5 @@ array('type' => 'int', 'unsigned' => TRUE, 'not null' => FALSE, 'default' => 0), 'type' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, 'default' => ''), 'language' => array('type' => 'varchar', 'length' => 12, 'not null' => TRUE, 'default' => ''), - 'title' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'title' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''), 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 'status' => array('type' => 'int', 'not null' => TRUE, 'default' => 1), 'created' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), @@ -19,6 +19,12 @@ function node_schema() { 'sticky' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), 'tnid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), 'translate' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'last_activity' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'last_activity_uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), + 'activity_count' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'view_count' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'big'), + 'view_count_today' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'medium'), + 'last_view' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), ), 'indexes' => array( 'nid' => array('nid'), @@ -29,10 +35,14 @@ function node_schema() { 'node_status_type' => array('status', 'type', 'nid'), 'node_title_type' => array('title', array('type', 4)), 'node_type' => array(array('type', 4)), - 'status' => array('status'), 'uid' => array('uid'), 'tnid' => array('tnid'), 'translate' => array('translate'), + 'tracker' => array('status', 'last_activity'), + 'tracker_uid' => array('status', 'uid', 'last_activity'), + 'view_count' => array('status', 'view_count'), + 'view_count_today' => array('status', 'view_count_today'), + 'last_view' => array('status', 'last_view'), ), 'unique keys' => array( 'nid_vid' => array('nid', 'vid'), @@ -57,22 +67,12 @@ function node_schema() { ), ); - $schema['node_counter'] = array( - 'fields' => array( - 'nid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'totalcount' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'big'), - 'daycount' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0, 'size' => 'medium'), - 'timestamp' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0) - ), - 'primary key' => array('nid'), - ); - $schema['node_revisions'] = array( 'fields' => array( 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), 'vid' => array('type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE), 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'title' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), + 'title' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, 'default' => ''), 'body' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'), 'teaser' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'), 'log' => array('type' => 'text', 'not null' => TRUE, 'size' => 'big'), @@ -105,7 +105,29 @@ function node_schema() { ), 'primary key' => array('type'), ); - + + $schema['node_user_activity'] = array( + 'fields' => array( + 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'last_activity' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + ); + 'primary key' => array('nid', 'uid'), + 'indexes' => array( + 'user_tracker' => array('uid', 'last_activity'), + ), + ); + + $schema['node_user_view'] = array( + 'fields' => array( + 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + 'timestamp' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0) + 'activity_count' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0), + ), + 'primary key' => array('uid', 'nid'), + ); + return $schema; } Index: modules/search/search.module =================================================================== RCS file: /cvs/drupal/drupal/modules/search/search.module,v retrieving revision 1.229 diff -u -p -r1.229 search.module --- modules/search/search.module 8 Jul 2007 12:18:02 -0000 1.229 +++ modules/search/search.module 5 Aug 2007 14:05:07 -0000 @@ -849,7 +849,7 @@ function _search_parse_query(&$word, &$s * * @param $join2 * (optional) Inserted into the JOIN par of the second SQL query. - * For example "INNER JOIN {node_comment_statistics} n ON n.nid = i.sid" + * For example "INNER JOIN {node} n ON n.nid = i.sid". * * @param $arguments2 * (optional) Extra SQL arguments belonging to the second query parameter. Index: modules/statistics/statistics.module =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.module,v retrieving revision 1.263 diff -u -p -r1.263 statistics.module --- modules/statistics/statistics.module 3 Jul 2007 20:10:50 -0000 1.263 +++ modules/statistics/statistics.module 5 Aug 2007 14:05:08 -0000 @@ -58,12 +58,7 @@ function statistics_exit() { // We are counting content views. if ((arg(0) == 'node') && is_numeric(arg(1)) && arg(2) == '') { // A node has been viewed, so update the node's counters. - db_query('UPDATE {node_counter} SET daycount = daycount + 1, totalcount = totalcount + 1, timestamp = %d WHERE nid = %d', time(), arg(1)); - // If we affected 0 rows, this is the first time viewing the node. - if (!db_affected_rows()) { - // We must create a new row to store counters for the new node. - db_query('INSERT INTO {node_counter} (nid, daycount, totalcount, timestamp) VALUES (%d, 1, 1, %d)', arg(1), time()); - } + db_query('UPDATE {node} SET view_count_today = view_count_today + 1, view_count = view_count + 1, last_view = %d WHERE nid = %d', time(), arg(1)); } } if ((variable_get('statistics_enable_access_log', 0)) && (module_invoke('throttle', 'status') == 0)) { @@ -89,7 +84,7 @@ function statistics_link($type, $node = if ($type != 'comment' && user_access('view post access counter')) { $statistics = statistics_get($node->nid); if ($statistics) { - $links['statistics_counter']['title'] = format_plural($statistics['totalcount'], '1 read', '@count reads'); + $links['statistics_counter']['title'] = format_plural($statistics['view_count'], '1 read', '@count reads'); } } @@ -442,7 +437,7 @@ function statistics_cron() { if ((time() - $statistics_timestamp) >= 86400) { /* reset day counts */ - db_query('UPDATE {node_counter} SET daycount = 0'); + db_query('UPDATE {node} SET view_count_today = 0'); variable_set('statistics_day_timestamp', time()); } @@ -455,8 +450,8 @@ function statistics_cron() { * * @param $dbfield * one of - * - 'totalcount': top viewed content of all time. - * - 'daycount': top viewed content for today. + * - 'view_count': top viewed content of all time. + * - 'view_count_today': top viewed content for today. * - 'timestamp': last viewed node. * * @param $dbrows @@ -467,7 +462,7 @@ function statistics_cron() { * or FALSE if the query could not be executed correctly. */ function statistics_title_list($dbfield, $dbrows) { - return db_query_range(db_rewrite_sql("SELECT n.nid, n.title, u.uid, u.name FROM {node} n INNER JOIN {node_counter} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE %s <> '0' AND n.status = 1 ORDER BY %s DESC"), 's.'. $dbfield, 's.'. $dbfield, 0, $dbrows); + return db_query_range(db_rewrite_sql("SELECT n.nid, n.title, u.uid, u.name FROM {node} n INNER JOIN {node} s ON n.nid = s.nid INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 ORDER BY %s DESC"), 's.'. $dbfield, 0, $dbrows); } @@ -478,17 +473,17 @@ function statistics_title_list($dbfield, * node ID * * @return - * An array with three entries: [0]=totalcount, [1]=daycount, [2]=timestamp - * - totalcount: count of the total number of times that node has been viewed. - * - daycount: count of the total number of times that node has been viewed "today". - * For the daycount to be reset, cron must be enabled. + * An array with three entries: [0]=view_count, [1]=view_count_today, [2]=timestamp + * - view_count: count of the total number of times that node has been viewed. + * - view_count_today: count of the total number of times that node has been viewed "today". + * For the view_count_today to be reset, cron must be enabled. * - timestamp: timestamp of when that node was last viewed. */ function statistics_get($nid) { if ($nid > 0) { - /* retrieves an array with both totalcount and daycount */ - $statistics = db_fetch_array(db_query('SELECT totalcount, daycount, timestamp FROM {node_counter} WHERE nid = %d', $nid)); + /* retrieves an array with both view_count and view_count_today */ + $statistics = db_fetch_array(db_query('SELECT view_count, view_count_today, last_view FROM {node} WHERE nid = %d', $nid)); } return $statistics; @@ -525,17 +520,17 @@ function statistics_block($op = 'list', $content = array(); $daytop = variable_get('statistics_block_top_day_num', 0); - if ($daytop && ($result = statistics_title_list('daycount', $daytop)) && db_num_rows($result)) { + if ($daytop && ($result = statistics_title_list('view_count_today', $daytop)) && db_num_rows($result)) { $content[] = node_title_list($result, t("Today's:")); } $alltimetop = variable_get('statistics_block_top_all_num', 0); - if ($alltimetop && ($result = statistics_title_list('totalcount', $alltimetop)) && db_num_rows($result)) { + if ($alltimetop && ($result = statistics_title_list('view_count', $alltimetop)) && db_num_rows($result)) { $content[] = node_title_list($result, t('All time:')); } $lasttop = variable_get('statistics_block_top_last_num', 0); - if ($lasttop && ($result = statistics_title_list('timestamp', $lasttop)) && db_num_rows($result)) { + if ($lasttop && ($result = statistics_title_list('last_view', $lasttop)) && db_num_rows($result)) { $content[] = node_title_list($result, t('Last viewed:')); } @@ -572,7 +567,7 @@ function statistics_nodeapi(&$node, $op, switch ($op) { case 'delete': // clean up statistics table when node is deleted - db_query('DELETE FROM {node_counter} WHERE nid = %d', $node->nid); + db_query('DELETE FROM {node} WHERE nid = %d', $node->nid); } } Index: modules/statistics/statistics.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/statistics/statistics.schema,v retrieving revision 1.1 diff -u -p -r1.1 statistics.schema --- modules/statistics/statistics.schema 25 May 2007 12:46:45 -0000 1.1 +++ modules/statistics/statistics.schema 5 Aug 2007 14:05:08 -0000 @@ -20,4 +20,3 @@ function statistics_schema() { return $schema; } - Index: modules/system/system.schema =================================================================== RCS file: /cvs/drupal/drupal/modules/system/system.schema,v retrieving revision 1.8 diff -u -p -r1.8 system.schema --- modules/system/system.schema 15 Jul 2007 10:09:21 -0000 1.8 +++ modules/system/system.schema 5 Aug 2007 14:05:08 -0000 @@ -59,14 +59,6 @@ function system_schema() { 'primary key' => array('fid'), ); - $schema['history'] = array( - 'fields' => array( - 'uid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'nid' => array('type' => 'int', 'not null' => TRUE, 'default' => 0), - 'timestamp' => array('type' => 'int', 'not null' => TRUE, 'default' => 0) - ), - 'primary key' => array('uid', 'nid'), - ); $schema['menu_router'] = array( 'fields' => array( 'path' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => ''), Index: modules/tracker/tracker.module =================================================================== RCS file: /cvs/drupal/drupal/modules/tracker/tracker.module,v retrieving revision 1.150 diff -u -p -r1.150 tracker.module --- modules/tracker/tracker.module 4 Jul 2007 10:54:26 -0000 1.150 +++ modules/tracker/tracker.module 5 Aug 2007 14:05:08 -0000 @@ -81,49 +81,53 @@ function tracker_page($uid = 0) { // Add CSS drupal_add_css(drupal_get_path('module', 'tracker') .'/tracker.css', 'module', 'all', FALSE); - // TODO: These queries are very expensive, see http://drupal.org/node/105639 if ($uid) { - $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d) ORDER BY last_updated DESC'; - $sql = db_rewrite_sql($sql); - $sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = %d OR c.status IS NULL) WHERE n.status = 1 AND (n.uid = %d OR c.uid = %d)'; + $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, n.last_activity, n.activity_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 AND n.last_activity_uid = %d ORDER BY last_activity DESC'; + $sql = str_replace('DISTINCT', '', db_rewrite_sql($sql)); + $sql_count = 'SELECT COUNT(*) FROM {node} n WHERE n.status = 1 AND n.last_activity_uid = %d'; $sql_count = db_rewrite_sql($sql_count); - $result = pager_query($sql, 25, 0, $sql_count, COMMENT_PUBLISHED, $uid, $uid); + $result = pager_query($sql, 25, 0, $sql_count, $uid); } else { - $sql = 'SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid WHERE n.status = 1 ORDER BY last_updated DESC'; - $sql = db_rewrite_sql($sql); - $sql_count = 'SELECT COUNT(n.nid) FROM {node} n WHERE n.status = 1'; + $sql = 'SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, n.last_activity, n.comment_count FROM {node} n INNER JOIN {users} u ON n.uid = u.uid WHERE n.status = 1 ORDER BY last_activity DESC'; + $sql = str_replace('DISTINCT', '', db_rewrite_sql($sql)); + $sql_count = 'SELECT COUNT(*) FROM {node} n WHERE n.status = 1'; $sql_count = db_rewrite_sql($sql_count); $result = pager_query($sql, 25, 0, $sql_count); } $rows = array(); + $last_nid = 0; while ($node = db_fetch_object($result)) { - // Determine the number of comments: - $comments = 0; - if ($node->comment_count) { - $comments = $node->comment_count; - - if ($new = comment_num_new($node->nid)) { - $comments .= '
'; - $comments .= l(format_plural($new, '1 new', '@count new'), "node/$node->nid", array('fragment' => 'new')); + // Skip duplicates + if ($node->nid != $last_nid) { + // Determine the number of comments: + $activities = 0; + if ($node->activity_count) { + $activities = $node->activity_count; + + if ($new = comment_num_new($node->nid)) { + $comments .= '
'; + $comments .= l(format_plural($new, '1 new', '@count new'), 'node/' . $node->nid, array('fragment' => 'new')); + } } + + $rows[] = array( + node_get_types('name', $node->type), + l($node->title, 'node/' . $node->nid) .' '. theme('mark', node_mark($node->nid, $node->changed)), + theme('username', $node), + array('class' => 'replies', 'data' => $comments), + t('!time ago', array('!time' => format_interval(time() - $node->last_activity))) + ); + $last_nid = $node->nid; } - - $rows[] = array( - node_get_types('name', $node->type), - l($node->title, "node/$node->nid") .' '. theme('mark', node_mark($node->nid, $node->changed)), - theme('username', $node), - array('class' => 'replies', 'data' => $comments), - t('!time ago', array('!time' => format_interval(time() - $node->last_updated))) - ); } if (!$rows) { $rows[] = array(array('data' => t('No posts available.'), 'colspan' => '5')); } - $header = array(t('Type'), t('Post'), t('Author'), t('Replies'), t('Last updated')); + $header = array(t('Type'), t('Post'), t('Author'), t('Replies'), t('Last activity')); $output = '
'; $output .= theme('table', $header, $rows);