first(); if (! $tenant) { $this->command?->warn('Demo tenant missing – skipping DemoAchievementsSeeder'); return; } $sourceFiles = collect(Storage::disk('public')->files('photos')) ->filter(fn ($path) => Str::endsWith(Str::lower($path), '.jpg')) ->values(); if ($sourceFiles->isEmpty()) { $this->command?->warn('No demo photo files found – skipping DemoAchievementsSeeder'); return; } $emotions = Emotion::pluck('id')->all(); if ($emotions === []) { $this->command?->warn('No emotions available – skipping DemoAchievementsSeeder'); return; } $scenarios = [ [ 'event' => Event::with(['tasks', 'eventType']) ->where('slug', 'demo-wedding-2025') ->first(), 'blueprints' => [ ['guest' => 'Anna Mueller', 'photos' => 6, 'likes' => [12, 8, 5, 4, 2, 1], 'withTasks' => true], ['guest' => 'Max Schmidt', 'photos' => 4, 'likes' => [9, 7, 4, 2], 'withTasks' => true], ['guest' => 'Lisa Weber', 'photos' => 2, 'likes' => [3, 1], 'withTasks' => false], ['guest' => 'Tom Fischer', 'photos' => 1, 'likes' => [14], 'withTasks' => true], ['guest' => 'Team Brautparty', 'photos' => 5, 'likes' => [5, 4, 3, 3, 2], 'withTasks' => true], ], ], [ 'event' => Event::with(['tasks', 'eventType']) ->where('slug', 'demo-corporate-2025') ->first(), 'blueprints' => [ ['guest' => 'HR Dream Team', 'photos' => 4, 'likes' => [8, 6, 4, 3], 'withTasks' => true], ['guest' => 'Innovation Squad', 'photos' => 5, 'likes' => [10, 7, 5, 4, 2], 'withTasks' => true], ['guest' => 'Finance Crew', 'photos' => 3, 'likes' => [6, 5, 2], 'withTasks' => false], ['guest' => 'New Joiners', 'photos' => 4, 'likes' => [5, 4, 3, 2], 'withTasks' => true], ], ], ]; foreach ($scenarios as $scenario) { /** @var Event|null $event */ $event = $scenario['event']; if (! $event) { $this->command?->warn('Demo event missing – skipping achievements for one scenario.'); continue; } $taskIds = $event->tasks()->pluck('tasks.id')->all(); if ($taskIds === []) { $taskIds = Task::where('event_type_id', $event->event_type_id ?? optional($event->eventType)->id) ->pluck('id') ->all(); } if ($taskIds === []) { $this->command?->warn(sprintf('No tasks available for %s – achievements will use taskless entries.', $event->slug)); } $eventDate = $event->date ? CarbonImmutable::parse($event->date) : CarbonImmutable::now(); $baseDir = "events/{$event->id}/achievements"; Storage::disk('public')->makeDirectory($baseDir); Storage::disk('public')->makeDirectory("{$baseDir}/thumbs"); $photoIndex = 0; foreach ($scenario['blueprints'] as $groupIndex => $blueprint) { for ($i = 0; $i < $blueprint['photos']; $i++) { $sourcePath = $sourceFiles[$photoIndex % $sourceFiles->count()]; $photoIndex++; $filename = Str::slug($blueprint['guest'].'-'.$groupIndex.'-'.$i).'.jpg'; $destPath = "{$baseDir}/{$filename}"; if (! Storage::disk('public')->exists($destPath)) { Storage::disk('public')->copy($sourcePath, $destPath); } $thumbSource = str_replace('photos/', 'thumbnails/', $sourcePath); $thumbDest = "{$baseDir}/thumbs/{$filename}"; if (Storage::disk('public')->exists($thumbSource)) { Storage::disk('public')->copy($thumbSource, $thumbDest); } else { Storage::disk('public')->copy($sourcePath, $thumbDest); } $taskId = null; if (! empty($taskIds) && ($blueprint['withTasks'] ?? false)) { $taskId = $taskIds[($groupIndex + $i) % count($taskIds)]; } $emotionId = $emotions[($groupIndex * 3 + $i) % count($emotions)]; $createdAt = $eventDate->addHours($groupIndex * 2 + $i); $likes = $blueprint['likes'][$i] ?? 0; $photo = Photo::updateOrCreate( [ 'tenant_id' => $tenant->id, 'event_id' => $event->id, 'guest_name' => $blueprint['guest'], 'file_path' => $destPath, ], [ 'task_id' => $taskId, 'emotion_id' => $emotionId, 'thumbnail_path' => $thumbDest, 'likes_count' => $likes, 'is_featured' => $i === 0, 'metadata' => ['demo' => true, 'achievement' => true], 'created_at' => $createdAt, 'updated_at' => $createdAt, ] ); PhotoLike::where('photo_id', $photo->id)->delete(); for ($like = 0; $like < min($likes, 15); $like++) { PhotoLike::create([ 'photo_id' => $photo->id, 'guest_name' => 'Guest_'.Str::random(6), 'ip_address' => '10.0.'.rand(0, 254).'.'.rand(0, 254), 'created_at' => $createdAt->addMinutes($like * 3), ]); } } } $this->command?->info(sprintf('Demo achievements seeded for %s.', $event->slug)); } } }