- Issue created by @miha.wagner
- Merge request !39#3498774 Explicitly cast $value to string in StripTagsFilter plugin. → (Open) created by miha.wagner
- 🇺🇸United States tr CascadiaOK. Can you add a few asserts to the DataFilterTest to test this use case? Right now it just tests passing a literal string. This should be enhanced to check a Stringable object. 
- 🇸🇮Slovenia miha.wagnerI've added a test case to test with a $value of FilteredMarkup. Though this begs the question, if the value is being cast to a string via an explicit cast, maybe it would also make sense to check if the value implements __toString() or implements \Stringable in the canFilter method? 
- 🇺🇸United States tr CascadiaThanks for the test. As expected, the new test passes with your changes, and also as expected the test-only (without the other changes) fails (see the test output). That's a good sign. Note: you didn't use the $htmlStringvariable you defined...Yes, I intended that canFilter()should be changed, if necessary. ButcanFilter()is checking on the core Drupal data type via theDataDefinition, not on the PHP data type. I think the core 'string' data type should be sufficient here.But one thing about the test: $data = $this->typedDataManager->create(DataDefinition::create('string'), FilteredMarkup::create('<b>Test <em>striptags</em> filter</b>')); $this->assertEquals('Test striptags filter', $filter->filter($data->getDataDefinition(), $data->getValue(), []))Looking at this and the other data filter tests makes me question a few things about how all the data filters are implemented. Your original issue seems to indicate that there's a bigger problem here that needs more than just a type cast to fix. In this case, I would have expected that $datais of the 'string' data type, and that when initialized with aFilteredMarkup, there would be some internal casting or coercion to change theFilteredMarkupinto a string data type. But that doesn't seem to be the case because$data->getValue()returns aFilteredMarkupinstead of a string. That's part of the core string DataType, and suggests to me maybe we should be using$data->getCastedValue()in all these data filters AND inPlaceholderResolverrather than$data->getValue().In all the tests, filter()is called with$data->getDataDefinition()and$data->getValue(), but there is nothing that prevents the caller passing two parameters that have nothing to do with each other, like$first_data->getDataDefinition()and$second_data->getValue(). The only placefilter()is called is insidePlaceholderResolver, where these two values are always taken from the same variable$data, but that's not guaranteed iffilter()is called from any other place or any other module.Likewise, filtersTo()is returning a 'string'DataDefinitionobject. So what I would expectfilter()to return is a TypedData object of that type. But insteadfilter()in this case is returning a simple PHP string. But that's probably best left for a different issue, because changing the return type offilter()could have a lot of consequences.So the above patch is doing a cast inside of filter($definition, $value), which is making the assumptions that:
 1)$definitionis of type 'string'
 2)$valuecan be cast to a 'string'Instead, I think ALL the data filters should be doing something like this: public function filter(DataDefinitionInterface $definition, $value, array $arguments, ?BubbleableMetadata $bubbleable_metadata = NULL) { $data = $this->typedDataManager->create($definition, $value) ; return strip_tags($data->getCastedValue()); }You see what I am doing? Instead of assuming that $definitionand$valueare related to each other, I force$valueto be treated like$definition. Do you think this makes sense?
- 🇸🇮Slovenia miha.wagnerYes that makes sense. I've gone ahead and changed that. If the other filters will also be doing it like this then I thought it 
 made sense to do the preparing of the value in the base class. What do you think about that change?
- Assigned to miha.wagner