Problem/Motivation
In Drupal 7, editing a language selection using the Content Translation module will delete any files stored in a file field in the same node. This behavior is likely present in Drupal 8 and will need to be confirmed and fixed there first.
Proposed resolution
A solution has been proposed in #24 with a corresponding D7 patch. This solution approach has not been reviewed for Drupal 8.
Remaining tasks
- Test to confirm documented D7 behavior persists in D8
- If problem persists in D8, review proposed solution
- If problem persists:
- create D8 patch
- Test and approve D8 patch
- Backport solution to D7
User interface changes
TBD
API changes
TBD
Related Issues
#1399846: Make unused file 'cleanup' configurable
Original report by sreynen.
I've tested this a couple dozen times, but haven't found any pattern. Steps to reproduce:
1) Enable File and Content translation modules.
2) Create a content type with a file field.
3) Enable a few languages.
4) Create a node of any language with a file attached.
5) Edit the node and change the language.
Sometimes step 5 needs to be repeated a few times, sometimes it happens the first time, but eventually the file disappears, both in the node and in the file system. The specific languages don't appear to make any difference.
Proposed solution
See #24.
Comment | File | Size | Author |
---|---|---|---|
#37 | drupal-files_wiped-1141912-37.patch | 4.93 KB | plach |
#35 | drupal-files_wiped-1141912-35.patch | 4.94 KB | plach |
#34 | drupal-files_wiped-1141912-34.patch | 4.42 KB | plach |
#26 | drupal-files_wiped-1141912-26.D7.patch | 4.18 KB | plach |
#24 | drupal-files_wiped-1141912-24.patch | 4.03 KB | plach |
Comments
Comment #1
sreynen CreditAttribution: sreynen commentedOn further testing, the file is not deleted when file_usage_list() returns a count greater than 1, but deleted when file_usage_list() returns a count of only 1. I have no idea what causes that count to sometimes go above 1, as the file is only being used on 1 node.
Comment #2
sreynen CreditAttribution: sreynen commentedI found the pattern, and with it the bug.
The pattern is the order of the languages, the order they're in on admin/config/regional/language and in the language drop-down. This is the order of calls from _field_invoke() to file_field_update(), with a separate call for each language instance of the field. If you change languages moving up that list, the file stays, because the new language instance of the file is added before the old language instance is deleted. If you change languages moving down that list, the file is deleted, because the delete happens before the add.
My initial suggestion for fixing this is to move the add functionality to file_field_presave(), forcing it to happen before the deletes in file_field_update().
Comment #3
sreynen CreditAttribution: sreynen commentedComment #4
camdarley CreditAttribution: camdarley commentedSame problem for me, changing node language from english to language neutral delete file referenced by filefield...
Comment #5
sreynen CreditAttribution: sreynen commentedI'm moving this up to major, since it involved data loss.
Comment #6
catchMoving this to file module for now, I remember there being issues in file_field_insert()/update() before.
Comment #7
catchComment #8
catchoh dear.
Comment #9
webchickFixing tag.
Comment #10
domidc CreditAttribution: domidc commentedI confirm this bug
Comment #11
guillaumev CreditAttribution: guillaumev commentedI can confirm this as well...
Comment #12
camdarley CreditAttribution: camdarley commentedDoes anybody knows how to fix it? That's a major bug! I think it should be fixed on D7 before even think to D8...
Comment #13
camdarley CreditAttribution: camdarley commentedI made this change in file.field.inc in file_field_delete_file function:
As I use the media module, I can't see any situation where a file need to be deleted after a field change... hope i'm right.
Comment #14
aspilicious CreditAttribution: aspilicious commentedNo thats not ok :) you never going to delete files ever. :)
On the other hand this function has been changed in D8. So I wonder if it's still a bug there.
Comment #15
camdarley CreditAttribution: camdarley commentedActually, files are deleted because, as I said, I use the media module which handle files in a different way. You can remove a file from a field, but it still exist in the "media library", and if you want to delete it you have to go in this library and click on delete, thus media_multiple_delete_confirm_submit() is called, which calls file_delete().
Maybe that issue belong to the media module which has to alter file_field_delete_file to do it on its own way...
Back to D7 if the function has already been changed in D8.
Need confirmation for more experienced developers to move this issue to media module...
Comment #16
camdarley CreditAttribution: camdarley commentedComment #17
camdarley CreditAttribution: camdarley commentedI just search for file_field_delete_file issues in media module and here's what I found:
#1239056: Remove Media at content edit page cause the file to be completely deleted from server/database?
And the linked core issue:
#1399846: Make unused file 'cleanup' configurable
So I mark this as a duplicate
Comment #18
sreynen CreditAttribution: sreynen commentedThis is related to #1399846: Make unused file 'cleanup' configurable, but I disagree on calling this a duplicate. That's a feature request, which could be rejected, and may or may not fix this bug if it is applied. This is a bug, which needs to be fixed regardless.
Comment #19
aspilicious CreditAttribution: aspilicious commentedThis a problem with the media module NOT drupal core. It's caused by architectural decisions made in that module. So this can't be called a core bug. So yes this is a duplicate of the other issue.
Comment #20
sreynen CreditAttribution: sreynen commentedI wasn't even running media module when I ran into this bug, so I'm fairly confident it's not unique to media module. The problem, as documented in #2, is with file field, which is part of core.
Comment #21
sreynen CreditAttribution: sreynen commentedComment #22
camdarley CreditAttribution: camdarley commentedActually, I think sreynen is right. Although #1239056: Remove Media at content edit page cause the file to be completely deleted from server/database? should be corrected it belong to media module.
#13 is an easy and dirty workaround for those who use the media module, as it is critical for production sites, but for others, according to aspilicous in #14, files won't be deleted ever.
#2 is actually a start for a solution...
Comment #23
petros CreditAttribution: petros commentedquick and ugly fix...
in file file_field.inc
added this:
before this
also changed the $current_items variable to $original_fids2
very ugly but works. can also be improved with a static variable for caching.
Comment #24
plachHere is a patch addressing this for D7, for which I need a (hopefully) proper fix.
The change in this patch is pretty invasive, but I think the current logic is deeply flawed and cannot be fixed without a radical change in the approach: currently every field and language is checked for changes in the referenced files in isolation, not taking into account that files might be moved around. Hence, as we are seeing here, removing and then re-adding back simply doesn't work, since meanwhile we lose the file on the file system.
The current patch implements a global check: all fields attached to the entity belonging to the correct field type (file o image, at least in core) are inspected, and all file occurences are collected both for the original values and the submitted values. The occurrences are then compared and only actually removed files are deleted from the file system. The check is performed in
file_field_update()
to minimize the impact of this patch and reduce the chances of BC issues. A static cache is used to avoid repeating it for each field of the same type and for the various field translations. The static cache is cleared right afterwards to avoid problems of stale data.The check is extended to all fields of the same type because the issue here is not limited to the use case reported in the OP: if a file is referenced in one file field and then it's moved to another file field on the same entity, chances are that the it will be wiped exactly the same way reported in the OP.
I think this could be a reasonable approach to forward-port to D8, altough it does not address the (rare) case where a file is moved accross different field types. Probably a better way would be to simply drop automatical deletion of files that no longer have references, as discussed in http://groups.drupal.org/node/191183, but this would probably need some kind of file overview page as the one provided by Media.
Anyway, this patch should work in D7. Leaving the version to D7 so that the testbot will pick it up. I won't post a D8 forward-port nor test updates until we agree on a proper strategy to fix this.
Comment #25
plachLeaving to needs review so that we can get some feedback on the approach taken in #24.
Comment #26
plachFixed an edge case.
Comment #28
plachComment #29
drzraf CreditAttribution: drzraf commentedsee #1399846: Make unused file 'cleanup' configurable comment 8 for a testcase.
(advise there was... use
file_lock
)Comment #30
plachJust a note: #26 is supposed to be good but it has been tested against the 8.x branch, AAMOF the error is it doesn't apply.
Comment #31
plachMMh, let's actually try and test #26 on the correct branch.
Comment #32
plach#26: drupal-files_wiped-1141912-26.D7.patch queued for re-testing.
Comment #34
plachRerolled
Comment #35
plachSorry, wrong merge.
Comment #37
plachAw, windows newlines
Comment #38
plachBack to D8 to get feedback about #24.
Comment #39
benjifisher#37: drupal-files_wiped-1141912-37.patch queued for re-testing.
Comment #40
dcam CreditAttribution: dcam commentedhttp://drupal.org/node/1427826 contains instructions for updating the issue summary with the summary template.
The summary may need to be updated with information from comments.
Comment #42
kbasarab CreditAttribution: kbasarab commentedIssue summary is being reviewed and updated by bmadore in DrupalCon Portland Core Mentoring sprint.
Comment #43
ibakayoko CreditAttribution: ibakayoko commentedI am working on the reroll
Comment #43.0
ibakayoko CreditAttribution: ibakayoko commentedUpdated issue summary.
Comment #43.1
Barry Madore CreditAttribution: Barry Madore commentedUpdated issue summary.
Comment #43.2
Barry Madore CreditAttribution: Barry Madore commentedUpdated issue summary.
Comment #43.3
Barry Madore CreditAttribution: Barry Madore commentedUpdated issue summary.
Comment #43.4
Barry Madore CreditAttribution: Barry Madore commentedUpdated issue summary.
Comment #44
Barry Madore CreditAttribution: Barry Madore commentedI've reviewed the issue and edited the issue summary to update and conform to the correct format.
Comment #45
Barry Madore CreditAttribution: Barry Madore commentedI've tried to replicate this issue in D8 doing the following:
Following these steps, I did not encounter the issue described in this issue as occurring with the D7 Content Translation module. The file uploaded with the file field survived when I saved the node. I created several other nodes and tried several language changes. The files remain after editing.
This may not be a D8 issue after all. Can others confirm my findings?
Comment #46
ibakayoko CreditAttribution: ibakayoko commentedI was able to reproduce the issue in D8.
Will have three languages in the following Order:
English
French
Spanish
The attached file is deleted in specific cases see #2
The attached is deleted depending on the position of the language.
If the language of the node is the last option in the language select and you change to the first option the attached file will be deleted.
Comment #47
Barry Madore CreditAttribution: Barry Madore commentedI witnessed and confirmed ibakayoko's test at the PDX8 core sprint. But we both acknowledged that his build was a few days old. Given the numerous changes made even that day, I decided to re-test today (5/27) with a fresh install of Drupal 8.
I followed the same steps as ibakayoko in #46 and continued changing languages in nodes both up and down the list of 3 (and including the "not specified" and "not applicable" options). The file was not deleted no matter the original language or its position in the list. I even changed the order of languages and retested.
I suspect that changes have resolved the issue in D8. Can we confirm this? And if so, can someone identify the change that has solved the issue so we can backport the solution to D7?
Comment #48
plachTry using git bisect.
Comment #49
slashrsm CreditAttribution: slashrsm commentedD7 issue?
Comment #50
sreynen CreditAttribution: sreynen commentedBased on a comment at http://drupalcode.org/project/drupal.git/blob/refs/heads/8.x:/core/modul... it appears D8 is marking files for deletion removing usage numbers and only later deleting them on cron rather than deleting them immediately. It makes sense that this would resolve the problem, because there's only a very short period in the node save when the old language's file usage has been removed before the new language's file usage is added. So by the time cron runs, the file is no longer a candidate for deletion.
Is moving file deletes to cron a suitable solution for D7?
Comment #51
plachI don't think that can be backported without providing BC support, that is making the behavior optional. And if it is optional we need a different fix anyway.
Comment #52
sreynen CreditAttribution: sreynen commentedplach, I don't know what "BC support" means. Can you explain?
Comment #53
slashrsm CreditAttribution: slashrsm commented@sreynen: "backward-compatibility support"
Comment #54
plachYep, sorry :)
I think for D7 we still need to go with something like #37.
Comment #54.0
plachUpdated issue summary.
Comment #55
pingwin4egPatch in #37 worked for me.
It was the same problem, but it appeared only when I edited the content setting the language from some specific to neutral one (which is above in the select options list) and saved it. Changing back from neutral to some specific language was OK. And from one specific to another was OK too.
Comment #58
David_Rothstein CreditAttribution: David_Rothstein commentedHaven't reviewed the patch, but that looks like a testbot fluke so back to RTBC.
Comment #61
plachBack to RTBC
Comment #62
plachActually this needs some more work, but I'll leave it to RTBC for now to get @David's feedback about the overall approach. Not worth spending more time on this until it's validated.
We should add also the revision id, I think.
Comment #63
David_Rothstein CreditAttribution: David_Rothstein commentedThe basic approach looks reasonable to me. It would certainly be cleaner to do the whole thing in hook_field_attach_update() (and then I think supporting the case where the file moves from one field type to another would be simpler also) but I suppose you're right that for backwards compatibility reasons it's best to leave it where it is.
Comment #64
David_Rothstein CreditAttribution: David_Rothstein commentedBack to needs work, I guess, for #62.
Comment #65
steinmb CreditAttribution: steinmb as a volunteer commented