Problem/Motivation

When a media entity has a file field with multiplicity >1 or unlimited (-1) then FileUploadForm and multiple files are selected for upload, this results in multiple separate media entities of this type being created, instead of creating one media entity type with the uploaded items as field value!

FileUploadForm already seems to have logic in place to determine an upload field with multiplicity != 1 - It seems to be called $slots here:

protected function buildInputElement(array $form, FormStateInterface $form_state) {
    // [...]

    if (!$state->hasSlotsAvailable()) {
      return $form;
    }

    $slots = $state->getAvailableSlots();

    // [...]
    $form['container']['upload'] = [
      '#type' => 'managed_file',
      '#title' => $this->formatPlural($slots, 'Add file', 'Add files'),
      // @todo Move validation in https://www.drupal.org/node/2988215
      '#process' => array_merge(['::validateUploadElement'], $process, ['::processUploadElement']),
      '#upload_validators' => $item->getUploadValidators(),
      // Set multiple to true only if available slots is not exactly one
      // to ensure correct language (singular or plural) in UI
      '#multiple' => $slots != 1 ? TRUE : FALSE,  // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      // Do not limit the number uploaded. There is validation based on the
      // number selected in the media library that prevents overages.
      // @see Drupal\media_library\Form\AddFormBase::updateLibrary()
      '#cardinality' => FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED,
      '#remaining_slots' => $slots,
    ];

But in the later process the submit simply creates one media entity per file, instead of checking if the file field multiplicity is !=1, which means the files should all go into the same media field of the media entity!

  /**
   * Submit handler for the upload button, inside the managed_file element.
   *
   * @param array $form
   *   The form render array.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function uploadButtonSubmit(array $form, FormStateInterface $form_state) {
    $files = $this->entityTypeManager
      ->getStorage('file')
      ->loadMultiple($form_state->getValue('upload', []));
    $this->processInputValues($files, $form, $form_state);
  }

This later creates the media entities in a loop:

   $media = array_map(function ($source_field_value) use ($media_type, $media_storage, $source_field_name) {
      return $this->createMediaFromValue($media_type, $media_storage, $source_field_name, $source_field_value);
    }, $source_field_values);

Steps to reproduce

  1. Create a media item type with a file field (e.g. image field) that has multiplicity !=1, for example a media entity type "Slides" or "360°" or "Gallery"
  2. Create an entity, e.g. node with a media entity reference field on this type
  3. Select the media library widget
  4. Create an entity, e.g. node and click the "Add media" button
  5. In the Media library widget modal select multiple image files and submit

Expected:
One media entity is created and the uploaded files all land in the file field of that media entity, like if you'd create the media entity through its form

Actual:
For each uploaded file a separate media entity is created with one file in the file field

Proposed resolution

Only create one media entity, if the multiplicity of the upload field multiplicity of the media entity is !=1 and assign all uploaded values to this one file field!

Alternatively or as a first fix, the upload field and form could be hidden, if $slots !=1 and for example a link to the media types create form could be shown instead to mitigate the problem.

Remaining tasks

  • Discuss
  • Implement
  • Test
  • Release

User interface changes

TBD

Introduced terminology

-

API changes

-

Data model changes

-

Release notes snippet

TBD

Issue fork drupal-3477339

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:

Comments

anybody created an issue. See original summary.

anybody’s picture

Issue summary: View changes

cilefen’s picture

anybody’s picture

Okay I added a quickfix and a first draft example implementation to show, what I'm talking about. Still I think a media maintainer should first have a look what should be achieved before investing more time.

We ran into this issue, as a client was complaining about the unexpected behavior in a project, where a media entity for 360° images contains an image field for all the frames.

anybody’s picture

@cilefen thank you, no I don't think so. It's related, but not the same. I'm talking about unexpected behaviour of the Media library widget.

This currently DOES create multiple media entities in batch (one per uploaded file), but shouldn't ;)

If multi-file / bulk creation is not supported in core (and shouldn't be in the future), we should then not close this works by design or duplicate, but at least implement a simple message to prevent this misbehavior for end-users and show a message instead indicating, that this is not supported (or write it to log, whatever).

Draft for that simple "This is not supported, don't run into trouble"-approach in MR !9657.

anybody’s picture

anybody’s picture

StatusFileSize
new1008 bytes

Patch for the simple "Not supported" message, hiding the form as static patch for composer. We'll use it in the meantime to prevent confusion (and hundreds of files and media entities to be created unintentionally ;D)

anybody’s picture

StatusFileSize
new1.53 KB

Improved the quickfix a bit.

Version: 11.x-dev » main

Drupal core is now using the main branch as the primary development branch. New developments and disruptive changes should now be targeted to the main branch.

Read more in the announcement.