file_field_widget_form() broken when submitting programmatically a form having a multiple file field

Created on 9 February 2013, about 12 years ago
Updated 16 April 2024, 11 months ago

When submitting programmatically a node (or other entity) having a multiple file field, file_field_widget_form() throws errors and file is not added.

This problem does not occur with single file fields.

The extra empty($form_state['programmed']) check at line 511 is the culprit here.

🐛 Bug report
Status

Needs review

Version

7.0 ⚰️

Component
Form 

Last updated 26 minutes ago

Created by

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Merge Requests

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    The following lines have been added as per #1059268: Files are lost when adding multiple files to multiple file fields at the same time .

      // Load the items for form rebuilds from the field state as they might not be
      // in $form_state['values'] because of validation limitations. Also, they are
      // only passed in as $items when editing existing entities.
      $field_state = field_form_get_state($element['#field_parents'], $field['field_name'], $langcode, $form_state);
      if (isset($field_state['items'])) {
        $items = $field_state['items'];
      }
    

    The code that has been removed as per that issue is the following one.

      // 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]);
        }
      }
    

    The issue explains why that code has been added. Removing the && empty($form_state['programmed']) condition will probably mean refacing the bug that issue fixed.

  • 🇮🇹Italy apaderno Brescia, 🇮🇹

    Drupal 9.5 is still using that condition.

        $empty_single_allowed = $cardinality == 1 && $delta == 0;
        $empty_multiple_allowed = ($cardinality == FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED || $delta < $cardinality) && !$form_state->isProgrammed();
    
        // Add one more empty row for new uploads except when this is a programmed
        // multiple form as it is not necessary.
        if ($empty_single_allowed || $empty_multiple_allowed) {
          // Create a new empty item.
          $items->appendItem();
          $element = [
            '#title' => $title,
            '#description' => $description,
          ];
          $element = $this->formSingleElement($items, $delta, $element, $form, $form_state);
          if ($element) {
            $element['#required'] = $element['#required'] && $delta == 0;
            $elements[$delta] = $element;
          }
        }

    If that condition needs to be removed, it needs to first be removed in the current Drupal version.

  • Open in Jenkins → Open on Drupal.org →
    Environment: PHP 8.1 & MySQL 5.7
    last update 11 months ago
    2,179 pass
  • Pipeline finished with Success
    11 months ago
    Total: 373s
    #148468
Production build 0.71.5 2024