72 lines
2.2 KiB
PHP
72 lines
2.2 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Document;
|
|
use Carbon\Carbon;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\Storage;
|
|
|
|
class PruneDocumentPreviews extends Command
|
|
{
|
|
protected $signature = 'documents:prune-previews {--days=90 : Delete previews older than this many days} {--dry-run : Show what would be deleted without deleting}';
|
|
|
|
protected $description = 'Deletes generated document preview files older than N days and clears their metadata.';
|
|
|
|
public function handle(): int
|
|
{
|
|
$days = (int) $this->option('days');
|
|
if ($days < 1) {
|
|
$days = 90;
|
|
}
|
|
$cutoff = Carbon::now()->subDays($days);
|
|
|
|
$previewDisk = config('files.preview_disk', 'public');
|
|
$query = Document::query()
|
|
->whereNotNull('preview_path')
|
|
->whereNotNull('preview_generated_at')
|
|
->where('preview_generated_at', '<', $cutoff);
|
|
|
|
$count = $query->count();
|
|
if ($count === 0) {
|
|
$this->info('No stale previews found.');
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$this->info("Found {$count} previews older than {$days} days.");
|
|
$dry = (bool) $this->option('dry-run');
|
|
|
|
$query->chunkById(200, function ($docs) use ($previewDisk, $dry) {
|
|
foreach ($docs as $doc) {
|
|
$path = $doc->preview_path;
|
|
if (! $path) {
|
|
continue;
|
|
}
|
|
if ($dry) {
|
|
$this->line("Would delete: {$previewDisk}://{$path} (document #{$doc->id})");
|
|
|
|
continue;
|
|
}
|
|
try {
|
|
Storage::disk($previewDisk)->delete($path);
|
|
} catch (\Throwable $e) {
|
|
// ignore errors, continue processing
|
|
}
|
|
$doc->preview_path = null;
|
|
$doc->preview_mime = null;
|
|
$doc->preview_generated_at = null;
|
|
$doc->save();
|
|
}
|
|
});
|
|
|
|
if ($dry) {
|
|
$this->info('Dry run completed. No files were deleted.');
|
|
} else {
|
|
$this->info('Stale previews deleted and metadata cleared.');
|
|
}
|
|
|
|
return self::SUCCESS;
|
|
}
|
|
}
|