Files
fotospiel-app/app/Http/Controllers/Api/Tenant/SettingsController.php

213 lines
6.3 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Tenant;
use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\NotificationPreferencesRequest;
use App\Http\Requests\Tenant\SettingsStoreRequest;
use App\Models\Tenant;
use App\Services\Packages\TenantNotificationPreferences;
use App\Support\ApiError;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class SettingsController extends Controller
{
/**
* Get the tenant's settings.
*/
public function index(Request $request): JsonResponse
{
$tenant = $this->resolveTenant($request);
return response()->json([
'message' => 'Settings erfolgreich abgerufen.',
'data' => [
'id' => $tenant->id,
'settings' => $tenant->settings ?? [],
'updated_at' => $tenant->settings_updated_at?->toISOString(),
],
]);
}
public function notificationPreferences(
Request $request,
TenantNotificationPreferences $preferencesService
): JsonResponse {
$tenant = $this->resolveTenant($request);
$defaults = TenantNotificationPreferences::defaults();
$resolved = [];
foreach (array_keys($defaults) as $key) {
$resolved[$key] = $preferencesService->shouldNotify($tenant, $key);
}
return response()->json([
'data' => [
'defaults' => $defaults,
'preferences' => $resolved,
'overrides' => $tenant->notification_preferences ?? null,
],
]);
}
public function updateNotificationPreferences(
NotificationPreferencesRequest $request,
TenantNotificationPreferences $preferencesService
): JsonResponse {
$tenant = $this->resolveTenant($request);
$payload = $request->validated()['preferences'];
$tenant->update([
'notification_preferences' => $payload,
]);
$tenant->refresh();
$resolved = [];
foreach (array_keys(TenantNotificationPreferences::defaults()) as $key) {
$resolved[$key] = $preferencesService->shouldNotify($tenant->fresh(), $key);
}
return response()->json([
'message' => 'Benachrichtigungseinstellungen aktualisiert.',
'data' => [
'preferences' => $resolved,
'overrides' => $tenant->notification_preferences,
],
]);
}
/**
* Update the tenant's settings.
*/
public function update(SettingsStoreRequest $request): JsonResponse
{
$tenant = $this->resolveTenant($request);
$settings = $request->validated()['settings'];
$tenant->update([
'settings' => $settings,
'settings_updated_at' => now(),
]);
return response()->json([
'message' => 'Settings erfolgreich aktualisiert.',
'data' => [
'id' => $tenant->id,
'settings' => $settings,
'updated_at' => now()->toISOString(),
],
]);
}
/**
* Reset tenant settings to defaults.
*/
public function reset(Request $request): JsonResponse
{
$tenant = $this->resolveTenant($request);
$defaultSettings = [
'branding' => [
'logo_url' => null,
'primary_color' => '#3B82F6',
'secondary_color' => '#1F2937',
'font_family' => 'Inter, sans-serif',
],
'features' => [
'photo_likes_enabled' => true,
'event_checklist' => true,
'custom_domain' => false,
'advanced_analytics' => false,
],
'custom_domain' => null,
'contact_email' => $tenant->contact_email,
'event_default_type' => 'general',
];
$tenant->update([
'settings' => $defaultSettings,
'settings_updated_at' => now(),
]);
return response()->json([
'message' => 'Settings auf Standardwerte zurueckgesetzt.',
'data' => [
'id' => $tenant->id,
'settings' => $defaultSettings,
'updated_at' => now()->toISOString(),
],
]);
}
private function resolveTenant(Request $request): Tenant
{
$tenant = $request->attributes->get('tenant');
if ($tenant instanceof Tenant) {
return $tenant;
}
$tenantId = $request->attributes->get('tenant_id')
?? $request->attributes->get('current_tenant_id')
?? $request->user()?->tenant_id;
if ($tenantId) {
$tenant = Tenant::query()->find($tenantId);
if ($tenant) {
$request->attributes->set('tenant', $tenant);
return $tenant;
}
}
throw new HttpResponseException(ApiError::response(
'tenant_context_missing',
'Tenant context missing',
'Unable to determine tenant for the current request.',
Response::HTTP_UNAUTHORIZED
));
}
/**
* Validate custom domain availability.
*/
public function validateDomain(Request $request): JsonResponse
{
$domain = $request->input('domain');
if (! $domain) {
return ApiError::response(
'domain_missing',
'Domain erforderlich',
'Bitte gib eine Domain an.',
Response::HTTP_BAD_REQUEST
);
}
if (! $this->isValidDomain($domain)) {
return response()->json([
'available' => false,
'message' => 'Ungueltiges Domain-Format.',
]);
}
$taken = Tenant::where('custom_domain', $domain)
->where('id', '!=', $this->resolveTenant($request)->id)
->exists();
return response()->json([
'available' => ! $taken,
'message' => $taken ? 'Domain ist bereits vergeben.' : 'Domain ist verfuegbar.',
]);
}
private function isValidDomain(string $domain): bool
{
return filter_var($domain, FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) !== false;
}
}