diff --git a/core/lib/Drupal/Component/Utility/SafeStringInterface.php b/core/lib/Drupal/Component/Utility/SafeStringInterface.php index 136dd37a27e..45d536d1503 100644 --- a/core/lib/Drupal/Component/Utility/SafeStringInterface.php +++ b/core/lib/Drupal/Component/Utility/SafeStringInterface.php @@ -33,7 +33,7 @@ namespace Drupal\Component\Utility; * @see \Drupal\Component\Utility\SafeMarkup::isSafe() * @see \Drupal\Core\Template\TwigExtension::escapeFilter() */ -interface SafeStringInterface { +interface SafeStringInterface extends \JsonSerializable { /** * Returns a safe string. diff --git a/core/lib/Drupal/Component/Utility/SafeStringTrait.php b/core/lib/Drupal/Component/Utility/SafeStringTrait.php index a91e44ba571..bd1ee75aa5c 100644 --- a/core/lib/Drupal/Component/Utility/SafeStringTrait.php +++ b/core/lib/Drupal/Component/Utility/SafeStringTrait.php @@ -67,4 +67,14 @@ trait SafeStringTrait { return Unicode::strlen($this->string); } + /** + * Returns a representation of the object for use in JSON serialization. + * + * @return string + * The safe string content. + */ + public function jsonSerialize() { + return $this->__toString(); + } + } diff --git a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php index bffe6661983..7d36b51c718 100644 --- a/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php +++ b/core/lib/Drupal/Core/Ajax/AjaxResponseAttachmentsProcessor.php @@ -164,15 +164,15 @@ class AjaxResponseAttachmentsProcessor implements AttachmentsResponseProcessorIn $resource_commands = array(); if ($css_assets) { $css_render_array = $this->cssCollectionRenderer->render($css_assets); - $resource_commands[] = new AddCssCommand((string) $this->renderer->renderPlain($css_render_array)); + $resource_commands[] = new AddCssCommand($this->renderer->renderPlain($css_render_array)); } if ($js_assets_header) { $js_header_render_array = $this->jsCollectionRenderer->render($js_assets_header); - $resource_commands[] = new PrependCommand('head', (string) $this->renderer->renderPlain($js_header_render_array)); + $resource_commands[] = new PrependCommand('head', $this->renderer->renderPlain($js_header_render_array)); } if ($js_assets_footer) { $js_footer_render_array = $this->jsCollectionRenderer->render($js_assets_footer); - $resource_commands[] = new AppendCommand('body', (string) $this->renderer->renderPlain($js_footer_render_array)); + $resource_commands[] = new AppendCommand('body', $this->renderer->renderPlain($js_footer_render_array)); } foreach (array_reverse($resource_commands) as $resource_command) { $response->addCommand($resource_command, TRUE); diff --git a/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php b/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php index d83db5779f2..e48d06054d1 100644 --- a/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php +++ b/core/lib/Drupal/Core/Ajax/CommandWithAttachedAssetsTrait.php @@ -29,7 +29,7 @@ trait CommandWithAttachedAssetsTrait { * If content is a render array, it may contain attached assets to be * processed. * - * @return string + * @return string|\Drupal\Component\Utility\SafeStringInterface * HTML rendered content. */ protected function getRenderedContent() { @@ -37,10 +37,10 @@ trait CommandWithAttachedAssetsTrait { if (is_array($this->content)) { $html = \Drupal::service('renderer')->renderRoot($this->content); $this->attachedAssets = AttachedAssets::createFromRenderArray($this->content); - return (string) $html; + return $html; } else { - return (string) $this->content; + return $this->content; } } diff --git a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php index c54799db6cf..31192f35f99 100644 --- a/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php +++ b/core/lib/Drupal/Core/Render/MainContent/AjaxRenderer.php @@ -64,7 +64,7 @@ class AjaxRenderer implements MainContentRendererInterface { } } - $html = (string) $this->drupalRenderRoot($main_content); + $html = $this->drupalRenderRoot($main_content); $response->setAttachments($main_content['#attached']); // The selector for the insert command is NULL as the new content will @@ -72,7 +72,7 @@ class AjaxRenderer implements MainContentRendererInterface { // behavior can be changed with #ajax['method']. $response->addCommand(new InsertCommand(NULL, $html)); $status_messages = array('#type' => 'status_messages'); - $output = (string) $this->drupalRenderRoot($status_messages); + $output = $this->drupalRenderRoot($status_messages); if (!empty($output)) { $response->addCommand(new PrependCommand(NULL, $output)); } diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php index 6bf591a37ae..dffd2cf7ff7 100644 --- a/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php +++ b/core/lib/Drupal/Core/StringTranslation/TranslationWrapper.php @@ -118,4 +118,14 @@ class TranslationWrapper implements SafeStringInterface { return array('string', 'arguments', 'options'); } + /** + * Returns a representation of the object for use in JSON serialization. + * + * @return string + * The safe string content. + */ + public function jsonSerialize() { + return $this->__toString(); + } + } diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php index 8fe6788adc4..cc0d591d445 100644 --- a/core/lib/Drupal/Core/Template/Attribute.php +++ b/core/lib/Drupal/Core/Template/Attribute.php @@ -302,4 +302,14 @@ class Attribute implements \ArrayAccess, \IteratorAggregate, SafeStringInterface return $this->storage; } + /** + * Returns a representation of the object for use in JSON serialization. + * + * @return string + * The safe string content. + */ + public function jsonSerialize() { + return (string) $this; + } + } diff --git a/core/modules/contextual/src/ContextualController.php b/core/modules/contextual/src/ContextualController.php index ca248d19645..975113dc9d1 100644 --- a/core/modules/contextual/src/ContextualController.php +++ b/core/modules/contextual/src/ContextualController.php @@ -44,7 +44,7 @@ class ContextualController implements ContainerAwareInterface { '#type' => 'contextual_links', '#contextual_links' => _contextual_id_to_links($id), ); - $rendered[$id] = (string) $this->container->get('renderer')->renderRoot($element); + $rendered[$id] = $this->container->get('renderer')->renderRoot($element); } return new JsonResponse($rendered); diff --git a/core/modules/editor/src/EditorController.php b/core/modules/editor/src/EditorController.php index 192f3411e9b..44feda30f83 100644 --- a/core/modules/editor/src/EditorController.php +++ b/core/modules/editor/src/EditorController.php @@ -48,7 +48,7 @@ class EditorController extends ControllerBase { // Direct text editing is only supported for single-valued fields. $field = $entity->getTranslation($langcode)->$field_name; $editable_text = check_markup($field->value, $field->format, $langcode, array(FilterInterface::TYPE_TRANSFORM_REVERSIBLE, FilterInterface::TYPE_TRANSFORM_IRREVERSIBLE)); - $response->addCommand(new GetUntransformedTextCommand((string) $editable_text)); + $response->addCommand(new GetUntransformedTextCommand($editable_text)); return $response; } diff --git a/core/modules/quickedit/src/QuickEditController.php b/core/modules/quickedit/src/QuickEditController.php index 067a73a7c32..bf0b62d918e 100644 --- a/core/modules/quickedit/src/QuickEditController.php +++ b/core/modules/quickedit/src/QuickEditController.php @@ -216,7 +216,7 @@ class QuickEditController extends ControllerBase { $response->addCommand(new FieldFormSavedCommand($output, $other_view_modes)); } else { - $output = (string) $this->renderer->renderRoot($form); + $output = $this->renderer->renderRoot($form); // When working with a hidden form, we don't want its CSS/JS to be loaded. if ($request->request->get('nocssjs') !== 'true') { $response->setAttachments($form['#attached']); @@ -228,7 +228,7 @@ class QuickEditController extends ControllerBase { $status_messages = array( '#type' => 'status_messages' ); - $response->addCommand(new FieldFormValidationErrorsCommand((string) $this->renderer->renderRoot($status_messages))); + $response->addCommand(new FieldFormValidationErrorsCommand($this->renderer->renderRoot($status_messages))); } } @@ -255,7 +255,7 @@ class QuickEditController extends ControllerBase { * The view mode the field should be rerendered in. Either an Entity Display * view mode ID, or a custom one. See hook_quickedit_render_field(). * - * @return string + * @return \Drupal\Component\Utility\SafeStringInterface * Rendered HTML. * * @see hook_quickedit_render_field() @@ -275,7 +275,7 @@ class QuickEditController extends ControllerBase { $output = $this->moduleHandler()->invoke($module, 'quickedit_render_field', $args); } - return (string) $this->renderer->renderRoot($output); + return $this->renderer->renderRoot($output); } /** diff --git a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php index 1278a6da5fe..444caba7c4d 100644 --- a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php @@ -9,6 +9,7 @@ namespace Drupal\Tests\Component\Utility; use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\SafeStringInterface; +use Drupal\Component\Utility\SafeStringTrait; use Drupal\Tests\UnitTestCase; /** @@ -234,19 +235,5 @@ class SafeMarkupTestString { * SafeMarkup::set() is a global static that affects all tests. */ class SafeMarkupTestSafeString implements SafeStringInterface { - - protected $string; - - public function __construct($string) { - $this->string = $string; - } - - public function __toString() { - return $this->string; - } - - public static function create($string) { - $safe_string = new static($string); - return $safe_string; - } + use SafeStringTrait; }