123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- <?php
- namespace Drupal\Core\Render\Element;
- use Drupal\Core\Form\FormStateInterface;
- /**
- * Provides a form element for double-input of passwords.
- *
- * Formats as a pair of password fields, which do not validate unless the two
- * entered passwords match.
- *
- * Properties:
- * - #size: The size of the input element in characters.
- *
- * Usage example:
- * @code
- * $form['pass'] = array(
- * '#type' => 'password_confirm',
- * '#title' => $this->t('Password'),
- * '#size' => 25,
- * );
- * @endcode
- *
- * @see \Drupal\Core\Render\Element\Password
- *
- * @FormElement("password_confirm")
- */
- class PasswordConfirm extends FormElement {
- /**
- * {@inheritdoc}
- */
- public function getInfo() {
- $class = get_class($this);
- return [
- '#input' => TRUE,
- '#markup' => '',
- '#process' => [
- [$class, 'processPasswordConfirm'],
- ],
- '#theme_wrappers' => ['form_element'],
- ];
- }
- /**
- * {@inheritdoc}
- */
- public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
- if ($input === FALSE) {
- $element += ['#default_value' => []];
- return $element['#default_value'] + ['pass1' => '', 'pass2' => ''];
- }
- $value = ['pass1' => '', 'pass2' => ''];
- // Throw out all invalid array keys; we only allow pass1 and pass2.
- foreach ($value as $allowed_key => $default) {
- // These should be strings, but allow other scalars since they might be
- // valid input in programmatic form submissions. Any nested array values
- // are ignored.
- if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
- $value[$allowed_key] = (string) $input[$allowed_key];
- }
- }
- return $value;
- }
- /**
- * Expand a password_confirm field into two text boxes.
- */
- public static function processPasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
- $element['pass1'] = [
- '#type' => 'password',
- '#title' => t('Password'),
- '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'],
- '#required' => $element['#required'],
- '#attributes' => ['class' => ['password-field', 'js-password-field']],
- '#error_no_message' => TRUE,
- ];
- $element['pass2'] = [
- '#type' => 'password',
- '#title' => t('Confirm password'),
- '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
- '#required' => $element['#required'],
- '#attributes' => ['class' => ['password-confirm', 'js-password-confirm']],
- '#error_no_message' => TRUE,
- ];
- $element['#element_validate'] = [[get_called_class(), 'validatePasswordConfirm']];
- $element['#tree'] = TRUE;
- if (isset($element['#size'])) {
- $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size'];
- }
- return $element;
- }
- /**
- * Validates a password_confirm element.
- */
- public static function validatePasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
- $pass1 = trim($element['pass1']['#value']);
- $pass2 = trim($element['pass2']['#value']);
- if (strlen($pass1) > 0 || strlen($pass2) > 0) {
- if (strcmp($pass1, $pass2)) {
- $form_state->setError($element, t('The specified passwords do not match.'));
- }
- }
- elseif ($element['#required'] && $form_state->getUserInput()) {
- $form_state->setError($element, t('Password field is required.'));
- }
- // Password field must be converted from a two-element array into a single
- // string regardless of validation results.
- $form_state->setValueForElement($element['pass1'], NULL);
- $form_state->setValueForElement($element['pass2'], NULL);
- $form_state->setValueForElement($element, $pass1);
- return $element;
- }
- }
|