die tenant admin oauth authentifizierung wurde implementiert und funktioniert jetzt. Zudem wurde das marketing frontend dashboard implementiert.
This commit is contained in:
@@ -2,101 +2,189 @@
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Str;
|
||||
use App\Models\{Event, Task, Emotion, Photo, PhotoLike, Tenant};
|
||||
use Illuminate\Support\Facades\File;
|
||||
use App\Models\Emotion;
|
||||
use App\Models\Event;
|
||||
use App\Models\Photo;
|
||||
use App\Models\PhotoLike;
|
||||
use App\Models\Task;
|
||||
use App\Models\Tenant;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\File;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DemoPhotosSeeder extends Seeder
|
||||
{
|
||||
public function run(): void
|
||||
{
|
||||
// Get demo event and tenant
|
||||
$demoEvent = Event::where('slug', 'demo-wedding-2025')->first();
|
||||
$demoTenant = Tenant::where('slug', 'demo')->first();
|
||||
|
||||
if (!$demoEvent || !$demoTenant) {
|
||||
$this->command->info('Demo event or tenant not found, skipping DemoPhotosSeeder');
|
||||
$tenant = Tenant::where('slug', 'demo-tenant')->first();
|
||||
|
||||
if (! $tenant) {
|
||||
$this->command->info('Demo tenant not found, skipping DemoPhotosSeeder');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$photoDir = storage_path('app/public/photos');
|
||||
if (! File::exists($photoDir)) {
|
||||
$this->command->info('No demo photos available in storage/app/public/photos');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$photoFiles = collect(File::files($photoDir))
|
||||
->filter(fn ($file) => str_ends_with(strtolower($file->getFilename()), '.jpg'))
|
||||
->values();
|
||||
|
||||
if ($photoFiles->isEmpty()) {
|
||||
$this->command->info('No JPG demo photos found, skipping DemoPhotosSeeder');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Get all available tasks and emotions
|
||||
$tasks = Task::where('tenant_id', $demoTenant->id)->get();
|
||||
$emotions = Emotion::all();
|
||||
if ($emotions->isEmpty()) {
|
||||
$this->command->info('No emotions available, skipping DemoPhotosSeeder');
|
||||
|
||||
if ($tasks->isEmpty() || $emotions->isEmpty()) {
|
||||
$this->command->info('No tasks or emotions found, skipping DemoPhotosSeeder');
|
||||
return;
|
||||
}
|
||||
|
||||
// List of 20 guest names (ASCII only to avoid encoding issues)
|
||||
$guestNames = [
|
||||
'Anna Mueller', 'Max Schmidt', 'Lisa Weber', 'Tom Fischer', 'Sophie Bauer',
|
||||
'Lukas Hoffmann', 'Emma Wagner', 'Jonas Klein', 'Mia Schwarz', 'Felix Becker',
|
||||
'Lena Richter', 'Paul Lehmann', 'Julia Neumann', 'David Vogel', 'Sara Krueger',
|
||||
'Tim Berger', 'Nina Wolf', 'Ben Schaefer', 'Laura Stein', 'Moritz Fuchs'
|
||||
$events = [
|
||||
[
|
||||
'model' => Event::with(['tasks', 'eventPackage', 'eventPackages', 'eventType'])
|
||||
->where('slug', 'demo-wedding-2025')
|
||||
->first(),
|
||||
'guest_names' => [
|
||||
'Anna Mueller', 'Max Schmidt', 'Lisa Weber', 'Tom Fischer', 'Sophie Bauer',
|
||||
'Lukas Hoffmann', 'Emma Wagner', 'Jonas Klein', 'Mia Schwarz', 'Felix Becker',
|
||||
'Lena Richter', 'Paul Lehmann', 'Julia Neumann', 'David Vogel', 'Sara Krueger',
|
||||
'Tim Berger', 'Nina Wolf', 'Ben Schaefer', 'Laura Stein', 'Moritz Fuchs',
|
||||
],
|
||||
'like_range' => [4, 18],
|
||||
],
|
||||
[
|
||||
'model' => Event::with(['tasks', 'eventPackage', 'eventPackages', 'eventType'])
|
||||
->where('slug', 'demo-corporate-2025')
|
||||
->first(),
|
||||
'guest_names' => [
|
||||
'Clara Schmidt', 'Jan Becker', 'Noah Winkler', 'Sina Albrecht', 'Kai Lenz',
|
||||
'Tara Nguyen', 'Omar Hassan', 'Elias Roth', 'Greta Sommer', 'Leonard Busch',
|
||||
'Verena Graf', 'Nico Adler', 'Johanna Kurz', 'Fabian Scholz', 'Mara Kranz',
|
||||
'Yuki Tanaka', 'Mateo Ruiz', 'Amina Korb', 'Philipp Krüger', 'Selma Vogt',
|
||||
],
|
||||
'like_range' => [2, 12],
|
||||
],
|
||||
];
|
||||
|
||||
// Get all photo files from storage
|
||||
$photoDir = storage_path('app/public/photos');
|
||||
$photoFiles = File::files($photoDir);
|
||||
|
||||
$seededCount = 0;
|
||||
foreach ($photoFiles as $file) {
|
||||
$filename = $file->getFilename();
|
||||
if (!str_ends_with($filename, '.jpg')) {
|
||||
foreach ($events as $config) {
|
||||
/** @var Event|null $event */
|
||||
$event = $config['model'];
|
||||
|
||||
if (! $event) {
|
||||
$this->command->warn('Demo event missing, skipping photo seeding.');
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if already seeded (avoid duplicates)
|
||||
if (Photo::where('file_path', 'photos/' . $filename)->exists()) {
|
||||
$taskIds = $event->tasks()->pluck('tasks.id')->all();
|
||||
if ($taskIds === []) {
|
||||
$eventTypeId = $event->event_type_id ?? optional($event->eventType)->id;
|
||||
$taskIds = Task::where('event_type_id', $eventTypeId)->pluck('id')->all();
|
||||
}
|
||||
|
||||
if ($taskIds === []) {
|
||||
$this->command->warn(sprintf('No tasks assigned to %s. Photos will be seeded without task references.', $event->slug));
|
||||
}
|
||||
|
||||
$guestNames = $config['guest_names'];
|
||||
$photosToSeed = min($photoFiles->count(), count($guestNames));
|
||||
|
||||
if ($photosToSeed === 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate thumbnail path
|
||||
$thumbnailFilename = str_replace('.jpg', '_thumb.jpg', $filename);
|
||||
$thumbnailPath = 'thumbnails/' . $thumbnailFilename;
|
||||
$storage = Storage::disk('public');
|
||||
$storage->makeDirectory("events/{$event->id}/gallery");
|
||||
$storage->makeDirectory("events/{$event->id}/gallery/thumbs");
|
||||
|
||||
// Random assignments
|
||||
$randomTask = $tasks->random();
|
||||
$randomEmotion = $emotions->random();
|
||||
$randomGuest = $guestNames[array_rand($guestNames)];
|
||||
$randomLikes = rand(0, 20);
|
||||
$eventDate = $demoEvent->date;
|
||||
$randomUploadedAt = Carbon::parse($eventDate)->addHours(rand(0, 24))->addMinutes(rand(0, 59));
|
||||
$photosSeeded = 0;
|
||||
|
||||
// Create photo
|
||||
$photo = Photo::create([
|
||||
'tenant_id' => $demoTenant->id,
|
||||
'event_id' => $demoEvent->id,
|
||||
'task_id' => $randomTask->id,
|
||||
'emotion_id' => $randomEmotion->id,
|
||||
'guest_name' => $randomGuest,
|
||||
'file_path' => 'photos/' . $filename,
|
||||
'thumbnail_path' => $thumbnailPath,
|
||||
'likes_count' => $randomLikes,
|
||||
'is_featured' => false,
|
||||
'metadata' => [],
|
||||
'created_at' => $randomUploadedAt,
|
||||
'updated_at' => $randomUploadedAt,
|
||||
]);
|
||||
for ($i = 0; $i < $photosToSeed; $i++) {
|
||||
$sourceFile = $photoFiles->get($i % $photoFiles->count());
|
||||
$baseName = pathinfo($sourceFile->getFilename(), PATHINFO_FILENAME);
|
||||
$guestName = $guestNames[$i];
|
||||
$likes = rand($config['like_range'][0], $config['like_range'][1]);
|
||||
$timestamp = Carbon::parse($event->date ?? now())
|
||||
->addHours(rand(0, 36))
|
||||
->addMinutes(rand(0, 59));
|
||||
|
||||
// Add random likes
|
||||
if ($randomLikes > 0) {
|
||||
for ($i = 0; $i < $randomLikes; $i++) {
|
||||
$filename = sprintf('%s-demo-%02d.jpg', $event->slug, $i + 1);
|
||||
$destPath = "events/{$event->id}/gallery/{$filename}";
|
||||
|
||||
if (! $storage->exists($destPath)) {
|
||||
$storage->put($destPath, File::get($sourceFile->getRealPath()));
|
||||
}
|
||||
|
||||
$thumbFilename = sprintf('%s-demo-%02d_thumb.jpg', $event->slug, $i + 1);
|
||||
$thumbDest = "events/{$event->id}/gallery/thumbs/{$thumbFilename}";
|
||||
$existingThumb = "thumbnails/{$baseName}_thumb.jpg";
|
||||
|
||||
if ($storage->exists($existingThumb)) {
|
||||
if (! $storage->exists($thumbDest)) {
|
||||
$storage->copy($existingThumb, $thumbDest);
|
||||
}
|
||||
} else {
|
||||
if (! $storage->exists($thumbDest)) {
|
||||
$storage->put($thumbDest, File::get($sourceFile->getRealPath()));
|
||||
}
|
||||
}
|
||||
|
||||
$taskId = $taskIds ? $taskIds[array_rand($taskIds)] : null;
|
||||
$emotionId = $emotions->random()->id;
|
||||
|
||||
$photo = Photo::updateOrCreate(
|
||||
[
|
||||
'tenant_id' => $tenant->id,
|
||||
'event_id' => $event->id,
|
||||
'file_path' => $destPath,
|
||||
],
|
||||
[
|
||||
'task_id' => $taskId,
|
||||
'emotion_id' => $emotionId,
|
||||
'guest_name' => $guestName,
|
||||
'thumbnail_path' => $thumbDest,
|
||||
'likes_count' => $likes,
|
||||
'is_featured' => $i === 0,
|
||||
'metadata' => ['demo' => true],
|
||||
'created_at' => $timestamp,
|
||||
'updated_at' => $timestamp,
|
||||
]
|
||||
);
|
||||
|
||||
PhotoLike::where('photo_id', $photo->id)->delete();
|
||||
$maxLikes = min($likes, 10);
|
||||
for ($like = 0; $like < $maxLikes; $like++) {
|
||||
PhotoLike::create([
|
||||
'photo_id' => $photo->id,
|
||||
'guest_name' => 'GuestLike_' . Str::random(6),
|
||||
'ip_address' => '10.0.' . rand(0, 254) . '.' . rand(1, 254),
|
||||
'created_at' => $randomUploadedAt->clone()->addMinutes(rand(0, 60)),
|
||||
'guest_name' => 'GuestLike_'.Str::random(6),
|
||||
'ip_address' => '10.0.'.rand(0, 254).'.'.rand(1, 254),
|
||||
'created_at' => $timestamp->copy()->addMinutes($like * 3),
|
||||
]);
|
||||
}
|
||||
|
||||
$photosSeeded++;
|
||||
}
|
||||
|
||||
$seededCount++;
|
||||
}
|
||||
$eventPackage = $event->eventPackage ?? $event->eventPackages()->orderByDesc('purchased_at')->first();
|
||||
if ($eventPackage) {
|
||||
$eventPackage->forceFill([
|
||||
'used_photos' => max($eventPackage->used_photos ?? 0, $photosSeeded),
|
||||
'used_guests' => max($eventPackage->used_guests ?? 0, count(array_unique($guestNames))),
|
||||
])->save();
|
||||
}
|
||||
|
||||
$this->command->info(sprintf('Seeded %d demo photos with random tasks, emotions, uploaders, and likes', $seededCount));
|
||||
$this->command->info(sprintf('Seeded %d demo photos for %s', $photosSeeded, $event->slug));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user