-.png|jpg` (zero padded, e.g. 04-07) * in `storage/app/private/lifeline-images//`. Events that already * have a key image are skipped unless --force is given. */ class ImportLifelineImages extends Command { protected $signature = 'lifelines:import-images {handle : Lifeline handle, e.g. bruno} {--from= : Image directory (default: storage/app/private/lifeline-images/)} {--force : Replace key images that are already attached} {--dry-run : Only report what would be imported}'; protected $description = 'Attach generated key images to seeded lifeline events'; public function handle(EventMediaStore $store): int { $handle = (string) $this->argument('handle'); $dataPath = database_path("data/lifelines/{$handle}.json"); $imageDirectory = (string) ($this->option('from') ?: storage_path("app/private/lifeline-images/{$handle}")); if (! File::exists($dataPath)) { $this->error("No lifeline data found at {$dataPath}."); return self::FAILURE; } $lifeline = json_decode(File::get($dataPath), true, flags: JSON_THROW_ON_ERROR); $user = User::query()->where('email', $lifeline['person']['email'])->first(); if ($user === null) { $this->error("User {$lifeline['person']['email']} is not seeded yet. Run the LifelineSeeder first."); return self::FAILURE; } $imported = $skipped = $missing = 0; foreach ($lifeline['events'] as $data) { $slug = sprintf('%02d-%02d', $data['age'], $data['month']); $imagePath = $this->findImage($imageDirectory, $slug); if ($imagePath === null) { $missing++; continue; } $clientId = LifelineSeeder::clientId($lifeline['person']['email'], $data['age'], $data['month'], $data['day'] ?? null); $event = Event::query()->where('user_id', $user->id)->where('client_id', $clientId)->first(); if ($event === null) { $this->warn("{$slug}: event not seeded, skipping."); $missing++; continue; } if ($event->image !== null && ! $this->option('force')) { $skipped++; continue; } if ($this->option('dry-run')) { $this->line("{$slug}: would import ".basename($imagePath)." → {$event->title}"); $imported++; continue; } $store->store($event, new UploadedFile($imagePath, basename($imagePath), null, null, true), 'key_image'); $this->line("{$slug}: {$event->title}"); $imported++; } $this->info("Imported {$imported}, skipped {$skipped} (already attached), {$missing} without image."); return self::SUCCESS; } private function findImage(string $directory, string $slug): ?string { foreach (['png', 'jpg', 'jpeg'] as $extension) { $path = "{$directory}/{$slug}.{$extension}"; if (File::exists($path)) { return $path; } } return null; } }