From ece021ad2d60318913321f045018bdaac3cefcbc Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Fri, 10 Jan 2025 14:30:27 +0100 Subject: [PATCH 1/8] Explicitly cast $value to string in StripTagsFilter plugin. --- src/Plugin/TypedDataFilter/StripTagsFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Plugin/TypedDataFilter/StripTagsFilter.php b/src/Plugin/TypedDataFilter/StripTagsFilter.php index 938f6c7..16fe0de 100644 --- a/src/Plugin/TypedDataFilter/StripTagsFilter.php +++ b/src/Plugin/TypedDataFilter/StripTagsFilter.php @@ -30,7 +30,7 @@ class StripTagsFilter extends DataFilterBase { * {@inheritdoc} */ public function filter(DataDefinitionInterface $definition, $value, array $arguments, ?BubbleableMetadata $bubbleable_metadata = NULL) { - return strip_tags($value); + return strip_tags((string) $value); } /** -- GitLab From ee4a405a4f423b66fde12725a586151ac0472c44 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Sat, 11 Jan 2025 09:07:45 +0100 Subject: [PATCH 2/8] Add test case for striptags filter when stringable object is passed as value instead of string primitive. --- tests/src/Kernel/DataFilterTest.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/src/Kernel/DataFilterTest.php b/tests/src/Kernel/DataFilterTest.php index 2570c57..b09487c 100644 --- a/tests/src/Kernel/DataFilterTest.php +++ b/tests/src/Kernel/DataFilterTest.php @@ -8,6 +8,7 @@ use Drupal\Core\Datetime\Entity\DateFormat; use Drupal\Core\Entity\TypedData\EntityDataDefinition; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\TypedData\DataDefinition; +use Drupal\filter\Render\FilteredMarkup; use Drupal\KernelTests\KernelTestBase; use Drupal\file\Entity\File; use Drupal\filter\Entity\FilterFormat; @@ -291,6 +292,7 @@ class DataFilterTest extends KernelTestBase { * @covers \Drupal\typed_data\Plugin\TypedDataFilter\StripTagsFilter */ public function testStripTagsFilter(): void { + $htmlString = '<b>Test <em>striptags</em> filter</b>'; $filter = $this->dataFilterManager->createInstance('striptags'); $data = $this->typedDataManager->create(DataDefinition::create('string'), '<b>Test <em>striptags</em> filter</b>'); @@ -302,6 +304,17 @@ class DataFilterTest extends KernelTestBase { $this->assertEquals('Test striptags filter', $filter->filter($data->getDataDefinition(), $data->getValue(), [])); } + /** + * @covers \Drupal\typed_data\Plugin\TypedDataFilter\StripTagsFilter + */ + public function testStripTagsFilterWithFilteredMarkup(): void { + $filter = $this->dataFilterManager->createInstance('striptags'); + $data = $this->typedDataManager->create(DataDefinition::create('string'), FilteredMarkup::create('<b>Test <em>striptags</em> filter</b>')); + + $this->assertTrue($filter->canFilter($data->getDataDefinition())); + $this->assertEquals('Test striptags filter', $filter->filter($data->getDataDefinition(), $data->getValue(), [])); + } + /** * @covers \Drupal\typed_data\Plugin\TypedDataFilter\EntityUrlFilter */ -- GitLab From 941752ac256ce857d18976c47e5f2f6679906e51 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Mon, 13 Jan 2025 10:14:55 +0100 Subject: [PATCH 3/8] Remove unused variable. --- tests/src/Kernel/DataFilterTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/src/Kernel/DataFilterTest.php b/tests/src/Kernel/DataFilterTest.php index b09487c..416db2e 100644 --- a/tests/src/Kernel/DataFilterTest.php +++ b/tests/src/Kernel/DataFilterTest.php @@ -292,7 +292,6 @@ class DataFilterTest extends KernelTestBase { * @covers \Drupal\typed_data\Plugin\TypedDataFilter\StripTagsFilter */ public function testStripTagsFilter(): void { - $htmlString = '<b>Test <em>striptags</em> filter</b>'; $filter = $this->dataFilterManager->createInstance('striptags'); $data = $this->typedDataManager->create(DataDefinition::create('string'), '<b>Test <em>striptags</em> filter</b>'); -- GitLab From 6836cb6afbba3e84f09e95a83f668564a33f41d3 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Mon, 13 Jan 2025 10:20:06 +0100 Subject: [PATCH 4/8] Create typed data from the value and definition and use getCastedValue() instead of built-in cast. --- src/Plugin/TypedDataFilter/StripTagsFilter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Plugin/TypedDataFilter/StripTagsFilter.php b/src/Plugin/TypedDataFilter/StripTagsFilter.php index 16fe0de..609ad19 100644 --- a/src/Plugin/TypedDataFilter/StripTagsFilter.php +++ b/src/Plugin/TypedDataFilter/StripTagsFilter.php @@ -30,7 +30,9 @@ class StripTagsFilter extends DataFilterBase { * {@inheritdoc} */ public function filter(DataDefinitionInterface $definition, $value, array $arguments, ?BubbleableMetadata $bubbleable_metadata = NULL) { - return strip_tags((string) $value); + /** @var \Drupal\Core\TypedData\Type\StringInterface $data */ + $data = $this->typedDataManager->create($definition, $value); + return strip_tags($data->getCastedValue()); } /** -- GitLab From ccbdac0900b15afa7d8772f0fe9b75879b27aaf3 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Mon, 13 Jan 2025 10:31:23 +0100 Subject: [PATCH 5/8] Add prepareValue() method that returns the casted value for the typed data. --- src/DataFilterBase.php | 10 ++++++++++ src/DataFilterInterface.php | 17 +++++++++++++++++ src/Plugin/TypedDataFilter/StripTagsFilter.php | 4 +--- 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/DataFilterBase.php b/src/DataFilterBase.php index a1bdae2..86c8d9f 100644 --- a/src/DataFilterBase.php +++ b/src/DataFilterBase.php @@ -7,6 +7,8 @@ namespace Drupal\typed_data; use Drupal\Component\Plugin\PluginBase; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\DataDefinitionInterface; +use Drupal\Core\TypedData\PrimitiveInterface; +use Drupal\Core\TypedData\TypedDataInterface; use Drupal\Core\TypedData\TypedDataTrait; /** @@ -39,6 +41,14 @@ abstract class DataFilterBase extends PluginBase implements DataFilterInterface $this->pluginDefinition = $plugin_definition; } + /** + * {@inheritDoc} + */ + public function prepareValue(DataDefinitionInterface $definition, $value) { + $data = $this->typedDataManager->create($definition, $value); + return $data instanceof PrimitiveInterface ? $data->getCastedValue() : $value; + } + /** * {@inheritdoc} */ diff --git a/src/DataFilterInterface.php b/src/DataFilterInterface.php index 644a78a..ab5d14e 100644 --- a/src/DataFilterInterface.php +++ b/src/DataFilterInterface.php @@ -4,6 +4,7 @@ namespace Drupal\typed_data; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\TypedData\DataDefinitionInterface; +use Drupal\Core\TypedData\TypedDataInterface; /** * Interface for data filters. @@ -57,6 +58,22 @@ interface DataFilterInterface { */ public function filtersTo(DataDefinitionInterface $definition, array $arguments): DataDefinitionInterface; + /** + * Prepares a value to match the provided DataDefinition. + * + * If the typed data does not implement the PrimitiveInterface, the value will + * be returned as is, without being casted. + * + * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition + * The definition of the filtered data. + * @param $value + * The value from which to created the typed data object. + * + * @return mixed + * The cast value. + */ + public function prepareValue(DataDefinitionInterface $definition, $value); + /** * Gets the number of required arguments. * diff --git a/src/Plugin/TypedDataFilter/StripTagsFilter.php b/src/Plugin/TypedDataFilter/StripTagsFilter.php index 609ad19..a3c7df0 100644 --- a/src/Plugin/TypedDataFilter/StripTagsFilter.php +++ b/src/Plugin/TypedDataFilter/StripTagsFilter.php @@ -30,9 +30,7 @@ class StripTagsFilter extends DataFilterBase { * {@inheritdoc} */ public function filter(DataDefinitionInterface $definition, $value, array $arguments, ?BubbleableMetadata $bubbleable_metadata = NULL) { - /** @var \Drupal\Core\TypedData\Type\StringInterface $data */ - $data = $this->typedDataManager->create($definition, $value); - return strip_tags($data->getCastedValue()); + return strip_tags($this->prepareValue($definition, $value)); } /** -- GitLab From 45083d18db1658f59c82d022f227ea68ea822cfb Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Mon, 13 Jan 2025 10:37:09 +0100 Subject: [PATCH 6/8] Use getTypedDataManager() method instead of member. --- src/DataFilterBase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/DataFilterBase.php b/src/DataFilterBase.php index 86c8d9f..4722a4d 100644 --- a/src/DataFilterBase.php +++ b/src/DataFilterBase.php @@ -45,7 +45,7 @@ abstract class DataFilterBase extends PluginBase implements DataFilterInterface * {@inheritDoc} */ public function prepareValue(DataDefinitionInterface $definition, $value) { - $data = $this->typedDataManager->create($definition, $value); + $data = $this->getTypedDataManager()->create($definition, $value); return $data instanceof PrimitiveInterface ? $data->getCastedValue() : $value; } -- GitLab From e5de9666ec1757e9477fa42c0165dab95317bab7 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Sat, 25 Jan 2025 10:05:51 +0100 Subject: [PATCH 7/8] Revert to an ordinary string cast, add text for processed text. --- src/DataFilterBase.php | 8 -------- src/DataFilterInterface.php | 16 --------------- .../TypedDataFilter/StripTagsFilter.php | 2 +- tests/src/Kernel/DataFilterTest.php | 20 +++++++++++++++++++ 4 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/DataFilterBase.php b/src/DataFilterBase.php index 4722a4d..6b502ec 100644 --- a/src/DataFilterBase.php +++ b/src/DataFilterBase.php @@ -41,14 +41,6 @@ abstract class DataFilterBase extends PluginBase implements DataFilterInterface $this->pluginDefinition = $plugin_definition; } - /** - * {@inheritDoc} - */ - public function prepareValue(DataDefinitionInterface $definition, $value) { - $data = $this->getTypedDataManager()->create($definition, $value); - return $data instanceof PrimitiveInterface ? $data->getCastedValue() : $value; - } - /** * {@inheritdoc} */ diff --git a/src/DataFilterInterface.php b/src/DataFilterInterface.php index ab5d14e..22e5d66 100644 --- a/src/DataFilterInterface.php +++ b/src/DataFilterInterface.php @@ -58,22 +58,6 @@ interface DataFilterInterface { */ public function filtersTo(DataDefinitionInterface $definition, array $arguments): DataDefinitionInterface; - /** - * Prepares a value to match the provided DataDefinition. - * - * If the typed data does not implement the PrimitiveInterface, the value will - * be returned as is, without being casted. - * - * @param \Drupal\Core\TypedData\DataDefinitionInterface $definition - * The definition of the filtered data. - * @param $value - * The value from which to created the typed data object. - * - * @return mixed - * The cast value. - */ - public function prepareValue(DataDefinitionInterface $definition, $value); - /** * Gets the number of required arguments. * diff --git a/src/Plugin/TypedDataFilter/StripTagsFilter.php b/src/Plugin/TypedDataFilter/StripTagsFilter.php index a3c7df0..16fe0de 100644 --- a/src/Plugin/TypedDataFilter/StripTagsFilter.php +++ b/src/Plugin/TypedDataFilter/StripTagsFilter.php @@ -30,7 +30,7 @@ class StripTagsFilter extends DataFilterBase { * {@inheritdoc} */ public function filter(DataDefinitionInterface $definition, $value, array $arguments, ?BubbleableMetadata $bubbleable_metadata = NULL) { - return strip_tags($this->prepareValue($definition, $value)); + return strip_tags((string) $value); } /** diff --git a/tests/src/Kernel/DataFilterTest.php b/tests/src/Kernel/DataFilterTest.php index 416db2e..7d12cb2 100644 --- a/tests/src/Kernel/DataFilterTest.php +++ b/tests/src/Kernel/DataFilterTest.php @@ -8,11 +8,13 @@ use Drupal\Core\Datetime\Entity\DateFormat; use Drupal\Core\Entity\TypedData\EntityDataDefinition; use Drupal\Core\Render\BubbleableMetadata; use Drupal\Core\TypedData\DataDefinition; +use Drupal\filter\FilterProcessResult; use Drupal\filter\Render\FilteredMarkup; use Drupal\KernelTests\KernelTestBase; use Drupal\file\Entity\File; use Drupal\filter\Entity\FilterFormat; use Drupal\node\Entity\Node; +use Drupal\text\TextProcessed; /** * Tests using typed data filters. @@ -314,6 +316,24 @@ class DataFilterTest extends KernelTestBase { $this->assertEquals('Test striptags filter', $filter->filter($data->getDataDefinition(), $data->getValue(), [])); } + /** + * @covers \Drupal\typed_data\Plugin\TypedDataFilter\StripTagsFilter + */ + public function testStripTagsFilterWithProcessedtext(): void { + $filter = $this->dataFilterManager->createInstance('striptags'); + + $dataDefinition = DataDefinition::create('string'); + $dataDefinition->setComputed(TRUE); + $dataDefinition->setClass(TextProcessed::class); + $dataDefinition->setSetting('text source', 'value'); + + $value = new FilterProcessResult('<b>Test <em>striptags</em> filter</b>'); + $data = $this->typedDataManager->create($dataDefinition, $value); + + $this->assertTrue($filter->canFilter($data->getDataDefinition())); + $this->assertEquals('Test striptags filter', $filter->filter($data->getDataDefinition(), $data->getValue(), [])); + } + /** * @covers \Drupal\typed_data\Plugin\TypedDataFilter\EntityUrlFilter */ -- GitLab From b7ffc356438d832af929d360057355e0bfd67089 Mon Sep 17 00:00:00 2001 From: Mihael Wagner <mihael.wagner@agiledrop.com> Date: Sat, 25 Jan 2025 10:31:42 +0100 Subject: [PATCH 8/8] Modify canFilter() in striptags filter to also allow for TextProcessed instances. --- src/Plugin/TypedDataFilter/StripTagsFilter.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Plugin/TypedDataFilter/StripTagsFilter.php b/src/Plugin/TypedDataFilter/StripTagsFilter.php index 16fe0de..26bbc30 100644 --- a/src/Plugin/TypedDataFilter/StripTagsFilter.php +++ b/src/Plugin/TypedDataFilter/StripTagsFilter.php @@ -9,6 +9,7 @@ use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\TypedData\DataDefinition; use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\Type\StringInterface; +use Drupal\text\TextProcessed; use Drupal\typed_data\Attribute\DataFilter; use Drupal\typed_data\DataFilterBase; @@ -37,7 +38,8 @@ class StripTagsFilter extends DataFilterBase { * {@inheritdoc} */ public function canFilter(DataDefinitionInterface $definition): bool { - return is_subclass_of($definition->getClass(), StringInterface::class); + return is_subclass_of($definition->getClass(), StringInterface::class) + || is_a($definition->getClass(), TextProcessed::class, TRUE); } /** -- GitLab