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.')); + return confirm_form('user_edit_delete', $form, t('Are you sure you want to delete the user %username?', array('%username' => theme('placeholder', $account->name))), 'admin/user', t('You have chosen to: %options', array('%options' => theme('placeholder', $message))), t('Delete'), t('Cancel')); + } }