diff --git a/core/core.services.yml b/core/core.services.yml index bc94ced..f874942 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -331,7 +331,7 @@ services: arguments: ['@request_stack', '@url_generator'] form_error_handler: class: Drupal\Core\Form\FormErrorHandler - arguments: ['@string_translation', '@link_generator'] + arguments: ['@string_translation', '@link_generator', '@renderer'] form_cache: class: Drupal\Core\Form\FormCache arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@request_stack', '@page_cache_request_policy'] diff --git a/core/lib/Drupal/Core/Form/FormErrorHandler.php b/core/lib/Drupal/Core/Form/FormErrorHandler.php index df736b0..102a79b 100644 --- a/core/lib/Drupal/Core/Form/FormErrorHandler.php +++ b/core/lib/Drupal/Core/Form/FormErrorHandler.php @@ -7,9 +7,9 @@ namespace Drupal\Core\Form; -use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Render\Element; use Drupal\Core\Routing\LinkGeneratorTrait; +use Drupal\Core\Render\RendererInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Url; @@ -24,16 +24,26 @@ class FormErrorHandler implements FormErrorHandlerInterface { use LinkGeneratorTrait; /** + * The Renderer service. + * + * @var \Drupal\Core\Render\RendererInterface + */ + protected $renderer; + + /** * Constructs a new FormErrorHandler. * * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation * The string translation service. * @param \Drupal\Core\Utility\LinkGeneratorInterface $link_generator * The link generation service. + * @param \Drupal\Core\Render\RendererInterface $renderer + * The Renderer service. */ - public function __construct(TranslationInterface $string_translation, LinkGeneratorInterface $link_generator) { + public function __construct(TranslationInterface $string_translation, LinkGeneratorInterface $link_generator, RendererInterface $renderer) { $this->stringTranslation = $string_translation; $this->linkGenerator = $link_generator; + $this->renderer = $renderer; } /** @@ -82,9 +92,7 @@ protected function displayErrorMessages(array $form, FormStateInterface $form_st unset($errors[$name]); } elseif ($is_visible_element && $has_title && $has_id) { - // We need to pass this through SafeMarkup::escape() so - // drupal_set_message() does not encode the links. - $error_links[] = SafeMarkup::escape($this->l($title, Url::fromRoute('', [], ['fragment' => $form_element['#id'], 'external' => TRUE]))); + $error_links[] = $this->l($title, Url::fromRoute('', [], ['fragment' => $form_element['#id'], 'external' => TRUE])); unset($errors[$name]); } } @@ -95,9 +103,17 @@ protected function displayErrorMessages(array $form, FormStateInterface $form_st } if (!empty($error_links)) { - $message = $this->formatPlural(count($error_links), '1 error has been found: !errors', '@count errors have been found: !errors', [ - '!errors' => SafeMarkup::set(implode(', ', $error_links)), - ]); + $render_array = [ + [ + '#markup' => $this->formatPlural(count($error_links), '1 error has been found: ', '@count errors have been found: '), + ], + [ + '#type' => 'item_list', + '#items' => $error_links, + '#context' => => ['list_style' => 'comma-list'], + ], + ]; + $message = $this->renderer->renderPlain($render_array); $this->drupalSetMessage($message, 'error'); } } diff --git a/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php b/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php index 53d7e76..50f8d90 100644 --- a/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php +++ b/core/tests/Drupal/Tests/Core/Form/FormErrorHandlerTest.php @@ -25,8 +25,9 @@ public function testDisplayErrorMessages() { $link_generator->expects($this->any()) ->method('generate') ->willReturnArgument(0); + $renderer = $this->getMock('\Drupal\Core\Render\RendererInterface'); $form_error_handler = $this->getMockBuilder('Drupal\Core\Form\FormErrorHandler') - ->setConstructorArgs([$this->getStringTranslationStub(), $link_generator]) + ->setConstructorArgs([$this->getStringTranslationStub(), $link_generator, $renderer]) ->setMethods(['drupalSetMessage']) ->getMock();