Problem/Motivation
Under some circumstances, EntityDisplayFormBase (Form Display) throws PHP notices when opening field settings for Media Library Widget.
After digging into the codebase and trying to reproduce the issue, it was noticed that opening media widget settings triggers extra after_build callback that is attached to the media library settings renderable array.
This is happening because MediaLibraryWidget::settingsForm() attaching settings directly to the incoming $form array and then returns the whole form instead of just extra elements.
Steps to reproduce
- Enable the "Media Library" module.
- Add a field of type "Media" to a content type. In the entity form display, set the display to "Media Library."
- Add a second field of any type to the content type & save.
- Click the form widget display gears for the field of type "Media".
- The logs will show a PHP notice relating to the second field (and presumably any fields added subsequent to the Media field), reading Notice: Undefined index: field_test2 in Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity()
Proposed resolution
Return array of settings form items instead of appending settings to the existing form.
Remaining tasks
Review, commit.
| Comment | File | Size | Author |
|---|---|---|---|
| #32 | 3134554-pass.patch | 2.73 KB | larowlan |
| #32 | 3134554-fail.patch | 1.29 KB | larowlan |
| #17 | Screenshot 2021-05-25 at 23.24.25.png | 167.3 KB | matroskeen |
| #13 | before.png | 89.29 KB | paulocs |
| #13 | after.jpg | 40.68 KB | paulocs |
Issue fork drupal-3134554
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:
- 3134554-media-library-widget-notices
changes, plain diff MR !716
Comments
Comment #2
nils.destoop commentedThe notice is from core, but in your backtrace, I see that autosave is doing the submit. Moving this to autosave.
Comment #3
hchonovAutosave 2.x is doing a submit, but it is a regular submit and therefore the error is not related to autosave.
It just overrides the form builder but does not manipulate the submitted values or anything that might be causing such errors.
Moving back the issue.
Comment #4
nils.destoop commentedMoving to core and media module ;). Probably best to give more info about all fields on the entity
Comment #5
phenaproximaThis needs steps to reproduce, from a clean installation of Drupal.
Comment #6
phenaproximaComment #7
anybodyI can sadly confirm this problem. Media library form dispay widgets can not be edited currently due to this bug.
Here's my backtrace (no Autosave used, I think Autosave is unrelated here):
It happens for ALL fields on the entity so there are lots of errors messing up the form display page.
I think one very important information is, that it only happens for Media Entity References with Media Library widget. All other field form display settings (gears) work without this error!
If I switch the same field to Inline Entity Reference, the settings work. So I think it's very realistic that this error is caused by the Media Library widget in combination with ??something??
I'm courious if it has to do with layout_builder or perhaps with a messed up configuration... no idea yet how this could be caused.
**Workaround info:** With devel kint error (notice) display disabled I was at least able to set the fields as required.
Comment #8
mark_fullmerThis is a core problem in the Media module, and is not related to the enabling of Layout Builder. Here are steps to reproduce (done on a vanilla Drupal 9.1.8 site).
1. Enable the "Media Library" module.
1. Add a field of type "Media" to a content type. In the entity form display, set the display to "Media Library."
1. Add a second field of any type to the content type & save.
1. Click the form widget display gears for the field of type "Media".
1. The logs will show a PHP notice relating to the second field (and presumably any fields added subsequent to the Media field), reading Notice: Undefined index: field_test2 in Drupal\field_ui\Form\EntityDisplayFormBase->copyFormValuesToEntity()
Based on the above, I suggest we change the issue title to "Media fields with Media Library form widget trigger PHP 'Notice: Undefined index'"
Comment #9
mark_fullmerComment #10
phenaproximaRan the steps to reproduce and I can confirm this happens. It didn't produce a visible error for me, but one did show up in the logs.
Comment #11
matroskeenI'm editing the issue summary and will open a merge request with the fix soon.
Stay tuned :)
Comment #13
paulocsMR looks good. We just need test coverage.
MR 716 removes the gears of the media widget if one media type is allowed.
See images attached.
Comment #14
matroskeenI think it's fine given there is nothing to configure in this case.
What kind of test coverage do we expect here?
I noticed there is
MediaLibraryWidgetTest, which is a Kernel test.Creating a functional test for this type of thing seems like overhead to me.
Comment #15
phenaproximaWe need a test that causes PHP to produce the notice in question, so we can prove that your bug fix prevents the error from happening. It's not super important whether it's kernel or functional -- I'd actually prefer kernel in this case, if we can -- as long as its execution path is realistic and causes the notice to happen.
Comment #16
phenaproximaNot entirely sure about this. Is there a precedent in core already where a widget with nothing to configure doesn't show a gear icon? Or do all widgets show their gears, even if there are no settings? I ask because it it can be hard to get something committed if it deviates from existing UI patterns in core, even if those patterns are sub-optimal.
If there's not existing precedent, we might need UX team sign-off here.
EDIT: Looking at the screenshots @paulocs posted in #13, it appears that there are indeed other widgets which hide their gear in certain circumstances (see the "Authored on", "Comments", and "URL alias" fields in the before image). So, given that we have a precedent we can point to, I agree with you, @Matroskeen. Let's just get a test written, and land this thing!
Comment #17
matroskeenYep, this is default Drupal core behavior:

Comment #20
phenaproximaTransferring credit from #3188588: EntityDisplayFormBase (Form Display) throws Notices when opening field settings for Media Library Widget.
Comment #21
matroskeenThanks for moving credits here!
I also checked other core widgets to make sure they're using settings form correctly - everything's fine (no follow-ups to be created).
Regarding the test coverage, we can add something for the media widget, but it feels that we should have general protection for every widget provided by Drupal core. We can simply check whether
WidgetBase::settingsForm()is not modifying the input array, but creates a new one.Do you think this test would be relevant?
Comment #22
phenaproximaI'm not sure how we could protect against this generically for every possible widget, including widgets in contrib and custom code. But more to the point, that would significantly expand the scope of this issue and make it harder to commit...all to avoid what is, at the end of the day, a simple bug with a simple fix :)
The best thing to do here, I think, is to test and fix the bug for Media Library specifically. But by all means, please open a follow-up issue to discuss a generic guardrail if you feel strongly about it!
Comment #23
paulocsI'll write tests for it.
Comment #24
paulocsI added two lines in the functional js test.
I know #15 is asking for a functional or kernel test but maybe it is okay to add those lines in the functional JS test.
Please let me know.
Thanks!
Comment #25
phenaproximaI think adding those lines to the existing functional test is perfectly fine.
Comment #26
paulocsIs this a RTBC?
Comment #27
phenaproximaI need to do a bit of research into existing core code, and review the merge request, before I'd feel comfortable RTBCing this. Once I do have a moment, I'll update this issue's status so you'll know. :)
Comment #28
phenaproximaI think this is ready to go.
I did a little research into other core field widgets and discovered that, indeed, this is something Media Library has been doing incorrectly. It's kinda amazing that it didn't break anything else! I was originally thinking that renaming $form to $elements was out of scope, but given what other core widgets are doing, I think it makes sense. Other widgets are doing similar things.
The tests don't specifically check for the error message, but that's okay -- the proper fix here ensures that error should never show up anyway, and we are testing that the fix works as intended. So testing for the error message, or lack of it, would be beside the point. We could add a kernel test to prove that
MediaLibraryWidget::settingsForm()doesn't return unexpected elements, but that seems a tad overzealous to me.So full steam ahead, I say!
Comment #29
larowlanThanks for working on this folks.
I've been caught by similar issues in custom code, including one that ended up in an endless loop.
Can we get a fail/pass patch here (yes I realise this is an MR) to demonstrate that the test covers the bug we're trying to resolve.
Thanks
Comment #30
larowlanSaving issue credit for @phenaproxima who has provided reviews that shaped the final patch
Comment #31
phenaproxima@larowlan: I was initially going to ask for a fail patch too, but I realized that the actual proper fix here is to remove the very UI element which would allow the error to be triggered in the first place. Given that, I'm not sure how we could do a fail patch, since the condition that could cause the notice is completely eliminated.
So, tentatively restoring RTBC here, but please do send this back if I've missed something.
Comment #32
larowlanI tested this locally, and was able to reproduce it.
My log was full of such errors.
I then applied the patch, and it worked as promised.
Looking at the test, it should fail without the patch, because the button will be present, even though there's no form to edit.
So here's fail/pass patches to confirm
Comment #36
catchCommitted/pushed to 9.3.x and cherry-picked to 9.2.x, thanks!