RELEASE_DOWNLOAD_PREFIX, 'title' => t('Project release download'), 'callback' => 'release_download_handler', 'access' => TRUE, 'type' => MENU_CALLBACK, ); // Download statistics pages if (module_exists('project_release')) { $admin_access = user_access('administer projects'); $access_projects = user_access('access projects'); // Project download stats (admin only): $items[] = array( 'path' => 'admin/project/downloads', 'title' => t('Project download statistics'), 'description' => t('View download statistics for projects and project releases.'), 'callback' => 'release_download_statistics_admin', 'access' => $admin_access, 'type' => MENU_NORMAL_ITEM, ); // Project download stats (all users): if (module_exists('project')) { $terms = taxonomy_get_tree(_project_get_vid()); foreach ($terms as $i => $term) { // Only use the first-level terms. if ($term->depth == 0) { $items[] = array( 'path' => 'project/' . $term->name . '/stats', 'title' => t('Statistics'), 'description' => t('View download statistics for projects and project releases.'), 'callback' => 'release_download_statistics', 'access' => $access_projects, 'type' => MENU_LOCAL_TASK, 'weight' => 15, ); } } } else { $items[] = array( 'path' => 'project/stats', 'title' => t('Project download statistics'), 'description' => t('View download statistics for projects and project releases.'), 'callback' => 'release_download_statistics', 'access' => $access_projects, 'type' => MENU_NORMAL_ITEM, ); } } } return $items; } function release_download_statistics_admin() { $header = array( array('data' => t('User'), 'field' => 'name'), array('data' => t('Project'), 'field' => 'project'), array('data' => t('Version'), 'field' => 'release_version'), array('data' => t('Hostname'), 'field' => 'hostname'), array('data' => t('Timestamp'), 'field' => 'timestamp', 'sort' => 'desc'), ); $sql = 'SELECT DISTINCT ird.uid AS uid, u.name AS name, prn.pid AS project, n.title AS project_name, ird.nid AS rid, prn.version AS release_version, ird.hostname AS hostname , ird.timestamp AS timestamp FROM {release_download} ird LEFT JOIN {project_release_nodes} prn ON ird.nid = prn.nid INNER JOIN {users} u ON u.uid = ird.uid INNER JOIN {node} n ON n.nid = ird.nid '. tablesort_sql($header); $result = pager_query($sql, 20, 0, 'SELECT DISTINCT COUNT(*) FROM {release_download}'); while ($download = db_fetch_object($result)) { if ($download->uid) { $user = user_load(array('uid' => $download->uid)); } $rows[] = array( $download->uid ? theme('username', $user) : variable_get('anonymous', 'Anonymous'), $download->project ? l($download->project_name, 'node/'. $download->project) : '', $download->release_version ? l($download->release_version, 'node/' . $download->rid) : '', $download->hostname, $download->timestamp ? format_date($download->timestamp) : '', ); } return theme('table', $header, $rows) . theme('pager', NULL, 20); } function release_download_statistics() { if (module_exists('project')) { project_project_set_breadcrumb(); } $header = array( array('data' => t('Project'), 'field' => 'title'), array('data' => t('Downloads'), 'field' => 'count', 'sort' => 'desc'), ); $order_by = tablesort_sql($header); $sql = release_download_most_downloaded_query($order_by); $result = pager_query($sql, 20, 0, 'SELECT DISTINCT COUNT(*) FROM {project_release_projects}'); while ($download = db_fetch_object($result)) { $rows[] = array( $download->title ? l($download->title, 'node/'. $download->nid) : '', $download->count, ); } return theme('table', $header, $rows) . theme('pager', NULL, 20); } /** * Copy of file_download() from file.inc */ function release_download_handler() { // Merge remainder of arguments from GET['q'], into relative file path. $args = func_get_args(); $filepath = implode('/', $args); // Maintain compatibility with old ?file=paths saved in node bodies. if (isset($_GET['file'])) { $filepath = $_GET['file']; } if (file_exists(file_create_path($filepath))) { $headers = release_download_file_download($filepath); if (in_array(-1, $headers)) { return drupal_access_denied(); } if (count($headers)) { file_transfer($filepath, $headers); } } return drupal_not_found(); } /** * Implementation of hook_file_download() * * Saves information about file download request to the database if the file * is part of a project release. */ function release_download_file_download($filename) { global $user; $filepath = file_create_path($filename); // Determine what release node this file is associated with if ($release = db_fetch_object(db_query("SELECT nid FROM {project_release_nodes} WHERE file_path = '%s'", $filepath))) { db_query("INSERT INTO {release_download} (nid, uid, timestamp, hostname) VALUES (%d, %d, %d, '%s')", $release->nid, $user->uid, time(), $_SERVER['REMOTE_ADDR']); // Strip file_directory_path from $path so that the downloaded file will // have the appropriate name. if ($pos = strrpos($filepath, '/')) { $filename = trim(substr($filepath, $pos), '\\/'); } return array( 'Content-Type: application/octet-stream', 'Content-Length: '. filesize($filepath), 'Content-Disposition: attachment; filename="'. mime_header_encode($filename) .'"', ); } } function release_download_get_prefix() { return RELEASE_DOWNLOAD_PREFIX; } /** * Implementation of hook_nodeapi() * * Queries database to get number of downloads for project_project nodes and * project_release nodes. */ function release_download_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { switch ($op) { case 'view': switch ($node->type) { case 'project_project': $result = db_query("SELECT DISTINCT count(ird.nid) as count, ird.nid FROM {release_download} ird INNER JOIN {project_release_nodes} prn ON ird.nid = prn.nid WHERE prn.pid = %d GROUP BY ird.nid", $node->nid); $counts = array(); while ($release = db_fetch_object($result)) { $counts["$release->nid"] = $release->count; } $node->release_download = array(); $node->release_download['num_downloads'] = array_sum($counts); $node->release_download['releases'] = $counts; $output = t('Downloaded !times', array('!times' => format_plural($node->release_download['num_downloads'], '1 time', '@count times'))) .'
'; $node->content['downloads'] = array( '#value' => $output, '#weight' => -7, ); break; case 'project_release': $node->release_download = array(); $node->release_download['num_downloads'] = db_result(db_query("SELECT count(nid) FROM {release_download} WHERE nid = %d", $node->nid)); $output = ''. t('Downloaded !times', array('!times' => format_plural($node->release_download['num_downloads'], '1 time', '@count times'))) .'
'; $node->content['downloads'] = array( '#value' => '
'. $output .'
', '#weight' => -3, ); break; } break; } } /** * implementation of hook_block */ function release_download_block($op = 'list', $delta = O, $edit = array()) { if ($op == 'view') { $num_to_display = variable_get('release_download_block_num', 5); $blocks['subject'] = variable_get('release_download_block_title', 'Most frequently downloaded'); if (($result = release_download_most_downloaded($num_to_display)) && db_num_rows($result)) { $blocks['content'] = theme('release_download_block_list',$result); } if ($blocks['content']) { if (module_exists('project_release') && user_access('access projects')) { $blocks['content'] .= ''; } } } elseif ($op == 'list') { $blocks[0]['info'] = t('Project release most downloaded'); } elseif ($op == 'configure') { $form['title'] = array( '#type' => 'textfield', '#title' => t('Block title'), '#default_value' => variable_get('release_download_block_title', 'Most frequently downloaded'), '#maxlength' => 64, '#description' => t('The title of the block as shown to the user.'), ); $form['num_to_display'] = array( '#type' => 'textfield', '#title' => t('Number of downloads to display'), '#default_value' => variable_get('release_download_block_num', 5), '#description' => t('Specify how many projects should be displayed in the block.'), ); return $form; } elseif ($op == 'save') { variable_set('release_download_block_title', $edit['title']); variable_set('release_download_block_num', $edit['num_to_display']); return; } return $blocks; } /** * Returns all time or today top or last viewed node(s). * * @param $dbrows * number of rows to be returned. * * @return * A query result containing n.nid, n.title of the most downloaded projects * or FALSE if the query could not be executed correctly. */ function release_download_most_downloaded($dbrows) { return db_query_range(release_download_most_downloaded_query('ORDER BY count DESC'), 0, $dbrows); } function release_download_most_downloaded_query($order_by = NULL) { return db_rewrite_sql("SELECT DISTINCT n.title AS title, n.nid AS nid, COUNT(ird.nid) AS count FROM {node} n LEFT JOIN {project_release_nodes} prn ON n.nid = prn.pid LEFT JOIN {release_download} ird ON ird.nid = prn.nid WHERE n.status = 1 AND n.type = 'project_project' GROUP BY n.nid $order_by"); } function theme_release_download_block_list($result) { while ($row = db_fetch_object($result)) { // Only include items that have at least one download in the list of downloads if ($row->count) { $items[] .= l(check_plain($row->title .' ('. $row->count .')'), 'node/'. $row->nid); } } return theme('node_list', $items); }