Upload::TYPE_INVOICE] )] #[IsGranted('ROLE_ADMINISTRATIVE')] public function index(string $type): Response { $status = Upload::TYPE_INVOICE === $type ? Upload::STATUS_PAID : Upload::STATUS_CHECKED; $uploads = $this ->uploadRepository ->getBatchDownloadList($type, $status) ; if (0 === count($uploads)) { $this->addFlash('error', 'Keine Dokumente vorhanden'); return $this->redirectToRoute('app_administrative_document_index'); } $zipFilename = sprintf('%ss_%s.zip', $type, date('YmdHi')); $response = new StreamedResponse(function () use ($uploads, $zipFilename) { $zip = new ZipStream( defaultEnableZeroHeader: true, outputName: $zipFilename, contentType: 'application/octet-stream' ); $namer = new DownloadNamer(); foreach ($uploads as $upload) { /** @var Upload $upload */ $teamer = $upload->getOwner()->getTeamer(); $filename = $namer->nameForTeamer($upload, $teamer); $filepath = $this->uploadHandler->getResolvedUploadFilepath($upload); try { $zip->addFileFromPath(fileName: $filename, path: $filepath); $upload ->setDownloaded() ->setDownloadedBy($this->getUser()->getUserIdentifier()) ; } catch (FileNotFoundException|FileNotReadableException $e) { $this->logger->error('Unable to add file to ZIP', [ 'upload' => $upload->getUuid(), 'error' => $e->getMessage(), ]); } } $zip->finish(); $this->entityManager->flush(); }); $disposition = HeaderUtils::makeDisposition('attachment', $zipFilename, md5($zipFilename)); $response->headers->set('Content-Disposition', $disposition); return $response; } }