Index: modules/upload/upload.admin.inc
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.admin.inc,v
retrieving revision 1.10
diff -u -r1.10 upload.admin.inc
--- modules/upload/upload.admin.inc	16 Jul 2008 21:59:28 -0000	1.10
+++ modules/upload/upload.admin.inc	22 Aug 2008 22:22:12 -0000
@@ -150,3 +150,240 @@
 
   return system_settings_form($form);
 }
+
+/*
+ * Menu callback:
+ * Page where admins manage uploaded files
+ */
+function upload_admin_page($form_state) {
+  $items = array();
+  
+  if (!isset($form_state['storage']['state'])) {
+    $nodes_per_page = variable_get('default_nodes_main', 10);
+     
+    $operations = array(
+      'delete' => array(t('Delete the selected files'), '')
+    );
+  
+    // Make sure the update controls are disabled if we don't have any rows
+    // to select from.
+    $disabled = TRUE;
+    
+    $items['options'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Update options')
+    );
+  
+    $options = array();
+    foreach ($operations as $key => $value) {
+      $options[$key] = $value[0];
+      $disabled = FALSE;
+    }
+    
+    $items['options']['operation'] = array(
+      '#type' => 'select',
+      '#options' => $options,
+      '#disabled' => $disabled
+    );
+    
+    $items['options']['op'] = array(
+      '#value' => t('Update'),
+      '#type' => 'submit',
+      '#disabled' => $disabled
+    );
+  
+    $headers = array(
+	  array('data' => t('File name'), 'field' => 'f.filename'),
+	  array('data' => t('Owner'), 'field' => 'us.name', 'sort' => 'asc'),
+	  array('data' => t('Size'), 'field' => 'total_filesize')
+	);
+
+    $sql = '
+  SELECT f.*, u.description, SUM(fu.filesize) AS total_filesize
+  FROM {upload} u 
+  INNER JOIN {files} f ON f.fid = u.fid
+  INNER JOIN {users} us ON us.uid = f.uid
+  INNER JOIN {files} fu ON fu.uid = f.uid
+  GROUP BY fu.uid';
+    $sql .= tablesort_sql($headers);
+    $result = pager_query($sql, $nodes_per_page);
+    
+    $files_options = array();
+    while ($file = db_fetch_array($result)) {
+      $files_options[$file['fid']] = $file;
+    }
+    
+    $items['file_data'] = array(
+      '#type' => 'value',
+      '#value' => $files_options
+    );
+    
+    if (count($files_options)) {
+	    $items['files'] = array(
+	      '#type' => 'checkboxes',
+          '#options' => array_combine(array_keys($files_options), array_keys($files_options))
+	    );
+    }
+    
+  }
+  else {
+    $question = '';
+    switch ($form_state['storage']['operation']) {
+      case 'delete':
+        $question = t('Are you sure you wish to delete these files?');
+        break;
+    }
+    
+    $items = confirm_form($items, $question, 'admin/content/uploads');
+  }
+
+  return $items;
+}
+
+function upload_admin_page_validate($form, &$form_state) {
+  $are_files = FALSE;
+  if (!isset($form_state['storage']['state']) || !$form_state['storage']['state']) {
+    foreach ($form_state['values']['files'] as $fid => $enabled) {
+      if ($enabled) {
+        $are_files = TRUE;
+        break;
+      }
+    }
+	
+    if (!$are_files) {
+      form_set_error('files', t('Please select files to operate on'));
+    }
+  }
+}
+
+function upload_admin_page_submit($form, &$form_state) {
+
+  if (!isset($form_state['storage']['state'])) {
+    $form_state['storage']['state'] = true;
+    $form_state['storage']['files'] = $form_state['values']['files'];
+    $form_state['storage']['operation'] = $form_state['values']['operation'];
+  }
+  else {
+    
+    // Delete upload and detach from all revisions
+    db_query('DELETE FROM {upload} WHERE fid IN (' . db_placeholders($form_state['storage']['files'], 'int') . ')', $form_state['storage']['files']);
+
+    // If the file isn't used by any other revisions delete it.
+    $qry = db_query('SELECT fid, COUNT(fid) AS count FROM {upload} WHERE fid IN (' . db_placeholders($form_state['storage']['files'], 'int') . ') GROUP BY fid', $form_state['storage']['files']);
+    $files_to_delete = array();
+    while ($row = db_fetch_object($qry)) {
+      if ($row->count == 0) {
+        $filepath = db_result(db_query('SELECT filepath FROM {files} WHERE fid = %d', $row->fid));
+	      file_delete($filepath);
+	      $files_to_delete[] = $row->fid;
+	    }
+    }
+  
+    if (!empty($files_to_delete)) {
+      db_query('DELETE FROM {files} WHERE fid IN (' . db_placeholders($files_to_delete, 'int') . ')', $files_to_delete);
+    }
+    
+    switch ($form_state['storage']['operation']) {
+      case 'delete':
+        $message = t('Files successfully deleted');
+        break;
+    }
+    drupal_set_message($message);
+    
+    $form_state['storage'] = NULL;
+  }
+}
+
+function theme_upload_admin_page($form) {
+  $output = '';
+  
+  if (!empty($form['files']['#options'])) {
+    
+    $headers = array(
+	  array('data' => t('File name'), 'field' => 'f.filename'),
+	  array('data' => t('Owner'), 'field' => 'us.name', 'sort' => 'asc'),
+	  array('data' => t('Size'), 'field' => 'total_filesize')
+	);
+	
+    $rows = array();
+    foreach ($form['file_data']['#value'] as $fid => $info) {
+      unset($form['files'][$fid]['#title']);
+      $href = file_create_url($info['filepath']);
+      $rows[] = array(l($info['filename'], $href), 
+                      theme('username', user_load(array('uid' => $info['uid']))), 
+                      format_size($info['filesize']), 
+                      drupal_render($form['files'][$fid])
+      );
+    }
+    
+    $output .= theme('table', $headers, $rows);
+    
+    $nodes_per_page = variable_get('default_nodes_main', 10);
+    $output .= theme('pager', NULL, $nodes_per_page);
+  }
+  else {
+    $output .= '<p>' . t('No uploaded files available.') . '</p>';
+  }
+  
+  $output .= drupal_render($form);
+  
+  return $output;
+}
+
+/**
+ * Menu callback:
+ * Page listing disk space usage for each user
+ **/
+function upload_admin_usage_page() {
+  $header = array(
+    array('data' => t('Username'), 'field' => 'name'),
+    array('data' => t('Size'), 'field' => 'total_filesize', 'sort' => 'desc')
+  );
+  
+  $nodes_per_page = variable_get('default_nodes_main', 10);
+  
+  $sql = '
+  SELECT u.uid, u.name, SUM(f.filesize) AS total_filesize
+  FROM {users} u 
+  INNER JOIN {files} f ON f.uid = u.uid
+  WHERE u.uid > 0
+  GROUP BY f.uid';
+  $sql .= tablesort_sql($header);
+  $result = pager_query($sql, $nodes_per_page);
+
+  // Make sure the update controls are disabled if we don't have any rows
+  // to select from.
+  $disabled = TRUE;
+
+  $format_user = new StdClass();
+  while ($users = db_fetch_object($result)) {
+    $format_user->name = $users->name;
+    $format_user->uid = $users->uid;
+
+    $rows[] = array(
+      theme('username', $format_user),
+      format_size($users->total_filesize)
+    );
+    $disabled = FALSE;
+  }
+
+  if ($pager = theme('pager', NULL, $nodes_per_page)) {
+    $rows[] = array(array('data' => $pager, 'colspan' => '2'));
+  }
+
+  if (!$rows) {
+    $rows[] = array(array('data' => t('No users have uploaded files.'), 'colspan' => '2'));
+  }
+
+  $output = '';
+  
+  // Get statistics about files
+  $total_size = upload_total_space_used();
+  $output .= t('<p>Total disk space used: %size</p>', array('%size' => format_size($total_size)));
+
+  $output .= t('<p>If users aren\'t listed below, then they have no files uploaded to the site.</p>');
+
+  $output .= theme('table', $header, $rows);
+
+  return $output;
+}
Index: modules/upload/upload.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/upload/upload.module,v
retrieving revision 1.205
diff -u -r1.205 upload.module
--- modules/upload/upload.module	24 Jul 2008 16:25:19 -0000	1.205
+++ modules/upload/upload.module	22 Aug 2008 22:27:24 -0000
@@ -36,6 +36,9 @@
     'upload_form_new' => array(
       'arguments' => array('form' => NULL),
     ),
+    'upload_admin_page' => array(
+      'arguments' => array('form' => NULL),
+    ),
   );
 }
 
@@ -46,6 +49,7 @@
   return array(
     'upload files' => t('Attach images and other files to content.'),
     'view uploaded files' => t('View and download files attached to content.'),
+    'administer uploaded files' => t('Manage files attached to content.'),
   );
 }
 
@@ -93,6 +97,38 @@
     'access arguments' => array('administer site configuration'),
     'type' => MENU_NORMAL_ITEM,
   );
+  $items['admin/content/uploads'] = array(
+    'title' => 'Site uploads',
+    'description' => 'Manage uploads to the site',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('upload_admin_page'),
+    'access arguments' => array('administer uploaded files'),
+    'type' => MENU_NORMAL_ITEM,
+    'file' => 'upload.admin.inc',
+  );
+  $items['admin/content/uploads/confirm'] = array(
+    'title' => 'Site uploads',
+    'description' => 'Manage uploads to the site',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('upload_admin_page_confirm'),
+    'access arguments' => array('administer uploaded files'),
+    'type' => MENU_CALLBACK,
+    'file' => 'upload.admin.inc',
+  );
+  $items['admin/content/uploads/list'] = array(
+    'title' => 'Upload listing',
+    'access arguments' => array('administer uploaded files'),
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'file' => 'upload.admin.inc',
+    'weight' => -10
+  );
+  $items['admin/content/uploads/usage'] = array(
+    'title' => 'Disk space usage',
+    'page callback' => 'upload_admin_usage_page',
+    'access arguments' => array('administer uploaded files'),
+    'type' => MENU_LOCAL_TASK,
+    'file' => 'upload.admin.inc',
+  );
   return $items;
 }