diff --git a/core/modules/views/src/Plugin/views/field/EntityField.php b/core/modules/views/src/Plugin/views/field/EntityField.php index 6ef6b011b86347ac7d88ca841c9995fb66004232..e0b0f3841b212ac9d1dac711f29555a16a9088f9 100644 --- a/core/modules/views/src/Plugin/views/field/EntityField.php +++ b/core/modules/views/src/Plugin/views/field/EntityField.php @@ -986,7 +986,7 @@ protected function addSelfTokens(&$tokens, $item) { if (is_array($raw)) { if (isset($raw[$id]) && is_scalar($raw[$id])) { - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($raw[$id]); + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $raw[$id]; } else { // Make sure that empty values are replaced as well. @@ -999,7 +999,7 @@ protected function addSelfTokens(&$tokens, $item) { // Check if TypedDataInterface is implemented so we know how to render // the item as a string. if (!empty($property) && $property instanceof TypedDataInterface) { - $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = Xss::filterAdmin($property->getString()); + $tokens['{{ ' . $this->options['id'] . '__' . $id . ' }}'] = $property->getString(); } else { // Make sure that empty values are replaced as well. diff --git a/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_self_tokens.yml b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_self_tokens.yml new file mode 100644 index 0000000000000000000000000000000000000000..19eafff440716a94a2bf7354e5182d4c06c30153 --- /dev/null +++ b/core/modules/views/tests/modules/views_test_config/test_views/views.view.test_field_self_tokens.yml @@ -0,0 +1,33 @@ +langcode: en +status: true +dependencies: + module: + - node +id: test_field_self_tokens +label: '' +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + pager: + type: none + options: + offset: 0 + row: + type: fields + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + plugin_id: field diff --git a/core/modules/views/tests/src/Kernel/Handler/FieldSelfTokensTest.php b/core/modules/views/tests/src/Kernel/Handler/FieldSelfTokensTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d3ae3de87888fd2b7ca66f62b30fc2b930f2f525 --- /dev/null +++ b/core/modules/views/tests/src/Kernel/Handler/FieldSelfTokensTest.php @@ -0,0 +1,64 @@ +<?php + +namespace Drupal\Tests\views\Kernel\Handler; + +use Drupal\Core\Render\RenderContext; +use Drupal\node\Entity\Node; +use Drupal\node\Entity\NodeType; +use Drupal\Tests\views\Kernel\ViewsKernelTestBase; +use Drupal\views\Views; + +/** + * Tests token escaping in the EntityField handler. + * + * @group views + */ +class FieldSelfTokensTest extends ViewsKernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['node']; + + /** + * Views used by this test. + * + * @var array + */ + public static $testViews = ['test_field_self_tokens']; + + /** + * This method is called before each test. + */ + protected function setUp($import_test_views = TRUE): void { + parent::setUp(); + + $this->installEntitySchema('user'); + $this->installEntitySchema('node'); + + NodeType::create(['type' => 'article', 'name' => 'Article'])->save(); + + Node::create([ + 'title' => 'Questions & Answers', + 'type' => 'article', + ])->save(); + } + + /** + * {@inheritdoc} + */ + public function testSelfTokenEscaping() { + $view = Views::getView('test_field_self_tokens'); + $view->initHandlers(); + $this->executeView($view); + $row = $view->result[0]; + $title_field = $view->field['title']; + $title_field->options['alter']['text'] = '<p>{{ title__value }}</p>'; + $title_field->options['alter']['alter_text'] = TRUE; + $output = \Drupal::service('renderer')->executeInRenderContext(new RenderContext(), function () use ($title_field, $row) { + return $title_field->theme($row); + }); + $this->assertSame('<p>Questions & Answers</p>', (string) $output); + } + +}