option('limit'); $now = (bool) $this->option('now'); $docs = Document::query() ->whereNull('deleted_at') ->where(function ($q) { $q->whereRaw("lower(extension) in ('doc','docx')"); }) ->orderByDesc('updated_at') ->limit($limit * 5) ->get(); if ($docs->isEmpty()) { $this->info('No documents requiring preview generation.'); return self::SUCCESS; } $this->info('Scanning '.$docs->count().' candidate document(s) for (re)generation...'); $dispatched = 0; foreach ($docs as $doc) { // Verify source file exists on disk or under public before dispatching $disk = $doc->disk ?: 'public'; $relPath = ltrim($doc->path ?? '', '/\\'); if (str_starts_with($relPath, 'public/')) { $relPath = substr($relPath, 7); } $has = Storage::disk($disk)->exists($relPath); if (! $has) { $publicFull = public_path($relPath); $real = @realpath($publicFull); $publicRoot = @realpath(public_path()); $realN = $real ? str_replace('\\\\', '/', $real) : null; $rootN = $publicRoot ? str_replace('\\\\', '/', $publicRoot) : null; $has = $realN && $rootN && str_starts_with($realN, $rootN) && is_file($real); } if (! $has) { $this->warn('Skipping doc '.$doc->id.' (source file missing): '.$doc->path); continue; } // Determine if (re)generation is required $needs = false; $previewDisk = config('files.preview_disk', 'public'); if (empty($doc->preview_path)) { $needs = true; } else { $existsPreview = Storage::disk($previewDisk)->exists($doc->preview_path); if (! $existsPreview) { $needs = true; } elseif ($doc->preview_generated_at && $doc->updated_at && $doc->updated_at->gt($doc->preview_generated_at)) { $needs = true; } } if (! $needs) { continue; } if ($now) { GenerateDocumentPreview::dispatchSync($doc->id); } else { GenerateDocumentPreview::dispatch($doc->id); } $dispatched++; } $this->info(($now ? 'Ran' : 'Queued').' preview generation for '.$dispatched.' document(s).'); return self::SUCCESS; } }