6215b4367a
Sistem WebGIS analisis sebaran penduduk miskin dan jangkauan rumah ibadah. Fitur: peta interaktif Leaflet.js, CRUD rumah ibadah & penduduk miskin, auto-kategorisasi haversine, heatmap, export PDF/CSV, dashboard analitik, manajemen pengguna (superadmin/admin), login sistem. Teknologi: PHP, MySQL, Leaflet.js, OpenStreetMap, Nominatim Geocoding, mPDF. Catatan: jalankan `composer install` di folder uas/ untuk install dependencies. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
93 lines
4.2 KiB
PHP
93 lines
4.2 KiB
PHP
<?php
|
|
header('Content-Type: application/json');
|
|
include '../koneksi.php';
|
|
include '../auth.php';
|
|
requireLogin();
|
|
|
|
$kk_nama = esc($conn, $_POST['kk_nama'] ?? '');
|
|
$nik = esc($conn, $_POST['nik'] ?? '');
|
|
$alamat = esc($conn, $_POST['alamat'] ?? '');
|
|
$kecamatan = esc($conn, $_POST['kecamatan'] ?? '');
|
|
$kelurahan = esc($conn, $_POST['kelurahan'] ?? '');
|
|
$lat = (float)($_POST['lat'] ?? 0);
|
|
$lng = (float)($_POST['lng'] ?? 0);
|
|
$jumlah = max(1, (int)($_POST['jumlah_anggota'] ?? 1));
|
|
$status_allowed = ['belum_dibantu','sudah_dibantu','menunggu_verifikasi'];
|
|
$status = in_array($_POST['status_bantuan'] ?? '', $status_allowed) ? $_POST['status_bantuan'] : 'belum_dibantu';
|
|
$jenis_bantuan = esc($conn, $_POST['jenis_bantuan'] ?? '');
|
|
$tanggal = $_POST['tanggal_bantuan'] ?? '';
|
|
$tanggal_sql = ($tanggal && preg_match('/^\d{4}-\d{2}-\d{2}$/', $tanggal)) ? "'$tanggal'" : 'NULL';
|
|
|
|
if (!$kk_nama || !$alamat || !$lat || !$lng) {
|
|
echo json_encode(['status' => 'error', 'message' => 'Data tidak lengkap.']);
|
|
exit;
|
|
}
|
|
|
|
// --- Find nearest rumah ibadah ---
|
|
$ibadah_res = mysqli_query($conn, "SELECT id, lat, lng, radius FROM rumah_ibadah");
|
|
$nearest_id = null;
|
|
$nearest_dist = PHP_FLOAT_MAX;
|
|
|
|
while ($row = mysqli_fetch_assoc($ibadah_res)) {
|
|
$d = haversine($lat, $lng, (float)$row['lat'], (float)$row['lng']);
|
|
if ($d <= (float)$row['radius'] && $d < $nearest_dist) {
|
|
$nearest_dist = $d;
|
|
$nearest_id = $row['id'];
|
|
}
|
|
}
|
|
// If no ibadah covers, find nearest anyway
|
|
if (!$nearest_id) {
|
|
mysqli_data_seek($ibadah_res, 0);
|
|
while ($row = mysqli_fetch_assoc($ibadah_res)) {
|
|
$d = haversine($lat, $lng, (float)$row['lat'], (float)$row['lng']);
|
|
if ($d < $nearest_dist) { $nearest_dist = $d; $nearest_id = $row['id']; }
|
|
}
|
|
}
|
|
$jarak = $nearest_id ? round($nearest_dist, 2) : 'NULL';
|
|
$ibadah_id_sql = $nearest_id ? $nearest_id : 'NULL';
|
|
$jarak_sql = is_numeric($jarak) ? $jarak : 'NULL';
|
|
|
|
// --- Handle file upload ---
|
|
$bukti_file = '';
|
|
if (!empty($_FILES['bukti_file']['name']) && $_FILES['bukti_file']['error'] === UPLOAD_ERR_OK) {
|
|
$ext = strtolower(pathinfo($_FILES['bukti_file']['name'], PATHINFO_EXTENSION));
|
|
$allowed = ['jpg','jpeg','png','webp','pdf','doc','docx'];
|
|
if (in_array($ext, $allowed) && $_FILES['bukti_file']['size'] <= 5 * 1024 * 1024) {
|
|
$dir = __DIR__ . '/../uploads/bukti/';
|
|
if (!is_dir($dir)) mkdir($dir, 0755, true);
|
|
$fname = 'bukti_' . time() . '_' . bin2hex(random_bytes(4)) . '.' . $ext;
|
|
if (move_uploaded_file($_FILES['bukti_file']['tmp_name'], $dir . $fname)) {
|
|
$bukti_file = $fname;
|
|
}
|
|
}
|
|
}
|
|
$bukti_sql = $bukti_file ? "'".esc($conn,$bukti_file)."'" : 'NULL';
|
|
|
|
// --- Insert penduduk ---
|
|
$q = "INSERT INTO penduduk_miskin (kk_nama,nik,alamat,kecamatan,kelurahan,lat,lng,jumlah_anggota,rumah_ibadah_id,jarak_meter,status_bantuan,jenis_bantuan,tanggal_bantuan,bukti_file)
|
|
VALUES ('$kk_nama','$nik','$alamat','$kecamatan','$kelurahan',$lat,$lng,$jumlah,$ibadah_id_sql,$jarak_sql,'$status','$jenis_bantuan',$tanggal_sql,$bukti_sql)";
|
|
|
|
if (!mysqli_query($conn, $q)) {
|
|
echo json_encode(['status' => 'error', 'message' => mysqli_error($conn)]);
|
|
exit;
|
|
}
|
|
$pid = mysqli_insert_id($conn);
|
|
|
|
// --- Insert anggota keluarga ---
|
|
$anggota = json_decode($_POST['anggota'] ?? '[]', true) ?: [];
|
|
foreach ($anggota as $a) {
|
|
if (empty($a['nama'])) continue;
|
|
$an = esc($conn,$a['nama']); $ah = esc($conn,$a['hubungan'] ?? '');
|
|
$au = (int)($a['umur'] ?? 0); $ap = esc($conn,$a['pekerjaan'] ?? ''); $ak = esc($conn,$a['keterangan'] ?? '');
|
|
mysqli_query($conn, "INSERT INTO anggota_keluarga (penduduk_id,nama,hubungan,umur,pekerjaan,keterangan) VALUES ($pid,'$an','$ah',$au,'$ap','$ak')");
|
|
}
|
|
|
|
echo json_encode(['status' => 'success', 'id' => $pid, 'rumah_ibadah_id' => $nearest_id, 'jarak_meter' => $jarak]);
|
|
|
|
function haversine($lat1, $lon1, $lat2, $lon2) {
|
|
$R = 6371000;
|
|
$d1 = deg2rad($lat1 - $lat2); $d2 = deg2rad($lon1 - $lon2);
|
|
$a = sin($d1/2)**2 + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * sin($d2/2)**2;
|
|
return $R * 2 * atan2(sqrt($a), sqrt(1-$a));
|
|
}
|