Closed (fixed)
Project:
Drupal core
Version:
7.x-dev
Component:
file.module
Priority:
Normal
Category:
Task
Assigned:
Unassigned
Issue tags:
Reporter:
Created:
6 Jun 2010 at 18:50 UTC
Updated:
11 Apr 2025 at 01:49 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #1
eojthebraveI can confirm that this is an issue.
Steps to repeat the problem.
1. Edit the default article content type and change the image field to allow multiple images.
2. Create a new article node and upload multiple images.
3. After saving the node, return to the edit screen and use the drag/drop functionality to re-order the attached images and click save.
Expected outcome, images should be displayed on the node in the order you just set. Actual outcome. They retain the ordering from when the node was originally created (the order the files are uploaded.)
Comment #2
tsi commentedAnother detail : this is probably not related to the JS drag & drop.
Disabled JS and tried working with the weight drop-downs and still no change.
Comment #3
yoroy commentedMoving this to the dev queue
Comment #4
yched commentedVery possibly related (if not plain duplicate) : #817668: Removing image from Article not working for me
Comment #5
tsi commented@yched - I don't think so, as #817668: Removing image from Article not working for me is an AJAX issue and this one is probably not.
Comment #6
tsi commentedI hate doing this, but I think it's quiet a critical bug, and a very annoying one, at least for everyone trying to build some kind of an image gallery or a commerce site.
Comment #7
berdirAre you sure that this is still the case with latest HEAD? There was a image handing commit recently which afaik fixed this.
Comment #8
tsi commentedI've just checked with latest head, so yes, I'm pretty sure, but can please point me to the relevant issue ?
Comment #9
Anonymous (not verified) commentedsubscribe.
Comment #10
berdirYeah, I guess I was wrong, what I meant/remembered was broken *deletion* of images, that should have been fixed with #736298: Refactor file.module to use proper button click detection, enabling FAPI to improve button click detection security
Comment #11
tsi commentedYep, I can confirm "remove images" is fixed, "reorder images" is not.
Comment #12
aaronbaumanReordering files and images doesn't work because field_submit_default doesn't sort custom "multiple values" implementations.
This patch:
This patch is related to both file.module and image.module, but essentially is a file.module issue.
Comment #14
eojthebrave#12: 819816-image-file-field-sort-order.patch queued for re-testing.
Comment #16
yched commented1) if something needs to be done in both 'submit' and 'insert' ops, then 'presave' op might be more relevant.
But:
2) hook_field_[op]() hooks are run for a given field type, regardless of the widget being used. Even though there is only one widget available in core for File and Image field types, there might be alternate widgets in contrib at some point. Having the generic field-type hooks run code relevant only for a specific widget type (that happens to implement its own 'reorder' feature, I don't exactly remember why) is not too great.
Ideally, it should be the widget that needs it that triggers the extra submit steps, for instance in a FAPI #value_callback value.
Comment #17
aaronbaumanyched, thanks for the review.
I'm not sure the best way to use a #value_callback. The children need to be sorted based on their relative weights, and the parent element's #value_callback never gets called.
In this patch I moved the logic in the the #process callback, but it doesn't feel quite right.
How can make sure the #value_callback from the parent element gets triggered?
Comment #18
klausitrailing white space
trailing white space
51 critical left. Go review some!
Comment #19
aaronbaumanComment #20
yched commentedRight, my bad, #value_callback is only called for #input elements, and cannot be used on a simple wrapper element.
To tell you the truth, I'm not sure what the best solution is... Would be good to have quicksketch chime in here.
I'm not too fond of hitting $form_state['input'] directly.
While digging around, I stumbled upon #853926: Wrong order of multi-value file fields when form rebuilt (preview, failed validation), which looks related but is actually a different bug with a separate fix.
Comment #21
mtokoly commentedI have worked with the latest (passed) patch above, and it causes unusual behavior. You can not reorder images, yet you can 'swap' them (example: 4 for 10 OR 5 for 7). However, if you delete a 'swapped' image, all images added after the 'swapped' image will be deleted.
Comment #22
aaronbaumanAttached is a much more elegant solution, imo, starting from scratch.
file_field_element_validate() sorts the fields' form_state['values'].
This solution only requires changing one file, since image field's form builds on file_field_widget_form().
I'm not sure that #element_validate is the most intuitive place to stuff this logic, but there's no such thing as #element_submit, so it's really the only option. As noted above, #value_callback applies to single elements only, which precludes sorting a group of elements.
Now gimme some love, testbot!
Comment #23
yched commented#22 works - but you should use form_set_value() instead of writing to $form_state['values'] directly.
I've been wondering about a simpler fix - just let Field API sort items in all cases, instead of just the ones for which it handles multiple values itself (just removing the if around _field_sort_items() in field_default_submit()).
If the widget implements its own reordering (like file widget), it can take care of providing the _weight in the expected place;
if the widget is inherently not reorderable (multi selects, checkboxes), _weight is just not there.
The _field_sort_items_helper() sort function already handles the case where no _weight information is provided in the submitted form values. Problem is: in this case, usort() with a sort callback that always returns 0 ends up with an array in the reversed order :
So unless we have a workaround, #22 (having widgets do the extra mile) is the way to go. A widget re-implementing its own drag-drop should be enough of an edge case that it's not too big a deal.
Comment #24
damien tournoud commentedIf we can afford removing the NULL values (I guess that's the only case where an item can be something that isn't an array?), we can easily do something like that, and simplify the logic in _field_sort_items_helper().
Comment #25
yched commentedHm, removing empty values is the job of _field_filter_items() , I'd rather keep them separate if possible.
However, I'm a jerk - _field_sort_items() does check that the first element has a _weight, and does nothing if not.
So the approach in #23 should work. We just ask widgets that handle multiple values on their own to be consistent : either they provide a _weight for all values, or for none - which is only a fair assumption IMO.
Patch.
Comment #26
damien tournoud commentedSounds good to me.
What about:
1) Removing items before sorting (because (a) there is no point in sorting items we will remove and (b) what happens if you remove the first element and sort the other? the check at the beginning of _field_sort_items() might very well fail)
2) Simplify the logic of _field_sort_items_helper() so that it explicitly fails if a '_weight' key is missing
Comment #27
damien tournoud commentedSomething like this?
Comment #29
webchickRe-titling so I stop being confused when I see this in the critical bug queue. :)
Also, sounds like we need tests for this.
Comment #30
yched commented#26/#27 should be OK.
Fixed the syntax error (missing closing parenthesis).
Comment #32
aaronbaumana and b were reversed in the usort helper functions.
Comment #33
yched commentedLOL. RTBC, then. Thks !
Comment #34
casey commentedsub
Comment #35
webchickTests? Or is that impossible because it's JS functionality?
Comment #36
webchickI'm going to go ahead and assume that's the reason. If it is possible to write tests for this, let's please do.
In the meantime, committed to HEAD to close out another critical. w00t.
Comment #37
yched commentedIt's not strictly JS related, reordering works without JS too (plain old 'weight' form inputs). Should thus be testable.
Comment #38
klausiDowngrading
Comment #39
aaronbaumanI am pretty sure there are already tests for the weight fields.
These are the tests that were failing in #30, no?
Comment #40
yched commentedre #39 : no, the tests failing in #30 are testing generic reordering for widgets where field API takes care of handling multiple values - i.e not the tests that would have detected the bug in this thread with filefields.
Comment #41
druplicate commentedThis is a problem in D6 as well.
See #1083904: Drag 'n Drop reordering broken (within fieldgroups?)
Comment #42
Tor Arne Thune commentedComment #43
sander-martijn commentedmy last comment was inaccurate.
Comment #62
kim.pepperThis was fixed in 9.1.x. and left open for a backport to D7. Marking fixed since D7 is no longer supported.
Comment #63
quietone commented@kim.pepper, thanks for cleaning up issues.
Updating credit and version to the time of the commit.
Comment #64
quietone commented