PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ] ); $userId = (int) $_SESSION['user_id']; $errors = []; $successMessage = ''; $satelliteSearchResults = []; $minorplanetSearchResults = []; $cometSearchResults = []; $satelliteSearchQuery = trim($_GET['sat_q'] ?? ''); $minorplanetSearchQuery = trim($_GET['mp_q'] ?? ''); $cometSearchQuery = trim($_GET['com_q'] ?? ''); $pageTitle = 'Favoriten - AstroTools'; $headerIntroPre = 'Merkliste'; $headerIntroTitle = 'Favoriten'; $headerIntroSub = 'Satelliten und Kleinplaneten zentral verwalten.'; $htmxTriggers = []; function h(?string $value): string { return htmlspecialchars((string) $value, ENT_QUOTES, 'UTF-8'); } function isHtmxRequest(): bool { return strtolower((string) ($_SERVER['HTTP_HX_REQUEST'] ?? '')) === 'true'; } function renderMessages(string $successMessage, array $errors, bool $oob = false): string { ob_start(); ?>
>

>

Standorte

Es sind noch keine Standorte gespeichert.

Name Breitengrad Laengengrad Hoehe Zeitzone Standard
1): ?>
Letzter Standort
>

Noch keine Suche gestartet.

Suche nach Namen oder NORAD-ID, um passende Satelliten direkt hier einzublenden.

Suchergebnisse

Treffer fuer

Keine passenden Satelliten gefunden.

Probiere einen Namen wie ISS oder eine NORAD-ID wie 25544.

Name NORAD
>

Noch keine Suche gestartet.

Suche nach Nummer oder Bezeichnung, um passende Kleinplaneten direkt hier einzublenden.

Suchergebnisse

Treffer fuer

Keine passenden Kleinplaneten gefunden.

Probiere eine Nummer wie 1 oder eine Bezeichnung wie Ceres.

Bezeichnung Nummer
>

Meine Satelliten

Du hast noch keine Satelliten ausgewaehlt.

Name NORAD Favorit
Favorit bleibt gesetzt
1): ?>
Letzter Satellit
>

Meine Kleinplaneten

Du hast noch keine Kleinplaneten ausgewaehlt.

Bezeichnung Nummer Favorit
Favorit bleibt gesetzt
1): ?>
Letzter Kleinplanet
>

Noch keine Suche gestartet.

Suche nach MPC-Bezeichnung oder Kometenname, um passende Kometen direkt hier einzublenden.

Suchergebnisse

Treffer fuer

Keine passenden Kometen gefunden.

Probiere eine Bezeichnung wie 67P oder einen Namen wie Halley.

Bezeichnung
>

Meine Kometen

Du hast noch keine Kometen ausgewaehlt.

Bezeichnung Typ Favorit
Favorit bleibt gesetzt
1): ?>
Letzter Komet
beginTransaction(); try { $stmtCurrent = $pdo->prepare(" SELECT `is_favorite` FROM `{$tableName}` WHERE `user_id` = :user_id AND `{$idColumn}` = :entity_id LIMIT 1 "); $stmtCurrent->execute([ ':user_id' => $userId, ':entity_id' => $entityId, ]); $current = $stmtCurrent->fetchColumn(); if ($current === false) { $pdo->rollBack(); return false; } $newValue = (int) $current === 1 ? 0 : 1; if ($newValue === 1) { $stmtReset = $pdo->prepare(" UPDATE `{$tableName}` SET `is_favorite` = 0 WHERE `user_id` = :user_id "); $stmtReset->execute([ ':user_id' => $userId, ]); } $stmtSet = $pdo->prepare(" UPDATE `{$tableName}` SET `is_favorite` = :is_favorite WHERE `user_id` = :user_id AND `{$idColumn}` = :entity_id "); $stmtSet->execute([ ':is_favorite' => $newValue, ':user_id' => $userId, ':entity_id' => $entityId, ]); if ($newValue === 0) { $stmtNextFavorite = $pdo->prepare(" SELECT `{$idColumn}` FROM `{$tableName}` WHERE `user_id` = :user_id AND `{$idColumn}` <> :entity_id ORDER BY `created_at` ASC, `{$idColumn}` ASC LIMIT 1 "); $stmtNextFavorite->execute([ ':user_id' => $userId, ':entity_id' => $entityId, ]); $nextEntityId = $stmtNextFavorite->fetchColumn(); if ($nextEntityId !== false) { $stmtPromote = $pdo->prepare(" UPDATE `{$tableName}` SET `is_favorite` = 1 WHERE `user_id` = :user_id AND `{$idColumn}` = :entity_id "); $stmtPromote->execute([ ':user_id' => $userId, ':entity_id' => (int) $nextEntityId, ]); } } $pdo->commit(); return true; } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } throw $e; } } function countUserRows(PDO $pdo, string $tableName, int $userId): int { $stmtCount = $pdo->prepare(" SELECT COUNT(*) FROM `{$tableName}` WHERE `user_id` = :user_id "); $stmtCount->execute([ ':user_id' => $userId, ]); return (int) $stmtCount->fetchColumn(); } function ensureFavoriteIfNeeded(PDO $pdo, string $tableName, string $idColumn, int $userId): void { $stmtFavoriteCount = $pdo->prepare(" SELECT COUNT(*) FROM `{$tableName}` WHERE `user_id` = :user_id AND `is_favorite` = 1 "); $stmtFavoriteCount->execute([ ':user_id' => $userId, ]); $favoriteCount = (int) $stmtFavoriteCount->fetchColumn(); if ($favoriteCount > 0) { return; } $stmtNextFavorite = $pdo->prepare(" SELECT `{$idColumn}` FROM `{$tableName}` WHERE `user_id` = :user_id ORDER BY `created_at` ASC, `{$idColumn}` ASC LIMIT 1 "); $stmtNextFavorite->execute([ ':user_id' => $userId, ]); $nextEntityId = $stmtNextFavorite->fetchColumn(); if ($nextEntityId === false) { return; } $stmtPromote = $pdo->prepare(" UPDATE `{$tableName}` SET `is_favorite` = 1 WHERE `user_id` = :user_id AND `{$idColumn}` = :entity_id "); $stmtPromote->execute([ ':user_id' => $userId, ':entity_id' => (int) $nextEntityId, ]); } function validateLocationForm(array $input, array &$errors): array { $name = trim((string) ($input['name'] ?? '')); $latitude = trim((string) ($input['latitude'] ?? '')); $longitude = trim((string) ($input['longitude'] ?? '')); $elevation = trim((string) ($input['elevation'] ?? '')); $timezone = trim((string) ($input['timezone'] ?? 'Europe/Berlin')); 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.'; } return [ 'name' => $name, 'latitude' => $latitude, 'longitude' => $longitude, 'elevation' => $elevation, 'timezone' => $timezone, ]; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { $action = $_POST['action'] ?? ''; if ($action === 'add_satellite') { $satelliteId = (int) ($_POST['satellite_id'] ?? 0); if ($satelliteId <= 0) { $errors[] = 'Ungültiger Satellit.'; } if (empty($errors)) { $stmtCheck = $pdo->prepare(" SELECT `id` FROM `sat_satellites` WHERE `id` = :id LIMIT 1 "); $stmtCheck->execute([ ':id' => $satelliteId, ]); if (!$stmtCheck->fetch()) { $errors[] = 'Der Satellit wurde nicht gefunden.'; } } if (empty($errors)) { $stmtInsert = $pdo->prepare(" INSERT INTO `app_user_satellites` ( `user_id`, `satellite_id`, `is_favorite`, `created_at` ) VALUES ( :user_id, :satellite_id, 0, NOW() ) ON DUPLICATE KEY UPDATE `satellite_id` = VALUES(`satellite_id`) "); $stmtInsert->execute([ ':user_id' => $userId, ':satellite_id' => $satelliteId, ]); $successMessage = 'Der Satellit wurde hinzugefuegt.'; } } if ($action === 'remove_satellite') { $satelliteId = (int) ($_POST['satellite_id'] ?? 0); if ($satelliteId <= 0) { $errors[] = 'Ungültiger Satellit.'; } if (empty($errors)) { $stmtSatellite = $pdo->prepare(" SELECT `satellite_id`, `is_favorite` FROM `app_user_satellites` WHERE `user_id` = :user_id AND `satellite_id` = :satellite_id LIMIT 1 "); $stmtSatellite->execute([ ':user_id' => $userId, ':satellite_id' => $satelliteId, ]); $satelliteRow = $stmtSatellite->fetch(); if (!$satelliteRow) { $errors[] = 'Der Satellit ist nicht in deiner Liste vorhanden.'; } } if (empty($errors)) { $satelliteCount = countUserRows($pdo, 'app_user_satellites', $userId); if ($satelliteCount <= 1) { $errors[] = 'Der letzte Satellit kann nicht gelöscht werden.'; } } if (empty($errors)) { $pdo->beginTransaction(); try { $stmtDelete = $pdo->prepare(" DELETE FROM `app_user_satellites` WHERE `user_id` = :user_id AND `satellite_id` = :satellite_id "); $stmtDelete->execute([ ':user_id' => $userId, ':satellite_id' => $satelliteId, ]); if ((int) ($satelliteRow['is_favorite'] ?? 0) === 1) { $stmtNextFavorite = $pdo->prepare(" SELECT `satellite_id` FROM `app_user_satellites` WHERE `user_id` = :user_id ORDER BY `created_at` ASC, `satellite_id` ASC LIMIT 1 "); $stmtNextFavorite->execute([ ':user_id' => $userId, ]); $nextSatelliteId = $stmtNextFavorite->fetchColumn(); if ($nextSatelliteId !== false) { $stmtResetFavorites = $pdo->prepare(" UPDATE `app_user_satellites` SET `is_favorite` = 0 WHERE `user_id` = :user_id "); $stmtResetFavorites->execute([ ':user_id' => $userId, ]); $stmtSetFavorite = $pdo->prepare(" UPDATE `app_user_satellites` SET `is_favorite` = 1 WHERE `user_id` = :user_id AND `satellite_id` = :satellite_id "); $stmtSetFavorite->execute([ ':user_id' => $userId, ':satellite_id' => (int) $nextSatelliteId, ]); } } $pdo->commit(); $successMessage = 'Der Satellit wurde entfernt.'; } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $errors[] = 'Der Satellit konnte nicht entfernt werden.'; } } } if ($action === 'toggle_satellite_favorite') { $satelliteId = (int) ($_POST['satellite_id'] ?? 0); if ($satelliteId <= 0) { $errors[] = 'Ungültiger Satellit.'; } if (empty($errors)) { $stmtCurrentSatellite = $pdo->prepare(" SELECT `is_favorite` FROM `app_user_satellites` WHERE `user_id` = :user_id AND `satellite_id` = :satellite_id LIMIT 1 "); $stmtCurrentSatellite->execute([ ':user_id' => $userId, ':satellite_id' => $satelliteId, ]); $currentSatelliteFavorite = $stmtCurrentSatellite->fetchColumn(); if ($currentSatelliteFavorite === false) { $errors[] = 'Der Satellit ist nicht in deiner Liste vorhanden.'; } } if (empty($errors)) { $satelliteCount = countUserRows($pdo, 'app_user_satellites', $userId); if ($satelliteCount <= 1 && (int) $currentSatelliteFavorite === 1) { $errors[] = 'Beim letzten Satelliten kann der Favorit nicht entfernt werden.'; } } if (empty($errors)) { if (!setExclusiveFavorite($pdo, 'app_user_satellites', 'satellite_id', $userId, $satelliteId)) { $errors[] = 'Der Satellit ist nicht in deiner Liste vorhanden.'; } else { $successMessage = 'Der Satelliten-Favorit wurde aktualisiert.'; } } } if ($action === 'add_minorplanet') { $minorplanetId = (int) ($_POST['minorplanet_id'] ?? 0); if ($minorplanetId <= 0) { $errors[] = 'Ungültiger Kleinplanet.'; } if (empty($errors)) { $stmtCheck = $pdo->prepare(" SELECT `id` FROM `minorplanets_mpc` WHERE `id` = :id LIMIT 1 "); $stmtCheck->execute([ ':id' => $minorplanetId, ]); if (!$stmtCheck->fetch()) { $errors[] = 'Der Kleinplanet wurde nicht gefunden.'; } } if (empty($errors)) { $stmtInsert = $pdo->prepare(" INSERT INTO `app_user_minorplanets` ( `user_id`, `minorplanet_id`, `is_favorite`, `created_at` ) VALUES ( :user_id, :minorplanet_id, 0, NOW() ) ON DUPLICATE KEY UPDATE `minorplanet_id` = VALUES(`minorplanet_id`) "); $stmtInsert->execute([ ':user_id' => $userId, ':minorplanet_id' => $minorplanetId, ]); $successMessage = 'Der Kleinplanet wurde hinzugefuegt.'; } } if ($action === 'remove_minorplanet') { $minorplanetId = (int) ($_POST['minorplanet_id'] ?? 0); if ($minorplanetId <= 0) { $errors[] = 'Ungültiger Kleinplanet.'; } if (empty($errors)) { $minorplanetCount = countUserRows($pdo, 'app_user_minorplanets', $userId); if ($minorplanetCount <= 1) { $errors[] = 'Der letzte Kleinplanet kann nicht gelöscht werden.'; } } if (empty($errors)) { $stmtDelete = $pdo->prepare(" DELETE FROM `app_user_minorplanets` WHERE `user_id` = :user_id AND `minorplanet_id` = :minorplanet_id "); $stmtDelete->execute([ ':user_id' => $userId, ':minorplanet_id' => $minorplanetId, ]); $successMessage = 'Der Kleinplanet wurde entfernt.'; } } if ($action === 'toggle_minorplanet_favorite') { $minorplanetId = (int) ($_POST['minorplanet_id'] ?? 0); if ($minorplanetId <= 0) { $errors[] = 'Ungültiger Kleinplanet.'; } if (empty($errors)) { $stmtCurrentMinorplanet = $pdo->prepare(" SELECT `is_favorite` FROM `app_user_minorplanets` WHERE `user_id` = :user_id AND `minorplanet_id` = :minorplanet_id LIMIT 1 "); $stmtCurrentMinorplanet->execute([ ':user_id' => $userId, ':minorplanet_id' => $minorplanetId, ]); $currentMinorplanetFavorite = $stmtCurrentMinorplanet->fetchColumn(); if ($currentMinorplanetFavorite === false) { $errors[] = 'Der Kleinplanet ist nicht in deiner Liste vorhanden.'; } } if (empty($errors)) { $minorplanetCount = countUserRows($pdo, 'app_user_minorplanets', $userId); if ($minorplanetCount <= 1 && (int) $currentMinorplanetFavorite === 1) { $errors[] = 'Beim letzten Kleinplaneten kann der Favorit nicht entfernt werden.'; } } if (empty($errors)) { if (!setExclusiveFavorite($pdo, 'app_user_minorplanets', 'minorplanet_id', $userId, $minorplanetId)) { $errors[] = 'Der Kleinplanet ist nicht in deiner Liste vorhanden.'; } else { $successMessage = 'Der Kleinplaneten-Favorit wurde aktualisiert.'; } } } if ($action === 'add_comet') { $cometId = (int) ($_POST['comet_id'] ?? 0); if ($cometId <= 0) { $errors[] = 'Ungueltiger Komet.'; } if (empty($errors)) { $stmtCheck = $pdo->prepare(" SELECT `id` FROM `comets_mpc` WHERE `id` = :id LIMIT 1 "); $stmtCheck->execute([ ':id' => $cometId, ]); if (!$stmtCheck->fetch()) { $errors[] = 'Der Komet wurde nicht gefunden.'; } } if (empty($errors)) { $stmtInsert = $pdo->prepare(" INSERT INTO `app_user_comets` ( `user_id`, `comet_id`, `is_favorite`, `created_at` ) VALUES ( :user_id, :comet_id, 0, NOW() ) ON DUPLICATE KEY UPDATE `comet_id` = VALUES(`comet_id`) "); $stmtInsert->execute([ ':user_id' => $userId, ':comet_id' => $cometId, ]); $successMessage = 'Der Komet wurde hinzugefuegt.'; } } if ($action === 'remove_comet') { $cometId = (int) ($_POST['comet_id'] ?? 0); if ($cometId <= 0) { $errors[] = 'Ungueltiger Komet.'; } if (empty($errors)) { $cometCount = countUserRows($pdo, 'app_user_comets', $userId); if ($cometCount <= 1) { $errors[] = 'Der letzte Komet kann nicht gelöscht werden.'; } } if (empty($errors)) { $stmtDelete = $pdo->prepare(" DELETE FROM `app_user_comets` WHERE `user_id` = :user_id AND `comet_id` = :comet_id "); $stmtDelete->execute([ ':user_id' => $userId, ':comet_id' => $cometId, ]); $successMessage = 'Der Komet wurde entfernt.'; } } if ($action === 'toggle_comet_favorite') { $cometId = (int) ($_POST['comet_id'] ?? 0); if ($cometId <= 0) { $errors[] = 'Ungueltiger Komet.'; } if (empty($errors)) { $stmtCurrentComet = $pdo->prepare(" SELECT `is_favorite` FROM `app_user_comets` WHERE `user_id` = :user_id AND `comet_id` = :comet_id LIMIT 1 "); $stmtCurrentComet->execute([ ':user_id' => $userId, ':comet_id' => $cometId, ]); $currentCometFavorite = $stmtCurrentComet->fetchColumn(); if ($currentCometFavorite === false) { $errors[] = 'Der Komet ist nicht in deiner Liste vorhanden.'; } } if (empty($errors)) { $cometCount = countUserRows($pdo, 'app_user_comets', $userId); if ($cometCount <= 1 && (int) $currentCometFavorite === 1) { $errors[] = 'Beim letzten Kometen kann der Favorit nicht entfernt werden.'; } } if (empty($errors)) { if (!setExclusiveFavorite($pdo, 'app_user_comets', 'comet_id', $userId, $cometId)) { $errors[] = 'Der Komet ist nicht in deiner Liste vorhanden.'; } else { $successMessage = 'Der Kometen-Favorit wurde aktualisiert.'; } } } 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 Hoehe 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) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $errors[] = 'Der Standort konnte nicht gespeichert werden.'; } } } if ($action === 'update_location') { $locationId = (int) ($_POST['location_id'] ?? 0); $locationForm = validateLocationForm($_POST, $errors); $setDefault = isset($_POST['is_default']) ? 1 : 0; if ($locationId <= 0) { $errors[] = 'Ungültiger Standort.'; } $existingLocation = null; if (empty($errors)) { $stmtLocation = $pdo->prepare(" SELECT `id`, `is_default` FROM `app_user_locations` WHERE `id` = :id AND `user_id` = :user_id LIMIT 1 "); $stmtLocation->execute([ ':id' => $locationId, ':user_id' => $userId, ]); $existingLocation = $stmtLocation->fetch(); if (!$existingLocation) { $errors[] = 'Der Standort wurde nicht gefunden.'; } } if (empty($errors)) { $pdo->beginTransaction(); try { if ($setDefault === 1) { $stmtReset = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 0 WHERE `user_id` = :user_id "); $stmtReset->execute([ ':user_id' => $userId, ]); } $stmtUpdate = $pdo->prepare(" UPDATE `app_user_locations` SET `name` = :name, `latitude` = :latitude, `longitude` = :longitude, `elevation` = :elevation, `timezone` = :timezone, `is_default` = :is_default, `updated_at` = NOW() WHERE `id` = :id AND `user_id` = :user_id "); $stmtUpdate->execute([ ':id' => $locationId, ':user_id' => $userId, ':name' => $locationForm['name'], ':latitude' => (float) $locationForm['latitude'], ':longitude' => (float) $locationForm['longitude'], ':elevation' => $locationForm['elevation'] !== '' ? (float) $locationForm['elevation'] : null, ':timezone' => $locationForm['timezone'], ':is_default' => $setDefault === 1 ? 1 : (int) ($existingLocation['is_default'] ?? 0), ]); $pdo->commit(); $successMessage = 'Der Standort wurde aktualisiert.'; $htmxTriggers['favorites:location-updated'] = true; } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $errors[] = 'Der Standort konnte nicht aktualisiert 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) { if ($pdo->inTransaction()) { $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)) { $stmtLocation = $pdo->prepare(" SELECT `id`, `is_default` FROM `app_user_locations` WHERE `id` = :id AND `user_id` = :user_id LIMIT 1 "); $stmtLocation->execute([ ':id' => $locationId, ':user_id' => $userId, ]); $locationRow = $stmtLocation->fetch(); if (!$locationRow) { $errors[] = 'Der Standort wurde nicht gefunden.'; } } if (empty($errors)) { $locationCount = countUserRows($pdo, 'app_user_locations', $userId); if ($locationCount <= 1) { $errors[] = 'Der letzte Standort kann nicht gelöscht werden.'; } } if (empty($errors)) { $pdo->beginTransaction(); try { $stmtDelete = $pdo->prepare(" DELETE FROM `app_user_locations` WHERE `id` = :id AND `user_id` = :user_id "); $stmtDelete->execute([ ':id' => $locationId, ':user_id' => $userId, ]); if ((int) ($locationRow['is_default'] ?? 0) === 1) { $stmtNextDefault = $pdo->prepare(" SELECT `id` FROM `app_user_locations` WHERE `user_id` = :user_id ORDER BY `name` ASC, `id` ASC LIMIT 1 "); $stmtNextDefault->execute([ ':user_id' => $userId, ]); $nextLocationId = $stmtNextDefault->fetchColumn(); if ($nextLocationId !== false) { $stmtResetDefaults = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 0 WHERE `user_id` = :user_id "); $stmtResetDefaults->execute([ ':user_id' => $userId, ]); $stmtSetDefault = $pdo->prepare(" UPDATE `app_user_locations` SET `is_default` = 1 WHERE `user_id` = :user_id AND `id` = :id "); $stmtSetDefault->execute([ ':user_id' => $userId, ':id' => (int) $nextLocationId, ]); } } $pdo->commit(); $successMessage = 'Der Standort wurde gelöscht.'; } catch (Throwable $e) { if ($pdo->inTransaction()) { $pdo->rollBack(); } $errors[] = 'Der Standort konnte nicht gelöscht werden.'; } } } } if ($_SERVER['REQUEST_METHOD'] === 'POST') { ensureFavoriteIfNeeded($pdo, 'app_user_minorplanets', 'minorplanet_id', $userId); ensureFavoriteIfNeeded($pdo, 'app_user_comets', 'comet_id', $userId); } $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; if ($satelliteSearchQuery !== '') { if (ctype_digit($satelliteSearchQuery)) { $stmtSatelliteSearch = $pdo->prepare(" SELECT s.`id`, s.`norad_cat_id`, s.`object_name`, CASE WHEN aus.`satellite_id` IS NULL THEN 0 ELSE 1 END AS `already_added` FROM `sat_satellites` s LEFT JOIN `app_user_satellites` aus ON aus.`satellite_id` = s.`id` AND aus.`user_id` = :user_id WHERE s.`norad_cat_id` = :norad_cat_id ORDER BY s.`object_name` ASC LIMIT 50 "); $stmtSatelliteSearch->execute([ ':user_id' => $userId, ':norad_cat_id' => (int) $satelliteSearchQuery, ]); } else { $stmtSatelliteSearch = $pdo->prepare(" SELECT s.`id`, s.`norad_cat_id`, s.`object_name`, CASE WHEN aus.`satellite_id` IS NULL THEN 0 ELSE 1 END AS `already_added` FROM `sat_satellites` s LEFT JOIN `app_user_satellites` aus ON aus.`satellite_id` = s.`id` AND aus.`user_id` = :user_id WHERE s.`object_name` LIKE :query ORDER BY s.`object_name` ASC LIMIT 50 "); $stmtSatelliteSearch->execute([ ':user_id' => $userId, ':query' => '%' . $satelliteSearchQuery . '%', ]); } $satelliteSearchResults = $stmtSatelliteSearch->fetchAll(); } if ($minorplanetSearchQuery !== '') { if (ctype_digit($minorplanetSearchQuery)) { $stmtMinorplanetSearch = $pdo->prepare(" SELECT mp.`id`, mp.`mp_number`, mp.`designation_text`, mp.`desig_packed`, CASE WHEN aum.`minorplanet_id` IS NULL THEN 0 ELSE 1 END AS `already_added` FROM `minorplanets_mpc` mp LEFT JOIN `app_user_minorplanets` aum ON aum.`minorplanet_id` = mp.`id` AND aum.`user_id` = :user_id WHERE mp.`mp_number` = :mp_number ORDER BY mp.`mp_number` ASC, mp.`designation_text` ASC LIMIT 50 "); $stmtMinorplanetSearch->execute([ ':user_id' => $userId, ':mp_number' => (int) $minorplanetSearchQuery, ]); } else { $stmtMinorplanetSearch = $pdo->prepare(" SELECT mp.`id`, mp.`mp_number`, mp.`designation_text`, mp.`desig_packed`, CASE WHEN aum.`minorplanet_id` IS NULL THEN 0 ELSE 1 END AS `already_added` FROM `minorplanets_mpc` mp LEFT JOIN `app_user_minorplanets` aum ON aum.`minorplanet_id` = mp.`id` AND aum.`user_id` = :user_id WHERE mp.`designation_text` LIKE :query OR mp.`desig_packed` LIKE :query ORDER BY mp.`mp_number` IS NULL ASC, mp.`mp_number` ASC, mp.`designation_text` ASC LIMIT 50 "); $stmtMinorplanetSearch->execute([ ':user_id' => $userId, ':query' => '%' . $minorplanetSearchQuery . '%', ]); } $minorplanetSearchResults = $stmtMinorplanetSearch->fetchAll(); } if ($cometSearchQuery !== '') { $stmtCometSearch = $pdo->prepare(" SELECT c.`id`, c.`designation_and_name`, c.`designation_packed`, c.`orbit_type`, CASE WHEN auc.`comet_id` IS NULL THEN 0 ELSE 1 END AS `already_added` FROM `comets_mpc` c LEFT JOIN `app_user_comets` auc ON auc.`comet_id` = c.`id` AND auc.`user_id` = :user_id WHERE c.`designation_and_name` LIKE :query OR c.`designation_packed` LIKE :query ORDER BY c.`orbit_type` ASC, c.`designation_and_name` ASC LIMIT 50 "); $stmtCometSearch->execute([ ':user_id' => $userId, ':query' => '%' . $cometSearchQuery . '%', ]); $cometSearchResults = $stmtCometSearch->fetchAll(); } $stmtTrackedSatellites = $pdo->prepare(" SELECT s.`id`, s.`norad_cat_id`, s.`object_name`, aus.`is_favorite`, aus.`created_at` FROM `app_user_satellites` aus INNER JOIN `sat_satellites` s ON s.`id` = aus.`satellite_id` WHERE aus.`user_id` = :user_id ORDER BY aus.`is_favorite` DESC, s.`object_name` ASC "); $stmtTrackedSatellites->execute([ ':user_id' => $userId, ]); $trackedSatellites = $stmtTrackedSatellites->fetchAll(); $stmtTrackedMinorplanets = $pdo->prepare(" SELECT mp.`id`, mp.`mp_number`, mp.`designation_text`, mp.`desig_packed`, aum.`is_favorite`, aum.`created_at` FROM `app_user_minorplanets` aum INNER JOIN `minorplanets_mpc` mp ON mp.`id` = aum.`minorplanet_id` WHERE aum.`user_id` = :user_id ORDER BY aum.`is_favorite` DESC, mp.`mp_number` IS NULL ASC, mp.`mp_number` ASC, mp.`designation_text` ASC "); $stmtTrackedMinorplanets->execute([ ':user_id' => $userId, ]); $trackedMinorplanets = $stmtTrackedMinorplanets->fetchAll(); $stmtTrackedComets = $pdo->prepare(" SELECT c.`id`, c.`designation_and_name`, c.`orbit_type`, auc.`is_favorite`, auc.`created_at` FROM `app_user_comets` auc INNER JOIN `comets_mpc` c ON c.`id` = auc.`comet_id` WHERE auc.`user_id` = :user_id ORDER BY auc.`is_favorite` DESC, c.`orbit_type` ASC, c.`designation_and_name` ASC "); $stmtTrackedComets->execute([ ':user_id' => $userId, ]); $trackedComets = $stmtTrackedComets->fetchAll(); if (isHtmxRequest()) { if ($_SERVER['REQUEST_METHOD'] === 'GET' && array_key_exists('sat_q', $_GET)) { echo renderSatelliteSearchResults($satelliteSearchQuery, $satelliteSearchResults); exit; } if ($_SERVER['REQUEST_METHOD'] === 'GET' && array_key_exists('mp_q', $_GET)) { echo renderMinorplanetSearchResults($minorplanetSearchQuery, $minorplanetSearchResults); exit; } if ($_SERVER['REQUEST_METHOD'] === 'GET' && array_key_exists('com_q', $_GET)) { echo renderCometSearchResults($cometSearchQuery, $cometSearchResults); exit; } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if ($htmxTriggers !== []) { header('HX-Trigger: ' . (string) json_encode($htmxTriggers)); } echo renderMessages($successMessage, $errors); echo renderLocationsSection($locations, true); echo renderSatelliteSearchResults($satelliteSearchQuery, $satelliteSearchResults, true); echo renderMinorplanetSearchResults($minorplanetSearchQuery, $minorplanetSearchResults, true); echo renderCometSearchResults($cometSearchQuery, $cometSearchResults, true); echo renderTrackedSatellitesSection($trackedSatellites, true); echo renderTrackedMinorplanetsSection($trackedMinorplanets, true); echo renderTrackedCometsSection($trackedComets, true); exit; } } $loggedIn = true; ?>

Standorte

Es sind noch keine Standorte gespeichert.

Name Breitengrad Längengrad Hoehe Zeitzone Standard
1): ?>
Letzter Standort

Standort hinzufuegen

Suche einen Ort, nutze den Browser-Standort oder klicke direkt in die Karte.

>Bitte einen Namen für den Standort eingeben.

Standort bearbeiten

Satelliten suchen

Suchergebnisse

Keine passenden Satelliten gefunden.

Name NORAD

Noch keine Suche gestartet.

Suche nach Namen oder NORAD-ID, um passende Satelliten direkt hier einzublenden.

Kleinplaneten suchen

Suchergebnisse

Keine passenden Kleinplaneten gefunden.

Bezeichnung Nummer

Noch keine Suche gestartet.

Suche nach Nummer oder Bezeichnung, um passende Kleinplaneten direkt hier einzublenden.

Kometen suchen

Meine Satelliten

Du hast noch keine Satelliten ausgewählt.

Name NORAD Favorit
Favorit bleibt gesetzt
1): ?>
Letzter Satellit

Meine Kleinplaneten

Du hast noch keine Kleinplaneten ausgewählt.

Bezeichnung Nummer Favorit
Favorit bleibt gesetzt
1): ?>
Letzter Kleinplanet