denyAccessUnlessGranted('ROLE_VIEWER'); $document = $this->documentRepository->find($id); if (!$document) { return $this->json(['error' => 'Document not found.'], 404); } $path = $document->getPath(); // Backward compatibility: serve Base64 data URIs from DB if ($this->storageService->isBase64DataUri($path)) { $parts = explode(',', $path, 2); $content = base64_decode($parts[1] ?? '', true); if (false === $content) { return $this->json(['error' => 'Invalid document data.'], 500); } return new Response($content, 200, [ 'Content-Type' => $document->getMimeType(), 'Content-Disposition' => ResponseHeaderBag::DISPOSITION_INLINE.'; filename="'.$document->getFilename().'"', 'Content-Length' => (string) strlen($content), 'Cache-Control' => 'private, max-age=3600', ]); } // File-based path: serve from disk $absolutePath = $this->storageService->getAbsolutePath($path); if (!file_exists($absolutePath)) { return $this->json(['error' => 'File not found on disk.'], 404); } $response = new BinaryFileResponse($absolutePath); $response->headers->set('Content-Type', $document->getMimeType()); $response->setContentDisposition( ResponseHeaderBag::DISPOSITION_INLINE, $document->getFilename() ); $response->headers->set('Cache-Control', 'private, max-age=3600'); return $response; } #[Route('/{id}/download', name: 'document_download_file', methods: ['GET'])] public function download(string $id): Response { $this->denyAccessUnlessGranted('ROLE_VIEWER'); $document = $this->documentRepository->find($id); if (!$document) { return $this->json(['error' => 'Document not found.'], 404); } $path = $document->getPath(); if ($this->storageService->isBase64DataUri($path)) { $parts = explode(',', $path, 2); $content = base64_decode($parts[1] ?? '', true); if (false === $content) { return $this->json(['error' => 'Invalid document data.'], 500); } return new Response($content, 200, [ 'Content-Type' => 'application/octet-stream', 'Content-Disposition' => ResponseHeaderBag::DISPOSITION_ATTACHMENT.'; filename="'.$document->getFilename().'"', 'Content-Length' => (string) strlen($content), ]); } $absolutePath = $this->storageService->getAbsolutePath($path); if (!file_exists($absolutePath)) { return $this->json(['error' => 'File not found on disk.'], 404); } $response = new BinaryFileResponse($absolutePath); $response->setContentDisposition( ResponseHeaderBag::DISPOSITION_ATTACHMENT, $document->getFilename() ); return $response; } }