? _project.inc_
? _project.module_
? release/history
? usage/test.patch
Index: usage/project_usage.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/project/usage/project_usage.module,v
retrieving revision 1.4
diff -u -r1.4 project_usage.module
--- usage/project_usage.module	14 Aug 2007 00:51:53 -0000	1.4
+++ usage/project_usage.module	14 Aug 2007 22:09:45 -0000
@@ -29,6 +29,10 @@
 // Number of seconds in a year.
 define('PROJECT_USAGE_YEAR', PROJECT_USAGE_DAY * 365);
 
+// Date format for month and day.
+define('PROJECT_USAGE_DATE_SHORT', 'M j');
+define('PROJECT_USAGE_DATE_LONG', 'F jS');
+
 /**
  * Implementation of hook_menu().
  */
@@ -43,11 +47,195 @@
       'description' => t('Configure how long usage data is retained.'),
       'weight' => 1,
     );
+    $items[] = array(
+      'path' => 'project_usage',
+      'title' => t('Project usage'),
+      'callback' => 'project_usage_overview',
+      'access' => user_access('view project usage'),
+    );
+    $items[] = array(
+      'path' => 'project_usage/project',
+      'title' => t('Project usage'),
+      'callback' => 'project_usage_project_page',
+    );
+    $items[] = array(
+      'path' => 'project_usage/release',
+      'title' => t('Relase usage'),
+      'callback' => 'project_usage_release_page',
+    );
   }
   return $items;
 }
 
 /**
+ * Implementation of hook_help().
+ */
+function project_usage_help($section) {
+  switch ($section) {
+    case 'project_usage':
+      return t('The following is a summary of the the usage information for the projects on this site. The count is the total number of sites using any version of the project. Only sites that have opted to allow usage information to be tracked are included.');
+
+    case 'project_usage/project':
+      return t('The following is the usage counts for each API version of the project. Only sites that have opted to allow usage information to be tracked are included.');
+      
+    case 'project_usage/release':
+      return t('The following is the usage counts for each project release. Only sites that have opted to allow usage information to be tracked are included.');
+      
+    case 'admin/modules#description':
+      return t('Collects and processes usage information about projects and releases.');
+  }
+} 
+
+/**
+ * Implementation of hook_perm().
+ */
+function project_usage_perm() {
+  $perms = array(
+    'view project usage',
+  );
+  return $perms;
+}
+
+/**
+ * Display and overview of usage for all modules.
+ */
+function project_usage_overview() {
+  drupal_set_title(t('Project usage overview'));
+
+  $week_count = 6;
+  $weeks = project_usage_get_weeks_since(time() - ($week_count * PROJECT_USAGE_WEEK));
+
+  // Ignore the current week, since we won't have usage data for that and
+  // reverse the order so it's newest to oldest.
+  array_pop($weeks);
+  $weeks = array_reverse($weeks);
+
+  // Query builder join a copy of {project_usage_week_project} for each week
+  // to the {node} table.
+  $header = array(array('data' => t('Project'), 'field' => 'title', 'sort' => 'asc'));  
+  $fields = array('n.nid', 'n.title');
+  $joins = array();
+  foreach ($weeks as $i => $week) {
+    $header[] = array('data' => format_date($week, 'custom', PROJECT_USAGE_DATE_SHORT), 'field' => "week{$i}");
+    $fields[] = "p{$i}.count AS week{$i}";
+    $joins[] = "LEFT JOIN {project_usage_week_project} p{$i} ON n.nid = p{$i}.nid AND p{$i}.timestamp = $week"; 
+  }
+  $result = pager_query('SELECT '. implode(', ', $fields) .' FROM {node} n '
+    . implode(' ', $joins) .' WHERE n.nid IN (SELECT nid FROM {project_usage_week_project})'
+    . tablesort_sql($header), 30, 0); 
+
+  // Take the rows and cast any NULL week counts to zeros. 
+  while ($line = db_fetch_array($result)) {
+    $row = array(l($line['title'], 'project_usage/project/'. $line['nid']));
+    for ($i = 0; $i < $week_count; $i++) {
+      $row[] = (int) $line["week{$i}"];
+    }
+    $rows[] = $row;
+  }
+
+  return theme('table', $header, $rows) . theme('pager', NULL, 30, 0);
+}
+
+/**
+ * Display the usage history of a project node.
+ */
+function project_usage_project_page($nid = NULL) {
+  $node = node_load((int) $nid);
+  if (!$node->nid) {
+    drupal_not_found();
+    return;
+  }
+
+  drupal_set_title(check_plain($node->title));
+
+  // Build a table of the weekly usage data with a column for each API version.
+  $output .= '<h3>'. t('Weekly project usage') .'</h3>';
+
+  // Get an array of the weeks going back as far as we have data...
+  $oldest = db_result(db_query("SELECT MIN(timestamp) FROM {project_usage_week_project} WHERE nid = %d", $node->nid));
+  $weeks = project_usage_get_weeks_since($oldest);
+  // ...ignore the current week, since we won't have usage data for that and
+  // reverse the order so it's newest to oldest.
+  array_pop($weeks);
+  $weeks = array_reverse($weeks);
+
+  // The number of columns varies depending on how many different API versions
+  // are in use. Set up the header and a blank, template row, based on the
+  // number of distinct terms in use. 
+  $header = array(t('Week'));
+  $blank_row = array();
+  $result = db_query("SELECT DISTINCT td.tid, td.name FROM {project_usage_week_project} p INNER JOIN {term_data} td ON p.tid = td.tid WHERE p.nid = %d ORDER BY td.weight, td.name", $node->nid);
+  while ($row = db_fetch_object($result)) {
+    $header[$row->tid] = $row->name;
+    $blank_row[$row->tid] = 0;
+  }
+
+  // Now create a blank table with a row for each week and formatted date in
+  // the first column...
+  $rows = array();
+  foreach ($weeks as $week) {
+    $rows[$week] = array(0 => format_date($week, 'custom', PROJECT_USAGE_DATE_LONG)) + $blank_row;
+  }
+  // ...then fill it in with our data.
+  $result = db_query("SELECT timestamp, tid, count FROM {project_usage_week_project} WHERE nid = %d", $node->nid);
+  while ($row = db_fetch_object($result)) {
+    $rows[$row->timestamp][$row->tid] = $row->count;
+  }
+  // Strip out the keys so that the odd/even row themeing works correctly.
+  $rows = array_values($rows);
+  $output .= theme('table', $header, $rows);
+
+
+
+  // Now build a table showing this week's usage for each release.
+  $output .= '<h3>'. t("Previous week's release usage") .'</h3>';
+
+  $header = array(t('Release'), t('Count'));
+  $rows = array();
+  $releases = project_release_get_releases($node, FALSE);
+  $result = db_query('SELECT n.nid, p.count FROM {node} n LEFT JOIN {project_usage_week_release} p ON n.nid = p.nid AND p.timestamp = %d WHERE n.nid IN ('. implode(',', array_keys($releases)) .') ORDER BY n.title DESC', $weeks[0]);
+  while ($line = db_fetch_array($result)) {
+    $rows[] = array(
+      l($releases[$line['nid']], 'project_usage/release/'. $line['nid']),
+      (int) $line['count'],
+    );
+  } 
+  $output .= theme('table', $header, $rows, array(), $caption);
+
+  return $output;
+}
+
+/**
+ * Display the usage history of a release node.
+ */
+function project_usage_release_page($nid = NULL) {
+  $node = node_load((int) $nid);
+  if (!$node->nid) {
+    drupal_not_found();
+    return;
+  }
+
+  // Setup the menu so we're beneath the project.
+  $project = node_load($node->pid);
+  $breadcrumb = array(
+    array('path' => 'project_usage'),
+    array('path' => 'project_usage/project/'. $project->nid, 'title' => check_plain($project->title) ),
+    array('path' => 'project_usage/release/'. $node->nid, 'title' => check_plain($node->title)),
+  );
+  menu_set_location($breadcrumb);
+
+  // Table displaying the usage back through time.
+  $header = array(t('Week starting'), t('Count'));
+  $rows = array();
+  $query = db_query("SELECT timestamp, count FROM {project_usage_week_release} WHERE nid = %d ORDER BY timestamp DESC", $node->nid);
+  while ($row = db_fetch_object($query)) {
+    $rows[] = array(format_date($row->timestamp, 'custom', PROJECT_USAGE_DATE_LONG), $row->count);
+  }
+
+  return theme('table', $header, $rows);
+}
+
+/**
  * Module settings form.
  */
 function project_usage_settings_form() {
