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.

Issue fork drupal-1912458

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

cameron1729’s picture

Issue summary: View changes

Tried to change the version number but I couldn't, so instead I explained it in the summary.

cameron1729’s picture

Issue summary: View changes

edited

cameron1729’s picture

Version: 7.9 » 7.16
bengt’s picture

Version: 7.16 » 7.22

Any solution to this issue? It is the same in 7.22 as in 7.16 as far as I can tell.

pstewart’s picture

Version: 7.22 » 7.23

Confirmed in 7.23. This is a problem when trying to programmatically add an image that didn't previously exist, or add additional images beyond the number already saved in the field. Removing the && empty($form_state['programmed']) clause of the if statement allows the additional row to be added to $elements so a single additional image can be accepted.

In my case, I'm trying to add an image to an Ubercart product node via the services module. Ideally I would like to be able to add multiple additional images at once: perhaps looking at the number of submitted values in $form_state for the corresponding field and adding enough extra rows to accommodate them all?

pstewart’s picture

Issue summary: View changes

typo

Jan van Diepen’s picture

We need a downloadable patch for our installation profile.
So here's a patch that allows addition of an unlimited number of images to be done programmatically.

The patch is flawed so please don't use it.
Sorry I posted it in the first place.

davidserene’s picture

I uploaded and attached four images to a node from an HTML 5 application by posting the node -> posting all the images -> updating the created node for each of the images uploaded;

rakesh.nimje84@gmail.com’s picture

Issue summary: View changes
Priority: Minor » Normal
Status: Active » Needs review

Jan van Diepen has done great job.
But he has posted the fixed value for 'field_.......'.
Here I am posting the complete code block for if condition.

Replace the complete if block with following code. Hope this will solve notice & it will be dynamic for 'field_...'

    if (($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality'])) {
      if(!empty($form_state['programmed'])){
      // Lift restrictions on number of files to download.
        if (isset($form_state['values'][$element['#field_name']])) {
          foreach ($form_state['values'][$element['#field_name']]['und'] as $item) {
          $elements[$delta] = $element;
          $elements[$delta]['#default_value'] = $item;
          $elements[$delta]['#weight'] = $delta;
          $delta++;
         }
        }
        
      }
      $elements[$delta] = $element;
      $elements[$delta]['#default_value'] = $defaults;
      $elements[$delta]['#weight'] = $delta;
      $elements[$delta]['#required'] = ($element['#required'] && $delta == 0);
    }

Status: Needs review » Needs work

The last submitted patch, 4: programmatically_add_images-1912458-4.patch, failed testing.

batje’s picture

rakesh.nimje84@gmail.com could you turn that into a patch so it is easier for people to test it?

http://drupal.org/patch/

leewillis77’s picture

We've just hit this error trying to attach an existing file to a node being created via Services. Posting the following to services would result in the warnings noted in the error log, and the node being created with no attached file.

Array
        (
            [title] => Title
            [status] => 1
            [comment] => 0
            [promote] => 0
            [sticky] => 0
            [translate] => 0
            [type] => node_type
            [field_images] => Array
                (
                    [und] => Array
                        (
                            [0] => Array
                                (
                                    [fid] => 326
                                    [display] => 1
                                )

                        )

                )

        )

The patch attached resolves this issue for us, but I'm not clear why the additional check was added in the first place, so could do with a robust review.

leewillis77’s picture

Status: Needs work » Needs review

Hopefully triggering testbot.

mattlc’s picture

Hi,

#9 seems to create another bug upon validation when programmatically submitted field is empty.
As "programmed" test is here to avoid "front end tricks" due to ajax I guess, i tried to skip front end things when "programmed" flag is set.

Patch attached.

Status: Needs review » Needs work

The last submitted patch, 11: programmatically_submit_form_with_filefield-1912458-11.patch, failed testing.

basile.laderchi’s picture

@davidserene:

I uploaded and attached four images to a node from an HTML 5 application by posting the node -> posting all the images -> updating the created node for each of the images uploaded;

Could you post the code with what data are you posting to each service call?
I am trying to do the same thing and have no luck. (only difference is that I am creating the node and files from and Android application)

Shane Birley’s picture

Has anyone revisited this with any success? I am attempting to create nodes with attached files using the Services module and it works with mixed success.

Version: 7.23 » 7.x-dev

Core issues are now filed against the dev versions where changes will be made. Document the specific release you are using in your issue comment. More information about choosing a version.

anrikun’s picture

Title: file_field_widget_form function is broken when submitting some node forms programatically » file_field_widget_form() broken when submitting programmatically a form having a multiple file field
Issue summary: View changes
Status: Needs work » Needs review
FileSize
904 bytes

This empty($form_state['programmed']) check should definitely not be here in the first place.
Checking this when field is multiple but not when it is single brings behavior inconsistency:
I've turn a single file field into a multiple one and it completely broke my import function, taking me hours of debugging just for this simple check.

anrikun’s picture

Issue summary: View changes
anrikun’s picture

Issue summary: View changes
skylord’s picture

Thanks, #16 works OK and has no side effects. It's definitely a bug - single- and multiple- value fields should work in similar manner with 'programmed' forms.

apaderno’s picture

The following is the code after then changes done in #1059268: Files are lost when adding multiple files to multiple file fields at the same time.

    // And then add one more empty row for new uploads except when this is a
    // programmed form as it is not necessary.
    if (($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) && empty($form_state['programmed'])) {
      // Omissis
    }

The existing code was the following one.

    // And then add one more empty row for new uploads.
    $delta++;
    if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED || $delta < $field['cardinality']) {
      // Omissis
    }

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 and other issues.

apaderno’s picture

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.