query("SELECT id, nama, jenis, lat, lng, radius FROM rumah_ibadah")->fetchAll(); $best = null; $minDist = PHP_FLOAT_MAX; foreach ($rows as $row) { $dist = haversineDistance($lat, $lng, (float)$row['lat'], (float)$row['lng']); if ($dist <= (float)$row['radius'] && $dist < $minDist) { $minDist = $dist; $best = array_merge($row, ['jarak' => round($dist, 2)]); } } // Jika tidak ada dalam radius, cari yang paling dekat saja if ($best === null && !empty($rows)) { foreach ($rows as $row) { $dist = haversineDistance($lat, $lng, (float)$row['lat'], (float)$row['lng']); if ($dist < $minDist) { $minDist = $dist; $best = array_merge($row, ['jarak' => round($dist, 2), 'di_luar_radius' => true]); } } } return $best; } /** * Sanitize string input */ function sanitize(string $val): string { return trim(htmlspecialchars($val, ENT_QUOTES, 'UTF-8')); } /** * Format radius display */ function formatRadius(int $meter): string { return $meter >= 1000 ? number_format($meter / 1000, 1) . ' km' : $meter . ' m'; } /** * Format tanggal Indonesia */ function formatTanggal(?string $date): string { if (!$date) return '-'; $ts = strtotime($date); $bulan = ['','Jan','Feb','Mar','Apr','Mei','Jun','Jul','Agt','Sep','Okt','Nov','Des']; return date('d', $ts) . ' ' . $bulan[(int)date('n', $ts)] . ' ' . date('Y', $ts); } /** * Handle file upload */ function handleUpload(array $file, string $prefix = 'bukti'): ?string { if ($file['error'] !== UPLOAD_ERR_OK) return null; if ($file['size'] > UPLOAD_MAX_SIZE) return null; $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION)); if (!in_array($ext, UPLOAD_ALLOWED)) return null; if (!is_dir(UPLOAD_DIR)) mkdir(UPLOAD_DIR, 0755, true); $filename = $prefix . '_' . date('Ymd_His') . '_' . uniqid() . '.' . $ext; $dest = UPLOAD_DIR . $filename; if (move_uploaded_file($file['tmp_name'], $dest)) return $filename; return null; } /** * Emoji dan label untuk jenis ibadah */ function ibadahEmoji(string $jenis): string { $map = [ 'Masjid' => '🕌', 'Musholla' => '🕌', 'Gereja' => 'â›Ē', 'Katolik' => 'â›Ē', 'Pura' => '🛕', 'Vihara' => '🛕', 'Klenteng' => 'â›Šī¸', 'Lainnya' => '🙏', ]; return $map[$jenis] ?? 'đŸ›ī¸'; } /** * Color untuk marker berdasarkan status */ function statusColor(string $status): string { return match($status) { 'sudah' => '#22c55e', 'menunggu' => '#f59e0b', default => '#ef4444', }; }