'admin/settings/download_count', 'description' => t('Increments a download counter and logs a descriptive message each time an attached file is downloaded.'), 'title' => t('Download count'), 'callback' => 'drupal_get_form', 'callback arguments' => 'download_count_admin_settings', 'type' => MENU_NORMAL_ITEM); $items[] = array('path' => 'download_counter', 'title' => t('Download counter'), 'callback' => 'download_count_view_page', 'access' => $access, 'type' => MENU_NORMAL_ITEM); } return $items; } function download_count_admin_settings() { switch (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC)) { case FILE_DOWNLOADS_PUBLIC: $output = '

' . t('You are using public download. Set your download method to private on the ') . l('admin/settings', 'admin/settings') . t(' page (go in "File system"), if you wish for Drupal to keep a record of downloaded files.') . '

'; break; case FILE_DOWNLOADS_PRIVATE: $output = '

' . t('You are using the private download method, hence you have the correct setting to allow this module to keep a record of downloaded files.') . '

'; break; } $form['info on download method'] = array( '#value' => $output, ); $form['ignoring a set of file extensions'] = array( '#type' => 'fieldset', '#title' => t('Ignoring certain file extensions'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['ignoring a set of file extensions']['download_count_excluded_file_extensions'] = array( '#type' => 'textfield', '#title' => t('Excluded file extensions'), '#default_value' => variable_get('download_count_excluded_file_extensions', 'jpg jpeg gif png'), '#maxlength' => 255, '#description' => t('This module only considers files that have been uploaded with the upload module and that become file attachments. However, if you are using a contributed module to upload images and display them in the body of nodes, these files may get flagged as downloaded whenever a visitor or robot views the node page, because strictly speaking they are file attachments. This will happen with the module img_assist. Note that this won\'t happen with the module imce, because imce treats inline images as nodes. If you do not want to set a download counter for image files, list their extension here. Separate extensions with a space and do not include the leading dot. For example, you could list these extensions : jpg jpeg gif png. If you do not want to exclude any file, leave that field blank. ') ); $form['dounload count in nodes'] = array( '#type' => 'fieldset', '#title' => t('Download count in nodes'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['dounload count in nodes']['do_not_show_download_count_in_node_for_admin'] = array( '#type' => 'checkbox', '#title' => t('Do not show download count in the node view for the administrator'), '#default_value' => variable_get('do_not_show_download_count_in_node_for_admin', FALSE), '#description' => t('Check this if you do not want to see the download count in the node view.'), ); $form['download counter page'] = array( '#type' => 'fieldset', '#title' => t('Download counter page'), '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['download counter page']['download_counter_view_page_title'] = array( '#type' => 'textfield', '#title' => t('Title'), '#default_value' => variable_get('download_counter_view_page_title', t('Download counter')), '#description' => t('Title of this ') . l('page', 'download_counter') . '.', ); $form['download counter page']['download_counter_view_page_header'] = array( '#type' => 'textarea', '#title' => t('Header'), '#cols' => 60, '#rows' => 6, '#default_value' => variable_get('download_counter_view_page_header', t('')), '#description' => t('Text to appear between the title of the page and the download counter table.'), ); $form['download counter page']['download_counter_view_page_format'] = filter_form(variable_get('download_counter_view_page_format', 2), 0, array('download_counter_view_page_format')); $form['download counter page']['download_counter_view_page_footer'] = array( '#type' => 'textarea', '#title' => t('Footer'), '#cols' => 60, '#rows' => 6, '#default_value' => variable_get('download_counter_view_page_footer', t('')), '#description' => t('Text to appear underneath the download counter table.'), ); $form['info_on_access control'] = array( '#value' => '

' . t('Visit the ') . l('control access page', 'admin/user/access') . ' to allow roles to view download count in nodes and on the download counter page.

', ); return system_settings_form($form); } function download_count_view_page() { global $user; drupal_set_title(variable_get('download_counter_view_page_title', t('Download counter'))); $header[] = array('data' => t('filename'), 'field' => 'filename'); $header[] = array('data' => t('hits'), 'field' => 'count', 'sort' => 'desc'); $header[] = array('data' => t('last download'), 'field' => 'timestamp'); $header[] = array('data' => t('user'), 'field' => 'uid'); $header[] = array('data' => t('IP address'), 'field' => 'timestamp'); $header[] = array('data' => t('action')); $rows = array(); if(user_access('view all downloads count')) { $result = db_query("SELECT fd.filename, fd.count, fd.timestamp, fd.uid, fd.hostname, f.nid, n.type FROM {file_downloads} fd JOIN {files} f ON fd.filename = f.filename JOIN {node} n ON n.nid = f.nid" . tablesort_sql($header)); } else { $result = db_query("SELECT fd.filename, fd.count, fd.timestamp, fd.uid, fd.hostname, f.nid, n.type FROM {file_downloads} fd JOIN {files} f ON fd.filename = f.filename JOIN {node} n ON n.nid = f.nid WHERE n.uid = %d" . tablesort_sql($header), $user->uid); } while ($file = db_fetch_object($result)) { $row = array(); $row[] = $file->filename; $row[] = $file->count; $row[] = format_interval(time() - $file->timestamp) . ' ago'; $user = user_load(array(uid=>$file->uid)); $row[] = l($user->name, 'user/'.$user->uid); $row[] = $file->hostname; $row[] = l(t('view ' . $file->type), 'node/' . $file->nid); $rows[] = $row; } if (empty($rows)) { $rows[] = array(array('data' => t('No file attachment has been downloaded.'), 'colspan' => '3')); } $output = check_markup(variable_get('download_counter_view_page_header', ''), variable_get('download_counter_view_page_format', 0), false); $output .= theme('table', $header, $rows, array('class' => 'download_count')); $output .= check_markup(variable_get('download_counter_view_page_footer', ''), variable_get('download_counter_view_page_format', 0), false); return $output; } /** * Implementation of file_download() */ function download_count_file_download($filename) { global $user; $extensions = explode(' ', trim(variable_get('download_count_excluded_file_extensions', ''))); if (count($extensions)) { if (in_array(substr($filename, strpos($filename, '.') + 1), $extensions)) { return; } } $file = file_create_path($filename); $result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $file); if ($file = db_fetch_object($result)) { if (user_access('view uploaded files') && node_access('view', node_load($file->nid))) { $message = t('%file was downloaded', array('%file' => $filename)); watchdog('download', $message, WATCHDOG_NOTICE); // If the file is already added, just increment the count, // otherwise add the file with count 1 if(db_result(db_query("SELECT filename FROM {file_downloads} WHERE filename = '%s' AND uid = '$user->uid'", $filename))) { db_query("UPDATE {file_downloads} SET count = count+1, timestamp = %d WHERE filename = '%s' AND uid = '$user->uid'", time(), $filename); } else { db_query("INSERT INTO {file_downloads} (filename, count, timestamp, uid, hostname) VALUES ('%s', 1,%d, '$user->uid', '$user->hostname')", $filename, time()); } } else { $message = t('Failed to download %file', array('%file' => $filename)); watchdog('download', $message, WATCHDOG_WARNING); } } } /** * Implementation of hook_nodeapi() */ function download_count_nodeapi(&$node, $op) { if ($op == 'alter') { global $user; if ($user->uid == 1 && variable_get('do_not_show_download_count_in_node_for_admin', FALSE)) { return; } if (!$node->teaser && count($node->files)) { if (user_access('view all downloads count in nodes') || (user_access('view own nodes downloads count in nodes') && ($node->uid == $user->uid)) ) { $node->body = theme('download_count_body', $node); } } } } function theme_download_count_body($node) { $header[] = array('data' => t('Attachment')); $header[] = array('data' => t('Size')); $header[] = array('data' => t('Hits')); $header[] = array('data' => t('Last download')); $rows = array(); foreach ($node->files as $file) { if ($file->list) { $href = $file->fid ? file_create_url($file->filepath) : url(file_create_filename($file->filename, file_create_path())); $text = $file->description ? $file->description : $file->filename; $pick = db_query("SELECT filename, count, timestamp FROM {file_downloads} WHERE filename = '%s'", $file->filename); if ($attach = db_fetch_object($pick)){ $count = $attach->count; $last = format_interval(time() - $attach->timestamp) . ' ago'; } else { $count = 0; $last = t('Not yet downloaded'); } if (user_access('view uploaded files')) { $rows[] = array(l($text, $href), format_size($file->filesize), $count, $last); } else { $rows[] = array($file->filename, format_size($file->filesize), $count, $last); } } } if (count($rows)) { $attachments = theme('table', $header, $rows, array('id' => 'attachments')); } else { $attachments = ''; } if (strstr($node->body, 'body, '
body, '
', $start); return substr_replace($node->body, '', $start, $end - $start + 8) . $attachments; } else { return $node->body . $attachments; } }