PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); $userId = (int)$_SESSION['user_id']; $errors = []; $successMessage = ''; function h(?string $value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); } function validTimezone(string $timezone): bool { return in_array($timezone, timezone_identifiers_list(), true); } /* |-------------------------------------------------------------------------- | Benutzer laden |-------------------------------------------------------------------------- */ $stmtUser = $pdo->prepare(" SELECT `id`, `username`, `email`, `display_name`, `role`, `is_active` FROM `app_users` WHERE `id` = :id LIMIT 1 "); $stmtUser->execute([':id' => $userId]); $user = $stmtUser->fetch(); if (!$user) { $_SESSION = []; session_destroy(); header('Location: login.php'); exit; } /* |-------------------------------------------------------------------------- | Aktionen verarbeiten |-------------------------------------------------------------------------- */ if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; if ($action === 'update_profile') { $displayName = trim($_POST['display_name'] ?? ''); $email = trim($_POST['email'] ?? ''); if ($email === '' || !filter_var($email, FILTER_VALIDATE_EMAIL)) { $errors[] = 'Bitte eine gültige E-Mail-Adresse eingeben.'; } if ($displayName !== '' && mb_strlen($displayName) > 100) { $errors[] = 'Der Anzeigename darf maximal 100 Zeichen lang sein.'; } if (empty($errors)) { $stmtCheck = $pdo->prepare(" SELECT `id` FROM `app_users` WHERE `email` = :email AND `id` <> :id LIMIT 1 "); $stmtCheck->execute([ ':email' => $email, ':id' => $userId, ]); if ($stmtCheck->fetch()) { $errors[] = 'Die E-Mail-Adresse ist bereits vergeben.'; } } if (empty($errors)) { $stmtUpdate = $pdo->prepare(" UPDATE `app_users` SET `display_name` = :display_name, `email` = :email, `updated_at` = NOW() WHERE `id` = :id "); $stmtUpdate->execute([ ':display_name' => $displayName !== '' ? $displayName : null, ':email' => $email, ':id' => $userId, ]); $_SESSION['display_name'] = $displayName !== '' ? $displayName : null; $successMessage = 'Die Kontodaten wurden gespeichert.'; } } if ($action === 'change_password') { $currentPassword = $_POST['current_password'] ?? ''; $newPassword = $_POST['new_password'] ?? ''; $newPasswordRepeat = $_POST['new_password_repeat'] ?? ''; $stmtPassword = $pdo->prepare(" SELECT `password_hash` FROM `app_users` WHERE `id` = :id LIMIT 1 "); $stmtPassword->execute([':id' => $userId]); $passwordRow = $stmtPassword->fetch(); if (!$passwordRow || !password_verify($currentPassword, $passwordRow['password_hash'])) { $errors[] = 'Das aktuelle Passwort ist nicht korrekt.'; } if ($newPassword === '') { $errors[] = 'Bitte ein neues Passwort eingeben.'; } elseif (strlen($newPassword) < 8) { $errors[] = 'Das neue Passwort muss mindestens 8 Zeichen lang sein.'; } if ($newPassword !== $newPasswordRepeat) { $errors[] = 'Die neuen Passwörter stimmen nicht überein.'; } if (empty($errors)) { $newHash = password_hash($newPassword, PASSWORD_DEFAULT); $stmtUpdatePassword = $pdo->prepare(" UPDATE `app_users` SET `password_hash` = :password_hash, `updated_at` = NOW() WHERE `id` = :id "); $stmtUpdatePassword->execute([ ':password_hash' => $newHash, ':id' => $userId, ]); $successMessage = 'Das Passwort wurde geändert.'; } } if ($action === 'add_location') { $name = trim($_POST['name'] ?? ''); $latitude = trim($_POST['latitude'] ?? ''); $longitude = trim($_POST['longitude'] ?? ''); $elevation = trim($_POST['elevation'] ?? ''); $timezone = trim($_POST['timezone'] ?? 'Europe/Berlin'); $isDefault = isset($_POST['is_default']) ? 1 : 0; if ($name === '') { $errors[] = 'Bitte einen Namen für den Standort eingeben.'; } if ($latitude === '' || !is_numeric($latitude)) { $errors[] = 'Bitte einen gültigen Breitengrad eingeben.'; } else { $lat = (float)$latitude; if ($lat < -90 || $lat > 90) { $errors[] = 'Der Breitengrad muss zwischen -90 und 90 liegen.'; } } if ($longitude === '' || !is_numeric($longitude)) { $errors[] = 'Bitte einen gültigen Längengrad eingeben.'; } else { $lon = (float)$longitude; if ($lon < -180 || $lon > 180) { $errors[] = 'Der Längengrad muss zwischen -180 und 180 liegen.'; } } if ($elevation !== '' && !is_numeric($elevation)) { $errors[] = 'Die Höhe muss numerisch sein.'; } if (!validTimezone($timezone)) { $errors[] = 'Bitte eine gültige IANA-Zeitzone angeben, z. B. Europe/Berlin.'; } if (empty($errors)) { $pdo->beginTransaction(); try { if ($isDefault === 1) { $stmtReset = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 0 WHERE `user_id` = :user_id "); $stmtReset->execute([ ':user_id' => $userId, ]); } $stmtInsertLocation = $pdo->prepare(" INSERT INTO `app_user_locations` ( `user_id`, `name`, `latitude`, `longitude`, `elevation`, `timezone`, `is_default`, `created_at`, `updated_at` ) VALUES ( :user_id, :name, :latitude, :longitude, :elevation, :timezone, :is_default, NOW(), NOW() ) "); $stmtInsertLocation->execute([ ':user_id' => $userId, ':name' => $name, ':latitude' => (float)$latitude, ':longitude' => (float)$longitude, ':elevation' => $elevation !== '' ? (float)$elevation : null, ':timezone' => $timezone, ':is_default' => $isDefault, ]); $pdo->commit(); $successMessage = 'Der Standort wurde gespeichert.'; $_POST = []; } catch (Throwable $e) { $pdo->rollBack(); $errors[] = 'Der Standort konnte nicht gespeichert werden.'; } } } if ($action === 'set_default_location') { $locationId = (int)($_POST['location_id'] ?? 0); if ($locationId <= 0) { $errors[] = 'Ungültiger Standort.'; } if (empty($errors)) { $stmtCheckLocation = $pdo->prepare(" SELECT `id` FROM `app_user_locations` WHERE `id` = :id AND `user_id` = :user_id LIMIT 1 "); $stmtCheckLocation->execute([ ':id' => $locationId, ':user_id' => $userId, ]); if (!$stmtCheckLocation->fetch()) { $errors[] = 'Der Standort wurde nicht gefunden.'; } } if (empty($errors)) { $pdo->beginTransaction(); try { $stmtReset = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 0 WHERE `user_id` = :user_id "); $stmtReset->execute([ ':user_id' => $userId, ]); $stmtSet = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 1 WHERE `id` = :id AND `user_id` = :user_id "); $stmtSet->execute([ ':id' => $locationId, ':user_id' => $userId, ]); $pdo->commit(); $successMessage = 'Der Standard-Standort wurde gesetzt.'; } catch (Throwable $e) { $pdo->rollBack(); $errors[] = 'Der Standard-Standort konnte nicht gesetzt werden.'; } } } if ($action === 'delete_location') { $locationId = (int)($_POST['location_id'] ?? 0); if ($locationId <= 0) { $errors[] = 'Ungültiger Standort.'; } if (empty($errors)) { $stmtDelete = $pdo->prepare(" DELETE FROM `app_user_locations` WHERE `id` = :id AND `user_id` = :user_id "); $stmtDelete->execute([ ':id' => $locationId, ':user_id' => $userId, ]); $successMessage = 'Der Standort wurde gelöscht.'; } } $stmtUser->execute([':id' => $userId]); $user = $stmtUser->fetch(); } /* |-------------------------------------------------------------------------- | Standorte laden |-------------------------------------------------------------------------- */ $stmtLocations = $pdo->prepare(" SELECT `id`, `name`, `latitude`, `longitude`, `elevation`, `timezone`, `is_default` FROM `app_user_locations` WHERE `user_id` = :user_id ORDER BY `is_default` DESC, `name` ASC "); $stmtLocations->execute([ ':user_id' => $userId, ]); $locations = $stmtLocations->fetchAll(); $defaultLocation = null; foreach ($locations as $location) { if ((int)$location['is_default'] === 1) { $defaultLocation = $location; break; } } $mapLat = isset($_POST['latitude']) && is_numeric($_POST['latitude']) ? (float)$_POST['latitude'] : ($defaultLocation ? (float)$defaultLocation['latitude'] : 51.1657); $mapLon = isset($_POST['longitude']) && is_numeric($_POST['longitude']) ? (float)$_POST['longitude'] : ($defaultLocation ? (float)$defaultLocation['longitude'] : 10.4515); $mapZoom = $defaultLocation ? 10 : 6; $loggedIn = true; ?>
= h($successMessage) ?>
| Benutzername | = h($user['username']) ?> |
| Rolle | = h($user['role']) ?> |
Es sind noch keine Standorte gespeichert.
| Name | Breitengrad | Längengrad | Höhe | Zeitzone | Standard | |
|---|---|---|---|---|---|---|
| = h($location['name']) ?> | = h((string)$location['latitude']) ?> | = h((string)$location['longitude']) ?> | = h($location['elevation'] !== null ? (string)$location['elevation'] . ' m' : '—') ?> | = h($location['timezone']) ?> | = (int)$location['is_default'] === 1 ? '★' : '—' ?> |
Suche einen Ort, nutze den Browser-Standort oder klicke direkt in die Karte.