Index: user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user.module,v
retrieving revision 1.559
diff -u -r1.559 user.module
--- user.module	13 Jan 2006 19:02:38 -0000	1.559
+++ user.module	15 Jan 2006 23:35:14 -0000
@@ -425,7 +425,7 @@
  * Implementation of hook_perm().
  */
 function user_perm() {
-  return array('administer access control', 'administer users', 'access user profiles', 'change own username');
+  return array('administer access control', 'administer users', 'access user profiles', 'change own username', 'delete own account', 'delete content with account(s)');
 }
 
 /**
@@ -666,6 +666,8 @@
   $access_access = user_access('administer access control');
   // users should always be allowed to see their own user page
   $view_access = (user_access('access user profiles') || ($user->uid == arg(1)));
+  // delete access is granted to user administrators and to users themselves if they have permission.
+  $delete_access = (user_access('administer users') || ($user->uid == arg(1) && user_access('delete own account')));
 
   if ($may_cache) {
     $items[] = array('path' => 'user', 'title' => t('user account'),
@@ -760,7 +762,7 @@
           'callback' => 'user_edit', 'access' => $admin_access || $user->uid == arg(1),
           'type' => MENU_LOCAL_TASK);
         $items[] = array('path' => 'user/'. arg(1) .'/delete', 'title' => t('delete'),
-          'callback' => 'user_edit', 'access' => $admin_access,
+          'callback' => 'user_edit_delete', 'access' => $delete_access,
           'type' => MENU_CALLBACK);
 
         if (arg(2) == 'edit') {
@@ -1257,22 +1259,7 @@
   $account = user_load(array('uid' => arg(1)));
   $edit = $_POST['op'] ? $_POST['edit'] : (array)$account;
 
-  if (arg(2) == 'delete') {
-    if ($edit['confirm']) {
-      db_query('DELETE FROM {users} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {sessions} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
-      db_query('DELETE FROM {authmap} WHERE uid = %d', $account->uid);
-      watchdog('user', t('Deleted user: %name %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', '<'. $account->mail .'>'))), WATCHDOG_NOTICE);
-      drupal_set_message(t('The account has been deleted.'));
-      module_invoke_all('user', 'delete', $edit, $account);
-      drupal_goto('admin/user');
-    }
-    else {
-      return confirm_form('user_confirm_delete', $form, t('Are you sure you want to delete the account %name?', array('%name' => theme('placeholder', $account->name))), 'user/'. $account->uid, t('Deleting a user will remove all their submissions as well. This action cannot be undone.'), t('Delete'));
-    }
-  }
-  else if ($_POST['op'] == t('Delete')) {
+  if ($_POST['op'] == t('Delete')) {
     if ($_REQUEST['destination']) {
       $destination = drupal_get_destination();
       unset($_REQUEST['destination']);
@@ -1285,7 +1272,7 @@
   $form['_category'] = array('#type' => 'value', '#value' => $category);
   $form['_account'] = array('#type' => 'value', '#value' => $account);
   $form['submit'] = array('#type' => 'submit', '#value' => t('Submit'), '#weight' => 30);
-  if (user_access('administer users')) {
+  if ((user_access('administer users') || (user_access('delete own account') && $user->uid == arg(1))) && $account->status != 2) {
     $form['delete'] = array('#type' => 'submit', '#value' => t('Delete'), '#weight' => 31);
   }
   $form['#attributes'] = array('enctype' => 'multipart/form-data');
@@ -1317,6 +1304,64 @@
   drupal_goto('user/'. $account->uid);
 }
 
+function user_edit_delete() {
+  global $user;
+  $account = user_load(array('uid' => arg(1)));
+  
+  if ($_POST['op'] == 'Confirm') {
+    $edit = $_POST['edit'];
+    if ($edit['content_delete_options']['delete_content']) {
+	  // Permanently delete all the content associated with a user.
+	  $query = db_query('SELECT nid FROM {node} WHERE uid = %d', $account->uid);
+	  while($node = db_fetch_object($query)) {
+        node_delete($node->nid);
+	  }
+      $query2 = db_query('SELECT c.* FROM {comments} c WHERE c.uid = %d ORDER BY c.cid DESC', $account->uid);
+	  // We delete comments backwards (most recent first) to avoid any thread problems with _comment_delete_thread().
+	  while($comment = db_fetch_object($query2)) {
+        _comment_delete_thread($comment);
+        _comment_update_node_statistics($comment->nid);
+        drupal_set_message(t('Comment: %subject has been deleted.', array('%subject' => theme('placeholder', $comment->subject))));
+	  }
+	  db_query('DELETE FROM {node_revisions} WHERE uid = %d', $account->uid);
+    }
+    if ($edit['user_delete_options'] == 'delete_username') {
+	  // Delete all user data and set any remaining posts to anonymous.
+      db_query('DELETE FROM {users} WHERE uid = %d', $account->uid);
+	  db_query('DELETE FROM {users_roles} WHERE uid = %d', $account->uid);
+	  db_query('DELETE FROM {authmap} WHERE uid = %d', $account->uid);
+	  db_query('UPDATE {node} SET uid = 0 WHERE uid = %d', $account->uid);
+	  db_query('UPDATE {comments} SET uid = 0 WHERE uid = %d', $account->uid);
+	  drupal_set_message(t('The user %name has been deleted.', array('%name' => theme('placeholder', $account->name))));
+	}
+	elseif ($edit['user_delete_options'] == 'delete_details') {
+	  //Delete any personal data stored for user and set status to Deleted.
+      db_query("UPDATE {users} SET status = 2, pass = '', mail = '', theme = '', timezone = '', language = '', picture = '', init = '' WHERE uid = %d", $account->uid);
+	  drupal_set_message(t('Details for %name have been deleted but the username has not been deleted.', array('%name' => theme('placeholder', $account->name))));
+   	}
+    
+    // The user isn't going to be logging on again, anyway, so we should do this...
+    db_query('DELETE FROM {sessions} WHERE uid = %d', $account->uid);
+    
+    watchdog('user', t('Deleted user: %name %email.', array('%name' => theme('placeholder', $account->name), '%email' => theme('placeholder', '<'. $account->mail .'>'))), WATCHDOG_NOTICE);
+    module_invoke_all('user', 'delete', $edit, $account);
+	drupal_goto('admin/user');
+  }
+  else {
+    $user_delete_options = array('delete_details' => t('Delete personal information but retain username.'), 'delete_username' => t('Delete all account information and make posts anonymous.'));
+	$content_delete_options = array('delete_content' => t('Delete content.'));
+
+    $form['user_delete_options'] = array('#type' => 'radios', '#title' => t('User options'), '#options' => $user_delete_options, '#default_value' => 'delete_details');
+	if (user_access('delete content with account(s)')) {
+	  $form['content_delete_options'] = array('#type'=> 'checkboxes', '#title' => t('Content options'), '#options' => $content_delete_options);
+	}
+	$form['confirm'] = array('#type' => 'submit', '#value' => t('Confirm'));
+	
+	drupal_set_message(t('Are you sure you want to delete the account %name?  This action cannot be undone.', array('%name' => theme('placeholder', $account->name))), 'error');
+    return drupal_get_form('delete_user_form',$form);
+  }
+}
+
 function user_view($uid = 0) {
   global $user;
 
@@ -1782,7 +1827,7 @@
   $sql .= tablesort_sql($header);
   $result = pager_query($sql, 50);
 
-  $status = array(t('blocked'), t('active'));
+  $status = array(t('blocked'), t('active'), t('deleted'));
   while ($account = db_fetch_object($result)) {
     $rows[] = array(theme('username', $account),
                     $status[$account->status],