Support from Acquia helps fund testing for Drupal Acquia logo

Comments

yched’s picture

Title: PHP notice on multiple items image field » PHP notice in Field::getFieldSetting($unknown_setting)
Component: image system » field system
Status: Active » Needs review
FileSize
665 bytes

Right. That's because ImageWidget subsclasses FileWidget, which in some cases (when cardinality > 1) uses the 'display_field' setting, which does not exist for image fields.
That's slightly shaky, but is acceptable IMO since this is just used to populate a #property that ends up not being used if what runs is an ImageWidget.

The getFieldSetting() method should be resilient on such cases, and return NULL if the setting is unknown for the field type.
Patch attached.

effulgentsia’s picture

The getFieldSetting() method should be resilient on such cases

I don't know that I agree with that. I wonder if there's a way to handle the "subtype" case without removing the strictness otherwise.

amateescu’s picture

Status: Needs review » Reviewed & tested by the community

Unless we want to throw an exception, which would be an overkill for this situation imo, the reasoning and fix makes sense :)

Edit: Crossposted with Alex, please feel free to set it to NW if you think it needs more discussion.

effulgentsia’s picture

Status: Reviewed & tested by the community » Needs review

How about adding a $strict parameter (defaults TRUE) to getFieldSetting()? In situations where formatters/widgets don't care about whether the setting exists, they can explicitly pass FALSE.

yched’s picture

@eff: what are your concerns about returning NULL ?

effulgentsia’s picture

@eff: what are your concerns about returning NULL ?

The same as why PHP issues a notice when accessing any other undefined variable or array key. More strictness leads to better finding of code flaws and more maintainable code. By default, calling getFieldSetting() with a setting name not defined by the field type is nonsense, and is likely to be a result of a typo, or a code refactoring that missed some hunks, for which a notice is useful.

ImageWidget subsclasses FileWidget, which in some cases (when cardinality > 1) uses the 'display_field' setting, which does not exist for image fields. That's slightly shaky

Exactly. Ideally, we should fix that. We need to decide if ImageItem should extend FileItem. If yes, then it should also include all of the base type's settings, even if they're not used, just as PHP classes inherit the base class's public properties even if the subclass doesn't use them. If not, then I don't think it makes sense for ImageWidget to subclass FileWidget; instead maybe we need an abstract base class for each widget to subclass.

but is acceptable IMO since this is just used to populate a #property that ends up not being used

Yep, for rare cases where we know we're doing something not really right, but also not problematic, that's where I think a 2nd parameter to getFieldSetting() would be acceptable.

yched’s picture

You're right of course, failing with a notice is better than silently returning null, that's the whole point of developing with E_ALL.
It's just that the current notice is not really telling though - maybe we should add a custom trigger_error() message here 'unknown setting' or something.

When working with PHP arrays you typically use isset() when unsure - so maybe we should have hasFieldSetting() ?
Then it's up to FileWidget to know it's reused by ImageWidget (we're core...), on fields which might not have the 'display_field' setting ?

We need to decide if ImageItem should extend FileItem.

I think that's the plan, and thats what #2015697: Convert field type to typed data plugin for file and image modules is doing.

If yes, then it should also include all of the base type's settings, even if they're not used, just as PHP classes inherit the base class's public properties even if the subclass doesn't use them. If not, then I don't think it makes sense for ImageWidget to subclass FileWidget; instead maybe we need an abstract base class for each widget to subclass.

Hm, interesting / tricky.
The file field type does have a couple 'settings' (both field and instance level) that the image field type doesn't have.
Same for 'properties', BTW.

I'm not sure that reasoning holds. Class inheritance is purely a contract on members.
If it applies to "field and instance settings", I guess it also applies to "properties" (they are "almost" members, luckily they happen to be magic and exposed through a method).
There's no guarantee that an Item class has the same settings or TypedData properties as a parent, it's only about code reuse IMO.

yched’s picture

Well, one quick workaround is to use $this->getFieldSettings(), and work on the array.
Turns out, FileWidget::formElement() does exactly this already.

effulgentsia’s picture

Title: PHP notice in Field::getFieldSetting($unknown_setting) » PHP notice on multiple items image field
Status: Needs review » Reviewed & tested by the community

#8 solves the OP, but not the broader scope in the issue title change from #1, so restoring original title.

maybe we should have hasFieldSetting() ?

That seems good to me. Want to file a separate issue for that?

There's no guarantee that an Item class has the same settings or TypedData properties as a parent, it's only about code reuse IMO.

This could use some more discussion. I'll take a look at #2015697: Convert field type to typed data plugin for file and image modules and will add some thoughts there if relevant, or open a separate issue if needed.

effulgentsia’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: +Needs tests

Oh wait, the fact that bot didn't catch this bug to begin with indicates we're missing some test coverage for editing a multivalued image field.

swentel’s picture

Assigned: Unassigned » swentel

I'll write a test later this evening - unless someone beats me to it.

swentel’s picture

Status: Needs work » Needs review
FileSize
1.96 KB
783 bytes

fail patch will trigger the notice, pass will be green. I've kept it really easy as we do have tests for uploading multiple files already, so I think we're ok.

swentel’s picture

Assigned: swentel » Unassigned
Issue tags: -Needs tests

tests are added.

yched’s picture

thanks ! Back to RTBC then ?

Berdir’s picture

Status: Needs review » Reviewed & tested by the community

We have test coverage, the notice is fixed, the same code already exists in a different place, @effulgentsia was ok with the fix too. I'd say yes :)

catch’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.phpundefined
@@ -205,6 +205,10 @@ function testImageFieldSettings() {
+    // Set cardinality to unlimited.
+    $this->drupalPost('admin/structure/types/manage/article/fields/node.article.' . $field_name . '/field', array('field[cardinality]' => FIELD_CARDINALITY_UNLIMITED), t('Save field settings'));

There's no assert here - this at least needs a comment to explain that it's testing the absence of a notice, but a positive test would be better.

The change looks not ideal, but it's an improvement on #1 and I couldn't really find a better place to fix this..

swentel’s picture

Issue tags: +Field API

Right, makes sense, while adding asserts, I actually got new notices. Also tagging so I can follow it on our board.

swentel’s picture

Status: Needs work » Needs review
FileSize
1.52 KB
2.69 KB

More comments and positive asserts + an extra upload as well.

yched’s picture

Status: Needs review » Reviewed & tested by the community

Looks good.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -223,6 +223,19 @@ function testImageFieldSettings() {
+    $this->drupalPost('admin/structure/types/manage/article/fields/node.article.' . $field_name . '/field', array('field[cardinality]' => FIELD_CARDINALITY_UNLIMITED), t('Save field settings'));
...
+    $this->drupalPost('node/' . $nid . '/edit', $edit, t('Save and keep published'));

#2074037: Add drupalPostUrl() — drupalPost()/drupalPostAjax() are for forms only, D8 JS performs non-form HTTP requests has changed drupalPost to drupalPostForm

swentel’s picture

Status: Needs work » Reviewed & tested by the community
FileSize
2.7 KB

So this should work then ?

swentel’s picture

Issue tags: -Field API

Status: Reviewed & tested by the community » Needs work
Issue tags: +Field API

The last submitted patch, unknown_field_setting-2050113-21-pass.patch, failed testing.

yched’s picture

+++ b/core/modules/image/lib/Drupal/image/Tests/ImageFieldDisplayTest.php
@@ -223,6 +223,19 @@ function testImageFieldSettings() {
+    $edit['files[' . $field_name . '_' . Language::LANGCODE_NOT_SPECIFIED . '_1][]'] = drupal_realpath($test_image->uri);

Now that #2083811: Remove langcode nesting for fields in entity $form structures got in, this should be 'files[' . $field_name . '_1]' :-)

swentel’s picture

I know, but now I'm getting notices again, it's freaky ...

swentel’s picture

Status: Needs work » Needs review
FileSize
1.96 KB
3.48 KB

Finally have this. This also contains a fix that you can only reproduce on PHP 5.4.4 and our testbot doesn't catch on 5.3 ...

amateescu’s picture

+++ b/core/modules/image/lib/Drupal/image/Plugin/field/widget/ImageWidget.php
@@ -94,7 +94,12 @@ protected function formMultipleElements(FieldInterface $items, array &$form, arr
-      $elements['#file_upload_description'] = drupal_render($file_upload_help);

I suppose there is some code above that sets the $file_upload_help variable, is it still used anywhere else or can it be removed?

yched’s picture

Status: Needs review » Needs work

Yep, it seems ImageWidget::formMultipleElements() needs some additional cleanup :-)

Hydra’s picture

Status: Needs work » Needs review
FileSize
4.39 KB
1.52 KB

Okay something like this? Cleand up the multiple case and removed $file_upload_help variable.

Hydra’s picture

An other version, keeping the $file_upload_variable to avoid duplicated code, suggested by yched.

yched’s picture

Status: Needs review » Reviewed & tested by the community

Cancelled the test for #29.

#30 looks good if green - thanks !

Status: Reviewed & tested by the community » Needs work

The last submitted patch, unknown_field_setting-2050113-30.patch, failed testing.

netsensei’s picture

Status: Needs work » Needs review
FileSize
997 bytes
3.37 KB

We need those drupal_render() functions around $file_upload_help.

Rerolled the patch. This should pass.

yched’s picture

Wait, I thought we needed to remove those drupal_render() calls ?
(fwiw, they were removed in FileWidget already)

swentel’s picture

FileSize
651 bytes
3.67 KB

We actually can only drop one drupal_render() ..

Berdir’s picture

swentel’s picture

Hmm might be, although should start testing. I do know we don't have this issue in D7 IIRC - it would have popped up much more I guess.
This patch also fixes a stupid php 5.4 bug.

yoroy’s picture

Manually tested this. I changed the image field in the core Article content type to allow multiple fields. Before patch I get the notice, after the patch, no more notice. Tested locally under PHP 5.4.4.

longwave’s picture

Status: Needs review » Needs work

The last submitted patch, 39: 2050113-multiple-image-field-warning-39.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
FileSize
3.91 KB
1.35 KB

Forgot that the FIELD_CARDINALITY_UNLIMITED has moved as well.

swentel’s picture

Status: Needs review » Reviewed & tested by the community
webchick’s picture

The last submitted patch, 41: 2050113-multiple-image-field-warning-41.patch, failed testing.

webchick’s picture

Status: Reviewed & tested by the community » Needs work

...doing your job for you, testbot.

marthinal’s picture

Should apply now.

marthinal’s picture

Status: Needs work » Needs review
swentel’s picture

Status: Needs review » Reviewed & tested by the community

Yep, thanks

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed 185c50b and pushed to 8.x. Thanks!

penyaskito’s picture

Status: Fixed » Closed (fixed)

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

swentel’s picture

ridiculous quick follow up at #2639796: file widget duplicate code