Form Builder does not fully allow Ajax GET requests

Created on 23 February 2024, 4 months ago
Updated 1 May 2024, about 2 months ago

Problem/Motivation

In πŸ“Œ Allow AJAX to use GET requests Fixed we allowed ajax get requests; however, FormBuilder still specifically checks POST for form_id and throws exceptions if not in place. I came across this when attempting to build a table within a Form with sorters from non-database/non-views related content. The sorters and pagination are links rather than form elements and therefore do not POST data.

Steps to reproduce

Attempt to build a form during an ajax request that contains only GET variables
BrokenPostRequestException is thrown from FormBuilder here

if ($ajax_form_request && !$request->request->has('form_id')) {
  throw new BrokenPostRequestException($this->getFileUploadMaxSize());
}

and here:

if ($ajax_form_request && $form_state->isProcessingInput() && $request->request->get('form_id') == $form_id) {
  throw new FormAjaxException($form, $form_state);
}

Proposed resolution

Use $request->get() instead of $request->request->get()

Remaining tasks

  1. Fix issue
  2. Provide test

User interface changes

None

API changes

None

Data model changes

None

Release notes snippet

FormBuilder now allows a Form to be fully built in Ajax with GET requests

πŸ› Bug report
Status

Fixed

Version

10.2 ✨

Component
FormΒ  β†’

Last updated about 15 hours ago

Created by

πŸ‡¬πŸ‡§United Kingdom scott_euser

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

Merge Requests

Comments & Activities

  • Issue created by @scott_euser
  • Merge request !6755Allow form_id to come from GET request β†’ (Open) created by scott_euser
  • Issue was unassigned.
  • Status changed to Needs work 4 months ago
  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Needs a test case to show this still.

  • Pipeline finished with Failed
    4 months ago
    Total: 505s
    #102307
  • Status changed to Needs review 4 months ago
  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Tests added. Note that I renamed 'testGetPostAjaxRequest' existing test to 'testPostAjaxRequest', otherwise the logical new test method name would have been 'testGetGetAjaxRequest', so I hope this makes sense.

  • Pipeline finished with Success
    4 months ago
    Total: 460s
    #102314
  • First commit to issue fork.
  • Status changed to RTBC 4 months ago
  • πŸ‡ΊπŸ‡ΈUnited States smustgrave

    Test coverage can be found https://git.drupalcode.org/issue/drupal-3423454/-/jobs/889193

    Issue summary seems complete.

    Reviewed the code and fix makes sense to me.

    I applied my own suggestions but super nitpicky adding :void.

    LGTM!

  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Thanks for the quick review! Suggested changes look good of course :)

  • πŸ‡¬πŸ‡§United Kingdom catch

    This looks good. Those checks are for corrupted forms (incomplete submissions due to post_max_vars) and aren't supposed to enforce anything except more helpful error messages. Committed/pushed to 11.x, cherry-picked to 10.3.x and 10.2.x, thanks!

    • catch β†’ committed 30405997 on 10.2.x
      Issue #3423454 by scott_euser, smustgrave: Form Builder does not fully...
    • catch β†’ committed 1b4b5e52 on 10.3.x
      Issue #3423454 by scott_euser, smustgrave: Form Builder does not fully...
  • Status changed to Fixed 4 months ago
    • catch β†’ committed 09ade8fa on 11.x
      Issue #3423454 by scott_euser, smustgrave: Form Builder does not fully...
  • πŸ‡¬πŸ‡§United Kingdom scott_euser

    Thanks very much, really appreciate the quick turnaround!

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

  • πŸ‡ΊπŸ‡¦Ukraine abramm Lutsk

    This change has caused a regression in our application.
    I believe this is an edge case that's specific to our project (and a result of bad route argument naming), but I'm noting it here in case it would be helpful to anyone else.

    We have a custom form controller and a route defined like this:

    my_path:
      path: "/my-url/{some_param}"
      defaults:
        _controller: '\Drupal\my_module\Controller\CustomFormController::build'
        form_id: 'Drupal\my_module\Form\MyModuleFormClass'

    Due to the change in this commit, the form_id may be now fetched from the request attributes (\Symfony\Component\HttpFoundation\Request::get), which caused the wrong form_id value to be fetched from the route attributes rather than from the request GET/POST parameters.

    We've fixed this by changing the form_id argument to a different name (e.g. my_form_class) to avoid naming interference.

Production build 0.69.0 2024