From bc7937d2b37193c5bb67753ee63f6476f1d22b72 Mon Sep 17 00:00:00 2001 From: Yisroel Baum Date: Fri, 26 Jun 2026 08:16:15 +0300 Subject: [PATCH] extract pdf use case --- backend/app/Controllers/ElementController.php | 43 ++++++--------- .../UseCases/GetElementPdf/GetElementPdf.php | 53 +++++++++++++++++++ .../GetElementPdf/GetElementPdfRequest.php | 12 +++++ .../GetElementPdf/GetElementPdfResult.php | 28 ++++++++++ backend/app/Providers/AppServiceProvider.php | 6 +++ .../Shared/Files/LaravelStoredFileReader.php | 17 ++++++ backend/app/Shared/Files/StoredFileReader.php | 8 +++ 7 files changed, 141 insertions(+), 26 deletions(-) create mode 100644 backend/app/Element/UseCases/GetElementPdf/GetElementPdf.php create mode 100644 backend/app/Element/UseCases/GetElementPdf/GetElementPdfRequest.php create mode 100644 backend/app/Element/UseCases/GetElementPdf/GetElementPdfResult.php create mode 100644 backend/app/Shared/Files/LaravelStoredFileReader.php create mode 100644 backend/app/Shared/Files/StoredFileReader.php diff --git a/backend/app/Controllers/ElementController.php b/backend/app/Controllers/ElementController.php index e086df6..aeee12b 100644 --- a/backend/app/Controllers/ElementController.php +++ b/backend/app/Controllers/ElementController.php @@ -9,6 +9,8 @@ use App\Element\UseCases\DeleteChildElement\DeleteChildElement; use App\Element\UseCases\DeleteChildElement\DeleteChildElementRequest; use App\Element\UseCases\GetElement\GetElement; use App\Element\UseCases\GetElement\GetElementRequest; +use App\Element\UseCases\GetElementPdf\GetElementPdf; +use App\Element\UseCases\GetElementPdf\GetElementPdfRequest; use App\Element\UseCases\ReorderChildElements\ReorderChildElements; use App\Element\UseCases\ReorderChildElements\ReorderChildElementsRequest; use App\Element\UseCases\UpdateElement\UpdateElement; @@ -20,18 +22,16 @@ use Illuminate\Http\JsonResponse; use Illuminate\Http\Request; use Illuminate\Http\Response; use Illuminate\Http\UploadedFile; -use Illuminate\Support\Facades\Storage; class ElementController { - private const PDF_FOLDERS = ['short', 'long']; - public function __construct( private GetElement $getElement, private CreateChildElement $createChildElement, private DeleteChildElement $deleteChildElement, private ReorderChildElements $reorderChildElements, private UpdateElement $updateElement, + private GetElementPdf $getElementPdf, private FileUploader $fileUploader, ) { } @@ -72,31 +72,27 @@ class ElementController string $folder, string $fileName, ): Response|JsonResponse { - if (!$this->isAllowedPdfFolder($folder)) { + try { + $result = $this->getElementPdf->execute( + new GetElementPdfRequest( + folder: $folder, + fileName: $fileName, + ) + ); + } catch (NotFoundException $exception) { return new JsonResponse([ - 'error' => 'PDF not found', - ], 404); - } - - if (!preg_match('/^[A-Za-z0-9._-]+\.pdf$/', $fileName)) { - return new JsonResponse([ - 'error' => 'PDF not found', - ], 404); - } - - $path = "element-pdfs/$folder/$fileName"; - if (!Storage::disk('public')->exists($path)) { - return new JsonResponse([ - 'error' => 'PDF not found', + 'error' => $exception->getMessage(), ], 404); } return new Response( - Storage::disk('public')->get($path), + $result->getContents(), 200, [ - 'Content-Type' => 'application/pdf', - 'Content-Disposition' => "inline; filename=\"$fileName\"", + 'Content-Type' => $result->getMimeType(), + 'Content-Disposition' => 'inline; filename="' + . $result->getFileName() + . '"', ], ); } @@ -409,9 +405,4 @@ class ElementController return $path; } - - private function isAllowedPdfFolder(string $folder): bool - { - return in_array($folder, self::PDF_FOLDERS, true); - } } diff --git a/backend/app/Element/UseCases/GetElementPdf/GetElementPdf.php b/backend/app/Element/UseCases/GetElementPdf/GetElementPdf.php new file mode 100644 index 0000000..86d33cf --- /dev/null +++ b/backend/app/Element/UseCases/GetElementPdf/GetElementPdf.php @@ -0,0 +1,53 @@ +isAllowedPdfFolder($request->folder)) { + throw new NotFoundException('PDF not found'); + } + + if (!$this->isValidPdfFileName($request->fileName)) { + throw new NotFoundException('PDF not found'); + } + + $path = "element-pdfs/$request->folder/$request->fileName"; + $contents = $this->storedFileReader->read($path); + if ($contents === null) { + throw new NotFoundException('PDF not found'); + } + + return new GetElementPdfResult( + contents: $contents, + fileName: $request->fileName, + mimeType: self::PDF_MIME_TYPE, + ); + } + + private function isAllowedPdfFolder(string $folder): bool + { + return in_array($folder, self::PDF_FOLDERS, true); + } + + private function isValidPdfFileName(string $fileName): bool + { + return preg_match('/^[A-Za-z0-9._-]+\.pdf$/', $fileName) === 1; + } +} diff --git a/backend/app/Element/UseCases/GetElementPdf/GetElementPdfRequest.php b/backend/app/Element/UseCases/GetElementPdf/GetElementPdfRequest.php new file mode 100644 index 0000000..8824afd --- /dev/null +++ b/backend/app/Element/UseCases/GetElementPdf/GetElementPdfRequest.php @@ -0,0 +1,12 @@ +contents; + } + + public function getFileName(): string + { + return $this->fileName; + } + + public function getMimeType(): string + { + return $this->mimeType; + } +} diff --git a/backend/app/Providers/AppServiceProvider.php b/backend/app/Providers/AppServiceProvider.php index 9ea2b0c..333e4ed 100644 --- a/backend/app/Providers/AppServiceProvider.php +++ b/backend/app/Providers/AppServiceProvider.php @@ -10,6 +10,8 @@ use App\Auth\SystemClock; use App\Auth\TokenGenerator; use App\Shared\Files\FileUploader; use App\Shared\Files\LaravelFileUploader; +use App\Shared\Files\LaravelStoredFileReader; +use App\Shared\Files\StoredFileReader; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -32,5 +34,9 @@ class AppServiceProvider extends ServiceProvider FileUploader::class, LaravelFileUploader::class, ); + $this->app->bind( + StoredFileReader::class, + LaravelStoredFileReader::class, + ); } } diff --git a/backend/app/Shared/Files/LaravelStoredFileReader.php b/backend/app/Shared/Files/LaravelStoredFileReader.php new file mode 100644 index 0000000..d1d9fbf --- /dev/null +++ b/backend/app/Shared/Files/LaravelStoredFileReader.php @@ -0,0 +1,17 @@ +exists($path)) { + return null; + } + + return Storage::disk('public')->get($path); + } +} diff --git a/backend/app/Shared/Files/StoredFileReader.php b/backend/app/Shared/Files/StoredFileReader.php new file mode 100644 index 0000000..77117b6 --- /dev/null +++ b/backend/app/Shared/Files/StoredFileReader.php @@ -0,0 +1,8 @@ +