I'm seeing an issue with content types that contain two cck filefields using the Multiupload Filefield Widget. I've installed a clean version of Drupal 7, with only the Multiupload Filefield Widget enable.

Here is the behavior:

1) Create a content type with two filefields using the Multiupload Filefield Widget.
2) Create a node.
3) Upload several files to the first file field.
4) Upload several files to the second file field.
5) Save the node.
Result - First field contains just one image, Second field contains all images. After deleting the node, the missing images are stranded in the file_managed table in the database.

If you upload to just one file field at a time (between saves), it behaves as expected.

Comments

czigor’s picture

Can you confirm that with the second attempt all the files get uploaded? That is:
1. Upload some files
2. Save (only one file appears)
3. Edit node
4. Upload the missing files again
5. Save
How many files do you see now?

harris_david’s picture

I can confirm that the second attempt works. However, I believe this is not because of the second attempt, but because only one field is being adjusted. I can save to any one of the fields at a time . . . just not both.

Also, after following your steps, I see that the files that were "missed" on the first attempt get stranded in the filesystem and in the database ( file_managed table ).

I also noticed this behavior:
1) upload 5 files to each field and save.
result - 1 file in the first field, 5 in the second.
2) re-upload the 4 missing files to the first field, but add a new file to the second field.
result - 2 files in the first field, and 6 in the second.

It appears that if you make any changes to the second field, it will only add 1 file to the first field.

rockaholiciam’s picture

Version: 7.x-1.x-dev » 7.x-1.0

I can also confirm this. I only have one image field in my content type and the first attempt only registers one image file, even though the others get uploaded. Its only on the second attempt at uploading that the rest show up.

rockaholiciam’s picture

On some testing, I discovered that the bug can only be reproduced if you add another field in one of the multifields(any field with multiple values) on the form. If you dont, the files get uploaded fine. Its only on adding another item that only one file gets saved, however they all get uploaded.

czigor’s picture

This seems to be very similar:
http://drupal.org/node/1112966
It is fixed for D8, but it needs a backport to D7.

rockaholiciam’s picture

hei, thanks for the reply...its similar but not the same I believe...is it possible for you to point me to the chunk of code/method which sets the file as permanent and moves it to file usage after all is said and done? I found one file status field in code but changing it to 1 resulted in more errors for that validates the fields like title and alt text on upload...thanks

rockaholiciam’s picture

On further digging, I realized file_usage hasnt got much to do with it...the prob is that except for the default image, or 'delta 0', the others never make it to the field_images table...I believe at some point, the form_state gets overwritten and except for the default value, others are lost.

rockaholiciam’s picture

 /**
 * Implements hook_field_widget_form().
 *
 * Mostly copied from drupal core module /modules/file/file.field.inc
 */
function multiupload_filefield_widget_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  // This is essentially copied from file.field.inc.
  $defaults = array(
    'fid' => 0,
    'display' => !empty($field['settings']['display_default']),
    'description' => '',
  );

  // Retrieve any values set in $form_state, as will be the case during AJAX
  // rebuilds of this form.
  if (isset($form_state['values'])) {
    $path = array_merge($element['#field_parents'], array($field['field_name'], $langcode));
    $path_exists = FALSE;
    $values = drupal_array_get_nested_value($form_state['values'], $path, $path_exists);
    if ($path_exists) {
      $items = $values;
      drupal_array_set_nested_value($form_state['values'], $path, NULL);
    }
  }

  foreach ($items as $delta => $item) {
    $items[$delta] = array_merge($defaults, $items[$delta]);
    // Remove any items from being displayed that are not needed.
    if ($items[$delta]['fid'] == 0) {
      unset($items[$delta]);
    }
  }

  // Re-index deltas after removing empty items.
  $items = array_values($items);

  // Update order according to weight.
  $items = _field_sort_items($field, $items);

  // Essentially we use the mfw_managed_file type, extended with some enhancements.
  $element_info = element_info('mfw_managed_file');
  $element += array(
    '#type' => 'mfw_managed_file',
    '#default_value' => isset($items[$delta]) ? $items[$delta] : $defaults,
    '#upload_location' => file_field_widget_uri($field, $instance),
    '#upload_validators' => file_field_widget_upload_validators($field, $instance),
    '#value_callback' => 'mfw_field_widget_value',
    '#process' => array_merge($element_info['#process'], array('mfw_field_widget_process')),
  // Allows this field to return an array instead of a single value.
    '#extended' => TRUE,
  );

  if ($field['cardinality'] == 1) {
    // If there's only one field, return it as delta 0.
    if (empty($element['#default_value']['fid'])) {
      $element['#description'] = theme('file_upload_help', array('description' => $element['#description'], 'upload_validators' => $element['#upload_validators']));
    }
    $elements = array($element);
  }
  else {
    // If there are multiple values, add an element for each existing one.
    $delta = -1;
    foreach ($items as $delta => $item) {
      $elements[$delta] = $element;
      $elements[$delta]['#default_value'] = $item;
      $elements[$delta]['#weight'] = $delta;
    }
    // And then add one more empty row for new uploads.
    $delta++;
    if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) {
      $elements[$delta] = $element;
      $elements[$delta]['#default_value'] = $defaults;
      $elements[$delta]['#weight'] = $delta;
      $elements[$delta]['#required'] = ($element['#required'] && $delta == 0);
    }
    // The group of elements all-together need some extra functionality
    // after building up the full list (like draggable table rows).
    $elements['#file_upload_delta'] = $delta;
    $elements['#theme'] = 'file_widget_multiple';
    $elements['#theme_wrappers'] = array('fieldset');
    $elements['#process'] = array('mfw_field_widget_process_multiple');
    $elements['#title'] = $element['#title'];
    $elements['#description'] = $element['#description'];
    $elements['#field_name'] = $element['#field_name'];
    $elements['#language'] = $element['#language'];
    $elements['#display_field'] = $field['settings']['display_field'];

    // Add some properties that will eventually be added to the file upload
    // field. These are added here so that they may be referenced easily through
    // a hook_form_alter().
    $elements['#file_upload_title'] = t('Add a new file');
    $elements['#file_upload_description'] = theme('file_upload_help', array('description' => '', 'upload_validators' => $elements[0]['#upload_validators']));
  }

  if ( isset($form_state['values'])) { 
      if ( array_key_exists( $field['field_name'], $form_state['values'] ) ) {
          $form_state['bkp_elements'] = $elements;
      } else if ( isset($form_state['bkp_elements']) ) {
          $elements = $form_state['bkp_elements'];
      }
  }
  
  return $elements;
}
rockaholiciam’s picture

So here is my quick fix for the issue. I noticed that this method is being executed every time another field was being added to the form which I believe shouldn't be the case...one can also wrap some of the code above under a similar check that verifies if the field is indeed the one related to file for I see no point in all that code being executed if I add another text field for instance. I stripped it for simplicitys sake and only added this chunk before the $elements is returned in the multiupload_filefield_widget.field.inc file:

if ( isset($form_state['values'])) { 
      if ( array_key_exists( $field['field_name'], $form_state['values'] ) ) {
          $form_state['bkp_elements'] = $elements;
      } else if ( isset($form_state['bkp_elements']) ) {
          $elements = $form_state['bkp_elements'];
      }
  }

Hope it helps. Thanks.

dhalbert’s picture

I have a similar problem in the following situation:

I have a content type with two image fields (no field groups):
1. holds a single image (required field)
2. holds unlimited images (not required)

If I multi-upload a bunch of images to field 2, and then a single image to field 1, and then save the node, only one image gets saved to field 2. I can then go back and re-upload multiple images to field 2, and save, and they all get saved (with new names, and the original uploads are still in the target directory).

I also tried this on a fresh Drupal 7 installation without multiupload, uploading the files one at a time, and the problem does not occur. So it is not the core bug #1112966: Cannot upload file when having two file fields mentioned above, which is supposed to be fixed, anyway.

dhalbert’s picture

Hi - where is the patch in #9 supposed to go?

czigor’s picture

Title: Multiple Multiupload Filefield Widget Issue - only one image is saved to first field » Only one image is saved to first field

Changing the title

rockaholiciam’s picture

Refer to number #8. #9 only mentions the bit that was added to the method.

joeysantiago’s picture

Add #9 code to multiupload_filefield_widget.field.inc, line 120 (version 7.x-1.0+4-dev).

Works perfectly.

Neltharian’s picture

Version: 7.x-1.0 » 7.x-1.x-dev

Not working - showing from 2 to 1 images (((

cweagans’s picture

Project: » Multiupload Filefield Widget
Taxoman’s picture

robertom’s picture

Status: Active » Needs review
StatusFileSize
new3.86 KB

Hi, sorry for my bad English

Bug #1059268: Files are lost when adding multiple files to multiple file fields at the same time is fixed (commit), but multiupload filefield widget module uses old code of file.field.inc

I would add a proposed patch

czigor’s picture

Status: Needs review » Fixed

Status: Fixed » Closed (fixed)

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