Empty query params on source cause TypeError

Created on 18 October 2022, about 2 years ago
Updated 5 April 2023, almost 2 years ago

Problem/Motivation

As mentioned in the Comment I have got the same issue but with fatal error instead of warning. On php 8.1, when a redirect with no query params exists and Patch or Patch 2 📌 Make views dependency optional Needs work applied, visiting the list results in

The website encountered an unexpected error. Please try again later.
TypeError: array_walk(): Argument #1 ($array) must be of type array, null given in array_walk() (line 120 of core/lib/Drupal/Core/Utility/LinkGenerator.php).

Warning is on php < 8 and fatal error on php > 8

Code snippet from sandbox that illustrates the issue Sandbox

In the redirect source field serialized value of path and query params is stored.

Steps to reproduce

- Apply one of linked patches
- Create a redirect with no query params

Proposed resolution

- Save non existing query params as empty array instead of NULL

Remaining tasks

- Tests

🐛 Bug report
Status

Needs work

Version

1.8

Component

Code

Created by

🇸🇮Slovenia kbrodej

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

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • I encountered this problem after upgrading to php8, but when I used the patch package in composer.json, I was prompted that I could not apply it. I used the composer install -vvv command to get an error: can't find file to patch at input line 6 ; I did not find the file redirect.post_update.php; My project is drupal9.4.8, PHP8.

  • Assigned to River Zhao
  • Status changed to Needs review almost 2 years ago
  • None of these fixes solved my problem, nor could I even apply the fix; I found another one, but it was so old that while his modification fixed the problem, it also couldn't be applied, so I Decided to upload a patch pack myself.
    First describe my problem: my error is the same as here, and it is also caused by the upgrade of PHP to 8. I actually encountered an error when visiting /admin/config/search/redirect.

  • Issue was unassigned.
  • Status changed to Needs work almost 2 years ago
  • 🇨🇭Switzerland berdir Switzerland

    @River Zhao: Your patch is for core and doesn't belong here.

    1. +++ b/redirect.post_update.php
      @@ -0,0 +1,37 @@
      +  foreach ($ids as $id) {
      +    $redirect = $storage->load($id);
      +    $values = $redirect->get('redirect_source')->getValue();
      +    if (empty($values[0]['query'])) {
      +      $values[0]['query'] = [];
      

      It's not quite clear to me why this does another empty check since you query for that already. If anything it would need to be an isset() && ==== NULL check? empty returns TRUE both if the key isn't set at all and if it's an empty array, so that doesn't do much.

      Also, you can just access the query with $redirect->get('redirect_source')->query and set it in the same way, makes this a lot simpler.

    2. +++ b/src/Entity/Redirect.php
      @@ -90,6 +90,12 @@ class Redirect extends ContentEntityBase {
       
      +    $values = $this->get('redirect_source')->getValue();
      +    if (empty($values[0]['query'])) {
      +      $values[0]['query'] = [];
      +      $this->set('redirect_source', $values);
      +    }
      +
           // Get the language code directly from the field as language() might not
      

      I can't reproduce this error, what exactly is the backtrace?

      Instead of here, I would suggest that we handle this in \Drupal\redirect\Plugin\Field\FieldType\RedirectSourceItem, either in the toUrl() method, by not using query if it's not an array or in setValue() and make sure that query is always an array, that would likely avoid the update function entirely.

  • First commit to issue fork.
  • @merauluka opened merge request.
  • 🇺🇸United States merauluka

    Taking Berdir's advice and trying to update the setValue() function in RedirectSourceItem.php. I also updated the isEmpty() check to be a more basic empty() check.

    This is captured in the issue fork (and merge request) I created against this issue. But I'm capturing it here as a patch file for posterity as well.

  • 🇺🇸United States merauluka

    Why did I update the isEmpty() check when it wasn't actually related to the query parameters? The world may never know. smh

    I've reverted that portion of my patch. Reattaching here for posterity....again.

Production build 0.71.5 2024