Score:1

Compress file with ArchiveInterface without file paths

us flag

I'm trying to create an archive of log files to be downloadable in a form making a custom module in Drupal 9. In the form, the user can change the format of the archive, as per image: Screen of the log form

Here below my code:

private function download($form, $form_state) {
  $format = $form_state->getValue('format');
  $folder = $form_state->getValue('folders');

  $date = new DateTime();
  $date = $date->format("y_m_d_H_i_s");

  $logsDirectory = \Drupal::service('file_system')
    ->realpath($folder . "://logs/");
  //Retrieve all the files in the folder.
  $logs = glob($logsDirectory . "/*.log");

  $archiveName = $date . $format;

  $archive_path = \Drupal::service('file_system')
    ->saveData('', 'temporary://' . $archiveName);
  $archive = \Drupal::service('plugin.manager.archiver')
    ->getInstance(['filepath' => $archive_path]);

  foreach ($logs as $log) {
    $archive->add($log);
  }

  $response = new BinaryFileResponse($archive_path);
  $response->headers->set('Content-type', $this->getContentTypes($format));
  $response->headers->set('Content-Disposition', 'attachment;filename="' . $archive_path . '"');
  $form_state->setResponse($response);
}

Everything is going fine, I managed to achieve a button in this way that, when pressed, downloads the archive with all the log files inside. The problem is that inside of this zip all the files are inside their absolute path, in this way: Tree of files inside the zip

This is because in the ArchiveInterface Class the add method only accepts one parameter, $file_path, and it is not supported to add a second parameter to specify the name of the files. How could I solve this problem, being able of adding inside the archive only the files and not all the subfolders?

cn flag
I realised after posting an answer that the user chooses the format, so you need more than Zip. The Zip one is easy, unfortunately the Tar one not so much. The PHP archiver doesn't support what you want so you need to extend it (https://stackoverflow.com/questions/15831121/adding-files-to-a-tar-archive-in-php-with-different-filenames). Let me know if the answer isn't useful at all and I'll delete if so
Score:0
cn flag

Drupal's Zip archiver doesn't support that functionality directly, but the underlying PHP ZipArchive it uses does (see ZipArchive::addFile()), and you can get a reference to that object from the Drupal archiver.

For example:

$zip_archive = $archive->getArchive();
foreach ($logs as $log) {
  $zip_archive->addFile($log, basename($log));
}

Bear in mind that this only works well for a glob that brings back unique file names every time. If the structure changes and you end up with subfolders containing files with name clashes, you'll need to update the loop to accommodate, or risk some files not being included.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.