#2537732: PluginFormInterface must have access to the complete $form_state (introduce SubFormState for embedded forms) introduces subform states, to make sure that parent and embedded forms can work together without knowing anything about each other. Many plugins assume they can access the top levels of the form states they receive, for instance to retrieve submitted values from. If the parent form passes on its own form state to plugin forms, this fails, unless the plugin forms are embedded at the top level of the parent form, which generally is a bad idea due to conflicts with other elements.
To solve this, plugin selectors must create subform states and pass those on to plugin forms instead of parent form states.
| Comment | File | Size | Author |
|---|---|---|---|
| #38 | 2647312-38-use-subformstate.patch | 53.32 KB | froboy |
Issue fork plugin-2647312
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #2
xanoComment #3
xanoComment #4
xanoComment #5
xanoThis requires #2537732-105: PluginFormInterface must have access to the complete $form_state (introduce SubFormState for embedded forms).
It also improves the naming of the different complete and embdded form and form state variables throughout the codebase, to keep it readable.
Comment #6
xanoRe-roll, and enabling testing now [#11278695] has been fixed.
Comment #11
xanoThis fixes all unit test failures.
Comment #14
xanoComment #17
xanoTriggering new tests, because the previous ones failed because of something Java on Jenkins.
Comment #18
berdirThanks for the ping. Can't check right now, but I will test this in our environment and against our tests asap.
Comment #19
xanoThe last patch introduces
E_USER_DEPRECATEDerrors to the existing plugin selectors' embedded forms, for when they receive a form state that does not implemenSubformStateInterface. It's by design, to help people migrate and debug, but it may show up quite often in your automated tests.Comment #20
xanoRe-roll.
Comment #21
hamrant commentedTrying to apply last patch on plugin 8.x-2.4 and seems it need Re-roll.
My problem is that block field from plugin not save block settings, because in blockSubmit $form_state I get parent form state, and I think this patch should solve this problem.
@Xano, you made great job, thanks, I hope that you will finish this patch
I change priority of this issue because I think it quite critical for this module
Comment #22
sanchiz commentedThis patch is applicable for module version 2.5.
Comment #23
hamrant commentedConfirm, on 8.x-2.5 works great, thanks @Xano
Comment #24
bradjones1So I hate to effectively re-open this, though it's been "stuck" in RTBC for over a year. I ran into the issue described in #2994724: Trying to add more than one instance of a plugin field (through paragraphs) prevents saving node and initially thought it sounded like the issue in IEF that spawned another long-RTBC'd patch, #2653574: Unable to keep nested IEF data separate with multivalue fields.. However, applying that had no effect. It appeared the issue was indeed in plugin module.
I tracked this down to the interdiff'ed line in the enclosed patch;
PluginSelector::getPluginSelector()stored information regarding the selected plugin in the complete form's storage, using a key of the field name and delta. If you have, for instance, a paragraph type with a plugin field attached, and add more than one in the same complete form, these keys collide. I added a hash of the element's parents, since I think that should be one of the only stable ways of generating a key, since new entities don't have an ID. (I usedjson_encode()to serialize the parents array since I've read this is faster, and gets a similar effect of a hashable string.)Comment #26
dubs commentedSadly this didn't work for me. I had to manually apply the patch and still the config doesn't save when referenced in paragraphs.
Comment #27
dubs commentedHere's a new patch for the latest version. It does work if you delete the field data and re-add. There are still issues - if you change the plugin type you don't immediately see the config form (if you have one) for that plugin - you have to save the entity and re-edit to see the form. Aside from that, it seems to work okay.
This patch is purely a re-roll of the previous patch from @bradjones1 for the latest version of the module, so thanks for the work Brad :-)
Comment #28
bradjones1Thanks, Dubs. The Form API is my nemesis as well. Bumping to needs review for testbot.
Comment #29
fenstratAttached is a re-roll of #20 for 2.x-dev/2.7. It's passing locally for me, interested to see what the bot makes of it.
It still doesn't fully fix the issue with paragraphs noted in the previous few comments, I'm still digging into those.
Comment #30
fenstratAttached adds the changes from #24 which seem to be the correct approach to handling unique keys for things like multivalued paragraphs, nice catch @bradjones1!
Not quite sure how to go about testing this without introducing a test dependency on paragraphs?
There's still a (relatively) minor issue with the ajax I haven't got to the bottom of. It's fine on first form load (add/edit), but subsequent requests (e.g. by selecting a different plugin type) the config form doesn't get properly replaced and leaves the old stale form in place.
Also worth noting that we had a custom implementation to expose plugins which extended PluginBase. These are referenced via paragraphs and wouldn't save any config for those plugins with the patch here (others have mentioned that before with paragraphs). It was overriding the submitConfigurationForm() with
$this->setConfiguration($form_state->getValue($form['#parents']))and this is what broke with this switch to Subforms. The fix there was to switch that to simple$this->setConfiguration($form_state->getValues()).Comment #31
bradjones1I don't think you'd have to pull in all of paragraphs, just have a test that replicates (or even borrows code from) the specific piece of paragraphs that causes this.
Thanks for the review - I'm not super active on the project/subsystem that I discovered this on but I'm hopeful that this will help move the issue forward. Form API is so tricky. Test coverage will surely help.
Comment #32
fenstratRe-roll of #30. Still needs tests as per #31.
Comment #33
podarok#32 fixes https://www.drupal.org/project/plugin/issues/3174110 in Drupal 9
Comment #34
steffenrI can confirm, that #32 also works fine for us in drupal 9. Thx.
Comment #35
dubs commentedThis patch is still essential to work with config forms on plugins. Can it please be committed?
Comment #36
bradjones1Let me see about getting this in and rolling a release this week.
Comment #37
steffenrSince nearly a year passed since your last comment, i wonder, if there is any progress in the issue.
@bradkones1: Did you find time checking the patch / rolling a new release fixing the problem?
Thx in advance.
Comment #38
froboyIt's been a minute. Here's a rerolled patch for 8.x-2.12. Interdiff shows only indexes and surrounding text have changed.
Comment #39
ckaotikThis is a great upgrade and fix at the same time, thank you! The fix itself still applied to the current version (2.13.0). What's left to get this committed?