Compare commits

...

7 Commits

9 changed files with 381 additions and 56 deletions
+40 -9
View File
@@ -1,15 +1,46 @@
<?php
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASSWORD');
$pass = ($pass === false) ? '' : $pass;
$db = getenv('DB_NAME_01') ?: getenv('DB_NAME_SPBU') ?: getenv('DB_NAME') ?: 'spbu_db';
$port = (int)(getenv('DB_PORT') ?: 3306);
mysqli_report(MYSQLI_REPORT_OFF);
$conn = new mysqli($host, $user, $pass, $db, $port);
function env_value($keys, $default = null) {
foreach ($keys as $key) {
$value = getenv($key);
if ($value !== false && $value !== '') {
return $value;
}
}
return $default;
}
if ($conn->connect_error) {
die("Koneksi database gagal: " . $conn->connect_error);
$explicitHost = env_value(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST', 'DATABASE_HOST']);
$user = env_value(['DB_USER', 'MYSQL_USER', 'MARIADB_USER', 'DATABASE_USER'], 'root');
$pass = env_value(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD', 'DATABASE_PASSWORD'], '');
$db = env_value(['DB_NAME_01', 'DB_NAME_SPBU', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE', 'DATABASE_NAME'], 'spbu_db');
$port = (int) env_value(['DB_PORT', 'MYSQL_PORT', 'MARIADB_PORT', 'DATABASE_PORT'], 3306);
$hosts = $explicitHost ? [$explicitHost] : [];
if (file_exists('/.dockerenv')) {
$hosts = array_merge($hosts, ['mysql', 'mariadb', 'database', 'db']);
}
$hosts[] = 'localhost';
$hosts[] = '127.0.0.1';
$hosts = array_values(array_unique($hosts));
$conn = null;
$lastError = '';
foreach ($hosts as $host) {
$candidate = mysqli_init();
$candidate->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3);
if (@$candidate->real_connect($host, $user, $pass, $db, $port)) {
$conn = $candidate;
break;
}
$lastError = $candidate->connect_error ?: mysqli_connect_error();
}
if (!$conn) {
http_response_code(500);
die("Koneksi database gagal. Host dicoba: " . implode(', ', $hosts) . ". Error: " . $lastError);
}
$conn->set_charset("utf8mb4");
+40 -9
View File
@@ -1,15 +1,46 @@
<?php
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASSWORD');
$pass = ($pass === false) ? '' : $pass;
$db = getenv('DB_NAME_02') ?: getenv('DB_NAME_WEBGIS2') ?: getenv('DB_NAME') ?: 'webgis2';
$port = (int)(getenv('DB_PORT') ?: 3306);
mysqli_report(MYSQLI_REPORT_OFF);
$conn = new mysqli($host, $user, $pass, $db, $port);
function env_value($keys, $default = null) {
foreach ($keys as $key) {
$value = getenv($key);
if ($value !== false && $value !== '') {
return $value;
}
}
return $default;
}
if ($conn->connect_error) {
die("Koneksi database gagal: " . $conn->connect_error);
$explicitHost = env_value(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST', 'DATABASE_HOST']);
$user = env_value(['DB_USER', 'MYSQL_USER', 'MARIADB_USER', 'DATABASE_USER'], 'root');
$pass = env_value(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD', 'DATABASE_PASSWORD'], '');
$db = env_value(['DB_NAME_02', 'DB_NAME_WEBGIS2', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE', 'DATABASE_NAME'], 'webgis2');
$port = (int) env_value(['DB_PORT', 'MYSQL_PORT', 'MARIADB_PORT', 'DATABASE_PORT'], 3306);
$hosts = $explicitHost ? [$explicitHost] : [];
if (file_exists('/.dockerenv')) {
$hosts = array_merge($hosts, ['mysql', 'mariadb', 'database', 'db']);
}
$hosts[] = 'localhost';
$hosts[] = '127.0.0.1';
$hosts = array_values(array_unique($hosts));
$conn = null;
$lastError = '';
foreach ($hosts as $host) {
$candidate = mysqli_init();
$candidate->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3);
if (@$candidate->real_connect($host, $user, $pass, $db, $port)) {
$conn = $candidate;
break;
}
$lastError = $candidate->connect_error ?: mysqli_connect_error();
}
if (!$conn) {
http_response_code(500);
die("Koneksi database gagal. Host dicoba: " . implode(', ', $hosts) . ". Error: " . $lastError);
}
$conn->set_charset("utf8mb4");
+40 -9
View File
@@ -1,15 +1,46 @@
<?php
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASSWORD');
$pass = ($pass === false) ? '' : $pass;
$db = getenv('DB_NAME_04') ?: getenv('DB_NAME_SPBU') ?: getenv('DB_NAME') ?: 'spbu_db';
$port = (int)(getenv('DB_PORT') ?: 3306);
mysqli_report(MYSQLI_REPORT_OFF);
$conn = new mysqli($host, $user, $pass, $db, $port);
function env_value($keys, $default = null) {
foreach ($keys as $key) {
$value = getenv($key);
if ($value !== false && $value !== '') {
return $value;
}
}
return $default;
}
if ($conn->connect_error) {
die("Koneksi database gagal: " . $conn->connect_error);
$explicitHost = env_value(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST', 'DATABASE_HOST']);
$user = env_value(['DB_USER', 'MYSQL_USER', 'MARIADB_USER', 'DATABASE_USER'], 'root');
$pass = env_value(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD', 'DATABASE_PASSWORD'], '');
$db = env_value(['DB_NAME_04', 'DB_NAME_SPBU', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE', 'DATABASE_NAME'], 'spbu_db');
$port = (int) env_value(['DB_PORT', 'MYSQL_PORT', 'MARIADB_PORT', 'DATABASE_PORT'], 3306);
$hosts = $explicitHost ? [$explicitHost] : [];
if (file_exists('/.dockerenv')) {
$hosts = array_merge($hosts, ['mysql', 'mariadb', 'database', 'db']);
}
$hosts[] = 'localhost';
$hosts[] = '127.0.0.1';
$hosts = array_values(array_unique($hosts));
$conn = null;
$lastError = '';
foreach ($hosts as $host) {
$candidate = mysqli_init();
$candidate->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3);
if (@$candidate->real_connect($host, $user, $pass, $db, $port)) {
$conn = $candidate;
break;
}
$lastError = $candidate->connect_error ?: mysqli_connect_error();
}
if (!$conn) {
http_response_code(500);
die("Koneksi database gagal. Host dicoba: " . implode(', ', $hosts) . ". Error: " . $lastError);
}
$conn->set_charset("utf8mb4");
+15
View File
@@ -0,0 +1,15 @@
<?php
header('Content-Type: application/json');
include 'koneksi.php';
$result = $conn->query("SELECT DATABASE() AS db_name, NOW() AS server_time");
$row = $result ? $result->fetch_assoc() : null;
echo json_encode([
"status" => "success",
"db" => $row["db_name"] ?? null,
"server_time" => $row["server_time"] ?? null,
"host_env" => getenv("DB_HOST") ?: null,
"port_env" => getenv("DB_PORT") ?: null,
"user_env" => getenv("DB_USER") ?: null,
]);
+65 -20
View File
@@ -1103,8 +1103,8 @@ tr:hover td { background: var(--surface2); }
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" onclick="closeModal('penduduk')">Batal</button>
<button class="btn-primary" onclick="simpanPenduduk()">Simpan</button>
<button type="button" class="btn-cancel" onclick="closeModal('penduduk')">Batal</button>
<button type="button" class="btn-primary" onclick="simpanPenduduk(this)">Simpan</button>
</div>
</div>
</div>
@@ -1129,8 +1129,8 @@ tr:hover td { background: var(--surface2); }
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" onclick="closeModal('ibadah')">Batal</button>
<button class="btn-primary" onclick="simpanIbadah()" style="background:var(--ibadah)">Simpan</button>
<button type="button" class="btn-cancel" onclick="closeModal('ibadah')">Batal</button>
<button type="button" class="btn-primary" onclick="simpanIbadah(this)" style="background:var(--ibadah)">Simpan</button>
</div>
</div>
</div>
@@ -1157,8 +1157,8 @@ tr:hover td { background: var(--surface2); }
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" onclick="closeModal('laporan')">Batal</button>
<button class="btn-primary" onclick="simpanLaporan()" style="background:var(--laporan)">Kirim Laporan</button>
<button type="button" class="btn-cancel" onclick="closeModal('laporan')">Batal</button>
<button type="button" class="btn-primary" onclick="simpanLaporan(this)" style="background:var(--laporan)">Kirim Laporan</button>
</div>
</div>
</div>
@@ -1184,8 +1184,8 @@ tr:hover td { background: var(--surface2); }
</div>
</div>
<div class="modal-footer">
<button class="btn-cancel" onclick="closeModal('keluarga')">Batal</button>
<button class="btn-primary" onclick="simpanKeluarga()">Simpan KK</button>
<button type="button" class="btn-cancel" onclick="closeModal('keluarga')">Batal</button>
<button type="button" class="btn-primary" onclick="simpanKeluarga(this)">Simpan KK</button>
</div>
</div>
</div>
@@ -1948,8 +1948,37 @@ function showLaporanDetail(id) {
.catch(() => showToast('Gagal memuat detail laporan','error'));
}
function setSavingButton(btn, saving, text='Simpan') {
if (!btn) return;
btn.disabled = saving;
btn.style.opacity = saving ? '.65' : '';
btn.style.cursor = saving ? 'wait' : '';
btn.textContent = saving ? 'Menyimpan...' : text;
}
function postFormJson(url, fd) {
return fetch(url, {
method: 'POST',
body: fd,
credentials: 'same-origin',
cache: 'no-store'
}).then(async response => {
const text = await response.text();
let data;
try {
data = JSON.parse(text);
} catch (e) {
throw new Error(text.trim() || `HTTP ${response.status}`);
}
if (!response.ok) {
throw new Error(data.msg || data.error || `HTTP ${response.status}`);
}
return data;
});
}
// ===== SIMPAN PENDUDUK =====
function simpanPenduduk() {
function simpanPenduduk(btn) {
const nik=document.getElementById('p-nik').value.trim();
const nama=document.getElementById('p-nama').value.trim();
const lat=document.getElementById('p-lat').value;
@@ -1970,7 +1999,8 @@ function simpanPenduduk() {
fd.append('pendidikan_terakhir',document.getElementById('p-pendidikan').value);
fd.append('status_pendidikan',document.getElementById('p-statuspend').value);
fd.append('lat',lat); fd.append('lng',lng);
fetch('simpan.php',{method:'POST',body:fd}).then(r=>r.json()).then(res=>{
setSavingButton(btn, true);
postFormJson('simpan.php', fd).then(res=>{
if (res.status==='success') {
showToast('Penduduk berhasil disimpan ✓','success');
closeModal('penduduk');
@@ -1978,11 +2008,14 @@ function simpanPenduduk() {
tambahLog('tambah_penduduk','penduduk',res.id,'Tambah penduduk: '+nama);
}
else showToast('Error: '+(res.msg||'Gagal'),'error');
});
}).catch(err => {
showToast('Gagal simpan: '+err.message,'error');
console.error('Simpan penduduk gagal:', err);
}).finally(() => setSavingButton(btn, false, 'Simpan'));
}
// ===== SIMPAN IBADAH =====
function simpanIbadah() {
function simpanIbadah(btn) {
const nama=document.getElementById('i-nama').value.trim();
const lat=document.getElementById('i-lat').value;
const lng=document.getElementById('i-lng').value;
@@ -1995,7 +2028,8 @@ function simpanIbadah() {
fd.append('alamat',document.getElementById('i-alamat').value);
fd.append('radius',document.getElementById('i-radius').value);
fd.append('lat',lat); fd.append('lng',lng);
fetch('simpan.php',{method:'POST',body:fd}).then(r=>r.json()).then(res=>{
setSavingButton(btn, true);
postFormJson('simpan.php', fd).then(res=>{
if (res.status==='success') {
showToast('Rumah Ibadah ditambahkan ✓','success');
closeModal('ibadah');
@@ -2003,11 +2037,14 @@ function simpanIbadah() {
tambahLog('tambah_ibadah','rumah_ibadah',res.id,'Tambah rumah ibadah: '+document.getElementById('i-nama').value);
}
else showToast('Error: '+(res.msg||'Gagal'),'error');
});
}).catch(err => {
showToast('Gagal simpan: '+err.message,'error');
console.error('Simpan ibadah gagal:', err);
}).finally(() => setSavingButton(btn, false, 'Simpan'));
}
// ===== SIMPAN LAPORAN =====
function simpanLaporan() {
function simpanLaporan(btn) {
const desk=document.getElementById('l-desk').value.trim();
const lat=document.getElementById('l-lat').value;
if (!desk) return showToast('Deskripsi wajib diisi','error');
@@ -2018,7 +2055,8 @@ function simpanLaporan() {
fd.append('deskripsi',desk);
fd.append('urgensi',document.getElementById('l-urg').value);
fd.append('lat',lat); fd.append('lng',document.getElementById('l-lng').value);
fetch('simpan.php',{method:'POST',body:fd}).then(r=>r.json()).then(res=>{
setSavingButton(btn, true, 'Kirim Laporan');
postFormJson('simpan.php', fd).then(res=>{
if (res.status==='success') {
showToast('Laporan berhasil dikirim ✓','success');
closeModal('laporan');
@@ -2027,11 +2065,14 @@ function simpanLaporan() {
tambahLog('buat_laporan','laporan',res.id,'Buat laporan: '+document.getElementById('l-desk').value.slice(0,60));
}
else showToast('Gagal mengirim laporan','error');
});
}).catch(err => {
showToast('Gagal kirim: '+err.message,'error');
console.error('Simpan laporan gagal:', err);
}).finally(() => setSavingButton(btn, false, 'Kirim Laporan'));
}
// ===== SIMPAN KELUARGA =====
function simpanKeluarga() {
function simpanKeluarga(btn) {
const nokk = document.getElementById('kk-nokk').value.trim();
const alamat = document.getElementById('kk-alamat').value.trim();
const lat = document.getElementById('kk-lat').value;
@@ -2046,7 +2087,8 @@ function simpanKeluarga() {
fd.append('kecamatan', document.getElementById('kk-kec').value);
fd.append('lat', lat);
fd.append('lng', lng);
fetch('simpan.php', {method:'POST', body:fd}).then(r=>r.json()).then(res=>{
setSavingButton(btn, true, 'Simpan KK');
postFormJson('simpan.php', fd).then(res=>{
if (res.status==='success') {
showToast('Kartu Keluarga berhasil disimpan ✓','success');
closeModal('keluarga');
@@ -2055,7 +2097,10 @@ function simpanKeluarga() {
} else {
showToast('Error: '+(res.msg||'Gagal simpan KK'),'error');
}
});
}).catch(err => {
showToast('Gagal simpan KK: '+err.message,'error');
console.error('Simpan KK gagal:', err);
}).finally(() => setSavingButton(btn, false, 'Simpan KK'));
}
// ===== HAPUS =====
+42 -9
View File
@@ -1,16 +1,49 @@
<?php
$host = getenv('DB_HOST') ?: 'localhost';
$user = getenv('DB_USER') ?: 'root';
$pass = getenv('DB_PASSWORD');
$pass = ($pass === false) ? '' : $pass;
$db = getenv('DB_NAME_05') ?: getenv('DB_NAME_UAS') ?: getenv('DB_NAME') ?: 'webgis_uas';
$port = (int)(getenv('DB_PORT') ?: 3306);
mysqli_report(MYSQLI_REPORT_OFF);
$conn = new mysqli($host, $user, $pass, $db, $port);
function env_value($keys, $default = null) {
foreach ($keys as $key) {
$value = getenv($key);
if ($value !== false && $value !== '') {
return $value;
}
}
return $default;
}
if ($conn->connect_error) {
$explicitHost = env_value(['DB_HOST', 'MYSQL_HOST', 'MARIADB_HOST', 'DATABASE_HOST']);
$user = env_value(['DB_USER', 'MYSQL_USER', 'MARIADB_USER', 'DATABASE_USER'], 'root');
$pass = env_value(['DB_PASSWORD', 'MYSQL_PASSWORD', 'MARIADB_PASSWORD', 'DATABASE_PASSWORD'], '');
$db = env_value(['DB_NAME_05', 'DB_NAME_UAS', 'DB_NAME', 'MYSQL_DATABASE', 'MARIADB_DATABASE', 'DATABASE_NAME'], 'webgis_uas');
$port = (int) env_value(['DB_PORT', 'MYSQL_PORT', 'MARIADB_PORT', 'DATABASE_PORT'], 3306);
$hosts = $explicitHost ? [$explicitHost] : [];
if (file_exists('/.dockerenv')) {
$hosts = array_merge($hosts, ['mysql', 'mariadb', 'database', 'db']);
}
$hosts[] = 'localhost';
$hosts[] = '127.0.0.1';
$hosts = array_values(array_unique($hosts));
$conn = null;
$lastError = '';
foreach ($hosts as $host) {
$candidate = mysqli_init();
$candidate->options(MYSQLI_OPT_CONNECT_TIMEOUT, 3);
if (@$candidate->real_connect($host, $user, $pass, $db, $port)) {
$conn = $candidate;
break;
}
$lastError = $candidate->connect_error ?: mysqli_connect_error();
}
if (!$conn) {
http_response_code(500);
die(json_encode(["error" => "Koneksi database gagal: " . $conn->connect_error]));
die(json_encode([
"status" => "error",
"msg" => "Koneksi database gagal. Host dicoba: " . implode(', ', $hosts) . ". Error: " . $lastError
]));
}
$conn->set_charset("utf8mb4");
+3
View File
@@ -9,4 +9,7 @@ COPY . /var/www/html/
RUN mkdir -p /var/www/html/05/uploads/bukti \
&& chown -R www-data:www-data /var/www/html
ENV DB_HOST=db \
DB_PORT=3306
EXPOSE 80
+30
View File
@@ -0,0 +1,30 @@
services:
app:
build: .
restart: unless-stopped
depends_on:
- db
command: sh -c "php /var/www/html/docker/initdb.php && apache2-foreground"
environment:
DB_HOST: db
DB_PORT: "3306"
DB_ROOT_PASSWORD: rootwebgis
DB_USER: webgis
DB_PASSWORD: webgis
DB_NAME_01: spbu_db
DB_NAME_02: webgis2
DB_NAME_04: spbu_db
DB_NAME_05: webgis_uas
expose:
- "80"
db:
image: mariadb:10.11
restart: unless-stopped
environment:
MARIADB_ROOT_PASSWORD: rootwebgis
volumes:
- webgis_db_data:/var/lib/mysql
volumes:
webgis_db_data:
+106
View File
@@ -0,0 +1,106 @@
<?php
mysqli_report(MYSQLI_REPORT_OFF);
$host = getenv('DB_HOST') ?: 'db';
$port = (int)(getenv('DB_PORT') ?: 3306);
$rootPass = getenv('DB_ROOT_PASSWORD') ?: 'rootwebgis';
$appUser = getenv('DB_USER') ?: 'webgis';
$appPass = getenv('DB_PASSWORD') ?: 'webgis';
function log_line($message) {
echo "[initdb] " . $message . PHP_EOL;
}
function connect_mysql($host, $user, $pass, $db = null, $port = 3306) {
$conn = mysqli_init();
$conn->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
if (@$conn->real_connect($host, $user, $pass, $db, $port)) {
$conn->set_charset('utf8mb4');
return $conn;
}
return null;
}
$conn = null;
$lastError = '';
for ($i = 1; $i <= 90; $i++) {
$conn = connect_mysql($host, 'root', $rootPass, null, $port);
if ($conn) {
break;
}
$lastError = mysqli_connect_error();
log_line("Menunggu database siap ($i/90): " . ($lastError ?: 'belum siap'));
sleep(2);
}
if (!$conn) {
log_line("Database tidak bisa dihubungi. Host=$host Port=$port Error=$lastError");
exit(1);
}
log_line('Database siap.');
$safeUser = $conn->real_escape_string($appUser);
$safePass = $conn->real_escape_string($appPass);
$conn->query("CREATE USER IF NOT EXISTS '{$safeUser}'@'%' IDENTIFIED BY '{$safePass}'");
$conn->query("GRANT ALL PRIVILEGES ON *.* TO '{$safeUser}'@'%'");
$conn->query("FLUSH PRIVILEGES");
function table_exists($conn, $db, $table) {
$db = $conn->real_escape_string($db);
$table = $conn->real_escape_string($table);
$result = $conn->query("SHOW TABLES FROM `{$db}` LIKE '{$table}'");
return $result && $result->num_rows > 0;
}
function import_sql_file($conn, $path, $label) {
if (!is_file($path)) {
log_line("Lewati {$label}: file tidak ditemukan {$path}");
return;
}
$sql = file_get_contents($path);
if ($sql === false || trim($sql) === '') {
log_line("Lewati {$label}: file kosong");
return;
}
log_line("Import {$label} dari {$path}");
if (!$conn->multi_query($sql)) {
log_line("Import {$label} gagal: " . $conn->error);
exit(1);
}
do {
if ($result = $conn->store_result()) {
$result->free();
}
if ($conn->errno) {
log_line("Import {$label} gagal: " . $conn->error);
exit(1);
}
} while ($conn->more_results() && $conn->next_result());
log_line("Import {$label} selesai.");
}
if (!table_exists($conn, 'spbu_db', 'spbu')) {
import_sql_file($conn, '/var/www/html/01/spbu_db.sql', 'spbu_db');
} else {
log_line('spbu_db sudah ada.');
}
if (!table_exists($conn, 'webgis2', 'jalan')) {
import_sql_file($conn, '/var/www/html/02/webgis2.sql', 'webgis2');
} else {
log_line('webgis2 sudah ada.');
}
if (!table_exists($conn, 'webgis_uas', 'rumah_ibadah')) {
import_sql_file($conn, '/var/www/html/05/webgis_uas.sql', 'webgis_uas');
} else {
log_line('webgis_uas sudah ada.');
}
log_line('Inisialisasi database selesai.');