Laravel, framework PHP yang populer, menyediakan sistem validasi data yang powerful dan mudah digunakan. Namun, terkadang validasi bawaan Laravel tidak cukup untuk menangani kebutuhan spesifik aplikasi Anda. Di sinilah custom validation atau validasi kustom berperan. Artikel ini akan membahas tuntas tentang Custom Validation di Laravel Bahasa Indonesia, bagaimana cara membuatnya, dan mengapa validasi ini penting untuk fleksibilitas pengembangan aplikasi Anda. Kita akan menjelajahi berbagai teknik dan contoh kode praktis agar Anda dapat mengimplementasikan validasi kustom dengan mudah.
Mengapa Membutuhkan Validasi Kustom di Laravel?
Validasi data merupakan langkah krusial dalam pengembangan aplikasi web. Tujuannya adalah memastikan bahwa data yang masuk ke aplikasi Anda valid, konsisten, dan sesuai dengan aturan bisnis yang telah ditetapkan. Validasi mencegah data yang tidak valid disimpan dalam database, mengurangi risiko error, meningkatkan keamanan, dan memperbaiki pengalaman pengguna.
Laravel menyediakan validator bawaan yang sangat berguna untuk validasi umum seperti tipe data, panjang karakter, format email, dan lain-lain. Namun, terkadang Anda memerlukan validasi yang lebih kompleks dan spesifik, misalnya:
- Validasi Berdasarkan Logika Bisnis: Validasi yang bergantung pada kondisi atau data lain dalam database. Contohnya, memeriksa apakah kode promo masih berlaku atau apakah seorang pengguna sudah memiliki langganan aktif.
- Validasi Format Data yang Kompleks: Validasi format data yang tidak didukung oleh validator bawaan. Contohnya, validasi nomor rekening bank dengan format khusus.
- Validasi Terhadap Sumber Data Eksternal: Validasi yang memerlukan koneksi ke API atau sumber data eksternal lainnya. Contohnya, validasi alamat berdasarkan API geocoding.
Dalam kasus-kasus seperti ini, custom validation di Laravel menjadi solusi yang tepat. Dengan validasi kustom, Anda memiliki kendali penuh atas logika validasi dan dapat menyesuaikannya sesuai dengan kebutuhan aplikasi Anda.
Membuat Aturan Validasi Kustom di Laravel: Langkah Demi Langkah
Laravel menyediakan beberapa cara untuk membuat aturan validasi kustom. Berikut adalah salah satu cara yang paling umum dan direkomendasikan, yaitu menggunakan rule object:
1. Membuat Rule Object Menggunakan Artisan CLI
Gunakan perintah Artisan CLI berikut untuk membuat rule object:
php artisan make:rule ValidasiKodePromo
Perintah ini akan membuat file ValidasiKodePromo.php
di direktori app/Rules
.
2. Mengimplementasikan Rule Object
Buka file ValidasiKodePromo.php
dan implementasikan dua method utama: passes()
dan message()
.
-
passes($attribute, $value)
: Method ini berisi logika validasi.$attribute
adalah nama field yang sedang divalidasi, dan$value
adalah nilai dari field tersebut. Method ini harus mengembalikantrue
jika validasi berhasil danfalse
jika gagal. -
message()
: Method ini mengembalikan pesan error yang akan ditampilkan jika validasi gagal.
Berikut adalah contoh implementasi ValidasiKodePromo.php
yang memvalidasi apakah kode promo yang dimasukkan masih berlaku:
<?php
namespace AppRules;
use IlluminateContractsValidationRule;
use AppModelsKodePromo; // Gantilah dengan model yang sesuai
class ValidasiKodePromo implements Rule
{
/**
* Create a new rule instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
* @return bool
*/
public function passes($attribute, $value)
{
// Cek apakah kode promo ada di database
$kodePromo = KodePromo::where('kode', $value)->first();
if (!$kodePromo) {
return false; // Kode promo tidak ditemukan
}
// Cek apakah kode promo masih berlaku (misalnya, tanggal kedaluwarsa)
if ($kodePromo->tanggal_berakhir < now()) {
return false; // Kode promo sudah kedaluwarsa
}
return true; // Validasi berhasil
}
/**
* Get the validation error message.
*
* @return string
*/
public function message()
{
return 'Kode promo tidak valid atau sudah kedaluwarsa.';
}
}
Penjelasan Kode:
use AppModelsKodePromo;
: Mengimpor modelKodePromo
yang merepresentasikan tabel kode promo di database. Pastikan Anda menggantiAppModelsKodePromo
dengan namespace model yang sesuai dengan aplikasi Anda.$kodePromo = KodePromo::where('kode', $value)->first();
: Mencari kode promo di database berdasarkan nilai yang dimasukkan oleh pengguna.if (!$kodePromo) { return false; }
: Jika kode promo tidak ditemukan, validasi gagal.if ($kodePromo->tanggal_berakhir < now()) { return false; }
: Jika tanggal kedaluwarsa kode promo sudah lewat, validasi gagal.return 'Kode promo tidak valid atau sudah kedaluwarsa.';
: Pesan error yang akan ditampilkan jika validasi gagal.
3. Menggunakan Rule Object dalam Controller
Setelah rule object dibuat, Anda dapat menggunakannya dalam controller Anda. Berikut adalah contoh cara menggunakan ValidasiKodePromo
dalam method store()
:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
use AppRulesValidasiKodePromo;
class OrderController extends Controller
{
public function store(Request $request)
{
$request->validate([
'kode_promo' => ['required', new ValidasiKodePromo()],
'jumlah_barang' => 'required|integer|min:1',
// ... aturan validasi lainnya
]);
// Lakukan proses penyimpanan order jika validasi berhasil
// ...
}
}
Penjelasan Kode:
use AppRulesValidasiKodePromo;
: Mengimpor rule objectValidasiKodePromo
.'kode_promo' => ['required', new ValidasiKodePromo()],
: MenggunakanValidasiKodePromo
sebagai salah satu aturan validasi untuk fieldkode_promo
.'required'
memastikan bahwa fieldkode_promo
harus diisi.new ValidasiKodePromo()
membuat instance dari rule objectValidasiKodePromo
.
Opsi Lain untuk Validasi Kustom: Closure-Based Validation
Selain menggunakan rule object, Anda juga dapat membuat validasi kustom menggunakan closure (fungsi anonim). Cara ini lebih sederhana untuk validasi yang tidak terlalu kompleks dan tidak memerlukan rule object yang terpisah.
Berikut adalah contoh penggunaan closure-based validation untuk memvalidasi apakah sebuah string hanya mengandung huruf dan angka:
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
class UserController extends Controller
{
public function store(Request $request)
{
$request->validate([
'username' => ['required', 'string', 'max:255', function ($attribute, $value, $fail) {
if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) {
$fail($attribute.' hanya boleh mengandung huruf dan angka.');
}
}],
'email' => 'required|email|unique:users',
// ... aturan validasi lainnya
]);
// Lakukan proses penyimpanan user jika validasi berhasil
// ...
}
}
Penjelasan Kode:
function ($attribute, $value, $fail) { ... }
: Ini adalah closure yang mendefinisikan logika validasi.$attribute
: Nama field yang sedang divalidasi.$value
: Nilai dari field tersebut.$fail
: Fungsi yang digunakan untuk menandai validasi gagal. Anda harus memanggil$fail()
dengan pesan error sebagai argumen jika validasi gagal.if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) { ... }
: Menggunakan regular expression untuk memeriksa apakah nilai hanya mengandung huruf dan angka.$fail($attribute.' hanya boleh mengandung huruf dan angka.');
: Jika validasi gagal, memanggil$fail()
dengan pesan error yang sesuai.
Membuat Custom Validation Messages: Pesan Error yang Lebih Informatif
Laravel memungkinkan Anda untuk menyesuaikan pesan error validasi. Pesan error bawaan mungkin kurang jelas atau kurang informatif bagi pengguna. Dengan custom validation messages, Anda dapat memberikan pesan error yang lebih spesifik dan mudah dimengerti.
Ada beberapa cara untuk membuat custom validation messages:
1. Menggunakan File Bahasa (resources/lang/id/validation.php)
Ini adalah cara yang paling direkomendasikan untuk aplikasi yang mendukung beberapa bahasa. Anda dapat membuat file resources/lang/id/validation.php
(jika belum ada) dan menambahkan pesan error kustom di sana.
<?php
return [
'required' => 'Field :attribute harus diisi.',
'email' => 'Field :attribute harus berupa email yang valid.',
'integer' => 'Field :attribute harus berupa angka.',
'min' => [
'numeric' => 'Field :attribute minimal :min.',
'file' => 'Field :attribute minimal :min kilobytes.',
'string' => 'Field :attribute minimal :min karakter.',
'array' => 'Field :attribute minimal :min item.',
],
'custom' => [
'kode_promo' => [
'validasi_kode_promo' => 'Kode promo tidak valid atau sudah kedaluwarsa.',
],
'username' => [
'regex' => 'Username hanya boleh mengandung huruf dan angka.',
],
],
'attributes' => [
'kode_promo' => 'Kode Promo',
'username' => 'Username',
],
];
Penjelasan Kode:
'required' => 'Field :attribute harus diisi.',
: Menimpa pesan error bawaan untuk aturanrequired
.:attribute
akan digantikan dengan nama field yang sedang divalidasi.'custom' => [ ... ]
: Menampung pesan error kustom untuk aturan-aturan tertentu.'kode_promo' => [ 'validasi_kode_promo' => 'Kode promo tidak valid atau sudah kedaluwarsa.', ]
: Menentukan pesan error untuk aturanvalidasi_kode_promo
(aturan validasi kustom kita) pada fieldkode_promo
.'username' => [ 'regex' => 'Username hanya boleh mengandung huruf dan angka.', ]
: Menentukan pesan error untuk aturanregex
(yang digunakan dalam closure-based validation) pada fieldusername
.
'attributes' => [ ... ]
: Menentukan nama field yang akan ditampilkan dalam pesan error. Jika tidak didefinisikan, nama field akan diambil dari nama variabel.
2. Mendefinisikan Pesan Error Langsung di Validator
Anda juga dapat mendefinisikan pesan error langsung di validator saat memanggil method validate()
.
<?php
namespace AppHttpControllers;
use IlluminateHttpRequest;
class UserController extends Controller
{
public function store(Request $request)
{
$messages = [
'username.required' => 'Username wajib diisi.',
'username.regex' => 'Username hanya boleh mengandung huruf dan angka.',
'email.required' => 'Email wajib diisi.',
'email.email' => 'Email tidak valid.',
'email.unique' => 'Email ini sudah terdaftar.',
];
$request->validate([
'username' => ['required', 'string', 'max:255', function ($attribute, $value, $fail) {
if (!preg_match('/^[a-zA-Z0-9]+$/', $value)) {
$fail($attribute.' hanya boleh mengandung huruf dan angka.');
}
}],
'email' => 'required|email|unique:users',
// ... aturan validasi lainnya
], $messages);
// Lakukan proses penyimpanan user jika validasi berhasil
// ...
}
}
Penjelasan Kode:
$messages = [ ... ]
: Mendefinisikan array yang berisi pesan error kustom. Kuncinya adalah nama field dan aturan validasi yang dipisahkan oleh titik (.
).$request->validate([ ... ], $messages);
: Melewatkan array$messages
sebagai argumen kedua ke methodvalidate()
.
Tips untuk Custom Validation Messages:
- Gunakan Bahasa yang Jelas dan Singkat: Hindari penggunaan jargon teknis atau bahasa yang terlalu kompleks.
- Berikan Informasi yang Spesifik: Jelaskan dengan tepat mengapa validasi gagal.
- Konsisten dengan Gaya Bahasa Aplikasi: Pastikan pesan error konsisten dengan gaya bahasa yang digunakan di seluruh aplikasi Anda.
Validasi Data dengan Request Object di Laravel
Laravel menyediakan Request Object yang memungkinkan Anda untuk memindahkan logika validasi dari controller ke dalam class request. Hal ini membuat controller Anda lebih bersih dan fokus pada logika bisnis utama.
1. Membuat Request Object Menggunakan Artisan CLI
Gunakan perintah Artisan CLI berikut untuk membuat request object:
php artisan make:request StoreOrderRequest
Perintah ini akan membuat file StoreOrderRequest.php
di direktori app/Http/Requests
.
2. Mengimplementasikan Request Object
Buka file StoreOrderRequest.php
dan implementasikan dua method utama: authorize()
dan rules()
.
-
authorize()
: Method ini menentukan apakah pengguna yang sedang mencoba mengakses request ini memiliki izin untuk melakukannya. Biasanya, Anda akan melakukan pengecekan otorisasi di sini. Method ini harus mengembalikantrue
jika diizinkan danfalse
jika tidak. -
rules()
: Method ini mengembalikan array yang berisi aturan validasi.
Berikut adalah contoh implementasi StoreOrderRequest.php
yang menggunakan aturan validasi yang sama seperti contoh sebelumnya:
<?php
namespace AppHttpRequests;
use IlluminateFoundationHttpFormRequest;
use AppRulesValidasiKodePromo;
class StoreOrderRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true; // Sesuaikan dengan logika otorisasi Anda
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'kode_promo' => ['required', new ValidasiKodePromo()],
'jumlah_barang' => 'required|integer|min:1',
// ... aturan validasi lainnya
];
}
/**
* Get the error messages for the defined validation rules.
*
* @return array
*/
public function messages()
{
return [
'jumlah_barang.required' => 'Jumlah barang harus diisi.',
'jumlah_barang.integer' => 'Jumlah barang harus berupa angka.',
'jumlah_barang.min' => 'Jumlah barang minimal 1.',
];
}
}
Penjelasan Kode:
use IlluminateFoundationHttpFormRequest;
: Mengimpor classFormRequest
yang merupakan base class untuk request object.use AppRulesValidasiKodePromo;
: Mengimpor rule objectValidasiKodePromo
.public function authorize() { return true; }
: Untuk contoh ini, kita mengizinkan semua pengguna untuk mengakses request ini. Anda harus menggantireturn true;
dengan logika otorisasi yang sesuai dengan aplikasi Anda.public function rules() { ... }
: Mengembalikan array aturan validasi.public function messages() { ... }
: Mengembalikan array pesan error kustom.
3. Menggunakan Request Object dalam Controller
Setelah request object dibuat, Anda dapat menggunakannya dalam controller Anda dengan mengganti class Request
dengan class request object yang Anda buat.
<?php
namespace AppHttpControllers;
use AppHttpRequestsStoreOrderRequest;
class OrderController extends Controller
{
public function store(StoreOrderRequest $request)
{
// Validasi sudah dilakukan secara otomatis oleh StoreOrderRequest
// Lakukan proses penyimpanan order jika validasi berhasil
// ...
}
}
Penjelasan Kode:
use AppHttpRequestsStoreOrderRequest;
: Mengimpor request objectStoreOrderRequest
.public function store(StoreOrderRequest $request) { ... }
: MenggantiRequest $request
denganStoreOrderRequest $request
. Laravel akan secara otomatis menjalankan validasi yang didefinisikan dalamStoreOrderRequest
sebelum methodstore()
dieksekusi. Jika validasi gagal, Laravel akan secara otomatis mengembalikan response error kepada pengguna.
Contoh Kasus Lainnya untuk Custom Validation di Laravel
Berikut adalah beberapa contoh kasus lain di mana custom validation sangat berguna:
- Validasi Nomor Telepon: Memvalidasi format nomor telepon berdasarkan negara. Anda dapat menggunakan regular expression atau library pihak ketiga untuk melakukan validasi ini.
- Validasi Tanggal dan Waktu: Memvalidasi apakah tanggal dan waktu berada dalam rentang tertentu atau sesuai dengan format yang diharapkan.
- Validasi File Upload: Memvalidasi tipe file, ukuran file, dan konten file.
- Validasi Alamat Email Domain Tertentu: Memvalidasi apakah alamat email menggunakan domain yang diperbolehkan (misalnya, hanya memperbolehkan email dengan domain
@example.com
). - Validasi Password Strength: Memvalidasi apakah password memenuhi kriteria kekuatan tertentu (misalnya, minimal 8 karakter, mengandung huruf besar, huruf kecil, angka, dan simbol).
Kesimpulan: Kekuatan dan Fleksibilitas Validasi Kustom
Custom validation di Laravel memberikan Anda kekuatan dan fleksibilitas untuk membuat aturan validasi yang sesuai dengan kebutuhan spesifik aplikasi Anda. Dengan menggunakan rule object, closure-based validation, dan request object, Anda dapat membuat kode validasi yang bersih, mudah dipelihara, dan mudah diuji. Pesan error yang jelas dan informatif akan meningkatkan pengalaman pengguna dan membantu mereka untuk memperbaiki kesalahan dengan mudah. Selalu pertimbangkan penggunaan validasi kustom saat validasi bawaan Laravel tidak cukup untuk menangani kompleksitas aturan bisnis aplikasi Anda. Dengan memahami dan mengimplementasikan custom validation di Laravel Bahasa Indonesia, Anda dapat membangun aplikasi web yang lebih robust, aman, dan andal.