? .tracker2.install.swp
? .tracker2.module.swp
? .tracker2.test.swp
? tracker2_port_d6.patch
Index: tracker2.info
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tracker2/tracker2.info,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 tracker2.info
--- tracker2.info	2 Jun 2008 04:20:12 -0000	1.1.2.1
+++ tracker2.info	3 Jan 2009 19:47:09 -0000
@@ -1,4 +1,5 @@
 ; $Id: tracker2.info,v 1.1.2.1 2008/06/02 04:20:12 straussd Exp $
 name = Tracker 2
 description = Enables tracking of recent posts for users.
-dependencies = comment
+dependencies[] = comment
+core = 6.x
Index: tracker2.install
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tracker2/tracker2.install,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 tracker2.install
--- tracker2.install	2 Jun 2008 04:20:12 -0000	1.1.2.1
+++ tracker2.install	3 Jan 2009 19:47:09 -0000
@@ -2,71 +2,24 @@
 
 // $Id: tracker2.install,v 1.1.2.1 2008/06/02 04:20:12 straussd Exp $
 
-function tracker2_install() {
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      db_query("CREATE TABLE IF NOT EXISTS {tracker2_node} (
-        nid int(10) unsigned NOT NULL,
-        published tinyint(1) NOT NULL,
-        changed int(10) unsigned NOT NULL,
-        PRIMARY KEY  (nid),
-        KEY tracker (published,changed)
-      )");
-        
-      db_query("CREATE TABLE IF NOT EXISTS {tracker2_user} (
-        nid int(10) unsigned NOT NULL,
-        published tinyint(1) NOT NULL,
-        uid int(10) unsigned NOT NULL,
-        changed int(10) unsigned NOT NULL,
-        PRIMARY KEY  (nid,uid),
-        KEY tracker (uid,published,changed)
-      )");
-    
-      db_query('ALTER TABLE {comments} ADD INDEX tracker_changed (nid, status, timestamp)');
-      db_query('ALTER TABLE {comments} ADD INDEX tracker_subscription (uid, nid, status)');
-      break;
-    case 'pgsql':
-      db_query("CREATE TABLE {tracker2_node} (
-        nid int_unsigned NOT NULL,
-        published smallint NOT NULL,
-        changed int_unsigned NOT NULL,
-        PRIMARY KEY  (nid)
-      )");
-      db_query('CREATE INDEX {tracker2_node}_tracker_idx ON {tracker2_node} (published, changed)');
-    
-      db_query("CREATE TABLE {tracker2_user} (
-        nid int_unsigned NOT NULL,
-        published smallint NOT NULL,
-        uid int_unsigned NOT NULL,
-        changed int_unsigned NOT NULL,
-        PRIMARY KEY  (nid, uid)
-      )");
-      db_query('CREATE INDEX {tracker2_user}_tracker_idx ON {tracker2_user} (uid, published, changed)');
+  
+/**
+ * @file
+ * The (un)install and update code for the tracker2 module.
+ *
+ * @ingroup tracker2
+ */
 
-      db_query('CREATE INDEX {comments}_tracker_changed_idx ON {comments} (nid, status, timestamp)');
-      db_query('CREATE INDEX {comments}_tracker_subscription_idx ON {comments} (uid, nid, status)');
-      break;
-  }
+function tracker2_install() {
+  drupal_install_schema('tracker2');
+  tracker2_update_6001();
 }
 
 function tracker2_uninstall() {
-  switch ($GLOBALS['db_type']) {
-    case 'mysql':
-    case 'mysqli':
-      db_query('DROP TABLE IF EXISTS {tracker2_node}');
-      db_query('DROP TABLE IF EXISTS {tracker2_user}');
-      db_query('ALTER TABLE {comments} DROP INDEX tracker_changed');
-      db_query('ALTER TABLE {comments} DROP INDEX tracker_subscription');
-      break;
-    case 'pgsql':
-      db_query('DROP TABLE {tracker2_node}');
-      db_query('DROP TABLE {tracker2_user}');
-      db_query('DROP INDEX {comments}_tracker_changed_idx');
-      db_query('DROP INDEX {comments}_tracker_subscription_idx');
-      break;
-  }
+  drupal_uninstall_schema('tracker2');
   variable_del('tracker2_index_nid');
+  db_drop_index($ret, 'comments', 'tracker_changed');
+  db_drop_index($ret, 'comments', 'tracker_subscription');
 }
 
 function tracker2_enable() {
@@ -75,10 +28,72 @@ function tracker2_enable() {
   drupal_set_message(t('Tracker will index from node %nid downward.', array('%nid' => $max_nid)));
 }
 
-function tracker2_update_1() {
+function tracker2_update_6001() {
   $ret = array();
-  $ret[] = update_sql('ALTER TABLE {comments} DROP INDEX tracker');
-  $ret[] = update_sql('ALTER TABLE {comments} ADD INDEX tracker_changed (nid, status, timestamp)');
-  $ret[] = update_sql('ALTER TABLE {comments} ADD INDEX tracker_subscription (uid, nid, status)');
+  db_add_index($ret, 'comments', 'tracker_changed', array('nid', 'status', 'timestamp'));
+  db_add_index($ret, 'comments', 'tracker_subscription', array('uid', 'nid', 'status'));
   return $ret;
 }
+
+function tracker2_schema() {
+  $schema['tracker2_node'] = array(
+    'description' => 'Track changes to content',
+    'fields' => array(
+      'nid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => "{node}.nid",
+      ),
+      'published' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'description' => "True if {node}.status == 1",
+      ),
+      'changed' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => "{node}.changed",
+      ),
+    ),
+    'primary key' => array('nid'),
+    'indexes' => array(
+      'tracker' => array('published', 'changed'),
+    ),
+  );
+  $schema['tracker2_user'] = array(
+    'fields' => array(
+      'nid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => "{node}.nid"
+      ),
+     'uid' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => "{user}.uid",
+      ),
+      'published' => array(
+        'type' => 'int',
+        'size' => 'tiny',
+        'not null' => TRUE,
+        'description' => "True if {node}.status == 1",
+      ),
+      'changed' => array(
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+        'description' => "{node}.changed",
+      ),
+    ),
+    'primary key' => array('nid', 'uid'),
+    'indexes' => array(
+      'tracker' => array('uid', 'published', 'changed'),
+    ),
+  );
+  return $schema;
+}
Index: tracker2.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/tracker2/tracker2.module,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 tracker2.module
--- tracker2.module	2 Jun 2008 04:20:12 -0000	1.1.2.1
+++ tracker2.module	3 Jan 2009 19:47:10 -0000
@@ -1,12 +1,26 @@
 <?php
-
 // $Id: tracker2.module,v 1.1.2.1 2008/06/02 04:20:12 straussd Exp $
 
 /**
+ * @file
+ * Enables tracking of recent posts for users.
+ */
+
+/**
+ * Implementation of hook_help().
+ */
+function tracker2_help($path, $arg) {
+  switch ($path) {
+    case 'admin/help#tracker2':
+      $output = '<p>'. t('The Tracker2 module is a much more efficient tracker that maintains seperate database tables of updated items.') .'</p>';
+      return $output;
+  }
+}
+
+/**
  * Implementation of hook_menu().
  */
-function tracker2_menu($may_cache) {
-  global $user;
+function tracker2_menu() {
   $items = array();
 
   $base = 'tracker2';
@@ -16,58 +30,64 @@ function tracker2_menu($may_cache) {
     $user_base = 'track';
   }
 
-  if ($may_cache) {
-    $items[] = array(
-      'path' => $base,
-      'title' => t('Recent posts'),
-      'callback' => 'tracker2_page',
-      'access' => user_access('access content'),
-      'weight' => 1,
-    );
+  $items[$base] = array(
+    'title' => 'Recent posts',
+    'page callback' => 'tracker2_page',
+    'access arguments' => array('access content'),
+    'weight' => 1,
+  );
 
-    if ($user->uid) {
-      $items[] = array(
-        'path' => $base . '/all',
-        'title' => t('All recent posts'),
-        'type' => MENU_DEFAULT_LOCAL_TASK,
-      );
-      $items[] = array(
-        'path' => $base . '/'. $user->uid,
-        'title' => t('My recent posts'),
-        'type' => MENU_LOCAL_TASK,
-      );
-    }
-    
-    $items[] = array(
-      'path' => 'admin/settings/tracker2',
-      'title' => 'Tracker 2',
-      'description' => t('High-performance reimplementation of the Tracker module.'),
-      'callback' => 'drupal_get_form',
-      'access' => user_access('administer tracker'),
-      'callback arguments' => array('tracker2_admin_settings')
-    );
-  }
-  else {
-    if (arg(0) == 'user' && is_numeric(arg(1))) {
-      $items[] = array(
-        'path' => 'user/'. arg(1) .'/' . $user_base,
-        'title' => t('Track'),
-        'callback' => 'tracker2_track_user',
-        'access' => user_access('access content'),
-        'type' => MENU_IS_LOCAL_TASK
-      );
-      $items[] = array(
-        'path' => 'user/'. arg(1) .'/' . $user_base . '/posts',
-        'title' => t('Track posts'),
-        'type' => MENU_DEFAULT_LOCAL_TASK,
-      );
-    }
-  }
+  $items[$base .'/all'] = array(
+    'title' => 'All recent posts',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
+  $items[$base .'/%user_uid_optional'] = array(
+    'title' => 'My recent posts',
+    'access callback' => '_tracker2_myrecent_access',
+    'access arguments' => array(1),
+    'page arguments' => array(1),
+    'type' => MENU_LOCAL_TASK,
+  );
+
+  $items['admin/settings/tracker2'] = array(
+    'title' => 'Tracker 2',
+    'description' => 'High-performance reimplementation of the Tracker module.',
+    'page callback' => 'drupal_get_form',
+    'access arguments' => array('administer tracker'),
+    'page arguments' => array('tracker2_admin_settings')
+  );
+
+  $items['user/%user/'. $user_base] = array(
+    'title' => 'Track',
+    'page callback' => 'tracker2_track_user',
+    'access arguments' => array('access content'),
+    'type' => MENU_LOCAL_TASK,
+  );
+  $items['user/%user/'. $user_base .'/posts'] = array(
+    'title' => 'Track posts',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+  );
 
   return $items;
 }
 
 /**
+ * Access callback for tracker/%user_uid_optional
+ */
+function _tracker2_myrecent_access($account) {
+  // This path is only allowed for authenticated users looking at their own posts.
+  return $account->uid && ($GLOBALS['user']->uid == $account->uid) && user_access('access content');
+}
+
+/**
+ * Access callback for user/%user/track
+ */
+function _tracker2_user_access($account) {
+  return user_view_access($account) && user_access('access content');
+}
+
+
+/**
  * Implementation of hook_perm().
  */
 function tracker2_perm() {
@@ -79,20 +99,22 @@ function tracker2_perm() {
  */
 function tracker2_admin_settings() {
   $form = array();
-  
+
   $max_nid = variable_get('tracker2_index_nid', 0);
-  
+
   if ($max_nid) {
     $form['max_nid'] = array(
+      '#type' => 'value',
       '#value' => t('Max node ID for indexing on the next cron run: @max', array('@max' => $max_nid)),
     );
   }
   else {
     $form['max_nid'] = array(
+      '#type' => 'value',
       '#value' => t('Existing nodes have finished tracker indexing.'),
     );
   }
-  
+
   $form['tracker2_batch_size'] = array(
     '#title' => t('Batch size'),
     '#description' => t('Number of nodes to index during each cron run.'),
@@ -113,43 +135,43 @@ function tracker2_cron() {
   if ($max_nid > 0) {
     $last_nid = FALSE;
     $res = db_query_range('SELECT nid, uid, status FROM {node} WHERE nid <= %d ORDER BY nid DESC', $max_nid, 0, $batch_size);
-    
+
     $count = 0;
-    
+
     while ($row = db_fetch_object($res)) {
       //echo 'Indexing node ' . $row->nid . '<br />';
-      
+
       // Calculate the changed timestamp for this node.
       $changed = _tracker2_calculate_changed($row->nid);
-      
+
       // Remove existing data for this node.
       db_query('DELETE FROM {tracker2_node} WHERE nid = %d', $row->nid);
       db_query('DELETE FROM {tracker2_user} WHERE nid = %d', $row->nid);
-      
+
       // Insert the node-level data.
       db_query('INSERT INTO {tracker2_node} (nid, published, changed) VALUES (%d, %d, %d)', $row->nid, $row->status, $changed);
-      
+
       // Insert the user-level data for the node's author.
       db_query('INSERT INTO {tracker2_user} (nid, published, uid, changed) VALUES (%d, %d, %d, %d)', $row->nid, $row->status, $row->uid, $changed);
-      
+
       // Insert the user-level data for the commenters (except if a commenter is the node's author).
       db_query('INSERT INTO {tracker2_user} (nid, published, uid, changed) SELECT DISTINCT %d AS nid, %d AS published, uid, %d AS changed FROM {comments} WHERE nid = %d AND uid <> %d AND status = %d', $row->nid, $row->status, $changed, $row->nid, $row->uid, COMMENT_PUBLISHED);
 
       // Note that we have indexed at least one node.
       $last_nid = $row->nid;
-      
+
       ++$count;
     }
-    
+
     if ($last_nid !== FALSE) {
       // Prepare a starting point for the next run
       variable_set('tracker2_index_nid', $last_nid - 1);
-      
-      watchdog('tracker2', t('Indexed %count nodes for tracking.', array('%count' => $count)));
+
+      watchdog('tracker2', 'Indexed %count nodes for tracking.', array('%count' => $count));
     }
     else {
       // If all nodes have been indexed, set to zero to skip future cron runs
-      variable_set('tracker2_index_nid', 0);    
+      variable_set('tracker2_index_nid', 0);
     }
   }
 }
@@ -157,18 +179,17 @@ function tracker2_cron() {
 /**
  * Implementation of hook_form_alter().
  */
-function tracker2_form_alter($form_id, &$form) {
+function tracker2_form_alter(&$form, $form_state, $form_id) {
   if ($form_id == 'node_admin_nodes') {
-    $form['#submit']['tracker2_batch_node_alter'] = array();
+    $form['#submit'][] = 'tracker2_batch_node_alter';
   }
 }
 
-function tracker2_batch_node_alter($form_id, $form_values) {
-  //drupal_set_message('<pre>' . print_r($form_values, TRUE) . '</pre>');
+function tracker2_batch_node_alter($form, &$form_state) {
 
-  $op = $form_values['operation'];
-  foreach($form_values['nodes'] as $nid => $selected) {
-    if ($selected) {      
+  $op = $form_state['values']['operation'];
+  foreach ($form_values['nodes'] as $nid => $selected) {
+    if ($selected) {
       if ($op == 'publish') {
         db_query('UPDATE {tracker2_node} SET published = 1 WHERE nid = %d', $nid);
         db_query('UPDATE {tracker2_user} SET published = 1 WHERE nid = %d', $nid);
@@ -198,7 +219,7 @@ function _tracker2_add($nid, $uid, $chan
   else {
     db_query('INSERT INTO {tracker2_node} (changed, published, nid) VALUES (%d, %d, %d)', $changed, $node->status, $nid);
   }
-  
+
   // Create or update the user-level data
   db_query('UPDATE {tracker2_user} SET changed = %d, published = %d WHERE nid = %d', $changed, $node->status, $nid);
   $exists = db_result(db_query('SELECT COUNT(*) FROM {tracker2_user} WHERE nid = %d AND uid = %d', $nid, $uid));
@@ -223,11 +244,11 @@ function _tracker2_remove($nid, $uid = N
   // (1) The node exists.
   // (2) The user is either the node author or has commented on the node.
   $keep_subscription = FALSE;
-  
+
   if ($node) {
     // Self-authorship is one reason to keep the user's subscription.
     $keep_subscription = ($node->uid == $uid);
-    
+
     // Comments are a second reason to keep the user's subscription.
     if (!$keep_subscription) {
       // Check if the user has commented at least once on the given nid
@@ -238,18 +259,18 @@ function _tracker2_remove($nid, $uid = N
     if (!$keep_subscription) {
       db_query('DELETE FROM {tracker2_user} WHERE nid = %d AND uid = %d', $nid, $uid);
     }
-      
+
     // Now we need to update the (possibly) changed timestamps for other users and the node itself.
-    
+
     // We only need to do this if the removed item has a timestamp that equals
     // or exceeds the listed changed timestamp for the node
     $tracker_node = db_fetch_object(db_query('SELECT nid, changed FROM {tracker2_node} WHERE nid = %d', $nid));
     if ($tracker_node && $changed >= $tracker_node->changed) {
       // If we're here, the item being removed is *possibly* the item that established the node's changed timestamp.
-      
+
       // We just have to recalculate things from scratch.
       $changed = _tracker2_calculate_changed($nid);
-      
+
       // And then we push the out the new changed timestamp to our denormalized tables.
       db_query('UPDATE {tracker2_node} SET changed = %d, published = %d WHERE nid = %d', $changed, $node->status, $nid);
       db_query('UPDATE {tracker2_user} SET changed = %d, published = %d WHERE nid = %d', $changed, $node->status, $nid);
@@ -265,7 +286,7 @@ function _tracker2_remove($nid, $uid = N
 /**
  * Implementation of hook_nodeapi().
  */
-function tracker2_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
+function tracker2_nodeapi(&$node, $op) {
   if ($op == 'insert' || $op == 'update') {
     _tracker2_add($node->nid, $node->uid, $node->changed);
   }
@@ -278,7 +299,7 @@ function tracker2_nodeapi(&$node, $op, $
  * Implementation of hook_comment().
  */
 function tracker2_comment($a1, $op) {
-  //drupal_set_message($op . '<pre>' . print_r($a1, TRUE) . '</pre>');  
+  //drupal_set_message($op . '<pre>' . print_r($a1, TRUE) . '</pre>');
   $comment = (array) $a1;
   if ($op == 'insert' || $op == 'update' || $op == 'publish') {
     if ($comment['status'] == COMMENT_PUBLISHED) {
@@ -323,13 +344,16 @@ function tracker2_page($uid = 0) {
 
   if (!empty($nodes)) {
     // Now, get the data and put into the placeholder array
-    $placeholders = implode(',', array_fill(0, count($nodes), '%d'));
-    $result = db_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, 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 WHERE n.nid IN ($placeholders)", array_keys($nodes));
+    $placeholders = array_fill(0, count($nodes), '%d');
+
+    $result = db_query("SELECT n.nid, n.title, n.type, n.changed, n.uid, u.name, 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 
+      WHERE n.nid IN (". implode(',', $placeholders) .")", array_keys($nodes));
     while ($node = db_fetch_object($result)) {
       $node->last_activity = $nodes[$node->nid]->last_activity;
       $nodes[$node->nid] = $node;
     }
-  
+
     // Finally display the data
     $rows = array();
     foreach ($nodes as $node) {
@@ -337,13 +361,13 @@ function tracker2_page($uid = 0) {
       $comments = 0;
       if ($node->comment_count) {
         $comments = $node->comment_count;
-  
+
         if ($new = comment_num_new($node->nid)) {
           $comments .= '<br />';
           $comments .= l(format_plural($new, '1 new', '@count new'), 'node/'. $node->nid, NULL, NULL, 'new');
         }
       }
-  
+
       $rows[] = array(
         check_plain(node_get_types('name', $node->type)),
         l($node->title, "node/$node->nid") .' '. theme('mark', node_mark($node->nid, $node->changed)),
@@ -384,4 +408,4 @@ function tracker2_track_user() {
   else {
     drupal_not_found();
   }
-}
\ No newline at end of file
+}
Index: tracker2.test
===================================================================
RCS file: tracker2.test
diff -N tracker2.test
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tracker2.test	3 Jan 2009 19:47:10 -0000
@@ -0,0 +1,45 @@
+<?php
+// $Id$
+
+class Tracker2TestCase extends DrupalWebTestCase {
+  function getInfo() {
+    return array(
+      'name' => t('Tracker 2'),
+      'description' => t('tests the tracker2 module'),
+      'group' => t('tracker2'),
+    );
+  }
+
+  function setUp() {
+    parent::setUp('tracker2');
+  }
+
+  function testTracker2TrackUser() {
+    $base = 'tracker2';
+    $user_base = 'track2';
+    if (!module_exists('tracker')) {
+      $base = 'tracker';
+      $user_base = 'track';
+    }
+
+    // call tracker2_track_user -> there is not arg(1)
+    $this->drupalGet('user');
+    tracker2_track_user();
+    $this->assertResponse(404, t('take sure that the function returns 404, if there is no arg(1)'));
+
+    // create user
+    $web_user_1 = $this->drupalCreateUser();
+    $web_user_2 = $this->drupalCreateUser();
+    $web_user_1->status = 0;
+    user_save($web_user_1);
+    $admin_user = $this->drupalCreateUser(array('administer users'));
+
+    $this->drupalLogin($web_user_2);
+    $this->drupalGet('user/'. $web_user_1->uid .'/'. $user_base);
+    $this->assertResponse(403, t('take sure that it is pot possible to look at users with status 0 for normal users'));
+
+    $this->drupalLogin($admin_user);
+    $this->drupalGet('user/'. $web_user_1->uid .'/'. $user_base);
+    $this->assertTitle(check_plain($web_user_1->name), t('take sure that the title is set right'));
+  }
+}
