I thought this may be a duplicate of https://www.drupal.org/project/h5p/issues/3199600 but I tried the patch there and it did not help. It's not quite the same context or error, but they are both about upgrading.

Problem/Motivation

When I try to upgrade existing content from /admin/content/h5p, I get this error:

Error: Attempt to assign property "skipped" on array in Drupal\h5p\Controller\H5PContentUpgrade->upgrade() (line 145 of /opt/www/html/[site address]/web/modules/contrib/h5p/src/Controller/H5PContentUpgrade.php).

This blocks being able to edit older content, since it wants to first upgrade the library version of the content, but can't upgrade the library version of the content without an error.

Steps to reproduce

When content needs upgraded - in my most recent example it was Interactive Book but I have encountered the same in production for other libraries:

1. Go to /admin/content/h5p
2. Click the green upgrade button beside the content to be upgraded
3. Approve the version number to upgrade to
4. Error appears

I am on PHP 8.0.

Comments

ryanrobinson_wlu created an issue. See original summary.

ryan-l-robinson’s picture

There may be a lot more going on here than I know about, but I replaced the object syntax in src/Controller/H5PContentUpgrade.php at the spot specified by the error, with array syntax.

// Determine if any content has been skipped during the process
    $skipped = filter_input(INPUT_POST, 'skipped');
    if ($skipped !== NULL) {
      $out['skipped'] = json_decode($skipped);
      // Clean up input, only numbers
      foreach ($out['skipped'] as $i => $id) {
        $out['skipped'][$i] = intval($id);
      }
      $skipped = implode(',', $out['skipped']);
    }
    else {
      $out['skipped'] = array();
    }

I've attempted to get that into a patch, but haven't figured out how to do that quite properly yet.

That worked on my staging test to successfully upgrade 4 Interactive Book content nodes. But I don't know enough other context to be able to say that I am still achieving what this code was meant to do, or that I didn't introduce any other problems.

ryan-l-robinson’s picture

StatusFileSize
new2.13 KB

Tried this patch file, it doesn't work.

ryan-l-robinson’s picture

sokru’s picture

Sorry, I'm not being able to reproduce the issue. On my project or on vanilla Drupal installation /admin/content/h5p all buttons are disabled. Does it need some change to H5P settings at /admin/config/system/h5p ?

ryan-l-robinson’s picture

Thank you for looking at this sokru. To have the upgrade button, you need to have some content of that type to be upgraded. For example, in ours right now we have 110 Interactive Video nodes of version 1.22.14, while there is a version 1.24 available. Which means in practice it might take some time to generate it on a new site, as you'd have to create the content, wait for a newer version of that H5P type to be available, then come back.

ryan-l-robinson’s picture

I'm feeling pretty good about my fix, other than my failure to generate a patch file that works. Tracing through the code:

$out is declared as an array, not an object (line 93 in H5PContentUpgrade.php):

    // Prepare response
    $out = [
      'params' => [],
      'token' => \H5PCore::createToken('contentupgrade'),
    ];

But then farther down, it is using syntax as if $out was an object instead (line 134 in H5PContentUpgrade.php):

    // Determine if any content has been skipped during the process
    $skipped = filter_input(INPUT_POST, 'skipped');
    if ($skipped !== NULL) {
      $out->skipped = json_decode($skipped);
      // Clean up input, only numbers
      foreach ($out->skipped as $i => $id) {
        $out->skipped[$i] = intval($id);
      }
      $skipped = implode(',', $out->skipped);
    }
    else {
      $out->skipped = array();
    }

Changing that section to treat $out as the array it is seems to work in my tests so far:

    // Determine if any content has been skipped during the process
    $skipped = filter_input(INPUT_POST, 'skipped');
    if ($skipped !== NULL) {
      $out['skipped'] = json_decode($skipped);
      // Clean up input, only numbers
      foreach ($out['skipped'] as $i => $id) {
        $out['skipped'][$i] = intval($id);
      }
      $skipped = implode(',', $out['skipped']);
    }
    else {
      $out['skipped'] = array();
    }

It's possible there's something else elsewhere that breaks down with this change, but I don't see $out->skipped or $out['skipped'] being used again - it gets imploded into the $skipped variable and that is what gets used the rest of the way. I don't think I have any content being skipped to be able to test that.

ryan-l-robinson’s picture

StatusFileSize
new990 bytes

New patch file: I think this one worked to deploy over composer to a server.

ryan-l-robinson’s picture

Status: Active » Needs review
sokru’s picture

Status: Needs review » Reviewed & tested by the community

The changes on #8 looks very good to have, so changing the status to RTBC.

rajab natshah’s picture

Tested,
Thank you for the patch fix.

papijo’s picture

H5P for Drupal Version: 2.0.0-alpha3 - Using PHP 8.1.13 and Drupal 9.5.9
Successfully tested patch #8. Thanks @ryanrobinson_wlu !
This should really be made available ASAP... and a final release of H5P for Drupal 9 should be available too.

ryan-l-robinson’s picture

Version: 2.0.0-alpha2 » 2.0.0-alpha3
ryan-l-robinson’s picture

Updated to reflect that this is still an issue in alpha3 and that the patch still works on alpha3. It would be great to have this and several other patches here (Drupal 10 and PHP 8.1 compatibility) put into a release.

ryan-l-robinson’s picture

Bad news: this one appears to have not gotten included in the recent wave of integrated patches to the dev branch including D10 support.

Good news: the patch still applied fine for me against the newly-updated dev branch, so other changes needed here.

catch’s picture

Status: Reviewed & tested by the community » Fixed

Committed/pushed to 2.0.x, thanks!

Status: Fixed » Closed (fixed)

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