Problem/Motivation
Drupal\Core\Render\Element\Item has following documentation:
Provides a display-only form element with an optional title and description.
However, when item is rendered inside a form, it gets added to form state. This has potential side effects for example with config forms that are trying to save all values from form state. See #3082672-65: Form prefix/suffix redesign in Claro for an example of that.
Proposed resolution
Preferable approach would be to not add item elements to the form state. If this is not possible, we should at least update the documentation to make it clear that the item elements are not display only since they get added to the form state.
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comments
Comment #2
lauriiiHere's a failing test for this
Comment #4
tim.plunkettHmm this was added in #1825044: Turn contact form submissions into full-blown Contact Message entities, without storage to allow forms to sometimes use
#type => itemand sometimes use#type => textfield(or whatever), but to always have consistent $form_state.I'm not sure at the moment of a good workaround/fix. But just to see, let's find out what breaks.
Also, interesting to note that declaring #input (either TRUE or FALSE) is pointless in a FormElement, as ElementInfoManager forcibly sets it to TRUE anyway.
Comment #5
bnjmnmComment #7
bnjmnmI tracked down the origin of the code that removed in #4, which fixes the reported issues : #1825044: Turn contact form submissions into full-blown Contact Message entities, without storage
An earlier iteration of the comment we're removing helped me better understand the reason it was added
I did some xdebugging and confirmed that if a field is changed to
#type => 'item'there will be no submitted form values available for it, so should be fine to remove'#input' => trueand have it extend RenderElement instead. I suspect it was possible at some point to do this, hence the change, but something changed in the 8 years that followed.That alone should probably be sufficient confirmation that this can be removed without risk, but I did check a few more things
Contact Form has a test:
\Drupal\Tests\contact\Functional\ContactPersonalTest::testSendPersonalContactMessagewith a form that renders the 'name' and 'mail' fields as#type => 'item'and also confirms the contents of the submission include the correct data. This still works after the changes in #4This isn't surpriseing as
\Drupal\contact\MailHandler::sendMailMessagesdoes not use 'name' or 'mail' if the user submitting the form is authenticated, and that is the only core handling of that submission.It does not appear as if the comment module has any inputs that dynamically change to
#type => 'item'. It's quite possible this also changed in the 8 years since that change. Either way, it shouldn't be a concern as it's not possible for#type => 'item'to provide values anyway, even if it's extending formElement.No functionality is lost via the changes to Item.php, but we do gain the ability to use code>#type => 'item' fields in schema'd forms.
Comment #8
alexpottI think we need to be careful here. At the moment the Item element can act like a Value element - if you set #value or #default_value on the element then it'll be in form state. I think for example, http://grep.xnddx.ru/node/30909464#line-118 might use this feature. I'm not common I searched through plenty of contrib to find this.
I think we need to think about deprecating support for #value and #default_value on the Item element and once we've done that we can change to a render element.
Comment #9
bnjmnmIn #7 my evaluations led me to mistakenly believe that #value and #default_value on an
itemelement did not get added to form state in a useful manner - only enough to result in schema errors . I checked again based on #8 and confirmed I was incorrect.The suggestion in #8 "think about deprecating support for #value and #default_value on the Item element" sounds good. At first glance it seems like anything that could be accomplished by adding values to
itemelements in a form could also be done with a combination of hidden and markup fields.Comment #10
bnjmnmI looked into what would be needed to go about deprecating #value and #default_value on an
itemelement. The patch as-is definitely has some BC breaks, and it's possible that there are more core uses that need changing but aren't surfaced by test coverage.If the deprecation checked for just the presence of #value or #default_value, then I believe all uses of
itemwould fail since#input => true?From what I can tell, making these changes would probably be too much of a BC break to do in 9, although it may be possible to reproduce the end result by manually adding form classes to the
itemelements that have been converted tocontainer. My suspicion, however, is the best we could do in Drupal 9 is a deprecation that is added to the skipped deprecations list of our tests then make the changes in 10. Hope to find out I'm wrong about this as it would make the current obstacles in #3082672: Form prefix/suffix redesign in Claro easier to address.Comment #13
larowlanDid last week's security release impact this? Is this still relevant?
Comment #16
kristen polThanks for reporting this issue. We rely on issue reports like this one to resolve bugs and improve Drupal core.
As part of the Bug Smash Initiative, we are triaging issues that are marked "Postponed (maintainer needs more info)". This issue was marked "Postponed (maintainer needs more info)" almost a year ago with a request for more information and there has been no activity since that time.
Since we need more information to move forward with this issue, I am tagging for Bug Smash Initiative and keeping the status at Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!
Comment #17
lauriiiThis bug still exists. Here's the test-only patch from #2.
Comment #19
Aadhar_Gupta commentedPatch for d10 fixing test cases in comment #17
Comment #20
smustgrave commentedIf this was a reroll from #10 looks like some changes are now missing.
Please include an interdiff with patches and a comment for how it no longer applies.