? _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 19:37:02 -0000 @@ -43,11 +43,168 @@ '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 to add a join to {project_usage_week_project} for each week. + // + $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', 'M j'), '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)); + + // 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 starting')); + $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', 'F j')) + $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); + + return theme('table', $header, $rows); +} + +/** + * 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; + } + + drupal_set_title(check_plain($node->title)); + + $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), $row->count); + } + + return theme('table', $header, $rows); +} + +/** * Module settings form. */ function project_usage_settings_form() {