pdo(); $flash = $app->flash()->get(); $userId = (int)$_SESSION['user_id']; $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']) ? 1 : 0, 'vis' => $_POST['visibility'] ?? 'public', 'status' => 'published', ]); $info = 'Event gespeichert.'; } } 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; } $events = []; $stmt = $pdo->prepare('SELECT id, title, teaser_public, starts_at, city, visibility FROM events WHERE created_by = :id ORDER BY starts_at DESC'); $stmt->execute(['id' => $userId]); $events = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: []; ?>

Mitgliederbereich

Hallo, !

Verwalte dein Profil, Kinder, Events und Teilnahmen.

Fehler:
Profil

Deine Angaben

  • Name:
  • Anzeigename:
  • Ort:
  • E-Mail:
  • Telefon:
  • Beruf:
  • Sprachen:
  • About:
Kinder

Deine Kids

Noch keine Kinder eingetragen.

  • ,
Deine Events

Noch keine Events angelegt.

  • , ()
Eigenes Event

Neuen Termin erstellen