Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / lib / Drupal / Core / Render / Element / MachineName.php
index ace452b072578c49ebb341d1c7cbe5714908ac9e..9a193ba9b9eb623d28b9dfb3f2b68d5ca58ddb8d 100644 (file)
@@ -28,7 +28,8 @@ use Drupal\Core\Language\LanguageInterface;
  *     - The form state object.
  *     In most cases, an existing API or menu argument loader function can be
  *     re-used. The callback is only invoked if the submitted value differs from
- *     the element's #default_value.
+ *     the element's initial #default_value. The initial #default_value is
+ *     stored in form state so AJAX forms can be reliably validated.
  *   - source: (optional) The #array_parents of the form element containing the
  *     human-readable name (i.e., as contained in the $form structure) to use as
  *     source for the machine name. Defaults to array('label').
@@ -150,6 +151,17 @@ class MachineName extends Textfield {
       'field_suffix' => $element['#field_suffix'],
     ];
 
+    // Store the initial value in form state. The machine name needs this to
+    // ensure that the exists function is not called for existing values when
+    // editing them.
+    $initial_values = $form_state->get('machine_name.initial_values') ?: [];
+    // Store the initial values in an array so we can differentiate between a
+    // NULL default value and a new machine name element.
+    if (!array_key_exists($element['#name'], $initial_values)) {
+      $initial_values[$element['#name']] = $element['#default_value'];
+      $form_state->set('machine_name.initial_values', $initial_values);
+    }
+
     // By default, machine names are restricted to Latin alphanumeric characters.
     // So, default to LTR directionality.
     if (!isset($element['#attributes'])) {
@@ -246,8 +258,11 @@ class MachineName extends Textfield {
       }
     }
 
-    // Verify that the machine name is unique.
-    if ($element['#default_value'] !== $element['#value']) {
+    // Verify that the machine name is unique. If the value matches the initial
+    // default value then it does not need to be validated as the machine name
+    // element assumes the form is editing the existing value.
+    $initial_values = $form_state->get('machine_name.initial_values') ?: [];
+    if (!array_key_exists($element['#name'], $initial_values) || $initial_values[$element['#name']] !== $element['#value']) {
       $function = $element['#machine_name']['exists'];
       if (call_user_func($function, $element['#value'], $element, $form_state)) {
         $form_state->setError($element, t('The machine-readable name is already in use. It must be unique.'));