diff --git a/core/modules/user/lib/Drupal/user/Form/UserCancelConfirm.php b/core/modules/user/lib/Drupal/user/Form/UserCancelConfirm.php new file mode 100644 index 0000000..0650a41 --- /dev/null +++ b/core/modules/user/lib/Drupal/user/Form/UserCancelConfirm.php @@ -0,0 +1,158 @@ +account->id() == $user->uid) { + return t('Are you sure you want to cancel your account?'); + } + return t('Are you sure you want to cancel the account %name?', array('%name' => $this->account->name)); + } + + /** + * {@inheritdoc} + */ + protected function getCancelPath() { + return 'user/' . $this->account->id(); + } + + /** + * {@inheritdoc} + */ + protected function getDescription() { + $description = ''; + $default_method = config('user.settings')->get('cancel_method'); + if (user_access('administer users') || user_access('select account cancellation method')) { + $description = t('Select the method to cancel the account above.'); + } + // Options supplied via user_cancel_methods() can have a custom + // #confirm_description property for the confirmation form description. + elseif (isset($this->cancel_methods[$default_method]['#confirm_description'])) { + $description = $this->cancel_methods[$default_method]['#confirm_description']; + } + return $description . ' ' . t('This action cannot be undone.'); + } + + /** + * {@inheritdoc} + */ + protected function getConfirmText() { + return t('Cancel account'); + } + + /** + * {@inheritdoc} + * @param Drupal\user\Plugin\Core\Entity\User $account + * The user account to be canceled. + */ + public function buildForm(array $form, array &$form_state, User $account = NULL) { + $this->account = $account; + // @todo move to proper place + form_load_include($form_state, 'inc', 'user', 'user.pages'); + $this->cancel_methods = user_cancel_methods(); + global $user; + + $form['_account'] = array('#type' => 'value', '#value' => $account); + + // Display account cancellation method selection, if allowed. + $admin_access = user_access('administer users'); + $form['user_cancel_method'] = array( + '#type' => 'radios', + '#title' => ($account->uid == $user->uid ? t('When cancelling your account') : t('When cancelling the account')), + '#access' => $admin_access || user_access('select account cancellation method'), + ); + $form['user_cancel_method'] += $this->cancel_methods; + + // Allow user administrators to skip the account cancellation confirmation + // mail (by default), as long as they do not attempt to cancel their own + // account. + $override_access = $admin_access && ($account->uid != $user->uid); + $form['user_cancel_confirm'] = array( + '#type' => 'checkbox', + '#title' => t('Require e-mail confirmation to cancel account.'), + '#default_value' => ($override_access ? FALSE : TRUE), + '#access' => $override_access, + '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'), + ); + // Also allow to send account canceled notification mail, if enabled. + $default_notify = config('user.settings')->get('notify.status_canceled'); + $form['user_cancel_notify'] = array( + '#type' => 'checkbox', + '#title' => t('Notify user when account is canceled.'), + '#default_value' => ($override_access ? FALSE : $default_notify), + '#access' => $override_access && $default_notify, + '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'), + ); + + // Always provide entity id in the same form key as in the entity edit form. + $form['uid'] = array('#type' => 'value', '#value' => $account->uid); + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + global $user; + + // Cancel account immediately, if the current user has administrative + // privileges, no confirmation mail shall be sent, and the user does not + // attempt to cancel the own account. + if (user_access('administer users') && empty($form_state['values']['user_cancel_confirm']) && $this->account->id() != $user->uid) { + user_cancel($form_state['values'], $this->account->id(), $form_state['values']['user_cancel_method']); + + $form_state['redirect'] = 'admin/people'; + } + else { + // Store cancelling method and whether to notify the user in + // $this->account for user_cancel_confirm(). + $this->account->user_cancel_method = $form_state['values']['user_cancel_method']; + $this->account->user_cancel_notify = $form_state['values']['user_cancel_notify']; + $this->account->save(); + _user_mail_notify('cancel_confirm', $this->account); + drupal_set_message(t('A confirmation request to cancel your account has been sent to your e-mail address.')); + watchdog('user', 'Sent account cancellation request to %name %email.', array('%name' => $this->account->name, '%email' => '<' . $this->account->mail . '>'), WATCHDOG_NOTICE); + + $form_state['redirect'] = 'user/' . $this->account->id(); + } + } + +} diff --git a/core/modules/user/lib/Drupal/user/Form/UserMultipleCancelConfirm.php b/core/modules/user/lib/Drupal/user/Form/UserMultipleCancelConfirm.php new file mode 100644 index 0000000..1f0d44d --- /dev/null +++ b/core/modules/user/lib/Drupal/user/Form/UserMultipleCancelConfirm.php @@ -0,0 +1,147 @@ +cancel_methods = user_cancel_methods(); + + $edit = $form_state['input']; + + $form['accounts'] = array('#prefix' => '', '#tree' => TRUE); + $accounts = user_load_multiple(array_keys(array_filter($edit['accounts']))); + foreach ($accounts as $uid => $account) { + // Prevent user 1 from being canceled. + if ($uid <= 1) { + continue; + } + $form['accounts'][$uid] = array( + '#type' => 'hidden', + '#value' => $uid, + '#prefix' => '
  • ', + '#suffix' => check_plain($account->name) . "
  • \n", + ); + } + + // Output a notice that user 1 cannot be canceled. + if (isset($accounts[1])) { + $redirect = (count($accounts) == 1); + $message = t('The user account %name cannot be cancelled.', array('%name' => $accounts[1]->name)); + drupal_set_message($message, $redirect ? 'error' : 'warning'); + // If only user 1 was selected, redirect to the overview. + if ($redirect) { + drupal_goto('admin/people'); + } + } + + $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel'); + + $form['user_cancel_method'] = array( + '#type' => 'radios', + '#title' => t('When cancelling these accounts'), + ); + $form['user_cancel_method'] += $this->cancel_methods; + + // Allow to send the account cancellation confirmation mail. + $form['user_cancel_confirm'] = array( + '#type' => 'checkbox', + '#title' => t('Require e-mail confirmation to cancel account.'), + '#default_value' => FALSE, + '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'), + ); + // Also allow to send account canceled notification mail, if enabled. + $form['user_cancel_notify'] = array( + '#type' => 'checkbox', + '#title' => t('Notify user when account is canceled.'), + '#default_value' => FALSE, + '#access' => config('user.settings')->get('notify.status_canceled'), + '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'), + ); + + return parent::buildForm($form, $form_state); + } + + /** + * {@inheritdoc} + */ + public function submitForm(array &$form, array &$form_state) { + global $user; + + if ($form_state['values']['confirm']) { + foreach ($form_state['values']['accounts'] as $uid => $value) { + // Prevent programmatic form submissions from cancelling user 1. + if ($uid <= 1) { + continue; + } + // Prevent user administrators from deleting themselves without confirmation. + if ($uid == $user->uid) { + $admin_form_state = $form_state; + unset($admin_form_state['values']['user_cancel_confirm']); + // The $user global is not a complete user entity, so load the full + // entity. + $admin_form_state['values']['_account'] = user_load($user->uid); + $admin_form = new UserCancelConfirm(); + $admin_form_mock = array(); + $admin_form->submitForm($admin_form_mock, $admin_form_state); + } + else { + user_cancel($form_state['values'], $uid, $form_state['values']['user_cancel_method']); + } + } + } + $form_state['redirect'] = 'admin/people'; + } + +} diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc index 9946ae2..c68de6b 100644 --- a/core/modules/user/user.admin.inc +++ b/core/modules/user/user.admin.inc @@ -5,6 +5,8 @@ * Admin page callback file for the user module. */ +use Drupal\user\Form\UserMultipleCancelConfirm; + /** * Page callback: Generates the appropriate user administration form. * @@ -31,7 +33,8 @@ function user_admin($callback_arg = '') { break; default: if (!empty($_POST['accounts']) && isset($_POST['operation']) && ($_POST['operation'] == 'cancel')) { - $build['user_multiple_cancel_confirm'] = drupal_get_form('user_multiple_cancel_confirm'); + $confirm_form = new UserMultipleCancelConfirm(); + $build['user_multiple_cancel_confirm'] = drupal_get_form($confirm_form); } else { $build['user_filter_form'] = drupal_get_form('user_filter_form'); diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 0b884fa..9f43742 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -1013,11 +1013,7 @@ function user_menu() { ); $items['user/%user/cancel'] = array( 'title' => 'Cancel account', - 'page callback' => 'drupal_get_form', - 'page arguments' => array('user_cancel_confirm_form', 1), - 'access callback' => 'entity_page_access', - 'access arguments' => array(1, 'delete'), - 'file' => 'user.pages.inc', + 'route_name' => 'user_cancel_confirm', ); $items['user/%user/cancel/confirm/%/%'] = array( 'title' => 'Confirm account cancellation', @@ -2129,98 +2125,6 @@ function user_multiple_role_edit($accounts, $operation, $rid) { } } -function user_multiple_cancel_confirm($form, &$form_state) { - $edit = $form_state['input']; - - $form['accounts'] = array('#prefix' => '', '#tree' => TRUE); - $accounts = user_load_multiple(array_keys(array_filter($edit['accounts']))); - foreach ($accounts as $uid => $account) { - // Prevent user 1 from being canceled. - if ($uid <= 1) { - continue; - } - $form['accounts'][$uid] = array( - '#type' => 'hidden', - '#value' => $uid, - '#prefix' => '
  • ', - '#suffix' => check_plain($account->name) . "
  • \n", - ); - } - - // Output a notice that user 1 cannot be canceled. - if (isset($accounts[1])) { - $redirect = (count($accounts) == 1); - $message = t('The user account %name cannot be cancelled.', array('%name' => $accounts[1]->name)); - drupal_set_message($message, $redirect ? 'error' : 'warning'); - // If only user 1 was selected, redirect to the overview. - if ($redirect) { - drupal_goto('admin/people'); - } - } - - $form['operation'] = array('#type' => 'hidden', '#value' => 'cancel'); - - form_load_include($form_state, 'inc', 'user', 'user.pages'); - $form['user_cancel_method'] = array( - '#type' => 'radios', - '#title' => t('When cancelling these accounts'), - ); - $form['user_cancel_method'] += user_cancel_methods(); - - // Allow to send the account cancellation confirmation mail. - $form['user_cancel_confirm'] = array( - '#type' => 'checkbox', - '#title' => t('Require e-mail confirmation to cancel account.'), - '#default_value' => FALSE, - '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'), - ); - // Also allow to send account canceled notification mail, if enabled. - $form['user_cancel_notify'] = array( - '#type' => 'checkbox', - '#title' => t('Notify user when account is canceled.'), - '#default_value' => FALSE, - '#access' => config('user.settings')->get('notify.status_canceled'), - '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'), - ); - - return confirm_form($form, - t('Are you sure you want to cancel these user accounts?'), - 'admin/people', t('This action cannot be undone.'), - t('Cancel accounts'), t('Cancel')); -} - -/** - * Submit handler for mass-account cancellation form. - * - * @see user_multiple_cancel_confirm() - * @see user_cancel_confirm_form_submit() - */ -function user_multiple_cancel_confirm_submit($form, &$form_state) { - global $user; - - if ($form_state['values']['confirm']) { - foreach ($form_state['values']['accounts'] as $uid => $value) { - // Prevent programmatic form submissions from cancelling user 1. - if ($uid <= 1) { - continue; - } - // Prevent user administrators from deleting themselves without confirmation. - if ($uid == $user->uid) { - $admin_form_state = $form_state; - unset($admin_form_state['values']['user_cancel_confirm']); - // The $user global is not a complete user entity, so load the full - // entity. - $admin_form_state['values']['_account'] = user_load($user->uid); - user_cancel_confirm_form_submit(array(), $admin_form_state); - } - else { - user_cancel($form_state['values'], $uid, $form_state['values']['user_cancel_method']); - } - } - } - $form_state['redirect'] = 'admin/people'; -} - /** * List user administration filters that can be applied. */ diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc index 5817d9c..0251c24 100644 --- a/core/modules/user/user.pages.inc +++ b/core/modules/user/user.pages.inc @@ -217,107 +217,6 @@ function user_edit_cancel_submit($form, &$form_state) { } /** - * Form builder; confirm form for cancelling user account. - * - * @ingroup forms - * @see user_edit_cancel_submit() - */ -function user_cancel_confirm_form($form, &$form_state, $account) { - global $user; - - $form['_account'] = array('#type' => 'value', '#value' => $account); - - // Display account cancellation method selection, if allowed. - $admin_access = user_access('administer users'); - $can_select_method = $admin_access || user_access('select account cancellation method'); - $form['user_cancel_method'] = array( - '#type' => 'radios', - '#title' => ($account->uid == $user->uid ? t('When cancelling your account') : t('When cancelling the account')), - '#access' => $can_select_method, - ); - $form['user_cancel_method'] += user_cancel_methods(); - - // Allow user administrators to skip the account cancellation confirmation - // mail (by default), as long as they do not attempt to cancel their own - // account. - $override_access = $admin_access && ($account->uid != $user->uid); - $form['user_cancel_confirm'] = array( - '#type' => 'checkbox', - '#title' => t('Require e-mail confirmation to cancel account.'), - '#default_value' => ($override_access ? FALSE : TRUE), - '#access' => $override_access, - '#description' => t('When enabled, the user must confirm the account cancellation via e-mail.'), - ); - // Also allow to send account canceled notification mail, if enabled. - $default_notify = config('user.settings')->get('notify.status_canceled'); - $form['user_cancel_notify'] = array( - '#type' => 'checkbox', - '#title' => t('Notify user when account is canceled.'), - '#default_value' => ($override_access ? FALSE : $default_notify), - '#access' => $override_access && $default_notify, - '#description' => t('When enabled, the user will receive an e-mail notification after the account has been cancelled.'), - ); - - // Prepare confirmation form page title and description. - if ($account->uid == $user->uid) { - $question = t('Are you sure you want to cancel your account?'); - } - else { - $question = t('Are you sure you want to cancel the account %name?', array('%name' => $account->name)); - } - $default_method = config('user.settings')->get('cancel_method'); - $description = NULL; - if ($can_select_method) { - $description = t('Select the method to cancel the account above.'); - } - // Options supplied via user_cancel_methods() can have a custom - // #confirm_description property for the confirmation form description. - elseif (isset($form['user_cancel_method'][$default_method]['#confirm_description'])) { - $description = $form['user_cancel_method'][$default_method]['#confirm_description']; - } - - // Always provide entity id in the same form key as in the entity edit form. - $form['uid'] = array('#type' => 'value', '#value' => $account->uid); - return confirm_form($form, - $question, - 'user/' . $account->uid, - $description . ' ' . t('This action cannot be undone.'), - t('Cancel account'), t('Cancel')); -} - -/** - * Submit handler for the account cancellation confirm form. - * - * @see user_cancel_confirm_form() - * @see user_multiple_cancel_confirm_submit() - */ -function user_cancel_confirm_form_submit($form, &$form_state) { - global $user; - $account = $form_state['values']['_account']; - - // Cancel account immediately, if the current user has administrative - // privileges, no confirmation mail shall be sent, and the user does not - // attempt to cancel the own account. - if (user_access('administer users') && empty($form_state['values']['user_cancel_confirm']) && $account->uid != $user->uid) { - user_cancel($form_state['values'], $account->uid, $form_state['values']['user_cancel_method']); - - $form_state['redirect'] = 'admin/people'; - } - else { - // Store cancelling method and whether to notify the user in $account for - // user_cancel_confirm(). - $account->user_cancel_method = $form_state['values']['user_cancel_method']; - $account->user_cancel_notify = $form_state['values']['user_cancel_notify']; - $account->save(); - _user_mail_notify('cancel_confirm', $account); - drupal_set_message(t('A confirmation request to cancel your account has been sent to your e-mail address.')); - watchdog('user', 'Sent account cancellation request to %name %email.', array('%name' => $account->name, '%email' => '<' . $account->mail . '>'), WATCHDOG_NOTICE); - - $form_state['redirect'] = "user/$account->uid"; - } -} - -/** * Helper function to return available account cancellation methods. * * See documentation of hook_user_cancel_methods_alter(). @@ -327,8 +226,6 @@ function user_cancel_confirm_form_submit($form, &$form_state) { * * @see hook_user_cancel_methods_alter() * @see user_admin_settings() - * @see user_cancel_confirm_form() - * @see user_multiple_cancel_confirm() */ function user_cancel_methods() { $anonymous_name = config('user.settings')->get('anonymous'); diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index 409b033..2f8b9e2 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -54,3 +54,13 @@ user_role_delete: _form: '\Drupal\user\Form\UserRoleDelete' requirements: _entity_access: user_role.delete + +user_cancel_confirm: + pattern: '/user/{account}/cancel' + options: + converters: + account: 'user' + defaults: + _form: '\Drupal\user\Form\UserCancelConfirm' + requirements: + _entity_access: account.delete