Problem

The module stops working when run under a PHP 8 setup.

Testing

Install and configure the module as normal with Drupal 9 and PHP 8. Edit any node page, and attempt to insert an image using the default image upload. The image box comes up with the selected style and allows you to upload the image. Then try and save it. Saving fails, leaving the pop up box open and the following error in the log.

Error message

[15-Oct-2021 16:55:12 UTC] TypeError: array_keys(): Argument #1 ($array) must be of type array, null given in /drupal9/web/modules/contrib/inline_responsive_images/inline_responsive_images.module on line 258 #0 /drupal9/web/modules/contrib/inline_responsive_images/inline_responsive_images.module(258): array_keys(NULL)
#1 [internal function]: inline_responsive_images_form_editor_image_dialog_responsive_validate(Array, Object(Drupal\Core\Form\FormState))
#2 /drupal9/web/core/lib/Drupal/Core/Form/FormValidator.php(82): call_user_func_array('inline_responsi...', Array)
#3 /drupal9/web/core/lib/Drupal/Core/Form/FormValidator.php(275): Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object(Drupal\Core\Form\FormState))
#4 /drupal9/web/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'editor_image_di...')
#5 /drupal9/web/core/lib/Drupal/Core/Form/FormBuilder.php(589): Drupal\Core\Form\FormValidator->validateForm('editor_image_di...', Array, Object(Drupal\Core\Form\FormState))
#6 /drupal9/web/core/lib/Drupal/Core/Form/FormBuilder.php(321): Drupal\Core\Form\FormBuilder->processForm('editor_image_di...', Array, Object(Drupal\Core\Form\FormState))
#7 /drupal9/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\inline_responsive_images\Form\ResponsiveEditorImageDialog), Object(Drupal\Core\Form\FormState))
#8 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#9 /drupal9/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#10 /drupal9/web/core/lib/Drupal/Core/Render/Renderer.php(578): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#11 /drupal9/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#12 /drupal9/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#13 /drupal9/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#14 /drupal9/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#15 /drupal9/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /drupal9/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /drupal9/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /drupal9/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /drupal9/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /drupal9/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /drupal9/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /drupal9/web/core/lib/Drupal/Core/DrupalKernel.php(717): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /drupal9/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#24 {main}

The issue may be due to changes in how PHP 8 handles arrays.

The behavior of array_key_exists() regarding the type of the key parameter has been made consistent with isset() and normal array access. All key types now use the usual coercions and array/object keys throw a TypeError.

See https://www.php.net/manual/en/migration80.incompatible.php

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

reufhaadfe created an issue. See original summary.

avpaderno’s picture

Title: Module not compatible with PHP 8. » The module isn't compatible with PHP 8
Version: 8.x-2.2 » 8.x-2.x-dev
Issue summary: View changes

mohit.bansal623 made their first commit to this issue’s fork.

mohit.bansal623’s picture

Status: Active » Needs review

Please review.

reufhaadfe’s picture

The patch applies cleanly, but now there is a new error. See below.

[17-Oct-2021 01:26:29 UTC] AssertionError: Cannot load the "image_style" entity with NULL ID. in /apps/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php on line 244 #0 /apps/drupal/web/core/lib/Drupal/Core/Entity/EntityStorageBase.php(244): assert(false, 'Cannot load the...')
#1 /apps/drupal/web/core/lib/Drupal/Core/Entity/EntityBase.php(488): Drupal\Core\Entity\EntityStorageBase->load(NULL)
#2 /apps/drupal/web/core/modules/responsive_image/responsive_image.module(498): Drupal\Core\Entity\EntityBase::load(NULL)
#3 /apps/drupal/web/modules/contrib/inline_responsive_images/inline_responsive_images.module(286): _responsive_image_image_style_url(NULL, 'public://inline...')
#4 [internal function]: inline_responsive_images_form_editor_image_dialog_responsive_validate(Array, Object(Drupal\Core\Form\FormState))
#5 /apps/drupal/web/core/lib/Drupal/Core/Form/FormValidator.php(82): call_user_func_array('inline_responsi...', Array)
#6 /apps/drupal/web/core/lib/Drupal/Core/Form/FormValidator.php(275): Drupal\Core\Form\FormValidator->executeValidateHandlers(Array, Object(Drupal\Core\Form\FormState))
#7 /apps/drupal/web/core/lib/Drupal/Core/Form/FormValidator.php(118): Drupal\Core\Form\FormValidator->doValidateForm(Array, Object(Drupal\Core\Form\FormState), 'editor_image_di...')
#8 /apps/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(589): Drupal\Core\Form\FormValidator->validateForm('editor_image_di...', Array, Object(Drupal\Core\Form\FormState))
#9 /apps/drupal/web/core/lib/Drupal/Core/Form/FormBuilder.php(321): Drupal\Core\Form\FormBuilder->processForm('editor_image_di...', Array, Object(Drupal\Core\Form\FormState))
#10 /apps/drupal/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\inline_responsive_images\Form\ResponsiveEditorImageDialog), Object(Drupal\Core\Form\FormState))
#11 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#12 /apps/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#13 /apps/drupal/web/core/lib/Drupal/Core/Render/Renderer.php(578): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#14 /apps/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#15 /apps/drupal/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#16 /apps/drupal/vendor/symfony/http-kernel/HttpKernel.php(158): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#17 /apps/drupal/vendor/symfony/http-kernel/HttpKernel.php(80): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#18 /apps/drupal/web/core/lib/Drupal/Core/StackMiddleware/Session.php(57): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /apps/drupal/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(47): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /apps/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /apps/drupal/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /apps/drupal/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(47): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /apps/drupal/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(52): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /apps/drupal/vendor/stack/builder/src/Stack/StackedHttpKernel.php(23): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#25 /apps/drupal/web/core/lib/Drupal/Core/DrupalKernel.php(717): Stack\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#26 /apps/drupal/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#27 {main}
reufhaadfe’s picture

Status: Needs review » Needs work
reufhaadfe’s picture

Ping. Can one of the maintainers take a look at this? PHP 8 is going to be a hard requirement for Drupal ten.

avpaderno’s picture

-    $breakpoint_machine_names = array_keys($responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing']);
+    $breakpoint_machine_names = array_keys(is_array(
+      $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing']) ? $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'] : []);
     $image_style_mapping = $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'][$breakpoint_machine_names[0]];
 

Given its name, I take that $responsive_image_style->getKeyedImageStyleMappings() returns an arrray.
The original code, however, assumes that the value returned from $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'] is an array, which is not always true (given the error message shown in the IS). Replacing $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'] with an empty array, when $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'] isn't array, isn't the solution as in that case PHP would return an error when trying to access $breakpoint_machine_names[0] in the next line.

Is it normal that $responsive_image_style->getKeyedImageStyleMappings()['responsive_image.viewport_sizing'] returns NULL, or does that mean there is an error somewhere else?
What should the code do in that case? Is there any default value that make sense to use?

avpaderno’s picture

Title: The module isn't compatible with PHP 8 » inline_responsive_images_form_editor_image_dialog_responsive_validate() passes a value that isn't an array to array_keys()
Issue tags: -PHP 8.0

Actually, this isn't a compatibility with PHP 8 issue, as passing NULL to array_keys() would cause a PHP warning in PHP 7.2 too.

PHP Warning: array_keys() expects parameter 1 to be array, null given

reufhaadfe’s picture

The module does work with PHP 7.4. It fails with 8, which is why I reported it as a PHP 8 compatibility issue. Is there any update on making this work with PHP 8, or PHP 8.1?

reufhaadfe’s picture

Ping

jeroen_vreuls’s picture

I suspect this was fixed in #3089804: Don't hardcode breakpoint sets which was recently committed.

Could you test if the issue is fixed when you use the current dev version?

reufhaadfe’s picture

Confirmed. Setting 2.x-dev@dev in composer.json and upgrading fixes the issue. This was tested on PHP 8.1.

jeroen_vreuls’s picture

Status: Needs work » Closed (duplicate)

Thanks for testing. I will close this issue then.