Files
fotospiel-app/database/seeders/DemoEventSeeder.php
Codex Agent 9bab5f6c89
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Use marketing demo flag for demo page
2026-01-21 10:55:21 +01:00

260 lines
8.9 KiB
PHP

<?php
namespace Database\Seeders;
use App\Models\Event;
use App\Models\EventPackage;
use App\Models\EventType;
use App\Models\Package;
use App\Models\PackagePurchase;
use App\Models\Task;
use App\Models\TaskCollection;
use App\Models\Tenant;
use App\Services\EventJoinTokenService;
use Illuminate\Database\Seeder;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Schema;
class DemoEventSeeder extends Seeder
{
public function run(): void
{
$demoTenant = Tenant::where('slug', 'demo-tenant')->first();
if (! $demoTenant) {
return;
}
$weddingType = EventType::where('slug', 'wedding')->first();
$corporateType = EventType::where('slug', 'corporate')->first();
$standardPackage = Package::where('slug', 'standard')->first()
?? Package::where('type', 'endcustomer')->orderBy('price')->first();
$premiumPackage = Package::where('slug', 'premium')->first()
?? Package::where('type', 'endcustomer')->orderByDesc('price')->first();
$events = [
[
'slug' => 'demo-wedding-2025',
'name' => ['de' => 'Demo Hochzeit 2025', 'en' => 'Demo Wedding 2025'],
'description' => ['de' => 'Demo-Event', 'en' => 'Demo event'],
'date' => Carbon::now()->addMonths(3),
'event_type' => $weddingType,
'package' => $standardPackage,
'token_label' => 'Demo QR',
'token_value' => 'W2E3sbt7yclzpkAwNSARHYTVN1sPLBad8hfUjLVHmjkUviPd',
'collection_slugs' => ['wedding-classics-2025'],
'task_slug_prefix' => 'wedding-',
'branding' => [
'primary_color' => '#FF5A5F',
'secondary_color' => '#FFF8F5',
'background_color' => '#FFF8F5',
'font_family' => 'Playfair Display, serif',
],
'marketing_demo' => true,
],
[
'slug' => 'demo-corporate-2025',
'name' => ['de' => 'Demo Firmen-Event 2025', 'en' => 'Demo Corporate Summit 2025'],
'description' => ['de' => 'Launch-Event mit Networking', 'en' => 'Launch event with networking sessions'],
'date' => Carbon::now()->addMonths(2),
'event_type' => $corporateType,
'package' => $premiumPackage,
'token_label' => 'Corporate QR',
'collection_slugs' => ['corporate-classics-2025'],
'task_slug_prefix' => 'corporate-',
'branding' => [
'primary_color' => '#0ea5e9',
'secondary_color' => '#2563eb',
'background_color' => '#0f172a',
'font_family' => 'Inter, sans-serif',
],
],
];
foreach ($events as $config) {
if (! $config['event_type'] || ! $config['package']) {
continue;
}
$event = Event::updateOrCreate(
['slug' => $config['slug']],
[
'tenant_id' => $demoTenant->id,
'name' => $config['name'],
'description' => $config['description'],
'date' => $config['date']->toDateString(),
'event_type_id' => $config['event_type']->id,
'status' => 'published',
'is_active' => true,
'settings' => [
'branding' => $config['branding'],
'marketing_demo' => $config['marketing_demo'] ?? false,
],
'default_locale' => 'de',
]
);
$this->ensureJoinToken($event, $config['token_label'], $config['token_value'] ?? null);
$this->attachEventPackage(
event: $event,
package: $config['package'],
tenant: $demoTenant,
providerId: 'demo-seed-'.$config['slug'],
purchasedAt: Carbon::now()->subDays(7)
);
$this->attachTaskCollections($event, $config['collection_slugs']);
$this->attachEventTasks($event, $config['task_slug_prefix']);
}
}
private function ensureJoinToken(Event $event, string $label, ?string $token = null): void
{
if ($event->joinTokens()->exists()) {
$existingToken = $event->joinTokens()->latest('id')->first();
if ($existingToken) {
$metadata = $existingToken->metadata ?? [];
if (! array_key_exists('demo_read_only', $metadata)) {
$metadata['demo_read_only'] = true;
$existingToken->metadata = $metadata;
$existingToken->save();
}
}
return;
}
$metadata = ['demo_read_only' => true];
if ($token) {
$metadata = array_merge($metadata, ['seeded' => true, 'plain_token' => $token]);
}
$attributes = [
'label' => $label,
'metadata' => $metadata,
];
$tokenModel = app(EventJoinTokenService::class)->createToken($event, $attributes);
if ($token) {
$hash = hash('sha256', $token);
$preview = strlen($token) <= 10 ? $token : substr($token, 0, 6).'…'.substr($token, -4);
$tokenModel->forceFill([
'token' => $hash,
'token_hash' => $hash,
'token_encrypted' => Crypt::encryptString($token),
'token_preview' => $preview,
])->save();
}
}
private function attachEventPackage(Event $event, Package $package, Tenant $tenant, string $providerId, Carbon $purchasedAt): void
{
$eventPackageData = [
'purchased_price' => $package->price,
'purchased_at' => $purchasedAt,
];
if (Schema::hasColumn('event_packages', 'used_photos')) {
$eventPackageData['used_photos'] = 0;
}
if (Schema::hasColumn('event_packages', 'used_guests')) {
$eventPackageData['used_guests'] = 0;
}
if (Schema::hasColumn('event_packages', 'gallery_expires_at')) {
$eventPackageData['gallery_expires_at'] = $purchasedAt->copy()->addDays($package->gallery_days ?? 30);
}
EventPackage::updateOrCreate(
[
'event_id' => $event->id,
'package_id' => $package->id,
],
$eventPackageData
);
PackagePurchase::updateOrCreate(
[
'tenant_id' => $tenant->id,
'package_id' => $package->id,
'provider_id' => $providerId,
],
[
'event_id' => $event->id,
'price' => $package->price,
'type' => $package->type === 'reseller' ? 'reseller_subscription' : 'endcustomer_event',
'purchased_at' => $purchasedAt,
'metadata' => ['demo' => true, 'event_slug' => $event->slug],
'ip_address' => null,
'user_agent' => null,
]
);
}
private function attachTaskCollections(Event $event, array $collectionSlugs): void
{
if ($collectionSlugs === []) {
return;
}
$collections = TaskCollection::whereIn('slug', $collectionSlugs)->get();
$pivot = [];
foreach ($collections as $index => $collection) {
$pivot[$collection->id] = ['sort_order' => ($index + 1) * 10];
}
if ($pivot !== []) {
$event->taskCollections()->syncWithoutDetaching($pivot);
}
}
private function attachEventTasks(Event $event, string $slugPrefix): void
{
$tasks = [];
if ($event->event_type_id) {
$tasks = Task::where('event_type_id', $event->event_type_id)
->orderBy('sort_order')
->limit(25)
->pluck('id')
->all();
}
if ($tasks === [] && $slugPrefix !== '') {
$tasks = Task::where('slug', 'like', $slugPrefix.'%')
->orderBy('sort_order')
->limit(25)
->pluck('id')
->all();
}
if ($tasks === []) {
$tasks = Task::where('tenant_id', $event->tenant_id)
->orderBy('sort_order')
->limit(20)
->pluck('id')
->all();
}
if ($tasks === []) {
return;
}
$tasks = array_slice(array_unique($tasks), 0, 20);
$pivot = [];
foreach ($tasks as $index => $taskId) {
$pivot[$taskId] = ['sort_order' => ($index + 1) * 10];
}
$event->tasks()->syncWithoutDetaching($pivot);
}
}