From f2b84fa9f8737fc594afead2db25860c78254399 Mon Sep 17 00:00:00 2001 From: Philipp Reinking Date: Sat, 10 Oct 2026 14:28:24 +0200 Subject: [PATCH] Clear a form image path even when its file is already gone Co-Authored-By: Claude Opus 5.5 --- CHANGELOG.md | 1 + app/Http/Controllers/Api/FormImagesController.php | 12 +++++------- tests/Feature/FormImageTest.php | 11 +++++++++++ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9c0b38c2..db7efae4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -36,6 +36,7 @@ Lines marked **Upgrade step** need you to act after updating. - A failed template import shows an error in the settings, such as which link is not allowed or that the form already has answers. Before, nothing happened. (#211) - A form session's "active" check counted every session as active. Nothing in the app depends on it yet. (#194) - Forms with many submissions load faster: the dashboard, editor and submissions page count answers in the database instead of loading them all, and submitting uses new database indexes. The CSV export works with 10,000 submissions and more, an export without submissions has its header row, and answers starting with = + - @ get a leading `'` so spreadsheets don't run them as formulas. Plain numbers and phone numbers stay as they are. (#217) +- A logo or background whose file is already gone, and shows as a broken image, can be removed again. (#219) ### Security diff --git a/app/Http/Controllers/Api/FormImagesController.php b/app/Http/Controllers/Api/FormImagesController.php index 8ca296e3..971c7a8d 100644 --- a/app/Http/Controllers/Api/FormImagesController.php +++ b/app/Http/Controllers/Api/FormImagesController.php @@ -56,15 +56,13 @@ public function delete(Request $request, Form $form, DeleteUnusedFormImages $del ]); $fieldname = $request->input('type').'_path'; + $oldPath = $form->$fieldname; - if ($form->hasImage($request->input('type'))) { - $oldPath = $form->$fieldname; - - $form->$fieldname = null; - $form->save(); + // clear the path even when its file is already gone, so a broken image can be removed + $form->$fieldname = null; + $form->save(); - $deleteUnusedImages->delete(collect([$oldPath])); - } + $deleteUnusedImages->delete(collect([$oldPath])); return response()->json($form, 200); } diff --git a/tests/Feature/FormImageTest.php b/tests/Feature/FormImageTest.php index 3684b2cf..763b467b 100644 --- a/tests/Feature/FormImageTest.php +++ b/tests/Feature/FormImageTest.php @@ -158,6 +158,17 @@ expect($original->fresh()->hasImage($type))->toBeTrue(); })->with(['avatar', 'background']); +test('removing an image whose file is already gone clears its path', function (string $type) { + Storage::fake(); + $form = Form::factory()->create([$type.'_path' => 'form/gone.png']); + + $this->actingAs($form->user) + ->json('DELETE', route('api.forms.images.delete', $form->uuid), ['type' => $type]) + ->assertStatus(200); + + expect($form->fresh()->{$type.'_path'})->toBeNull(); +})->with(['avatar', 'background']); + test('replacing or removing an image no other form uses deletes it and its resized copies', function (string $type) { Storage::fake(); $form = Form::factory()->create([$type.'_path' => 'form/old.png']);