From 200918b725bb912408cd56065579f1f549d54ed6 Mon Sep 17 00:00:00 2001 From: Nayyara0412 Date: Thu, 11 Jun 2026 15:09:54 +0700 Subject: [PATCH] Fix deployed data rendering and database fallback --- webgis-v3/api/index.php | 12 +++++++++ webgis-v3/config/database.php | 48 +++++++++++++++++++++++++++++++---- webgis02/index.html | 20 ++++++++++++--- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/webgis-v3/api/index.php b/webgis-v3/api/index.php index 3bd625d..5e67c65 100644 --- a/webgis-v3/api/index.php +++ b/webgis-v3/api/index.php @@ -28,6 +28,7 @@ $action = $segments[2] ?? null; // Coba koneksi DB — jika gagal, pakai demo mode $dbOk = false; +$dbError = ''; try { require_once __DIR__ . '/../config/database.php'; $testDb = getDB(); @@ -37,10 +38,21 @@ try { } catch (Throwable $e) { // DB tidak tersedia — pakai demo mode $dbOk = false; + $dbError = $e->getMessage(); } // ── DEMO MODE (tanpa database) ────────────────────────────── if (!$dbOk) { + if (!in_array($method, ['GET', 'OPTIONS'], true)) { + http_response_code(503); + echo json_encode([ + 'success' => false, + 'message' => 'Database belum siap, data tidak bisa disimpan. Periksa DB_HOST, DB_USER, DB_PASSWORD, dan schema webgis_kemiskinan.', + 'errors' => ['database' => $dbError], + ], JSON_UNESCAPED_UNICODE); + exit; + } + demoRouter($resource, $id, $action, $method); exit; } diff --git a/webgis-v3/config/database.php b/webgis-v3/config/database.php index 41e99f0..c1a69ae 100644 --- a/webgis-v3/config/database.php +++ b/webgis-v3/config/database.php @@ -1,19 +1,57 @@ PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false, + ]); + + $safeDb = preg_replace('/[^a-zA-Z0-9_]/', '', DB_NAME); + $server->exec("CREATE DATABASE IF NOT EXISTS `$safeDb` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + + $dsn = "mysql:host=".DB_HOST.";dbname=".$safeDb.";charset=".DB_CHAR; $pdo = new PDO($dsn, DB_USER, DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); + + ensureWebgisV3Schema($pdo); } return $pdo; } + +function ensureWebgisV3Schema(PDO $pdo): void { + $stmt = $pdo->query("SHOW TABLES LIKE 'role'"); + if ($stmt->fetch()) return; + + $schemaFile = __DIR__ . '/../sql/schema.sql'; + if (!is_file($schemaFile)) return; + + $sql = file_get_contents($schemaFile); + $sql = preg_replace('/CREATE DATABASE IF NOT EXISTS\s+`?webgis_kemiskinan`?.*?;/is', '', $sql); + $sql = preg_replace('/USE\s+`?webgis_kemiskinan`?\s*;/i', '', $sql); + $sql = preg_replace('/^\s*--.*$/m', '', $sql); + + foreach (array_filter(array_map('trim', explode(';', $sql))) as $statement) { + if ($statement === '') continue; + $pdo->exec($statement); + } +} diff --git a/webgis02/index.html b/webgis02/index.html index 1b3c6be..9ba2641 100644 --- a/webgis02/index.html +++ b/webgis02/index.html @@ -316,6 +316,17 @@ const layerJalan = L.layerGroup().addTo(map); const layerParsil = L.layerGroup().addTo(map); const layerRusak = L.layerGroup().addTo(map); +function parseGeojsonSafe(raw){ + try { + const gj = typeof raw === 'string' ? JSON.parse(raw) : raw; + if (!gj || !gj.geometry || !gj.geometry.type) return null; + return gj; + } catch(e) { + console.warn('GeoJSON tidak valid:', raw); + return null; + } +} + // ============================================================= // 2. WARNA & IKON // ============================================================= @@ -688,7 +699,8 @@ async function loadJalan(q=''){ if(!data.length){ list.innerHTML='

'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan')+'

'; return; } list.innerHTML=''; data.forEach(item=>{ - const gj = JSON.parse(item.geojson); + const gj = parseGeojsonSafe(item.geojson); + if (!gj) { console.warn('Lewati data jalan tanpa geometry valid', item); return; } const style = WARNA_JALAN[item.status_jalan]||WARNA_JALAN['Kabupaten']; const layer = L.geoJSON(gj,{style}).addTo(layerJalan); layer.bindPopup(` @@ -739,7 +751,8 @@ async function loadParsil(q=''){ if(!data.length){ list.innerHTML='

'+(q?'Tidak ada hasil pencarian':'Belum ada data parsil')+'

'; return; } list.innerHTML=''; data.forEach(item=>{ - const gj = JSON.parse(item.geojson); + const gj = parseGeojsonSafe(item.geojson); + if (!gj) { console.warn('Lewati data parsil tanpa geometry valid', item); return; } const style = WARNA_PARSIL[item.status_kepemilikan]||WARNA_PARSIL['SHM']; const layer = L.geoJSON(gj,{style}).addTo(layerParsil); layer.bindPopup(` @@ -794,7 +807,8 @@ async function loadRusak(q=''){ if(!data.length){ list.innerHTML='

'+(q?'Tidak ada hasil pencarian':'Belum ada data jalan rusak')+'

'; return; } list.innerHTML=''; data.forEach(item=>{ - const gj = JSON.parse(item.geojson); + const gj = parseGeojsonSafe(item.geojson); + if (!gj || !Array.isArray(gj.geometry.coordinates)) { console.warn('Lewati data jalan rusak tanpa geometry valid', item); return; } const cfg = WARNA_RUSAK[item.tingkat]||WARNA_RUSAK['Sedang']; const coord = gj.geometry.coordinates; // [lng, lat] const layer = L.circleMarker([coord[1],coord[0]], cfg).addTo(layerRusak);