Files
fotospiel-app/app/Http/Controllers/Api/Tenant/LiveShowLinkController.php
Codex Agent 88012c35bd
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled
Add join token TTL policy and Live Show link sharing
2026-01-05 21:11:36 +01:00

136 lines
3.5 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Tenant;
use App\Http\Controllers\Controller;
use App\Models\Event;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use SimpleSoftwareIO\QrCode\Facades\QrCode;
class LiveShowLinkController extends Controller
{
public function show(Request $request, Event $event): JsonResponse
{
$this->authorizeEvent($request, $event);
$token = $event->ensureLiveShowToken();
return response()->json([
'data' => $this->buildPayload($event, $token),
]);
}
public function rotate(Request $request, Event $event): JsonResponse
{
$this->authorizeEvent($request, $event);
$token = $event->rotateLiveShowToken();
return response()->json([
'data' => $this->buildPayload($event, $token),
]);
}
private function authorizeEvent(Request $request, Event $event): void
{
$tenantId = $request->attributes->get('tenant_id');
if ($event->tenant_id !== $tenantId) {
abort(404, 'Event not found');
}
}
private function buildPayload(Event $event, string $token): array
{
$url = $this->buildLiveShowUrl($event, $token);
return [
'token' => $token,
'url' => $url,
'qr_code_data_url' => $this->buildQrCodeDataUrl($url),
'rotated_at' => $event->live_show_token_rotated_at?->toIso8601String(),
];
}
private function buildLiveShowUrl(Event $event, string $token): string
{
$baseUrl = $this->resolveBaseUrl($event);
return rtrim($baseUrl, '/').'/show/'.$token;
}
private function resolveBaseUrl(Event $event): string
{
$settings = is_array($event->settings) ? $event->settings : [];
$customDomain = $settings['custom_domain'] ?? null;
if (is_string($customDomain) && $customDomain !== '') {
return sprintf('%s://%s', $this->resolveScheme(), $customDomain);
}
$publicUrl = $settings['public_url'] ?? null;
if (is_string($publicUrl) && $publicUrl !== '') {
$parsed = parse_url($publicUrl);
$host = is_array($parsed) ? ($parsed['host'] ?? null) : null;
if (is_string($host) && $host !== '') {
$scheme = $parsed['scheme'] ?? $this->resolveScheme();
$port = $parsed['port'] ?? null;
$base = $scheme.'://'.$host;
if ($port) {
$base .= ':'.$port;
}
return $base;
}
}
return (string) config('app.url');
}
private function resolveScheme(): string
{
$appUrl = config('app.url');
if (is_string($appUrl)) {
$scheme = parse_url($appUrl, PHP_URL_SCHEME);
if (is_string($scheme) && $scheme !== '') {
return $scheme;
}
}
return 'https';
}
private function buildQrCodeDataUrl(string $url): ?string
{
if ($url === '') {
return null;
}
try {
$png = QrCode::format('png')
->size(360)
->margin(1)
->errorCorrection('M')
->generate($url);
$pngBinary = (string) $png;
if ($pngBinary === '') {
return null;
}
return 'data:image/png;base64,'.base64_encode($pngBinary);
} catch (\Throwable $exception) {
report($exception);
}
return null;
}
}