[AdminToolbarToolsSettingsForm] Fix Fatal Error: Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll()

Created on 7 August 2024, 7 months ago

Problem/Motivation

Fix PHP Fatal error resulting in WSOD, occurring when saving AdminToolbarToolsSettingsForm:

Error: Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll() in Drupal\admin_toolbar_tools\Form\AdminToolbarToolsSettingsForm->submitForm() (line 95 of /var/www/html/web/modules/contrib/admin_toolbar/admin_toolbar_tools/src/Form/AdminToolbarToolsSettingsForm.php).

Detailed stacktrace :

#0 [internal function]: Drupal\admin_toolbar_tools\Form\AdminToolbarToolsSettingsForm->submitForm(Array, Object(Drupal\Core\Form\FormState))
#1 /var/www/html/web/core/lib/Drupal/Core/Form/FormSubmitter.php(129): call_user_func_array(Array, Array)
#2 /var/www/html/web/core/lib/Drupal/Core/Form/FormSubmitter.php(67): Drupal\Core\Form\FormSubmitter->executeSubmitHandlers(Array, Object(Drupal\Core\Form\FormState))
#3 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(597): Drupal\Core\Form\FormSubmitter->doSubmitForm(Array, Object(Drupal\Core\Form\FormState))
#4 /var/www/html/web/core/lib/Drupal/Core/Form/FormBuilder.php(326): Drupal\Core\Form\FormBuilder->processForm('admin_toolbar_t...', Array, Object(Drupal\Core\Form\FormState))
#5 /var/www/html/web/core/lib/Drupal/Core/Controller/FormController.php(73): Drupal\Core\Form\FormBuilder->buildForm(Object(Drupal\admin_toolbar_tools\Form\AdminToolbarToolsSettingsForm), Object(Drupal\Core\Form\FormState))
#6 [internal function]: Drupal\Core\Controller\FormController->getContentResult(Object(Symfony\Component\HttpFoundation\Request), Object(Drupal\Core\Routing\RouteMatch))
#7 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(123): call_user_func_array(Array, Array)
#8 /var/www/html/web/core/lib/Drupal/Core/Render/Renderer.php(638): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#9 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(124): Drupal\Core\Render\Renderer->executeInRenderContext(Object(Drupal\Core\Render\RenderContext), Object(Closure))
#10 /var/www/html/web/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php(97): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->wrapControllerExecutionInRenderContext(Array, Array)
#11 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(181): Drupal\Core\EventSubscriber\EarlyRenderingControllerWrapperSubscriber->Drupal\Core\EventSubscriber\{closure}()
#12 /var/www/html/vendor/symfony/http-kernel/HttpKernel.php(76): Symfony\Component\HttpKernel\HttpKernel->handleRaw(Object(Symfony\Component\HttpFoundation\Request), 1)
#13 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/Session.php(53): Symfony\Component\HttpKernel\HttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#14 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/KernelPreHandle.php(48): Drupal\Core\StackMiddleware\Session->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#15 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ContentLength.php(28): Drupal\Core\StackMiddleware\KernelPreHandle->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#16 /var/www/html/web/core/modules/big_pipe/src/StackMiddleware/ContentLength.php(32): Drupal\Core\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#17 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(106): Drupal\big_pipe\StackMiddleware\ContentLength->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#18 /var/www/html/web/core/modules/page_cache/src/StackMiddleware/PageCache.php(85): Drupal\page_cache\StackMiddleware\PageCache->pass(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#19 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/ReverseProxyMiddleware.php(48): Drupal\page_cache\StackMiddleware\PageCache->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#20 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/NegotiationMiddleware.php(51): Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#21 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/AjaxPageState.php(36): Drupal\Core\StackMiddleware\NegotiationMiddleware->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#22 /var/www/html/web/core/lib/Drupal/Core/StackMiddleware/StackedHttpKernel.php(51): Drupal\Core\StackMiddleware\AjaxPageState->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#23 /var/www/html/web/core/lib/Drupal/Core/DrupalKernel.php(741): Drupal\Core\StackMiddleware\StackedHttpKernel->handle(Object(Symfony\Component\HttpFoundation\Request), 1, true)
#24 /var/www/html/web/index.php(19): Drupal\Core\DrupalKernel->handle(Object(Symfony\Component\HttpFoundation\Request))
#25 {main}

Steps to reproduce

0 - Install the admin_toolbar_tools module
1 - Browse to the Admin Toolbar Tools settings at: /admin/config/user-interface/admin-toolbar-tools
under: Home > Administration > Configuration > User interface > Admin Toolbar Tools
2 - Save the form by clicking on the Save configuration button.
3 - Confirm the page crashes with WSOD error:

The website encountered an unexpected error. Try again later.

Error: Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll() in Drupal\admin_toolbar_tools\Form\AdminToolbarToolsSettingsForm->submitForm() (line 97 of modules/contrib/admin_toolbar/admin_toolbar_tools/src/Form/AdminToolbarToolsSettingsForm.php).

Proposed resolution

This issue seems to have been introduced in commit:
https://git.drupalcode.org/project/admin_toolbar/-/commit/efb450aeb115f7...
and is the same as 🐛 [AdminToolbarSettingsForm] Fix Fatal Error: Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll() Fixed .

It appears the values for $container->get were reversed when injecting the dependencies.

Solution: Set the injected dependencies in the correct order, for each respective property.

Additionally, add a basic automated test class to confirm the changes fix the issue.

🐛 Bug report
Status

Active

Version

3.0

Component

Code

Created by

🇫🇷France dydave

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

Merge Requests

Comments & Activities

  • Issue created by @dydave
  • Pipeline finished with Success
    7 months ago
    Total: 346s
    #247259
  • Pipeline finished with Success
    7 months ago
    Total: 400s
    #247270
  • Status changed to Needs review 7 months ago
  • 🇫🇷France dydave

    Quick follow-up on this issue:

    Fixed fatal error 'Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll()' and added basic automated tests for the 'AdminToolbarToolsSettingsForm':
    Submit the form and confirm it doesn't crash with error.

    ✅ The merge request seems to be passing all tests, thus moving issue to Needs review.

    Please note: much more work is needed to improve the tests for the AdminToolbarToolsSettingsForm, in particular:
    While trying to write tests for max_bundle_number it appeared issue 🐛 Max Bundles not being honored Fixed is still not completely fixed:
    Tested with Media bundles: Setting the max_bundle_number to 2, for example, on a standard fresh D10 install (which should install several Media bundles by default: Audio, Document, Image, etc...), doesn't have any effect on the links under Content > Add media
    ==> All bundles are still displayed in the menu (under Content).

    However, this setting seems to work with menu items under Structure.

    I'm not sure if this is by design, but it is a bit misleading, as we would potentially expect bundles would be limited everywhere links for entity bundles are added, as the field says:

    Maximum number of bundle sub-menus to display
    Loading a large number of items can cause performance issues.

     
    In any case, this should most likely be addressed in a separate ticket, so for the time being, the tests minimally cover the error reported in this issue summary.
     

    We would greatly appreciate if a maintainer or someone with write permission could take a look at ticket's merge request MR!96 and let us know if there would be any more work needed.

    Feel free to let us know if you have any questions or concerns on any of the changes in the merge request or any aspect of this ticket in general, we would surely be glad to help.
    Thanks in advance for your feedback and reviews.

  • Similar problem here:
    - A batch upgrade from D10.2.7 to 10.3.2 brought the WSOD. A selective upgrade on 10.3.1 with PHP 8.3.9 made possible to pinpoint 'admin_toolbar' as the primary culprit, in combination with the 'admin_toolbar_tools'.
    Upgrading 'admin_toolbar_tools' (3.4.2 => 3.5.0) first while keeping 'admin_toolbar' at 3.4.2 went well. Then upgrading 'admin_toolbar' (3.4.2 => 3.5.0) as well yielded the trace below:

    TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given in method_exists() (line 68 of modules/contrib/admin_toolbar/admin_toolbar_tools/src/Plugin/Menu/MenuLinkEntity.php).

    Drupal\admin_toolbar_tools\Plugin\Menu\MenuLinkEntity->getDescription() (Line: 124)
    Drupal\Core\Menu\MenuLinkBase->getUrlObject() (Line: 215)
    Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->menuLinkCheckAccess() (Line: 107)
    Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->checkAccess() (Line: 111)
    Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->checkAccess() (Line: 111)
    Drupal\Core\Menu\DefaultMenuLinkTreeManipulators->checkAccess()
    call_user_func() (Line: 153)
    Drupal\Core\Menu\MenuLinkTree->transform() (Line: 124)
    Drupal\toolbar\Controller\ToolbarController::preRenderGetRenderedSubtrees()
    call_user_func_array() (Line: 113)
    Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 870)
    Drupal\Core\Render\Renderer->doCallback() (Line: 432)
    Drupal\Core\Render\Renderer->doRender() (Line: 248)
    Drupal\Core\Render\Renderer->render() (Line: 283)
    {closure}() (Line: 638)
    Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 282)
    toolbar_get_rendered_subtrees() (Line: 295)
    _toolbar_get_subtrees_hash() (Line: 168)
    toolbar_toolbar()
    call_user_func_array() (Line: 416)
    Drupal\Core\Extension\ModuleHandler->Drupal\Core\Extension\{closure}() (Line: 395)
    Drupal\Core\Extension\ModuleHandler->invokeAllWith() (Line: 415)
    Drupal\Core\Extension\ModuleHandler->invokeAll() (Line: 78)
    Drupal\toolbar\Element\Toolbar::preRenderToolbar()
    call_user_func_array() (Line: 113)
    Drupal\Core\Render\Renderer->doTrustedCallback() (Line: 870)
    Drupal\Core\Render\Renderer->doCallback() (Line: 432)
    Drupal\Core\Render\Renderer->doRender() (Line: 504)
    Drupal\Core\Render\Renderer->doRender() (Line: 248)
    Drupal\Core\Render\Renderer->render() (Line: 475)
    Drupal\Core\Template\TwigExtension->escapeFilter() (Line: 83)
    __TwigTemplate_d68a68533d331dfee346749b4e3826a0->doDisplay() (Line: 360)
    Twig\Template->yield() (Line: 335)
    Twig\Template->render() (Line: 38)
    Twig\TemplateWrapper->render() (Line: 33)
    twig_render_template() (Line: 348)
    Drupal\Core\Theme\ThemeManager->render() (Line: 491)
    Drupal\Core\Render\Renderer->doRender() (Line: 248)
    Drupal\Core\Render\Renderer->render() (Line: 158)
    Drupal\Core\Render\MainContent\HtmlRenderer->Drupal\Core\Render\MainContent\{closure}() (Line: 638)
    Drupal\Core\Render\Renderer->executeInRenderContext() (Line: 153)
    Drupal\Core\Render\MainContent\HtmlRenderer->renderResponse() (Line: 90)
    Drupal\Core\EventSubscriber\MainContentViewSubscriber->onViewRenderArray()
    call_user_func() (Line: 111)
    Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher->dispatch() (Line: 186)
    Symfony\Component\HttpKernel\HttpKernel->handleRaw() (Line: 76)
    Symfony\Component\HttpKernel\HttpKernel->handle() (Line: 53)
    Drupal\Core\StackMiddleware\Session->handle() (Line: 48)
    Drupal\Core\StackMiddleware\KernelPreHandle->handle() (Line: 28)
    Drupal\Core\StackMiddleware\ContentLength->handle() (Line: 32)
    Drupal\big_pipe\StackMiddleware\ContentLength->handle() (Line: 106)
    Drupal\page_cache\StackMiddleware\PageCache->pass() (Line: 85)
    Drupal\page_cache\StackMiddleware\PageCache->handle() (Line: 50)
    Drupal\ban\BanMiddleware->handle() (Line: 263)
    Drupal\shield\ShieldMiddleware->bypass() (Line: 219)
    Drupal\shield\ShieldMiddleware->handle() (Line: 48)
    Drupal\Core\StackMiddleware\ReverseProxyMiddleware->handle() (Line: 51)
    Drupal\Core\StackMiddleware\NegotiationMiddleware->handle() (Line: 36)s
    Drupal\Core\StackMiddleware\AjaxPageState->handle() (Line: 51)
    Drupal\Core\StackMiddleware\StackedHttpKernel->handle() (Line: 741)
    Drupal\Core\DrupalKernel->handle() (Line: 19)

  • 🇫🇷France dydave

    @dgwolf ==> Wrong issue :

    Could you please take a look at : 🐛 TypeError: method_exists(): Argument #1 ($object_or_class) must be of type object|string, null given Needs review ?

    Thanks in advance !

  • Status changed to Needs work 6 months ago
  • 🇨🇦Canada Liam Morland Ontario, CA 🇨🇦

    @dydave The merge request only adds a test. It does not appear to do anything that would fix the error with ::invalidateAll().

  • Pipeline finished with Failed
    5 months ago
    Total: 532s
    #295766
  • Pipeline finished with Failed
    5 months ago
    Total: 564s
    #295772
  • Pipeline finished with Failed
    about 1 month ago
    Total: 370s
    #392868
  • Pipeline finished with Failed
    about 1 month ago
    Total: 413s
    #392877
  • Pipeline finished with Failed
    about 1 month ago
    Total: 537s
    #392883
  • Pipeline finished with Success
    about 1 month ago
    Total: 1246s
    #392892
  • Status changed to Needs review about 1 month ago
  • 🇫🇷France dydave

    Thanks everyone and sorry for the delay on this!

    Thanks a lot @osopolar:

    It seems that the fix got committed with the related issue 🐛 [AdminToolbarSettingsForm] Fix Fatal Error: Call to undefined method Drupal\Core\Menu\MenuLinkManager::invalidateAll() Fixed , see also https://git.drupalcode.org/project/admin_toolbar/-/merge_requests/94/diffs

    Indeed, it seems the fix for the AdminToolbarToolsSettingsForm got committed without an associated Functional test.

    The merge request has been updated to add a new test file for the AdminToolbarToolsSettingsForm.

    The test doesn't do much at this stage, but at least it ensures the form could be saved with its default values
    ==> It would therefore prevent crashes on the settings form pages, such as the ones reported in this ticket and fixed in the other MR.

    Fixed PHPCS errors in admin_toolbar_tools/src/Controller/ToolbarController.php to allow the MR to pass, but should probably be addressed in other tickets (?!).

    Watchout: The tests for previous major had to be disabled for MR!96 to pass.
    The errors reported in the build seemed to be related with other issues or files that are not modified in the MR, see:
    https://git.drupalcode.org/issue/admin_toolbar-3466743/-/jobs/3984130#L52
    Therefore, this change should probably be reverted once the tests issues are fixed, probably in other tickets.

    It would be great to see this MR getting merged and more Functional tests being added!

    Any feedback, comments or reviews would be greatly appreciated!
    Thanks in advance!

  • 🇫🇷France dydave

    PHPCS and previous major issues addressed in 🐛 Fix automated tests Active .

    • dydave committed ef117857 on 3.x
      Issue #3466743 by DYdave: Added initial automated tests for the '...
  • 🇫🇷France dydave

    Thanks everyone for your help on this issue!

    The changes have been merged above at #11, adding another basic test case to the module.

    Please let us know if you have any comments or concerns on any aspects of the latest changes or this issue in general, we would surely be glad to help.
    Thanks in advance!

Production build 0.71.5 2024