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

135 lines
4.6 KiB
PHP

<?php
namespace App\Http\Controllers\Api\Tenant;
use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\ProfileUpdateRequest;
use App\Models\User;
use App\Support\ApiError;
use App\Support\TenantAuth;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
class ProfileController extends Controller
{
public function show(Request $request): JsonResponse
{
try {
$user = TenantAuth::resolveAdminUser($request);
} catch (\Throwable $exception) {
Log::warning('[TenantProfile] Unable to resolve user for profile show', [
'tenant_id' => $request->attributes->get('tenant_id'),
'error' => $exception->getMessage(),
]);
return ApiError::response(
'profile_user_missing',
'Profil nicht verfügbar',
'Für diesen Tenant konnte kein Account gefunden werden.',
Response::HTTP_NOT_FOUND
);
}
return response()->json([
'data' => $this->transformUser($user),
]);
}
public function update(ProfileUpdateRequest $request): JsonResponse
{
try {
$user = TenantAuth::resolveAdminUser($request);
} catch (\Throwable $exception) {
Log::warning('[TenantProfile] Unable to resolve user for profile update', [
'tenant_id' => $request->attributes->get('tenant_id'),
'error' => $exception->getMessage(),
]);
return ApiError::response(
'profile_user_missing',
'Profil nicht verfügbar',
'Für diesen Tenant konnte kein Account gefunden werden.',
Response::HTTP_NOT_FOUND
);
}
$data = $request->validated();
$updates = [];
$emailChanged = false;
if (isset($data['name']) && $data['name'] !== $user->name) {
$updates['name'] = $data['name'];
}
if (array_key_exists('preferred_locale', $data) && $data['preferred_locale'] !== $user->preferred_locale) {
$updates['preferred_locale'] = $data['preferred_locale'] ? Str::lower($data['preferred_locale']) : null;
}
if (isset($data['email']) && Str::lower($data['email']) !== Str::lower((string) $user->email)) {
$updates['email'] = $data['email'];
$updates['email_verified_at'] = null;
$emailChanged = true;
}
if ($request->filled('password')) {
$currentPassword = (string) $request->input('current_password');
if (! $request->filled('current_password') || ! Hash::check($currentPassword, $user->password)) {
return ApiError::response(
'profile.invalid_current_password',
'Aktuelles Passwort ungültig',
'Das aktuelle Passwort stimmt nicht.',
Response::HTTP_UNPROCESSABLE_ENTITY,
[
'errors' => [
'current_password' => ['Das aktuelle Passwort stimmt nicht.'],
],
]
);
}
$updates['password'] = $request->input('password');
}
if ($updates !== []) {
$user->forceFill($updates);
$user->save();
if ($emailChanged) {
try {
$user->sendEmailVerificationNotification();
} catch (\Throwable $exception) {
Log::error('[TenantProfile] Failed to send verification email after profile update', [
'user_id' => $user->getKey(),
'tenant_id' => $request->attributes->get('tenant_id'),
'error' => $exception->getMessage(),
]);
}
}
}
return response()->json([
'message' => 'Profil erfolgreich aktualisiert.',
'data' => $this->transformUser($user->fresh()),
]);
}
/**
* @return array<string, mixed>
*/
private function transformUser(User $user): array
{
return [
'id' => $user->getKey(),
'name' => $user->name,
'email' => $user->email,
'preferred_locale' => $user->preferred_locale,
'email_verified' => $user->email_verified_at !== null,
'email_verified_at' => $user->email_verified_at?->toIso8601String(),
];
}
}