Text filter should return a string, not a Markup object

Created on 9 October 2023, about 1 year ago
Updated 13 February 2024, 10 months ago

Problem/Motivation

The CollapseText filter plugin sets the processed text to a Markup object instead of a string. Other filter plugins expect a string and may operate on the text as if it were, which can cause fatal PHP errors. This is true even though Markup can be converted to a string easily.

FilterInterface, which all text filters implement, indicates that the process function of the filter plugin should return a string.

Steps to reproduce

  1. In a text format, enable the "Collapsible text blocks" filter (provided by this module), followed by the "Lazy load images" filter (provided by Drupal 10.1 in #3247795: Add text filter plugin to support and remove it from editor_file_reference β†’ )
  2. Add collapse text to a text field that uses that text format
  3. Observe that a fatal PHP error is thrown "TypeError: stripos(): Argument #1 ($haystack) must be of type string, Drupal\Core\Render\Markup given"

Proposed resolution

Simply cast the rendered Markup object to a string before returning.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Fixed

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @bkosborne
  • Status changed to Needs review about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA
  • πŸ‡·πŸ‡ΈSerbia levmyshkin Novi Sad, Serbia

    It's working for me: Drupal 10.1.2, Collapse Text 2.0.0

  • Status changed to RTBC about 1 year ago
  • πŸ‡ΊπŸ‡ΈUnited States bkosborne New Jersey, USA
  • πŸ‡ͺπŸ‡ΈSpain dioni

    Attached the .patch, thanks @bkosborne

  • Status changed to Fixed 11 months ago
  • πŸ‡«πŸ‡·France dydave

    Hi Brian (@bkosborne),

    Thanks again very much for your great help on this, it's greatly appreciated.

    Just a quick message to let you know the changes from related !MR3 have been committed manually at #7 with a slightly updated commit message (from the MR).

    Otherwise, I have tested this locally and it worked as expected :
    I created a node with the Collapse Text markup in Full HTML and moved the filter Collapsible text blocks right above the Lazy load images, as suggested in the issue summary.
    After refreshing a node page with collapse text content, the following error appeared:

    The website encountered an unexpected error. Try again later.
    
    TypeError: stripos(): Argument #1 ($haystack) must be of type string, Drupal\Core\Render\Markup given in stripos() (line 31 of core/modules/filter/src/Plugin/Filter/FilterImageLazyLoad.php).
    Drupal\filter\Plugin\Filter\FilterImageLazyLoad->process(Object, 'en') (Line: 118)
    Drupal\filter\Element\ProcessedText::preRenderText(Array)
    call_user_func_array(Array, Array) (Line: 111)
    Drupal\Core\Render\Renderer->doTrustedCallback(Array, Array, 'Render #pre_render callbacks must be methods of a class that implements \Drupal\Core\Security\TrustedCallbackInterface or be an anonymous function. The callback was %s. See https://www.drupal.org/node/2966725', 'exception', 'Drupal\Core\Render\Element\RenderCallbackInterface') (Line: 858)
    Drupal\Core\Render\Renderer->doCallback('#pre_render', Array, Array) (Line: 421)
    Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 240)
    Drupal\Core\Render\Renderer->render(Array) (Line: 475)
    Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 88)
    __TwigTemplate_3fe1a6925ac55df2dcc0b507a451e16c->doDisplay(Array, Array) (Line: 394)
    Twig\Template->displayWithErrorHandling(Array, Array) (Line: 367)
    Twig\Template->display(Array, Array) (Line: 46)
    __TwigTemplate_f30e847664dc7313311f7b5f269e3cec->doDisplay(Array, Array) (Line: 394)
    Twig\Template->displayWithErrorHandling(Array, Array) (Line: 367)
    Twig\Template->display(Array, Array) (Line: 43)
    __TwigTemplate_2b95f2567c5ed02a628d1f559a79016a->doDisplay(Array, Array) (Line: 394)
    Twig\Template->displayWithErrorHandling(Array, Array) (Line: 367)
    Twig\Template->display(Array) (Line: 379)
    Twig\Template->render(Array) (Line: 38)
    Twig\TemplateWrapper->render(Array) (Line: 39)
    twig_render_template('core/themes/olivero/templates/field/field--text-with-summary.html.twig', Array) (Line: 348)
    Drupal\Core\Theme\ThemeManager->render('field', Array) (Line: 480)
    Drupal\Core\Render\Renderer->doRender(Array) (Line: 493)
    Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 240)
    Drupal\Core\Render\Renderer->render(Array) (Line: 475)
    Drupal\Core\Template\TwigExtension->escapeFilter(Object, Array, 'html', NULL, 1) (Line: 135)
    __TwigTemplate_a9b34a8fde9573e53e43081bbf05e4ab->doDisplay(Array, Array) (Line: 394)
    Twig\Template->displayWithErrorHandling(Array, Array) (Line: 367)
    Twig\Template->display(Array) (Line: 379)
    Twig\Template->render(Array) (Line: 38)
    Twig\TemplateWrapper->render(Array) (Line: 39)
    twig_render_template('core/themes/olivero/templates/content/node.html.twig', Array) (Line: 348)
    Drupal\Core\Theme\ThemeManager->render('node', Array) (Line: 480)
    Drupal\Core\Render\Renderer->doRender(Array, ) (Line: 240)
    Drupal\Core\Render\Renderer->render(Array, ) (Line: 238)
    Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 627)
    Drupal\Core\Render\Renderer->executeInRenderContext(Object, Object) (Line: 239)
    Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object, Object) (Line: 128)
    Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object, Object) (Line: 90)
    Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object, 'kernel.view', Object)
    call_user_func(Array, Object, 'kernel.view', Object) (Line: 111)
    Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object, 'kernel.view') (Line: 186)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object, 1) (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle(Object, 1, 1) (Line: 58)
    Drupal\Core\StackMiddleware\Session->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object, 1, 1) (Line: 28)
    Drupal\Core\StackMiddleware\ContentLength->handle(Object, 1, 1) (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass(Object, 1, 1) (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle(Object, 1, 1) (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object, 1, 1) (Line: 36)
    Drupal\Core\StackMiddleware\AjaxPageState->handle(Object, 1, 1) (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object, 1, 1) (Line: 704)
    Drupal\Core\DrupalKernel->handle(Object) (Line: 19)
    

    After applying the patch, the error disappeared and the page displayed fine.

    Once again, thank you very much for keeping an eye on the module and fixing issues as they come.

    Feel free to let us know at any time if you have any questions, concerns, suggestions or comments on any of the recent code changes, this ticket, or the module in general, we would be glad to help.
    Thanks again to everyone for your contributions, testing and feedback.
    Cheers !

  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024