- Sistem Informasi Perpustakaan CodeIgniter 4: Rancangan Aplikasi SIPUS
- Sistem Informasi Perpustakaan CodeIgniter 4: Setup dan Konfigurasi Database
MWI – Halo sobat pembelajar pada web MuSa. Tutorial CodeIgniter 4 perpustakaan merupakan langkah awal yang sangat baik bagi Anda yang ingin menguasai pengembangan aplikasi web modern dengan pola Model-View-Controller. Melalui seri pertama ini, Anda akan mempelajari persiapan lingkungan kerja, konfigurasi database MySQL, serta pembuatan struktur tabel menggunakan fitur migration dan seeder.
Daftar Isi
Mengenal Aplikasi SIPUS dan Keunggulannya
Aplikasi Sistem Informasi Perpustakaan Sekolah (SIPUS) dirancang untuk mengelola data koleksi buku, anggota, serta transaksi peminjaman secara terstruktur. Penggunaan framework CodeIgniter 4 memberikan performa yang cepat, struktur kode yang rapi, serta tingkat keamanan bawaan yang sangat andal.
Di samping itu, Anda juga akan memanfaatkan kerangka kerja Bootstrap 5 untuk membangun antarmuka pengguna yang responsif. Untuk mempelajari dasar-dasar sintaks dan fitur framework ini secara lebih mendalam, Anda dapat mengunjungi dokumentasi resmi CodeIgniter 4.
Instalasi dan Konfigurasi Framework CodeIgniter 4
Langkah pertama, buka terminal atau command prompt pada komputer Anda. Jalankan perintah composer berikut untuk mengunduh framework CodeIgniter 4 ke dalam folder htdocs atau www:
composer create-project codeigniter4/appstarter sipus
Setelah proses pengunduhan selesai, buka folder proyek sipus menggunakan editor kode pilihan Anda. Selanjutnya, ubah nama berkas env menjadi .env lalu atur konfigurasi database MySQL seperti berikut:
CI_ENVIRONMENT = development
database.default.hostname = localhost
database.default.database = sipus_db
database.default.username = root
database.default.password =
database.default.DBDriver = MySQLi
database.default.port = 3306
Membuat DB dan Migration Tabel Database
Langkah kedua, Kita perlu mempersiapkan database terdahulu dengan perintah
php spark db:create sipus_db
Lanjutkan dengan membuat struktur tabel database menggunakan fitur migration agar perubahan skema data terorganisasi dengan baik. Jalankan perintah CLI berikut untuk membuat berkas migration:
php spark make:migration CreateSipusTables
Buka berkas migration yang baru terbentuk di folder app/Database/Migrations, lalu tambahkan skema pembuatan tabel users, categories, books, dan members. 2026-10-16-000001_CreateSipusTables.php — membuat tujuh tabel beserta relasi.
<?php
namespace App\Database\Migrations;
use CodeIgniter\Database\Migration;
class CreateSipusTables extends Migration
{
public function up()
{
// 1. USERS
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'name' => ['type' => 'VARCHAR', 'constraint' => 100],
'email' => ['type' => 'VARCHAR', 'constraint' => 150],
'password_hash' => ['type' => 'VARCHAR', 'constraint' => 255],
'role' => ['type' => 'VARCHAR', 'constraint' => 20, 'default' => 'petugas'],
'is_active' => ['type' => 'TINYINT', 'constraint' => 1, 'unsigned' => true, 'default' => 1],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey('email');
$this->forge->createTable('users', true, ['ENGINE' => 'InnoDB']);
// 2. CATEGORIES
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'name' => ['type' => 'VARCHAR', 'constraint' => 100],
'description' => ['type' => 'TEXT', 'null' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey('name');
$this->forge->createTable('categories', true, ['ENGINE' => 'InnoDB']);
// 3. BOOKS
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'category_id' => ['type' => 'INT', 'unsigned' => true],
'code' => ['type' => 'VARCHAR', 'constraint' => 30],
'title' => ['type' => 'VARCHAR', 'constraint' => 200],
'author' => ['type' => 'VARCHAR', 'constraint' => 150],
'publisher' => ['type' => 'VARCHAR', 'constraint' => 150, 'null' => true],
'published_year' => ['type' => 'YEAR', 'null' => true],
'stock_total' => ['type' => 'INT', 'unsigned' => true, 'default' => 0],
'stock_available' => ['type' => 'INT', 'unsigned' => true, 'default' => 0],
'is_active' => ['type' => 'TINYINT', 'constraint' => 1, 'unsigned' => true, 'default' => 1],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey('code');
$this->forge->addKey('category_id');
$this->forge->addForeignKey('category_id', 'categories', 'id', 'CASCADE', 'RESTRICT');
$this->forge->createTable('books', true, ['ENGINE' => 'InnoDB']);
// 4. MEMBERS
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'member_code' => ['type' => 'VARCHAR', 'constraint' => 30],
'name' => ['type' => 'VARCHAR', 'constraint' => 150],
'class_name' => ['type' => 'VARCHAR', 'constraint' => 50, 'null' => true],
'phone' => ['type' => 'VARCHAR', 'constraint' => 30, 'null' => true],
'status' => ['type' => 'VARCHAR', 'constraint' => 20, 'default' => 'active'],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey('member_code');
$this->forge->addKey('status');
$this->forge->createTable('members', true, ['ENGINE' => 'InnoDB']);
// 5. LOANS
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'loan_code' => ['type' => 'VARCHAR', 'constraint' => 30],
'member_id' => ['type' => 'INT', 'unsigned' => true],
'user_id' => ['type' => 'INT', 'unsigned' => true],
'loan_date' => ['type' => 'DATE'],
'due_date' => ['type' => 'DATE'],
'status' => ['type' => 'VARCHAR', 'constraint' => 20, 'default' => 'active'],
'notes' => ['type' => 'TEXT', 'null' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey('loan_code');
$this->forge->addKey('member_id');
$this->forge->addKey('user_id');
$this->forge->addKey('status');
$this->forge->addForeignKey('member_id', 'members', 'id', 'CASCADE', 'RESTRICT');
$this->forge->addForeignKey('user_id', 'users', 'id', 'CASCADE', 'RESTRICT');
$this->forge->createTable('loans', true, ['ENGINE' => 'InnoDB']);
// 6. LOAN_DETAILS
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'loan_id' => ['type' => 'INT', 'unsigned' => true],
'book_id' => ['type' => 'INT', 'unsigned' => true],
'quantity' => ['type' => 'INT', 'unsigned' => true, 'default' => 1],
'created_at' => ['type' => 'DATETIME', 'null' => true],
'updated_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addUniqueKey(['loan_id', 'book_id']);
$this->forge->addKey('book_id');
$this->forge->addForeignKey('loan_id', 'loans', 'id', 'CASCADE', 'RESTRICT');
$this->forge->addForeignKey('book_id', 'books', 'id', 'CASCADE', 'RESTRICT');
$this->forge->createTable('loan_details', true, ['ENGINE' => 'InnoDB']);
// 7. LOAN_RETURNS
// Satu detail peminjaman dapat dikembalikan beberapa kali (partial return).
$this->forge->addField([
'id' => ['type' => 'INT', 'unsigned' => true, 'auto_increment' => true],
'loan_detail_id' => ['type' => 'INT', 'unsigned' => true],
'user_id' => ['type' => 'INT', 'unsigned' => true],
'quantity' => ['type' => 'INT', 'unsigned' => true],
'returned_at' => ['type' => 'DATETIME'],
'notes' => ['type' => 'TEXT', 'null' => true],
'created_at' => ['type' => 'DATETIME', 'null' => true],
]);
$this->forge->addKey('id', true);
$this->forge->addKey('loan_detail_id');
$this->forge->addKey('user_id');
$this->forge->addForeignKey('loan_detail_id', 'loan_details', 'id', 'CASCADE', 'RESTRICT');
$this->forge->addForeignKey('user_id', 'users', 'id', 'CASCADE', 'RESTRICT');
$this->forge->createTable('loan_returns', true, ['ENGINE' => 'InnoDB']);
}
public function down()
{
// Drop dari tabel anak ke tabel induk karena terdapat foreign key.
$this->db->disableForeignKeyChecks();
$this->forge->dropTable('loan_returns', true);
$this->forge->dropTable('loan_details', true);
$this->forge->dropTable('loans', true);
$this->forge->dropTable('members', true);
$this->forge->dropTable('books', true);
$this->forge->dropTable('categories', true);
$this->forge->dropTable('users', true);
$this->db->enableForeignKeyChecks();
}
}
Eksekusi perintah php spark migrate pada terminal untuk menerapkan skema tersebut ke dalam database MySQL Anda.
php spark migrate
php spark migrate:status
Mengisi Data Awal Menggunakan Seeder
Langkah ketiga, buatlah berkas seeder untuk mengisikan akun pengguna awal serta data kategori bawaan menggunakan perintah berikut:
php spark make:seeder SipusSeeder
SipusSeeder.php — menyiapkan akun admin, kategori, buku, dan anggota contoh.
<?php
namespace App\Database\Seeds;
use CodeIgniter\Database\Seeder;
use RuntimeException;
class SipusSeeder extends Seeder
{
public function run()
{
// Password wajib ditentukan di .env agar tidak ada password default tersembunyi.
$adminPassword = env('SIPUS_ADMIN_PASSWORD');
if (! is_string(adminPassword)||strlen(adminPassword) < 12) {
throw new RuntimeException(
'Atur SIPUS_ADMIN_PASSWORD di .env (minimal 12 karakter) sebelum menjalankan seeder.'
);
}
$users = $this->db->table('users');
$adminEmail = 'admin@sipus.local';
if (! $users->where('email', $adminEmail)->get()->getRowArray()) {
$users->insert([
'name' => 'Administrator SIPUS',
'email' => $adminEmail,
'password_hash' => password_hash($adminPassword, PASSWORD_DEFAULT),
'role' => 'admin',
'is_active' => 1,
'created_at' => date('Y-m-d H:i:s'),
]);
}
$categories = [
['name' => 'Fiksi', 'description' => 'Novel, cerpen, dan karya fiksi.'],
['name' => 'Pendidikan', 'description' => 'Buku pelajaran dan materi pembelajaran.'],
['name' => 'Sains', 'description' => 'Ilmu pengetahuan alam dan teknologi.'],
];
foreach ($categories as $category) {
$exists = $this->db->table('categories')
->where('name', $category['name'])
->get()->getRowArray();
if (! $exists) {
this->db->table('categories')->insert(category);
}
}
$categoryRows = $this->db->table('categories')->get()->getResultArray();
$categoryIds = [];
foreach ($categoryRows as $category) {
categoryIds[category['name']] = $category['id'];
}
$books = [
[
'category_id' => $categoryIds['Fiksi'],
'code' => 'BK-0001',
'title' => 'Laskar Pelangi',
'author' => 'Andrea Hirata',
'publisher' => 'Bentang Pustaka',
'published_year' => 2005,
'stock_total' => 4,
'stock_available' => 4,
'is_active' => 1,
],
[
'category_id' => $categoryIds['Pendidikan'],
'code' => 'BK-0002',
'title' => 'Matematika SMA',
'author' => 'Tim Penyusun',
'publisher' => 'Penerbit Contoh',
'published_year' => 2024,
'stock_total' => 5,
'stock_available' => 5,
'is_active' => 1,
],
[
'category_id' => $categoryIds['Sains'],
'code' => 'BK-0003',
'title' => 'Pengantar Ilmu Sains',
'author' => 'Tim Penyusun',
'publisher' => 'Penerbit Contoh',
'published_year' => 2023,
'stock_total' => 3,
'stock_available' => 3,
'is_active' => 1,
],
];
foreach ($books as $book) {
$exists = $this->db->table('books')
->where('code', $book['code'])
->get()->getRowArray();
if (! $exists) {
$book['created_at'] = date('Y-m-d H:i:s');
this->db->table('books')->insert(book);
}
}
$members = [
[
'member_code' => 'AG-0001',
'name' => 'Andi Pratama',
'class_name' => 'X-1',
'phone' => '081200000001',
'status' => 'active',
],
[
'member_code' => 'AG-0002',
'name' => 'Siti Rahma',
'class_name' => 'X-2',
'phone' => '081200000002',
'status' => 'active',
],
[
'member_code' => 'AG-0003',
'name' => 'Budi Santoso',
'class_name' => 'XI-1',
'phone' => '081200000003',
'status' => 'inactive',
],
];
foreach ($members as $member) {
$exists = $this->db->table('members')
->where('member_code', $member['member_code'])
->get()->getRowArray();
if (! $exists) {
$member['created_at'] = date('Y-m-d H:i:s');
this->db->table('members')->insert(member);
}
}
}
}
Jalankan perintah php spark db:seed UserSeeder untuk memasukkan data awal ke dalam database.
php spark db:seed SipusSeeder
Akhirnya, persiapan awal tutorial CodeIgniter 4 perpustakaan telah selesai dan siap dilanjutkan ke tahap pembuatan master data pada artikel berikutnya. (ms)