From f63bd2eed640ae8d800652e13dbaf7106a365235 Mon Sep 17 00:00:00 2001 From: Tajim Date: Tue, 1 Sep 2026 22:21:34 +0600 Subject: [PATCH 1/2] fix(commands): update DeleteUnusedImages to cover all image storage paths Add forum posts, forum answers, and support ticket attachments. Add per-directory summary output. Skip emails/images (not model-tracked). --- app/Console/Commands/DeleteUnusedImages.php | 61 ++++++++++++++++----- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/app/Console/Commands/DeleteUnusedImages.php b/app/Console/Commands/DeleteUnusedImages.php index 24f71e9c..2cb02a3a 100644 --- a/app/Console/Commands/DeleteUnusedImages.php +++ b/app/Console/Commands/DeleteUnusedImages.php @@ -3,8 +3,11 @@ namespace App\Console\Commands; use App\Models\Blog; +use App\Models\ForumAnswer; +use App\Models\ForumPost; use App\Models\Notice; use App\Models\Resource; +use App\Models\SupportTicket; use App\Models\User; use Illuminate\Console\Command; use Illuminate\Support\Facades\Storage; @@ -13,31 +16,23 @@ class DeleteUnusedImages extends Command { protected $signature = 'resources:clean-unused-images {--dry-run}'; - protected $description = 'Delete unused uploaded images'; + protected $description = 'Delete unused uploaded images from all storage directories'; public function handle(): void { - $this->cleanDirectory( - 'resources', - Resource::whereNotNull('file_path') - ->pluck('file_path') - ->toArray() - ); - + // User profile images $this->cleanDirectory( 'users', - User::whereNotNull('image_path') - ->pluck('image_path') - ->toArray() + User::whereNotNull('image_path')->pluck('image_path')->toArray() ); + // Blog featured images $this->cleanDirectory( 'blogs', - Blog::whereNotNull('featured_image_path') - ->pluck('featured_image_path') - ->toArray() + Blog::whereNotNull('featured_image_path')->pluck('featured_image_path')->toArray() ); + // Notice images (skip external URLs) $this->cleanDirectory( 'notices', Notice::whereNotNull('image') @@ -46,6 +41,36 @@ public function handle(): void ->toArray() ); + // Resource files (notes, images, videos — all stored under resources/) + $this->cleanDirectory( + 'resources', + Resource::whereNotNull('file_path')->pluck('file_path')->toArray() + ); + + // Forum post images + $this->cleanDirectory( + 'forum/posts', + ForumPost::whereNotNull('image_path')->pluck('image_path')->toArray() + ); + + // Forum answer images + $this->cleanDirectory( + 'forum/answers', + ForumAnswer::whereNotNull('image_path')->pluck('image_path')->toArray() + ); + + // Support ticket attachments + $this->cleanDirectory( + 'tickets', + SupportTicket::whereNotNull('attachment_path') + ->where('attachment_path', 'not like', 'http%') + ->pluck('attachment_path') + ->toArray() + ); + + // emails/images is intentionally skipped — those paths are embedded + // inline into email HTML bodies and not tracked in any model column. + $this->info('Done.'); } @@ -53,14 +78,22 @@ protected function cleanDirectory(string $directory, array $usedFiles): void { $files = Storage::allFiles($directory); + $deleted = 0; + foreach ($files as $file) { if (! in_array($file, $usedFiles, true)) { $this->line("Unused: {$file}"); if (! $this->option('dry-run')) { Storage::delete($file); + $deleted++; } } } + + $label = $this->option('dry-run') ? 'would delete' : 'deleted'; + $count = $this->option('dry-run') ? count(array_diff($files, $usedFiles)) : $deleted; + + $this->info("[{$directory}] {$count} file(s) {$label}."); } } From a3500eb344414a9ca437df2c258f44b4641f9325 Mon Sep 17 00:00:00 2001 From: Tajim Date: Tue, 1 Sep 2026 22:25:22 +0600 Subject: [PATCH 2/2] fix(commands): fix Notice image path bug in DeleteUnusedImages Notice::pluck('image') goes through getImageAttribute() which returns a full URL instead of the raw storage path, causing every notice image to be falsely flagged as unused and deleted. Use DB::table to bypass the accessor and get the raw path. --- app/Console/Commands/DeleteUnusedImages.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/Console/Commands/DeleteUnusedImages.php b/app/Console/Commands/DeleteUnusedImages.php index 2cb02a3a..8fd9b29d 100644 --- a/app/Console/Commands/DeleteUnusedImages.php +++ b/app/Console/Commands/DeleteUnusedImages.php @@ -10,6 +10,7 @@ use App\Models\SupportTicket; use App\Models\User; use Illuminate\Console\Command; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Storage; class DeleteUnusedImages extends Command @@ -32,10 +33,13 @@ public function handle(): void Blog::whereNotNull('featured_image_path')->pluck('featured_image_path')->toArray() ); - // Notice images (skip external URLs) + // Notice images — use DB::table to bypass the getImageAttribute accessor, + // which converts stored paths to full URLs and would cause every notice + // image to be falsely flagged as unused. $this->cleanDirectory( 'notices', - Notice::whereNotNull('image') + DB::table('notices') + ->whereNotNull('image') ->where('image', 'not like', 'http%') ->pluck('image') ->toArray()