515 lines
12 KiB
PHP
515 lines
12 KiB
PHP
<?php
|
|
|
|
// Tangkap semua output PHP (termasuk error/warning) sebelum header dikirim
|
|
ob_start();
|
|
|
|
// Tampilkan semua error ke buffer, bukan langsung ke browser
|
|
ini_set('display_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
// Set header JSON di awal
|
|
header('Content-Type: application/json');
|
|
|
|
// Tangkap fatal error dan kembalikan sebagai JSON
|
|
register_shutdown_function(function () {
|
|
$error = error_get_last();
|
|
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
|
|
ob_clean();
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'PHP Fatal Error: ' . $error['message'] . ' (line ' . $error['line'] . ')'
|
|
]);
|
|
}
|
|
});
|
|
|
|
// Tangkap exception yang tidak tertangkap
|
|
set_exception_handler(function ($e) {
|
|
ob_clean();
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Exception: ' . $e->getMessage()
|
|
]);
|
|
exit;
|
|
});
|
|
|
|
// Cek apakah config.php ada
|
|
if (!file_exists(__DIR__ . '/config.php')) {
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'File config.php tidak ditemukan di: ' . __DIR__
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
include 'config.php';
|
|
|
|
// Buang output apapun yang tidak sengaja tercetak sebelum JSON (misal warning PHP)
|
|
ob_clean();
|
|
|
|
$action = $_GET['action'] ?? '';
|
|
|
|
// ============================================================
|
|
// Helper Upload Foto
|
|
// ============================================================
|
|
function uploadFoto($fileKey)
|
|
{
|
|
if (
|
|
!isset($_FILES[$fileKey]) ||
|
|
$_FILES[$fileKey]['error'] !== UPLOAD_ERR_OK
|
|
) {
|
|
return null;
|
|
}
|
|
|
|
$uploadDir = 'uploads/';
|
|
|
|
if (!is_dir($uploadDir)) {
|
|
mkdir($uploadDir, 0777, true);
|
|
}
|
|
|
|
$ext = strtolower(pathinfo($_FILES[$fileKey]['name'], PATHINFO_EXTENSION));
|
|
|
|
$allowed = ['jpg', 'jpeg', 'png', 'webp'];
|
|
|
|
if (!in_array($ext, $allowed)) {
|
|
return null;
|
|
}
|
|
|
|
$filename = uniqid('img_', true) . '.' . $ext;
|
|
$destination = $uploadDir . $filename;
|
|
|
|
if (move_uploaded_file($_FILES[$fileKey]['tmp_name'], $destination)) {
|
|
return $filename;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
// ============================================================
|
|
// GET DATA
|
|
// ============================================================
|
|
if ($action === 'get_data') {
|
|
|
|
$roadsResult = $conn->query("SELECT * FROM roads ORDER BY id DESC");
|
|
$parcelsResult = $conn->query("SELECT * FROM parcels ORDER BY id DESC");
|
|
$damagedResult = $conn->query("SELECT * FROM damaged_roads ORDER BY id DESC");
|
|
|
|
if (!$roadsResult || !$parcelsResult || !$damagedResult) {
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Query gagal: ' . $conn->error
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$roads = $roadsResult->fetch_all(MYSQLI_ASSOC);
|
|
$parcels = $parcelsResult->fetch_all(MYSQLI_ASSOC);
|
|
$damaged = $damagedResult->fetch_all(MYSQLI_ASSOC);
|
|
|
|
foreach ($roads as &$row) {
|
|
$row['foto_url'] = !empty($row['foto'])
|
|
? 'uploads/' . $row['foto']
|
|
: null;
|
|
}
|
|
|
|
foreach ($parcels as &$row) {
|
|
$row['foto_url'] = !empty($row['foto'])
|
|
? 'uploads/' . $row['foto']
|
|
: null;
|
|
}
|
|
|
|
foreach ($damaged as &$row) {
|
|
$row['foto_url'] = !empty($row['foto'])
|
|
? 'uploads/' . $row['foto']
|
|
: null;
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'roads' => $roads,
|
|
'parcels' => $parcels,
|
|
'damaged_roads' => $damaged
|
|
]);
|
|
|
|
exit;
|
|
}
|
|
|
|
// ============================================================
|
|
// SEARCH
|
|
// ============================================================
|
|
if ($action === 'search') {
|
|
|
|
$keyword = $_GET['q'] ?? '';
|
|
$keyword = $conn->real_escape_string($keyword);
|
|
$like = "%{$keyword}%";
|
|
|
|
$roadsSearch = $conn->query("
|
|
SELECT
|
|
id,
|
|
name,
|
|
status,
|
|
length_m AS measure,
|
|
'road' AS type
|
|
FROM roads
|
|
WHERE name LIKE '$like'
|
|
OR status LIKE '$like'
|
|
");
|
|
|
|
$parcelsSearch = $conn->query("
|
|
SELECT
|
|
id,
|
|
name,
|
|
status,
|
|
area_sqm AS measure,
|
|
'parcel' AS type
|
|
FROM parcels
|
|
WHERE name LIKE '$like'
|
|
OR status LIKE '$like'
|
|
");
|
|
|
|
$damagedSearch = $conn->query("
|
|
SELECT
|
|
id,
|
|
name,
|
|
status,
|
|
description AS measure,
|
|
'damaged' AS type
|
|
FROM damaged_roads
|
|
WHERE name LIKE '$like'
|
|
OR status LIKE '$like'
|
|
OR description LIKE '$like'
|
|
");
|
|
|
|
if (!$roadsSearch || !$parcelsSearch || !$damagedSearch) {
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Query pencarian gagal: ' . $conn->error
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$roads = $roadsSearch->fetch_all(MYSQLI_ASSOC);
|
|
$parcels = $parcelsSearch->fetch_all(MYSQLI_ASSOC);
|
|
$damaged = $damagedSearch->fetch_all(MYSQLI_ASSOC);
|
|
|
|
$results = array_merge(
|
|
$roads,
|
|
$parcels,
|
|
$damaged
|
|
);
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'data' => $results
|
|
]);
|
|
|
|
exit;
|
|
}
|
|
|
|
// ============================================================
|
|
// GET ONE
|
|
// ============================================================
|
|
if ($action === 'get_one') {
|
|
|
|
$id = (int)($_GET['id'] ?? 0);
|
|
$type = $_GET['type'] ?? '';
|
|
|
|
switch ($type) {
|
|
|
|
case 'road':
|
|
$table = 'roads';
|
|
break;
|
|
|
|
case 'parcel':
|
|
$table = 'parcels';
|
|
break;
|
|
|
|
case 'damaged':
|
|
$table = 'damaged_roads';
|
|
break;
|
|
|
|
default:
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Tipe tidak valid'
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$result = $conn->query(
|
|
"SELECT * FROM $table WHERE id = $id"
|
|
);
|
|
|
|
$row = $result->fetch_assoc();
|
|
|
|
if ($row) {
|
|
$row['foto_url'] = !empty($row['foto'])
|
|
? 'uploads/' . $row['foto']
|
|
: null;
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'data' => $row
|
|
]);
|
|
|
|
exit;
|
|
}
|
|
|
|
// ============================================================
|
|
// SAVE DATA
|
|
// ============================================================
|
|
if ($action === 'save') {
|
|
|
|
$id = isset($_POST['id'])
|
|
? (int)$_POST['id']
|
|
: 0;
|
|
|
|
$type = $_POST['type'] ?? '';
|
|
|
|
$name = $conn->real_escape_string($_POST['name'] ?? '');
|
|
$status = $conn->real_escape_string($_POST['status'] ?? '');
|
|
$geom = $conn->real_escape_string($_POST['geom'] ?? '');
|
|
$measure = $conn->real_escape_string($_POST['measure'] ?? '');
|
|
$description = $conn->real_escape_string($_POST['description'] ?? '');
|
|
|
|
$newFoto = uploadFoto('foto');
|
|
|
|
if ($type === 'road') {
|
|
|
|
if ($id > 0) {
|
|
|
|
$fotoSql = $newFoto
|
|
? ", foto='$newFoto'"
|
|
: "";
|
|
|
|
$sql = "
|
|
UPDATE roads
|
|
SET
|
|
name='$name',
|
|
status='$status',
|
|
length_m='$measure',
|
|
geom='$geom'
|
|
$fotoSql
|
|
WHERE id=$id
|
|
";
|
|
|
|
} else {
|
|
|
|
$fotoVal = $newFoto
|
|
? "'$newFoto'"
|
|
: "NULL";
|
|
|
|
$sql = "
|
|
INSERT INTO roads
|
|
(
|
|
name,
|
|
status,
|
|
length_m,
|
|
geom,
|
|
foto
|
|
)
|
|
VALUES
|
|
(
|
|
'$name',
|
|
'$status',
|
|
'$measure',
|
|
'$geom',
|
|
$fotoVal
|
|
)
|
|
";
|
|
}
|
|
|
|
} elseif ($type === 'parcel') {
|
|
|
|
if ($id > 0) {
|
|
|
|
$fotoSql = $newFoto
|
|
? ", foto='$newFoto'"
|
|
: "";
|
|
|
|
$sql = "
|
|
UPDATE parcels
|
|
SET
|
|
name='$name',
|
|
status='$status',
|
|
area_sqm='$measure',
|
|
geom='$geom'
|
|
$fotoSql
|
|
WHERE id=$id
|
|
";
|
|
|
|
} else {
|
|
|
|
$fotoVal = $newFoto
|
|
? "'$newFoto'"
|
|
: "NULL";
|
|
|
|
$sql = "
|
|
INSERT INTO parcels
|
|
(
|
|
name,
|
|
status,
|
|
area_sqm,
|
|
geom,
|
|
foto
|
|
)
|
|
VALUES
|
|
(
|
|
'$name',
|
|
'$status',
|
|
'$measure',
|
|
'$geom',
|
|
$fotoVal
|
|
)
|
|
";
|
|
}
|
|
|
|
} elseif ($type === 'damaged') {
|
|
|
|
if ($id > 0) {
|
|
|
|
$fotoSql = $newFoto
|
|
? ", foto='$newFoto'"
|
|
: "";
|
|
|
|
$sql = "
|
|
UPDATE damaged_roads
|
|
SET
|
|
name='$name',
|
|
status='$status',
|
|
description='$description',
|
|
geom='$geom'
|
|
$fotoSql
|
|
WHERE id=$id
|
|
";
|
|
|
|
} else {
|
|
|
|
$fotoVal = $newFoto
|
|
? "'$newFoto'"
|
|
: "NULL";
|
|
|
|
$sql = "
|
|
INSERT INTO damaged_roads
|
|
(
|
|
name,
|
|
status,
|
|
description,
|
|
geom,
|
|
foto
|
|
)
|
|
VALUES
|
|
(
|
|
'$name',
|
|
'$status',
|
|
'$description',
|
|
'$geom',
|
|
$fotoVal
|
|
)
|
|
";
|
|
}
|
|
|
|
} else {
|
|
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Tipe data tidak valid'
|
|
]);
|
|
|
|
exit;
|
|
}
|
|
|
|
if ($conn->query($sql)) {
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'message' => 'Data berhasil disimpan',
|
|
'id' => $id > 0 ? $id : $conn->insert_id
|
|
]);
|
|
|
|
} else {
|
|
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => $conn->error
|
|
]);
|
|
}
|
|
|
|
exit;
|
|
}
|
|
|
|
// ============================================================
|
|
// DELETE DATA
|
|
// ============================================================
|
|
if ($action === 'delete') {
|
|
|
|
$id = (int)($_POST['id'] ?? 0);
|
|
$type = $_POST['type'] ?? '';
|
|
|
|
switch ($type) {
|
|
|
|
case 'road':
|
|
$table = 'roads';
|
|
break;
|
|
|
|
case 'parcel':
|
|
$table = 'parcels';
|
|
break;
|
|
|
|
case 'damaged':
|
|
$table = 'damaged_roads';
|
|
break;
|
|
|
|
default:
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Tipe tidak valid'
|
|
]);
|
|
exit;
|
|
}
|
|
|
|
$check = $conn->query(
|
|
"SELECT foto FROM $table WHERE id=$id"
|
|
);
|
|
|
|
if ($check && $check->num_rows > 0) {
|
|
|
|
$row = $check->fetch_assoc();
|
|
|
|
if (
|
|
!empty($row['foto']) &&
|
|
file_exists('uploads/' . $row['foto'])
|
|
) {
|
|
unlink('uploads/' . $row['foto']);
|
|
}
|
|
}
|
|
|
|
if ($conn->query(
|
|
"DELETE FROM $table WHERE id=$id"
|
|
)) {
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'message' => 'Data berhasil dihapus'
|
|
]);
|
|
|
|
} else {
|
|
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => $conn->error
|
|
]);
|
|
}
|
|
|
|
exit;
|
|
}
|
|
|
|
// ============================================================
|
|
// ACTION TIDAK DITEMUKAN
|
|
// ============================================================
|
|
|
|
echo json_encode([
|
|
'success' => false,
|
|
'message' => 'Action tidak ditemukan'
|
|
]);
|