Codeigniter 4 – Mencatat Aktivitas User dalam CRUD

بِسْمِ اللَّهِ Mudah-mudahan tutorial Codeigniter 4 – Mencatat Aktivitas User dalam CRUD ini bermanfaat

Tutorial kali ini saya akan membuat log atau aktivitas pekerjaan User dalam operasi CRUD yang akan disimpan ke dalam database. Sebenarnya log ini bisa dijadikan satu dengan tabel yang bersangkutan, tetapi biasanya yang akan dicatat hanya tanggal pembuatan dan user yang membuat, serta tanggal dan user update terakhir. Disini kita akan kesulitan untuk melacak perubahan yang dilakukan diantara setelah pembuatan sampai update terakhir. Juga akan kesulitan dalam melacak nilai sebelum dan atau setelah perubahan.

Ada banyak metode yang bisa digunakan untuk melakukan hal tersebut. Dari sekian banyak metode, yang sering digunakan ada dua metode yaitu

  1. Menambahkan trigger tabel yang ada didatabase
  2. Pemrograman yaitu melalui model di Codeigniter

Disini yang akan dibahas adalah metode yang pertama yaitu membuat trigger untuk tabel dalam database. Metode ini menurut saya paling mudah, karena tidak perlu lagi otak-atik coding dalam Codeigniter. Karena saya belum pernah juga menggunakan metode yang kedua. Belum terpikirkan juga. Bisa jadi metode yang kedua ada yang lebih mudah.

Persiapan Codeigniter 4 – Mencatat Aktivitas User dalam CRUD

Untuk melanjutkan tutorial pastikan sudah:

Ada database dan Project Codeigniter anda sudah terhubung dengan database, tutorialnya silakan disini
Menerapkan template untuk project Codeigniter

Pertama

Buat tabel log_activities untuk menyimpan atau mencatat aktivitas user. Scriptnya sebagai berikut:

CREATE TABLE `log_activities` (
  `id` int(11) NOT NULL,
  `tables_name` varchar(255) NOT NULL,
  `description` varchar(255) NOT NULL,
  `before` varchar(255) DEFAULT NULL,
  `after` varchar(255) DEFAULT NULL,
  `create_date` datetime NOT NULL,
  `create_by` varchar(75) NOT NULL,
  `active` tinyint(1) NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

ALTER TABLE `log_activities`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `id` (`id`);

ALTER TABLE `log_activities`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=1;

Berikut penjelasan untuk masing-masing field, mungkin bisa dikurang atau ditambah. Silakan sesuaikan dengan kebutuhan Anda.

tables_name = untuk menyimpan nama tabel (ditrigger di hardcode sesuaikan dengan nama tabel)
description = untuk menyimpan keterangan tambah, update, delete (bisa disesuaikan dengan keinginan Anda)
before = jika dibutuhkan untuk menyimpan nilai sebelum perubahan (biasanya untuk AFTER UPDATE)
after = jika dibutuhkan untuk menyimpan nilai baru setelah perubahan (biasanya untuk AFTER UPDATE)
create_date = untuk menyimpan tanggal aktivitas
create_by = untuk menyimpan user yang melakukan aktivitas

Kedua

Membuat trigger untuk tabel yang bersangkutan, hal ini dilakukan untuk semua tabel yang akan dicatat aktivitas (INSERT, UPDATE, DELETE)nya. Ada dua trigger yang diperlukan untuk melakukan hal tersebut, yaitu AFTER INSERT dan AFTER UPDATE.

Bisa juga Anda menambahkan trigger yang ketiga yaitu AFTER DELETE, tapi tidak saya lakukan disini. Dikarena untuk trigger AFTER DELETE saya masih belum menemukan cara untuk mendapatkan user yang melakukan update.

Berikut ini script sql AFTER INSERT

DELIMITER $$
CREATE TRIGGER `after_books_insert` AFTER INSERT ON `books` FOR EACH ROW BEGIN
   INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
        VALUES ('books','tambah buku','',NEW.id, NEW.create_date, NEW.create_by, 1);
END
$$
DELIMITER ;

Selanjutnya script sql AFTER UPDATE (dan AFTER DELETE)

DELIMITER $$
CREATE TRIGGER `after_books_update` AFTER UPDATE ON `books` FOR EACH ROW BEGIN
    IF OLD.title <> new.title THEN
        INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
        VALUES ('books',CONCAT('Update field title pada tabel buku id:',NEW.id),OLD.title,NEW.title, NEW.update_date, NEW.update_by, 1);
    END IF;
    IF OLD.description <> new.description THEN
        INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
        VALUES ('books',CONCAT('Update field description pada tabel buku id:',NEW.id),OLD.description,NEW.description, NEW.update_date, NEW.update_by, 1);
    END IF;
    IF OLD.contents <> new.contents THEN
        INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
        VALUES ('books',CONCAT('Update field contents pada tabel buku id:',NEW.id),OLD.contents,NEW.contents, NEW.update_date, NEW.update_by, 1);
    END IF;
    
    IF OLD.active <> new.active THEN
        INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
        VALUES ('books',CONCAT('delete tabel buku id:',NEW.id), OLD.id, '', NEW.update_date, NEW.update_by, 1);
    END IF;

END
$$
DELIMITER ;

Script AFTER INSERT sudah cukup jelas

Untuk AFTER UPDATE, perhatikan script berikut. Ketiga bagian script ini untuk seluruh field yang ada di tabel. Contoh pada tabel books ada field-field active, contents, create_by, create_date, description, id, slug, title, update_by, update_date, url. Harusnya ada 11 pasang IF … END IF;. Tapi mungkin disini field-field seperti create_by, create_date, id, update_by, update_date tidak perlu dimasukan aktivitas. Berarti cukup ada 6 pasang IF … END IF;.

Dalam trigger AFTER UPDATE kita akan mendapatkan record OLD (berisi data sebelum diupdate) dan NEW (berisi data setelah diupdate). OLD dan NEW yang akan dimanfaatkan untuk membandingkan ada perubahan data atau tidak. Script berikut ini untuk membandingkan OLD.title <> new.title

IF OLD.title <> new.title THEN

Jika lolos (ada perubahan) maka tambah data log_activities

INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
VALUES ('books',CONCAT('Update field title pada tabel buku id:',NEW.id),OLD.title,NEW.title, NEW.update_date, NEW.update_by, 1);

Berikutnya adalah penutup IF

END IF;

Berbeda untuk bagian DELETE berikut ini. Saya memanfaatkan field active, kalau yang ada disini setiap ada perubahan pada field active dianggap delete data buku.

IF OLD.active <> new.active THEN
    INSERT INTO log_activities (`tables_name`, `description`, `before`, `after`, create_date, create_by, active) 
    VALUES ('books',CONCAT('delete tabel buku id:',NEW.id), OLD.id, '', NEW.update_date, NEW.update_by, 1);
END IF;

Mungkin silakan diupdate lagi, jika active=0 maka delete sebaliknya jika active=1 maka diaktifkan

Ketiga

Menampilkan aktifitas tersebut kedalam website. Cara sederhananya disini saya buat list berikut pencarian. Jadi yang saya lakukan adalah membuat model LogActivitiesModel dengan lokasi \app\Models\LogActivitiesModel.php. Scriptnya sebagai berikut

<?php

namespace App\Models;

use CodeIgniter\Model;

class LogActivitiesModel extends Model
{
    protected $table = 'log_activities';
    protected $allowedFields = 
    [
        'tables_name', 'description', 'before', 'after', 'create_date', 'create_by', 'active'
    ];

    public function getLogActivities($id = '')
    {
        if ($id === '')
        {
            return $this->asObject()
                    ->where(['active' => '1'])
                    ->findAll();
        }

        return $this->asObject()
                    ->where(['id' => $id, 'active' => '1'])
                    ->first();

    }
    
    public function getLatestLogActivities()
    {
        return $this->asObject()
                    ->where(['active' => '1'])
                    ->orderBy('create_date', 'desc')
                    ->findAll(10);

    }

    public function make_query($create_date, $create_by)
    {
        $query = "
        SELECT * from log_activities
        WHERE active=1 
        ";

        if (isset($create_date) && $create_date !== '') {
            $query .= "
                AND create_date='".$create_date."'
            ";
        }

        if (isset($create_by)) {
            $create_by = substr($this->db->escape($create_by), 1, -1);
            $query .= "
                AND create_by like '%".$create_by."%'
            ";
        }

        return $query;
    }

    public function fetch_data($limit, $start, $create_date, $create_by)
    {
        $query = $this->make_query($create_date, $create_by);
        $query .= ' LIMIT '.$start.', '.$limit; 
        $data = $this->db->query($query);
        return $data->getResult();
    }

    public function count_all($create_date, $create_by)
    {
        $query = $this->make_query($create_date, $create_by);
        $data = $this->db->query($query);

        return count($data->getResultArray());
    }
}

Kemudian membuat controller LogActivities dengan lokasi \app\Controllers\LogActivities.php. Scriptnya sebagai berikut

<?php

namespace App\Controllers;

use App\Models\LogActivitiesModel;

class LogActivities extends BaseController
{
    public function index()
	{
        return redirect()->to(base_url('/logActivities/list?page=1'));
	}

	public function list()
    {
        $pager = \Config\Services::pager();
        $model = new LogActivitiesModel();
        $create_date = $this->request->getVar('create_date');
        $create_by = $this->request->getVar('create_by');
        
        $per_page = 5;
		$page = $this->request->getVar('page');
		$start = ($page -1) * $per_page;

        $data = [
            'create_by' => $create_by,
            'create_date' => $create_date,
            'per_page' => $per_page,
            'start' => $start,
            'page' => $page,
            'pager' => $pager
        ];

        $data['count_all'] = $model->count_all($create_date, $create_by);
        
        $data['log_activities'] = $model->fetch_data($per_page, $start < 0 ? 0 : $start, $create_date, $create_by);

        if($data['count_all']>0 && count($data['log_activities'])===0) {
            $page = 1;
            $start = ($page -1) * $per_page;
            $data['log_activities'] = $model->fetch_data($per_page, $start < 0 ? 0 : $start, $create_date, $create_by);
        }

        $data['start'] = $start;        
        $data['page'] = $page;

        $data['menu'] = 'log_activities';        
        $data['title'] = 'Aktivitas';
        
        return view('log_activities/index', $data);
    }

}

Yang berikutnya buat view index.php yang lokasinya di \app\Views\log_activities\index.php. Berikut ini scriptnya

<?= $this->extend('template/index') ?>            

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

                    <form class="user">
                        <input type="hidden" name="page" value="<?= $page; ?>" />
                        <div class="form-group row">
                            <div class="col-sm-6 mb-3 mb-sm-0">
                                <input name="title"
                                    type="text"
                                    class="form-control form-control-user"
                                    placeholder="Nama User" value="<?= $create_by; ?>"/>
                            </div>
                            <div class="col-sm-6">
                                <input name="create_date"
                                    type="date"
                                    class="form-control form-control-user"
                                    placeholder="Tanggal" value="<?= $create_date; ?>"/>
                            </div>
                        </div>
                        <div class="col-sm-12">
                            <div class="row">
                                <div class="col-sm-6">
                                    <button type="submit" class="btn btn-success">Cari</button>
                                </div>
                            </div>
                            <?= $pager->makeLinks($page, $per_page, $count_all, 'bootstrap-bullet_pagination') ?>
                        </div>
                    </form>
                    <div class="card shadow mb-4">
                        <div class="card-header py-3">
                            <h6 class="m-0 font-weight-bold text-primary">Daftar Aktivitas</h6>
                        </div>
                        <div class="card-body">
                            <div class="table-responsive">
                                <table class="table table-bordered" id="dataTable" width="100%" cellspacing="0">
                                    <thead>
                                        <tr>
                                            <th>ID</th>
                                            <th>Nama Tabel</th>
                                            <th>Deskripsi</th>
                                            <th>Nama User</th>
                                            <th>Tanggal</th>
                                        </tr>
                                    </thead>
                                    <tfoot>
                                        <tr>
                                            <th>ID</th>
                                            <th>Nama Tabel</th>
                                            <th>Deskripsi</th>
                                            <th>Nama User</th>
                                            <th>Tanggal</th>
                                        </tr>
                                    </tfoot>
                                    <tbody>
                                        <?php foreach($log_activities as $row): ?>
                                        <tr>
                                            <td><?= $row->id; ?></td>
                                            <td><?= $row->tables_name; ?></td>
                                            <td><?= $row->description; ?></td>
                                            <td><?= $row->create_by; ?></td>                                            
                                            <td><?= $row->create_date; ?></td>                                            
                                        </tr>
                                        <?php endforeach; ?>                                        
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    </div>

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

Terakhir

Tampilan akhirnya kurang lebih seperti ini

Demikian tutorial Codeigniter 4 – Mencatat Aktivitas User dalam CRUD . Silakan dilanjutkan dan dikembangkan lagi.

Untuk contohnya bisa dilihat di https://demo.belajardisiniaja.com/

Mudah-mudahan tutorial ini bermanfaat.

Share

You may also like...

2 Responses

  1. tempmail says:

    Receive and send emails through your temporary messaging system. Use our webmail or your favorite email software with our absolutely free disposable email. temp mail

  2. Hairstyles says:

    Thanks for your publication. I would also like to say this that the first thing you will need to complete is determine if you really need credit score improvement. To do that you will need to get your hands on a replica of your credit file. That should really not be difficult, since the government makes it necessary that you are allowed to acquire one cost-free copy of your credit report on a yearly basis. You just have to check with the right persons. You can either look at website for your Federal Trade Commission or perhaps contact one of the main credit agencies directly.

Leave a Reply

Your email address will not be published. Required fields are marked *