"kak, gimana sih caranya membuat fitur CRUD menggunakan CodeIgniter 4?". Itulah salah satu pertanyaan yang ditanyakan oleh salah satu member dari grup programmer yang saya ikuti. Ya, belakangan ini di salah satu grup programmer yang saya ikuti sedang ramai membahas tentang CodeIgniter 4. Dan saat ini framework tersebut sudah masuk versi rc.3 lho (per tanggal 19 oktober 2019, dan sekarang sudah masuk versi 4.1.1). Tentu hal ini betul-betul membuat saya tertarik untuk ngulik dan membuat beberapa aplikasi sederhana yang sudah menerapkan operasi CRUD dengan menggunakan CodeIgniter 4. Setelah mencoba beberapa kali, akhirnya saya menuliskan dokumentasinya dalam bentuk tutorial CodeIgniter 4 dan sekaligus sebagai jawaban dari pertanyaan bagaimana sih caranya membuat fitur CRUD di CodeIgniter 4 dan apa saja langkah-langkahnya.

Pada tutorial CodeIgniter 4 ini kita akan belajar beberapa hal terkait operasi CRUD. Sebagai pengingat, crud adalah singkatan dari create, read, update, dan delete. Karena ada keempat operasi tersebut, tentu dalam tutorial ini kita akan belajar penggunaan model yang ada di codeigniter 4. Selain operasi CRUD, kita juga akan belajar bagaimana cara menggunakan migration dan juga templating UI secara sekilas.

Seperti di seri tutorial lainnya, di edisi kali ini kita juga akan membuat sebuah aplikasi sederhana. Dan studi kasus untuk tutorial CRUD CodeIgniter 4 ini adalah membuat blog sederhana untuk mengelola post. Dan fiturnya pun tentu sesuai dengan tujuan tutorial ini, yaitu:

  • Fitur untuk menampilkan daftar post,
  • Fitur untuk membuat post baru,
  • Fitur untuk memperbaharui post,
  • Dan fitur untuk menghapus post.

Lalu, apa saja langkah-langkah dalam membuat fitur CRUD di CodeIgniter 4? Check this out, ya! Daftar Isi

  1. Step 1 Persiapan Development
  2. Step 2 Instalasi CodeIgniter 4
  3. Step 3 Konfigurasi Project
  4. Step 4 Membuat Database
  5. Step 5 Membuat file migration
  6. Step 6 Membuat template UI
  7. Step 7 Fitur Menampilkan Daftar Post
  8. Step 8 Fitur Membuat Post Baru
  9. Step 9 Fitur Update Post
  10. Step 10 Fitur Hapus Post
  11. Step 11 Uji Coba Project
  12. Kesimpulan
  13. Referensi

Step 1 Persiapan Development

Menurut Dokumentasi Resminya1, ada beberapa requirement untuk menggunakan CodeIgniter 4, check this out ya!

  1. PHP yang digunakan adalah versi 7.2 atau yang terbaru, dengan 'intl' extension.
  2. Ekstensi php-json
  3. Ekstensi php-mbstring
  4. Ekstensi php-mysqlnd
  5. Ekstensi php-xml
  6. libcurl untuk kebutuhan CURLRequest

Catatan: lupa install ekstensi intl ini menjadi salah satu penyebab error dan sering ditanyakan di forum programmer, jadi pastikan kawan-kawan sudah install ekstensinya ya..

Dan untuk database, ada beberapa database yang sudah didukung oleh CodeIgniter:

  1. MySQL (5.1+) via MySQLi driver
  2. PostgreSQL via Postgre driver
  3. SQLite3 via SQLite3 driver

Di tutorial ini, kita akan menggunakan MYSQL untuk database-nya dan, untuk proses instalasi kita juga akan menggunakan composer (recommended). Jadi pastikan composer sudah terinstall. Kalau belum diinstall boleh baca tutorial install composer terlebih dahulu.

Step 2 Instalasi CodeIgniter 4

Langkah pertama adalah instalasi CodeIgniter 4. Ada beberapa cara untuk instal CodeIgniter 4, yang pertama secara manual dan yang kedua adalah menggunakan composer. Karena ada banyak manfaat yang sudah saya rasakan setelah menggunakan composer, jadi saya lebih merekomendasikan instalasi menggunakan composer.

Untuk menginstal CodeIgniter 4 menggunakan composer. Kita buka terminal atau cmd terlebih dahulu, lalu kita jalankan command:

composer create-project codeigniter4/appstarter blog

Tunggu sampai proses instalasi menggunakan composer selesai.

Nah, setelah instalasi CodeIgniter 4 selesai, selanjutnya masuk ke folder project dengan command:

cd blog

Selanjutnya kita coba cek apakah CodeIgniter 4 sudah berhasil kita install. Kita coba running project kita menggunakan server built-in untuk development dengan menggunakan command:

php spark serve

Buka browser lalu kita buka url http://localhost:8080. Kita bisa lihat tampilan awal dari CodeIgniter 4.

Step 3 Konfigurasi Project

Selanjutnya kita akan mengatur beberapa konfigurasi seperti environment project, base url, dan konfigurasi database. Buat file .env dengan menggunakan command:

cp env .env

Maksud command di atas adalah mengcopy-paste file env yang ada di project kita lalu direname dengan nama .env. Ya, kawan.. selain menggunakan terminal kita bisa langsung buat file .env secara manual juga.

Selanjutnya kita buka project kita di text editor. Nah kita bisa lihat ada file .env yang baru saja kita buat. Selanjutnya buka file .env, lalu kita temukan kode berikut ini:

# CI_ENVIRONMENT = production

# app.baseURL = ''

# database.default.hostname = localhost
# database.default.database = ci4
# database.default.username = root
# database.default.password = root
# database.default.DBDriver = MySQLi

Kita sesuaikan konfigurasinya menjadi seperti di bawah ini.

CI_ENVIRONMENT = development

app.baseURL = 'http://localhost:8080/'

database.default.hostname = localhost
database.default.database = blog
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi

Catatan: di baris kode di atas, Variable CI_ENVIRONMENT ini digunakan untuk mengatur enviroment project kita. Karena kita masih dalam tahap development, jadi kita atur menjadi development. Selain itu ada juga variable untuk konfigurasi database. Untuk database.default.password, teman-teman sesuaikan dengan password akun mysql masing-masing. Jika menggunakan XAMPP, biasanya passwordnya kosong atau tidak diisi seperti yang tertulis di baris kode di atas.

Step 4 Membuat Database

Oke langkah selanjutnya, kita buat dulu database dengan nama seperti yang ada di file .env yaitu database blog. Buka phpMyAdmin, lalu buat database baru dengan nama blog.

Step 5 Membuat file migration

Langkah selanjutnya adalah membuat table baru untuk menyimpan data post. Nah, berbeda dengan edisi tutorial sebelumnya, kali ini kita akan belajar menggunakan fitur migration punya CodeIgniter 42 lho!

Pada langkah ini, kita buat file migration untuk membuat table posts. Buka kembali terminal / cmd, lalu jalankan command berikut ini untuk membuat file migration:

php spark migrate:create Posts

Output:

CodeIgniter v4.4.1 Command Line Tool - Server Time: 2023-10-08 02:41:21 UTC+00:00

File created: APPPATH/Database/Migrations/2023-10-08-024121_Posts.php

Selanjutnya kita bisa lihat file baru yang dibuat command di atas di direktori app/Database/Migrations dan memiliki nama dengan format YYYY-MM-DD-HHIISS_namatable.php misalnya 2020-01-28-043908_Posts.php sesuai dengan timestamp ketika filenya dibuat. Buka file 2020-01-28-043908_Posts.php lalu sesuaikan kodenya menjadi seperti berikut ini:

<?php namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class Posts extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type' => 'INT',
                'unsigned' => TRUE,
                'auto_increment' => TRUE
            ],
            'title' => [
                'type' => 'VARCHAR',
                'constraint' => 128,
                'null' => FALSE,
            ],
            'content' => [
                'type' => 'TEXT',
                'null' => FALSE
            ],
            'slug' => [
                'type' => 'VARCHAR',
                'constraint' => 128,
                'null' => FALSE
            ],
            'status' => [
                'type' => 'INT',
                'constraint' => 1,
                'null' => FALSE
            ],
            'created_at' => [
                'type' => 'datetime',
                'null' => TRUE
            ],
            'updated_at' => [
                'type' => 'datetime',
                'null' => TRUE
            ],
            'deleted_at' => [
                'type' => 'datetime',
                'null' => TRUE
            ]
        ]);

        $this->forge->addKey('id', TRUE);
        $this->forge->createTable('posts');

    }

    //--------------------------------------------------------------------

    public function down()
    {
        $this->forge->dropTable('posts');
    }
}

Selanjutnya kita run perintah migrate di terminal atau cmd. Buka terminal atau cmd lalu jalankan command:

php spark migrate

Output:

CodeIgniter v4.4.1 Command Line Tool - Server Time: 2023-10-08 02:42:08 UTC+00:00

Running all new migrations...
    Running: (App) 2023-10-08-024121_App\Database\Migrations\Posts
Migrations complete.

Ketika kita cek di phpMyAdmin, kita bisa melihat terdapat dua table baru di database blog, ada table migrations dan table posts sesuai dengan file migration yang sudah kita ketik sebelumnya.

Step 6 Membuat template UI

CodeIgniter mendukung sistem layout yang mudah dan fleksibel, sehingga dapat digunakan untuk lebih dari satu layout tampilan halaman untuk project kita. Nah di langkah ini kita akan menggunakan sistem layout milik CodeIgniter untuk membuat template UI. Selain itu kita juga akan menggunakan Bootsrap 4 untuk UI project kita.

Nah sekarang kita buat folder baru di direktori app/Views dengan nama layouts. Lalu buat file baru di dalam folder tersebut (app/Views/layouts) dengan nama main.php. Lalu ketik kode berikut ini ya..

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <meta name="<?= csrf_token() ?>" content="<?= csrf_hash() ?>">
    <title><?= $title; ?></title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
</head>

<body>

    <!-- Content -->
    <?= $this->renderSection('content') ?>

    <!-- /.Content -->

    <footer class="text-center mt-5">
        <p><em><small>Seri Tutorial CodeIgniter 4: CRUD CodeIgniter @ <a href="https://qadrlabs.com/">qadrLabs</a></small></em></p>
    </footer>
    <script src="https://code.jquery.com/jquery-3.4.1.slim.min.js" integrity="sha384-J6qa4849blE2+poT4WnyKhv5vZF5SrPo0iEjwBvKU7imGFAV0wwj1yYfoRSJoZ+n" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/umd/popper.min.js" integrity="sha384-Q6E9RHvbIyZFJoft+2mJbHaEWldlvI9IOYy5n3zV9zzTtmI3UksdQRVvoxMfooAo" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/js/bootstrap.min.js" integrity="sha384-wfSDF2E50Y2D1uUdj0O3uMBJnjuUD4Ih7YwaYd1iqfktj0Uod8GCExl3Og8ifwB6" crossorigin="anonymous"></script>

    <?= $this->renderSection('extra-js') ?>

</body>

</html>

Di dalam code di atas, terdapat code $this->renderSection('content') dan juga $this->renderSection('extra-js'). code tersebut nantinya akan kita gunakan untuk me-render tampilan untuk masing-masing content dan extra-js untuk me-render section khusus javascript.

Step 7 Fitur Menampilkan Daftar Post

Fitur yang akan kita buat adalah fitur untuk menampilkan daftar Post. Pertama kita buat file model dengan nama PostModel.php di direktori app/Models. Lalu ketik code berikut ini:


<?php

namespace App\Models;

use CodeIgniter\Model;

class PostModel extends Model
{
    protected $table = 'posts';

}

Selanjutnya buat sebuah Controller baru dengan nama Post.php di direktori app/Controllers. Lalu ketik code di bawah ini:

<?php namespace App\Controllers;

use App\Models\PostModel;

class Post extends BaseController
{
    /**
     *
     * @var Model
     */
    protected $model;

    public function __construct()
    {
        $this->model = new PostModel();
        $this->helpers = ['form', 'url'];

    }

    public function index()
    {
        $data = [
            'posts' => $this->model->paginate(10),
            'pager' => $this->model->pager,
            'title' => 'POST LIST'
        ];

        return view('posts/index', $data);
    }

}

Di method index() terdapat code return view('posts/index', $data); itu artinya method tersebut me-render sebuah view dengan nama index.php yang ada di direktori app/Views/posts.

Nah langkah selanjutnya kita buat folder baru sesuai dengan view yang dirender di method index(). Buat folder baru dengan nama posts (pake s ya..) di direktori app/Views. Lalu buat file baru dengan nama index.php di dalam folder yang baru saja dibuat. Selanjutnya yuk kita ketik kode ini:

<?= $this->extend('layouts/main') ?>

<?= $this->section('content') ?>

<div class="container mt-5">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">
                    POST
                    <a href="<?php echo base_url('post/create'); ?>" class="btn btn-primary btn-sm float-right">New Record</a>
                </div>
                <div class="card-body">

                    <?php if (session()->getFlashdata('success')) { ?>
                        <div class="alert alert-success">
                            <?php echo session()->getFlashdata('success'); ?>
                        </div>
                    <?php } ?>

                    <?php if (session()->getFlashdata('error')) { ?>
                        <div class="alert alert-danger">
                            <?php echo session()->getFlashdata('error'); ?>
                        </div>
                    <?php } ?>

                    <table class="table table-bordered">
                        <thead class="text-center">
                            <tr>
                                <th scope="col">Title</th>
                                <th scope="col">Status</th>
                                <th scope="col">Created Date</th>
                                <th scope="col">Action</th>
                            </tr>
                        </thead>
                        <tbody class="text-center">
                            <?php if (!empty($posts) && is_array($posts)) { ?>
                                <?php foreach ($posts as $row) { ?>
                                    <tr>
                                        <td><?php echo $row['title']; ?></td>
                                        <td><?php echo ($row['status'] == 2) ? 'Publish':'Draft'; ?></td>
                                        <td><?= $row['created_at'] ?></td>
                                        <td>

                                            <form onsubmit="return confirm('Apakah Anda Yakin ?');"  
                                                action="<?php echo base_url('post/destroy/' . $row['id']); ?>" method="POST">  

                                                <input type="hidden" name="{csrf_token}" value="{csrf_hash}">
                                                <input type="hidden" name="_method" value="DELETE"> 

                                                <a href="<?php echo base_url('post/edit/' . $row['id']); ?>" class="btn btn-primary btn-sm">Edit</a>

                                                <button type="submit" class="btn btn-danger btn-sm">Delete</button>  
                                            </form>  
                                        </td>
                                    </tr>

                                <?php } ?>
                            <?php } else { ?>
                                <tr>
                                    <td colspan="4" class="text-center">No post found.</td>
                                </tr>

                            <?php } ?>
                        </tbody>
                    </table>

                    <?= $pager->links(); ?>
                </div>

            </div>
        </div>
    </div>
</div>

<?= $this->endSection() ?>

<?= $this->section('extra-js') ?>
<script>
    $(document).ready(function() {
        $('.pagination li').addClass('page-item');
        $('.pagination li a').addClass('page-link');
    })
</script>
<?= $this->endSection() ?>

Oke, fitur untuk menampilkan daftar post sudah selesai. Nah supaya ketika halaman daftar post ini pertama kali ditampilkan ketika project kita running di browser, kita harus atur dulu route untuk default controller-nya.

Jadi kita atur route-nya supaya controller Post sebagai controller default ketika project kita running. Buka file app/Config/Routes.php, lalu cek baris kode ke-75 (kurang lebih). Temukan kode seperti ini:


$routes->get('/', 'Home::index');

Lalu kita ubah menjadi:

$routes->get('/', 'Post::index');

Karena pada real project jarang ada yang menampilkan data berupa table di halaman pertama, sebagai pembelajaran kita tambahkan route kedua untuk menampilkan data post.

$routes->get('/', 'Post::index');
$routes->get('/post', 'Post::index');

Untuk running project, buka cmd atau terminal lalu jalankan command:

php spark serve

Lalu buka url http://localhost:8080 di browser, maka project kita akan menampilkan halaman daftar post.

Okee, kita lanjut coding fitur selanjutnya...

Step 8 Fitur Membuat Post Baru

Selanjutnya kita buat fitur untuk menambahkan postingan baru. Buka kembali file model PostModel.php, lalu kita tambahkan beberapa properties di dalam class PostModel:


<?php

namespace App\Models;

use CodeIgniter\Model;

class PostModel extends Model
{
    protected $table = 'posts';
    protected $allowedFields = ['title', 'slug' , 'content', 'status'];
    protected $useTimestamps = true;
    protected $createdField = 'created_at';
    protected $updatedField = 'updated_at';
    protected $deletedField = 'deleted_at';

    protected $validationRules = [
        'title' => 'required|min_length[10]|max_length[100]',
        'content' => 'required',
        'status' => 'required'
    ];

    protected $skipValidation = false;

}

Selanjutnya, buka kembali file controller Post.php, lalu tambahkan method create() di dalam class Post.

  // [CODE SEBELUMNYA]

    public function create()
    {
        $data = ['title' => 'Create new post'];

        return view('posts/create', $data);
    }

  // [CODE SELANJUTNYA]

Selanjutnya kita buat file baru dengan nama create.php di dalam direktori app/Views/posts. Yuk kita ketik kode ini...

<?= $this->extend('layouts/main') ?>

<?= $this->section('content') ?>

<div class="container mt-5">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">
                    <?= $title ?>
                </div>
                <div class="card-body">

                    <?php if (session()->getFlashdata('success')) { ?>
                        <div class="alert alert-success">
                            <?php echo session()->getFlashdata('success'); ?>
                        </div>
                    <?php } ?>

                    <?php if (session()->getFlashdata('error')) { ?>
                        <div class="alert alert-danger">
                            <?php echo session()->getFlashdata('error'); ?>
                        </div>
                    <?php } ?>

                    <?= form_open('post/store'); ?>
                    <div class="form-group">
                        <label for="title">Title</label>
                        <input type="text" name="title" class="form-control" required>
                    </div>
                    <div class="form-group">
                        <label for="content">Content</label>
                        <textarea name="content" id="post_content" class="form-control" required></textarea>
                    </div>
                    <div class="form-group">
                        <label for="status">Status</label>
                        <select name="status" id="" class="form-control">
                            <option value="1" selected>Draft</option>
                            <option value="2">Publish</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-primary">Save</button>
                        <a href="<?= base_url('post') ?>" class="btn btn-link">Back</a>
                    </div>
                    <?= form_close(); ?>
                </div>

            </div>
        </div>
    </div>
</div>

<?= $this->endSection() ?>

<?= $this->section('extra-js') ?>
<!-- include summernote css/js -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.js"></script>
<script>
    $(document).ready(function() {
        $('#post_content').summernote({
            tabsize: 2,
            height: 500
        });
    })
</script>
<?= $this->endSection() ?>

Selanjutnya kita tambahkan method untuk menyimpan data post ke database. Buka kembali file controller Post.php. Kita tambahkan method store() untuk menangani proses insert data ke dalam table posts.


  // ... [CODE SEBELUMNYA]

    public function store()
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title(strtolower($title)),
        ];

        $save = $this->model->save($post);

        if ($save) {
            session()->setFlashdata('success', 'Post has been added successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }

  }

  // ... [CODE SELANJUTNYA]

Sehingga keseluruhan file Post.php menjadi:

<?php namespace App\Controllers;

use App\Models\PostModel;

class Post extends BaseController
{
    /**
     *
     * @var Model
     */
    protected $model;

    public function __construct()
    {
        $this->model = new PostModel();
        $this->helpers = ['form', 'url'];

    }
    public function index()
    {
        $data = [
            'posts' => $this->model->paginate(10),
            'pager' => $this->model->pager,
            'title' => 'POST LIST'
        ];

        return view('posts/index', $data);
    }

    public function create()
    {
        $data = ['title' => 'Create new post'];

        return view('posts/create', $data);

    }

    public function store()
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title(strtolower($title)),
        ];

        $save = $this->model->save($post);

        if ($save) {
            session()->setFlashdata('success', 'Post has been added successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }

    }

}

Selanjutnya kita tambahkan route baru untuk create dan store data post. Buka kembali file app/Config/Routes.php, lalu kita tambahkan route baru.

$routes->get('/post/create', 'Post::create');
$routes->post('/post/store', 'Post::store');

Save kembali file app/Config/Routes.php.

Step 9 Fitur Update Post

Selanjutnya kita tambahkan fitur untuk memperbaharui data post ke dalam project kita. Buka kembali file controller Post.php. Lalu kita tambahkan method edit() di dalam class Post. Yuk kita ketik lagi kodenya... ^^

    public function edit($id)
    {
        $post = $this->model->find($id);

        if (empty($post)) {
            session()->setFlashdata('error','Post not found');
            return redirect()->back();
        }

        $data = [
            'title' => 'Edit Post',
            'post' => $post
        ];

        return view('posts/edit', $data);

    }

Dan seperti biasa kita buat file untuk view-nya. Kita buat file edit.php di dalam direktori app/Views/posts, lalu kita ketik baris code di bawah ini.

<?= $this->extend('layouts/main') ?>

<?= $this->section('content') ?>

<div class="container mt-5">
    <div class="row">
        <div class="col-md-12">
            <div class="card">
                <div class="card-header">
                    <?= $title ?>
                </div>
                <div class="card-body">

                    <?php if (session()->getFlashdata('success')) { ?>
                        <div class="alert alert-success">
                            <?php echo session()->getFlashdata('success'); ?>
                        </div>
                    <?php } ?>

                    <?php if (session()->getFlashdata('error')) { ?>
                        <div class="alert alert-danger">
                            <?php echo session()->getFlashdata('error'); ?>
                        </div>
                    <?php } ?>

                    <?= form_open('post/update/'. $post['id']); ?>
                    <input type="hidden" name="_method" value="PUT">

                    <div class="form-group">
                        <label for="title">Title</label>
                        <input type="text" name="title" value="<?= $post['title'];?>" class="form-control" required>
                    </div>
                    <div class="form-group">
                        <label for="content">Content</label>
                        <textarea name="content" id="post_content" class="form-control" required><?= $post['content'];?></textarea>
                    </div>
                    <div class="form-group">
                        <label for="status">Status</label>
                        <select name="status" id="" class="form-control">
                            <option value="1" <?php echo ($post['status'] == 1) ? 'selected':'';?>>Draft</option>
                            <option value="2" <?php echo ($post['status'] == 2) ? 'selected':'';?>>Publish</option>
                        </select>
                    </div>
                    <div class="form-group">
                        <button class="btn btn-primary">Update</button>
                        <a href="<?= base_url('post') ?>" class="btn btn-link">Back</a>
                    </div>
                    <?= form_close(); ?>

                </div>

            </div>
        </div>
    </div>
</div>

<?= $this->endSection() ?>

<?= $this->section('extra-js') ?>
<!-- include summernote css/js -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/summernote-bs4.min.js"></script>
<script>
    $(document).ready(function() {
        $('#post_content').summernote({
            tabsize: 2,
            height: 500
        });
    })
</script>
<?= $this->endSection() ?>

Selanjutnya kita tambahkan code untuk memperbaharui data yang ada di database. Buka kembali file controller Post.php lalu kita tambahkan method update() di dalam class Post.

    public function update($id)
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title($title)
        ];

        $update = $this->model->update($id, $post);

        if ($update) {
            session()->setFlashdata('success', 'Post has been updated successfully');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }
    }

Sehingga keseluruhan file controller Post.php menjadi:

<?php namespace App\Controllers;

use App\Models\PostModel;

class Post extends BaseController
{
    /**
     *
     * @var Model
     */
    protected $model;

    public function __construct()
    {
        $this->model = new PostModel();
        $this->helpers = ['form', 'url'];

    }
    public function index()
    {
        $data = [
            'posts' => $this->model->paginate(10),
            'pager' => $this->model->pager,
            'title' => 'POST LIST'
        ];

        return view('posts/index', $data);
    }

    public function create()
    {
        $data = ['title' => 'Create new post'];

        return view('posts/create', $data);

    }

    public function store()
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title(strtolower($title)),
        ];

        $save = $this->model->save($post);

        if ($save) {
            session()->setFlashdata('success', 'Post has been added successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }

    }

    public function edit($id)
    {
        $post = $this->model->find($id);

        if (empty($post)) {
            session()->setFlashdata('error','Post not found');
            return redirect()->back();
        }

        $data = [
            'title' => 'Edit Post',
            'post' => $post
        ];

        return view('posts/edit', $data);

    }

    public function update($id)
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title($title)
        ];

        $update = $this->model->update($id, $post);

        if ($update) {
            session()->setFlashdata('success', 'Post has been updated successfully');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }
    }

}

Selanjutnya kita daftarkan route untuk menangani proses menampilkan form update dan proses update. Buka kembali file app/Config/Routes.php, lalu tambahkan route berikut ini.

$routes->get('/post/edit/(:num)', 'Post::edit/$1');
$routes->put('/post/update/(:num)', 'Post::update/$1');

Save kembali file app/Config/Routes.php.

Step 10 Fitur Hapus Post

Fitur terakhir adalah fitur untuk menghapus data post di project kita. Buka kembali file controller Post.php, lalu kita tambahkan method destroy() di dalam class Post.

    public function destroy($id)
    {

        if (empty($id)) {
            return redirect()->to(base_url('post'));
        }

        $delete = $this->model->delete($id);

        if ($delete) {
            session()->setFlashdata('success', 'Post has been removed successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->to(base_url('post'));
        }

    }

Sehingga keseluruhan file controller Post.php menjadi:

<?php namespace App\Controllers;

use App\Models\PostModel;

class Post extends BaseController
{
    /**
     *
     * @var Model
     */
    protected $model;

    public function __construct()
    {
        $this->model = new PostModel();
        $this->helpers = ['form', 'url'];

    }
    public function index()
    {
        $data = [
            'posts' => $this->model->paginate(10),
            'pager' => $this->model->pager,
            'title' => 'POST LIST'
        ];

        return view('posts/index', $data);
    }

    public function create()
    {
        $data = ['title' => 'Create new post'];

        return view('posts/create', $data);

    }

    public function store()
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title(strtolower($title)),
        ];

        $save = $this->model->save($post);

        if ($save) {
            session()->setFlashdata('success', 'Post has been added successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }

    }

    public function edit($id)
    {
        $post = $this->model->find($id);

        if (empty($post)) {
            session()->setFlashdata('error','Post not found');
            return redirect()->back();
        }

        $data = [
            'title' => 'Edit Post',
            'post' => $post
        ];

        return view('posts/edit', $data);

    }

    public function update($id)
    {
        $title = $this->request->getPost('title');
        $content = $this->request->getPost('content');
        $status = $this->request->getPost('status');

        $post = [
            'title' => $title,
            'content' => $content,
            'status' => $status,
            'slug' => url_title($title)
        ];

        $update = $this->model->update($id, $post);

        if ($update) {
            session()->setFlashdata('success', 'Post has been updated successfully');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->back();
        }
    }

    public function destroy($id)
    {

        if (empty($id)) {
            return redirect()->to(base_url('post'));
        }

        $delete = $this->model->delete($id);

        if ($delete) {
            session()->setFlashdata('success', 'Post has been removed successfully.');
            return redirect()->to(base_url('post'));
        } else {
            session()->setFlashdata('error', 'Some problems occured, please try again.');
            return redirect()->to(base_url('post'));
        }

    }

}

Sekarang kita daftarkan route terakhir untuk menghapus data. Buka kembali file app/Config/Routes.php, lalu kita tambahkan route baru.

$routes->delete('/post/destroy/(:num)', 'Post::destroy/$1');

Step 11 Uji Coba Project

Langkah terakhir dari tutorial ini kita coba running aplikasi kita, lalu kita cek satu persatu fitur yang sudah kita coding di langkah-langkah sebelumnya. Untuk running project kita, buka terminal atau cmd lalu jalankan command berikut ini:

php spark serve

Buka browser, lalu buka project kita di url http://localhost:8080. Ya, tampilan yang pertama kali muncul adalah tampilan daftar post.

Uji coba project

Selanjutnya kita coba buat post baru, tekan tombol New Record yang ada di atas tabel post.

Ya, muncul tampilan post dan juga di sini kita gunakan summernote untuk menulis artikel baru.

Uji coba project

Nah sekarang kita coba ketik post baru, kita tulis bebas aja.

Uji coba project

Lalu kita tekan tombol save.

Nah, ketika berhasil, project akan kembali ke halaman daftar post dan juga ada notifikasi post berhasil disimpan. ^^

Uji coba project

Selanjutnya kita coba tambahkan beberapa postingan sampai sebelas (11) postingan atau lebih. Yep, ketika data kita udah lebih dari sepuluh, kita bisa lihat adanya pagination di bawah table daftar post kita.

Uji coba project

Oke, selanjutnya kita coba perbaharui data salah satu post. Tekan tombol edit di salah satu data. Maka akan tampil halaman form untuk edit post.

Kita coba edit isi postnya dan statusnya kita coba ubah menjadi publish.

Uji coba project

Lalu kita tekan tombol update. Nah ketika data berhasil diperbaharui, project kita akan menampilkan kembali daftar post dan juga ada notifikasi data post berhasil diperbaharui.

Uji coba project

Nah selanjutnya kita coba fitur terakhir, yaitu hapus data post. Tekan tombol Delete di salah satu data post. Ketika tombol Delete ditekan, akan muncul pop up tulisan 'Kamu yakin?'. Tekan tombol ok dan apabila data berhasil dihapus, project akan menampilkan kembali daftar post dan juga notifikasi bahwa datanya berhasil dihapus.

Uji coba project

Uji coba project

Kesimpulan

Di tutorial ini kita sudah belajar tentang membuat fitur CRUD menggunakan CodeIgniter 4. Ada beberapa perbedaan yang menarik ketika kita membuat fitur CRUD ini dibandingkan dengan CRUD CodeIgniter versi 3.x.x. Salah satu contohnya adalah kita tidak perlu menuliskan method yang diperlukan untuk fitur CRUD di dalam file model kita, seperti save, update, delete dan untuk pagination juga sudah ditangani oleh model3.

Selain itu secara sekilas kita juga sudah belajar bagaimana cara menggunakan fitur Migration, templating UI menggunakan CodeIgniter 4 dan jangan lupa. Untuk explore lebih lanjut, kamu bisa cek dokumentasi resmi CodeIgniter 4 di bagian Referensi. Semoga bermanfaat.. ^^

Sampai jumpa lagi di edisi tutorial berikutnya... ^^

Gun Gun Priatna
Software Engineer, Content Writer and Founder qadrlabs.com
Komentar

blog comments powered by Disqus