Harden Project 01 public endpoints
This commit is contained in:
@@ -8,8 +8,8 @@ $result = $conn->query(
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Tabel belum ada. Jalankan setup_database.sql terlebih dahulu. (' . $conn->error . ')']);
|
||||
$conn->close(); exit;
|
||||
error_log('Project 01 choropleth metadata read failed: ' . $conn->error);
|
||||
json_error('Gagal memuat layer.', 500);
|
||||
}
|
||||
|
||||
$rows = [];
|
||||
@@ -26,4 +26,4 @@ while ($r = $result->fetch_assoc()) {
|
||||
}
|
||||
$conn->close();
|
||||
|
||||
echo json_encode(['status' => 'success', 'data' => $rows, 'total' => count($rows)]);
|
||||
json_success(['data' => $rows, 'total' => count($rows)]);
|
||||
|
||||
@@ -4,10 +4,14 @@ header('Content-Type: application/json');
|
||||
|
||||
$id = (int)($_GET['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); exit;
|
||||
json_error('ID tidak valid.', 400);
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("SELECT geojson FROM choropleth_layers WHERE id = ?");
|
||||
$stmt = $conn->prepare("SELECT geojson FROM choropleth_layers WHERE id = ? AND is_visible = 1");
|
||||
if (!$stmt) {
|
||||
error_log('Project 01 choropleth geojson prepare failed: ' . $conn->error);
|
||||
json_error('Gagal memuat GeoJSON.', 500);
|
||||
}
|
||||
$stmt->bind_param('i', $id);
|
||||
$stmt->execute();
|
||||
$row = $stmt->get_result()->fetch_assoc();
|
||||
@@ -15,8 +19,7 @@ $stmt->close();
|
||||
$conn->close();
|
||||
|
||||
if (!$row) {
|
||||
http_response_code(404);
|
||||
echo json_encode(['status' => 'error', 'message' => 'Layer tidak ditemukan.']); exit;
|
||||
json_error('Layer tidak ditemukan.', 404);
|
||||
}
|
||||
|
||||
echo $row['geojson'];
|
||||
|
||||
+18
-16
@@ -1,26 +1,28 @@
|
||||
<?php
|
||||
require_once '../../koneksi.php';
|
||||
require_admin_json();
|
||||
header('Content-Type: application/json');
|
||||
require_once '../../auth/helper.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Method tidak valid.']); exit;
|
||||
}
|
||||
require_admin_post();
|
||||
require_once '../../koneksi.php';
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); exit;
|
||||
json_error('ID tidak valid.', 400);
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("DELETE FROM choropleth_layers WHERE id = ?");
|
||||
$stmt->bind_param('i', $id);
|
||||
$stmt->execute();
|
||||
$affected = $stmt->affected_rows;
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
|
||||
if ($affected === 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Layer tidak ditemukan.']); exit;
|
||||
if (!$stmt) {
|
||||
error_log('Project 01 choropleth delete prepare failed: ' . $conn->error);
|
||||
json_error('Gagal menghapus layer.', 500);
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'success']);
|
||||
$stmt->bind_param('i', $id);
|
||||
if (!$stmt->execute()) {
|
||||
error_log('Project 01 choropleth delete failed: ' . $stmt->error);
|
||||
json_error('Gagal menghapus layer.', 500);
|
||||
}
|
||||
|
||||
if ($stmt->affected_rows <= 0) {
|
||||
json_error('Layer tidak ditemukan.', 404);
|
||||
}
|
||||
|
||||
json_success();
|
||||
|
||||
@@ -1,27 +1,39 @@
|
||||
<?php
|
||||
require_once '../../koneksi.php';
|
||||
require_admin_json();
|
||||
header('Content-Type: application/json');
|
||||
require_once '../../auth/helper.php';
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Method tidak valid.']); exit;
|
||||
}
|
||||
require_admin_post();
|
||||
require_once '../../koneksi.php';
|
||||
|
||||
$id = (int)($_POST['id'] ?? 0);
|
||||
if ($id <= 0) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'ID tidak valid.']); exit;
|
||||
json_error('ID tidak valid.', 400);
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("UPDATE choropleth_layers SET is_visible = 1 - is_visible WHERE id = ?");
|
||||
if (!$stmt) {
|
||||
error_log('Project 01 choropleth toggle prepare failed: ' . $conn->error);
|
||||
json_error('Gagal mengubah visibilitas layer.', 500);
|
||||
}
|
||||
|
||||
$stmt->bind_param('i', $id);
|
||||
$stmt->execute();
|
||||
if (!$stmt->execute()) {
|
||||
error_log('Project 01 choropleth toggle failed: ' . $stmt->error);
|
||||
json_error('Gagal mengubah visibilitas layer.', 500);
|
||||
}
|
||||
$stmt->close();
|
||||
|
||||
$stmt2 = $conn->prepare("SELECT is_visible FROM choropleth_layers WHERE id = ?");
|
||||
if (!$stmt2) {
|
||||
error_log('Project 01 choropleth visibility prepare failed: ' . $conn->error);
|
||||
json_error('Gagal memuat status layer.', 500);
|
||||
}
|
||||
|
||||
$stmt2->bind_param('i', $id);
|
||||
$stmt2->execute();
|
||||
$row = $stmt2->get_result()->fetch_assoc();
|
||||
$stmt2->close();
|
||||
$conn->close();
|
||||
|
||||
echo json_encode(['status' => 'success', 'is_visible' => (bool)$row['is_visible']]);
|
||||
if (!$row) {
|
||||
json_error('Layer tidak ditemukan.', 404);
|
||||
}
|
||||
|
||||
json_success(['is_visible' => (bool)$row['is_visible']]);
|
||||
|
||||
@@ -1,54 +1,47 @@
|
||||
<?php
|
||||
require_once '../../auth/helper.php';
|
||||
require_once '../../includes/validation.php';
|
||||
|
||||
require_admin_post();
|
||||
require_once '../../koneksi.php';
|
||||
require_admin_json();
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Method tidak valid.']); exit;
|
||||
}
|
||||
$nama = clean_string($_POST['nama'] ?? '', 150);
|
||||
$deskripsi = clean_string($_POST['deskripsi'] ?? '', 500);
|
||||
$attrKey = clean_string($_POST['attribute_key'] ?? '', 100);
|
||||
$palette = validate_enum($_POST['palette'] ?? '', ['blue', 'orange', 'green', 'purple']) ?? 'blue';
|
||||
|
||||
$nama = trim($_POST['nama'] ?? '');
|
||||
$deskripsi = trim($_POST['deskripsi'] ?? '');
|
||||
$attr_key = trim($_POST['attribute_key'] ?? '');
|
||||
$palette = in_array($_POST['palette'] ?? '', ['blue', 'orange', 'green', 'purple'])
|
||||
? $_POST['palette'] : 'blue';
|
||||
|
||||
if (!$nama || !$attr_key) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Nama layer dan atribut wajib diisi.']); exit;
|
||||
if ($nama === '' || $attrKey === '') {
|
||||
json_error('Nama layer dan atribut wajib diisi.', 400);
|
||||
}
|
||||
|
||||
if (empty($_FILES['geojson']['tmp_name']) || $_FILES['geojson']['error'] !== UPLOAD_ERR_OK) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'File GeoJSON tidak ditemukan atau gagal diupload.']); exit;
|
||||
json_error('File GeoJSON tidak ditemukan atau gagal diupload.', 400);
|
||||
}
|
||||
|
||||
if ($_FILES['geojson']['size'] > 10 * 1024 * 1024) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'File terlalu besar (maksimum 10 MB).']); exit;
|
||||
if ($_FILES['geojson']['size'] > MAX_GEOJSON_BYTES) {
|
||||
json_error('File terlalu besar.', 400);
|
||||
}
|
||||
|
||||
$raw = file_get_contents($_FILES['geojson']['tmp_name']);
|
||||
if ($raw === false) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'Gagal membaca file.']); exit;
|
||||
json_error('Gagal membaca file.', 400);
|
||||
}
|
||||
|
||||
$gj = json_decode($raw, true);
|
||||
if (!$gj || !isset($gj['type']) || $gj['type'] !== 'FeatureCollection') {
|
||||
echo json_encode(['status' => 'error', 'message' => 'File bukan GeoJSON FeatureCollection yang valid.']); exit;
|
||||
}
|
||||
if (empty($gj['features'])) {
|
||||
echo json_encode(['status' => 'error', 'message' => 'GeoJSON tidak memiliki fitur/data.']); exit;
|
||||
}
|
||||
|
||||
$first_props = $gj['features'][0]['properties'] ?? [];
|
||||
if (!array_key_exists($attr_key, $first_props)) {
|
||||
$available = implode(', ', array_keys($first_props));
|
||||
echo json_encode(['status' => 'error', 'message' => "Atribut '{$attr_key}' tidak ditemukan. Tersedia: {$available}"]); exit;
|
||||
$geojson = decode_geojson($raw);
|
||||
if ($geojson === null || !validate_feature_collection($geojson, $attrKey)) {
|
||||
json_error('GeoJSON tidak valid atau atribut choropleth tidak lengkap.', 400);
|
||||
}
|
||||
|
||||
$stmt = $conn->prepare("INSERT INTO choropleth_layers (nama, deskripsi, geojson, attribute_key, palette) VALUES (?, ?, ?, ?, ?)");
|
||||
$stmt->bind_param('sssss', $nama, $deskripsi, $raw, $attr_key, $palette);
|
||||
$stmt->execute();
|
||||
$id = $conn->insert_id;
|
||||
$stmt->close();
|
||||
$conn->close();
|
||||
if (!$stmt) {
|
||||
error_log('Project 01 choropleth upload prepare failed: ' . $conn->error);
|
||||
json_error('Gagal menyimpan layer.', 500);
|
||||
}
|
||||
|
||||
echo json_encode(['status' => 'success', 'id' => $id, 'nama' => $nama]);
|
||||
$stmt->bind_param('sssss', $nama, $deskripsi, $raw, $attrKey, $palette);
|
||||
if (!$stmt->execute()) {
|
||||
error_log('Project 01 choropleth upload failed: ' . $stmt->error);
|
||||
json_error('Gagal menyimpan layer.', 500);
|
||||
}
|
||||
|
||||
json_success(['id' => $conn->insert_id, 'nama' => $nama]);
|
||||
|
||||
Reference in New Issue
Block a user