Problem/Motivation
WebformAccessBreadcrumbBuilder::applies() passes the result of
RouteMatchInterface::getRouteName() straight to str_contains().
That method is documented to return string|null — "NULL if no route is matched" —
and passing NULL to a string parameter has been deprecated since PHP 8.1. Every enabled breadcrumb
builder is asked whether it applies, so on a route-less match sites with webform_access
enabled log:
Deprecated function: str_contains(): Passing null to parameter #1 ($haystack) of type string is deprecated
This is the unfinished half of
#3158332. That issue
(fixed in 2020, commit 9863ce8) reported this exact builder blowing up during Solr
search indexing, because entities were being rendered in a context with no route. The fix added:
if (!$route_match->getRouteObject()) {
return FALSE;
}…but placed it after the route-name check rather than before it. On PHP 7 that
ordering was harmless, since strpos(NULL, ...) simply worked. Once PHP 8.1 deprecated
passing NULL to a string parameter, the very first line — the one #3158332 did not touch —
started emitting a deprecation in precisely the scenario #3158332 documented. The guard is one line
too late.
The sibling WebformBreadcrumbBuilder::applies() already has the correct form,
if (!$route_name || !str_contains($route_name, 'webform')), and
WebformBreadcrumbBuilderTest::providerTestApplies() already covers the NULL route name
case (its first data set, [FALSE], relies on the ?string $route_name = NULL
default). The access variant was never brought in line.
Steps to reproduce
Any render of an entity without a route match will do — search indexing is the real-world
case documented in #3158332. Minimal deterministic reproduction:
- Install Drupal 11.4 on PHP 8.3 and enable
webformandwebform_access. - Build a route match that matched no route and ask the builder whether it applies:
$request = \Symfony\Component\HttpFoundation\Request::create('/this-path-does-not-exist'); $route_match = \Drupal\Core\Routing\RouteMatch::createFromRequest($request); // getRouteName() is NULL here. \Drupal::service('webform_access.breadcrumb')->applies($route_match); - Observe the deprecation notice. It also appears in dblog on ordinary 404 responses.
Proposed resolution
Guard the route name before the str_contains() call, using exactly the same
expression the sibling WebformBreadcrumbBuilder already uses:
if (!$route_name || !str_contains($route_name, 'webform_access')) {A NULL or empty route name can never contain webform_access, so the method still
returns FALSE and behaviour is unchanged for every route that previously matched.
Remaining tasks
- Review the merge request.
- Optional: add a unit test for
WebformAccessBreadcrumbBuildermirroring
WebformBreadcrumbBuilderTest::testApplies();webform_accesscurrently
has no breadcrumb test coverage at all. A[FALSE]data set (NULL route name) would
have caught this.
AI-Generated: Yes (used to draft the fix and this issue summary, reviewed and tested by me.)
Issue fork webform-3623528
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
Comment #3
vas-alyfantis commentedComment #4
liam morlandThe merge request contains no proposed changes to review.
Comment #5
vas-alyfantis commentedApologies, the branch is now updated and contains the suggested proposed fix
Comment #6
vas-alyfantis commented