85 lines
2.9 KiB
PHP
85 lines
2.9 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Models\LegalPage;
|
|
use App\Support\ApiError;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Routing\Controller as BaseController;
|
|
use League\CommonMark\Environment\Environment;
|
|
use League\CommonMark\Extension\Autolink\AutolinkExtension;
|
|
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
|
|
use League\CommonMark\Extension\Strikethrough\StrikethroughExtension;
|
|
use League\CommonMark\Extension\Table\TableExtension;
|
|
use League\CommonMark\Extension\TaskList\TaskListExtension;
|
|
use League\CommonMark\MarkdownConverter;
|
|
use Symfony\Component\HttpFoundation\Response;
|
|
|
|
class LegalController extends BaseController
|
|
{
|
|
protected MarkdownConverter $markdown;
|
|
|
|
public function __construct()
|
|
{
|
|
$environment = new Environment([
|
|
'html_input' => 'strip',
|
|
'allow_unsafe_links' => false,
|
|
]);
|
|
|
|
$environment->addExtension(new CommonMarkCoreExtension());
|
|
$environment->addExtension(new TableExtension());
|
|
$environment->addExtension(new AutolinkExtension());
|
|
$environment->addExtension(new StrikethroughExtension());
|
|
$environment->addExtension(new TaskListExtension());
|
|
|
|
$this->markdown = new MarkdownConverter($environment);
|
|
}
|
|
|
|
public function show(Request $request, string $slug)
|
|
{
|
|
$locale = $request->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 ApiError::response(
|
|
'legal_page_not_found',
|
|
'Legal Page Not Found',
|
|
'The requested legal document does not exist.',
|
|
Response::HTTP_NOT_FOUND,
|
|
['slug' => $resolved]
|
|
);
|
|
}
|
|
|
|
$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,
|
|
'body_html' => $this->convertMarkdownToHtml($body),
|
|
])->header('Cache-Control', 'no-store');
|
|
}
|
|
|
|
protected function convertMarkdownToHtml(string $markdown): string
|
|
{
|
|
return trim((string) $this->markdown->convert($markdown));
|
|
}
|
|
}
|