connect_error) { sendJson(['status' => 'error', 'msg' => 'Database connection failed: ' . $conn->connect_error]); } $action = $_GET['action'] ?? $_POST['action'] ?? ''; $input = []; $rawBody = file_get_contents('php://input'); if (!empty($rawBody)) { $decoded = json_decode($rawBody, true); if ($decoded) { $input = $decoded; if (isset($input['action'])) { $action = $input['action']; } } } // ==================== UPLOAD FOTO ==================== if ($action == 'upload_foto') { // Pakai path absolut supaya tidak bergantung letak file yang memanggil $base_dir = dirname(__FILE__); $target_dir = $base_dir . DIRECTORY_SEPARATOR . 'uploads' . DIRECTORY_SEPARATOR; $web_path = 'uploads/'; // path relatif untuk disimpan ke DB & ditampilkan di browser if (!file_exists($target_dir)) { if (!mkdir($target_dir, 0777, true)) { sendJson(['status' => 'error', 'msg' => 'Gagal membuat folder uploads. Cek permission direktori parent.']); } } if (!is_writable($target_dir)) { sendJson(['status' => 'error', 'msg' => 'Folder uploads tidak bisa ditulis. Jalankan di server: chmod 777 uploads/']); } if (!isset($_FILES['foto']) || $_FILES['foto']['error'] === UPLOAD_ERR_NO_FILE) { sendJson(['status' => 'error', 'msg' => 'Tidak ada file yang diupload']); exit; } if ($_FILES['foto']['error'] !== UPLOAD_ERR_OK) { $err_map = [ UPLOAD_ERR_INI_SIZE => 'Ukuran file melebihi batas server (upload_max_filesize)', UPLOAD_ERR_FORM_SIZE => 'Ukuran file melebihi MAX_FILE_SIZE', UPLOAD_ERR_PARTIAL => 'File hanya terupload sebagian, coba lagi', UPLOAD_ERR_NO_TMP_DIR=> 'Folder temporary tidak ditemukan', UPLOAD_ERR_CANT_WRITE=> 'Gagal menulis file ke disk, cek permission', UPLOAD_ERR_EXTENSION => 'Upload dihentikan oleh ekstensi PHP', ]; $msg = $err_map[$_FILES['foto']['error']] ?? 'Error upload: kode ' . $_FILES['foto']['error']; sendJson(['status' => 'error', 'msg' => $msg]); exit; } if ($_FILES['foto']['size'] <= 0) { sendJson(['status' => 'error', 'msg' => 'File kosong (ukuran 0 byte)']); exit; } // Maksimal 5MB if ($_FILES['foto']['size'] > 5000000) { sendJson(['status' => 'error', 'msg' => 'Ukuran file maksimal 5MB']); exit; } // Validasi benar-benar gambar $check = @getimagesize($_FILES['foto']['tmp_name']); if ($check === false) { sendJson(['status' => 'error', 'msg' => 'File bukan gambar yang valid']); exit; } // Ekstensi yang diizinkan $ext = strtolower(pathinfo($_FILES['foto']['name'], PATHINFO_EXTENSION)); if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif', 'webp'])) { sendJson(['status' => 'error', 'msg' => 'Format tidak didukung. Gunakan JPG, PNG, GIF, atau WEBP']); exit; } $clean_name = preg_replace('/[^a-zA-Z0-9._-]/', '_', basename($_FILES['foto']['name'])); $file_name = time() . '_' . $clean_name; $target_file = $target_dir . $file_name; $foto_url = $web_path . $file_name; // simpan path relatif ke DB if (move_uploaded_file($_FILES['foto']['tmp_name'], $target_file)) { sendJson(['status' => 'ok', 'foto_url' => $foto_url]); } else { // Cek permission folder untuk bantu debug $perm = substr(sprintf('%o', fileperms($target_dir)), -4); sendJson([ 'status' => 'error', 'msg' => 'Gagal menyimpan file. Permission folder uploads: ' . $perm . '. Pastikan folder bisa ditulis (chmod 777).', ]); } exit; } // ==================== GET DATA ==================== if ($action == 'get_masjid') { $data = []; $query = mysqli_query($conn, "SELECT id, nama_rumah_ibadah as nama, alamat, lat, lng FROM rumah_ibadah WHERE jenis_rumah_ibadah = 'masjid' OR jenis_rumah_ibadah IS NULL OR jenis_rumah_ibadah = ''"); while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } sendJson($data); exit; } if ($action == 'get_gereja') { $data = []; $query = mysqli_query($conn, "SELECT id, nama_rumah_ibadah as nama, alamat, lat, lng FROM rumah_ibadah WHERE jenis_rumah_ibadah = 'gereja'"); while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } sendJson($data); exit; } if ($action == 'get_poverty') { $data = []; $query = mysqli_query($conn, "SELECT * FROM penduduk_miskin ORDER BY id DESC"); while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } sendJson($data); exit; } if ($action == 'get_bantuan') { $data = []; $query = mysqli_query($conn, "SELECT b.*, p.nama as nama_penduduk FROM bantuan b LEFT JOIN penduduk_miskin p ON b.penduduk_id = p.id ORDER BY b.tanggal_bantuan DESC LIMIT 50"); while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } sendJson($data); exit; } if ($action == 'get_stats_bantuan') { $data = []; $query = mysqli_query($conn, "SELECT DATE_FORMAT(tanggal_bantuan, '%b') as bulan, COUNT(*) as jumlah FROM bantuan GROUP BY MONTH(tanggal_bantuan) ORDER BY MONTH(tanggal_bantuan)"); while ($row = mysqli_fetch_assoc($query)) { $data[] = $row; } sendJson($data); exit; } // ==================== CREATE (TAMBAH DATA) ==================== if ($action == 'add_masjid') { $nama = isset($input['nama']) ? trim($input['nama']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $lat = isset($input['lat']) ? floatval($input['lat']) : 0; $lng = isset($input['lng']) ? floatval($input['lng']) : 0; if (empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Nama wajib diisi']); exit; } $nama = mysqli_real_escape_string($conn, $nama); $alamat = mysqli_real_escape_string($conn, $alamat); $sql = "INSERT INTO rumah_ibadah (nama_rumah_ibadah, alamat, lat, lng, jenis_rumah_ibadah) VALUES ('$nama', '$alamat', $lat, $lng, 'masjid')"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok', 'id' => mysqli_insert_id($conn)]); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'add_gereja') { $nama = isset($input['nama']) ? trim($input['nama']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $lat = isset($input['lat']) ? floatval($input['lat']) : 0; $lng = isset($input['lng']) ? floatval($input['lng']) : 0; if (empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Nama wajib diisi']); exit; } $nama = mysqli_real_escape_string($conn, $nama); $alamat = mysqli_real_escape_string($conn, $alamat); $sql = "INSERT INTO rumah_ibadah (nama_rumah_ibadah, alamat, lat, lng, jenis_rumah_ibadah) VALUES ('$nama', '$alamat', $lat, $lng, 'gereja')"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok', 'id' => mysqli_insert_id($conn)]); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'add_poverty') { $nama = isset($input['nama']) ? trim($input['nama']) : ''; $nik = isset($input['nik']) ? trim($input['nik']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $pekerjaan = isset($input['pekerjaan']) ? trim($input['pekerjaan']) : ''; $penghasilan = isset($input['penghasilan']) ? intval($input['penghasilan']) : 0; $anggota = isset($input['anggota']) ? intval($input['anggota']) : 1; $tanggungan = isset($input['tanggungan']) ? intval($input['tanggungan']) : 0; $kategori = isset($input['kategori']) ? trim($input['kategori']) : 'Miskin'; $status_bantuan = isset($input['status_bantuan']) ? trim($input['status_bantuan']) : 'Belum'; $keterangan = isset($input['keterangan']) ? trim($input['keterangan']) : ''; $lat = isset($input['lat']) ? floatval($input['lat']) : 0; $lng = isset($input['lng']) ? floatval($input['lng']) : 0; $foto = isset($input['foto']) ? trim($input['foto']) : ''; if (empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Nama wajib diisi']); exit; } $nama = mysqli_real_escape_string($conn, $nama); $nik = mysqli_real_escape_string($conn, $nik); $alamat = mysqli_real_escape_string($conn, $alamat); $pekerjaan = mysqli_real_escape_string($conn, $pekerjaan); $kategori = mysqli_real_escape_string($conn, $kategori); $status_bantuan = mysqli_real_escape_string($conn, $status_bantuan); $keterangan = mysqli_real_escape_string($conn, $keterangan); $foto = mysqli_real_escape_string($conn, $foto); $sql = "INSERT INTO penduduk_miskin (nama, nik, alamat, pekerjaan, penghasilan, jumlah_anggota_keluarga, jumlah_tanggungan, kategori_kemiskinan, status_bantuan, keterangan, foto, lat, lng) VALUES ('$nama', '$nik', '$alamat', '$pekerjaan', $penghasilan, $anggota, $tanggungan, '$kategori', '$status_bantuan', '$keterangan', '$foto', $lat, $lng)"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok', 'id' => mysqli_insert_id($conn)]); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'add_bantuan') { $jenis = isset($input['jenis_bantuan']) ? trim($input['jenis_bantuan']) : ''; $jumlah = isset($input['jumlah']) ? trim($input['jumlah']) : ''; $tanggal = isset($input['tanggal']) ? trim($input['tanggal']) : date('Y-m-d'); $keterangan = isset($input['keterangan']) ? trim($input['keterangan']) : ''; $penduduk_id = isset($input['id_penduduk']) ? intval($input['id_penduduk']) : 0; $jenis = mysqli_real_escape_string($conn, $jenis); $jumlah = mysqli_real_escape_string($conn, $jumlah); $tanggal = mysqli_real_escape_string($conn, $tanggal); $keterangan = mysqli_real_escape_string($conn, $keterangan); $sql = "INSERT INTO bantuan (penduduk_id, jenis_bantuan, jumlah_bantuan, tanggal_bantuan, keterangan) VALUES ($penduduk_id, '$jenis', '$jumlah', '$tanggal', '$keterangan')"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } // ==================== UPDATE (EDIT DATA) ==================== if ($action == 'update_masjid') { $id = isset($input['id']) ? intval($input['id']) : 0; $nama = isset($input['nama']) ? trim($input['nama']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $lat = isset($input['lat']) ? floatval($input['lat']) : 0; $lng = isset($input['lng']) ? floatval($input['lng']) : 0; if ($id == 0 || empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Data tidak lengkap']); exit; } $nama = mysqli_real_escape_string($conn, $nama); $alamat = mysqli_real_escape_string($conn, $alamat); $sql = "UPDATE rumah_ibadah SET nama_rumah_ibadah = '$nama', alamat = '$alamat', lat = $lat, lng = $lng WHERE id = $id AND (jenis_rumah_ibadah = 'masjid' OR jenis_rumah_ibadah IS NULL)"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'update_gereja') { $id = isset($input['id']) ? intval($input['id']) : 0; $nama = isset($input['nama']) ? trim($input['nama']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $lat = isset($input['lat']) ? floatval($input['lat']) : 0; $lng = isset($input['lng']) ? floatval($input['lng']) : 0; if ($id == 0 || empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Data tidak lengkap']); exit; } $nama = mysqli_real_escape_string($conn, $nama); $alamat = mysqli_real_escape_string($conn, $alamat); $sql = "UPDATE rumah_ibadah SET nama_rumah_ibadah = '$nama', alamat = '$alamat', lat = $lat, lng = $lng WHERE id = $id AND jenis_rumah_ibadah = 'gereja'"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'update_poverty') { $id = isset($input['id']) ? intval($input['id']) : 0; if ($id == 0) { sendJson(['status' => 'error', 'msg' => 'ID tidak valid']); } if (isset($input['status_bantuan']) && !isset($input['nama'])) { $status_bantuan = mysqli_real_escape_string($conn, trim($input['status_bantuan'])); $sql = "UPDATE penduduk_miskin SET status_bantuan = '$status_bantuan' WHERE id = $id"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } $nama = isset($input['nama']) ? trim($input['nama']) : ''; $nik = isset($input['nik']) ? trim($input['nik']) : ''; $alamat = isset($input['alamat']) ? trim($input['alamat']) : ''; $pekerjaan = isset($input['pekerjaan']) ? trim($input['pekerjaan']) : ''; $penghasilan = isset($input['penghasilan']) ? intval($input['penghasilan']) : 0; $anggota = isset($input['anggota']) ? intval($input['anggota']) : 1; $tanggungan = isset($input['tanggungan']) ? intval($input['tanggungan']) : 0; $kategori = isset($input['kategori']) ? trim($input['kategori']) : 'Miskin'; $status_bantuan = isset($input['status_bantuan']) ? trim($input['status_bantuan']) : 'Belum'; $keterangan = isset($input['keterangan']) ? trim($input['keterangan']) : ''; $foto = isset($input['foto']) ? trim($input['foto']) : ''; if (empty($nama)) { sendJson(['status' => 'error', 'msg' => 'Nama wajib diisi']); } $nama = mysqli_real_escape_string($conn, $nama); $nik = mysqli_real_escape_string($conn, $nik); $alamat = mysqli_real_escape_string($conn, $alamat); $pekerjaan = mysqli_real_escape_string($conn, $pekerjaan); $kategori = mysqli_real_escape_string($conn, $kategori); $status_bantuan = mysqli_real_escape_string($conn, $status_bantuan); $keterangan = mysqli_real_escape_string($conn, $keterangan); $foto = mysqli_real_escape_string($conn, $foto); $sql = "UPDATE penduduk_miskin SET nama = '$nama', nik = '$nik', alamat = '$alamat', pekerjaan = '$pekerjaan', penghasilan = $penghasilan, jumlah_anggota_keluarga = $anggota, jumlah_tanggungan = $tanggungan, kategori_kemiskinan = '$kategori', status_bantuan = '$status_bantuan', keterangan = '$keterangan', foto = '$foto' WHERE id = $id"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } // ==================== DELETE (HAPUS DATA) ==================== if ($action == 'delete_masjid') { $id = isset($input['id']) ? intval($input['id']) : 0; if ($id == 0) { sendJson(['status' => 'error', 'msg' => 'ID tidak valid']); exit; } $sql = "DELETE FROM rumah_ibadah WHERE id = $id AND (jenis_rumah_ibadah = 'masjid' OR jenis_rumah_ibadah IS NULL)"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'delete_gereja') { $id = isset($input['id']) ? intval($input['id']) : 0; if ($id == 0) { sendJson(['status' => 'error', 'msg' => 'ID tidak valid']); exit; } $sql = "DELETE FROM rumah_ibadah WHERE id = $id AND jenis_rumah_ibadah = 'gereja'"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } if ($action == 'delete_poverty') { $id = isset($input['id']) ? intval($input['id']) : 0; if ($id == 0) { sendJson(['status' => 'error', 'msg' => 'ID tidak valid']); exit; } $query = mysqli_query($conn, "SELECT foto FROM penduduk_miskin WHERE id = $id"); if ($row = mysqli_fetch_assoc($query)) { if (!empty($row['foto']) && file_exists($row['foto'])) { unlink($row['foto']); } } mysqli_query($conn, "UPDATE bantuan SET penduduk_id = NULL WHERE penduduk_id = $id"); $sql = "DELETE FROM penduduk_miskin WHERE id = $id"; if (mysqli_query($conn, $sql)) { sendJson(['status' => 'ok']); } else { sendJson(['status' => 'error', 'msg' => mysqli_error($conn)]); } exit; } sendJson(['status' => 'error', 'msg' => 'Aksi tidak dikenal: ' . $action]);