# Panduan Instalasi KabarNikah

Versi aplikasi: 1.0.0 · Basis data: SQLite · Bahasa server: PHP 8.2+ (diuji pada PHP 8.3.6)

## 1. Isi paket `KabarNikah_Siap_Upload.zip`

```
public_html/        → isi folder ini diletakkan di document root domain (folder publik)
kabarnikah/         → folder PRIVAT aplikasi (kode, konfigurasi, basis data, unggahan)
  ├─ bin/           → skrip cron: maintenance.php, wa-dispatch.php
  ├─ config/        → config.php dibuat otomatis oleh installer
  ├─ migrations/    → skema basis data (diterapkan otomatis)
  ├─ src/, views/, templates/
  ├─ storage/       → basis data, foto, bukti transfer, cadangan, log (harus dapat ditulis PHP)
  └─ tests/run.php  → tes otomatis (opsional)
dokumen/            → seluruh panduan dan laporan
```

Tidak ada akun admin bawaan, kata sandi bawaan, kunci pembayaran, atau data pelanggan di dalam paket. Semuanya diisi sendiri saat instalasi dan di panel admin.

## 2. Persyaratan server

| Kebutuhan | Minimal | Catatan |
|---|---|---|
| PHP | 8.2 | Diuji 8.3.6 |
| Ekstensi PHP | pdo_sqlite, sodium, gd, zip, xmlreader, mbstring, curl, fileinfo | `intl` opsional (format tanggal). GD dengan WebP disarankan |
| SQLite | 3.27 | Dibutuhkan untuk `VACUUM INTO` (cadangan konsisten) |
| Web server | Apache + mod_rewrite (`.htaccess` disertakan) atau Nginx (contoh di bawah) | |
| HTTPS | Wajib untuk produksi | Cookie sesi otomatis `Secure` bila HTTPS |
| Batas unggah | `upload_max_filesize` & `post_max_size` ≥ 8 MB (disarankan 16–20 MB) | `memory_limit` ≥ 256 MB untuk olah foto besar |
| Cron | Disarankan | Untuk pembersihan, cadangan harian, dan (opsional) pengirim WhatsApp |

Fitur WhatsApp membutuhkan server OpenWA terpisah (VPS/Docker). Lihat `PANDUAN_OPENWA.md`. Tanpa OpenWA, seluruh fitur lain tetap berjalan.

## 3. Unggah berkas

**Cara yang disarankan (folder privat di luar document root):**

```
/home/NAMAAKUN/
├─ public_html/     ← isi dari public_html/ di ZIP
└─ kabarnikah/      ← folder kabarnikah/ dari ZIP
```

`public_html/index.php` otomatis mencari folder privat di `../kabarnikah`. Alternatif:
- Variabel lingkungan `KABARNIKAH_PRIVATE=/jalur/lengkap/kabarnikah` (mis. di konfigurasi PHP-FPM).
- Bila hosting tidak mengizinkan folder di luar document root: letakkan sebagai `public_html/kabarnikah/`. Folder itu ditolak oleh `.htaccess` (aturan `RewriteRule ^kabarnikah(/|$) - [F,L]`) dan admin dapat memastikannya di **Admin → Pemeriksaan Sistem → Uji akses folder privat**. Cara ini kurang aman dibanding di luar document root.

Izin berkas (sesuaikan dengan pengguna PHP di hosting):

```bash
chmod -R 750 kabarnikah/storage kabarnikah/config
```

Instalasi di subfolder (mis. `https://domain.com/undangan/`) didukung: unggah isi `public_html/` ke subfolder tersebut dan isi alamat lengkap pada installer.

## 4. Menjalankan installer

1. Buka `https://domain-anda/install`.
2. Installer membuat berkas **`kabarnikah/storage/install-code.txt`**. Buka berkas itu lewat File Manager/SSH; **kode instalasi ada di baris kedua**.
3. Isi: kode instalasi, alamat situs lengkap (contoh `https://undangan.domainanda.com`), nama, email, dan kata sandi admin (minimal 10 karakter; sandi umum seperti `1234567890` ditolak).
4. Simpan. Installer membuat `config/config.php` (berisi kunci aplikasi acak), menjalankan migrasi, mengisi katalog 4 desain, membuat admin pertama, lalu mengunci diri (`storage/installed.lock`) dan menghapus kode instalasi.
5. Setelah terkunci, `/install` mengembalikan 404. Untuk memasang ulang di server uji, hapus `config/config.php`, `storage/installed.lock`, dan `storage/db/` (seluruh data hilang).

Batas percobaan: 10 kali per 15 menit untuk kode yang salah.

## 5. Cron (tugas berkala)

Ganti `/usr/bin/php` dan jalur sesuai hosting:

```
*/10 * * * *  /usr/bin/php /home/NAMAAKUN/kabarnikah/bin/maintenance.php cleanup
15 2 * * *    /usr/bin/php /home/NAMAAKUN/kabarnikah/bin/maintenance.php backup
```

- `cleanup`: menghapus berkas impor kedaluwarsa, nonce worker lama, sesi kedaluwarsa, menandai invoice lewat tenggat, dan mencoba ulang email antre.
- `backup`: cadangan harian (basis data + kunci aplikasi). Tambahkan `--media` untuk ikut menyalin foto (lebih besar).
- Pengirim WhatsApp: gunakan worker Node (disarankan) **atau** cron PHP setiap menit:
  `* * * * * /usr/bin/php /home/NAMAAKUN/kabarnikah/bin/wa-dispatch.php`

Perintah lain: `php kabarnikah/bin/maintenance.php check` (pemeriksaan sistem di terminal), `worker-secret` (menampilkan rahasia worker), `migrate`.

## 6. Konfigurasi Nginx (bila tidak memakai Apache)

```nginx
server {
    server_name undangan.domainanda.com;
    root /home/NAMAAKUN/public_html;
    index index.php;
    client_max_body_size 24m;

    location ^~ /kabarnikah/ { deny all; return 404; }
    location ~ /\.            { deny all; return 404; }
    location ~* \.(sqlite|db|log|lock|bak|sql|env|zip)$ { deny all; return 404; }

    location ~ ^/(assets|tpl)/ { try_files $uri =404; expires 30d; add_header Cache-Control "public"; }
    location / { try_files $uri /index.php?$query_string; }
    location = /index.php {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root/index.php;
        fastcgi_pass unix:/run/php/php8.3-fpm.sock;
    }
    location ~ \.php$ { return 404; }
}
```

## 7. Setelah instalasi

Masuk sebagai admin lalu ikuti **Pengaturan awal** di `PANDUAN_ADMIN.md` (rekening transfer, konfirmasi hak aset desain, harga, SMTP, kontak bantuan, kebijakan). Selama langkah itu belum selesai, produk tidak dapat dibeli dan halaman **Ringkasan** admin menampilkan peringatan.

## 8. Memperbarui aplikasi

1. Buat cadangan (Admin → Cadangan) dan unduh.
2. Ganti seluruh berkas **kecuali** `kabarnikah/config/config.php` dan `kabarnikah/storage/`.
3. Buka situs sekali: migrasi baru diterapkan otomatis (dikunci agar hanya berjalan sekali).

## 9. Uji lokal (opsional)

```bash
cd public_html
php -d upload_max_filesize=20M -d post_max_size=24M -S 127.0.0.1:8080 -t . router-dev.php
```

Tes otomatis (menyalin aplikasi ke folder sementara, memasang ulang, menjalankan 111 pemeriksaan; tidak mengubah data Anda):

```bash
php kabarnikah/tests/run.php
```

## 10. Masalah umum

| Gejala | Penyebab & solusi |
|---|---|
| "Folder aplikasi kabarnikah tidak ditemukan" | Folder privat tidak di `../kabarnikah`. Pindahkan, atau setel `KABARNIKAH_PRIVATE`. |
| Halaman 500 setelah unggah | Periksa versi PHP dan ekstensi (`php kabarnikah/bin/maintenance.php check`). Log ada di `kabarnikah/storage/logs/`. |
| Unggah foto gagal "melebihi batas" | Naikkan `upload_max_filesize`/`post_max_size`. |
| Email tidak terkirim | SMTP belum diisi; lihat Admin → Email (status "SMTP belum diatur"). |
| Tampilan tanpa gaya setelah update | Bersihkan cache browser/CDN; aset diberi versi. |
| Pemeriksaan sistem: "BAHAYA: berkas storage dapat diunduh" | `.htaccess` tidak aktif (AllowOverride None) atau Nginx tanpa aturan `deny`. Perbaiki sebelum menerima pelanggan. |
