diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..cc91f52 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ + +# Coolify Local Debugger config +.env +.coolify-local.json +Dockerfile.coolify diff --git a/01/.gitignore b/01/.gitignore index 03966d8..57f0d99 100644 --- a/01/.gitignore +++ b/01/.gitignore @@ -15,3 +15,8 @@ access_log # OS generated files .DS_Store Thumbs.db + +# Coolify Local Debugger config +.env +.coolify-local.json +Dockerfile.coolify diff --git a/01/Dockerfile b/01/Dockerfile index dcdc8f5..292e8c6 100644 --- a/01/Dockerfile +++ b/01/Dockerfile @@ -5,8 +5,7 @@ FROM php:8.1-apache WORKDIR /var/www/html # Install system dependencies -RUN apt-get update && apt-get install -y \ - mysql-client \ +RUN apt-get update && (apt-get install -y mysql-client || apt-get install -y default-mysql-client) && apt-get install -y \ git \ curl \ zip \ diff --git a/01/dashboard.html b/01/dashboard.html index 7a8ab88..f1800b2 100644 --- a/01/dashboard.html +++ b/01/dashboard.html @@ -611,7 +611,7 @@
- @@ -619,6 +619,54 @@
+ + +
@@ -859,6 +907,57 @@
+ + + diff --git a/01/docker-compose.yml b/01/docker-compose.yml index a7a135d..6855ccc 100644 --- a/01/docker-compose.yml +++ b/01/docker-compose.yml @@ -11,6 +11,11 @@ services: - .:/var/www/html environment: - APP_ENV=development + - DB_HOST=mysql + - DB_USER=root + - DB_PASSWORD=root_password + - DB_DATABASE=pemetaan_kemiskinan + - DB_PORT=3306 depends_on: - mysql networks: diff --git a/01/js/main.js b/01/js/main.js index 55da330..390b71a 100644 --- a/01/js/main.js +++ b/01/js/main.js @@ -634,12 +634,31 @@ function attachEventListeners() { const form_jalan = document.getElementById('form-jalan'); const form_polygon = document.getElementById('form-polygon'); const form_spbu = document.getElementById('form-spbu'); + const form_bantuan = document.getElementById('form-bantuan'); if (form_masyarakat) form_masyarakat.addEventListener('submit', function(e) { e.preventDefault(); submitFormMasyarakat(); }); if (form_ibadah) form_ibadah.addEventListener('submit', function(e) { e.preventDefault(); submitFormIbadah(); }); if (form_jalan) form_jalan.addEventListener('submit', function(e) { e.preventDefault(); submitFormJalan(); }); if (form_polygon) form_polygon.addEventListener('submit', function(e) { e.preventDefault(); submitFormPolygon(); }); if (form_spbu) form_spbu.addEventListener('submit', function(e) { e.preventDefault(); submitFormSPBU(); }); + if (form_bantuan) form_bantuan.addEventListener('submit', function(e) { e.preventDefault(); submitFormBantuan(); }); + + // BPJS Fields Toggle + const bpjs_status_select = document.getElementById('form-status-bpjs'); + const bpjs_detail_fields = document.getElementById('bpjs-detail-fields'); + if (bpjs_status_select && bpjs_detail_fields) { + bpjs_status_select.addEventListener('change', function() { + if (this.value === 'Ya') { + bpjs_detail_fields.style.display = 'block'; + const dateInput = bpjs_detail_fields.querySelector('input[type="date"]'); + if (dateInput && !dateInput.value) { + dateInput.value = new Date().toISOString().substring(0, 10); + } + } else { + bpjs_detail_fields.style.display = 'none'; + } + }); + } // Shortcut keyboard untuk membuka formulir penambahan data baru document.addEventListener('keydown', function(e) { @@ -757,8 +776,30 @@ function submitFormMasyarakat() { .then(handleFetchResponse) .then(result => { if (result.status === 'success') { + // Tambahkan detail BPJS jika status_bpjs adalah Ya + const status_bpjs = form_data.get('status_bpjs'); + if (status_bpjs === 'Ya') { + const bpjs_data = new FormData(); + bpjs_data.append('id_masyarakat', result.data.id); + bpjs_data.append('no_peserta', form_data.get('bpjs_no_peserta')); + bpjs_data.append('jenis_bpjs', form_data.get('bpjs_jenis_bpjs')); + bpjs_data.append('tingkat', form_data.get('bpjs_tingkat')); + bpjs_data.append('status_aktif', form_data.get('bpjs_status_aktif')); + bpjs_data.append('tanggal_daftar', form_data.get('bpjs_tanggal_daftar')); + bpjs_data.append('faskes_tingkat_1', form_data.get('bpjs_faskes_tingkat_1')); + + fetch(API_PATH + 'simpan_bpjs.php', { + method: 'POST', + body: bpjs_data + }) + .then(handleFetchResponse) + .catch(err => console.error("Gagal menyimpan detail BPJS:", err)); + } + showAlert('alert-form', 'Data berhasil disimpan!', 'success'); form.reset(); + const bpjs_detail_fields = document.getElementById('bpjs-detail-fields'); + if (bpjs_detail_fields) bpjs_detail_fields.style.display = 'none'; setTimeout(() => { closeModal('modal-form-masyarakat'); loadMasyarakat(); @@ -879,7 +920,45 @@ function hapusData(tipe, id) { } function editBantuan(id) { - alert('Fitur tambah bantuan dengan ID ' + id + ' akan ditambahkan segera'); + const form = document.getElementById('form-bantuan'); + if (form) form.reset(); + + const idInput = document.getElementById('bantuan-id-masyarakat'); + if (idInput) idInput.value = id; + + const dateInput = document.querySelector('#form-bantuan input[name="tanggal_bantuan"]'); + if (dateInput) dateInput.value = new Date().toISOString().substring(0, 10); + + openModal('modal-form-bantuan'); +} + +function submitFormBantuan() { + const form = document.getElementById('form-bantuan'); + if (!form) return; + const form_data = new FormData(form); + + fetch(API_PATH + 'simpan_bantuan.php', { + method: 'POST', + body: form_data + }) + .then(handleFetchResponse) + .then(result => { + if (result.status === 'success') { + showAlert('alert-form-bantuan', 'Riwayat bantuan berhasil disimpan!', 'success'); + form.reset(); + const citizenId = form_data.get('id_masyarakat'); + setTimeout(() => { + closeModal('modal-form-bantuan'); + // Refresh detail modal + showDetail(citizenId); + }, 1000); + } else { + showAlert('alert-form-bantuan', result.message || 'Gagal menyimpan riwayat bantuan.', 'error'); + } + }) + .catch(error => { + showAlert('alert-form-bantuan', 'Terjadi kesalahan sistem: ' + error.message, 'error'); + }); } function openModal(modalId) { diff --git a/01/php/db_check.php b/01/php/db_check.php new file mode 100644 index 0000000..f2d5424 --- /dev/null +++ b/01/php/db_check.php @@ -0,0 +1,402 @@ +connect_error) { + $errors[] = "Koneksi database gagal: " . $conn->connect_error; +} else { + $success_logs[] = "Koneksi ke database `{$database}` berhasil!"; +} + +// 2. Baca file database.sql untuk mengambil DDL jika tabel perlu dibuat +$sql_content = ''; +$sql_file = __DIR__ . '/../database.sql'; +if (file_exists($sql_file)) { + $sql_content = file_get_contents($sql_file); + $success_logs[] = "File `database.sql` ditemukan dan berhasil dibaca."; +} else { + $errors[] = "File `database.sql` tidak ditemukan di {$sql_file}. Skrip akan menggunakan DDL cadangan."; +} + +// Helper untuk eksekusi query pembuatan tabel cadangan jika database.sql tidak ada +$fallback_ddl = [ + 'masyarakat_miskin' => "CREATE TABLE IF NOT EXISTS `masyarakat_miskin` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(100) NOT NULL, + `tanggal_lahir` date NOT NULL, + `jenis_kelamin` enum('Laki-laki','Perempuan') NOT NULL, + `nik` varchar(20), + `alamat` text NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `status_bpjs` enum('Ya','Tidak','Proses') DEFAULT 'Tidak', + `no_hp` varchar(15), + `pekerjaan` varchar(100), + `pendapatan_bulanan` int(11), + `jumlah_tanggungan` int(11), + `status_rumah` enum('Milik Sendiri','Sewa','Menumpang') DEFAULT 'Menumpang', + `kelurahan` varchar(100), + `kecamatan` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'rumah_ibadah' => "CREATE TABLE IF NOT EXISTS `rumah_ibadah` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(100) NOT NULL, + `jenis` enum('Masjid','Gereja','Vihara','Kelenteng','Sinagog','Lain') NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `alamat` text NOT NULL, + `nama_pemimpin` varchar(100), + `no_hp_pemimpin` varchar(15), + `kapasitas` int(11), + `tahun_didirikan` year, + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'bantuan_riwayat' => "CREATE TABLE IF NOT EXISTS `bantuan_riwayat` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `id_masyarakat` int(11) NOT NULL, + `jenis_bantuan` varchar(100) NOT NULL, + `tanggal_bantuan` date NOT NULL, + `nilai` int(11) NOT NULL, + `satuan` varchar(50), + `keterangan` text, + `nama_pemberi` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + FOREIGN KEY (`id_masyarakat`) REFERENCES `masyarakat_miskin`(`id`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'bpjs_record' => "CREATE TABLE IF NOT EXISTS `bpjs_record` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `id_masyarakat` int(11) NOT NULL, + `no_peserta` varchar(20) NOT NULL UNIQUE, + `jenis_bpjs` enum('Kesehatan','Ketenagakerjaan','Jaminan Hari Tua') DEFAULT 'Kesehatan', + `tingkat` enum('Penerima Bantuan Iuran (PBI)','Pekerja Penerima Upah','Pekerja Bukan Penerima Upah','Peserta Mandiri') DEFAULT 'Penerima Bantuan Iuran (PBI)', + `tanggal_daftar` date NOT NULL, + `status_aktif` enum('Aktif','Nonaktif','Suspended') DEFAULT 'Aktif', + `faskes_tingkat_1` varchar(100), + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + FOREIGN KEY (`id_masyarakat`) REFERENCES `masyarakat_miskin`(`id`) ON DELETE CASCADE + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'users' => "CREATE TABLE IF NOT EXISTS `users` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `username` varchar(50) NOT NULL UNIQUE, + `password` varchar(255) NOT NULL, + `nama_lengkap` varchar(100) NOT NULL, + `role` enum('Admin','Surveyor','Viewer') DEFAULT 'Surveyor', + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'fasilitas_jalan' => "CREATE TABLE IF NOT EXISTS `fasilitas_jalan` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `geojson` text NOT NULL, + `tipe` varchar(50), + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'fasilitas_polygon' => "CREATE TABLE IF NOT EXISTS `fasilitas_polygon` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `geojson` text NOT NULL, + `tipe` varchar(50), + `keterangan` text, + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;", + + 'fasilitas_spbu' => "CREATE TABLE IF NOT EXISTS `fasilitas_spbu` ( + `id` int(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, + `nama` varchar(150) NOT NULL, + `latitude` decimal(10,8) NOT NULL, + `longitude` decimal(11,8) NOT NULL, + `alamat` text, + `is_24_jam` enum('Ya','Tidak') DEFAULT 'Tidak', + `created_at` timestamp DEFAULT CURRENT_TIMESTAMP, + `updated_at` timestamp DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;" +]; + +// Cek dan buat tabel jika belum ada +foreach ($required_tables as $table) { + $check_table = $conn->query("SHOW TABLES LIKE '{$table}'"); + if ($check_table && $check_table->num_rows > 0) { + // Tabel ada, cek jumlah baris + $count_res = $conn->query("SELECT COUNT(*) as total FROM `{$table}`"); + $count = $count_res ? $count_res->fetch_assoc()['total'] : 0; + $table_status[$table] = [ + 'exists' => true, + 'count' => $count, + 'action' => 'No action needed' + ]; + } else { + // Tabel tidak ada, coba buat dari file SQL + $created = false; + if (!empty($sql_content)) { + // parsing DDL dari sql_content secara sederhana (karena multi_query bisa lambat / error untuk tabel spesifik) + // Sebagai alternatif, jalankan DDL cadangan agar 100% aman dan presisi + $ddl = $fallback_ddl[$table] ?? ''; + if ($ddl && $conn->query($ddl)) { + $created = true; + } + } else { + $ddl = $fallback_ddl[$table] ?? ''; + if ($ddl && $conn->query($ddl)) { + $created = true; + } + } + + if ($created) { + $table_status[$table] = [ + 'exists' => true, + 'count' => 0, + 'action' => 'Table created successfully' + ]; + $success_logs[] = "Tabel `{$table}` berhasil dibuat karena tidak ditemukan."; + } else { + $table_status[$table] = [ + 'exists' => false, + 'count' => 0, + 'action' => 'Failed to create: ' . $conn->error + ]; + $errors[] = "Gagal membuat tabel `{$table}`: " . $conn->error; + } + } +} + +// 3. Cek Default Admin User +if (isset($table_status['users']) && $table_status['users']['exists']) { + $check_admin = $conn->query("SELECT id FROM users WHERE username = 'admin'"); + if ($check_admin && $check_admin->num_rows === 0) { + $insert_admin = $conn->query("INSERT INTO `users` (`username`, `password`, `nama_lengkap`, `role`) VALUES + ('admin', '5f4dcc3b5aa765d61d8327deb882cf99', 'Administrator', 'Admin')"); + if ($insert_admin) { + $success_logs[] = "Akun default admin berhasil ditambahkan."; + $table_status['users']['count'] += 1; + } else { + $errors[] = "Gagal menambahkan akun default admin: " . $conn->error; + } + } +} + +// 4. Masukkan Data Sampel jika tabel kosong +if (isset($table_status['masyarakat_miskin']) && $table_status['masyarakat_miskin']['exists'] && $table_status['masyarakat_miskin']['count'] == 0) { + $insert_sampel = $conn->query("INSERT INTO `masyarakat_miskin` + (`id`, `nama`, `tanggal_lahir`, `jenis_kelamin`, `nik`, `alamat`, `latitude`, `longitude`, `status_bpjs`, `no_hp`, `pekerjaan`, `pendapatan_bulanan`, `jumlah_tanggungan`, `status_rumah`, `kelurahan`, `kecamatan`) VALUES + (1, 'Siti Nur Azizah', '1985-03-15', 'Perempuan', '6101234567890123', 'Jl. Mahakam No. 25', -0.06120000, 109.34450000, 'Ya', '081234567890', 'Buruh Harian', 1500000, 4, 'Menumpang', 'Sungai Jawi', 'Pontianak Kota')"); + if ($insert_sampel) { + $success_logs[] = "Data sampel warga `Siti Nur Azizah` berhasil ditambahkan."; + $table_status['masyarakat_miskin']['count'] = 1; + + // Tambahkan juga riwayat bantuan dan BPJS record yang cocok + $conn->query("INSERT INTO `bpjs_record` (`id_masyarakat`, `no_peserta`, `jenis_bpjs`, `tingkat`, `tanggal_daftar`, `status_aktif`, `faskes_tingkat_1`) VALUES + (1, '0001234567890', 'Kesehatan', 'Penerima Bantuan Iuran (PBI)', '2020-01-15', 'Aktif', 'Puskesmas Pontianak Kota')"); + + $conn->query("INSERT INTO `bantuan_riwayat` (`id_masyarakat`, `jenis_bantuan`, `tanggal_bantuan`, `nilai`, `satuan`, `keterangan`, `nama_pemberi`) VALUES + (1, 'Bantuan Pangan Non Tunai (BPNT)', '2026-05-10', 200000, 'Rupiah/Bulan', 'Bantuan Sembako tahap V', 'Dinas Sosial')"); + + $success_logs[] = "Data sampel BPJS & Riwayat Bantuan berhasil dihubungkan ke warga."; + } +} + +if (isset($table_status['rumah_ibadah']) && $table_status['rumah_ibadah']['exists'] && $table_status['rumah_ibadah']['count'] == 0) { + $insert_sampel_ibadah = $conn->query("INSERT INTO `rumah_ibadah` (`nama`, `jenis`, `latitude`, `longitude`, `alamat`, `nama_pemimpin`, `no_hp_pemimpin`, `kapasitas`, `tahun_didirikan`) VALUES + ('Masjid Al-Hidayah', 'Masjid', -0.06150000, 109.34500000, 'Jl. Diponegoro No. 45', 'Ustaz Ahmad', '081234567890', 500, 2005), + ('Gereja Hati Kudus', 'Gereja', -0.06100000, 109.34400000, 'Jl. Jend Sudirman No. 12', 'Pdt. Bonaventura', '081234567891', 300, 1995)"); + if ($insert_sampel_ibadah) { + $success_logs[] = "Data sampel rumah ibadah (Masjid & Gereja) berhasil ditambahkan."; + $table_status['rumah_ibadah']['count'] = 2; + } +} + +// Bersihkan buffer output +ob_end_clean(); + +// Tampilkan halaman Laporan Diagnostik +?> + + + + + + Database Deployment Diagnostic - WebGIS + + + + + +
+

📊 Status Diagnostik Database WebGIS

+ +

Hasil Pengecekan Tabel

+ + + + + + + + + + + false, 'count' => 0, 'action' => 'Error']; + ?> + + + + + + + + +
Nama TabelStatus KeberadaanJumlah Baris DataTindakan Sistem
+ + Tersedia + + Tidak Ditemukan + + baris + + + +
+ +
+

Logs Sistem:

+ +
[SUCCESS]
+ + +
[ERROR]
+ +
+ +
+ Kembali ke Portal WebGIS → +
+
+ + + diff --git a/01/php/db_tool.php b/01/php/db_tool.php new file mode 100644 index 0000000..7a426a9 --- /dev/null +++ b/01/php/db_tool.php @@ -0,0 +1,444 @@ +query("SET FOREIGN_KEY_CHECKS = 0;"); + + if ($conn->multi_query($sql)) { + do { + if ($res = $conn->store_result()) { + $res->free(); + } + } while ($conn->more_results() && $conn->next_result()); + + $conn->query("SET FOREIGN_KEY_CHECKS = 1;"); + $logs[] = "File SQL " . basename($filepath) . " berhasil diimpor sepenuhnya."; + return true; + } else { + $conn->query("SET FOREIGN_KEY_CHECKS = 1;"); + $error_logs[] = "Gagal mengimpor SQL: " . $conn->error; + return false; + } +} + +// Handler Aksi Perbaikan Database (Hanya berjalan jika terautentikasi) +$action_result = null; +if ($authenticated && isset($_POST['action'])) { + $action = $_POST['action']; + + if ($action === 'check_connection') { + if ($conn->ping()) { + $logs[] = "Koneksi ke database server aktif! Server info: " . $conn->server_info; + } else { + $error_logs[] = "Koneksi database terputus: " . $conn->error; + } + } + + elseif ($action === 'fix_missing') { + $logs[] = "Mulai memeriksa tabel yang hilang..."; + // Dapatkan DDL Cadangan + $sql_file = __DIR__ . '/../database.sql'; + + foreach ($required_tables as $table) { + $check = $conn->query("SHOW TABLES LIKE '{$table}'"); + if ($check && $check->num_rows > 0) { + $logs[] = "Tabel `{$table}` sudah ada (Lewati)."; + } else { + $logs[] = "Tabel `{$table}` hilang! Mencoba membuat tabel..."; + // Kita coba jalankan inisialisasi tabel dari db_check fallback atau database.sql + // Agar aman, buat manual tabel dasar + $created = false; + if (file_exists($sql_file)) { + // Jika file sql ada, kita impor untuk membuat yang kurang + // Supaya tidak meng-drop tabel lain, di database.sql harus menggunakan CREATE TABLE IF NOT EXISTS + executeSQLFile($conn, $sql_file, $logs, $error_logs); + $created = true; + break; + } + } + } + $logs[] = "Pemeriksaan tabel selesai."; + } + + elseif ($action === 'optimize_repair') { + $logs[] = "Mulai proses perbaikan & optimasi tabel..."; + foreach ($required_tables as $table) { + $check = $conn->query("SHOW TABLES LIKE '{$table}'"); + if ($check && $check->num_rows > 0) { + $conn->query("REPAIR TABLE `{$table}`"); + $conn->query("OPTIMIZE TABLE `{$table}`"); + $logs[] = "Tabel `{$table}` berhasil diperbaiki dan dioptimalkan."; + } else { + $error_logs[] = "Tabel `{$table}` tidak ditemukan untuk dioptimalkan."; + } + } + $logs[] = "Proses optimasi selesai."; + } + + elseif ($action === 'hard_reset') { + $logs[] = "⚠️ Melakukan HARD RESET Database..."; + // Drop all known tables + $conn->query("SET FOREIGN_KEY_CHECKS = 0;"); + foreach ($required_tables as $table) { + $conn->query("DROP TABLE IF EXISTS `{$table}`"); + $logs[] = "Menghapus tabel `{$table}` jika ada."; + } + $conn->query("SET FOREIGN_KEY_CHECKS = 1;"); + + // Impor ulang database.sql + $sql_file = __DIR__ . '/../database.sql'; + if (executeSQLFile($conn, $sql_file, $logs, $error_logs)) { + $logs[] = "✅ Database berhasil di-reset ke kondisi awal."; + } else { + $error_logs[] = "❌ Hard reset gagal saat mengimpor skema."; + } + } +} + +// Kumpulkan status database saat ini +$status_tables = []; +if ($authenticated && !$conn->connect_error) { + foreach ($required_tables as $table) { + $check = $conn->query("SHOW TABLES LIKE '{$table}'"); + if ($check && $check->num_rows > 0) { + $count_res = $conn->query("SELECT COUNT(*) as total FROM `{$table}`"); + $count = $count_res ? $count_res->fetch_assoc()['total'] : 0; + $status_tables[$table] = [ + 'exists' => true, + 'count' => $count + ]; + } else { + $status_tables[$table] = [ + 'exists' => false, + 'count' => 0 + ]; + } + } +} +?> + + + + + + Database Master Tool - WebGIS + + + + + +
+

+ 🛠️ Database Master Debug Tool + + Logout / Lock + +

+ + + +
+

Keamanan Diperlukan

+

Masukkan PIN Keamanan untuk mengakses fungsi diagnostik database.

+ + +
+ +
+ + +
+
+ + +
+ +
+

+ * PIN default lokal adalah 123456 (Atur via DB_TOOL_PIN di .env) +

+
+ + +
+ +
+

📊 Status Tabel Database

+ + + + + + + + + + false, 'count' => 0]; + ?> + + + + + + + +
Nama TabelKeberadaanJumlah Data
+ + OK (Tersedia) + + Hilang / Tidak Ada + + Baris
+
+ + +
+

⚡ Aksi Perbaikan

+
+ +
+ + Konektivitas Database + Uji ulang ping ke server MySQL dan baca info status server. + +
+ +
+ + Buat Tabel yang Hilang + Membuat tabel yang hilang secara otomatis tanpa menyentuh tabel yang sudah ada. + +
+ +
+ + Perbaiki & Optimasi + Menjalankan perintah SQL REPAIR dan OPTIMIZE untuk memperbaiki data corrupt. + +
+ +
+ + Reset Ulang (Hard Reset) + Menghapus semua tabel dan mengimpor ulang skema awal dari database.sql. + +
+
+
+
+ + + +
+

💻 Output Log Eksekusi

+
+ +
[INFO]
+ + +
[ERROR]
+ +
+
+ + +
+ ← Kembali ke Portal WebGIS +
+ +
+ + + diff --git a/01/php/koneksi.php b/01/php/koneksi.php index 97e4e23..35f8896 100644 --- a/01/php/koneksi.php +++ b/01/php/koneksi.php @@ -18,19 +18,35 @@ if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') { // Baca dari Environment Variable (untuk deployment Coolify/server) // Jika tidak ada, fallback ke konfigurasi XAMPP lokal -$host = getenv('DB_HOST') ?: "localhost"; -$username = getenv('DB_USER') ?: "root"; -$password = getenv('DB_PASSWORD') ?: ""; -$database = getenv('DB_DATABASE') ?: "pemetaan_kemiskinan"; -$port = getenv('DB_PORT') ?: 3306; +$host = getenv('DB_HOST') ?: ($_SERVER['DB_HOST'] ?? ($_ENV['DB_HOST'] ?? "localhost")); +$username = getenv('DB_USER') ?: ($_SERVER['DB_USER'] ?? ($_ENV['DB_USER'] ?? "root")); +$password = getenv('DB_PASSWORD') ?: ($_SERVER['DB_PASSWORD'] ?? ($_ENV['DB_PASSWORD'] ?? "")); +$database = getenv('DB_DATABASE') ?: ($_SERVER['DB_DATABASE'] ?? ($_ENV['DB_DATABASE'] ?? "pemetaan_kemiskinan")); +$port = getenv('DB_PORT') ?: ($_SERVER['DB_PORT'] ?? ($_ENV['DB_PORT'] ?? 3306)); -// KONEKSI MYSQLI -$conn = new mysqli($host, $username, $password, $database, (int)$port); +// KONEKSI MYSQLI DENGAN LOGIKA FALLBACK +$conn = null; -// CEK KONEKSI -if ($conn->connect_error) { - sendJSON('error', 'Koneksi database gagal: ' . $conn->connect_error); - exit(); +// Aktifkan throwing exception untuk mysqli agar try-catch berfungsi dengan baik +mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); + +try { + // 1. Coba koneksi utama sesuai konfigurasi Environment / Env File + $conn = new mysqli($host, $username, $password, $database, (int)$port); +} catch (Exception $e) { + // 2. Coba koneksi Fallback ke Docker Host (host.docker.internal) + try { + $conn = new mysqli("host.docker.internal", "root", "", "pemetaan_kemiskinan", 3306); + } catch (Exception $e_docker) { + // 3. Coba koneksi Fallback ke Localhost murni + try { + $conn = new mysqli("localhost", "root", "", "pemetaan_kemiskinan", 3306); + } catch (Exception $e_local) { + // Jika semua gagal, berikan respon error + sendJSON('error', 'Koneksi database utama & fallback gagal: ' . $e_local->getMessage()); + exit(); + } + } } // SET CHARSET UTF-8