Index: modules/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload.module,v
retrieving revision 1.31.2.6
diff -u -F^f -r1.31.2.6 upload.module
--- modules/upload.module 17 Aug 2005 20:03:29 -0000 1.31.2.6
+++ modules/upload.module 19 Aug 2005 12:34:10 -0000
@@ -15,6 +15,8 @@ function upload_help($section) {
return t('Allows users to upload and attach files to content.');
case 'admin/settings/upload':
return t('
Users with the upload files permission can upload attachments. You can choose which post types can take attachments on the content types settings page.
', array('%permissions' => url('admin/access'), '%types' => url('admin/node/configure/types')));
+ case 'admin/uploads':
+ return t('Users with the administer uploaded files permission can administer uploaded files.
', array('%permissions' => url('admin/access')));
}
}
@@ -22,7 +24,7 @@ function upload_help($section) {
* Implementation of hook_perm().
*/
function upload_perm() {
- return array('upload files', 'view uploaded files');
+ return array('upload files', 'view uploaded files', 'administer uploaded files');
}
/**
@@ -48,6 +50,108 @@ function upload_link($type, $node = 0, $
}
/**
+ * Return statistics about uploads
+ *
+ * @param $user
+ * A UID to return statistics for. If no UIDs are supplied, only generic statistical information for all
+ * UIDs will be returned.
+ *
+ * @return
+ * Themed statistical information.
+**/
+function upload_statistics($uid = NULL) {
+ $user_stats = array();
+ $total_size = 0;
+ $total_num = 0;
+
+ // no UID passed
+ if ($uid == NULL) {
+ $result = db_query("SELECT f.filesize, u.uid, u.name FROM {files} f INNER JOIN {node} n ON f.nid = n.nid INNER JOIN {users} u ON u.uid = n.uid");
+ while ($file = db_fetch_object($result)) {
+ if ($user_stats[$file->uid]['name'] == NULL) {
+ $user_stats[$file->uid]['name'] = $file->name;
+ }
+ if ($user_stats[$file->uid]['uid'] == NULL) {
+ $user_stats[$file->uid]['uid'] = $file->uid;
+ }
+ $user_stats[$file->uid]['total'] += $file->filesize;
+
+ $total_size += $file->filesize;
+ $total_num++;
+ }
+
+ array_multisort($user_stats, SORT_DESC, SORT_NUMERIC);
+
+ // only show up to 10 results
+ $tot = (10 < sizeof($user_stats)) ? 10 : sizeof($user_stats);
+
+ $items = array();
+ $items[] = 'Total disk space used: '. format_size($total_size) .'
';
+ $content = theme('item_list', $items);
+ $output = theme('box', 'Statistics', $content);
+
+ if ($tot) {
+ $content = '';
+ for ($i = 0; $i < $tot; $i++) {
+ $format_user->name = $user_stats[$i]['name'];
+ $format_user->uid = $user_stats[$i]['uid'];
+
+ $content .= ' - '. format_size($user_stats[$i]['total']) .' used by '. theme('username', $format_user) .'
';
+ }
+ $content .= '
';
+ }
+ else {
+ $content = 'No users have uploaded files.
';
+ }
+ $output .= theme('box', 'Top 10 disk space users', $content);
+ }
+ else {
+ $result = db_query("SELECT f.filesize, u.name FROM {files} f INNER JOIN {node} n ON f.nid = n.nid INNER JOIN {users} u ON u.uid = n.uid WHERE u.uid = %d", $uid);
+ while ($file = db_fetch_object($result)) {
+ if ($name == NULL) {
+ $name = $file->name;
+ }
+ $total_size += $file->filesize;
+ $total_num++;
+ }
+
+ $result = db_query("SELECT rid FROM {users_roles} WHERE uid = %d", $uid);
+ while ($roles = db_fetch_object($result)) {
+ $rid = $roles->rid;
+ $temp_array = explode(' ', variable_get("upload_extensions_$rid", 'jpg jpeg gif png txt html doc xls pdf ppt pps'));
+ $temp_array = array_flip($temp_array);
+ $extensions = array_merge($extensions, $temp_array);
+
+ $uploadsize = variable_get("upload_uploadsize_$rid", 1) * 1024 * 1024;
+ $max_one_size = ($uploadsize > $max_one_size) ? $uploadsize : $max_one_size;
+ $usersize = variable_get("upload_usersize_$rid", 1) * 1024 * 1024;
+ $max_all_size = ($usersize > $max_all_size) ? $usersize : $max_all_size;
+ }
+
+ // prepare information
+ $extensions = array_flip($extensions);
+ $percent = ($max_all_size) ? ' ('. sprintf("%.2f", ($total_size / $max_all_size) * 100) .'%)' : '';
+ $max_one_size = ($max_one_size) ? ($max_one_size) : 'unlimited';
+ $max_all_size = ($max_all_size) ? (format_size($max_all_size)) : 'unlimited';
+
+ $items = array();
+ $items[] = 'Allowed file extensions: '. implode(' ', $extensions) .'
';
+ $items[] .= 'Maximum size of each file: '. format_size($max_one_size) .'
';
+ $items[] .= 'Maximum size of all files: '. $max_all_size .'
';
+ $content = theme('item_list', $items);
+ $output = theme('box', 'Allowances', $content);
+
+ $items = array();
+ $items[] = 'Total files: '. $total_num .'
';
+ $items[] .= 'Disk usage: '. format_size($total_size) .' of '. $max_all_size . $percent .'
';
+ $content = theme('item_list', $items);
+ $output .= theme('box', 'Statistics', $content);
+ }
+
+ return $output;
+}
+
+/**
* Implementation of hook_menu().
*/
function upload_menu($may_cache) {
@@ -56,10 +160,16 @@ function upload_menu($may_cache) {
if ($may_cache) {
$items[] = array(
'path' => 'admin/settings/upload', 'title' => t('uploads'),
+ 'callback' => 'upload_settings',
+ 'access' => user_access('administer uploaded files'));
+ $items[] = array(
+ 'path' => 'upload', 'title' => t('my uploads'),
+ 'callback' => 'upload_page',
+ 'access' => user_access('upload files'));
+ $items[] = array(
+ 'path' => 'admin/upload', 'title' => t('uploads'),
'callback' => 'upload_admin',
- 'access' => user_access('administer site configuration'),
- 'type' => MENU_NORMAL_ITEM
- );
+ 'access' => user_access('administer uploaded files'));
}
else {
// Add handlers for previewing new uploads.
@@ -80,7 +190,211 @@ function upload_menu($may_cache) {
return $items;
}
+/*
+ * Menu callback:
+ * Page where admins manage uploaded files
+ */
function upload_admin() {
+
+ $operations = array(
+ 'delete' => array(t('Delete the selected files'), '')
+ );
+
+ // Handle operations
+ $op = $_POST['op'];
+ $edit = $_POST['edit'];
+
+ if (($op == t('Update') || $op == t('Delete all')) && isset($edit['operation']) && isset($edit['files'])) {
+ $edit['files'] = array_diff($edit['files'], array(0));
+ if (count($edit['files']) == 0) {
+ form_set_error('', t('Please select some items to perform the update on.'));
+ }
+ else {
+ if ($edit['operation'] == 'delete') {
+ // Mass delete
+ if ($edit['confirm']) {
+ upload_delete('files', $edit['files']);
+ drupal_set_message(t('The items have been deleted.'));
+ }
+ else {
+ $extra = '';
+ foreach ($edit['files'] as $fid => $value) {
+ if ($value) {
+ $title = db_result(db_query('SELECT filename FROM {files} WHERE fid = %d', $fid));
+ $extra .= '- '. form_hidden('files]['. $fid, 1) . check_plain($title) .'
';
+ }
+ }
+ $extra .= '
';
+ $extra .= form_hidden('operation', 'delete');
+
+ $output = theme('confirm',
+ t('Are you sure you want to delete these items?'),
+ 'admin/upload',
+ t('This action cannot be undone.'),
+ t('Delete all'),
+ t('Cancel'),
+ $extra);
+ print theme('page', $output);
+ return;
+ }
+ }
+ }
+ }
+
+ $output .= upload_statistics();
+
+ $header = array(
+ NULL,
+ array('data' => t('Filename'), 'field' => 'filename'),
+ array('data' => t('Title'), 'field' => 'title'),
+ array('data' => t('Author'), 'field' => 'name'),
+ array('data' => t('Size'), 'field' => 'filesize', 'sort' => 'desc')
+ );
+
+ $sql = "SELECT f.fid, n.nid, n.status, n.title, f.filename, f.filepath, f.filesize, n.uid, u.name FROM {files} f INNER JOIN {node} n ON f.nid = n.nid INNER JOIN {users} u ON u.uid = n.uid";
+ $sql .= tablesort_sql($header);
+ $result = pager_query($sql, 50);
+
+ // Make sure the update controls are disabled if we don't have any rows
+ // to select from.
+ $disabled = !db_num_rows($result);
+
+ $options = array();
+ foreach ($operations as $key => $value) {
+ $options[$key] = $value[0];
+ }
+
+ $form = form_select(NULL, 'operation', 0, $options, NULL, ($disabled ? 'disabled="disabled"' : ''));
+ $form .= form_submit(t('Update'), 'op', ($disabled ? array('disabled' => 'disabled') : array()));
+
+ $output .= form_group(t('Update options'), "$form
");
+
+ $destination = drupal_get_destination();
+ while ($file = db_fetch_object($result)) {
+ $format_user->name = $file->name;
+ $format_user->uid = $file->uid;
+
+ $rows[] = array(
+ form_checkbox(NULL, 'files]['. $file->fid, 1, 0),
+ l($file->filename, file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path())))),
+ ($file->status) ? l($file->title, "node/$file->nid") : $file->title,
+ theme('username', $format_user),
+ format_size($file->filesize)
+ );
+ }
+
+ if ($pager = theme('pager', NULL, 50, 0, tablesort_pager())) {
+ $rows[] = array(array('data' => $pager, 'colspan' => '5'));
+ }
+
+ if (!$rows) {
+ $rows[] = array(array('data' => t('No uploaded files available.'), 'colspan' => '5'));
+ }
+ $output .= theme('table', $header, $rows);
+ print theme('page', form($output, 'post', url('admin/upload')));
+}
+
+/*
+ * Menu callback:
+ * Page where users manage their uploaded files
+ */
+function upload_page() {
+ global $user;
+
+ $operations = array(
+ 'delete' => array(t('Delete the selected files'), '')
+ );
+
+ // Handle operations
+ $op = $_POST['op'];
+ $edit = $_POST['edit'];
+
+ if (($op == t('Update') || $op == t('Delete all')) && isset($edit['operation']) && isset($edit['files'])) {
+ $edit['files'] = array_diff($edit['files'], array(0));
+ if (count($edit['files']) == 0) {
+ form_set_error('', t('Please select some items to perform the update on.'));
+ }
+ else {
+ if ($edit['operation'] == 'delete') {
+ // Mass delete
+ if ($edit['confirm']) {
+ upload_delete('files', $edit['files']);
+ drupal_set_message(t('The items have been deleted.'));
+ }
+ else {
+ $extra = '';
+ foreach ($edit['files'] as $fid => $value) {
+ if ($value) {
+ $title = db_result(db_query('SELECT filename FROM {files} WHERE fid = %d', $fid));
+ $extra .= '- '. form_hidden('files]['. $fid, 1) . check_plain($title) .'
';
+ }
+ }
+ $extra .= '
';
+ $extra .= form_hidden('operation', 'delete');
+
+ $output = theme('confirm',
+ t('Are you sure you want to delete these items?'),
+ 'upload',
+ t('This action cannot be undone.'),
+ t('Delete all'),
+ t('Cancel'),
+ $extra);
+ print theme('page', $output);
+ return;
+ }
+ }
+ }
+ }
+
+ $output .= upload_statistics($user->uid);
+
+ $header = array(
+ NULL,
+ array('data' => t('Filename'), 'field' => 'filename'),
+ array('data' => t('Title'), 'field' => 'title'),
+ array('data' => t('Size'), 'field' => 'filesize', 'sort' => 'desc')
+ );
+
+ $sql = "SELECT f.fid, n.nid, n.status, n.title, f.filename, f.filepath, f.filesize, n.uid FROM {files} f INNER JOIN {node} n ON f.nid = n.nid WHERE n.uid = %d";
+ $sql .= tablesort_sql($header);
+ $result = pager_query($sql, 50, 0, NULL, $user->uid);
+
+ // Make sure the update controls are disabled if we don't have any rows
+ // to select from.
+ $disabled = !db_num_rows($result);
+
+ $options = array();
+ foreach ($operations as $key => $value) {
+ $options[$key] = $value[0];
+ }
+
+ $form = form_select(NULL, 'operation', 0, $options, NULL, ($disabled ? 'disabled="disabled"' : ''));
+ $form .= form_submit(t('Update'), 'op', ($disabled ? array('disabled' => 'disabled') : array()));
+
+ $output .= form_group(t('Update options'), "$form
");
+
+ $destination = drupal_get_destination();
+ while ($file = db_fetch_object($result)) {
+ $rows[] = array(
+ form_checkbox(NULL, 'files]['. $file->fid, 1, 0),
+ l($file->filename, file_create_url(($file->fid ? $file->filepath : file_create_filename($file->filename, file_create_path())))),
+ ($file->status) ? l($file->title, "node/$file->nid") : $file->title,
+ format_size($file->filesize)
+ );
+ }
+
+ if ($pager = theme('pager', NULL, 50, 0, tablesort_pager())) {
+ $rows[] = array(array('data' => $pager, 'colspan' => '4'));
+ }
+
+ if (!$rows) {
+ $rows[] = array(array('data' => t('No uploaded files available.'), 'colspan' => '4'));
+ }
+ $output .= theme('table', $header, $rows);
+ print theme('page', form($output, 'post', url('upload')));
+}
+
+function upload_settings() {
system_settings_save();
$group .= form_textfield(t('Maximum total file size'), 'upload_maxsize_total', variable_get('upload_maxsize_total', 0), 10, 10, t('The maximum size of a file a user can upload in megabytes. Enter 0 for unlimited.'));
@@ -138,6 +452,7 @@ function upload_nodeapi(&$node, $op, $ar
break;
case 'validate':
+
$node->files = upload_load($node);
// Double check existing files:
@@ -159,7 +474,8 @@ function upload_nodeapi(&$node, $op, $ar
}
}
- if (($file = file_check_upload('upload')) && user_access('upload files')) {
+ if ($file = file_check_upload('upload')) {
+ if (user_access('upload files')) {
global $user;
$file = _upload_image($file);
@@ -223,6 +539,7 @@ function upload_nodeapi(&$node, $op, $ar
$node->files[$key] = $file;
}
}
+ }
break;
case 'form post':
@@ -287,7 +604,7 @@ function upload_nodeapi(&$node, $op, $ar
break;
case 'delete':
- upload_delete($node);
+ upload_delete('node', $node);
break;
case 'search result':
return $node->files ? format_plural(count($node->files), '1 attachment', '%count attachments') : null;
@@ -341,8 +658,7 @@ function upload_save($node) {
else {
// Remove or update existing files:
if ($node->remove[$key]) {
- file_delete($file->filepath);
- db_query("DELETE FROM {files} WHERE fid = %d", $key);
+ upload_delete('files', array($file));
}
if ($file->list != $node->list[$key]) {
db_query("UPDATE {files} SET list = %d WHERE fid = %d", $node->list[$key], $key);
@@ -352,12 +668,25 @@ function upload_save($node) {
return;
}
-function upload_delete($node) {
- $node->files = upload_load($node);
- foreach ($node->files as $file) {
- file_delete($file->filepath);
+function upload_delete($op, $arg) {
+ switch($op) {
+ case 'node':
+ $node = $arg;
+ $node->files = upload_load($node);
+ foreach ($node->files as $file) {
+ file_delete($file->filepath);
+ }
+ db_query("DELETE FROM {files} WHERE nid = %d", $node->nid);
+ break;
+ case 'files':
+ foreach ($arg as $fid => $value) {
+ db_query("SELECT filepath FROM {files} WHERE fid = %d", $fid);
+ $file = db_fetch_object($result);
+ file_delete($file->filepath);
+ db_query("DELETE FROM {files} WHERE fid = %d", $fid);
+ }
+ break;
}
- db_query("DELETE FROM {files} WHERE nid = %d", $node->nid);
}
function upload_form($node) {