233 lines
10 KiB
PHP
233 lines
10 KiB
PHP
<?php
|
|
session_start();
|
|
header("Content-Type: application/json");
|
|
|
|
// ── KONFIGURASI DATABASE ──────────────────────────────────────
|
|
$host = 'ifuntanhub.dev';
|
|
$port = '33060';
|
|
$db = 'default';
|
|
$user = 'mysql';
|
|
$pass = 'hKZQ51CbVYQsSQL7j5799WtF0kgqTHg4hNRgKo6fq3WSQAHHDFBz3gtIPRAMfTcO';
|
|
|
|
try {
|
|
$pdo = new PDO("mysql:host=$host;port=$port;dbname=$db;charset=utf8mb4", $user, $pass, [
|
|
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
|
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
|
|
]);
|
|
} catch (PDOException $e) {
|
|
http_response_code(500);
|
|
echo json_encode(['error' => 'Koneksi DB Gagal: ' . $e->getMessage()]);
|
|
exit;
|
|
}
|
|
|
|
// ── ROUTER ────────────────────────────────────────────────────
|
|
$route = $_GET['route'] ?? '';
|
|
$method = $_SERVER['REQUEST_METHOD'];
|
|
$data = json_decode(file_get_contents('php://input'), true) ?: [];
|
|
|
|
// Helper Authentication
|
|
function checkAuth() {
|
|
if (!isset($_SESSION['user'])) {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Login diperlukan']);
|
|
exit;
|
|
}
|
|
return $_SESSION['user'];
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════
|
|
// AUTH ENDPOINTS
|
|
// ══════════════════════════════════════════════════
|
|
if ($route === '/login' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ? AND password_hash = ?");
|
|
// Menggunakan SHA256 sesuai format di schema.sql Anda
|
|
$stmt->execute([$data['email'] ?? '', hash('sha256', $data['password'] ?? '')]);
|
|
$user = $stmt->fetch();
|
|
|
|
if ($user && $user['is_active']) {
|
|
$_SESSION['user'] = $user;
|
|
echo json_encode($user);
|
|
} else {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'Email, password salah, atau akun nonaktif']);
|
|
}
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/register' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("SELECT id FROM users WHERE email = ?");
|
|
$stmt->execute([$data['email']]);
|
|
if ($stmt->fetch()) {
|
|
http_response_code(409); echo json_encode(['error' => 'Email sudah terdaftar']); exit;
|
|
}
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO users (nama, email, password_hash, role, wilayah) VALUES (?, ?, ?, 'masyarakat', ?)");
|
|
$stmt->execute([$data['nama'], $data['email'], hash('sha256', $data['password']), $data['wilayah']]);
|
|
|
|
$user = ['id' => $pdo->lastInsertId(), 'nama' => $data['nama'], 'role' => 'masyarakat', 'wilayah' => $data['wilayah']];
|
|
$_SESSION['user'] = $user;
|
|
echo json_encode($user);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/logout' && $method === 'POST') {
|
|
session_destroy();
|
|
echo json_encode(['message' => 'Logout berhasil']);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/me' && $method === 'GET') {
|
|
checkAuth();
|
|
echo json_encode($_SESSION['user']);
|
|
exit;
|
|
}
|
|
|
|
// ══════════════════════════════════════════════════
|
|
// DATA ENDPOINTS (Memerlukan Login)
|
|
// ══════════════════════════════════════════════════
|
|
$user = checkAuth();
|
|
|
|
if ($route === '/stats' && $method === 'GET') {
|
|
$total = $pdo->query("SELECT COUNT(*) FROM rumah_tangga")->fetchColumn();
|
|
$verified = $pdo->query("SELECT COUNT(*) FROM rumah_tangga WHERE status='verified'")->fetchColumn();
|
|
$ri_count = $pdo->query("SELECT COUNT(*) FROM rumah_ibadah")->fetchColumn();
|
|
$covered = $pdo->query("SELECT COUNT(*) FROM rumah_tangga WHERE assigned_ri IS NOT NULL")->fetchColumn();
|
|
|
|
$kelurahan = $pdo->query("SELECT kelurahan, COUNT(*) as n FROM rumah_tangga GROUP BY kelurahan")->fetchAll();
|
|
$status = $pdo->query("SELECT status, COUNT(*) as n FROM rumah_tangga GROUP BY status")->fetchAll();
|
|
|
|
echo json_encode([
|
|
'total' => $total, 'verified' => $verified, 'ri_count' => $ri_count,
|
|
'pct_covered' => $total ? round(($covered/$total)*100) : 0,
|
|
'by_kelurahan' => $kelurahan, 'by_status' => $status
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/rumah-tangga' && $method === 'GET') {
|
|
$rows = $pdo->query("SELECT rt.*, ri.nama as ri_nama FROM rumah_tangga rt LEFT JOIN rumah_ibadah ri ON rt.assigned_ri=ri.id ORDER BY rt.created_at DESC")->fetchAll();
|
|
echo json_encode($rows);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/rumah-tangga' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("INSERT INTO rumah_tangga (nama_kk, alamat, kelurahan, kecamatan, lat, lng, anggota, penghasilan, kondisi, kebutuhan, catatan, dilaporkan_oleh) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([
|
|
$data['nama_kk'], $data['alamat']??'', $data['kelurahan']??'', $data['kecamatan']??'',
|
|
$data['lat'], $data['lng'], $data['anggota']??1, $data['penghasilan']??'',
|
|
$data['kondisi']??'', $data['kebutuhan']??'', $data['catatan']??'', $user['id']
|
|
]);
|
|
|
|
$rt_id = $pdo->lastInsertId();
|
|
|
|
if (!empty($data['tanggungan'])) {
|
|
$tStmt = $pdo->prepare("INSERT INTO tanggungan (rumah_tangga_id, nama, tanggal_lahir, jenis_kelamin, hubungan, pendidikan, pekerjaan) VALUES (?, ?, ?, ?, ?, ?, ?)");
|
|
foreach ($data['tanggungan'] as $t) {
|
|
$tStmt->execute([$rt_id, $t['nama'], $t['tanggal_lahir'], $t['jenis_kelamin']??'L', $t['hubungan']??'', $t['pendidikan']??'', $t['pekerjaan']??'']);
|
|
}
|
|
}
|
|
echo json_encode(['id' => $rt_id, 'message' => 'Laporan tersimpan']);
|
|
exit;
|
|
}
|
|
|
|
if (preg_match('#^/rumah-tangga/(\d+)$#', $route, $matches) && $method === 'GET') {
|
|
$id = $matches[1];
|
|
$rt = $pdo->prepare("SELECT rt.*, ri.nama as ri_nama, ri.tipe as ri_tipe FROM rumah_tangga rt LEFT JOIN rumah_ibadah ri ON rt.assigned_ri=ri.id WHERE rt.id = ?");
|
|
$rt->execute([$id]);
|
|
$rtData = $rt->fetch();
|
|
|
|
if($rtData) {
|
|
$tang = $pdo->prepare("SELECT * FROM tanggungan WHERE rumah_tangga_id = ?");
|
|
$tang->execute([$id]);
|
|
$rtData['tanggungan'] = $tang->fetchAll();
|
|
}
|
|
echo json_encode($rtData);
|
|
exit;
|
|
}
|
|
|
|
if (preg_match('#^/rumah-tangga/(\d+)/verifikasi$#', $route, $matches) && $method === 'POST') {
|
|
$id = $matches[1];
|
|
$aksi = $data['aksi'];
|
|
|
|
$rtStmt = $pdo->prepare("SELECT * FROM rumah_tangga WHERE id = ?");
|
|
$rtStmt->execute([$id]);
|
|
$rt = $rtStmt->fetch();
|
|
|
|
if ($aksi === 'confirm') {
|
|
$pdo->prepare("UPDATE rumah_tangga SET confirmations = confirmations + 1 WHERE id = ?")->execute([$id]);
|
|
} elseif ($aksi === 'reject') {
|
|
$pdo->prepare("UPDATE rumah_tangga SET status = 'rejected' WHERE id = ?")->execute([$id]);
|
|
} elseif ($aksi === 'admin_approve') {
|
|
$pdo->prepare("UPDATE rumah_tangga SET status = 'verified' WHERE id = ?")->execute([$id]);
|
|
|
|
// Logika sederhana: Assign RI terdekat
|
|
$ris = $pdo->query("SELECT id, lat, lng, radius FROM rumah_ibadah")->fetchAll();
|
|
$bestId = null; $bestDist = 99999999;
|
|
foreach($ris as $ri) {
|
|
// Kalkulasi Haversine sederhana di PHP
|
|
$theta = $rt['lng'] - $ri['lng'];
|
|
$dist = sin(deg2rad($rt['lat'])) * sin(deg2rad($ri['lat'])) + cos(deg2rad($rt['lat'])) * cos(deg2rad($ri['lat'])) * cos(deg2rad($theta));
|
|
$dist = acos($dist); $dist = rad2deg($dist); $meters = $dist * 60 * 1.1515 * 1609.344;
|
|
if ($meters <= $ri['radius'] && $meters < $bestDist) { $bestDist = $meters; $bestId = $ri['id']; }
|
|
}
|
|
if($bestId) $pdo->prepare("UPDATE rumah_tangga SET assigned_ri = ? WHERE id = ?")->execute([$bestId, $id]);
|
|
}
|
|
echo json_encode(['message' => 'Verifikasi berhasil diperbarui']);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/rumah-ibadah' && $method === 'GET') {
|
|
$rows = $pdo->query("SELECT ri.*, (SELECT COUNT(*) FROM rumah_tangga WHERE assigned_ri=ri.id) as assigned_count FROM rumah_ibadah ri ORDER BY ri.nama")->fetchAll();
|
|
echo json_encode($rows);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/rumah-ibadah' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("INSERT INTO rumah_ibadah (nama, tipe, kelurahan, lat, lng, radius) VALUES (?, ?, ?, ?, ?, ?)");
|
|
$stmt->execute([$data['nama'], $data['tipe'], $data['kelurahan']??'', $data['lat'], $data['lng'], $data['radius']??500]);
|
|
echo json_encode(['id' => $pdo->lastInsertId()]);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/program' && $method === 'GET') {
|
|
$rows = $pdo->query("SELECT pb.*, ri.nama as ri_nama FROM program_bantuan pb LEFT JOIN rumah_ibadah ri ON pb.ri_id=ri.id")->fetchAll();
|
|
echo json_encode($rows);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/program' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("INSERT INTO program_bantuan (nama, tipe, ri_id, target, tanggal) VALUES (?, ?, ?, ?, CURDATE())");
|
|
$stmt->execute([$data['nama'], $data['tipe'], $data['ri_id'], $data['target']??10]);
|
|
echo json_encode(['id' => $pdo->lastInsertId()]);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/donasi' && $method === 'GET') {
|
|
$rows = $pdo->query("SELECT d.*, u.nama as nama_donatur, ri.nama as nama_ri FROM donasi d LEFT JOIN users u ON d.donatur_id=u.id LEFT JOIN rumah_ibadah ri ON d.ri_id=ri.id")->fetchAll();
|
|
echo json_encode($rows);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/donasi' && $method === 'POST') {
|
|
$stmt = $pdo->prepare("INSERT INTO donasi (donatur_id, ri_id, jumlah, keterangan) VALUES (?, ?, ?, ?)");
|
|
$stmt->execute([$user['id'], $data['ri_id'], $data['jumlah'], $data['keterangan']??'']);
|
|
echo json_encode(['id' => $pdo->lastInsertId()]);
|
|
exit;
|
|
}
|
|
|
|
if ($route === '/users' && $method === 'GET') {
|
|
$rows = $pdo->query("SELECT id, nama, email, role, wilayah, is_active FROM users ORDER BY role")->fetchAll();
|
|
echo json_encode($rows);
|
|
exit;
|
|
}
|
|
|
|
if (preg_match('#^/users/(\d+)/toggle$#', $route, $matches) && $method === 'POST') {
|
|
$id = $matches[1];
|
|
$pdo->prepare("UPDATE users SET is_active = NOT is_active WHERE id = ?")->execute([$id]);
|
|
echo json_encode(['ok' => true]);
|
|
exit;
|
|
}
|
|
|
|
// ── 404 FALLBACK ────────────────────────────────────────────────
|
|
http_response_code(404);
|
|
echo json_encode(['error' => 'Endpoint tidak ditemukan']); |