Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Filefield suffers from the same critical database problem that imagefield suffers from: deleted files are deleted from the {files} table, but not from the CCK field (residing in the {content_type_TYPE} table). Also see the comments further below in this imagefield issue.
This patch doesn't fix the problem, but adds an additional guard so that non-existing files are not even attempted to be displayed. Please review and apply (this patch is for filefield HEAD).
Comment | File | Size | Author |
---|---|---|---|
#8 | filefield-database-consistency-try6.patch | 4.96 KB | jpetso |
#7 | filefield-database-consistency-try5.patch | 4.45 KB | jpetso |
#6 | filefield-database-consistency-try4.patch | 4.41 KB | jpetso |
#5 | filefield-database-consistency-try3.patch | 4.27 KB | jpetso |
#2 | filefield-database-consistency-try2.patch | 4.28 KB | jpetso |
Comments
Comment #1
jpetso CreditAttribution: jpetso commentedOk, here's an attempt for the real solution. Rationale:
Comment #2
jpetso CreditAttribution: jpetso commentedAs requested on IRC, here's a version with a bit more documentation, and the steps on how to reproduce the bug that this patch fixes. I seem to like bullet lists, so here's for each of the three different cases that can happen if this patch is not applied:
Database inconsistency with a multiple-value upload field
Database inconsistency with a single-value upload field
Database inconsistency with two single-value fields, one of which being filefield
I consider this last issue to be a shortcoming of CCK, because it places empty single-field items into {content_type_TYPE} even when they are not required, that is, even when they may be empty. And that causes the relatively unexpected behaviour mentioned in the last explanation. ...I guess that's a good opportunity to file a bug against CCK so that it also places single-value, non-required fields into their own {content_field_FIELD} tables. When that happens, we can remove the additional check on $op='load'.
Comment #3
yched CreditAttribution: yched commentedI consider this last issue to be a shortcoming of CCK, because it places empty single-field items into {content_type_TYPE} even when they are not required, that is, even when they may be empty. And that causes the relatively unexpected behaviour mentioned in the last explanation. ...I guess that's a good opportunity to file a bug against CCK so that it also places single-value, non-required fields into their own {content_field_FIELD} tables. When that happens, we can remove the additional check on $op='load'.
This is not wanted nor required. CCK tries to keep fields in the same (content-type) table whenever possible, for performance reasons, to limit the number of table joins. OK, node data are cached in a dedicated cache table so node_load is OK, but this is no reason to multiply tables. Caching has no effect on views queries, for instance.
Field modules have to be prepared to the fact a value can get stored even for empty field (the value defined as 'default' in
hook_field_settings($op = 'database columns')
)As a matter of fact, the right behaviour is the opposite of what you propose : multiple field or not, shared field or not, a value (possibly NULL) should _always_ be stored in the db for empty fields.
This ensures consistency for empty fields between single / non shared fields and multiple or shared fields. That way, you can differentiate records (nodes) for which the field exists but is empty, from records for which the field 'is not defined', and build queries selecting the nodes where a given field is empty / not empty.
Comment #4
jpetso CreditAttribution: jpetso commentedWhatever, let it be one way or the other :) Your desired approach would still be less error-prone than the current one, because at the moment you just don't know what to expect unless you dive into content.module's code. No matter what the best behaviour might be, it ought to go all the way. imho.
Comment #5
jpetso CreditAttribution: jpetso commentedOops, forgot to remove the parameter from filefield_default_item(), which was a leftover from when I tried it with filefield_field_settings($op='database columns'). Revised version attached.
Comment #6
jpetso CreditAttribution: jpetso commentedAnother one, eliminating the $output variable in filefield_field() in favor of direct return statements, like done in imagefield.
Comment #7
jpetso CreditAttribution: jpetso commentedAnother one, using array_merge() instead of the "+=" operator for adding the $file to $node_field['delta'] in filefield_field($op='load'). Imagefield does so as well.
Comment #8
jpetso CreditAttribution: jpetso commentedAnd yet another revision, this time with better code documentation as requested in the related imagefield issue.
Comment #9
jpetso CreditAttribution: jpetso commentedCommitted to filefield HEAD. I am so relieved that this could finally be applied.
Comment #10
(not verified) CreditAttribution: commented