Images and Files are not populating their respective node entity reference fields

Created on 30 March 2021, about 4 years ago
Updated 28 April 2023, almost 2 years ago

Problem/Motivation

I am not getting images or files mapped correctly. I've set the fields to use the public file system and made sure they're mapped correctly but the new node doesn't get any content for those fields. The fields are entity references to media and files. I can see from the submission page the images/pdfs were submitted, but they never make it to the node. No errors in the console and no errors in the log. I updated to v2, ran drush updb, removed the webform encrypt module, and made sure all fields were still mapped. No change.

πŸ› Bug report
Status

Needs work

Version

3.0

Component

Code

Created by

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

Comments & Activities

Not all content is available!

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

  • πŸ‡΅πŸ‡ΉPortugal joaomarques736

    Hello cebronix,

    I tested using the mappings Image file (Webform) -> Image (Content Type) and File (Webform) -> File (Content Type), using the public folder, and it seems to work properly. Maybe you need to implement new field mapping plugins in order to achieve mappings for different field types (for example, mapping Webform image file with content type media entity reference).

    Best regards.

  • Status changed to Closed: works as designed almost 2 years ago
  • πŸ‡ΊπŸ‡ΈUnited States loopy1492

    Note it is a bad idea to allow anonymous users to upload to the public file system.

    We'll try to write a hook for this because we really can't allow the alternative.

  • πŸ‡ΊπŸ‡ΈUnited States loopy1492

    We created a custom presave hook in a oursite_submit_events module. This moves the files from private to public and back again when publishing and unpublishing the content item:

    <?php
    
    use Drupal\Core\Entity\EntityInterface;
    use Drupal\node\NodeInterface;
    use Drupal\file\Entity\File;
    use Drupal\Core\File\FileSystemInterface;
    
    /**
     * Implements hook_entity_presave().
     * 
     * Copy uploaded images from the private file system to public 
     * when "submit_an_event" content is published. This ensures that 
     * images uploaded via the webform are only made publicly 
     * accessible once the associated content item is published.
     * 
     * Note: due to time constraints, this function is very strict in 
     * that it assumes the folder where the files are originally stored is 
     * webform/submit_an_event. If that location changes in the future, 
     * this code will break.
     */
    function oursite_submit_events_entity_presave(EntityInterface $entity) {
      // Only execute on the specific content type.
      if ($entity instanceof NodeInterface && $entity->bundle() === 'submit_an_event') {
        // Only execute if the image field has values.
        $field_name = 'field_event_images';
        if ($entity->hasField($field_name) && !$entity->get($field_name)->isEmpty()) {
          /** @var \Drupal\Core\File\FileSystemInterface $file_system */
          $file_system = \Drupal::service('file_system');
          $new_items = [];
          // Execute for each image.
          foreach ($entity->get($field_name) as $item) {
            $file = File::load($item->target_id);
            if ($file) {
              // For safety, by default we're moving public to private.
              $source_dir = 'public://';
              $target_dir = 'private://';
              $target_folder = 'webform/submit_an_event/';
              if ($entity->isPublished()) { 
                // If we are publishing content, we're moving from private to public instead
                $source_dir = 'private://';
                $target_dir = 'public://';
                $target_folder = 'webform_uploads/';
              }
              // Prepare the folder if it doesn't exist yet
              $full_target_dir = $target_dir . $target_folder;
              $file_system->prepareDirectory($full_target_dir, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);
              // Start logic for copying the file
              $original_uri = $file->getFileUri();
              // If the file is still in the source directory, we need to move it...
              if (str_starts_with($original_uri, $source_dir)) {
                $new_uri = $full_target_dir . basename($original_uri);
                // Attempt to copy the file to the new location...
                if ($copied_uri = $file_system->copy($original_uri, $new_uri, FileSystemInterface::EXISTS_RENAME)) {
                  // Create a new file entity referencing the new location...
                  $new_file = File::create([
                    'uri' => $copied_uri,
                    'status' => TRUE,
                  ]);
                  $new_file->save();
                  // Assign the new file item to the field's file array...
                  $new_items[] = [
                    'target_id' => $new_file->id(),
                    'alt' => $item->alt ?? '',
                    'title' => $item->title ?? '',
                  ];
                  // Delete the original file if we are moving from public to private.
                  if ($source_dir == 'public://') {
                    $file->delete();
                  }
                }
                else {
                  \Drupal::logger('oursite_submit_events')->error("Failed to copy file from $original_uri to $new_uri");
                }
              }
              else {
                // Already in target directory, so keep as-is.
                $new_items[] = [
                  'target_id' => $file->id(),
                  'alt' => $item->alt ?? '',
                  'title' => $item->title ?? '',
                ];
              }
            }
            else {
              \Drupal::logger('oursite_submit_events')->warning("Could not load file ID {$item->target_id}");
            }
          }
    
          // Replace the field value with updated file including the file location.
          $entity->set($field_name, $new_items);
        }
        else {
          \Drupal::logger('oursite_submit_events')->info("No image field data present on node {$entity->id()}");
        }
      }
    }
    
    
Production build 0.71.5 2024