Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / lib / Drupal / Core / Render / Element / PasswordConfirm.php
1 <?php
2
3 namespace Drupal\Core\Render\Element;
4
5 use Drupal\Core\Form\FormStateInterface;
6
7 /**
8  * Provides a form element for double-input of passwords.
9  *
10  * Formats as a pair of password fields, which do not validate unless the two
11  * entered passwords match.
12  *
13  * Properties:
14  * - #size: The size of the input element in characters.
15  *
16  * Usage example:
17  * @code
18  * $form['pass'] = array(
19  *   '#type' => 'password_confirm',
20  *   '#title' => $this->t('Password'),
21  *   '#size' => 25,
22  * );
23  * @endcode
24  *
25  * @see \Drupal\Core\Render\Element\Password
26  *
27  * @FormElement("password_confirm")
28  */
29 class PasswordConfirm extends FormElement {
30
31   /**
32    * {@inheritdoc}
33    */
34   public function getInfo() {
35     $class = get_class($this);
36     return [
37       '#input' => TRUE,
38       '#markup' => '',
39       '#process' => [
40         [$class, 'processPasswordConfirm'],
41       ],
42       '#theme_wrappers' => ['form_element'],
43     ];
44   }
45
46   /**
47    * {@inheritdoc}
48    */
49   public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
50     if ($input === FALSE) {
51       $element += ['#default_value' => []];
52       return $element['#default_value'] + ['pass1' => '', 'pass2' => ''];
53     }
54     $value = ['pass1' => '', 'pass2' => ''];
55     // Throw out all invalid array keys; we only allow pass1 and pass2.
56     foreach ($value as $allowed_key => $default) {
57       // These should be strings, but allow other scalars since they might be
58       // valid input in programmatic form submissions. Any nested array values
59       // are ignored.
60       if (isset($input[$allowed_key]) && is_scalar($input[$allowed_key])) {
61         $value[$allowed_key] = (string) $input[$allowed_key];
62       }
63     }
64     return $value;
65   }
66
67   /**
68    * Expand a password_confirm field into two text boxes.
69    */
70   public static function processPasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
71     $element['pass1'] = [
72       '#type' => 'password',
73       '#title' => t('Password'),
74       '#value' => empty($element['#value']) ? NULL : $element['#value']['pass1'],
75       '#required' => $element['#required'],
76       '#attributes' => ['class' => ['password-field', 'js-password-field']],
77       '#error_no_message' => TRUE,
78     ];
79     $element['pass2'] = [
80       '#type' => 'password',
81       '#title' => t('Confirm password'),
82       '#value' => empty($element['#value']) ? NULL : $element['#value']['pass2'],
83       '#required' => $element['#required'],
84       '#attributes' => ['class' => ['password-confirm', 'js-password-confirm']],
85       '#error_no_message' => TRUE,
86     ];
87     $element['#element_validate'] = [[get_called_class(), 'validatePasswordConfirm']];
88     $element['#tree'] = TRUE;
89
90     if (isset($element['#size'])) {
91       $element['pass1']['#size'] = $element['pass2']['#size'] = $element['#size'];
92     }
93
94     return $element;
95   }
96
97   /**
98    * Validates a password_confirm element.
99    */
100   public static function validatePasswordConfirm(&$element, FormStateInterface $form_state, &$complete_form) {
101     $pass1 = trim($element['pass1']['#value']);
102     $pass2 = trim($element['pass2']['#value']);
103     if (strlen($pass1) > 0 || strlen($pass2) > 0) {
104       if (strcmp($pass1, $pass2)) {
105         $form_state->setError($element, t('The specified passwords do not match.'));
106       }
107     }
108     elseif ($element['#required'] && $form_state->getUserInput()) {
109       $form_state->setError($element, t('Password field is required.'));
110     }
111
112     // Password field must be converted from a two-element array into a single
113     // string regardless of validation results.
114     $form_state->setValueForElement($element['pass1'], NULL);
115     $form_state->setValueForElement($element['pass2'], NULL);
116     $form_state->setValueForElement($element, $pass1);
117
118     return $element;
119   }
120
121 }