Nama Proyek: Sistem Manajemen Donor Darah PMI
Tujuan: Mengelola data pendonor, stok darah, transaksi donasi, kegiatan donasi, dan distribusi darah secara terpusat dan terorganisir
Teknologi: PHP 7.4+, MySQL, Bootstrap 5, PDO (Database Abstraction), Query Builder Custom
Bahasa: Bahasa Indonesia
Aplikasi ini menyediakan modul-modul utama untuk mengelola sistem PMI:
-
Authentication (Autentikasi)
- Login/Logout untuk petugas
- Session management
- Password hashing dengan BCRYPT
-
Dashboard
- Overview stok darah real-time
- Statistik jumlah kantong per golongan darah
- Status stok (tersedia, terpakai, kadaluarsa)
-
Manajemen Pendonor
- Registrasi pendonor baru
- Data screening kesehatan pendonor
- Riwayat donasi per pendonor
- Edit/delete pendonor
-
Manajemen Transaksi Donasi
- Input data donasi dari kegiatan
- Automatic stok creation setelah pengujian darah
- Status uji (lolos/tidak lolos)
- Tracking tanggal donasi
-
Manajemen Stok Darah
- Lihat stok darah per golongan
- Update status uji dan tanggal kadaluarsa
- Soft delete dan arsip
- Real-time status (tersedia, terpakai, kadaluarsa)
-
Manajemen Distribusi
- Input penerimaan darah oleh rumah sakit
- Tracking status distribusi (diajukan, diterima, selesai)
-
Manajemen Kegiatan Donasi
- CRUD kegiatan donasi
- Soft delete kegiatan
-
Manajemen Petugas (Admin)
- Profile management (edit nama, email, password)
- User roles (saat ini semua petugas same role)
TUBES-PL/
├── Config/
│ ├── Database.php # Koneksi database PDO
│ └── Path.php # Helper untuk path file
├── Controllers/
│ ├── PetugasController.php # Logic authentication & profile
│ ├── PendonorController.php # Logic pendonor CRUD
│ ├── TransaksiController.php # Logic transaksi donasi
│ ├── StokController.php # Logic stok darah
│ ├── DistribusiController.php # Logic distribusi
│ └── LaporanController.php # Logic laporan
├── Model/
│ ├── QueryBuilder.php # Custom query builder (ORM sederhana)
│ ├── PetugasModel.php # Query pendonor ke DB
│ ├── PendonorModel.php # Query pendonor ke DB
│ ├── TransaksiModel.php # Query transaksi ke DB
│ ├── StokModel.php # Query stok ke DB
│ ├── DistribusiModel.php # Query distribusi ke DB
│ ├── KegiatanModel.php # Query kegiatan ke DB
│ └── LaporanModel.php # Query laporan ke DB
├── View/
│ ├── dashboard/
│ │ └── index.php # Dashboard home page
│ ├── petugas/
│ │ ├── login.php # Login form
│ │ ├── profile.php # Profile page
│ │ └── edit.php # Edit profile
│ ├── pendonor/
│ │ ├── index.php # List pendonor
│ │ ├── create.php # Form tambah pendonor
│ │ ├── edit.php # Form edit pendonor
│ │ ├── detail.php # Detail pendonor
│ │ ├── riwayat.php # History donasi pendonor
│ │ └── trash.php # Daftar pendonor terhapus
│ ├── transaksi/
│ │ ├── index.php # List transaksi
│ │ ├── create.php # Form input transaksi
│ │ ├── edit.php # Form edit transaksi
│ │ ├── detail.php # Detail transaksi
│ │ ├── lacak.php # Tracking transaksi
│ │ └── trash.php # Transaksi terhapus
│ ├── stok/
│ │ ├── index.php # List stok darah
│ │ ├── create.php # Form buat stok (disabled)
│ │ ├── edit.php # Form edit stok (disabled)
│ │ ├── detail.php # Detail stok + input status uji
│ │ ├── trash.php # Stok terhapus
│ │ └── update_group.php # Batch update stok
│ ├── distribusi/
│ │ ├── index.php # List distribusi
│ │ ├── create.php # Form distribusi baru
│ │ ├── create_grouped.php # Distribusi grouped
│ │ ├── edit.php # Edit distribusi
│ │ ├── detail.php # Detail distribusi
│ │ ├── lacak.php # Tracking distribusi
│ │ └── trash.php # Distribusi terhapus
│ ├── kegiatan/
│ │ ├── index.php # List kegiatan
│ │ ├── create.php # Form tambah kegiatan
│ │ ├── edit.php # Form edit kegiatan
│ │ ├── detail.php # Detail kegiatan
│ │ └── trash.php # Kegiatan terhapus
│ ├── rumah_sakit/
│ │ ├── index.php # List rumah sakit
│ │ ├── create.php # Form tambah RS
│ │ ├── edit.php # Form edit RS
│ │ ├── detail.php # Detail RS
│ │ ├── laporan.php # Laporan distribusi RS
│ │ └── trash.php # RS terhapus
│ └── template/
│ ├── header.php # Header navbar
│ ├── footer.php # Footer
│ ├── alerts.php # Flash message component
│ ├── pagination.php # Pagination component
│ ├── toast.php # Toast notification
│ ├── auth_header.php # Header untuk halaman login
│ ├── auth_footer.php # Footer untuk halaman login
│ └── assets/
│ ├── css/
│ │ ├── ui.css # Styling PMI theme
│ │ └── custom-overrides.css # Custom color overrides
│ ├── js/
│ │ └── ui.js # JavaScript utilities
│ └── img/ # Logo dan image
├── seeds/
│ └── DATABASE.sql # SQL schema & initial data
├── index.php # Router utama (entry point)
├── api_delete.php # API untuk soft delete
└── README.md # Documentation (file ini)
Controller: LaporanController.php
-
Lokasi:
Controllers/LaporanController.php -
Tujuan: Menyediakan endpoint/view untuk laporan dan evaluasi data (kinerja donor, evaluasi stok, dan laporan distribusi). Controller ini bersifat read-only (mengambil data melalui Model dan menampilkan View) — tidak melakukan perubahan data di database.
-
Dependency:
TransaksiModel,StokModel,DistribusiModel, serta koneksi DB melaluiConfig/Database.php. -
Metode utama:
-
viewKinerjaDonor()- Input:
$_GET['periode'](format YYYY-MM), default current month jika tidak disediakan. - Action: memanggil
TransaksiModel::getLaporanKinerjaDonor($periode)untuk mengambil metrik kinerja donor pada periode tersebut. - Output: memanggil View
View/laporan/kinerja_donor.phpdengan array['laporan' => ..., 'periode' => $periode].
- Input:
-
viewEvaluasiStok()- Input: tidak ada parameter wajib.
- Action: mengambil data stok realtime dan daftar stok kadaluarsa melalui
StokModel::getDashboardStokRealtime()danStokModel::getStokKadaluarsa(). - Output: memanggil View
View/laporan/evaluasi_stok.phpdengan array['stok' => ..., 'stok_kadaluarsa' => ...].
-
generateLaporanDistribusi()- Input:
$_GET['rs_id'](opsional),$_GET['tanggal_awal'],$_GET['tanggal_akhir']. Default ke rentang bulan berjalan bila tidak disediakan. - Action: memanggil
DistribusiModel::getLaporanDistribusi($rs_id, $tanggal_awal, $tanggal_akhir)untuk mengambil baris distribusi sesuai filter; juga mengambil daftar rumah sakit untuk dropdown/label viagetRumahSakit(). - Output: memanggil View
View/laporan/distribusi.phpdengan data filter dan hasil laporan.
- Input:
-
-
Catatan implementasi:
- Semua metode memanggil helper private
view($view, $data = [])yang mengekstrak$datadan menyertakan file viewView/laporan/$view.php. - Controller ini tidak memodifikasi data (INSERT/UPDATE/DELETE) — hanya mengumpulkan data untuk reporting.
- Jika Anda menambahkan format export (CSV/PDF), itu biasanya diimplementasikan sebagai metode tambahan di controller ini.
- Semua metode memanggil helper private
User (Browser)
↓ [GET/POST to index.php?action=...]
index.php (Router)
↓ [Match action parameter]
Controller (e.g., PendonorController)
↓ [Process request, call Model methods]
Model (e.g., PendonorModel)
↓ [Execute query via QueryBuilder → PDO]
Database (MySQL)
↓ [Return query result]
Model
↓ [Return data array]
Controller
↓ [Extract data, include View file]
View (PHP template)
↓ [Render HTML + send to browser]
User (Browser)
1. User open index.php?action=login
→ view/petugas/login.php (form login)
2. User submit form (POST)
→ index.php?action=authenticate
→ PetugasController::authenticate()
→ Query DB cari email & verify password
→ Set $_SESSION['isLoggedIn'] = true
→ Redirect ke dashboard
3. User akses halaman lain
→ Controller checkAuth() → Check $_SESSION['isLoggedIn']
→ Jika tidak login, redirect ke login page
4. User logout
→ index.php?action=logout
→ session_destroy()
→ Redirect ke login
1. Input transaksi donasi (nama pendonor, tanggal, etc)
→ TransaksiController::store()
→ Insert ke tabel transaksi_donasi
→ Redirect ke stok detail form
2. Petugas isi hasil pengujian (status uji, tanggal kadaluarsa)
→ StokController::storeInputPascaUji()
→ Create stok baru di tabel stok_darah
→ Insert history transaksi_donasi_detail
3. Stok now tersedia untuk distribusi
┌─────────────────────────────────────────────────────────────────────────────┐
│ SISTEM MANAJEMEN DONOR DARAH │
└─────────────────────────────────────────────────────────────────────────────┘
┌──────────────────┐
│ GOLONGAN_DARAH │
│ (Master Data) │
├──────────────────┤
│ id_gol_darah (PK)│
│ nama_gol_darah │
│ rhesus (+/-) │
└────────┬─────────┘
│ (1:M)
┌──────────────────┼──────────────────┐
│ │ │
↓ ↓ ↓
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ PENDONOR │ │ STOK_DARAH │ │ TRANSAKSI_DONASI│
├──────────────────┤ ├──────────────────┤ ├──────────────────┤
│ id_pendonor (PK) │ │ id_stok (PK) │ │id_transaksi (PK) │
│ nama (UNIQUE) │ │ id_gol_darah (FK)│ │ id_pendonor (FK) │
│ kontak │ │ id_transaksi(FK) │ │ id_kegiatan (FK) │
│ is_layak (0/1) │ │ status_uji │ │ tanggal_donasi │
│ screening fields │ │ tanggal_pengujian│ │ volume │
│ is_deleted │ │ tgl_kadaluarsa │ │ is_deleted │
└──────────┬───────┘ │ status (status) │ └────────┬─────────┘
│ │ is_deleted │ │
│ └────────┬─────────┘ │
│ │ │
└─────────┬─────────┴────────────────────┘
│
┌─────────┴─────────┐
│ │
↓ ↓
┌──────────────────┐ ┌──────────────────┐
│ KEGIATAN_DONASI │ │ DISTRIBUSI │
├──────────────────┤ ├──────────────────┤
│id_kegiatan (PK) │ │id_distribusi (PK)│
│ nama_kegiatan │ │ id_stok (FK) │
│ tanggal │ │ id_rs (FK) │
│ lokasi │ │ tgl_pengajuan │
│ is_deleted │ │ status (status) │
└──────────────────┘ │ jml_kantong │
│ is_deleted │
└────────┬─────────┘
│ (M:1)
│
┌─────────────┴──────────┐
│ │
↓ ↓
┌──────────────────┐ ┌──────────────────┐
│ RUMAH_SAKIT │ │ PETUGAS │
├──────────────────┤ ├──────────────────┤
│ id_rs (PK) │ │id_petugas (PK) │
│ nama_rs │ │ nama_petugas │
│ alamat_rs │ │ email (UNIQUE) │
│ kontak_rs │ │ password_hash │
│ is_deleted │ │ kontak │
└──────────────────┘ │ status │
│ is_deleted │
└──────────────────┘
Keterangan Hubungan (Relationships):
| From Table | To Table | Type | Keterangan |
|---|---|---|---|
| GOLONGAN_DARAH | PENDONOR | 1:M | Satu golongan darah memiliki banyak pendonor |
| GOLONGAN_DARAH | STOK_DARAH | 1:M | Satu golongan darah memiliki banyak stok |
| PENDONOR | TRANSAKSI_DONASI | 1:M | Satu pendonor bisa melakukan banyak transaksi donasi |
| KEGIATAN_DONASI | TRANSAKSI_DONASI | 1:M | Satu kegiatan memiliki banyak transaksi donor |
| TRANSAKSI_DONASI | STOK_DARAH | 1:M | Satu transaksi bisa menghasilkan banyak stok (per kantong) |
| STOK_DARAH | DISTRIBUSI | 1:M | Satu stok darah bisa didistribusikan ke banyak RS |
| RUMAH_SAKIT | DISTRIBUSI | 1:M | Satu rumah sakit menerima banyak distribusi darah |
START
↓
Petugas buka Menu Pendonor → Tambah Pendonor
↓
Form Pendaftaran Pendonor muncul
↓
Input data pendonor:
├─ Nama (REQUIRED)
├─ Kontak (REQUIRED - minimum 6 digit)
├─ Golongan Darah (REQUIRED)
├─ Riwayat Penyakit (optional)
├─ Screening Kesehatan:
│ ├─ Hepatitis B/C
│ ├─ AIDS
│ ├─ Hemofilia
│ ├─ Sickle Cell
│ ├─ Thalassemia
│ ├─ Leukemia
│ ├─ Lymphoma
│ ├─ Myeloma
│ ├─ CJD
│ └─ Other Illness (text)
↓
Sistem hitung: is_layak = (tidak ada penyakit) ? 1 : 0
↓
Save ke tabel PENDONOR
↓
Success message
↓
Redirect ke list Pendonor
↓
END
START
↓
Petugas buka Menu Transaksi Donasi → Tambah Transaksi
↓
Form Input Transaksi:
├─ Pilih Pendonor (dari PENDONOR table)
├─ Pilih Kegiatan (dari KEGIATAN_DONASI table)
├─ Tanggal Donasi
└─ Volume (ml)
↓
Validasi:
├─ Pendonor harus is_layak = 1
└─ Pendonor tidak boleh ulang < 3 bulan
↓
INSERT ke TRANSAKSI_DONASI table
↓
Redirect ke STOK Detail Input Page
↓
Petugas isi hasil pengujian darah:
├─ Status Uji (Lolos / Tidak Lolos)
├─ Tanggal Pengujian
└─ Tanggal Kadaluarsa
↓
Validasi: Tgl Kadaluarsa > Tgl Pengujian
↓
System CREATE stok baru:
├─ INSERT ke STOK_DARAH
│ ├─ id_gol_darah = dari pendonor
│ ├─ id_transaksi = dari transaksi yang baru dibuat
│ ├─ status_uji = lolos/tidak lolos
│ ├─ status = "tersedia" (default)
│ └─ jumlah_kantong = 1
↓
Success message
↓
Stok sekarang tersedia untuk DISTRIBUSI
↓
END
START
↓
Petugas buka Menu Distribusi → Tambah Distribusi
↓
Form Input Distribusi:
├─ Pilih Stok Darah (dari STOK_DARAH yang status="tersedia")
├─ Pilih Rumah Sakit (dari RUMAH_SAKIT table)
└─ Jumlah Kantong
↓
Validasi: Stok tersedia >= Jumlah yang diminta
↓
INSERT ke DISTRIBUSI table:
├─ id_stok = stok yang dipilih
├─ id_rs = rumah sakit yang dipilih
├─ status = "diajukan"
├─ tgl_pengajuan = hari ini
└─ jml_kantong = jumlah
↓
UPDATE STOK_DARAH:
├─ status = "terpakai" (jika semua kantong distributed)
└─ atau create 2 stok (1 terpakai, 1 tersisa)
↓
Success message
↓
Rumah Sakit bisa update status distribusi:
├─ "diajukan" → "diterima" (RS terima darah)
└─ "diterima" → "selesai" (RS selesai gunakan darah)
↓
END
START (User buka Dashboard)
↓
System auto-check STOK_DARAH table:
├─ Update stok yang sudah kadaluarsa:
│ └─ IF tanggal_kadaluarsa < hari_ini THEN status = "kadaluarsa"
↓
Query dan COUNT stok per golongan darah:
├─ Total kantong per golongan
├─ Count tersedia (status="tersedia")
├─ Count terpakai (status="terpakai")
└─ Count kadaluarsa (status="kadaluarsa")
↓
Display dashboard dengan:
├─ Card per golongan darah (O+, O-, A+, dll)
├─ Warna coding:
│ ├─ Green = tersedia
│ ├─ Yellow = terpakai
│ └─ Red = kadaluarsa
└─ Total summary di atas
↓
END
MASTER DATA (Static References)
├─ GOLONGAN_DARAH (Jenis darah)
├─ PETUGAS (Staff login)
└─ RUMAH_SAKIT (Hospital list)
TRANSACTION DATA (Dynamic)
├─ PENDONOR (Donor registry)
│ └─ depends on: GOLONGAN_DARAH
├─ KEGIATAN_DONASI (Donation event)
│ └─ independent (dapat dibuat kapan saja)
└─ TRANSAKSI_DONASI (Donation transaction)
├─ depends on: PENDONOR, KEGIATAN_DONASI
└─ creates: STOK_DARAH (auto-generate stok)
PROCESSING DATA (After Transaction)
├─ STOK_DARAH (Blood inventory)
│ ├─ depends on: TRANSAKSI_DONASI, GOLONGAN_DARAH
│ └─ used by: DISTRIBUSI
└─ DISTRIBUSI (Distribution record)
├─ depends on: STOK_DARAH, RUMAH_SAKIT
└─ tracks: delivery status
Tujuan: Mengelola koneksi database
Jika ingin mengubah database:
- Buka file:
Config/Database.phpbaris 14-17 - Ubah:
$host= alamat server database$db_name= nama database$username= username database$password= password database
Contoh:
private $host = "localhost";
private $db_name = "pmi_darah"; // Ganti nama database di sini
private $username = "root";
private $password = "";Tujuan: Helper untuk path ke View dan Template
Jika ingin menambah path baru:
- Buka file:
Config/Path.php - Tambah method static baru:
public static function uploads($path) {
return __DIR__ . '/../uploads/' . $path;
}Tujuan: Mengelola authentication dan profil petugas
Bagian yang sering diubah saat ujian:
-
Login & Password Verification (baris 155-185)
- Query email dari database
- Verify password dengan
password_verify() - Set session jika berhasil
Jika diminta: Ubah validasi password, tambah 2FA, atau custom message
-
Authentication Check (baris 224-231)
- Helper method yang dipanggil di awal setiap action
- Memastikan user sudah login
Jika diminta: Tambah role-based access control
Tujuan: Memudahkan query database dengan ORM sederhana
Contoh penggunaan:
// SELECT dengan WHERE, JOIN, ORDER BY
$builder = new QueryBuilder($pdo, 'stok_darah sd');
$result = $builder->select('sd.*, gd.nama_gol_darah')
->join('golongan_darah gd', 'sd.id_gol_darah = gd.id_gol_darah')
->where('sd.status', 'tersedia')
->orderBy('sd.tanggal_kadaluarsa', 'ASC')
->getResultArray();
// INSERT
$builder = new QueryBuilder($pdo, 'pendonor');
$builder->insert([
'nama' => 'John Doe',
'kontak' => '081234567890',
'id_gol_darah' => 1
]);
// UPDATE dengan WHERE
$builder = new QueryBuilder($pdo, 'stok_darah');
$builder->where('id_stok', $id)
->update(['status' => 'terpakai']);Method yang tersedia:
select($columns)- SELECT querywhere($column, $value, $operator)- WHERE condition (AND)orWhere($column, $value, $operator)- WHERE condition (OR)whereRaw($condition)- Raw WHERE (gunakan dengan hati-hati)join($table, $condition, $type)- JOIN clausegroupBy($column)- GROUP BY clausehaving($condition)- HAVING clauseorderBy($column, $direction)- ORDER BY clauseinsert($data)- INSERT queryupdate($data)- UPDATE querygetResultArray()- Fetch multiple rowsgetRowArray()- Fetch single rowexecute()- Execute non-SELECT query
Tujuan: CRUD Pendonor + Screening kesehatan
Bagian yang sering diubah:
-
Input Pendonor Baru (baris 44-134)
- Validasi input (nama, kontak, golongan darah)
- Filter kontak hanya angka
- Check screening fields (penyakit)
- Calculate
is_layak(eligible/tidak)
Jika diminta: Tambah field screening baru, ubah validasi, atau ubah rules eligibility
-
Screening Fields (baris 67-80)
- Deteksi penyakit-penyakit tertentu
- Hanya donor tanpa penyakit yang layak donasi
Jika diminta: Tambah/hapus jenis screening, atau ubah logic eligibility
-
Edit Pendonor (baris 168-259)
- Update semua field termasuk screening
- Recalculate
is_layakbased on screening
Tujuan: Manajemen stok darah
Bagian yang sering diubah:
-
Dashboard Real-time (baris 26-31)
- Auto-update expired statuses
- Get stok by blood type & rhesus
- Show counts: available, used, expired
Jika diminta: Ubah query untuk custom reports, atau tambah filter
-
Stock Detail & Input Hasil Uji (baris 51-120)
- Display stok information
- Input status uji (lolos/tidak lolos)
- Input tanggal pengujian & kadaluarsa
Jika diminta: Tambah field test details, atau ubah status options
-
Delete Stock (baris 77-85)
- Soft delete (tidak benar-benar dihapus)
Jika diminta: Implement hard delete, atau add confirmation
Tujuan: Query stok darah dari database
Fungsi-fungsi utama:
getDashboardStokRealtime()- Get stok count per golongan darahgetStokTersedia()- Get all available (non-expired) stockgetStokById($id)- Get detail stok dengan join ke golongan & transaksiupdateStatusStok($id, $status)- Update status (tersedia/terpakai/kadaluarsa)updateExpiredStatuses()- Auto-update stok yang sudah kadaluarsacreateStokPascaUji($id_transaksi, $data)- Create stok after testing
Jika diminta: Ubah query untuk custom logic
- Navbar dengan brand & navigation menu
- User profile dropdown
- CSS & JS includes
- Material Symbols font
Jika diminta: Ubah navbar, tambah menu item, atau custom styling
- Flash message component
- Show success/danger/warning/info messages
Jika diminta: Custom styling messages, atau tambah message types
- Footer content
- Copyright info
id_petugas(PK)nama_petugasemail(UNIQUE)password_hash(BCRYPT)kontakstatus(aktif/nonaktif)is_deleted(soft delete)
id_pendonor(PK)namakontak(number only)riwayat_penyakit(text)id_gol_darah(FK)has_hepatitis_b,has_hepatitis_c, ... (screening fields)other_illness(text)is_layak(1/0)is_deleted(soft delete)
id_transaksi(PK)id_pendonor(FK)id_kegiatan(FK)tanggal_donasivolume(ml)is_deleted(soft delete)
id_stok(PK)id_transaksi(FK)id_gol_darah(FK)tanggal_pengujianstatus_uji(lolos/tidak lolos)tanggal_kadaluarsastatus(tersedia/terpakai/kadaluarsa)jumlah_kantongis_deleted(soft delete)
id_gol_darah(PK)nama_gol_darah(O, A, B, AB)rhesus(+/-)
id_distribusi(PK)id_stok(FK)id_rs(FK)tanggal_pengajuanstatus(diajukan/diterima/selesai)jumlah_kantong
id_kegiatan(PK)nama_kegiatantanggallokasiis_deleted(soft delete)
id_rs(PK)nama_rsalamat_rskontak_rsis_deleted(soft delete)
- File:
Controllers/PendonorController.php(baris 73-87) - Ubah rules, tambah/hapus validasi field
- File:
Model/StokModel.php,Model/PendonorModel.php - Ubah WHERE conditions, JOIN tables, atau ORDER BY
- File:
Controllers/StokController.php,Controllers/PendonorController.php - Ubah calculation rules (e.g., is_layak), atau add new features
- File:
seeds/DATABASE.sql - Ubah/tambah kolom ke table
- Jangan lupa update Model & Controller untuk new columns
- File:
View/directory (all .php files) - Ubah form fields, table columns, atau styling
- File:
index.php(switch statement) - Tambah/ubah action routes
- PHP 7.4+
- MySQL 5.7+
- Laragon / XAMPP / or local PHP server
-
Clone atau copy project ke folder web root
cd C:\laragon\www\ git clone <repo-url> TUBES-PL # atau copy folder jika tidak menggunakan git
-
Setup Database
- Buka phpMyAdmin (http://localhost/phpmyadmin)
- Create database baru dengan nama
pmi_darah - Import file:
seeds/DATABASE.sql
-- Atau jalankan dari command line: mysql -u root pmi_darah < seeds/DATABASE.sql
-
Verifikasi Config
- Buka
Config/Database.php - Pastikan credentials sesuai (host, username, password)
- Buka
-
Run Aplikasi
- Buka browser:
http://localhost/TUBES-PL/ - Atau
http://127.0.0.1/TUBES-PL/
- Buka browser:
-
Login
- Email: (lihat di seed data)
- Password: (lihat di seed data atau setup akun baru)
- Selalu gunakan
password_hash()denganPASSWORD_BCRYPT - Jangan pernah simpan password plain text
- Verify dengan
password_verify()
- Gunakan QueryBuilder dengan prepared statements (parameter binding)
- Jangan gabung user input langsung ke SQL string
- Check
$_SESSION['isLoggedIn']di setiap protected page - Destroy session saat logout
- Gunakan
is_deletedflag (1/0) untuk logical delete - Jangan hard delete data
- Use
try-catchuntuk exception handling - Log errors ke
error_log()untuk debugging
- Validate dan sanitize semua user input (
$_POST,$_GET) - Use
trim(),htmlspecialchars(), atau filter functions
- Error:
Connection error: SQLSTATE[...] - Solution:
- Pastikan MySQL server running
- Cek
Config/Database.phpcredentials - Cek database name di
$db_name
- Error:
View tidak ditemukan: ... - Solution:
- Pastikan file view ada di folder
View/ - Cek path in Controller
$this->view()
- Pastikan file view ada di folder
- Error: Redirect ke login terus-menerus
- Solution:
- Pastikan
session_start()dipanggil - Check
$_SESSIONvalues di login form
- Pastikan
- Error:
QueryBuilder Error: ... - Solution:
- Check prepared statement syntax
- Pastikan parameters count sesuai dengan
?placeholders
- Solution:
- Check
error_log()file (usually diC:\laragon\logs\) - Enable
error_reporting(E_ALL)untuk debug mode
- Check
- Pahami alur request-response di
index.php - Baca seluruh Controller & Model files
- Understand QueryBuilder syntax dan prepared statements
- Practice membuat form & tambah field baru
- Backup database schema
- Baca soal dengan teliti - pahami requirement dengan detail
- Identifikasi file mana yang perlu diubah - gunakan flow diagram di atas
- Ubah file secara bertahap:
- Database (jika perlu tambah kolom)
- Model (ubah query)
- Controller (ubah logic)
- View (ubah form/table)
- Test setiap perubahan - jangan tunda-tunda
- Gunakan comment - catat perubahan & alasan
Soal: Tambahkan field "No. Identitas" di form pendonor
Solusi:
-
Buka
seeds/DATABASE.sql- Tambah kolom:
ALTER TABLE pendonor ADD COLUMN no_identitas VARCHAR(20);
- Tambah kolom:
-
Buka
View/pendonor/create.php- Tambah input field:
<input name="no_identitas" class="form-control" required>
- Tambah input field:
-
Buka
Controllers/PendonorController.phpmethodstore()(baris 44+)- Ambil input:
'no_identitas' => $_POST['no_identitas'] - Tambahkan ke
$dataarray
- Ambil input:
-
Buka
View/pendonor/index.php- Tambah kolom di table:
<th>No. Identitas</th> - Tambah data di loop:
<td><?= htmlspecialchars($pendonor['no_identitas']) ?></td>
- Tambah kolom di table:
-
Test & verify
Untuk pertanyaan lebih lanjut:
- Baca dokumentasi di file-file (ada komentar detail)
- Check DATABASE.sql untuk schema
- Lihat View files untuk contoh form/table structure
Dokumentasi ini ditulis dengan bahasa Indonesia formal-akademik untuk memudahkan pemahaman dan penggunaan saat ujian praktik.
Terakhir diperbaharui: Desember 2025