summaryrefslogtreecommitdiffstats
path: root/core/lib/Drupal/Core/Render
diff options
context:
space:
mode:
authorNathaniel Catchpole2018-07-04 11:48:07 (GMT)
committerNathaniel Catchpole2018-07-04 11:48:07 (GMT)
commitcb67958df88092f704405a9b0039b80ba6e52be7 (patch)
treeb8f11982a6827d158f922d95fe33b29caf738996 /core/lib/Drupal/Core/Render
parent5e07c02053aa73d84a6cb67b8e7632a6f37dfe32 (diff)
Issue #2557299 by alexpott, Manuel Garcia, borisson_, phenaproxima, swentel, Berdir, larowlan, mbovan, martin107, LKS90, segi, tim.plunkett, giancarlosotelo: Any AJAX call disregards machine name verification when AJAX is used and leads to a fatal error
Diffstat (limited to 'core/lib/Drupal/Core/Render')
-rw-r--r--core/lib/Drupal/Core/Render/Element/MachineName.php21
1 files changed, 18 insertions, 3 deletions
diff --git a/core/lib/Drupal/Core/Render/Element/MachineName.php b/core/lib/Drupal/Core/Render/Element/MachineName.php
index ace452b..9a193ba 100644
--- a/core/lib/Drupal/Core/Render/Element/MachineName.php
+++ b/core/lib/Drupal/Core/Render/Element/MachineName.php
@@ -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.'));