Setting "Allowed number of values" in field storage settings when using paragraphs_limits breaks edit pages

Created on 28 August 2024, 5 months ago
Updated 9 September 2024, 4 months ago

Problem/Motivation

After update to rc2, i get WSOD with message:

TypeError: _paragraphs_limits_add_more_is_empty(): Argument #1 ($element) must be of type array, null given, called in /home/merlin/Code/geeks4change/sites/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module on line 90 in _paragraphs_limits_add_more_is_empty() (Zeile 105 in /home/merlin/Code/geeks4change/sites/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module).

Steps to reproduce

  • Create a node type and add a paragraphs field to it
  • Go to field storage settings for the paragraphs field and set the "Allowed number of values" limit to a number, e.g 4.
  • Switch the paragraphs handler to paragraphs_limits and set some limits for a few paragraphs.
  • Add a node with this node type and add enough paragraphs to trigger the upper limit.
  • When the upper limit is reached Drupal removes the add more field completely which may break the add more widget.
  • Visit the node edit page again to make more changes. Edit page will be broken.

A workaround to this is to set the storage setting limit of the host field to unlimited.

Proposed resolution

If there's no add_more button in the the widget pass an empty array to the helper function that checks if the add more is empty.

Remaining tasks

User interface changes

None

API changes

None

Data model changes

None

πŸ› Bug report
Status

Fixed

Version

1.0

Component

Code

Created by

πŸ‡©πŸ‡ͺGermany geek-merlin Freiburg, Germany

Live updates comments and jobs are added and updated live.
  • Regression

    It restores functionality that was present in earlier versions.

Sign in to follow issues

Merge Requests

Comments & Activities

  • Issue created by @geek-merlin
  • Pipeline finished with Success
    5 months ago
    Total: 145s
    #267262
  • Status changed to Needs review 5 months ago
  • πŸ‡©πŸ‡ͺGermany geek-merlin Freiburg, Germany

    Added a trivial fix that covers the case when $elements['widget']['add_more'] is empty.

    Applies cleanly on my composer site and fixes the issue for me.

  • Status changed to RTBC 5 months ago
  • πŸ‡©πŸ‡ͺGermany anruether Bonn

    As for the Steps to reproduce
    I have a field config that includes:

    settings:
      handler: paragraphs_limits
      handler_settings:
        target_bundles:
          h4d_commerce_house: h4d_commerce_house
          h4d_commerce_consumer: h4d_commerce_consumer
          h4d_commerce_business: h4d_commerce_business
        negate: 0
        target_bundles_drag_drop:
          h4d_commerce_house:
            weight: 0
            enabled: true
            lower_limit: 0
            upper_limit: 1
          h4d_commerce_consumer:
            weight: 1
            enabled: true
            lower_limit: 0
            upper_limit: 1
          h4d_commerce_business:
            weight: 2
            enabled: true
            lower_limit: 0
            upper_limit: 1

    When creating/editing content, I clicked to add a paragraph (button widget), but the form won't show. Instead I get a warning and an error. The patch fixes this for me.

    Warning: Undefined array key "add_more" in _paragraphs_limits_disallow_limited_paragraphs() (line 90 of /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module)
    #0 /home/andi/git/site-h4d-greenopolis/web/core/includes/bootstrap.inc(166): _drupal_error_handler_real()
    #1 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module(90): _drupal_error_handler()
    #2 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module(45): _paragraphs_limits_disallow_limited_paragraphs()
    #3 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(552): paragraphs_limits_field_widget_complete_paragraphs_form_alter()
    #4 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/hux/src/HuxModuleHandler.php(163): Drupal\Core\Extension\ModuleHandler->alter()
    #5 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Field/WidgetBase.php(156): Drupal\hux\HuxModuleHandler->alter()
    #6 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs/src/Plugin/Field/FieldWidget/ParagraphsWidget.php(1503): Drupal\Core\Field\WidgetBase->form()
    #7 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php(190): Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->form()
    #8 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/ContentEntityForm.php(121): Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm()
    #9 /home/andi/git/site-h4d-greenopolis/web/core/modules/node/src/NodeForm.php(134): Drupal\Core\Entity\ContentEntityForm->form()
    #10 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/EntityForm.php(107): Drupal\node\NodeForm->form()
    #11 [internal function]: Drupal\Core\Entity\EntityForm->buildForm()
    #12 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(536): call_user_func_array()
    #13 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(375): Drupal\Core\Form\FormBuilder->retrieveForm()
    #14 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(633): Drupal\Core\Form\FormBuilder->rebuildForm()
    #15 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm()
    #16 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/EntityFormBuilder.php(48): Drupal\Core\Form\FormBuilder->buildForm()
    #17 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/group/src/Entity/Controller/GroupRelationshipController.php(391): Drupal\Core\Entity\EntityFormBuilder->getForm()
    #18 /home/andi/git/site-h4d-greenopolis/web/modules/custom/route_controller/src/WrapExistingRoute/WrapExistingRouteController.php(96): Drupal\group\Entity\Controller\GroupRelationshipController->createForm()
    #19 /home/andi/git/site-h4d-greenopolis/web/modules/custom/h4d_entity_logic/src/RouteDecorator/GroupOnlyOneRouteControllerDecorator.php(66): Drupal\route_controller\WrapExistingRoute\WrapExistingRouteController->build()
    #20 [internal function]: Drupal\h4d_entity_logic\RouteDecorator\GroupOnlyOneRouteControllerDecorator->build()
    #21 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
    #22 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #23 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext()
    #24 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
    #25 /home/andi/git/site-h4d-greenopolis/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #26 /home/andi/git/site-h4d-greenopolis/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
    #27 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
    #28 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
    #29 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
    #30 /home/andi/git/site-h4d-greenopolis/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle()
    #31 /home/andi/git/site-h4d-greenopolis/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
    #32 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
    #33 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
    #34 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
    #35 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
    #36 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
    #37 /home/andi/git/site-h4d-greenopolis/web/index.php(19): Drupal\Core\DrupalKernel->handle()
    #38 /home/andi/git/site-h4d-greenopolis/vendor/drush/drush/misc/d8-rs-router.php(48): require('...')
    #39 {main}
    
    TypeError: _paragraphs_limits_add_more_is_empty(): Argument #1 ($element) must be of type array, null given, called in /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module on line 90 in _paragraphs_limits_add_more_is_empty() (line 105 of /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module).
    Severity	Error
    Hostname	127.0.0.1
    Operations	
    Backtrace	
    #0 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module(90): _paragraphs_limits_add_more_is_empty()
    #1 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs_limits/paragraphs_limits.module(45): _paragraphs_limits_disallow_limited_paragraphs()
    #2 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Extension/ModuleHandler.php(552): paragraphs_limits_field_widget_complete_paragraphs_form_alter()
    #3 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/hux/src/HuxModuleHandler.php(163): Drupal\Core\Extension\ModuleHandler->alter()
    #4 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Field/WidgetBase.php(156): Drupal\hux\HuxModuleHandler->alter()
    #5 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/paragraphs/src/Plugin/Field/FieldWidget/ParagraphsWidget.php(1503): Drupal\Core\Field\WidgetBase->form()
    #6 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/Entity/EntityFormDisplay.php(190): Drupal\paragraphs\Plugin\Field\FieldWidget\ParagraphsWidget->form()
    #7 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/ContentEntityForm.php(121): Drupal\Core\Entity\Entity\EntityFormDisplay->buildForm()
    #8 /home/andi/git/site-h4d-greenopolis/web/core/modules/node/src/NodeForm.php(134): Drupal\Core\Entity\ContentEntityForm->form()
    #9 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/EntityForm.php(107): Drupal\node\NodeForm->form()
    #10 [internal function]: Drupal\Core\Entity\EntityForm->buildForm()
    #11 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(536): call_user_func_array()
    #12 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(375): Drupal\Core\Form\FormBuilder->retrieveForm()
    #13 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(633): Drupal\Core\Form\FormBuilder->rebuildForm()
    #14 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm()
    #15 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Entity/EntityFormBuilder.php(48): Drupal\Core\Form\FormBuilder->buildForm()
    #16 /home/andi/git/site-h4d-greenopolis/web/modules/contrib/group/src/Entity/Controller/GroupRelationshipController.php(391): Drupal\Core\Entity\EntityFormBuilder->getForm()
    #17 /home/andi/git/site-h4d-greenopolis/web/modules/custom/route_controller/src/WrapExistingRoute/WrapExistingRouteController.php(96): Drupal\group\Entity\Controller\GroupRelationshipController->createForm()
    #18 /home/andi/git/site-h4d-greenopolis/web/modules/custom/h4d_entity_logic/src/RouteDecorator/GroupOnlyOneRouteControllerDecorator.php(66): Drupal\route_controller\WrapExistingRoute\WrapExistingRouteController->build()
    #19 [internal function]: Drupal\h4d_entity_logic\RouteDecorator\GroupOnlyOneRouteControllerDecorator->build()
    #20 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array()
    #21 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #22 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(121): Drupal\Core\Render\Renderer->executeInRenderContext()
    #23 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext()
    #24 /home/andi/git/site-h4d-greenopolis/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
    #25 /home/andi/git/site-h4d-greenopolis/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw()
    #26 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle()
    #27 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle()
    #28 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle()
    #29 /home/andi/git/site-h4d-greenopolis/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\Core\StackMiddleware\ContentLength->handle()
    #30 /home/andi/git/site-h4d-greenopolis/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass()
    #31 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle()
    #32 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle()
    #33 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle()
    #34 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle()
    #35 /home/andi/git/site-h4d-greenopolis/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle()
    #36 /home/andi/git/site-h4d-greenopolis/web/index.php(19): Drupal\Core\DrupalKernel->handle()
    #37 /home/andi/git/site-h4d-greenopolis/vendor/drush/drush/misc/d8-rs-router.php(48): require('...')
    #38 {main}
  • Status changed to Needs work 5 months ago
  • πŸ‡¨πŸ‡¦Canada pavlosdan

    So the issue seems to be happening when the field is limited by core's field storage setting "Allowed number of values". If this is set to unlimited the pages are working as intended. If this is limited at the storage level, Drupal removes the add more button completely from the form and paragraphs_limits breaks.

    Would be nice to have a test for this.

  • πŸ‡¨πŸ‡¦Canada pavlosdan

    Admittedly setting a limit at the storage level was not something I thought about since I thought we'd be setting granular limits using the handler. Good catch!

    Is it fair to assume that you weren't using the patch from ✨ This module should disallow adding more than the allowed amount of paragraph items in the add widget Fixed prior to rc2?

  • πŸ‡©πŸ‡ͺGermany anruether Bonn

    @pavlosdan Thanks for your reply! That's correct ;)

    Indeed, when setting field storage to unlimited this issue does not come up. I can see edge cases that might want to use limited storage, but we don't have them atm.

  • First commit to issue fork.
  • Pipeline finished with Success
    4 months ago
    Total: 148s
    #278476
  • Pipeline finished with Success
    4 months ago
    Total: 147s
    #278477
  • Status changed to Needs review 4 months ago
  • πŸ‡ΊπŸ‡ΈUnited States seanpclark

    Tests for storage limit added.

  • Pipeline finished with Success
    4 months ago
    Total: 166s
    #278615
  • πŸ‡¨πŸ‡¦Canada pavlosdan

    Merged. Thanks all!

  • Status changed to Fixed 4 months ago
  • Automatically closed - issue fixed for 2 weeks with no activity.

Production build 0.71.5 2024