Contoh Simple 'Advance Where' Query Builder di Laravel


Tips laravel kali ini saya akan memberi contoh kode sederhana untuk Searching database pakai Query Builder di laravel.
Misal kita ingin melakukan Search pada sebuah table sebut saja tabel 'artikel'  . mungkin ada sebelumnya ada yang meng-Kode seperti ini
//MyModel.php

public static function getSearch($search=null){
    
    //is_publish : 0 = pending, 1 = published

    $result = DB::table('article')
        ->where('article.is_publish','1')
        ->where('article.title','LIKE','%'.$search.'%')
        ->orWhere('article.content', 'LIKE','%'.$search.'%')
        ->select('*')
        ->orderBy('article.id', 'desc')->paginate(10);

    return $result;
}
Scenario Query diatas adalah mencari Artikel DIMANA artikel itu sudah di Publish (is_publish =1 ) DAN judul artikel seperti '%...%' ATAU konten artikel seperti '%...%' .
SELECT * FROM `article` WHERE `article`.`is_publish` = '1' AND `article`.`title` LIKE '%search%' OR `article`.`content` LIKE '%search%'...
Query diatas tidak error tapi akan memunculkan hasil yang salah dimana Artikel yang is_publish = 0 juga ikut muncul. Untuk membuatnya benar, kita harus membuat kode seperti berikut
public static function getSearch($search=null){
    
    //is_publish : 0 = pending, 1 = published

    $result = DB::table('article')
        ->where('article.is_publish','1')
        ->where(function($query) use ($search){

            $query->where('article.title','LIKE','%'.$search.'%')
                  ->orWhere('article.content', 'LIKE','%'.$search.'%');
        })
        ->select('*')
        ->orderBy('article.id', 'desc')->paginate(10);

    return $result;
}
Kode diatas akan menghasilkan Raw query berikut
SELECT * FROM `article` WHERE `article`.`is_publish` = '1' AND (`article`.`title` LIKE '%search%' OR `article`.`content` LIKE '%search%')...

Perhatikan bahwa kita harus menggunakan Closure
....
->where(function($query) use ($search){

    $query->where('article.title','LIKE','%'.$search.'%')
           ->orWhere('article.content', 'LIKE','%'.$search.'%');
 })
sebab kita mengakses variable diluar fungsi.

Contoh Redirect::intended() Di Laravel


Saat user ingin mengakses url di Aplikasi/Web yang membutuhkan Autentifikasi atau harus login dahulu, sebaiknya kita mengarahkan kembali si User ke halaman yang diaksesnya setelah login. Ini sangat penting bagi User Experience aplikasi web kita.

misalnya seorang user ingin mengakses halaman pribadinya sbb :

http://example.com/profile
atau bisa saja halaman yang lain yang memerlukan login seperti

http://example.com/admin
http://example.com/dashboard
http://example.com/edit-profile
...
...
Nah seringkali setelah login (pasca mengakses url diatas) kita redirect/arahkan ke halaman utama seperti ke Home,Admin dsb. Untuk UX yang bagus, kita harus mengarahkan user kembali ke halaman/url yang ia coba akses sebelumnya. 

Untuk melakukan itu, Laravel memberikan kita kemudahan dengan fitur Redirect::intended()
untuk membuat Redirect::intended() berkerja, kita harus mengubah filter.php sbb:

//filter.php
Route::filter('auth', function()
{
    if (Auth::guest()) return Redirect::to('login');
});

menjadi 

//filter.php
Route::filter('auth', function()
{
    if (Auth::guest()) return Redirect::guest('login');
});

Redirect::guest() akan otomatis menambahkan Session untuk menyimpan url yang sebelumnya diakses. Jika sudah kita tinggal merubah Login handler nya. 

//AuthController.php

public function doLogin(){
        
   //check auth
   if(Auth::attempt(Input::all())){

       return Redirect::intended(); //see this line
            
   }else{
            
      return Redirect::to('login')->with('error', 'Invalid username or password')->withInput();
   }
        
}

Route nya seperti biasa

//route profile
Route::get('profile',array('uses'=>'UserController@myProfile','before'=>'auth'));

//route login
Route::post('/login', array('uses' => 'AuthController@doLogin'));
Jika sudah silahkan test . misal user akses url dalam keadaan belum login

http://example.com/profile
akan di redirect ke halaman Login, lalu setelah Login akan kembali ke halaman Profile dengan url

http://example.com/profile

Sekian, semoga bermanfaat.


Tips Error Handling Sederhana Pada Query Builder Laravel


Jika kamu lebih memilh pakai Query builder di Laravel ketimbang Eloquent, saya ada dipihak kamu :D karena saya juga pakai query Builder untuk kebanyakan aktifitas Query di Aplkikasi Laravel saya.
Nah biasanya bawaan Koding dari lahir mungkin yah :D, saat query Insert,Update,Delete mungkin ada yang masih seperti ini
public function doUpdate($data){

    $data = array(
     'nama' => $data['nama'],
     'alamar' => $data['alamar']
    );

    //Auth::user()->id : Session logged user    $update = DB::table('user')->where('user_id',Auth::user()->id)
                                  ->update($data);
    if($update)
        return Redirect::to('user/profile');
     else
        //blablaa...
}
atau seperti ini
public function doUpdate($data){

    $data = array(
     'nama' => $data['nama'],
     'alamar' => $data['alamar']
    );

    //Auth::user()->id : Session logged user    $update = DB::table('user')->where('user_id',Auth::user()->id)
                                  ->update($data);
    if(!$update){

        //redirect with error
        return Redirect::to('user/profile')->with('error_update',true);
    
     }
     else
       return Redirect::to('user/profile');
}
Untuk Update, Delete pakai Query builder di laravel, return nya berupa Affected rows. jadi Query di atas kurang tepat dan dapat menimbulkan masalah.
Secara sederhana bisa kita handle sperti ini saja
public function doUpdate($data){

    $data = array(
     'nama' => $data['nama'],
     'alamar' => $data['alamar']
    );

    //Auth::user()->id : Session logged user

    try{
        DB::table('user')->where('user_id',Auth::user()->id)->update($data);

    }catch(\Exception $e){

        //Log akan disimpan di STorage/logs/laravel.log
        Log::error('Cannot process update : '.$e->getMessage());
        //redirect with Error
        return Redirect::to('user/profile')->with('error_update',true);
   }

   //redirect success
   return Redirect::to('user/profile')->with('success_update',true);
  
}
dengan try catch kita bisa menentukan kapan Query kita berhasil atau tidak
CMIIW

Tips Login dengan Username atau Email di Laravel


Tak jarang kita menyertakan Username dan Email di form registrasi seperti ini
Email : 
Username : 
Password :
....

lalu setelah user sukses registrasi biasanya kita minta Login dengan menyertakan Username saja dan password. Namun tak jarang bisa menyertakan baik Username atau Email beserta password seperti ini :





Jadi user bisa login dengan Username atau email nya. Tips simple ini sebenarnya di PHP native atau di framewok yang lain juga bisa.
berikut cara simple nya di Laravel

#AuthController.php
public function doLogin(){
   
   $username = Input::get('username');
   $password = Input::get('password'); 

   $field = filter_var($username, FILTER_VALIDATE_EMAIL) ? 'email':'username';
   
   if(Auth::attempt(array($field => $username,'password' => $password)))
   {
      return Redirect::intended();            
   }
   else
   {           
       return Redirect::to('login')->with('error', 'Invalid username/email or password')
->withInput();
   }


}//end of function
     
Form login nya cukup seperti biasa
<input type="text" name="username" placeholder="Email or username...">
<input type="password" name="password" placeholder="password..."

Penjelasan : 
 perhatikan kode berikut :
if(Auth::attempt(array($field => $username,'password' => $password)))

Secara default Auth::attempt() membutuhkan (normalnya) 2 input-tan yakni username dan password . Kita hanya perlu membuat field username flexible saja .
filter_var($username, FILTER_VALIDATE_EMAIL) ? 'email':'username';
dengan method diatas field username telah kita buat dinamis dan otomatis nge-Cek apakah yang diinput itu email atau bukan.

Sekian Tips kali ini. Happy coding !!!