From 0298ec5b1bddc4f0052f5fe194f6fed52b408beb Mon Sep 17 00:00:00 2001 From: Cam Kemshal-Bell Date: Tue, 17 Dec 2024 13:44:57 +1100 Subject: [PATCH 1/5] fix: add const for holding the image disk --- app/Livewire/Questions/Create.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app/Livewire/Questions/Create.php b/app/Livewire/Questions/Create.php index a83fd1053..c3a890799 100644 --- a/app/Livewire/Questions/Create.php +++ b/app/Livewire/Questions/Create.php @@ -30,6 +30,8 @@ final class Create extends Component { use WithFileUploads; + private const string IMAGE_DISK = 'public'; + /** * Max number of images allowed. */ @@ -284,7 +286,7 @@ public function render(): View */ private function optimizeImage(string $path): void { - $imagePath = Storage::disk('public')->path($path); + $imagePath = Storage::disk(self::IMAGE_DISK)->path($path); $imagick = new Imagick($imagePath); if ($imagick->getNumberImages() > 1) { @@ -318,7 +320,7 @@ private function deleteImage(string $path): void return; } - Storage::disk('public')->delete($path); + Storage::disk(self::IMAGE_DISK)->delete($path); $this->cleanSession($path); } @@ -331,7 +333,7 @@ private function uploadImages(): void $today = now()->format('Y-m-d'); /** @var string $path */ - $path = $image->store("images/{$today}", 'public'); + $path = $image->store("images/{$today}", self::IMAGE_DISK); $this->optimizeImage($path); if ($path) { From 4267e261821ddf4596f55a2ea17a63c433b30c02 Mon Sep 17 00:00:00 2001 From: Cam Kemshal-Bell Date: Tue, 17 Dec 2024 13:45:39 +1100 Subject: [PATCH 2/5] fix: extract method for get images from session --- app/Livewire/Questions/Create.php | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/app/Livewire/Questions/Create.php b/app/Livewire/Questions/Create.php index c3a890799..ce508f00c 100644 --- a/app/Livewire/Questions/Create.php +++ b/app/Livewire/Questions/Create.php @@ -358,10 +358,7 @@ private function uploadImages(): void */ private function cleanSession(string $path): void { - /** @var array $images */ - $images = session()->get('images', []); - - $remainingImages = collect($images) + $remainingImages = collect($this->getSessionImages()) ->reject(fn (string $imagePath): bool => $imagePath === $path); session()->put('images', $remainingImages->toArray()); @@ -372,13 +369,23 @@ private function cleanSession(string $path): void */ private function deleteUnusedImages(): void { - /** @var array $images */ - $images = session()->get('images', []); - - collect($images) + collect($this->getSessionImages()) ->reject(fn (string $path): bool => str_contains($this->content, $path)) ->each(fn (string $path): ?bool => $this->deleteImage($path)); session()->forget('images'); } + + /** + * Get the session images. + * + * @return array + */ + private function getSessionImages(): array + { + /** @var array $images */ + $images = session()->get('images', []); + + return $images; + } } From 0c131b5e1aa15221ff29aad1ce084642ac8694b6 Mon Sep 17 00:00:00 2001 From: Cam Kemshal-Bell Date: Tue, 17 Dec 2024 13:46:10 +1100 Subject: [PATCH 3/5] fix: add public method with validation to delete images from the client --- app/Livewire/Questions/Create.php | 36 +++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/app/Livewire/Questions/Create.php b/app/Livewire/Questions/Create.php index ce508f00c..8f04eb82a 100644 --- a/app/Livewire/Questions/Create.php +++ b/app/Livewire/Questions/Create.php @@ -281,6 +281,42 @@ public function render(): View ]); } + /** + * Validate and delete the image if it meets criteria. + */ + public function deleteImageAfterValidation(string $path): void + { + if (! $this->validateImagePath($path)) { + return; + } + + $this->deleteImage($path); + } + + /** + * Validate if the image path is eligible for deletion. + */ + private function validateImagePath(string $path): bool + { + $images = $this->getSessionImages(); + + return in_array($path, $images, true) && $this->isValidImageFile($path); + } + + /** + * Check if the path exists and is a valid image file. + */ + private function isValidImageFile(string $path): bool + { + if (! Storage::disk(self::IMAGE_DISK)->exists($path)) { + return false; + } + + $imageContent = Storage::disk(self::IMAGE_DISK)->get($path) ?: ''; + + return @getimagesizefromstring($imageContent) !== false; + } + /** * Optimize the images. */ From 7bbee9959c9339141bff9635189c3d8f83b6cf93 Mon Sep 17 00:00:00 2001 From: Cam Kemshal-Bell Date: Tue, 17 Dec 2024 13:46:33 +1100 Subject: [PATCH 4/5] fix: update alpine component to use safe public method --- resources/js/image-upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/js/image-upload.js b/resources/js/image-upload.js index cfb9e9a2c..e3cc01df7 100644 --- a/resources/js/image-upload.js +++ b/resources/js/image-upload.js @@ -138,7 +138,7 @@ const imageUpload = () => ({ removeImage(event, index) { event.preventDefault(); - this.$wire.deleteImage( + this.$wire.deleteImageAfterValidation( this.normalizePath(this.images[index].path) ); this.removeMarkdownImage(index); From e8c2724e748d131f03b9e044d233d3641476e07f Mon Sep 17 00:00:00 2001 From: Cam Kemshal-Bell Date: Tue, 17 Dec 2024 13:56:17 +1100 Subject: [PATCH 5/5] fix: add annotations to the const --- app/Livewire/Questions/Create.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/Livewire/Questions/Create.php b/app/Livewire/Questions/Create.php index 8f04eb82a..9619f7518 100644 --- a/app/Livewire/Questions/Create.php +++ b/app/Livewire/Questions/Create.php @@ -30,6 +30,9 @@ final class Create extends Component { use WithFileUploads; + /** + * The disk to store the images. + */ private const string IMAGE_DISK = 'public'; /**