Problem/Motivation

I created a modal to open every time someone accesses the front page. The Modal works fine, but I see lots of error messages in the Drupal log:

Error: Call to undefined method Drupal\Core\Extension\ModuleHandler::getImplementations() in Drupal\modal_page\Controller\ModalAjaxController->hookModalSubmit() (line 126 of /redacted/web/modules/contrib/modal_page/src/Controller/ModalAjaxController.php).

Steps to reproduce

Drupal 10
PHP 8.2
Modal 5.0.1

Create a Welcome Modal for the Front Page

Comments

ishore created an issue. See original summary.

ishore’s picture

Issue summary: View changes
ishore’s picture

Issue summary: View changes
kevinquillen’s picture

Version: 5.0.1 » 5.0.x-dev
Priority: Normal » Major

This does not work and breaks the API for intercepting the submit event.

kevinquillen’s picture

This doesn't make sense:

    // Load Methods.
    $projectsThatImplementsHookModalSubmit = $this->projectHandler->getImplementations('modal_submit');

    if (empty($projectsThatImplementsHookModalSubmit)) {
      echo FALSE;
      exit;
    }

    $hookNameModalIdModalSubmit = $modalId . '_modal_submit';

    $this->projectHandler->invokeAll($hookNameModalIdModalSubmit, $argsToHookModalSubmit);

First, the hook should be invoked regardless if any module was detected defining the hook. The 'getImplementations' method doesn't exist anyway, echo FALSE doesn't do anything and exiting gives no indication of successful execution. A few lines later, echo TRUE, same thing.

The docs for hook_modal_submit mention nothing about needing a specific modal id:


/**
 * Implements hook_modal_submit().
 */
function hook_modal_submit($modal, $modal_state, $modal_id) {

  // Your AJAX here.
  \Drupal::logger('modal_page')->notice('Modal Submit was triggered');

}

Hooks of this nature typically follow modulename_modal_submit. The modal id is passed to the function anyway. Otherwise this is never going to work and developers have to write long and specific function names that they shouldn't have to do.

That should just make it:

->invokeAll('modal_submit', $argsToHookModalSubmit);

There are several examples of this in core.

tguerineau’s picture

I've been working on addressing the issue as described, and here's a summary of the changes I made:
Improved Response Handling: Instead of directly echoing TRUE or FALSE and exiting, I transitioned to using structured JSON responses. This approach provides more context on the outcome, whether it's a success or a failure, and offers additional information that can be helpful for debugging.

return new \Symfony\Component\HttpFoundation\JsonResponse([
  'success' => TRUE/FALSE,
  'message' => 'Reason for success or failure',
  ...
]);

Handling non-scalar $modalState Values: To avoid issues with non-scalar values in $modalState, I implemented a check. If the $modalState contains an array or an object, the response will indicate that it holds 'Array/Object Data' rather than trying to serialize the data directly.

$responseModalState = is_scalar($modalState) ? $modalState : 'Array/Object Data';

Removed Unnecessary Check: I removed the getImplementations('modal_submit') check as suggested, as it was causing issues and not adding any real value.

While testing, I did come across a potential new issue related to the $modalState. Specifically, when the $modalState contains a non-scalar value, the system throws the following error:

Symfony\Component\HttpKernel\Exception\BadRequestHttpException: Input value "modal_state" contains a non-scalar value. in Symfony\Component\HttpKernel\HttpKernel->handle() (line 81 of /app/vendor/symfony/http-kernel/HttpKernel.php).

It seems that the error occurs here:

$modalState = [];
if (!empty($this->requestStack->getCurrentRequest()->request->get('modal_state'))) {
  $modalState = $this->requestStack->getCurrentRequest()->request->get('modal_state');
}

I believe this section requires further examination, and I'd appreciate input on the intended purpose of $modalState.

I've tried to handle it in the code to prevent any immediate issues, but I believe we need to investigate this further. It could be symptomatic of a deeper problem or an unintended use case. Has anyone else experienced this?

Question:
1. What's the primary goal or use-case for the $modalState variable?

Attached is the patch with the changes I've made. Feedback and further testing are appreciated!

renatog’s picture

StatusFileSize
new2.01 KB

Thanks for reporting and providing feedbacks

  1. undefined method Drupal\Core\Extension\ModuleHandler::getImplementations() is the same of #3293221: D10: ModuleHandler::getImplementations() deprecation
  2. Input value contains a non-scalar value is the same of #3326841: Ajax pager - Input value "viewsreference" contains a non-scalar value

Attached the patch with these fixes

  • renatog authored 4cb042da on 5.0.x
    Issue #3363861 by tguerineau, renatog, ishore, kevinquillen:  undefined...
renatog’s picture

Status: Active » Fixed

Moved to the dev branch

@tguerineau great suggestion of improving the format of AJAX response from "integer" to JSON. I created this separated issue and we can work there

renatog’s picture

New release 5.0.5 available with this fix

Status: Fixed » Closed (fixed)

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