This commit is contained in:
2025-12-30 03:06:37 +01:00
parent 119a0bb4d8
commit 3110b48c33

View File

@@ -1,222 +1,8 @@
<?php <?php
if (!isset($_SESSION['user_id'])) {
redirect('/login');
}
$app = app(); $app = app();
$pdo = $app->pdo(); $vm = \App\AccountPages::dashboard($app);
$flash = $app->flash()->get(); extract($vm, EXTR_OVERWRITE);
$userId = (int)$_SESSION['user_id']; $editing = isset($editEvent) && $editEvent !== null;
$error = '';
$info = '';
$crypto = null;
try { $crypto = new \App\Crypto($app->config()); } catch (\Throwable) {}
function geocode_address(?string $street, ?string $zip, ?string $city, ?string $region): array
{
$parts = array_filter([
$street ?: null,
$zip ?: null,
$city ?: null,
$region ?: null,
]);
if (!$parts) {
return [null, null];
}
$query = implode(', ', $parts);
$url = 'https://nominatim.openstreetmap.org/search?' . http_build_query([
'format' => 'jsonv2',
'limit' => 1,
'q' => $query,
]);
$ctx = stream_context_create([
'http' => [
'method' => 'GET',
'header' => "User-Agent: papa-kind-treff/1.0\r\nAccept-Language: de\r\n",
'timeout' => 6,
],
]);
$resp = @file_get_contents($url, false, $ctx);
if ($resp === false) {
return [null, null];
}
$json = json_decode($resp, true);
if (!is_array($json) || empty($json[0]['lat']) || empty($json[0]['lon'])) {
return [null, null];
}
return [round((float)$json[0]['lat'], 7), round((float)$json[0]['lon'], 7)];
}
// POST Aktionen
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$action = $_POST['action'] ?? '';
try {
if ($action === 'profile') {
$languages = $_POST['languages'] ?? '';
if (is_array($languages)) {
$languages = implode(', ', array_map('trim', $languages));
}
$phoneEnc = $crypto ? $crypto->encrypt(trim((string)$_POST['contact_phone'])) : trim((string)$_POST['contact_phone']);
$stmt = $pdo->prepare('UPDATE user_profiles SET display_name=:name, first_name=:fname, last_name=:lname, zip=:zip, city=:city, profession=:prof, languages=:langs, about=:about, contact_phone=:phone, updated_at=NOW() WHERE user_id=:id');
$stmt->execute([
'name' => trim((string)$_POST['display_name']),
'fname' => trim((string)$_POST['first_name']),
'lname' => trim((string)$_POST['last_name']),
'zip' => trim((string)$_POST['zip']),
'city' => trim((string)$_POST['city']),
'prof' => trim((string)$_POST['profession']),
'langs' => trim((string)$languages),
'about' => trim((string)$_POST['about']),
'phone' => $phoneEnc,
'id' => $userId,
]);
$info = 'Profil gespeichert.';
} elseif ($action === 'child_add') {
$firstNameEnc = $crypto ? $crypto->encrypt(trim((string)$_POST['first_name'])) : trim((string)$_POST['first_name']);
$noteEnc = $crypto ? $crypto->encrypt(trim((string)$_POST['note'])) : trim((string)$_POST['note']);
$stmt = $pdo->prepare('INSERT INTO children (user_id, gender, birthdate, age_years, encrypted_first_name, note, created_at, updated_at) VALUES (:uid, :gender, :birthdate, :age, :name, :note, NOW(), NOW())');
$stmt->execute([
'uid' => $userId,
'gender' => $_POST['gender'] ?? 'unknown',
'birthdate' => $_POST['birthdate'] ?: null,
'age' => $_POST['age_years'] ?: null,
'name' => $firstNameEnc,
'note' => $noteEnc,
]);
$info = 'Kind hinzugefügt.';
} elseif ($action === 'event_add') {
$street = trim((string)($_POST['street'] ?? ''));
$zip = trim((string)($_POST['zip'] ?? ''));
$city = trim((string)($_POST['city'] ?? ''));
$region = trim((string)($_POST['region'] ?? ''));
$lat = isset($_POST['lat']) && $_POST['lat'] !== '' ? (float)$_POST['lat'] : null;
$lng = isset($_POST['lng']) && $_POST['lng'] !== '' ? (float)$_POST['lng'] : null;
if ($lat === 0.0 && $lng === 0.0 && ($_POST['lat'] === '0' || $_POST['lng'] === '0')) {
// keep zero if explicitly set (unlikely)
} elseif ($lat === null || $lng === null) {
[$lat, $lng] = geocode_address($street, $zip, $city, $region);
}
$stmt = $pdo->prepare('INSERT INTO events (created_by, title, teaser_public, description, location_label, street, zip, city, region, lat, lng, starts_at, allow_kids, visibility, status, created_at, updated_at) VALUES (:uid, :title, :teaser, :descr, :loc, :street, :zip, :city, :region, :lat, :lng, :start, :allow, :vis, :status, NOW(), NOW())');
$stmt->execute([
'uid' => $userId,
'title' => trim((string)$_POST['title']),
'teaser' => trim((string)$_POST['teaser']),
'descr' => trim((string)$_POST['description']),
'loc' => trim((string)$_POST['location_label']),
'street' => $street ?: null,
'zip' => $zip,
'city' => $city,
'region' => $region,
'lat' => $lat,
'lng' => $lng,
'start' => $_POST['starts_at'] ?? null,
'allow' => isset($_POST['allow_kids']) ? 0 : 1, // checkbox = Treffen ohne Kinder
'vis' => $_POST['visibility'] ?? 'public',
'status' => 'published',
]);
$info = 'Event gespeichert.';
} elseif ($action === 'event_delete') {
$eventId = (int)($_POST['event_id'] ?? 0);
$stmt = $pdo->prepare('SELECT id, created_by, status, (SELECT COUNT(*) FROM event_participants ep WHERE ep.event_id = events.id) AS participant_count FROM events WHERE id = :id LIMIT 1');
$stmt->execute(['id' => $eventId]);
$ev = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$ev || (int)$ev['created_by'] !== $userId) {
throw new RuntimeException('Event nicht gefunden.');
}
if ((int)$ev['participant_count'] > 0) {
throw new RuntimeException('Event hat Anmeldungen und kann nicht gelöscht werden.');
}
$pdo->prepare('DELETE FROM events WHERE id = :id')->execute(['id' => $eventId]);
$info = 'Event gelöscht.';
} elseif ($action === 'event_cancel') {
$eventId = (int)($_POST['event_id'] ?? 0);
$stmt = $pdo->prepare('SELECT id, created_by FROM events WHERE id = :id LIMIT 1');
$stmt->execute(['id' => $eventId]);
$ev = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$ev || (int)$ev['created_by'] !== $userId) {
throw new RuntimeException('Event nicht gefunden.');
}
$pdo->prepare('UPDATE events SET status = :st, updated_at = NOW() WHERE id = :id')->execute([
'st' => 'cancelled',
'id' => $eventId,
]);
$info = 'Event wurde abgesagt.';
}
} catch (Throwable $e) {
$error = $e->getMessage();
}
}
// Daten laden
$profile = [
'display_name' => '',
'first_name' => '',
'last_name' => '',
'zip' => '',
'city' => '',
'profession' => '',
'languages' => '',
'about' => '',
'email' => '',
'contact_phone' => '',
];
$stmt = $pdo->prepare('SELECT u.email, u.status, p.display_name, p.first_name, p.last_name, p.zip, p.city, p.profession, p.languages, p.about, p.contact_phone FROM users u LEFT JOIN user_profiles p ON p.user_id = u.id WHERE u.id = :id LIMIT 1');
$stmt->execute(['id' => $userId]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row) {
$profile = array_merge($profile, array_filter($row, fn($v) => $v !== null));
if ($crypto && !empty($profile['contact_phone'])) {
$profile['contact_phone'] = $crypto->decrypt((string)$profile['contact_phone']) ?: '';
}
}
$children = [];
$stmt = $pdo->prepare('SELECT id, encrypted_first_name AS first_name, note, gender, birthdate, age_years FROM children WHERE user_id = :id ORDER BY id DESC');
$stmt->execute(['id' => $userId]);
$childrenRaw = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
foreach ($childrenRaw as $c) {
if ($crypto) {
$c['first_name'] = $crypto->decrypt((string)$c['first_name']) ?: '';
$c['note'] = $crypto->decrypt((string)($c['note'] ?? '')) ?: '';
}
$children[] = $c;
}
$eventsUpcoming = [];
$eventsPast = [];
$editEvent = null;
$stmt = $pdo->prepare(
'SELECT e.id, e.title, e.teaser_public, e.description, e.location_label, e.street, e.zip, e.city, e.region, e.starts_at, e.allow_kids, e.visibility, e.status, e.lat, e.lng,
(SELECT COUNT(*) FROM event_participants ep WHERE ep.event_id = e.id) AS participant_count
FROM events e
WHERE e.created_by = :id AND e.starts_at >= NOW()
ORDER BY e.starts_at ASC'
);
$stmt->execute(['id' => $userId]);
$eventsUpcoming = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
$stmt = $pdo->prepare(
'SELECT e.id, e.title, e.teaser_public, e.starts_at, e.city, e.visibility, e.status,
(SELECT COUNT(*) FROM event_participants ep WHERE ep.event_id = e.id) AS participant_count
FROM events e
WHERE e.created_by = :id AND e.starts_at < NOW()
ORDER BY e.starts_at DESC'
);
$stmt->execute(['id' => $userId]);
$eventsPast = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];
if (isset($_GET['edit_event'])) {
$editId = (int)$_GET['edit_event'];
$stmt = $pdo->prepare('SELECT * FROM events WHERE id = :id AND created_by = :uid AND starts_at >= NOW() LIMIT 1');
$stmt->execute(['id' => $editId, 'uid' => $userId]);
$editEvent = $stmt->fetch(PDO::FETCH_ASSOC) ?: null;
}
?>
<?php
$actionEvent = $editing ? 'event_update' : 'event_add'; $actionEvent = $editing ? 'event_update' : 'event_add';
$startVal = $editEvent ? date('Y-m-d\TH:i', strtotime((string)$editEvent['starts_at'])) : ''; $startVal = $editEvent ? date('Y-m-d\TH:i', strtotime((string)$editEvent['starts_at'])) : '';
$allowNoKidsChecked = $editEvent ? ((int)$editEvent['allow_kids'] === 0) : false; $allowNoKidsChecked = $editEvent ? ((int)$editEvent['allow_kids'] === 0) : false;