82 lines
4.1 KiB
PHP
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);
|
|
}
|