You are here

public function EmailedExport::executeTask in Webform Scheduled Tasks 8.2

Execute a task.

Parameters

\Iterator $submissions: An iterator of webform submissions to process.

Throws

\Exception

\Drupal\webform_scheduled_tasks\Exception\RetryScheduledTaskException

\Drupal\webform_scheduled_tasks\Exception\HaltScheduledTaskException

Overrides TaskPluginInterface::executeTask

File

src/Plugin/WebformScheduledTasks/Task/EmailedExport.php, line 209

Class

EmailedExport
A task which emails an export of a list of webforms.

Namespace

Drupal\webform_scheduled_tasks\Plugin\WebformScheduledTasks\Task

Code

public function executeTask(\Iterator $submissions) {
  $exporter = $this
    ->initializeExporter();
  $exporter
    ->writeHeader();
  $processed_submission_ids = [];
  foreach ($submissions as $submission) {

    // @todo, ask that ::writeRecords accepts an iterator.
    $exporter
      ->writeRecords([
      $submission,
    ]);
    $processed_submission_ids[] = $submission
      ->id();
  }
  $exporter
    ->writeFooter();

  // This is required to add actual submission data file into the associated
  // archive when files have been included inside the export.
  if ($exporter
    ->isArchive()) {
    $exporter
      ->writeExportToArchive();
  }

  // If no submissions were present while running this scheduled task, there
  // is no need to send an export.
  if (empty($processed_submission_ids)) {
    return;
  }

  // Defensively catch errors in an export early to prevent any data loss,
  // check the file exists and the file has some data in it.
  if (!file_exists($this
    ->getExportFileOrArchivePath($exporter)) || filesize($this
    ->getExportFileOrArchivePath($exporter)) === 0) {
    throw new HaltScheduledTaskException('Export files are failing to generate or are empty.');
  }

  // Archive tar can throw warnings and produce a corrupt tar file without
  // ever throwing an exception, see d.o/project/drupal/issues/3026470.
  // Attempt to be a bit more defensive about this and try to verify a valid
  // archive was produced. With the php internal functions used to build the
  // archiver throwing warnings, a big risk is silent failure. The current
  // verification is a "best guess", given complexities around the number and
  // size of various files which should be in the archive.
  if ($exporter
    ->isArchive() && !$this
    ->verifyArchive($this
    ->getExportFileOrArchivePath($exporter))) {
    throw new HaltScheduledTaskException('An invalid archive file was generated.');
  }
  $target_directory = static::DESTINATION_DIRECTORY;
  if (!$this->fileSystem
    ->prepareDirectory($target_directory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS)) {
    throw new HaltScheduledTaskException('Could not create a directory for the exported files to be written to.');
  }
  $attempted_file_destination_uri = sprintf('%s/%s', static::DESTINATION_DIRECTORY, $this
    ->getExportFileOrArchiveName($exporter));
  if (!($unique_destination_file_uri = $this->fileSystem
    ->copy($this
    ->getExportFileOrArchivePath($exporter), $attempted_file_destination_uri))) {
    throw new HaltScheduledTaskException('Could not write the generated file to the private file system.');
  }

  // Save a file entity with the data so the file can be deleted from the UI
  // if it has been downloaded.
  $file = File::create([
    'uri' => $unique_destination_file_uri,
    'filename' => $this
      ->getExportFileOrArchiveName($exporter),
    'status' => FILE_STATUS_PERMANENT,
  ]);
  $file
    ->save();

  // Register a file usage that tells Drupal the file URI was sent in an
  // email, to prevent the make_unused_managed_files_temporary setting from
  // deleting it. This will ensure the file sticks around until the user
  // explicitly decides to delete the export.
  $this->fileUsage
    ->add($file, 'webform_scheduled_tasks', 'email_uri', $this
    ->getScheduledTask()
    ->id());

  // Add the export as an email attachment if the task is configured as such.
  // Note, the file is still written to the private file system regardless, to
  // ensure no data is lost in the case of dropped, rejected or undelivered
  // mail.
  $email_attachments = [];
  if ($this->configuration['storage_type'] === static::STORAGE_TYPE_EMAIL) {
    $email_attachments[] = [
      'filecontent' => file_get_contents($file
        ->getFileUri()),
      'filename' => $file
        ->getFilename(),
      'filemime' => $file
        ->getMimeType(),
      'filepath' => $this->fileSystem
        ->realpath($file
        ->getFileUri()),
    ];
  }
  $this
    ->emailRecipients('export_summary_filesystem', [
    'file_url' => file_create_url($unique_destination_file_uri),
    'task_id' => $this
      ->getScheduledTask()
      ->id(),
    'attachments' => $email_attachments,
  ]);
  if ($this->configuration['delete_submissions']) {
    foreach ($processed_submission_ids as $submission_delete_id) {
      WebformSubmission::load($submission_delete_id)
        ->delete();
    }
  }
}