Files
skyview.astronomiemuseum.de/public/ajax/observation_suggestions.php
T
2026-09-15 15:58:51 +02:00

82 lines
4.1 KiB
PHP

<?php
declare(strict_types=1);
session_start();
require_once __DIR__ . '/../auth_helpers.php';
require_once __DIR__ . '/../observation_suggestions_helpers.php';
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
function observationReply(array $data, int $status = 200): never
{
http_response_code($status);
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Allow: POST');
observationReply(['ok' => false, 'error' => 'Bitte die Berechnung über das Formular starten.'], 405);
}
if (!isset($_SESSION['user_id'])) {
observationReply(['ok' => false, 'error' => 'Bitte erneut anmelden.'], 401);
}
$token = $_POST['csrf_token'] ?? null;
if (!is_string($token) || !isset($_SESSION['observation_csrf']) || !hash_equals($_SESSION['observation_csrf'], $token)) {
observationReply(['ok' => false, 'error' => 'Sitzung abgelaufen. Bitte die Seite neu laden.'], 403);
}
try {
$cfg = require __DIR__ . '/../../config/database.php';
$pdo = new PDO(sprintf('mysql:host=%s;dbname=%s;charset=%s', $cfg['host'], $cfg['dbname'], $cfg['charset'] ?? 'utf8mb4'),
$cfg['user'], $cfg['pass'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC]);
$userId = (int) $_SESSION['user_id'];
if (!currentUserIsAdminLike()) {
$permission = $pdo->prepare('SELECT 1 FROM app_user_page_permissions WHERE user_id = ? AND page_key = ? LIMIT 1');
$permission->execute([$userId, 'beobachtungsvorschlaege.php']);
if (!$permission->fetchColumn()) {
observationReply(['ok' => false, 'error' => 'Keine Berechtigung für Beobachtungsvorschläge.'], 403);
}
}
$stmt = $pdo->prepare('SELECT name, latitude, longitude, elevation, timezone FROM app_user_locations
WHERE user_id = ? AND is_default = 1 LIMIT 1');
$stmt->execute([$userId]);
$location = $stmt->fetch();
if (!$location) {
observationReply(['ok' => false, 'error' => 'Bitte zuerst einen Standardstandort in den Favoriten hinterlegen.'], 422);
}
$filters = [];
foreach (['observation_date', 'object_size_min', 'object_size_max', 'object_magnitude', 'object_altitude_min',
'object_altitude_max', 'object_azimuth_start', 'object_azimuth_end', 'sun_altitude_max', 'moon_separation_min',
'include_unknown_magnitude'] as $key) {
$value = $_POST[$key] ?? '';
if (!is_string($value) || strlen($value) > 32) {
observationReply(['ok' => false, 'error' => 'Ungültige Filterangabe.'], 422);
}
$filters[$key] = $value;
}
foreach (['object_types' => ['moon', 'planets', 'open_clusters', 'globular_clusters', 'galaxies', 'nebulae',
'planetary_nebulae', 'double_stars', 'variable_stars', 'comets'], 'night_halves' => ['first', 'second']] as $key => $allowed) {
$values = $_POST[$key] ?? [];
if (!is_array($values) || !$values || count($values) > count($allowed)) {
observationReply(['ok' => false, 'error' => 'Bitte mindestens einen Objekttyp und eine Nachthälfte auswählen.'], 422);
}
foreach ($values as $value) {
if (!is_string($value) || !in_array($value, $allowed, true)) {
observationReply(['ok' => false, 'error' => 'Ungültige Auswahl.'], 422);
}
}
$filters[$key] = array_values(array_unique($values));
}
// No session lock while Python is working; other pages remain usable.
session_write_close();
set_time_limit(120);
$payload = ['filters' => $filters, 'location' => $location, 'objects' => observationCatalog($pdo, $filters['object_types'])];
$result = runObservationSuggestions($payload);
observationReply($result, $result['ok'] ? 200 : 422);
} catch (Throwable $e) {
error_log('Observation suggestions: ' . $e->getMessage());
observationReply(['ok' => false, 'error' => $e instanceof RuntimeException && !($e instanceof PDOException)
? $e->getMessage() : 'Die Beobachtungsvorschläge konnten nicht berechnet werden. Bitte später erneut versuchen.'], 500);
}