بِسْمِ اللَّهِ Mudah-mudahan tutorial Codeigniter 4 – CRUD Bagian 1 (Tambah data dengan upload gambar) ini bermanfaat
Salah satu bagian CRUD (Create, Read, Update, dan Delete) adalah Create atau disini saya menyebutnya tambah data. Hal ini sangat penting karena disini adalah awal data masuk, dimana ini memerlukan validasi untuk memastikan data sudah dimasukkan dengan benar. Apalagi pada tutorial ini ditambah fitur yang tidak kalah penting yaitu upload gambar.
Persiapan Codeigniter 4 – CRUD Bagian 1 (Tambah data dengan upload gambar)
Untuk melanjutkan tutorial pastikan sudah ada ini:
Editor yang digunakan adalah Visual Studio Code
Project Codeigniter, untuk membuatnya bisa dilihat tutorial Codeigniter 4 Pengenalan dan Instalasi.
Pastikan Koneksi ke database bisa dilihat di Codeigniter 4 – Koneksi ke Database
Dan sudah mengikuti tutorial pengaplikasian template pada project Codeigniter 4 sebelumnya, jika belum silakan cek disini
Untuk WYSIWYG disini menggunakan TinyMCE, untuk versi terbaru bisa download disini atau yang sama dengan di tutorial bisa didownload disini
Pertama
Dalam CRUD akan berhubungan dengan entri atau isian, maka perlu tambahkan helper form dengan mengupdate \app\Controllers\BaseController.php, cari protected $helpers. Update dengan script ini:
protected $helpers = ['form'];
Kedua
Untuk membuat judul halaman menjadi dinamis sesuai yang dikirimkan dari Controller, update template pada \app\Views\template\index.php pada bagian tag <title></title> dengan script berikut:
<title><?= $title; ?></title>
Kemudian hilang judul yang ada di body, nantinya judul tersebut akan dipindahkan ke masing-masing view dari fungsi yang ada di Controller. Tujuannya untuk mempermudah pengaturan tampilan. Hapus <h1 class=”h3 mb-4 text-gray-800″>…</h1> sehingga script menjadi seperti ini
<!-- Begin Page Content -->
<div class="container-fluid">
<!-- Page Heading -->
<?= $this->renderSection('page-content'); ?>
</div>
<!-- /.container-fluid -->
Terakhir tambahkan pada bagian paling bawah script ini 3r<?= $this->renderSection(‘script-js’); ?> yang berfungsi untuk memanggil bagian script-js dari view. Setelah ditambah akan seperti ini:
<!-- Bootstrap core JavaScript-->
<script src="<?= base_url() ?>/assets/vendor/jquery/jquery.min.js"></script>
<script src="<?= base_url() ?>/assets/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Core plugin JavaScript-->
<script src="<?= base_url() ?>/assets/vendor/jquery-easing/jquery.easing.min.js"></script>
<!-- Custom scripts for all pages-->
<script src="<?= base_url() ?>/assets/js/sb-admin-2.min.js"></script>
<?= $this->renderSection('script-js'); ?>
Ketiga
Tambahkan NewsModel yang lokasinya ada di \app\Models\NewsModel.php. Berikut scriptnya
<?php
namespace App\Models;
use CodeIgniter\Model;
class NewsModel extends Model
{
protected $table = 'news';
protected $allowedFields =
[
'active'
, 'body'
, 'image'
, 'publish_date'
, 'slug'
, 'title'
];
public function getNews($id = '')
{
if ($id === '')
{
return $this->asObject()
->orderBy('publish_date', 'desc')
->findAll();
}
return $this->asObject()
->where(['id' => $id])
->first();
}
public function getPageSlug($slug = false)
{
return $this->asObject()
->where(['slug' => $slug])
->first();
}
function checkSlug($string){
$str=$string;
$query = "SELECT * from news WHERE slug like '%".$string."%' ";
$data = $this->db->query($query);
$countResult = count($data->getResultArray());
if ($countResult > 0) {
$str=$str.'-'.$countResult;
}
return $str;
}
public function getLatestNews()
{
return $this->asObject()
->orderBy('publish_date', 'desc')
->findAll(3);
}
public function make_query($publish_date, $title, $body)
{
$query = "
SELECT * from news
WHERE 1=1
";
if (isset($body)) {
$body = substr($this->db->escape($body), 1, -1);
$query .= "
AND body like '%".$body."%'
";
}
if (isset($publish_date) && $publish_date !== '') {
$query .= "
AND publish_date='".$publish_date."'
";
}
if (isset($title)) {
$title = substr($this->db->escape($title), 1, -1);
$query .= "
AND title like '%".$title."%'
";
}
return $query;
}
public function fetch_data($limit, $start, $publish_date, $title, $body)
{
$query = $this->make_query($publish_date, $title, $body);
$query .= ' LIMIT '.$start.', '.$limit;
$data = $this->db->query($query);
return $data->getResult();
}
public function count_all($publish_date, $title, $body)
{
$query = $this->make_query($publish_date, $title, $body);
$data = $this->db->query($query);
return count($data->getResultArray());
}
}
Keempat
Update Controller \app\Controllers\News.php dengan menambahkan dua fungsi berikut
- add untuk tambah berita
- save untuk menyimpan berita dan sekaligus upload gambar ke folder public/images/news
public function add()
{
$data['title'] = 'Tambah Berita';
$data['menu'] = 'news';
return view('news/add', $data);
}
public function save()
{
$rules = [
'body' => 'required',
'image_file' => 'uploaded[image_file]|is_image[image_file]',
'title' => 'required'
];
if($this->validate($rules)){
$model = new NewsModel();
$fileImage_name = "";
if(isset($_FILES) && @$_FILES['image_file']['error'] != '4') {
if($fileImage = $this->request->getFile('image_file')) {
if (! $fileImage->isValid()) {
throw new \RuntimeException($fileImage->getErrorString().'('.$fileImage->getError().')');
} else {
$fileImage->move('images/news');
$fileImage_name = $fileImage->getName();
}
}
}
$slug = $model->checkSlug(url_title($this->request->getVar('title'), '-', TRUE));
$data = [
'body' => $this->request->getVar('body'),
'slug' => $slug,
'title' => $this->request->getVar('title'),
'image' => $fileImage_name,
'publish_date' => $this->request->getVar('publish_date')
];
$model->save($data);
return redirect()->to(base_url('/news/list?page=1'));
} else {
$data['validation'] = $this->validator;
$data['title'] = 'Tambah Berita';
$data['menu'] = 'news';
return view('news/add', $data);
}
}
Kelima
Untuk memanggil fungsi tambah disini kita mengolah view, pertama update \app\Views\news\index.php menjadi seperti ini:
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<button type="submit" class="btn btn-success">Cari Berita</button>
</div>
<div class="col-sm-6">
<a href="<?= base_url(); ?>/news/add" class="btn btn-success float-right">Tambah Berita</a>
</div>
</div>
<?= $pager->makeLinks($page, $per_page, $count_all, 'bootstrap-bullet_pagination') ?>
</div>
Kemudian buat file add.php pada folder \app\Views\news kemudian isi dengan script berikut
<?= $this->extend('template/index') ?>
<?= $this->section('page-content') ?>
<!-- start page title -->
<div class="row">
<div class="col-12">
<div class="page-title-box d-sm-flex align-items-center justify-content-between">
<h1 class="h3 mb-4 text-gray-800"><?= $title; ?></h1>
<div class="page-title-right">
<ol class="breadcrumb m-0">
<li class="breadcrumb-item"><a href="<?= base_url(); ?>">Halaman Utama</a></li>
<li class="breadcrumb-item"><a href="<?= base_url('news'); ?>">Daftar Berita</a></li>
<li class="breadcrumb-item active">
<?=$title;?>
</li>
</ol>
</div>
</div>
</div>
</div>
<!-- end page title -->
<div class="page-section">
<form action="<?= base_url(); ?>/news/save" method="post" enctype="multipart/form-data">
<div class="row card-group-row">
<?php if (isset($validation)) { ?>
<div class="col-md-12">
<?php foreach ($validation->getErrors() as $error) : ?>
<div class="alert alert-warning" role="alert">
<i class="mdi mdi-alert-outline me-2"></i>
<?= esc($error) ?>
</div>
<?php endforeach ?>
</div>
<?php } ?>
<div class="col-md-12">
<div class="list-group list-group-flush">
<div class="list-group-item p-3">
<div class="row align-items-start">
<div class="col-md-4 mb-8pt mb-md-0">
<div class="media align-items-left">
<div class="d-flex flex-column media-body media-middle">
<span
class="card-title">Judul Berita</span>
</div>
</div>
</div>
<div class="col mb-8pt mb-md-0">
<input name="title"
type="text"
class="form-control"
placeholder="Judul Berita" />
</div>
</div>
</div>
<div class="list-group-item p-3">
<div class="row align-items-start">
<div class="col-md-4 mb-8pt mb-md-0">
<div class="media align-items-left">
<div class="d-flex flex-column media-body media-middle">
<span
class="card-title">Tanggal Terbit</span>
</div>
</div>
</div>
<div class="col mb-8pt mb-md-0">
<input name="publish_date" type="date" class="form-control publish_date" placeholder="Tanggal Terbit" value="<?php echo set_value ('publish_date'); ?>" />
</div>
</div>
</div>
<div class="list-group-item p-3">
<div class="row align-items-start">
<div class="col-md-4 mb-8pt mb-md-0">
<div class="media align-items-left">
<div class="d-flex flex-column media-body media-middle">
<span
class="card-title">Gambar</span>
</div>
</div>
</div>
<div class="col mb-8pt mb-md-0">
<input type="file" id="image_file" name="image_file" class="form-control image_file" accept=".jpg,.png,.jpeg,.gif" />
</div>
</div>
</div>
<div class="list-group-item p-3">
<div class="row align-items-start">
<div class="col-md-4 mb-8pt mb-md-0">
<div class="media align-items-left">
<div class="d-flex flex-column media-body media-middle">
<span
class="card-title">Isi Berita</span>
</div>
</div>
</div>
<div class="col mb-8pt mb-md-0">
<textarea name="body" style="width:100%; height: 300px">
</textarea>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col align-items-right">
<button type="submit" class="btn btn-success">Simpan</button>
</div>
</div>
</form>
</div>
<?= $this->endSection() ?>
<?= $this->section('script-js') ?>
<script language="javascript" type="text/javascript" src="<?= base_url() ?>/assets//js/tiny_mce/tiny_mce.js"></script>
<script language="javascript" type="text/javascript">
tinyMCE.init({
theme : "advanced",
mode : "textareas",
external_image_list_url : "ext_image_list.php"
});
</script>
<?= $this->endSection() ?>
Akhirnya
Berikut ini hasil yang diupdate
Daftar berita
Tambah berita
Sampai disini sudah selesai untuk Codeigniter 4 – CRUD Bagian 1 yaitu Tambah data. Mudah-mudahan bermanfaat.
Thanks for this excellent article. One more thing to mention is that most digital cameras can come equipped with the zoom lens that permits more or less of your scene to generally be included by simply ‘zooming’ in and out. All these changes in target length usually are reflected within the viewfinder and on large display screen right at the back of your camera.