Codeigniter 4 – Mencatat Aktivitas User dalam CRUD 2

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

Melanjutkan tutorial sebelumnya Codeigniter 4 – Mencatat Aktivitas User dalam CRUD, pada tutorial kali ini yang akan dibahas adalah metode yang kedua. Yaitu memanfaatkan model yang ada di Codeigniter 4. Setelah cari-cari ternyata Codeigniter juga menyediakan fitur Model Events. Fungsinya yang bisa digunakan adalah $beforeInsert, $afterInsert, $beforeUpdate, $afterUpdate, $afterFind, dan $afterDelete. Tapi disini saya hanya akan menggunakan $afterInsert dan $afterUpdate saja.

Mungkin bisa menjadi referensi, saya menemukan dari link berikut. Disana ada penjelasan Model Events.

Dengan menggunakan fitur Model Events yang disediakan oleh Codeigniter, kita bisa menyimpan log atau aktivitas User. Akah tetapi disini saya masih belum menemukan data before dan data after terutama pada saat after update. Tapi setidaknya ini bisa membantu melacak aktivitas yang User lakukan terkait CRUD terhadap tabel dalam database.

Codeigniter menyediakan perintah untuk membuat model. Perintah yang digunakan adalah

php spark make:model Book --suffix

Dengan perintah tersebut kita akan dibuatkan sebuah model dengan nama BookModel dengan lokasi \app\Models\BookModel.php. Berikut script yang dihasilkan dengan peritah tersebut

<?php

namespace App\Models;

use CodeIgniter\Model;

class BookModel extends Model
{
    protected $DBGroup          = 'default';
    protected $table            = 'books';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $insertID         = 0;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = false;
    protected $protectFields    = true;
    protected $allowedFields    = [];

    // Dates
    protected $useTimestamps = false;
    protected $dateFormat    = 'datetime';
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';
    protected $deletedField  = 'deleted_at';

    // Validation
    protected $validationRules      = [];
    protected $validationMessages   = [];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = [];
    protected $afterInsert    = [];
    protected $beforeUpdate   = [];
    protected $afterUpdate    = [];
    protected $beforeFind     = [];
    protected $afterFind      = [];
    protected $beforeDelete   = [];
    protected $afterDelete    = [];
}

Tapi pada tutorial ini saya tidak menggunakan cara tersebut. Dikarenakan hanya fungsi yang saya gunakan dan juga field-field hasil generate model tidak saya gunakan. Disini saya akan menggunakan model yang sudah ada.

Persiapan Codeigniter 4 – Mencatat Aktivitas User dalam CRUD 2

Untuk melanjutkan tutorial pastikan sudah:

Ada database dan Project Codeigniter anda sudah terhubung dengan database, tutorialnya silakan disini
Menerapkan template untuk project Codeigniter
Mengerjakan tutorial CRUD Codeigniter 4 – CRUD Bagian 1 (Tambah data dengan upload gambar)

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

Bagian pertama ini tidak perlu Anda lakukan jika Anda sudah mengerjakan tutorial Codeigniter 4 – Mencatat Aktivitas User dalam CRUD. Karena tabel yang saya gunakan sama dengan tutorial tersebut.

Kedua

Update model yang akan ditambahkan Model Events, disini yang akan diupdate adalah \app\Models\BooksModel.php. Tambahkan fungsi afterInsert dan afterUpdate. Caranya dengan menambahkan script berikut setelah protected $allowedFields

...
    protected $afterInsert = ['doAfterInsert'];
    protected $afterUpdate = ['doAfterUpdate'];

    public function doAfterInsert(array $row)
    {
        $logModel = new LogActivitiesModel();
        $data = [
            'tables_name' => 'books', 
            'description' => 'tambah data buku id : '.$row['id'], 
            'before' => '', 
            'after' => $row['id'], 
            'create_date' => $row['data']['create_date'], 
            'create_by' => $row['data']['create_by'], 
            'active' => '1'
        ];
        $logModel->save($data);
    }

    public function doAfterUpdate(array $row)
    {
        $logModel = new LogActivitiesModel();
        if($row['data']['active'] === 0) {
            $data = [
                'tables_name' => 'books', 
                'description' => 'delete data buku id : '.$row['id'][0], 
                'before' => '', 
                'after' => $row['id'][0], 
                'create_date' => $row['data']['update_date'], 
                'create_by' => $row['data']['update_by'], 
                'active' => '1'
            ];
        } else {
            $data = [
                'tables_name' => 'books', 
                'description' => 'update data buku id : '.$row['id'][0], 
                'before' => '', 
                'after' => $row['id'][0], 
                'create_date' => $row['data']['update_date'], 
                'create_by' => $row['data']['update_by'], 
                'active' => '1'
            ];
        }
        $logModel->save($data);
    }
...

Untuk mengaktifkan event afterInsert cukup memanggilnya dengan script protected $afterInsert, sedangkan [‘doAfterInsert’] adalah fungsi atau perintah yang dijalankan setelah input data (afterInsert).

Fungsi doAfterInsert akan menghasilkan nilai keluaran

  • id = id untuk data yang baru, atau 0 jika ada error (bertipe integer)
  • data = data yang diinput (bergantung field yang diinsert).
  • result = insert data berhasil akan bernilai true atau jika gagal bernilai false (bertipe boolean)

Fungsi doAfterUpdate akan menghasilkan nilai keluaran

  • id = id untuk data-data yang yang diupdate (bertipe array)
  • data = data yang diupdate (bergantung field yang diupdate).
  • result = update data berhasil akan bernilai true atau jika gagal bernilai false (bertipe boolean)

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() ?>  

Langkah ketiga bisa dilewati jika anda sudah mengerjakan tutorial sebelumnya Codeigniter 4 – Mencatat Aktivitas User dalam CRUD

Terakhir

Tampilan akhirnya kurang lebih seperti ini

Demikian tutorial Codeigniter 4 – Mencatat Aktivitas User dalam CRUD 2. Silakan dilanjutkan dan dikembangkan lagi. Mungkin ada yang sudah bisa mengambil data sebelum update pada event afterUpdate seperti pada trigger database AfterUpdate.

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

Mudah-mudahan tutorial ini bermanfaat.

Share

You may also like...

2 Responses

  1. bujangan says:

    Gimana cara menggunakan callback beforeDelete atau afterDelete untuk hapus file ya? kok selalu null untuk data

    • Sepertinya cara terbaik menggunakan afterUpdate Pak, saya sudah coba cara

      Saya coba tambahkan script ini :

      protected $useSoftDeletes = false;

      protected $beforeDelete = [‘doBeforeDelete’];
      protected $afterDelete = [‘doAfterDelete’];

      protected function doBeforeDelete(array $row)
      {
      log_message(‘info’, ‘data row : ‘. json_encode($row));
      $logModel = new LogActivitiesModel();
      $data = [
      ‘tables_name’ => ‘books’,
      ‘description’ => ‘DELETE data buku id : ‘.$row[‘id’],
      ‘before’ => ”,
      ‘after’ => $row[‘id’],
      ‘active’ => ‘1’
      ];
      $logModel->save($data);
      //return $data;
      }

      protected function doAfterDelete(array $row)
      {
      log_message(‘info’, ‘data row : ‘. json_encode($row));
      //return $data;
      }

      Ini log yg saya dapat :
      beforeUpdate => INFO – 2023-11-20 03:48:22 –> data row : {“id”:null,”purge”:false}
      afterUpdate => INFO – 2023-11-20 03:48:22 –> data row : {“id”:null,”data”:null,”purge”:false,”result”:true}

Leave a Reply

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