Problem/Motivation
File usage for inline images is only recorded for first field item. When the option "Delete orphaned files" is enabled, inline images in the second or later field items will be deleted.
To reproduce, create a node type with a formatted text field with unlimited cardinality. Add a node and fill two or more field items of the text field with an image. See that the file_usage table only contains references to images added in the first field item.
Proposed resolution
Update _editor_get_file_uuids_by_field() so it takes all field items into consideration, not just the first.
Remaining tasks
Fix.- Tests.
- Get to RTBC.
- Commit.
User interface changes
None
API changes
None
Data model changes
None
RC
Without this fix, file_usage data will be wrong when:
- multi-value formatted text fields are used
- in those fields, the
EditorFileReferenceis active (which tracks images uploaded via a Text Editor infile_usage)
Combined, that means uploaded files may be deleted because Drupal doesn't know an entity uses them.
| Comment | File | Size | Author |
|---|---|---|---|
| #44 | interdiff-2574737-36-44.txt | 5.75 KB | thpoul |
| #44 | 2574737-44.patch | 10.27 KB | thpoul |
| #36 | 2574737-36.patch | 9.96 KB | thpoul |
| #36 | interdiff-2574737-31-36.txt | 3.05 KB | thpoul |
| #31 | 2574737-31.patch | 10.34 KB | thpoul |
Comments
Comment #2
wim leersAmazing find!
This is the culprit:
This does not specify a delta, and so it only access the first item (delta zero).
Note that we do have test coverage for this, we just didn't think about multi-valued formatted text fields.
Comment #3
thpoul commentedIt's indeed a nice catch casey! I think I got it working but still needs the tests.
PS: This is my first patch ever to Drupal so please be kind :)
Comment #4
thpoul commentedComment #6
aneek commentedGreat @thpoul!
Has Whitespace warning upon applying #3 patch. Uploading a new patch by removing the whitespaces.
Tested with the below SQL,
This SQL should not return any NULL value from file_usage table.
@WimLeers, I think you are referring to
\Drupal\editor\Tests\EditorFileUsageTest? I'll have a look at the test suite.Thanks!
Comment #7
aneek commentedComment #8
thpoul commented@aneek oh my editor did it again!
@WimLeers do you think it should be tagged "rc target" ?
Comment #9
wim leersFix looks fine. Still needs tests though.
@aneek: yep, that's the one!
@thpoul: yes, I think this will qualify. To some extent, this is data loss. Tagging accordingly.
Let's rename this variable to
$field_items. "children" is the wrong term here.Comment #10
wim leersUpdated IS to justify .
Comment #11
thpoul commentedChanged variable name as requested to
$field_itemsComment #12
thpoul commentedComment #13
wim leersLooks good. Still needs tests.
Comment #14
wim leersUpdating status for #13.
Comment #15
thpoul commentedTests added :) Hopefully everything is ok. Crossing fingers!
Comment #16
blackra commentedSomething odd is going on here. If I apply just the new tests (the interdiff) against an unpatched 8.0.x then the tests pass, which they shouldn't...
Comment #17
aneek commented@thpoul, great! But can we have a "test-only" patch? This will help us to understand the test and the fix in a better way.
Thanks!
Comment #18
thpoul commented@blackra just realized that the test is only checking multiple inline images in the body field without unlimited cardinality (as described from the op)
I'm writing a new test now
Comment #19
wim leersGreat, thanks! Will review the next patch when it's ready :)
Comment #20
thpoul commentedI have an issue which I don't seem able to figure out. The test fails now for the images of the additional body items.
PS: for some reason the files are cached try uncaching the url to view the actual files correctly
Comment #21
wim leersThe patch isn't relative to latest HEAD; it includes a revert for the last commit to Drupal 8 (#2609110: Update Twig to 1.23.1).
Comment #22
thpoul commentedTry these:
https://www.drupal.org/files/issues/2574737-20-do-not-test.patch?1
https://www.drupal.org/files/issues/interdiff-2574737-15-20.txt?1
Comment #23
wim leersI think @thpoul has uncovered a deeper Entity API bug. Potentially a critical bug.
It seems that when update hooks are called, only the first field item is present, even though there are three field items!
Attached patch adds some debug output that makes this very easy to debug. Raising to critical to bring it to the immediate attention of Entity/Field API experts. If my suspicion is correct, this will of course need to be split off to a separate issue, but given we're so close to RC4, I think it's worth making this issue critical because it makes it very easy to reproduce the problem: just run
EditorFileUsageTest(a very fast test) and observe the problem: all debug output says3, except in one place, where it says1.Review of the patch for @thpoul:
Comment can be removed; this is clear from context.
Missing trailing period.
Missing trailing period.
Trailing whitespace.
Trailing space.
Also, we don't ever use
sizeof(). Usecount()instead.Finally,
$i=0->$i = 0.s/YOLO/modified/ — no need to change this from what it is in HEAD.
Comment #24
dawehnerIMHO having test coverage that we don't loose files for itself is pretty significant.
Comment #26
yched commentedCannot check myself atm. Wondering, though : the test and steps to reproduce in the IS only seem to mention the case of images embedded into a text editor on a formatted text field ? Is that specific to this case ? (as opposed to images directly in an image field ?)
Comment #27
berdirFalse alarm, everything is fine with Entity API, just a bit confusing.
Add this to setUp():
and the test passes.
Also, I would recommend that you rely on the Entity API magic methods to simplify your code, makes it alot easier to read, I initially thought something is wrong with your code there in the loop that changes the value:
It's quite confusing what $body actually is in this scenario (it's not the body field, it's just the string of it). This is IMHO much easier to read, partially because I'm used to it:
See also http://drupal.stackexchange.com/a/180393/31 for a recent DA answer that I wrote on that topic.
Comment #28
wim leersDarn. That crossed my mind, but I dismissed it based on the fact that everywhere else the expected number of field items exists. I guess Entity/Field API simply do not *enforce* the configured cardinality (or even validate it). I think this is the perfect example of where assertions would be valuable?
In any case, many thanks for checking this, Berdir, and sorry for the false alarm!
Comment #29
yched commentedHah, nice job @Berdir :-)
Yeah, entity/field API doesn't prevent extraneous deltas in runtime objects. They just don't get stored (but IIRC that's in the hands of the storage layer) I *think* validation would fail too, but validation is not enforced.
I don't think we ever really discussed enforcing the max delta in runtime FieldItemList objects, nor do I have a clear vision of what the impact would be.
Comment #30
wim leersHence why I think an
assert()makes sense. No impact in production. Developers warned in development.Comment #31
thpoul commentedAfter @WimLeers and @Berdir great input I am attaching what aims to be the last patch for this issue :D
Comment #32
thpoul commentedComment #33
wim leersLots of silly whitespace problems. Easy fixes.
These are indented by 4 instead of 2.
Unnecessary newline addition.
Trailing whitespace.
Double comment indentation :P
Comment #34
wim leersOther than that, this looks great.
Comment #36
thpoul commentedHopefully the curse my ide has, has been removed.
Comment #37
wim leersLooks great! Thank you very much, a very useful first Drupal core contribution! :)
Comment #39
catchDiscussed with xjm and tagging as RC target due to data-loss potential.
Comment #40
alexpottSince these assertion messages are in a loop I think we should be specifying which image.
Comment #41
wim leersThere's only 3 image entities. So each message appears three times. When I was debugging this patch, that wasn't hard to work with at all.
Comment #42
alexpott@Wim Leers I dunno repeated test assertion messages that aren't asserting the same thing seems easy to fix and not something we should be encouraging.
Comment #43
wim leersAlright.
Comment #44
thpoul commented@alexpott you are right! Here it is.
Comment #46
wim leersThanks!
Comment #48
catchCommitted/pushed to 8.0.x, thanks!