fileSystem = $file_system; $this->tempStoreFactory = $tempStoreFactory; $this->flysystemFactory = $flysystemFactory; $this->streamWrapperManager = $streamWrapperManager; } public static function create(ContainerInterface $container): self { return new self( $container->get('file_system'), $container->get('tempstore.private'), $container->get('flysystem_factory'), $container->get('stream_wrapper_manager') ); } /** * Builds and downloads archive. * * @param string $filename * * @return \Symfony\Component\HttpFoundation\StreamedResponse */ public function download(string $filename): StreamedResponse { $temp_store = $this->tempStoreFactory->get('islandora_collection_harvest'); $media_entities = $temp_store->get($filename); if (empty($media_entities)) { throw new \Symfony\Component\HttpKernel\Exception\NotFoundHttpException('No media found.'); } return new StreamedResponse(function() use ($media_entities) { $zip = new \ZipArchive(); $tmpfile = tempnam(sys_get_temp_dir(), 'collection_zip_'); $zip->open($tmpfile, \ZipArchive::CREATE | \ZipArchive::OVERWRITE); foreach ($media_entities as $media) { $source_field = $media->getSource() ->getConfiguration()['source_field'] ?? NULL; if (!$source_field || !$media->hasField($source_field)) { continue; } $file = $media->get($source_field)->entity; if (!$file) { continue; } $uri = $file->getFileUri(); $filename_in_zip = basename($uri); $real_path = $this->fileSystem->realpath($uri); if ($real_path && file_exists($real_path)) { $zip->addFile($real_path, $filename_in_zip); } else { // Flysystem v1 fallback try { $scheme = $this->streamWrapperManager->getScheme($uri); $path = substr($uri, strlen($scheme) + 3); $filesystem = $this->flysystemFactory->getFilesystem($scheme); if ($filesystem && $filesystem->has($path)) { $contents = $filesystem->read($path); if ($contents !== FALSE) { $tmp_fly = tempnam(sys_get_temp_dir(), 'zip_'); file_put_contents($tmp_fly, $contents); $zip->addFile($tmp_fly, $filename_in_zip); } } } catch (\Exception $e) { $this->logger('islandora_collection_harvest')->error( 'Error reading @uri from Flysystem: @msg', ['@uri' => $uri, '@msg' => $e->getMessage()] ); } } } $zip->close(); readfile($tmpfile); unlink($tmpfile); }, 200, [ 'Content-Type' => 'application/zip', 'Content-Disposition' => 'attachment; filename="' . $filename . '"', ]); } }