Index: modules/user.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/user.module,v
retrieving revision 1.578
diff -u -r1.578 user.module
--- modules/user.module	2 Feb 2006 01:51:54 -0000	1.578
+++ modules/user.module	3 Feb 2006 23:58:51 -0000
@@ -422,7 +422,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)');
 }
 
 /**
@@ -679,6 +679,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'),
@@ -739,6 +741,9 @@
     $items[] = array('path' => 'admin/access/rules/delete', 'title' => t('delete rule'),
       'callback' => 'user_admin_access_delete', 'access' => $access_access,
       'type' => MENU_CALLBACK);
+    $items[] = array('path' => 'user/delete/confirm', 'title' => t('confirm delete user'),
+      'callback' => 'user_edit_delete_confirm', 'access' => $delete_access,
+      'type' => MENU_CALLBACK);
 
     if (module_exist('search')) {
       $items[] = array('path' => 'admin/user/search', 'title' => t('search'),
@@ -772,8 +777,8 @@
         $items[] = array('path' => 'user/'. arg(1) .'/edit', 'title' => t('edit'),
           '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,
+        $items[] = array('path' => 'user/'. arg(1) .'/delete', 'title' => t('delete user'),
+          'callback' => 'user_edit_delete', 'access' => $delete_access,
           'type' => MENU_CALLBACK);
 
         if (arg(2) == 'edit') {
@@ -1269,22 +1274,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']);
@@ -1297,7 +1287,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');
@@ -1329,6 +1319,82 @@
   drupal_goto('user/'. $account->uid);
 }
 
+function user_edit_delete() {
+  $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['#action'] = url('user/delete/confirm');
+  $form['user_to_delete'] = array('#type' => 'hidden', '#value' => arg(1));
+  $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['submit'] = array('#type' => 'submit', '#value' => t('Submit'));
+	
+  return drupal_get_form('delete_user_form',$form);
+}
+
+function user_edit_delete_confirm() {
+  $edit = $_POST['edit'];
+
+  if (!$edit['user_to_delete']) {
+    return drupal_not_found();
+  }
+
+  $account = user_load(array('uid' => $edit['user_to_delete']));
+
+  if ($edit['confirm']) {
+    if ($edit['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 {
+    $form['user_to_delete'] = array('#type' => 'hidden', '#value' => $edit['user_to_delete']);
+    $form['user_delete_options'] = array('#type' => 'hidden', '#value' => $edit['user_delete_options']);
+	  if ($edit['content_delete_options']) {
+	    $form['delete_content'] = array('#type'=> 'hidden', '#value' => $edit['content_delete_options']['delete_content']);
+	  }
+    print_r ($form);
+    $message = ($form['user_delete_options']['#value'] == 'delete_username' ? t('Completely delete user and make posts anonymous.') : t('Delete personal information.'));
+    $message .= ($form['delete_content']['#value'] == 'delete_content' ?  t(' Delete all content.') : t(' Do not delete content.'));