Direkt zum Seiteninhalt
Schaufensterbummel.online
Firmen - Produkte - Dienstleistungen
aus der Region zwischen Karlsruhe und Pforzheim

Schaufensterbummel.online
Firmen - Produkte - Dienstleistungen
aus der Region zwischen Karlsruhe und Pforzheim

Schaufensterbummel.online
Firmen - Produkte - Dienstleistungen
aus der Region zwischen Karlsruhe und Pforzheim

Die Region
zwischen KA und PF

Menü - zwischen-ka-pf.de öffnen
Menü -schaufensterbummel.online öffnen
Schaufensterbummel.online Firmen · Produkte · Dienstleistungen
Schaufensterbummel.online
Menü überspringen
Schaufensterbummel.online
Schaufensterbummel.online
Schaufensterbummel.online
[ 'label' => 'Freizeitangebote', 'singular' => 'Freizeitangebot', 'main_file' => $dataDir . '/freizeit.json', 'pending_file' => $dataDir . '/freizeit_meldungen.json', 'download_name' => 'freizeit.json', 'prefix' => 'FR', 'default_category' => 'Freizeit & Erlebnis', 'categories' => [ 'See & Baden', 'Museum & Kultur', 'Aussicht & Natur', 'Familie & Tiere', 'Sport & Aktiv', 'Freizeit & Erlebnis', 'Sonstiges' ] ], 'badeseen' => [ 'label' => 'Badeseen & Bäder', 'singular' => 'Badesee / Bad', 'main_file' => $dataDir . '/badeseen.json', 'pending_file' => $dataDir . '/badeseen_meldungen.json', 'download_name' => 'badeseen.json', 'prefix' => 'BAD', 'default_category' => 'See & Baden', 'categories' => [ 'Badesee', 'Freibad', 'Hallenbad', 'Therme', 'Naturbad', 'Strandbad', 'Wasserspielplatz', 'Sonstiges' ] ], 'grillplaetze' => [ 'label' => 'Grillplätze', 'singular' => 'Grillplatz', 'main_file' => $dataDir . '/grillplaetze.json', 'pending_file' => $dataDir . '/grillplaetze_meldungen.json', 'download_name' => 'grillplaetze.json', 'prefix' => 'GRILL', 'default_category' => 'Grillplatz', 'categories' => [ 'Grillplatz', 'Waldgrillplatz', 'Grillhütte', 'Feuerstelle', 'Picknickplatz', 'Familienplatz', 'Sonstiges' ] ] ]; $regionOptions = [ 'Karlsruhe', 'Pforzheim', 'Landkreis Karlsruhe', 'Enzkreis', 'Sonstige angrenzende Region' ]; $areaTypeOptions = [ 'Stadt', 'Landkreis', 'Gemeinde', 'Ortsteil', 'Naturraum', 'Sonstiges' ]; /* ========================= HELFER ========================= */ function esc(string $value): string { return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function ensureDir(string $dir): void { if (!is_dir($dir)) { mkdir($dir, 0755, true); } } function defaultData(): array { return [ 'generated_on' => date('Y-m-d'), 'count' => 0, 'items' => [] ]; } function readJsonFile(string $file, bool $listOnly = false): array { if (!file_exists($file)) { return $listOnly ? [] : defaultData(); } $raw = file_get_contents($file); if ($raw === false || trim($raw) === '') { return $listOnly ? [] : defaultData(); } $json = json_decode($raw, true); if (!is_array($json)) { return $listOnly ? [] : defaultData(); } if ($listOnly) { if (isset($json['items']) && is_array($json['items'])) { return $json['items']; } return array_values($json); } if (!isset($json['items']) || !is_array($json['items'])) { $json = [ 'generated_on' => $json['generated_on'] ?? date('Y-m-d'), 'count' => 0, 'items' => [] ]; } $json['items'] = array_values($json['items']); $json['count'] = count($json['items']); $json['generated_on'] = $json['generated_on'] ?? date('Y-m-d'); return $json; } function writeJsonFile(string $file, array $data): bool { ensureDir(dirname($file)); $data['generated_on'] = date('Y-m-d'); $data['items'] = array_values($data['items'] ?? []); $data['count'] = count($data['items']); $json = json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if ($json === false) { return false; } return file_put_contents($file, $json . PHP_EOL, LOCK_EX) !== false; } function writePendingFile(string $file, array $items): bool { ensureDir(dirname($file)); $items = array_values($items); $json = json_encode($items, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); if ($json === false) { return false; } return file_put_contents($file, $json . PHP_EOL, LOCK_EX) !== false; } function cleanString($value): string { return trim((string)($value ?? '')); } function cleanFloat($value) { $value = str_replace(',', '.', trim((string)($value ?? ''))); if ($value === '') { return ''; } return is_numeric($value) ? (float)$value : ''; } function normalizeItem(array $item): array { return [ 'id' => cleanString($item['id'] ?? ''), 'name' => cleanString($item['name'] ?? ''), 'region' => cleanString($item['region'] ?? ''), 'area_type' => cleanString($item['area_type'] ?? ''), 'municipality' => cleanString($item['municipality'] ?? ''), 'category' => cleanString($item['category'] ?? ''), 'lat' => cleanFloat($item['lat'] ?? ''), 'lon' => cleanFloat($item['lon'] ?? ''), 'url' => cleanString($item['url'] ?? ''), 'short_report' => cleanString($item['short_report'] ?? ''), 'address' => cleanString($item['address'] ?? ''), 'source' => cleanString($item['source'] ?? ''), 'status' => cleanString($item['status'] ?? 'published'), 'created_at' => cleanString($item['created_at'] ?? ''), 'updated_at' => date('c') ]; } function normalizePendingItem(array $item): array { return [ 'id' => cleanString($item['id'] ?? ''), 'name' => cleanString($item['name'] ?? ''), 'region' => cleanString($item['region'] ?? ''), 'area_type' => cleanString($item['area_type'] ?? ''), 'municipality' => cleanString($item['municipality'] ?? ''), 'category' => cleanString($item['category'] ?? ''), 'lat' => cleanFloat($item['lat'] ?? ''), 'lon' => cleanFloat($item['lon'] ?? ''), 'url' => cleanString($item['url'] ?? ''), 'short_report' => cleanString($item['short_report'] ?? ''), 'address' => cleanString($item['address'] ?? ''), 'contact_name' => cleanString($item['contact_name'] ?? ''), 'contact_email' => cleanString($item['contact_email'] ?? ''), 'message' => cleanString($item['message'] ?? ''), 'submitted_at' => cleanString($item['submitted_at'] ?? date('c')), 'status' => cleanString($item['status'] ?? 'neu') ]; } function suggestNextId(array $items, string $prefix): string { $max = 0; foreach ($items as $item) { $id = (string)($item['id'] ?? ''); if (stripos($id, $prefix) === 0 && preg_match('/(\d+)$/', $id, $m)) { $max = max($max, (int)$m[1]); } } return $prefix . str_pad((string)($max + 1), 3, '0', STR_PAD_LEFT); } function jsonResponse(array $payload, int $status = 200): void { http_response_code($status); header('Content-Type: application/json; charset=utf-8'); echo json_encode($payload, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); exit; } function requireLoginAjax(): void { if (empty($_SESSION['freizeit_admin_logged_in'])) { jsonResponse([ 'ok' => false, 'message' => 'Nicht angemeldet.' ], 401); } } function validSection(string $key, array $sections): bool { return isset($sections[$key]); } /* ========================= LOGIN / LOGOUT ========================= */ if (isset($_POST['login_action']) && $_POST['login_action'] === 'login') { $user = cleanString($_POST['username'] ?? ''); $pass = (string)($_POST['password'] ?? ''); if (mb_strtolower($user) === mb_strtolower($adminUser) && $pass === $adminPass) { $_SESSION['freizeit_admin_logged_in'] = true; header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); exit; } $loginError = 'Benutzername oder Passwort ist falsch.'; } if (isset($_GET['logout'])) { session_destroy(); header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); exit; } /* ========================= AJAX API ========================= */ if (isset($_POST['ajax_action'])) { requireLoginAjax(); $action = cleanString($_POST['ajax_action'] ?? ''); $sectionKey = cleanString($_POST['section'] ?? 'freizeit'); if (!validSection($sectionKey, $sections)) { jsonResponse([ 'ok' => false, 'message' => 'Ungültiger Bereich.' ], 400); } $section = $sections[$sectionKey]; if ($action === 'load_section') { $main = readJsonFile($section['main_file'], false); $pending = readJsonFile($section['pending_file'], true); jsonResponse([ 'ok' => true, 'section' => $sectionKey, 'main' => $main, 'pending' => array_values(array_map('normalizePendingItem', $pending)), 'next_id' => suggestNextId($main['items'], $section['prefix']) ]); } if ($action === 'save_main') { $payload = $_POST['payload'] ?? ''; $decoded = json_decode((string)$payload, true); if (!is_array($decoded)) { jsonResponse([ 'ok' => false, 'message' => 'JSON konnte nicht gelesen werden.' ], 400); } $items = $decoded['items'] ?? []; if (!is_array($items)) { $items = []; } $cleanItems = []; foreach ($items as $item) { if (is_array($item)) { $cleanItems[] = normalizeItem($item); } } $data = [ 'generated_on' => date('Y-m-d'), 'count' => count($cleanItems), 'items' => $cleanItems ]; $ok = writeJsonFile($section['main_file'], $data); jsonResponse([ 'ok' => $ok, 'message' => $ok ? 'Bestand wurde gespeichert.' : 'Bestand konnte nicht gespeichert werden.', 'main' => $data ], $ok ? 200 : 500); } if ($action === 'approve_pending') { $pendingIndex = (int)($_POST['pending_index'] ?? -1); $editedRaw = $_POST['edited_item'] ?? ''; $pending = readJsonFile($section['pending_file'], true); $main = readJsonFile($section['main_file'], false); if (!isset($pending[$pendingIndex])) { jsonResponse([ 'ok' => false, 'message' => 'Meldung nicht gefunden.' ], 404); } $edited = json_decode((string)$editedRaw, true); if (!is_array($edited)) { $edited = $pending[$pendingIndex]; } $item = normalizeItem($edited); if ($item['id'] === '') { $item['id'] = suggestNextId($main['items'], $section['prefix']); } if ($item['category'] === '') { $item['category'] = $section['default_category']; } if ($item['area_type'] === '') { $item['area_type'] = 'Freizeitangebot'; } $item['status'] = 'published'; $item['source'] = 'Meldeformular'; $item['created_at'] = date('c'); $item['updated_at'] = date('c'); $main['items'][] = $item; unset($pending[$pendingIndex]); $pending = array_values($pending); $okMain = writeJsonFile($section['main_file'], $main); $okPending = writePendingFile($section['pending_file'], $pending); jsonResponse([ 'ok' => $okMain && $okPending, 'message' => ($okMain && $okPending) ? 'Meldung wurde freigegeben und übernommen.' : 'Beim Speichern ist ein Fehler aufgetreten.', 'main' => readJsonFile($section['main_file'], false), 'pending' => array_values(array_map('normalizePendingItem', $pending)), 'next_id' => suggestNextId(readJsonFile($section['main_file'], false)['items'], $section['prefix']) ], ($okMain && $okPending) ? 200 : 500); } if ($action === 'reject_pending') { $pendingIndex = (int)($_POST['pending_index'] ?? -1); $pending = readJsonFile($section['pending_file'], true); if (!isset($pending[$pendingIndex])) { jsonResponse([ 'ok' => false, 'message' => 'Meldung nicht gefunden.' ], 404); } unset($pending[$pendingIndex]); $pending = array_values($pending); $ok = writePendingFile($section['pending_file'], $pending); jsonResponse([ 'ok' => $ok, 'message' => $ok ? 'Meldung wurde abgelehnt/entfernt.' : 'Meldung konnte nicht entfernt werden.', 'pending' => array_values(array_map('normalizePendingItem', $pending)) ], $ok ? 200 : 500); } if ($action === 'bulk_import_pending') { $pending = readJsonFile($section['pending_file'], true); $main = readJsonFile($section['main_file'], false); $approved = 0; foreach ($pending as $pendingItem) { if (!is_array($pendingItem)) { continue; } $item = normalizeItem($pendingItem); if ($item['name'] === '') { continue; } if ($item['id'] === '') { $item['id'] = suggestNextId($main['items'], $section['prefix']); } if ($item['category'] === '') { $item['category'] = $section['default_category']; } $item['status'] = 'published'; $item['source'] = 'Meldeformular'; $item['created_at'] = date('c'); $item['updated_at'] = date('c'); $main['items'][] = $item; $approved++; } $okMain = writeJsonFile($section['main_file'], $main); $okPending = writePendingFile($section['pending_file'], []); jsonResponse([ 'ok' => $okMain && $okPending, 'message' => $approved . ' Meldungen wurden übernommen.', 'main' => readJsonFile($section['main_file'], false), 'pending' => [] ], ($okMain && $okPending) ? 200 : 500); } jsonResponse([ 'ok' => false, 'message' => 'Unbekannte Aktion.' ], 400); } /* ========================= LOGIN-SEITE ========================= */ $isLoggedIn = !empty($_SESSION['freizeit_admin_logged_in']); ?> Freizeitdaten Verwaltung

Geschützter Bereich

Bitte Benutzername und Passwort eingeben, um die Freizeitdaten-Verwaltung zu öffnen.

Verwaltung für Freizeitangebote, Badeseen & Bäder sowie Grillplätze.

Freizeitdaten verwalten

Zentrale Verwaltung für Freizeitangebote, Badeseen & Bäder sowie Grillplätze. Du kannst bestehende Einträge bearbeiten und neue Meldungen aus dem Formular prüfen, freigeben oder ablehnen.

Bestand verwalten Meldungen freigeben JSON direkt speichern Mehrere Bereiche
Aktiver Bereich
Bestand
0
Meldungen
0
Hinweise
0
Lade Daten …

Eintrag bearbeiten

Noch kein Eintrag gewählt

Wähle links einen Datensatz oder lege einen neuen Eintrag an.
Region
Ort
Kategorie
Koordinaten

Prüfung & Hinweise

Noch keine Prüfung durchgeführt.

JSON-Ausgabe aktueller Bereich

Zurück zum Seiteninhalt
App-Icon
Firmen, Produkte und Dienstleistungen - Digitale Sichtbarkeit für Karlsruhe–Pforzheim Installieren Sie diese Website auf Ihrem Startbildschirm für ein besseres Erlebnis
Tippen Sie auf Installationsschaltfläche auf iOS und dann auf „Zu Ihrem Bildschirm hinzufügen“