summaryrefslogtreecommitdiffstats
path: root/core/modules/user/src/Form/UserCancelForm.php
blob: a1fd5f7c86ce5b52de7da42c02cf8e9faa6c2ec8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
<?php

namespace Drupal\user\Form;

use Drupal\Core\Entity\ContentEntityConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * Provides a confirmation form for cancelling user account.
 *
 * @internal
 */
class UserCancelForm extends ContentEntityConfirmFormBase {

  /**
   * Available account cancellation methods.
   *
   * @var array
   */
  protected $cancelMethods;

  /**
   * The user being cancelled.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $entity;

  /**
   * {@inheritdoc}
   */
  public function getQuestion() {
    if ($this->entity->id() == $this->currentUser()->id()) {
      return $this->t('Are you sure you want to cancel your account?');
    }
    return $this->t('Are you sure you want to cancel the account %name?', ['%name' => $this->entity->label()]);
  }

  /**
   * {@inheritdoc}
   */
  public function getCancelUrl() {
    return $this->entity->urlInfo();
  }

  /**
   * {@inheritdoc}
   */
  public function getDescription() {
    $description = '';
    $default_method = $this->config('user.settings')->get('cancel_method');
    if ($this->currentUser()->hasPermission('administer users') || $this->currentUser()->hasPermission('select account cancellation method')) {
      $description = $this->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->cancelMethods[$default_method]['#confirm_description'])) {
      $description = $this->cancelMethods[$default_method]['#confirm_description'];
    }
    return $description . ' ' . $this->t('This action cannot be undone.');
  }

  /**
   * {@inheritdoc}
   */
  public function getConfirmText() {
    return $this->t('Cancel account');
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $user = $this->currentUser();
    $this->cancelMethods = user_cancel_methods();

    // Display account cancellation method selection, if allowed.
    $admin_access = $user->hasPermission('administer users');
    $form['user_cancel_method'] = [
      '#type' => 'radios',
      '#title' => ($this->entity->id() == $user->id() ? $this->t('When cancelling your account') : $this->t('When cancelling the account')),
      '#access' => $admin_access || $user->hasPermission('select account cancellation method'),
    ];
    $form['user_cancel_method'] += $this->cancelMethods;

    // 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 && ($this->entity->id() != $user->id());
    $form['user_cancel_confirm'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Require email confirmation to cancel account'),
      '#default_value' => !$override_access,
      '#access' => $override_access,
      '#description' => $this->t('When enabled, the user must confirm the account cancellation via email.'),
    ];
    // Also allow to send account canceled notification mail, if enabled.
    $default_notify = $this->config('user.settings')->get('notify.status_canceled');
    $form['user_cancel_notify'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Notify user when account is canceled'),
      '#default_value' => ($override_access ? FALSE : $default_notify),
      '#access' => $override_access && $default_notify,
      '#description' => $this->t('When enabled, the user will receive an email notification after the account has been canceled.'),
    ];

    // Always provide entity id in the same form key as in the entity edit form.
    $form['uid'] = ['#type' => 'value', '#value' => $this->entity->id()];

    // Store the user permissions so that it can be altered in hook_form_alter()
    // if desired.
    $form['access'] = [
      '#type' => 'value',
      '#value' => $user->hasPermission('administer users'),
    ];

    $form = parent::buildForm($form, $form_state);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // 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 (!$form_state->isValueEmpty('access') && $form_state->isValueEmpty('user_cancel_confirm') && $this->entity->id() != $this->currentUser()->id()) {
      user_cancel($form_state->getValues(), $this->entity->id(), $form_state->getValue('user_cancel_method'));

      $form_state->setRedirectUrl($this->entity->urlInfo('collection'));
    }
    else {
      // Store cancelling method and whether to notify the user in
      // $this->entity for
      // \Drupal\user\Controller\UserController::confirmCancel().
      $this->entity->user_cancel_method = $form_state->getValue('user_cancel_method');
      $this->entity->user_cancel_notify = $form_state->getValue('user_cancel_notify');
      $this->entity->save();
      _user_mail_notify('cancel_confirm', $this->entity);
      $this->messenger()->addStatus($this->t('A confirmation request to cancel your account has been sent to your email address.'));
      $this->logger('user')->notice('Sent account cancellation request to %name %email.', ['%name' => $this->entity->label(), '%email' => '<' . $this->entity->getEmail() . '>']);

      $form_state->setRedirect(
        'entity.user.canonical',
        ['user' => $this->entity->id()]
      );
    }
  }

}