Coba Commit

This commit is contained in:
naukyy
2026-06-12 22:46:13 +07:00
parent f167f233b7
commit 66bb4c4c7c
126 changed files with 1613 additions and 866 deletions
+113
View File
@@ -0,0 +1,113 @@
<?php
/**
* api_fasilitas.php
* Endpoint: CRUD untuk layer Rumah Ibadah (Point).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama, agama, radius_bantuan_meter, created_at,
ST_AsGeoJSON(geom) AS geojson FROM rumah_ibadah"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama' => $row['nama'],
'agama' => $row['agama'],
'radius_bantuan_meter' => $row['radius_bantuan_meter'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Rumah Ibadah berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Rumah Ibadah: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama']) || !isset($input['agama']) || !isset($input['geometry'])) {
sendError('Nama, agama, dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO rumah_ibadah (nama, agama, radius_bantuan_meter, geom)
VALUES (:nama, :agama, :radius_bantuan_meter, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama' => $input['nama'],
':agama' => $input['agama'],
':radius_bantuan_meter' => $input['radius_bantuan_meter'] ?? 1000,
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Rumah Ibadah berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Rumah Ibadah: ' . $e->getMessage(), 500);
}
break;
case 'PUT':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Rumah Ibadah wajib disertakan');
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) sendError('Data tidak valid');
try {
$stmt = $pdo->prepare(
"UPDATE rumah_ibadah SET nama = :nama, agama = :agama, radius_bantuan_meter = :radius_bantuan_meter WHERE id = :id"
);
$stmt->execute([
':nama' => $input['nama'],
':agama' => $input['agama'],
':radius_bantuan_meter' => $input['radius_bantuan_meter'] ?? 1000,
':id' => $id,
]);
sendSuccess(null, 'Data Rumah Ibadah berhasil diperbarui');
} catch (PDOException $e) {
sendError('Gagal memperbarui Rumah Ibadah: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Rumah Ibadah wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM rumah_ibadah WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Rumah Ibadah berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Rumah Ibadah: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+88
View File
@@ -0,0 +1,88 @@
<?php
/**
* api_jalan.php
* Endpoint: CRUD untuk layer Jalan (LineString).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama, jenis_jalan, created_at, ST_AsGeoJSON(geom) AS geojson FROM jalan"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama' => $row['nama'],
'jenis_jalan' => $row['jenis_jalan'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Jalan berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Jalan: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama']) || !isset($input['geometry'])) {
sendError('Nama dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO jalan (nama, jenis_jalan, geom)
VALUES (:nama, :jenis_jalan, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama' => $input['nama'],
':jenis_jalan' => $input['jenis_jalan'] ?? 'Lokal',
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Jalan berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Jalan: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Jalan wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM jalan WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Jalan berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Jalan: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+91
View File
@@ -0,0 +1,91 @@
<?php
/**
* api_kavling.php
* Endpoint: CRUD untuk layer Kavling (Polygon).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama_pemilik, status_kepemilikan, luas, created_at,
ST_AsGeoJSON(geom) AS geojson FROM kavling"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama_pemilik' => $row['nama_pemilik'],
'status_kepemilikan' => $row['status_kepemilikan'],
'luas' => $row['luas'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Kavling berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Kavling: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama_pemilik']) || !isset($input['geometry'])) {
sendError('Nama pemilik dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO kavling (nama_pemilik, status_kepemilikan, luas, geom)
VALUES (:nama_pemilik, :status_kepemilikan, :luas, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama_pemilik' => $input['nama_pemilik'],
':status_kepemilikan' => $input['status_kepemilikan'] ?? 'SHM',
':luas' => $input['luas'] ?? 0,
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Kavling berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Kavling: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Kavling wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM kavling WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Kavling berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Kavling: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+86
View File
@@ -0,0 +1,86 @@
<?php
/**
* api_kawasan.php
* Endpoint: CRUD untuk layer Kawasan Kumuh (Polygon).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama_kawasan, created_at, ST_AsGeoJSON(geom) AS geojson FROM kawasan_kumuh"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama_kawasan' => $row['nama_kawasan'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Kawasan Kumuh berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Kawasan Kumuh: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama_kawasan']) || !isset($input['geometry'])) {
sendError('Nama kawasan dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO kawasan_kumuh (nama_kawasan, geom)
VALUES (:nama_kawasan, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama_kawasan' => $input['nama_kawasan'],
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Kawasan Kumuh berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Kawasan Kumuh: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Kawasan Kumuh wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM kawasan_kumuh WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Kawasan Kumuh berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Kawasan Kumuh: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+117
View File
@@ -0,0 +1,117 @@
<?php
/**
* api_laporan.php
* Endpoint: CRUD untuk Laporan Warga.
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
require_once __DIR__ . '/../core_config/session_mgr.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
startAppSession();
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
requireApiLogin();
try {
$userId = $_SESSION['user_id'] ?? null;
$role = $_SESSION['role'] ?? 'user';
if ($role === 'admin') {
$stmt = $pdo->query(
"SELECT lw.id, lw.user_id, u.username, lw.kategori, lw.deskripsi,
lw.status, lw.created_at, ST_AsGeoJSON(lw.geometry) AS geojson
FROM laporan_warga lw
JOIN users u ON u.id = lw.user_id
ORDER BY lw.created_at DESC"
);
} else {
$stmt = $pdo->prepare(
"SELECT id, user_id, kategori, deskripsi, status, created_at,
ST_AsGeoJSON(geometry) AS geojson
FROM laporan_warga WHERE user_id = :uid ORDER BY created_at DESC"
);
$stmt->execute([':uid' => $userId]);
}
$rows = $stmt->fetchAll();
foreach ($rows as &$r) {
$r['geojson'] = json_decode($r['geojson']);
}
sendSuccess($rows, 'Data Laporan berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil laporan: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiLogin();
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['kategori']) || !isset($input['deskripsi']) || !isset($input['geometry'])) {
sendError('Kategori, deskripsi, dan geometri wajib diisi');
}
$userId = $_SESSION['user_id'];
try {
$stmt = $pdo->prepare(
"INSERT INTO laporan_warga (user_id, kategori, deskripsi, geometry)
VALUES (:user_id, :kategori, :deskripsi, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':user_id' => $userId,
':kategori' => $input['kategori'],
':deskripsi'=> $input['deskripsi'],
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Laporan berhasil dikirim', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan laporan: ' . $e->getMessage(), 500);
}
break;
case 'PUT':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
$id = $_GET['id'] ?? null;
if (!$id || !isset($input['status'])) sendError('ID dan status wajib disertakan');
$allowed = ['menunggu', 'diproses', 'selesai', 'ditolak'];
if (!in_array($input['status'], $allowed)) sendError('Status tidak valid');
try {
$stmt = $pdo->prepare("UPDATE laporan_warga SET status = :status WHERE id = :id");
$stmt->execute([':status' => $input['status'], ':id' => $id]);
sendSuccess(null, 'Status laporan berhasil diperbarui');
} catch (PDOException $e) {
sendError('Gagal memperbarui laporan: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID laporan wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM laporan_warga WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Laporan berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus laporan: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+77
View File
@@ -0,0 +1,77 @@
<?php
/**
* api_pengguna.php
* Endpoint: Manajemen data Pengguna (hanya Admin).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
requireApiRole('admin');
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, username, role, nama_lengkap, created_at FROM users ORDER BY created_at DESC"
);
sendSuccess($stmt->fetchAll(), 'Data Pengguna berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data pengguna: ' . $e->getMessage(), 500);
}
break;
case 'POST':
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['username'], $input['password'])) {
sendError('Username dan password wajib diisi');
}
try {
$hash = password_hash($input['password'], PASSWORD_BCRYPT);
$stmt = $pdo->prepare(
"INSERT INTO users (username, password, role, nama_lengkap)
VALUES (:username, :password, :role, :nama_lengkap)"
);
$stmt->execute([
':username' => $input['username'],
':password' => $hash,
':role' => $input['role'] ?? 'user',
':nama_lengkap'=> $input['nama_lengkap'] ?? null,
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Pengguna berhasil dibuat', 201);
} catch (PDOException $e) {
sendError('Gagal membuat pengguna: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID pengguna wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM users WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Pengguna berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus pengguna: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+91
View File
@@ -0,0 +1,91 @@
<?php
/**
* api_spbu.php
* Endpoint: CRUD untuk layer SPBU (Point).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama, deskripsi, buka_24_jam, created_at,
ST_AsGeoJSON(geom) AS geojson FROM spbu"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama' => $row['nama'],
'deskripsi' => $row['deskripsi'],
'buka_24_jam' => (bool) $row['buka_24_jam'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data SPBU berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data SPBU: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama']) || !isset($input['geometry'])) {
sendError('Nama dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO spbu (nama, deskripsi, buka_24_jam, geom)
VALUES (:nama, :deskripsi, :buka_24_jam, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama' => $input['nama'],
':deskripsi' => $input['deskripsi'] ?? '',
':buka_24_jam' => isset($input['buka_24_jam']) && $input['buka_24_jam'] ? 1 : 0,
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data SPBU berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan SPBU: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID SPBU wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM spbu WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data SPBU berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus SPBU: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+62
View File
@@ -0,0 +1,62 @@
<?php
/**
* api_spbu_nearby.php
* Endpoint: Mencari SPBU terdekat dari titik koordinat pengguna.
* Query params: lat, lng, radius (meter, default 5000)
*/
require_once __DIR__ . '/../core_config/database.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
if ($method !== 'GET') { sendError('Method not allowed', 405); }
$lat = isset($_GET['lat']) ? (float) $_GET['lat'] : null;
$lng = isset($_GET['lng']) ? (float) $_GET['lng'] : null;
$radius = isset($_GET['radius']) ? (int) $_GET['radius'] : 5000;
if ($lat === null || $lng === null) { sendError('Parameter lat dan lng wajib disertakan'); }
try {
$stmt = $pdo->prepare(
"SELECT id, nama, deskripsi, buka_24_jam, created_at,
ST_AsGeoJSON(geom) AS geojson,
ST_Distance_Sphere(geom, ST_GeomFromText(:point)) AS jarak_meter
FROM spbu
WHERE ST_Distance_Sphere(geom, ST_GeomFromText(:point)) <= :radius
ORDER BY jarak_meter ASC"
);
$stmt->execute([':point' => "POINT({$lng} {$lat})", ':radius' => $radius]);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama' => $row['nama'],
'deskripsi' => $row['deskripsi'],
'buka_24_jam' => (bool) $row['buka_24_jam'],
'jarak_meter' => round($row['jarak_meter'], 2),
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'SPBU Terdekat berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil SPBU Terdekat: ' . $e->getMessage(), 500);
}
+41
View File
@@ -0,0 +1,41 @@
<?php
/**
* api_spbu_status.php
* Endpoint: Mengambil ringkasan status SPBU (berapa 24 jam, berapa tidak).
*/
require_once __DIR__ . '/../core_config/database.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
if ($method !== 'GET') {
sendError('Method not allowed', 405);
}
try {
$stmt = $pdo->query(
"SELECT
COUNT(*) AS total,
SUM(buka_24_jam = 1) AS buka_24_jam,
SUM(buka_24_jam = 0) AS tidak_24_jam
FROM spbu"
);
$summary = $stmt->fetch();
sendSuccess($summary, 'Status SPBU berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil status SPBU: ' . $e->getMessage(), 500);
}
+65
View File
@@ -0,0 +1,65 @@
<?php
/**
* api_statistik.php
* Endpoint: Mengembalikan ringkasan statistik keseluruhan data WebGIS.
*/
require_once __DIR__ . '/../core_config/database.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
if ($method !== 'GET') { sendError('Method not allowed', 405); }
try {
$counts = [];
$tables = [
'spbu' => 'total_spbu',
'rumah_ibadah' => 'total_rumah_ibadah',
'jalan' => 'total_jalan',
'kavling' => 'total_kavling',
'kawasan_kumuh' => 'total_kawasan_kumuh',
'warga_miskin' => 'total_warga_miskin',
'laporan_warga' => 'total_laporan',
'users' => 'total_users',
];
foreach ($tables as $table => $key) {
$row = $pdo->query("SELECT COUNT(*) AS cnt FROM `{$table}`")->fetch();
$counts[$key] = (int) $row['cnt'];
}
// Additional SPBU breakdown
$spbuStatus = $pdo->query(
"SELECT SUM(buka_24_jam=1) AS buka_24_jam, SUM(buka_24_jam=0) AS tidak_24_jam FROM spbu"
)->fetch();
$counts['spbu_buka_24_jam'] = (int) $spbuStatus['buka_24_jam'];
$counts['spbu_tidak_24_jam'] = (int) $spbuStatus['tidak_24_jam'];
// Laporan by status
$laporanStatus = $pdo->query(
"SELECT status, COUNT(*) AS cnt FROM laporan_warga GROUP BY status"
)->fetchAll();
$counts['laporan_by_status'] = [];
foreach ($laporanStatus as $row) {
$counts['laporan_by_status'][$row['status']] = (int) $row['cnt'];
}
sendSuccess($counts, 'Statistik berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil statistik: ' . $e->getMessage(), 500);
}
+100
View File
@@ -0,0 +1,100 @@
<?php
/**
* api_ulasan.php
* Endpoint: CRUD untuk Ulasan Fasilitas (SPBU / Rumah Ibadah).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
require_once __DIR__ . '/../core_config/session_mgr.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
startAppSession();
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
$tipe = $_GET['tipe'] ?? null;
$fid = $_GET['fasilitas_id'] ?? null;
try {
if ($tipe && $fid) {
$stmt = $pdo->prepare(
"SELECT uf.id, uf.user_id, u.username, uf.fasilitas_tipe,
uf.fasilitas_id, uf.rating, uf.komentar, uf.created_at
FROM ulasan_fasilitas uf
JOIN users u ON u.id = uf.user_id
WHERE uf.fasilitas_tipe = :tipe AND uf.fasilitas_id = :fid
ORDER BY uf.created_at DESC"
);
$stmt->execute([':tipe' => $tipe, ':fid' => $fid]);
} else {
$stmt = $pdo->query(
"SELECT uf.id, uf.user_id, u.username, uf.fasilitas_tipe,
uf.fasilitas_id, uf.rating, uf.komentar, uf.created_at
FROM ulasan_fasilitas uf
JOIN users u ON u.id = uf.user_id
ORDER BY uf.created_at DESC"
);
}
sendSuccess($stmt->fetchAll(), 'Data Ulasan berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil ulasan: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiLogin();
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['fasilitas_tipe'], $input['fasilitas_id'], $input['rating'])) {
sendError('fasilitas_tipe, fasilitas_id, dan rating wajib diisi');
}
$allowed = ['spbu', 'rumah_ibadah'];
if (!in_array($input['fasilitas_tipe'], $allowed)) sendError('fasilitas_tipe tidak valid');
if ($input['rating'] < 1 || $input['rating'] > 5) sendError('Rating harus antara 1-5');
try {
$stmt = $pdo->prepare(
"INSERT INTO ulasan_fasilitas (user_id, fasilitas_tipe, fasilitas_id, rating, komentar)
VALUES (:user_id, :fasilitas_tipe, :fasilitas_id, :rating, :komentar)"
);
$stmt->execute([
':user_id' => $_SESSION['user_id'],
':fasilitas_tipe'=> $input['fasilitas_tipe'],
':fasilitas_id' => $input['fasilitas_id'],
':rating' => $input['rating'],
':komentar' => $input['komentar'] ?? null,
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Ulasan berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan ulasan: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID ulasan wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM ulasan_fasilitas WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Ulasan berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus ulasan: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+91
View File
@@ -0,0 +1,91 @@
<?php
/**
* api_warga_miskin.php
* Endpoint: CRUD untuk layer Warga Miskin (Point).
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
$stmt = $pdo->query(
"SELECT id, nama_kk, penghasilan, jumlah_tanggungan, created_at,
ST_AsGeoJSON(geom) AS geojson FROM warga_miskin"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama_kk' => $row['nama_kk'],
'penghasilan' => $row['penghasilan'],
'jumlah_tanggungan' => $row['jumlah_tanggungan'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Warga Miskin berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Warga Miskin: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama_kk']) || !isset($input['geometry'])) {
sendError('Nama KK dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO warga_miskin (nama_kk, penghasilan, jumlah_tanggungan, geom)
VALUES (:nama_kk, :penghasilan, :jumlah_tanggungan, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama_kk' => $input['nama_kk'],
':penghasilan' => $input['penghasilan'] ?? 0,
':jumlah_tanggungan' => $input['jumlah_tanggungan'] ?? 0,
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Warga Miskin berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Warga Miskin: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Warga Miskin wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM warga_miskin WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Warga Miskin berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Warga Miskin: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+98
View File
@@ -0,0 +1,98 @@
<?php
/**
* area_blank.php
* Endpoint: Blank Spot — area tanpa sinyal seluler.
* Menggunakan tabel kawasan_kumuh sebagai proxy (tidak ada tabel blank_spot tersendiri).
* Mengembalikan FeatureCollection kosong jika tabel belum ada.
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
function sendSuccess($data = null, $message = 'Success', $code = 200) {
http_response_code($code);
echo json_encode(['status' => 'success', 'message' => $message, 'data' => $data]);
exit();
}
function sendError($message = 'Error', $code = 400) {
http_response_code($code);
echo json_encode(['status' => 'error', 'message' => $message]);
exit();
}
$pdo = Database::getConnection();
$method = $_SERVER['REQUEST_METHOD'];
switch ($method) {
case 'GET':
try {
// Check if blank_spot table exists, otherwise return empty collection
$check = $pdo->query("SHOW TABLES LIKE 'blank_spot'")->rowCount();
if ($check === 0) {
sendSuccess(
['type' => 'FeatureCollection', 'features' => []],
'Tabel blank_spot belum tersedia'
);
}
$stmt = $pdo->query(
"SELECT id, nama, keterangan, created_at, ST_AsGeoJSON(geom) AS geojson FROM blank_spot"
);
$features = [];
while ($row = $stmt->fetch()) {
$features[] = [
'type' => 'Feature',
'geometry' => json_decode($row['geojson']),
'properties' => [
'id' => $row['id'],
'nama' => $row['nama'],
'keterangan' => $row['keterangan'],
'created_at' => $row['created_at'],
],
];
}
sendSuccess(['type' => 'FeatureCollection', 'features' => $features], 'Data Blank Spot berhasil diambil');
} catch (PDOException $e) {
sendError('Gagal mengambil data Blank Spot: ' . $e->getMessage(), 500);
}
break;
case 'POST':
requireApiRole('admin');
$input = json_decode(file_get_contents('php://input'), true);
if (!isset($input['nama']) || !isset($input['geometry'])) {
sendError('Nama dan geometri wajib diisi');
}
try {
$stmt = $pdo->prepare(
"INSERT INTO blank_spot (nama, keterangan, geom)
VALUES (:nama, :keterangan, ST_GeomFromGeoJSON(:geometry))"
);
$stmt->execute([
':nama' => $input['nama'],
':keterangan' => $input['keterangan'] ?? '',
':geometry' => json_encode($input['geometry']),
]);
sendSuccess(['id' => $pdo->lastInsertId()], 'Data Blank Spot berhasil disimpan', 201);
} catch (PDOException $e) {
sendError('Gagal menyimpan Blank Spot: ' . $e->getMessage(), 500);
}
break;
case 'DELETE':
requireApiRole('admin');
$id = $_GET['id'] ?? null;
if (!$id) sendError('ID Blank Spot wajib disertakan');
try {
$stmt = $pdo->prepare("DELETE FROM blank_spot WHERE id = :id");
$stmt->execute([':id' => $id]);
sendSuccess(null, 'Data Blank Spot berhasil dihapus');
} catch (PDOException $e) {
sendError('Gagal menghapus Blank Spot: ' . $e->getMessage(), 500);
}
break;
default:
sendError('Method not allowed', 405);
}
+35
View File
@@ -0,0 +1,35 @@
<?php
/**
* cek_srid.php
* Utility: Cek SRID (Spatial Reference ID) dari semua kolom geometri.
* Hanya untuk Admin / debugging.
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
requireApiRole('admin');
$pdo = Database::getConnection();
try {
$tables = ['spbu', 'rumah_ibadah', 'jalan', 'kavling', 'kawasan_kumuh', 'warga_miskin'];
$results = [];
foreach ($tables as $table) {
$stmt = $pdo->query(
"SELECT ST_SRID(geom) AS srid, COUNT(*) AS jumlah
FROM `{$table}`
GROUP BY ST_SRID(geom)"
);
$results[$table] = $stmt->fetchAll();
}
http_response_code(200);
echo json_encode(['status' => 'success', 'data' => $results]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}
+33
View File
@@ -0,0 +1,33 @@
<?php
/**
* perbaiki_srid.php
* Utility: Perbaiki SRID semua geometri ke SRID 0 (tidak terdefinisi, kompatibel dengan MySQL).
* Hanya untuk Admin / debugging.
*/
require_once __DIR__ . '/../core_config/database.php';
require_once __DIR__ . '/../core_config/middleware_auth.php';
header('Content-Type: application/json; charset=utf-8');
requireApiRole('admin');
$pdo = Database::getConnection();
try {
$tables = ['spbu', 'rumah_ibadah', 'jalan', 'kavling', 'kawasan_kumuh', 'warga_miskin'];
$updated = [];
foreach ($tables as $table) {
$affected = $pdo->exec(
"UPDATE `{$table}` SET geom = ST_GeomFromWKB(ST_AsWKB(geom), 0) WHERE ST_SRID(geom) != 0"
);
$updated[$table] = ['rows_updated' => $affected];
}
http_response_code(200);
echo json_encode(['status' => 'success', 'message' => 'SRID diperbaiki', 'data' => $updated]);
} catch (PDOException $e) {
http_response_code(500);
echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}