You are here

function force_password_change_form_alter in Force Password Change 2.0.x

Same name and namespace in other branches
  1. 8 force_password_change.module \force_password_change_form_alter()
  2. 6.3 force_password_change.module \force_password_change_form_alter()
  3. 6.2 force_password_change.module \force_password_change_form_alter()
  4. 7.2 force_password_change.module \force_password_change_form_alter()
  5. 7 force_password_change.module \force_password_change_form_alter()

Implements hook_form_alter().

File

./force_password_change.module, line 16

Code

function force_password_change_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Alter the role edit page for a single role.
  if ($form_id == 'user_role_form') {

    // Set a message depending on whether pending password changes are
    // checked on every page, or only login.
    if (\Drupal::config('force_password_change.settings')
      ->get('check_login_only')) {
      $description = t('Users will be required to change their password upon their next login.');
    }
    else {
      $description = t('Users who are not signed in will be required to change their password immediately upon login. Users who are currently signed in will be required to change their password upon their next page click, and after changing their password will be redirected back to the page they were attempting to access.');
    }
    $form['force_password_change'] = [
      '#type' => 'checkbox',
      '#title' => t('Force users in this role to change their password'),
      '#description' => $description . '<br />' . t('Note: When you return to this page, this box will be unchecked. This is because this setting is a trigger, not a persistant state.'),
    ];

    // Add a custom submit function that forces all users in
    // the role to change their password.
    $form['actions']['submit']['#submit'][] = 'force_password_change_edit_role';
  }
  elseif ($form_id == 'user_role_delete_form') {
    $role = \Drupal::routeMatch()
      ->getParameter('user_role');
    $form['rid'] = [
      '#type' => 'value',
      '#value' => $role
        ->id(),
    ];

    // Add a custom submit function that removes the role
    // from the {force_password_change_roles} table.
    $form['actions']['submit']['#submit'][] = 'force_password_change_delete_role';
  }
  elseif ($form_id == 'user_form') {
    $account = \Drupal::routeMatch()
      ->getParameter('user');
    $current_user = \Drupal::currentUser();

    // Only alter the form if the user has the correct permission.
    if ($current_user
      ->hasPermission('administer force password change')) {

      // Find out where the password area lies, in case
      // a module has moved it from its default location.
      if (isset($form['account'])) {
        $use_form =& $form['account'];
      }
      else {
        $use_form =& $form;
      }

      // Set a weight on the name and email
      // fields to ensure they remain at the top.
      $use_form['name']['#weight'] = -10;
      $use_form['mail']['#weight'] = -9;

      // Create a fieldset to contain all password information.
      $use_form['password'] = [
        '#type' => 'fieldset',
        '#title' => t('Password'),
        '#weight' => -1,
      ];

      // Add the original password field to the fieldset.
      $use_form['password']['pass'] = $use_form['pass'];
      if (isset($use_form['pass'])) {
        unset($use_form['pass']);
      }

      // Get the correct message to show depending on the site settings.
      if (\Drupal::config('force_password_change.settings')
        ->get('check_login_only')) {
        $description = t('If this box is checked, the user will be forced to change their password upon their next login.');
      }
      else {
        $description = t('If this box is checked, the user will be forced to change their password. If the user is signed in, they will be forced to change their password on their next page load. If they are not signed in, they will be forced to change their password the next time they log in.');
      }
      $use_form['password']['force_password_change'] = [
        '#type' => 'checkbox',
        '#title' => t('Force this user to change their password'),
        '#access' => $current_user
          ->hasPermission('administer force password change'),
        '#description' => $description . '<br />' . t('Note: This box will be unchecked each time the page is loaded, as it is a trigger, not a persistent state.'),
      ];

      // Get the data regarding the users last password change and last force.
      $last_force_time = \Drupal::service('user.data')
        ->get('force_password_change', $account
        ->id(), 'last_force');
      if ($last_force_time) {
        $last_force = \Drupal::service('date.formatter')
          ->format($last_force_time, 'short');
      }
      elseif (\Drupal::config('force_password_change.settings')
        ->get('first_time_login_password_change') && $account
        ->getCreatedTime() > \Drupal::config('force_password_change.settings')
        ->get('installation_date')) {
        $last_force = t('Their first login');
      }
      else {
        $forced_uids = \Drupal::service('force_password_change.service')
          ->getFirstTimeLoginUids();
        if (count($forced_uids) && isset($forced_uids[$account
          ->id()])) {
          $last_force = t('First login');
        }
        else {
          $last_force = t('Never');
        }
      }
      $items[] = t('User has a pending forced password change: @pending', [
        '@pending' => \Drupal::service('user.data')
          ->get('force_password_change', $account
          ->id(), 'pending_force') ? t('Yes') : t('No'),
      ]);
      $items[] = t('User was last forced to change their password on: @last_force', [
        '@last_force' => $last_force,
      ]);
      $last_change_time = \Drupal::service('user.data')
        ->get('force_password_change', $account
        ->id(), 'last_change');
      $items[] = t("User's password was last changed on: @last_change", [
        '@last_change' => $last_change_time ? \Drupal::service('date.formatter')
          ->format($last_change_time, 'short') : t('Never'),
      ]);

      // Display the user's password change stats for the administrator.
      $use_form['password']['password_stats'] = [
        'header' => [
          '#prefix' => '<p><strong>',
          '#suffix' => '</strong></p>',
          '#markup' => t('Password Stats:'),
        ],
        'list' => [
          '#theme' => 'item_list',
          '#items' => $items,
        ],
      ];
    }
    $pass_reset = isset($_SESSION['pass_reset_' . $account
      ->id()]) && isset($_GET['pass-reset-token']) && $_GET['pass-reset-token'] == $_SESSION['pass_reset_' . $account
      ->id()];
    $protected_values = [];

    // The user may only change their own password without their current
    // password if they logged in via a one-time login link.
    if (!$pass_reset) {
      $protected_values['mail'] = $form['account']['mail']['#title'];
      $protected_values['pass'] = t('Password');
      $url = Url::fromRoute('user.pass', [], [
        'attributes' => [
          'title' => t('Request new password via e-mail.'),
        ],
      ]);
      $request_link = Link::fromTextAndUrl(t('request a new password'), $url);
      $request_new = new FormattableMarkup('@link', [
        '@link' => $request_link
          ->toString(),
      ]);
      $form['account']['current_pass']['#description'] = t('Enter your current password to change the %mail or %pass. If you do not know your current password, you can @request_new.', [
        '%mail' => $protected_values['mail'],
        '%pass' => $protected_values['pass'],
        '@request_new' => $request_new,
      ]);
    }

    // Set a flag indicating whether the user is being
    // force to change their password.
    $form['pending_force_password_change'] = [
      '#type' => 'value',
      '#value' => \Drupal::service('user.data')
        ->get('force_password_change', $account
        ->id(), 'force_password_change'),
    ];

    // Add a custom validation function to check that the user
    // has both filled in a password, and that it has been changed
    // from the previous password.
    $form['#validate'][] = 'force_password_change_validate_user';
    $form['actions']['submit']['#submit'][] = 'force_password_change_update_user';
  }
  elseif ($form_id == 'user_register_form' && \Drupal::currentUser()
    ->id()) {

    // Add the option to force the user to change their password on
    // first time login only if it is not turned on site-wide.
    if (!\Drupal::config('force_password_change.settings')
      ->get('first_time_login_password_change')) {

      // Get the location of the password field.
      if ($form['account']) {
        $use_form =& $form['account'];
      }
      else {
        $use_form =& $form;
      }
      $use_form['name']['#weight'] = -10;
      $use_form['mail']['#weight'] = -9;
      $use_form['password']['#weight'] = -8;
      $use_form['password']['pass'] = $use_form['pass'];
      unset($use_form['pass']);
      $use_form['password']['force_password_change'] = [
        '#type' => 'checkbox',
        '#title' => t('Force password change on first-time login'),
        '#description' => t('If this box is checked, the user will be forced to change their password on their first login.'),
        '#access' => \Drupal::currentUser()
          ->hasPermission('administer force password change'),
      ];
      $form['actions']['submit']['#submit'][] = 'force_password_change_insert_user';
    }
  }
}