Files
UAS_WEBGIS_AlifaAisyahRahma…/Web GIS Rumah Ibadah/api_laporan.php
T
2026-06-09 19:36:57 +07:00

167 lines
5.6 KiB
PHP

<?php
// ============================================================
// API: Laporan Masyarakat
// POST: publik (tanpa login, rate-limited) | GET: admin+walikota | PUT: admin
// ============================================================
require_once __DIR__ . '/config.php';
$method = $_SERVER['REQUEST_METHOD'];
// ── POST: Submit laporan baru (tanpa auth, dengan rate limit) ─
if ($method === 'POST') {
// Rate limit: maks 5 submit per jam per IP
$ip = getClientIP();
if (!checkRateLimit($pdo, $ip)) {
jsonResponse(null, 'Anda telah mencapai batas maksimal 5 laporan per jam. Silakan coba lagi nanti.', false, 429);
}
// Ambil data dari form multipart (karena ada file upload)
$nama_terlapor = clean($_POST['nama_terlapor'] ?? '');
$nik_terlapor = clean($_POST['nik_terlapor'] ?? '');
$nama_pelapor = clean($_POST['nama_pelapor'] ?? '');
$no_hp = clean($_POST['no_hp'] ?? '');
$alamat_terlapor = clean($_POST['alamat_terlapor'] ?? '');
$lat = (float)($_POST['lat'] ?? 0);
$lng = (float)($_POST['lng'] ?? 0);
$deskripsi = clean($_POST['deskripsi'] ?? '');
if (!$alamat_terlapor || !$lat || !$lng || !$deskripsi) {
jsonResponse(null, 'Alamat, koordinat, dan deskripsi wajib diisi.', false, 400);
}
// Validasi NIK jika diisi (harus 16 digit angka)
if ($nik_terlapor && !preg_match('/^\d{16}$/', $nik_terlapor)) {
jsonResponse(null, 'NIK harus 16 digit angka.', false, 400);
}
// Handle upload foto (opsional)
$fotoPath = handleUpload('foto');
// Simpan laporan
$stmt = $pdo->prepare("
INSERT INTO laporan_masyarakat
(nama_terlapor, nik_terlapor, nama_pelapor, no_hp, alamat_terlapor, lat, lng, deskripsi, foto, status)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'Baru')
");
$stmt->execute([
$nama_terlapor ?: null,
$nik_terlapor ?: null,
$nama_pelapor ?: null,
$no_hp ?: null,
$alamat_terlapor,
$lat, $lng,
$deskripsi,
$fotoPath
]);
$newId = (int)$pdo->lastInsertId();
jsonResponse(['id' => $newId], 'Laporan berhasil dikirim. Terima kasih atas partisipasi Anda.');
}
// ── GET: Daftar laporan (admin & walikota) ───────────────────
if ($method === 'GET') {
$user = requireRole(['admin', 'walikota']);
$id = isset($_GET['id']) ? (int)$_GET['id'] : null;
if ($id) {
$stmt = $pdo->prepare("
SELECT lm.*,
u.nama AS nama_penangan,
kk.nama_kepala_keluarga AS nama_kk_converted
FROM laporan_masyarakat lm
LEFT JOIN users u ON lm.ditangani_oleh = u.id
LEFT JOIN keluarga_miskin kk ON lm.converted_to_kk_id = kk.id
WHERE lm.id = ?
");
$stmt->execute([$id]);
$row = $stmt->fetch();
if (!$row) {
jsonResponse(null, 'Laporan tidak ditemukan.', false, 404);
}
jsonResponse($row, 'Detail laporan.');
}
// Filter status
$where = [];
$params = [];
if (!empty($_GET['status'])) {
$where[] = 'lm.status = ?';
$params[] = clean($_GET['status']);
}
$sql = "
SELECT lm.*,
u.nama AS nama_penangan,
kk.nama_kepala_keluarga AS nama_kk_converted
FROM laporan_masyarakat lm
LEFT JOIN users u ON lm.ditangani_oleh = u.id
LEFT JOIN keluarga_miskin kk ON lm.converted_to_kk_id = kk.id
";
if (!empty($where)) {
$sql .= ' WHERE ' . implode(' AND ', $where);
}
$sql .= ' ORDER BY lm.created_at DESC';
$stmt = $pdo->prepare($sql);
$stmt->execute($params);
$rows = $stmt->fetchAll();
jsonResponse($rows, 'Daftar laporan masyarakat.');
}
// ── PUT: Update status laporan (admin only) ──────────────────
if ($method === 'PUT') {
$user = requireRole(['admin']);
$body = json_decode(file_get_contents('php://input'), true) ?? [];
$id = (int)($body['id'] ?? 0);
$status = clean($body['status'] ?? '');
$alasan_tolak = clean($body['alasan_tolak'] ?? '');
$converted_to_kk = isset($body['converted_to_kk_id']) ? (int)$body['converted_to_kk_id'] : null;
if (!$id || !$status) {
jsonResponse(null, 'ID dan status wajib diisi.', false, 400);
}
$validStatus = ['Baru', 'Diverifikasi', 'Ditolak'];
if (!in_array($status, $validStatus)) {
jsonResponse(null, 'Status tidak valid. Pilih: Baru, Diverifikasi, atau Ditolak.', false, 400);
}
// Jika ditolak, wajib ada alasan
if ($status === 'Ditolak' && empty($alasan_tolak)) {
jsonResponse(null, 'Alasan penolakan wajib diisi.', false, 400);
}
// Update laporan
$stmt = $pdo->prepare("
UPDATE laporan_masyarakat SET
status = ?,
alasan_tolak = ?,
ditangani_oleh = ?,
converted_to_kk_id = ?
WHERE id = ?
");
$stmt->execute([
$status,
$status === 'Ditolak' ? $alasan_tolak : null,
$user['id'],
$status === 'Diverifikasi' ? $converted_to_kk : null,
$id
]);
if ($stmt->rowCount() === 0) {
jsonResponse(null, 'Laporan tidak ditemukan.', false, 404);
}
jsonResponse(null, 'Status laporan berhasil diperbarui ke: ' . $status);
}
// ── Method tidak didukung ────────────────────────────────────
jsonResponse(null, 'Method tidak didukung.', false, 405);