Problem/Motivation

When a node has an entity reference which allows multiple values a PHP error is thrown when the node create form is displayed. This was fine in Drupal 10.1.7 but fails in Drupal 10.2.0.

Error:

TypeError: strlen(): Argument #1 ($string) must be of type string, array given in strlen() (line 395 of /code/web/core/lib/Drupal/Component/Utility/Unicode.php).
#0 /var/lib/tugboat/stm/web/core/lib/Drupal/Component/Utility/Unicode.php(395): strlen(Array)
#1 /var/lib/tugboat/stm/web/core/lib/Drupal/Component/Utility/Xss.php(65): Drupal\Component\Utility\Unicode::validateUtf8(Array)
#2 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(829): Drupal\Component\Utility\Xss::filter(Array, Array)
#3 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(427): Drupal\Core\Render\Renderer->ensureMarkupIsSafe(Array)
#4 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender(Array, false)
#5 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Template/TwigExtension.php(475): Drupal\Core\Render\Renderer->render(Array)
#6 /var/lib/tugboat/stm/web/sites/default/files/php/twig/657fb1296416e_table.html.twig_ZNK6eE18Qtv5NTjCJ09A_UAwu/6pezqUwoEcav3sCYQwIahtNpcsnsIr45c7ps28ugXQo.php(132): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true)
#7 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(394): __TwigTemplate_5242cfb9459fe4f4a405164ed3106cd9->doDisplay(Array, Array)
#8 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#9 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(379): Twig\Template->display(Array)
#10 /var/lib/tugboat/stm/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render(Array)
#11 /var/lib/tugboat/stm/web/core/themes/engines/twig/twig.engine(39): Twig\TemplateWrapper->render(Array)
#12 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template('themes/contrib/...', Array)
#13 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(480): Drupal\Core\Theme\ThemeManager->render('table', Array)
#14 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender(Array, false)
#15 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Template/TwigExtension.php(475): Drupal\Core\Render\Renderer->render(Array)
#16 /var/lib/tugboat/stm/web/sites/default/files/php/twig/657fb1296416e_field-multiple-value-form_2b503Zb8dN0hT5YLOFgKgdfAq/rCqc4iaHq7l3nE2y3uf401VAXPei8guFGjhLWRiu5E8.php(44): Drupal\Core\Template\TwigExtension->escapeFilter(Object(Drupal\Core\Template\TwigEnvironment), Array, 'html', NULL, true)
#17 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(394): __TwigTemplate_da57364eaa41b4e152231b7a02653a7d->doDisplay(Array, Array)
#18 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(367): Twig\Template->displayWithErrorHandling(Array, Array)
#19 /var/lib/tugboat/stm/vendor/twig/twig/src/Template.php(379): Twig\Template->display(Array)
#20 /var/lib/tugboat/stm/vendor/twig/twig/src/TemplateWrapper.php(38): Twig\Template->render(Array)
#21 /var/lib/tugboat/stm/web/core/themes/engines/twig/twig.engine(39): Twig\TemplateWrapper->render(Array)
#22 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Theme/ThemeManager.php(348): twig_render_template('themes/contrib/...', Array)
#23 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(480): Drupal\Core\Theme\ThemeManager->render('field_multiple_...', Array)
#24 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender(Array)
#25 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(493): Drupal\Core\Render\Renderer->doRender(Array)
#26 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(240): Drupal\Core\Render\Renderer->doRender(Array, false)
#27 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(238): Drupal\Core\Render\Renderer->render(Array, false)
#28 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/Renderer.php(627): Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}()
#29 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(239): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#30 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/Render/MainContent/HtmlRenderer.php(128): Drupal\Core\Render\MainContent\HtmlRenderer->prepare(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#31 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/EventSubscriber/MainContentViewSubscriber.php(90): Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse(Array, Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\CurrentRouteMatch))
#32 [internal function]: Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#33 /var/lib/tugboat/stm/web/core/lib/Drupal/Component/EventDispatcher/ContainerAwareEventDispatcher.php(111): call_user_func(Array, Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view', Object(Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher))
#34 /var/lib/tugboat/stm/vendor/symfony/http-kernel/HttpKernel.php(186): Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch(Object(Symfony\Component\HttpKernel\Event\ViewEvent), 'kernel.view')
#35 /var/lib/tugboat/stm/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#36 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/Session.php(58): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#37 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#38 /var/lib/tugboat/stm/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#39 /var/lib/tugboat/stm/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#40 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#41 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#42 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#43 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#44 /var/lib/tugboat/stm/web/core/lib/Drupal/Core/DrupalKernel.php(704): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#45 /var/lib/tugboat/stm/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#46 {main}

Steps to reproduce

  1. Drupal 10.2.0 standard install profile with bootstrap 3.29.
  2. Ensure bootstrap theme active for creating content - either login as a non-admin user or disable Use the administration theme when editing or creating content at /admin/appearance.
  3. Edit the article structure to add a new field:
    1. Label = Users
    2. Field type = Reference
    3. Reference type = User
    4. Rest as default
  4. Add article content (/node/add/article) - page loads OK.
  5. Go back to the Users field settings and set the Allowed number of values to a value > 1 or Unlimited.
  6. Add article content (/node/add/article) - page fails to load and PHP error is observed in log.

Proposed resolution

The problem as I understand it is there are some fields which have no heading but the theme expects one in /templates/system/table.html.twig. By checking for a suitable value the problem is resolved:

89c89,91
<         {{- cell.content -}}
---
>         {% if cell.content['#value'] or (cell.content['#markup']) %}
>           {{- cell.content -}}
>         {% endif %}

However the standard Claro theme has no problem and has the same twig above so there must be somewhere else that's setting a value (empty string).

Issue fork bootstrap-3409370

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

gaddman created an issue. See original summary.

viren18febS made their first commit to this issue’s fork.

viren18febs’s picture

Hi @gaddman
i have added a patch for the changes .Please review
Thanks

viren18febs’s picture

Status: Active » Needs review
gaddman’s picture

Status: Needs review » Active

Yeah, that works, I just wasn't sure if that's the right solution since the Claro theme doesn't do that. As an example, editing web/themes/contrib/bootstrap/src/Plugin/Preprocess/FieldMultipleValueForm.php also avoids the problem:

          if (is_array($header_row) && isset($header_row['data'])) {
            $header_row['data'] = is_array($header_row['data']) ? ($prefixes + $header_row['data']) : ($prefixes + ['#markup' => $header_row['data']]);
+         } elseif (empty($header_row)) {
+           $header_row = ['data' => $prefixes];
          } else {
            $header_row = ['data' => $prefixes + ['#markup' => $header_row]];
          }

sakthi_dev made their first commit to this issue’s fork.

sakthi_dev’s picture

Status: Active » Needs review

Hi @viren18febs from the backend we have else condition that might not require.

gaddman’s picture

Title: PHP error when form has entity reference » PHP error when form has entity reference in Drupal 10.2.0
Status: Needs review » Active

Just confirming that on Drupal 10.1.7 this issue isn't present.

easp’s picture

I applied patch #3 and it fixed my node edit error.

Now I am having problems with table form types:

$form['report_result_wrapper']['sales'] = [
'#type' => 'table',
'#header' => $header,
'#rows' => $rows,
'#empty' => t('Nothing found'),
'#attributes' => ['class' => ['report-results-table', 'sticky-header', 'table-condensed']],
'#sticky' => TRUE,
];

All header and rows display as empty.

gaddman’s picture

@easp what if you edit as per my comment #5 (retaining the original else condition)?

easp’s picture

Comment #5 appears to have corrected the node edit error and now table form types display correctly.

klemendev’s picture

#12 (based on comment #5) seems to fix this problem for me

klemendev’s picture

Status: Active » Reviewed & tested by the community
danchadwick’s picture

+1 on RTBC. I have this problem not with an entity reference but with a table I'm generating which has empty column headers.

gaddman’s picture

Status: Reviewed & tested by the community » Needs review

I misread @easp's comment #10 so just realising now that @sakthi_dev's MR32 in comment #7 (patch link) hasn't been tested. It's a simpler fix than my proposal (@easp's patch #12) so would be good to see if there's any downside of that approach. Fixes the issue for me and hasn't broken anything obvious I can see.

klemendev’s picture

I can confirm the MR fixes the bug for our websites and does not seem to introduce any additional regressions.

klemendev’s picture

Status: Needs review » Reviewed & tested by the community
klemendev’s picture

Could any maintainer merge this into a release? This issue could be preventing people from updating to 10.2.x unless they opt to use a patch

klemendev’s picture

Priority: Normal » Major
gaddman’s picture

Issue summary: View changes
gaddman’s picture

Issue summary: View changes
stopopol’s picture

+1

runbits’s picture

We can confirm the original bug report on Drupal 10.2.1 under PHP 8.1.27.
And more importantly, can confirm the crash is fixed after applying a patch for the changes that MR32 makes (https://git.drupalcode.org/project/bootstrap/-/merge_requests/32.patch).

klemendev’s picture

I can now confirm RTBC based on 2-week running experiment on one of the sites, LGTM

liam morland’s picture

Version: 8.x-3.29 » 8.x-3.x-dev
Status: Reviewed & tested by the community » Needs review
StatusFileSize
new894 bytes

The TypeError is because #markup is not a string. The patch in #12 does fix that problem for me, but it does not ensure that #markup is always a string. It could break in other situations, ending up an a non-empty array without a data key or an integer, for example. The patch in this issue ensures it is a string.

I have also updated the issue fork with the change in this patch.

Status: Needs review » Needs work
liam morland’s picture

Status: Needs work » Needs review

Test did not fail.

stopopol’s picture

Applied the patch which fixed the issue.

TomChiverton’s picture

https://git.drupalcode.org/project/bootstrap/-/merge_requests/32.patch fixes it for me too. Can we get it merged and deployed ?

klemendev’s picture

Status: Needs review » Reviewed & tested by the community
aaronbauman’s picture

RTBC+1 for MR 32

beatnikdude’s picture

Likewise RTBC+1 for MR 32

stevenjay’s picture

patch in #27 fixes issue for me

jordik’s picture

MR 32 solved the issue for me. RTBC+1

pappis’s picture

Patch in #27 fixes issue for me too.

This was a scary bug.
Took me some time until google sent me to this page.

shelane made their first commit to this issue’s fork.

  • shelane committed 41126d52 on 8.x-3.x authored by sakthi_dev
    Issue #3409370 by Liam Morland, gaddman: PHP error when form has entity...
shelane’s picture

Status: Reviewed & tested by the community » Fixed

Thanks. Sorry, I have been out sick for a while. It has taken me some time to get well and get to this.

Status: Fixed » Closed (fixed)

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

ainsofs’s picture

#27 worked for me too. Was in same boat as #37