Problem/Motivation

Similar, but not quite the same as #2715859: ImageWidget::validateRequiredFields() produces an error message if an image field is hidden with hook_entity_field_access().

ImageWidget::validateRequiredFields() currently makes an assumption that a #submit array will be present on the return value of $form_state->getTriggeringElement() but that's sometimes not the case (e.g. if a form has been submitted by a non-button via ajax).

This can result in PHP Warnings like this:

Warning: in_array() expects parameter 2 to be array, null given in Drupal\image\Plugin\Field\FieldWidget\ImageWidget::validateRequiredFields() (line 256 of ...docroot/core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php).

Proposed resolution

A simple tweak to avoid this would be to check for the presence of the array before using it in a function call e.g.:

   public static function validateRequiredFields($element, FormStateInterface $form_state) {
     // Only do validation if the function is triggered from other places than
     // the image process form.
-    if (!in_array('file_managed_file_submit', $form_state->getTriggeringElement()['#submit'])) {
+    if (is_array($form_state->getTriggeringElement()['#submit']) && !in_array('file_managed_file_submit', $form_state->getTriggeringElement()['#submit'])) {

...patch on the way in #15 but minor changes requested in #26.

Remaining tasks

  1. Write patch (done in #15)
  2. Review patch. (done in #15 and #26)
  3. Revisions (minor issues found in #26)
  4. RTBC (success stories for the patch in #15 are in #18, #20, #22, and #27)
  5. Core maintainer review and feedback
  6. Commit

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

mcdruid created an issue. See original summary.

mcdruid’s picture

Status: Active » Needs review
StatusFileSize
new1021 bytes
mcdruid’s picture

Issue summary: View changes
mcdruid’s picture

Issue summary: View changes
mcdruid’s picture

Status: Needs review » Needs work

Actually, if the intention of the check is to:

  // Only do validation if the function is triggered from other places than
  // the image process form.

...the simple approach of checking for the #submit array on the triggering element in the if condition (before looking for a specific key within the array) avoids a possible PHP Warning, but would also mean that the validation doesn't take place if the form's submitted by a non-button. I don't think that's how this is supposed to work.

However, there's already an else clause in the logic... So I'm taking another look at how to avoid the PHP Warning without stopping the validation from happening when it should, or causing other problems.

tim.plunkett’s picture

Issue tags: +Needs tests
mcdruid’s picture

StatusFileSize
new1.29 KB

New patch which reverses the check for the form being submitted by a file_managed_file_submit button, which I think avoids the previously outlined problem where non-button submissions would skip validation.

Also changed to use isset instead of is_array as with the latter PHP still emits a Notice: Undefined index: #submit.

I believe this works okay now (I've verified there are no PHP errors but that the validation runs when the form is submitted via a non-button / ajax callback), but will look at tests next per tim.plunkett's update.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.0-beta1 was released on August 3, 2016, which means new developments and disruptive changes should now be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

juampynr’s picture

Status: Needs work » Needs review
StatusFileSize
new1.03 KB

Here is an alternative version where I am just adjusting the condition. I have verified that this works at the project I am working at, where there is a form with an image field plus a custom field with an AJAX handler. It is when I trigger the custom field's AJAX request that this error happens.

I will now see if I can reproduce this in a test.

juampynr’s picture

StatusFileSize
new7.97 KB
new6.95 KB

Here are two patches. One is #9 with a test and the other is the test that proves the bug.

juampynr’s picture

Issue tags: -Needs tests

Removing Need Tests tag.

Status: Needs review » Needs work

The last submitted patch, 10: 2745491-10-test-only.patch, failed testing.

juampynr’s picture

Status: Needs work » Needs review
juampynr’s picture

Is there anything missing at #10 that I could improve?

mcdruid’s picture

StatusFileSize
new33.62 KB
new6.76 KB
new7.79 KB

Great work getting the test done juampynr!

The only tweak that I'd suggest is that I don't think it's necessary to test for the absence of the PHP Notice:

     $this->drupalPostAjaxForm(NULL, $edit, 'field_dummy_select[select_widget]');
-
-    // Reload the Add new article page. There should be no warning messages.
-    $this->drupalGet('node/add/article');
-    $this->assertNoText('Notice: Undefined index: #submit');
   }

So here are the same two patches with that removed.

We expect the test-only patch to produce two exceptions:

PHP exceptions

I ran this past tim.plunkett and he agreed that's sufficient.

The last submitted patch, 15: 2745491-15-just_test.patch, failed testing.

mcdruid’s picture

Just to confirm, the test that failed is the one we expect to fail; it's the proof that there is a problem before the code is changed:

Drupal\image\Plugin\Field\FieldWidget\ImageWidget::validateRequiredFields
exception: [Notice] Line 256 of core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php:
Undefined index: #submit

exception: [Warning] Line 256 of core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php:
in_array() expects parameter 2 to be array, null given

So this just needs further review, and is not awaiting more work AFAIK.

mariacha1’s picture

Status: Needs review » Needs work

This patch works great for me (also applies in 8.2!), but given the feedback in #15, I'm setting this to Needs Work.

juampynr’s picture

Status: Needs work » Needs review

@mariacha1, I think that what @mcdruid means at #15 is that his patch makes a small adjustment. We believe that there is nothing left to do but waiting for core reviewers to chime in. Thanks for testing the patch though!

tobias.grasse’s picture

Patch in #15 works great, applied on 8.2.x site.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.0-alpha1 will be released the week of January 30, 2017, which means new developments and disruptive changes should now be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

xsdx’s picture

Tested patch #15 works fine. Fixed issues with Address module when using on same form with imagefield.

jasonawant’s picture

Cross referencing: Adding related issue: https://www.drupal.org/node/2346893. That issue's patch conflicts with this one in /core/modules/image/src/Tests/ImageFieldValidateTest.php.

mcdruid’s picture

Patch from #15 still applies at the moment, but may need a re-roll if #2346893: Duplicate AJAX wrapper around a file field lands first; thanks for the link @jasonawant

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

gambry’s picture

Status: Needs review » Needs work

Minor issues:

  1. +++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
    @@ -156,4 +159,43 @@ protected function getFieldSettings($min_resolution, $max_resolution) {
    +    // Add a custom field to the Article content type that contains
    +    // an AJAX handler on a select field.
    

    Inline comments should try to get to 80chars limit as close as possible.

  2. +++ b/core/modules/image/src/Tests/ImageFieldValidateTest.php
    @@ -156,4 +159,43 @@ protected function getFieldSettings($min_resolution, $max_resolution) {
    +    entity_get_form_display('node', 'article', 'default')
    

    entity_get_form_display() is deprecated. Its docblock gives hints on what to replace it with.

  3. +++ b/core/modules/image/tests/modules/image_module_test/src/Plugin/Field/FieldWidget/DummyAjaxWidget.php
    @@ -0,0 +1,57 @@
    + * Default widget for Zeus videos.
    ...
    +   * Ajax callback to update the video widget fields when select is changed.
    ...
    +   *   Ajax response with updated widget for video.
    

    These need to be updated as they refer to a video widget.

mparker17’s picture

Issue tags: +Needs backport to 8.3.x
StatusFileSize
new8.78 KB

The problem addressed in this issue is occurring for me on a client site running drupal-8.3.7 and address-8.x-1.1 — selecting a country from the select list in the first step of an address widget fails to AJAX-load the rest of the address widget fields because the validation for an image widget much lower down on the node/add page breaks validation for the address widget.

The patch in #15 fixes the issue; but Composer can't apply it automatically because the patch context doesn't match exactly (Hunk #1 succeeded at 256 (offset 3 lines) while patching file core/modules/image/src/Plugin/Field/FieldWidget/ImageWidget.php), so I'm uploading a copy of the patch in #15, but generated against drupal-8.3.x to make Composer happy.

Since I've confirmed this is a bug in 8.3.x., and I daresay these are not "disruptive changes", I'm adding the "Needs backport to 8.3.x" tag. Feel free to remove if necessary. There doesn't seem to be a "Needs backport to 8.4.x" tag yet.

mparker17’s picture

Issue summary: View changes

Updating issue summary (especially, Remaining tasks).

gambry’s picture

Issue summary: View changes
Issue tags: -Needs backport to 8.3.x

Since I've confirmed this is a bug in 8.3.x., and I daresay these are not "disruptive changes", I'm adding the "Needs backport to 8.3.x" tag. Feel free to remove if necessary. There doesn't seem to be a "Needs backport to 8.4.x" tag yet.

There won't be any more patch releases for 8.3.x so it's unlikely - I would say impossible - that this patch will ever see 8.3.x. Even more 8.2.x which is now close.
So removing both from remaining tasks and removing the Needs backport 8.3.x tag.

Then I'm not 100% sure what 'Backport to 8.4.x' would mean, as we backport between major versions only AFAIK (i.e. D8->D7). Patches are cherry-picked between minor versions by committers and normally it's at their discretion. As this patch is a non-disruptive bugfix has all the chances to get into 8.4.x.
See https://www.drupal.org/core/backport-policy and https://www.drupal.org/core/d8-allowed-changes .

The patch in #15 fixes the issue; but Composer can't apply it automatically because the patch context doesn't match exactly

I see what you mean, however I'm using #15 with composer against 8.3.7 and applies nicely.

sanduhrs’s picture

Status: Needs work » Needs review
StatusFileSize
new5.73 KB
new9.48 KB

Addressing minor issues in #26 and some code style fixes in touched files.

Status: Needs review » Needs work

The last submitted patch, 30: 2745491-30.patch, failed testing. View results

rodrigoaguilera’s picture

Status: Needs work » Needs review
StatusFileSize
new9.91 KB

Just a rebase

Status: Needs review » Needs work

The last submitted patch, 32: 2745491-32.patch, failed testing. View results

gambry’s picture

Issue tags: +Needs reroll, +Novice

Hi #30 and #31. Thanks for your work! Much appreciated.
However your patches are changing pieces of code out of this issue's scope. I can see all of them are trying to fix Coding Standards issues, but they will need to be fixed in a separated issue.

Can you re-roll patch on #15 and apply feedback from #26?

Adding re-roll tag + setting the current patch back to #15.
Also adding Novice tag as both re-rolling task and comments on #26 are not that complicated. (Global sprint weekend 2018 is coming after all, and we need Novice tasks!)

Thanks a lot to everybody!

snehi’s picture

Assigned: Unassigned » snehi
snehi’s picture

Status: Needs work » Needs review
StatusFileSize
new3.48 KB

Re-rolled and created the patch. Please review.

Status: Needs review » Needs work

The last submitted patch, 36: 2745491-37.patch, failed testing. View results
- codesniffer_fixes.patch Interdiff of automated coding standards fixes only.

mcdruid’s picture

Status: Needs work » Needs review
StatusFileSize
new7.88 KB

Thanks, but it looks like most of the test(s) got chopped out in that reroll somehow.

Here's another attempt at rerolling patch #15 for 8.5.x

This is just the reroll, I've not tried to address the points in #26 yet.

jofitz’s picture

Assigned: snehi » Unassigned
Issue tags: -Needs reroll
StatusFileSize
new1.85 KB
new7.91 KB

Addressed points in #26.

jofitz’s picture

Sorry, only saw this was tagged as Novice after I'd created the patch. :#

snehi’s picture

Looks great now.
+1 for RTBC.

gambry’s picture

Status: Needs review » Needs work

Thank you for the hard work guys!

#26.3 is still outstanding.

mcdruid’s picture

Status: Needs work » Needs review
StatusFileSize
new7.88 KB
new1.12 KB

Removed references to video widgets etc.. in the comments in DummyAjaxWidget.

snehi’s picture

Looks ok to me +1 for RTBC.

gambry’s picture

Status: Needs review » Reviewed & tested by the community
Issue tags: -Novice
Related issues: +#2863626: Convert web tests to browser tests for image module

Looks good to me. The only things I'm not sure is if we should re-write the test to use phpunit instead of simpletest (and so postpone this issue until #2863626: Convert web tests to browser tests for image module is in).
To me it makes sense to add it in there and migrate then all test class at once in its own issue, but not sure if committers will agree.
Adding the related issue and RTBCing.

Thanks everyone for the hard work!

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

  • catch committed 38fca3a on 8.6.x
    Issue #2745491 by mcdruid, juampynr, Jo Fitzgerald, sanduhrs, snehi,...

  • catch committed 63fa6f2 on 8.5.x
    Issue #2745491 by mcdruid, juampynr, Jo Fitzgerald, sanduhrs, snehi,...
catch’s picture

Version: 8.6.x-dev » 8.5.x-dev
Status: Reviewed & tested by the community » Fixed

Committed/pushed to 8.6.x and cherry-picked to 8.5.x. Thanks!

It's OK to add the new method here and convert all the tests in one go together.

Status: Fixed » Closed (fixed)

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