Problem/Motivation
This is a followup issue for #992928: Command line (Drush) install fails on SQLite ($form_state['input'] is not always populated for programmatic form submissions), with the part of the patch that wasn't committed there.
The bug is that it is possible to submit a form using drupal_form_submit() without Drupal ever identifying any button (or "triggering element") as the one that was clicked. Since code exists to make sure that Drupal always identifies a clicked button for browser-based form submissions, it doesn't make sense to allow a loophole for programmatic form submissions to get around that. For example, people writing forms may attach certain behaviors such as #limit_validation_errors to a button, and if it is the only button on the form, expect that that code will always run (that's the situation that came up in the above issue).
This patch makes it so the same code that runs for browsers also runs for programmatic form submissions and so that a triggering element is always identified. In the other issue it was suggested that perhaps this should be bumped to Drupal 8, but to me it seems like a straight-up bugfix. I don't see how anyone could legitimately write a programmatic form submission that relies on Drupal thinking the form was submitted without any of its buttons being clicked, when we already disallow that for regular form submissions.
Steps to reproduce
Proposed resolution
TBA
Remaining tasks
Update patch
Review
Commit
User interface changes
API changes
Data model changes
Release notes snippet
| Comment | File | Size | Author |
|---|---|---|---|
| #17 | drupal-form-submit-no-buttons-1008644-17.patch | 1.57 KB | Mandakini_Kumari |
| drupal-form-submit-no-buttons.patch | 1.7 KB | David_Rothstein |
Comments
Comment #1
moshe weitzman commentedAgree that is it is a bug fix. This is gonna pop up from time to time and it is very hard to spot.
Comment #2
webchickSeems sensible, but I'd love to get someone from #684846: AJAX triggered by non-submit element fails if any elements are validated to chime in here on this fix.
Comment #3
David_Rothstein commentedI added a comment to #684846: AJAX triggered by non-submit element fails if any elements are validated asking for a review of this issue.
Comment #4
sunAFAIK, you always had to specify the form button for programmatic form submissions (also in D6).
Therefore, I'm reluctant to do this change. Especially, because browsers actually do not simply choose the "first" button — they are doing something along the lines of
and if they are not, then they are violating the HTML5 spec, which apparently defines that browsers should do this ugly fuzzy match.
Since there is no triggering element for programmatic form submissions, it gets even more weird: Is it
To be honest, I don't like this idea. Whatever you do programmatically, you should be explicit. Doing assumptions in this kind of functionality quickly turns into "black magic" and confusing behavior that no one understands.
Comment #5
David_Rothstein commentedIf Drupal uses an incorrect algorithm to detect the clicked button, that's not an issue with this patch. The code already runs for Internet Explorer. (Or so it claims.) All this patch does is make things consistent.
If you absolutely need to ensure a particular button was clicked in a programmatic form submission, you should still pass it in, of course. This patch simply makes it impossible to wind up in a nonsensical situation where there is no
clicked button[edit: triggering element] at all.Comment #6
effulgentsia commentedI'm not sure if this makes sense for D7 or not. Logically, I think it does, and I think the Drush use case is worth considering here. But this is old code from D6 or before, so I'm not sure how much we want to mess with it before D8.
In D6, you have:
form_builder():
_form_builder_ie_cleanup():
In #684846: AJAX triggered by non-submit element fails if any elements are validated, we changed this for D7 to not distinguish between 'button' and 'submit', because both are rendered as a submit button as far as the browser is concerned, so that was a clear bug fix and related to other things needed by that issue. But changing the logic for programmed form submissions wasn't seen as part of that issue's scope, since programmed form submissions can specify the button explicitly, so we don't have to work around browser quirks. That said, given that we do have an algorithm for picking the correct button when the browser fails to say what it is, I don't see it as all that risky to use the same algorithm for a programmatic form submission.
Sorry, I can't really give this a +1 or -1 at this time. I'll think about it more, and am interested in what chx and eaton think.
Comment #8
casey commentedsub
Comment #9
sunI do not think that you should be able to submit a form programmatically without specifying the form button to be triggered.
I'm aware that we still have code for IE in core that tries to automatically determine the button you "intended" to press, but IMHO that's a dirty hack, which is a level of random guessing that is dangerous and risky on its own, which we should remove as soon as possible, and not something we want to advance on.
Comment #10
sunJust to provide some additional pointers to back up my position:
#1342066: Document that buttons with the same #value need a unique #name for the form API to distinguish them, or change the form API to assign unique #names automatically
#1452894: Elements with #has_garbage_value (image buttons) are always set as a triggering element
Comment #11
David_Rothstein commentedThat might be a reasonable way to deal with this, but if so, we have to make it do that :) Right now, nothing enforces this at all.
So, we could, for example, throw a validation error in the case where a form was submitted programmatically with no button specified (and where the form has more than one button to choose from).
Comment #12
David_Rothstein commentedBetter status.
Comment #13
Mandakini_Kumari commenteddrupal-form-submit-no-buttons.patch queued for re-testing.
Comment #15
Mandakini_Kumari commentedPatch no longer applies.
Getting below error:
ubuntu@ubuntu-Lenovo-G570:/var/www/drupal$ git apply -v drupal-form-submit-no-buttons.patch
Checking patch form.inc...
error: form.inc: No such file or directory
ubuntu@ubuntu-Lenovo-G570:/var/www/drupal$
Comment #16
star-szr@Mandakini_Kumari: It's a CVS patch, so git won't be able to apply it. You can find some tips on applying old patches here:
http://drupal.org/node/60116
If you're able to provide a new patch created with git that might be helpful:
http://drupal.org/patch/reroll
http://drupal.org/patch/create
Comment #17
Mandakini_Kumari commentedThanks Cottser attached here is re-rolled patch.
Comment #20
shwetap_07 commentedI want to validate textfield using ajax before submitting form. i.e. if i write something in textfield it should get validate after tab or enter. please help.
please let me known where going wrong :(
Comment #33
quietone commentedThis was discussed at a bugsmash group triage meeting. Discussed with Pandaski , catch and myself. catch pointed out "there are still use-cases for programmatically submitting a form like combining multiple form definitions into one (multiform, entity embed etc.)". He also said that this is a task, there is no bug here.
I am updating the issue.
Comment #34
catchThis conflicts with #2910320: Validating managed files should account for null triggering elements