diff --git a/core/lib/Drupal/Core/Render/Element/MachineName.php b/core/lib/Drupal/Core/Render/Element/MachineName.php index 66c85c7..8b9c840 100644 --- a/core/lib/Drupal/Core/Render/Element/MachineName.php +++ b/core/lib/Drupal/Core/Render/Element/MachineName.php @@ -232,12 +232,38 @@ public static function validateMachineName(&$element, FormStateInterface $form_s } } - // Verify that the machine name is unique. - if ($element['#default_value'] !== $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.')); + // Verify that the machine name is unique. Check form state if we need to + // explicitly validate the element. This happens every time when an error + // has been set, since this breaks on AJAX requests. + // @see https://www.drupal.org/node/2557299. + $needs_revalidation = $form_state->get('needs_revalidation', $element['#name']); + if ($needs_revalidation) { + self::isUnique($element, $form_state); + } + elseif ($element['#default_value'] !== $element['#value']) { + self::isUnique($element, $form_state); + } + + } + + /** + * Verify that the machine name is unique. + * + * @param $element + * The form element + * @param FormStateInterface $form_state + * The form state interface. + * @param (optional) $set_needs_revalidation + * Whether to set a property on form state in case of an error to revalidate + * the element again on the next submission. + */ + public static function isUnique($element, FormStateInterface $form_state, $set_needs_revalidation = TRUE) { + $function = $element['#machine_name']['exists']; + if (call_user_func($function, $element['#value'], $element, $form_state)) { + if ($set_needs_revalidation) { + $form_state->set('needs_revalidation', $element['#name']); } + $form_state->setError($element, t('The machine-readable name is already in use. It must be unique.')); } } diff --git a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php index 6c5ee13..83a326d 100644 --- a/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php +++ b/core/modules/ckeditor/src/Tests/CKEditorAdminTest.php @@ -218,6 +218,20 @@ function testExistingFormat() { $editor = entity_load('editor', 'filtered_html'); $this->assertTrue($editor instanceof Editor, 'An Editor config entity exists.'); $this->assertIdentical($expected_settings, $editor->getSettings()); + + $this->drupalGet('admin/config/content/formats/add'); + // Now attempt to add another filter format with the same editor and same + // machine name. + $edit = array( + 'format' => 'filtered_html', + 'name' => 'Filtered HTML', + 'editor[editor]' => 'ckeditor', + ); + $this->drupalPostAjaxForm(NULL, $edit, 'editor_configure'); + $this->assertResponse(200); + $this->drupalPostForm(NULL, $edit, t('Save configuration')); + $this->assertResponse(200); + $this->assertText(t('The machine-readable name is already in use. It must be unique.')); } /**