real_escape_string($_GET['search']) : ''; $query = "SELECT * FROM masjid"; if (!empty($search)) { $query .= " WHERE nama LIKE '%$search%' OR alamat LIKE '%$search%'"; } $query .= " ORDER BY created_at DESC"; $result = $conn->query($query); $data = []; while ($row = $result->fetch_assoc()) { $data[] = $row; } sendResponse(true, 'Data Masjid berhasil diambil', $data); } // ACTION: TAMBAH MASJID (HANYA ADMIN) elseif ($method === 'POST' && $action === 'create') { if ($userRole !== 'admin') { sendResponse(false, 'Akses ditolak! Hanya Admin yang dapat menambah marker masjid baru.'); } $input = json_decode(file_get_contents('php://input'), true); $stmt = $conn->prepare("INSERT INTO masjid (nama, alamat, latitude, longitude, radius, nama_pimpinan, no_hp) VALUES (?, ?, ?, ?, ?, ?, ?)"); $stmt->bind_param("ssddiss", $input['nama'], $input['alamat'], $input['latitude'], $input['longitude'], $input['radius'], $input['nama_pimpinan'], $input['no_hp']); if ($stmt->execute()) { sendResponse(true, 'Masjid berhasil ditambahkan', ['id' => $conn->insert_id]); } else { sendResponse(false, 'Gagal menambahkan masjid: ' . $stmt->error); } $stmt->close(); } // ACTION: UPDATE MASJID (ADMIN FULL, PENGURUS HANYA RADIUS) elseif (($method === 'PUT' || $method === 'POST') && $action === 'update') { $id = intval($_GET['id']); $input = json_decode(file_get_contents('php://input'), true); if ($userRole === 'admin') { // Admin bebas mengubah data apapun $stmt = $conn->prepare("UPDATE masjid SET nama=?, alamat=?, latitude=?, longitude=?, radius=?, nama_pimpinan=?, no_hp=? WHERE id=?"); $stmt->bind_param("ssddissi", $input['nama'], $input['alamat'], $input['latitude'], $input['longitude'], $input['radius'], $input['nama_pimpinan'], $input['no_hp'], $id); } elseif ($userRole === 'pengurus_masjid') { // Pengurus masjid hanya diizinkan mengubah radius masjid miliknya sendiri saja if ($id !== intval($userMasjidId)) { sendResponse(false, 'Akses ditolak! Anda tidak diizinkan mengubah data masjid lain.'); } $stmt = $conn->prepare("UPDATE masjid SET radius=? WHERE id=?"); $stmt->bind_param("ii", $input['radius'], $id); } else { sendResponse(false, 'Akses ditolak! Anda tidak memiliki otoritas mengubah data masjid.'); } if ($stmt->execute()) { // Otomatis hitung ulang jangkauan dhuafa setelah radius masjid berubah autoReassignSystem($conn); sendResponse(true, 'Data masjid berhasil diperbarui'); } else { sendResponse(false, 'Gagal memperbarui data: ' . $stmt->error); } $stmt->close(); } // ACTION: HAPUS MASJID (HANYA ADMIN) elseif ($method === 'DELETE' && $action === 'delete') { if ($userRole !== 'admin') { sendResponse(false, 'Akses ditolak! Hanya Admin yang dapat menghapus data masjid.'); } $id = intval($_GET['id']); $stmt = $conn->prepare("DELETE FROM masjid WHERE id=?"); $stmt->bind_param("i", $id); if ($stmt->execute()) { // Putuskan hubungan pengampu di tabel dhuafa jika masjid dihapus $conn->query("UPDATE orang_berkebutuhan SET status='merah', masjid_pengampu_id=NULL, jarak_ke_masjid=NULL WHERE masjid_pengampu_id=$id"); sendResponse(true, 'Masjid berhasil dihapus'); } else { sendResponse(false, 'Gagal menghapus masjid: ' . $stmt->error); } $stmt->close(); } } // ============================================================================ // 2. MODUL ORANG BERKEBUTUHAN (DHUAFA) // ============================================================================ elseif ($type === 'orang') { // ACTION: AMBIL DATA DHUAFA (SESUAI HAK AKSES) // ACTION: AMBIL DATA DHUAFA / ORANG BERKEBUTUHAN if ($method === 'GET' && $action === 'getAll') { $search = isset($_GET['search']) ? $conn->real_escape_string($_GET['search']) : ''; // JIKA yang login adalah role dhuafa, paksa query hanya mengambil data dirinya sendiri if ($userRole === 'dhuafa') { if (empty($userDhuafaId)) { sendResponse(false, 'Akun user Anda belum ditautkan ke data dhuafa di database.'); } $query = "SELECT o.*, m.nama AS nama_masjid FROM orang_berkebutuhan o LEFT JOIN masjid m ON o.masjid_pengampu_id = m.id WHERE o.id = $userDhuafaId"; } else { // Jika admin atau pengurus masjid, panggil semua/sesuai search $query = "SELECT o.*, m.nama AS nama_masjid FROM orang_berkebutuhan o LEFT JOIN masjid m ON o.masjid_pengampu_id = m.id"; if (!empty($search)) { $query .= " WHERE o.nama LIKE '%$search%' OR o.no_kk LIKE '%$search%'"; } $query .= " ORDER BY o.created_at DESC"; } $result = $conn->query($query); $data = []; while ($row = $result->fetch_assoc()) { $data[] = $row; } sendResponse(true, 'Data berhasil dimuat.', $data); } // ACTION: TAMBAH DATA DHUAFA (ADMIN ATAU MANDIRI MAKSIMAL 1 MARKER) elseif ($method === 'POST' && $action === 'create') { $input = json_decode(file_get_contents('php://input'), true); $targetUserId = null; if ($userRole === 'dhuafa') { // Cek apakah akun dhuafa ini sudah pernah membuat marker sebelumnya $check = $conn->query("SELECT id FROM orang_berkebutuhan WHERE user_id = $userId"); if ($check->num_rows >= 1) { sendResponse(false, 'Akses ditolak! Batas maksimal pembuatan marker adalah 1 lokasi.'); } $targetUserId = $userId; } elseif ($userRole !== 'admin') { sendResponse(false, 'Akses ditolak! Anda tidak memiliki otoritas menambah data warga.'); } $stmt = $conn->prepare("INSERT INTO orang_berkebutuhan (nama, no_kk, alamat, latitude, longitude, tgl_lahir, no_hp, user_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->bind_param("ssissssi", $input['nama'], $input['no_kk'], $input['alamat'], $input['latitude'], $input['longitude'], $input['tgl_lahir'], $input['no_hp'], $targetUserId); if ($stmt->execute()) { $newDhuafaId = $conn->insert_id; // Jika dia dhuafa, langsung tautkan dhuafa_id ke tabel users agar sinkron if ($userRole === 'dhuafa') { $conn->query("UPDATE users SET dhuafa_id = $newDhuafaId WHERE id = $userId"); $_SESSION['dhuafa_id'] = $newDhuafaId; } autoReassignSystem($conn); sendResponse(true, 'Data dhuafa berhasil ditambahkan', ['id' => $newDhuafaId]); } else { sendResponse(false, 'Gagal menambahkan: ' . $stmt->error); } $stmt->close(); } // ACTION: UPDATE DATA DHUAFA (ADMIN ATAU MILIK DIRINYA SENDIRI) elseif (($method === 'PUT' || $method === 'POST') && $action === 'update') { $id = intval($_GET['id']); $input = json_decode(file_get_contents('php://input'), true); if ($userRole === 'dhuafa') { // Dhuafa hanya bisa mengedit data miliknya sendiri if ($id !== intval($userDhuafaId)) { sendResponse(false, 'Akses ditolak! Anda tidak berhak mengubah data milik orang lain.'); } } elseif ($userRole !== 'admin') { sendResponse(false, 'Akses ditolak! Hak akses Anda tidak mengizinkan pengubahan data dhuafa.'); } $stmt = $conn->prepare("UPDATE orang_berkebutuhan SET nama=?, no_kk=?, alamat=?, latitude=?, longitude=?, tgl_lahir=?, no_hp=? WHERE id=?"); $stmt->bind_param("ssissssi", $input['nama'], $input['no_kk'], $input['alamat'], $input['latitude'], $input['longitude'], $input['tgl_lahir'], $input['no_hp'], $id); if ($stmt->execute()) { autoReassignSystem($conn); sendResponse(true, 'Data dhuafa berhasil diupdate'); } else { sendResponse(false, 'Gagal mengupdate: ' . $stmt->error); } $stmt->close(); } // ACTION: HAPUS DATA DHUAFA (ADMIN ATAU MILIK DIRINYA SENDIRI) elseif ($method === 'DELETE' && $action === 'delete') { $id = intval($_GET['id']); if ($userRole === 'dhuafa') { if ($id !== intval($userDhuafaId)) { sendResponse(false, 'Akses ditolak!'); } } elseif ($userRole !== 'admin') { sendResponse(false, 'Akses ditolak! Anda tidak memiliki otoritas menghapus data ini.'); } $stmt = $conn->prepare("DELETE FROM orang_berkebutuhan WHERE id=?"); $stmt->bind_param("i", $id); if ($stmt->execute()) { if ($userRole === 'dhuafa') { $conn->query("UPDATE users SET dhuafa_id = NULL WHERE id = $userId"); $_SESSION['dhuafa_id'] = null; } sendResponse(true, 'Data berhasil dihapus'); } else { sendResponse(false, 'Gagal menghapus: ' . $stmt->error); } $stmt->close(); } } // ============================================================================ // 3. ADMIN SUMMARY (FITUR RINGKASAN DIAGRAM & KPI UNTUK ADMIN) // ============================================================================ elseif ($type === 'summary' && $userRole === 'admin') { if ($method === 'GET') { // Ambil hitungan KPI $totMasjid = $conn->query("SELECT COUNT(*) as total FROM masjid")->fetch_assoc()['total']; $totDhuafa = $conn->query("SELECT COUNT(*) as total FROM orang_berkebutuhan")->fetch_assoc()['total']; $totTerampu = $conn->query("SELECT COUNT(*) as total FROM orang_berkebutuhan WHERE status='hijau'")->fetch_assoc()['total']; $totBelum = $conn->query("SELECT COUNT(*) as total FROM orang_berkebutuhan WHERE status='merah'")->fetch_assoc()['total']; sendResponse(true, 'Data ringkasan admin berhasil dimuat', [ 'total_masjid' => intval($totMasjid), 'total_dhuafa' => intval($totDhuafa), 'terampu' => intval($totTerampu), 'belum_terampu' => intval($totBelum) ]); } } // ============================================================================ // SISTEM FILTER RADIUS JANGKAUAN OTOMATIS (FUNGSI INTERNAL) // ============================================================================ function autoReassignSystem($conn) { // 1. Ambil data masjid $resMasjid = $conn->query("SELECT id, latitude, longitude, radius FROM masjid"); $masjidList = []; while($m = $resMasjid->fetch_assoc()) { $masjidList[] = $m; } // 2. Ambil data dhuafa $resOrang = $conn->query("SELECT id, latitude, longitude FROM orang_berkebutuhan"); $wargaList = []; while($o = $resOrang->fetch_assoc()) { $wargaList[] = $o; } // 3. Reset hitungan jumlah diampu di semua masjid $conn->query("UPDATE masjid SET jumlah_diampu = 0"); // 4. Hitung ulang jarak geospatial secara otomatis foreach($wargaList as $w) { $latWarga = floatval($w['latitude']); $lngWarga = floatval($w['longitude']); $minJarak = 99999999; $assignedMasjidId = null; foreach($masjidList as $m) { $jarak = hitungJarakInPHP($latWarga, $lngWarga, floatval($m['latitude']), floatval($m['longitude'])); if($jarak <= floatval($m['radius'])) { if($jarak < $minJarak) { $minJarak = $jarak; $assignedMasjidId = $m['id']; } } } if($assignedMasjidId) { // PERBAIKAN: Tipe data bind_param disesuaikan (i = integer, d = double/float) $up = $conn->prepare("UPDATE orang_berkebutuhan SET status='hijau', masjid_pengampu_id=?, jarak_ke_masjid=? WHERE id=?"); $up->bind_param("idi", $assignedMasjidId, $minJarak, $w['id']); $up->execute(); $up->close(); // Tambahkan hitungan ke masjid pengampu $conn->query("UPDATE masjid SET jumlah_diampu = jumlah_diampu + 1 WHERE id = $assignedMasjidId"); } else { // Jika di luar radius semua masjid, set status menjadi merah $conn->query("UPDATE orang_berkebutuhan SET status='merah', masjid_pengampu_id=NULL, jarak_ke_masjid=NULL WHERE id=" . $w['id']); } } } function hitungJarakInPHP($lat1, $lng1, $lat2, $lng2) { $R = 6371000; $dLat = deg2rad($lat2 - $lat1); $dLon = deg2rad($lng2 - $lng1); $a = sin($dLat/2) * sin($dLat/2) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($dLon/2) * sin($dLon/2); $c = 2 * atan2(sqrt($a), sqrt(1-$a)); return $R * $c; } ?>