承接 sejator/ci4-datatables 相关项目开发

从需求分析到上线部署,全程专人跟进,保证项目质量与交付效率

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

sejator/ci4-datatables

最新稳定版本:v1.0.5

Composer 安装命令:

composer require sejator/ci4-datatables

包简介

Library DataTables server-side untuk CodeIgniter 4

README 文档

README

Library helper untuk integrasi jQuery DataTables (server-side) di CodeIgniter 4, dengan fokus:

✅ Aman
✅ Mudah dipakai
✅ Siap production

Fitur Utama

  • Pagination (server-side)
  • Searching (global search)
  • Filtering (where & conditional)
  • Ordering
  • Debug SQL lengkap
  • Search aman (whitelist kolom)

1️⃣ Penggunaan Dasar

use Sejator\DataTables\DataTables;

return DataTables::from('users')
    ->select('id, name, email, status')
    ->searchable(['name', 'email']) // 🔒 whitelist kolom search
    ->make();

📌 Catatan Penting

  • searchable() sangat direkomendasikan
  • Kolom di luar whitelist tidak akan ikut di-search
  • Tanpa searchable(), library akan fallback ke request DataTables (kurang aman)

2️⃣ Dengan Filter (Where & Conditional)

Filter statis

return DataTables::from('users')
    ->select('id, name, email, status')
    ->where('status', 'active')
    ->searchable(['name', 'email'])
    ->make();

Filter dinamis (opsional)

$status = $this->request->getGetPost('status');

return DataTables::from('users')
    ->select('*')
    ->when($status, fn ($q, $v) => $q->where('status', $v))
    ->searchable(['name', 'email'])
    ->make();

✔ Jika $status kosong (null, ''), filter tidak diterapkan

3️⃣ Debug SQL Lengkap (Mode Debug)

Digunakan untuk melihat seluruh query yang dipakai DataTables:

  • Query data
  • Count total
  • Count filtered
return DataTables::from('users')
    ->select('id, name, email, status')
    ->where('status', 'active')
    ->searchable(['name', 'email'])
    ->debug()
    ->make();

Output JSON Debug:

{
  "debug": true,
  "queries": {
    "data": "SELECT id, name, email, status FROM users WHERE status = 'active' LIMIT 10 OFFSET 0",
    "count_all": "SELECT COUNT(*) FROM users",
    "count_filtered": "SELECT COUNT(*) FROM users WHERE status = 'active'"
  }
}

📌 Kegunaan debug

  • Validasi pagination
  • Cek search & filter
  • Audit performa query
  • Troubleshooting hasil DataTables

4️⃣ Dump SQL Langsung (Development Only)

Digunakan saat development untuk dump SQL dan menghentikan eksekusi.

DataTables::from('users')
    ->select('*')
    ->where('status', 'inactive')
    ->ddSql();

Output:

SELECT * FROM users WHERE status = 'inactive'

⚠️ Jangan dipakai di production

5️⃣ Logging Query ke Log CI4

Query akan dicatat ke file log CI4:

📁 writable/logs/log-YYYY-MM-DD.php

DataTables::from('users')
    ->select('*')
    ->where('status', 'pending')
    ->logSql()
    ->make();

Contoh log:

DEBUG - DataTables SQL: SELECT * FROM users WHERE status = 'pending'

6️⃣ Search Aman (Whitelist Column)

📌 Wajib digunakan jika query menggunakan JOIN atau alias kolom.

Tanpa searchable(), DataTables dapat menghasilkan query tidak valid atau fitur pencarian tidak sesuai.

->searchable(['name', 'email'])

✔ Mencegah:

  • SQL injection via DataTables request
  • Search ke kolom yang tidak diinginkan

❌ Tanpa searchable():

  • Semua kolom searchable=true dari frontend akan dipakai
  • Kurang aman & sulit dikontrol

7️⃣ Ringkasan Method Penting

Method Fungsi
from($table) Tentukan tabel
select() Kolom yang diambil
where() Filter data
when() Filter kondisional
searchable() Whitelist kolom search
orderBy() Sorting manual
debug() Tampilkan SQL lengkap
ddSql() Dump SQL & stop
logSql() Log SQL ke CI4
make() / draw() Eksekusi DataTables
withRelation() Load relasi tanpa JOIN (lazy & nested)

📌 make() dan draw() setara (pilih salah satu untuk konsistensi)

🔄 reset()

Digunakan untuk mengembalikan DataTables ke kondisi awal.

📌 Wajib dipakai jika instance digunakan lebih dari sekali

$dt = DataTables::from('users');

$dt->where('status', 'active')->make();

$dt->reset()
   ->where('status', 'inactive')
   ->make();

8️⃣ Relasi Data (withRelation)

Fitur withRelation() digunakan untuk memuat data relasi tanpa JOIN, sehingga:

✅ Aman untuk pagination ✅ Tidak menduplikasi row ✅ Performa lebih baik ✅ Cocok untuk server-side DataTables

Relasi akan dimuat setelah query utama dieksekusi dan disisipkan ke setiap row hasil.

8.1️⃣ Penggunaan Dasar

return DataTables::from('izin')
    ->select('id, tanggal_mulai, status')
    ->withRelation(
        'izin_id',     // foreign key di tabel relasi
        'id',          // primary key di tabel utama
        'izin_histori',
        'izin_id, tanggal'
    )
    ->make();

Hasil data:

$row['izin_histori'] = [
    ['izin_id' => 1, 'tanggal' => '2024-01-01'],
    ['izin_id' => 1, 'tanggal' => '2024-01-02'],
];

8.2️⃣ Lazy Load Relasi (Direkomendasikan)

Relasi hanya akan di-load jika benar-benar digunakan pada addColumn() atau editColumn().

return DataTables::from('izin')
    ->select('id, status')
    ->withRelation(
        'izin_id',
        'id',
        'izin_histori',
        'izin_id, tanggal',
        [
            'onlyIfUsedIn' => ['tanggal']
        ]
    )
    ->addColumn('tanggal', function ($row) {
        return implode(
            ', ',
            array_column($row->izin_histori, 'tanggal')
        );
    })
    ->make();

📌 Jika kolom tanggal tidak dipakai, query relasi tidak akan dijalankan.

8.3️⃣ Nested Relation (Relasi Bertingkat)

Mendukung relasi di dalam relasi.

return DataTables::from('izin')
    ->select('id, status')
    ->withRelation(
        'izin_id',
        'id',
        'izin_histori',
        'id, izin_id, tanggal',
        [
            'nested' => [
                [
                    'foreignKey' => 'izin_histori_id',
                    'localKey'   => 'id',
                    'table'      => 'izin_histori_detail',
                    'columns'    => '*',
                ]
            ]
        ]
    )
    ->make();

Akses data:

$row->izin_histori[0]['izin_histori_detail']

8.4️⃣ Kenapa withRelation Tidak Menggunakan JOIN?

❌ JOIN menyebabkan:

  • Duplikasi row
  • Pagination tidak akurat
  • Count total & filtered salah

✅ withRelation:

  • Query utama tetap bersih
  • Relasi di-load sekali (no N+1)
  • Aman untuk DataTables server-side

8.5️⃣ Rekomendasi Best Practice

  • ✔ Gunakan withRelation() untuk data child (histori, detail, log)
  • ✔ Aktifkan onlyIfUsedIn untuk performa optimal
  • ✔ Gunakan JOIN hanya untuk data 1–1 yang memang ditampilkan langsung
  • ✔ Hindari JOIN untuk data 1–N pada DataTables

统计信息

  • 总下载量: 7
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-12-30