Files

316 lines
14 KiB
PHP

<?php
// api_masjid.php - Integrasi Hak Akses & Session Ruleplay
require_once 'config.php';
// Proteksi global: Semua request ke API ini wajib dalam keadaan login
checkLogin();
$method = $_SERVER['REQUEST_METHOD'];
$type = isset($_GET['type']) ? $_GET['type'] : '';
$action = isset($_GET['action']) ? $_GET['action'] : '';
// Mengambil data identitas dari session user yang sedang login
$userRole = $_SESSION['role'];
$userMasjidId = $_SESSION['masjid_id'];
$userDhuafaId = $_SESSION['dhuafa_id'];
$userId = $_SESSION['user_id'];
// ============================================================================
// 1. MODUL MASJID
// ============================================================================
if ($type === 'masjid') {
// ACTION: AMBIL DATA MASJID
if ($method === 'GET' && $action === 'getAll') {
// Aturan: Semua role bisa melihat data masjid untuk kebutuhan visualisasi Peta (Map)
$search = isset($_GET['search']) ? $conn->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;
}
?>