From 57949c8b5fa80c18032218c256c8ec990abe45cb Mon Sep 17 00:00:00 2001 From: SEB Fotografie - soeren Date: Tue, 9 Sep 2025 21:22:58 +0200 Subject: [PATCH] feat: Add legal pages API and seeding --- app/Http/Controllers/Api/LegalController.php | 45 ++++ .../2025_09_08_120000_seed_legal_pages.php | 203 ++++++++++++++++++ database/seeders/LegalPagesSeeder.php | 185 ++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100644 app/Http/Controllers/Api/LegalController.php create mode 100644 database/migrations/2025_09_08_120000_seed_legal_pages.php create mode 100644 database/seeders/LegalPagesSeeder.php diff --git a/app/Http/Controllers/Api/LegalController.php b/app/Http/Controllers/Api/LegalController.php new file mode 100644 index 0000000..333fa04 --- /dev/null +++ b/app/Http/Controllers/Api/LegalController.php @@ -0,0 +1,45 @@ +query('lang', 'de'); + + // Support common English aliases as fallbacks + $s = strtolower($slug); + $aliasMap = [ + 'imprint' => 'impressum', + 'privacy' => 'datenschutz', + 'terms' => 'agb', + ]; + $resolved = $aliasMap[$s] ?? $s; + + $page = LegalPage::query() + ->where('slug', $resolved) + ->where('is_published', true) + ->orderByDesc('version') + ->first(); + if (! $page) { + return response()->json(['error' => ['code' => 'not_found', 'message' => 'Legal page not found']], 404); + } + + $title = $page->title[$locale] ?? $page->title[$page->locale_fallback] ?? $page->title['de'] ?? $page->title['en'] ?? $page->slug; + $body = $page->body_markdown[$locale] ?? $page->body_markdown[$page->locale_fallback] ?? reset($page->body_markdown); + + return response()->json([ + 'slug' => $page->slug, + 'version' => (int) $page->version, + 'effective_from' => optional($page->effective_from)->toIso8601String(), + 'locale' => $locale, + 'title' => $title, + 'body_markdown' => (string) $body, + ])->header('Cache-Control', 'no-store'); + } +} diff --git a/database/migrations/2025_09_08_120000_seed_legal_pages.php b/database/migrations/2025_09_08_120000_seed_legal_pages.php new file mode 100644 index 0000000..ddbd58b --- /dev/null +++ b/database/migrations/2025_09_08_120000_seed_legal_pages.php @@ -0,0 +1,203 @@ +toDateString(); + + $rows = [ + [ + 'slug' => 'impressum', + 'version' => 1, + 'title' => json_encode(['de' => 'Impressum'], JSON_UNESCAPED_UNICODE), + 'body_markdown' => json_encode(['de' => self::impressumDe()], JSON_UNESCAPED_UNICODE), + 'locale_fallback' => 'de', + 'effective_from' => $now, + 'is_published' => true, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'slug' => 'datenschutz', + 'version' => 1, + 'title' => json_encode(['de' => 'Datenschutzerklärung'], JSON_UNESCAPED_UNICODE), + 'body_markdown' => json_encode(['de' => self::datenschutzDe($now)], JSON_UNESCAPED_UNICODE), + 'locale_fallback' => 'de', + 'effective_from' => $now, + 'is_published' => true, + 'created_at' => now(), + 'updated_at' => now(), + ], + [ + 'slug' => 'agb', + 'version' => 1, + 'title' => json_encode(['de' => 'Allgemeine Geschäftsbedingungen'], JSON_UNESCAPED_UNICODE), + 'body_markdown' => json_encode(['de' => self::agbDe($now)], JSON_UNESCAPED_UNICODE), + 'locale_fallback' => 'de', + 'effective_from' => $now, + 'is_published' => true, + 'created_at' => now(), + 'updated_at' => now(), + ], + ]; + + foreach ($rows as $r) { + DB::table('legal_pages')->updateOrInsert( + ['slug' => $r['slug'], 'version' => $r['version']], + $r + ); + } + } + + public function down(): void + { + if (! Schema::hasTable('legal_pages')) return; + DB::table('legal_pages')->whereIn('slug', ['impressum','datenschutz','agb'])->delete(); + } + + private static function impressumDe(): string + { + return <<upsert('impressum', [ + 'de' => 'Impressum', + ], [ + 'de' => $impressumDe, + ], $now); + + // Datenschutz (DE) — baseline for Fotospiel platform + $datenschutzDe = <<format('Y-m-d')} +MD; + + $this->upsert('datenschutz', [ + 'de' => 'Datenschutzerklärung', + ], [ + 'de' => $datenschutzDe, + ], $now); + + // AGB (DE) — baseline Terms for Fotospiel + $agbDe = <<format('Y-m-d')} +MD; + + $this->upsert('agb', [ + 'de' => 'Allgemeine Geschäftsbedingungen', + ], [ + 'de' => $agbDe, + ], $now); + } + + private function upsert(string $slug, array $titleByLocale, array $bodyByLocale, \DateTimeInterface $effectiveFrom): void + { + $existing = LegalPage::where('slug', $slug)->orderByDesc('version')->first(); + $version = $existing ? ($existing->version + 1) : 1; + LegalPage::updateOrCreate( + ['slug' => $slug, 'version' => $version], + [ + 'title' => $titleByLocale, + 'body_markdown' => $bodyByLocale, + 'locale_fallback' => 'de', + 'version' => $version, + 'effective_from' => $effectiveFrom, + 'is_published' => true, + ] + ); + } +} +