You are here

protected function WebformSubmissionExportImportImporter::importManageFileElement in Webform 6.x

Same name and namespace in other branches
  1. 8.5 modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php \Drupal\webform_submission_export_import\WebformSubmissionExportImportImporter::importManageFileElement()

Import managed file element.

Parameters

array $element: A managed file element.

mixed $value: File URI(s) from CSV record.

\Drupal\webform\WebformSubmissionInterface|null $webform_submission: Existing submission or NULL if new submission.

array $errors: An array of error messages.

Return value

array|int|null An array of multiple files, single file id, or NULL if file could not be imported.

1 call to WebformSubmissionExportImportImporter::importManageFileElement()
WebformSubmissionExportImportImporter::importElement in modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php
Import element.

File

modules/webform_submission_export_import/src/WebformSubmissionExportImportImporter.php, line 707

Class

WebformSubmissionExportImportImporter
Webform submission export importer.

Namespace

Drupal\webform_submission_export_import

Code

protected function importManageFileElement(array $element, $value, WebformSubmissionInterface $webform_submission = NULL, array &$errors) {
  $webform = $this
    ->getWebform();
  $element_plugin = $this->elementManager
    ->getElementInstance($element);

  // Prepare managed file element with a temp submission.
  $element_plugin
    ->prepare($element, $this
    ->getSubmissionStorage()
    ->create([
    'webform_id' => $webform
      ->id(),
  ]));

  // Get file destination.
  $file_destination = isset($element['#upload_location']) ? $element['#upload_location'] : NULL;
  if (isset($file_destination) && !$this->fileSystem
    ->prepareDirectory($file_destination, FileSystemInterface::CREATE_DIRECTORY)) {
    $this->loggerFactory
      ->get('file')
      ->notice('The upload directory %directory for the file element %name could not be created or is not accessible. A newly uploaded file could not be saved in this directory as a consequence, and the upload was canceled.', [
      '%directory' => $file_destination,
      '%name' => $element['#webform_key'],
    ]);
    return $element_plugin
      ->hasMultipleValues($element) ? [] : NULL;
  }

  // Get file upload validators.
  $file_upload_validators = $element['#upload_validators'];

  // Create a uri and sha1 lookup tables for existing files.
  $existing_file_ids = [];
  $existing_file_uris = [];
  $existing_files = $webform_submission ? $element_plugin
    ->getTargetEntities($element, $webform_submission) ?: [] : [];
  foreach ($existing_files as $existing_file) {
    $existing_file_uri = file_create_url($existing_file
      ->getFileUri());
    $existing_file_uris[$existing_file_uri] = $existing_file
      ->id();
    $existing_file_hash = sha1_file($existing_file
      ->getFileUri());
    $existing_file_ids[$existing_file_hash] = $existing_file
      ->id();
  }

  // Find or upload new file.
  $new_file_ids = [];
  $new_file_uris = explode(',', $value);
  foreach ($new_file_uris as $new_file_uri) {

    // Check existing file URIs.
    if (isset($existing_file_uris[$new_file_uri])) {
      $new_file_ids[$new_file_uri] = $existing_file_uris[$new_file_uri];
      continue;
    }
    $t_args = [
      '@element_key' => $element['#webform_key'],
      '@url' => $new_file_uri,
    ];

    // Check URL protocol.
    if (!preg_match('#^https?://#', $new_file_uri)) {
      $errors[] = $this
        ->t('[@element_key] Invalid file URL (@url). URLS must begin with http:// or https://.', $t_args);
      continue;
    }

    // Check URL status code.
    $file_headers = @get_headers($new_file_uri);
    if (!$file_headers || $file_headers[0] === 'HTTP/1.1 404 Not Found') {
      $errors[] = $this
        ->t('[@element_key] URL (@url) returns 404 file not found.', $t_args);
      continue;
    }
    $new_file_hash = @sha1_file($new_file_uri);
    if (!$new_file_hash) {
      $errors[] = $this
        ->t('[@element_key] Unable to read file from URL (@url).', $t_args);
      continue;
    }

    // Check existing file hashes.
    if (isset($existing_file_ids[$new_file_hash])) {
      $new_file_ids[$new_file_hash] = $existing_file_ids[$new_file_hash];
      continue;
    }

    // Write new file URI to server and upload it.
    $temp_file_contents = @file_get_contents($new_file_uri);
    if (!$temp_file_contents) {
      $errors[] = $this
        ->t('[@element_key] Unable to read file from URL (@url).', $t_args);
      continue;
    }

    // Create a temp file.
    $handle = tmpfile();
    fwrite($handle, $temp_file_contents);
    $temp_file_meta_data = stream_get_meta_data($handle);
    $temp_file_path = $temp_file_meta_data['uri'];
    $temp_file_size = filesize($temp_file_path);

    // Mimic Symfony and Drupal's upload file handling.
    $temp_file_info = new UploadedFile($temp_file_path, basename($new_file_uri), NULL, $temp_file_size);
    $webform_element_key = $element_plugin
      ->getLabel($element);
    $new_file = _webform_submission_export_import_file_save_upload_single($temp_file_info, $webform_element_key, $file_upload_validators, $file_destination);
    if ($new_file) {
      $new_file_ids[$new_file_hash] = $new_file
        ->id();
    }
  }
  $values = array_values($new_file_ids);
  if (empty($values)) {
    return $element_plugin
      ->hasMultipleValues($element) ? [] : NULL;
  }
  else {
    return $element_plugin
      ->hasMultipleValues($element) ? $values : reset($values);
  }
}