Skill Level
Intermediate
Categories
Web Development
Reading Time
7 minutes, 51 seconds
Technology
PHP
Framework
Laravel
Library
No library
Laravel Advanced search? Facade? Local Scopes? Here we go!

Dalam sebuah website entah itu Blog atau E-Commerce fitur search merupakan bagian terpenting tapi apa yang berjalan di belakang layar tidak kalah penting, Selain optimasi code, clean code & flexibility juga harus di perhatikan dalam men-design sebuah Software.

Mungkin basic search seperti ini ya, Saya punya model Blog jadi misal untuk membuat fitur search blog post saya akan membuat kode seperti dibawah ini ke dalam BlogController

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Blog;

class BlogController extends Controller
{
    public function search(Request $request) {
        return Blog::where('title', 'LIKE', '%' . $request->q . '%')
                    ->orWhere('body', 'LIKE', '%' . $request->q . '%')
                    ->get();
    }
}

Gak ada masalah si, dan work juga lancar, tapi, kalo misalnya search nya mau dipakai lagi di page lain? di route lain? atau bahkan di API? apakah kita mau nulis ulang codenya? Kalo mau si ga masalah wkwkwk, tapi kan bad practice, Lalu gimana solusinya?? Kita akan pakai Local Scope!

Blog::search('keyword')->get()

 

Karena resultnya adalah instance dari query builder, bahkan kamu bisa Paginate resultnya!

Lalu bagaimana cara membuatnya? Mudah saja, semua local scope Laravel harus return Query Builder instance, & di prefix menggunakan scope jadimisalnya kamu ingin membuat scope search maka nama methodnya adalah scopeSearch(), nah scope itu sendiri menerima 2 parameter, Parameter pertama yaitu instance query builder, parameter kedua dan selanjutnya bisa kamu tambahkan sesuai kebutuhan.

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    public function scopeSearch($query, $queryString) {
        return $query->where('title', 'LIKE', '%'. $queryString .'%')
                     ->orWhere('body', 'LIKE', '%' . $queryString . '%');
    }
}

pada code di atas yaitu pada method scopeSearch() terdapat 2 parameter, seperti yang saya jelaskan di atas, parameter pertama adalah instance dari query builder, jadi kamu bisa akses method seperti where(), orWhere(),limit(), bahkan join() selengkapnya dapat kamu baca di Query Builder Documentation untuk semua method yang tersedia.

Untuk menggunakanya, kamu tidak perlu assign parameter pertama/query builder instance-nya, karena secara otomatis sudah di resolve oleh Laravel sendiri, jadi misalnya kamu membuat method seperti dibawah ini.

public function scopeArticlePublished($query, $category, $date) {
        ...
}

dan kamu menggunakanya seperti dibawah ini

Blog::articlePublished($category, $date);

Code di atas hanya memiliki 2 parameter kan? yatu $category & $date padahal di scope nya membutuhkan 3 parameter, yaitu, $query, $category, & $date ,, Tapi tidak apa-apa, karna parameter $query secara otomatis akan di resolve oleh Laravel, jadi kamu cukup memenuhi parameter ke-dua dan seterusnya saja.

Kira-kira seperti itu konsep dari Laravel Local Scope, Untuk lebih jelasnya atau penjelasan resmi dari Laravel, silahkan menuju ke Dokumentasi nya di Eloquent: Query Scopes .

Facade!

Siapa yang tak kenal facade? kalo belum kenal, ayo kenalan dulu, Pernahkah kamu menulis code Auth::user() atau Auth::check() atau File::put() atau DB::table('tabl')->where().... atau.. udah ah. itu adalah Built in Laravel Facade, tapi apakah kita bisa membuat custom facade? Tentu saja 😀 mari kita transform query scope kita ke Facade! Yeeyy!

Sebelum mulai membuat Facade saya asumsikan pembaca sudah paham minimal mengerti sedikit tentang Laravel Service Container, jika belum silahkan baca dokumentasinya atau bisa baca series tentang LSC di kodinger dengan mengunjungi link di Laravel Service Container .

Facade pada dasarnya adalah alias dari sebuah class yang di Short kan supaya pemanggilanya simple daripada harus mengingat namespace yang sangat panjang, bayangkan saja kalau harus menulis kode seperti

\Illuminate\Support\Facades\Auth::user()->isAdmin()

hanya untuk mengetahui bahwa user tersebut adalah admin, nah dengan alias kita cukup menulisnya seperti ini Auth::user()->isAdmin() simple kan?

Pertama kita akan membuat class untuk facade nya, terserah mau di simpan di mana, yang penting dapat di load oleh PSR-4 saya prefer membuat folder baru di app jadi simpan di folder app/Facades.

App/Facades/Search.php

<?php 

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Search extends Facade {

    protected static function getFacadeAccessor() {
        return 'search';
    }

}

Saat kita bind sebuah instance ke service container kita akan men-assign sebuah instance kedalam sebuah key seperti

$this->app->bind('serach', SearchFactory::class);

nah, sama juga konsepnya dengan facade, saat Aliasnya dipanggil misal Auth::check() itu dibelakang layar laravel akan memanggil method getFacadeAccessor() yang return search pada kasus kali ini, lalu cek ke service container apakah ada instance yang di bind dengan key search lalu jika ada maka akan memanggil method check() dari instance tersebut.

Setekah kita membuat facade accessor nya, selanjutnya kita akan membuat Facade wrapper nya, yaitu class dimana kita akan membuat method untuk facade kita.

App/Facades/SearchFactory.php

<?php 

namespace App\Facades;

use App\Blog;
use App\Product;

class SearchFactory {

    public function blog($query) {
        return Blog::search($query);
    }

    public function product($query) {
        return Product::search($query);
    }

}

Setelah kita membuat SearchFactory sekarang kita akan bind key dari facade accessor dan kita arahkan ke SearchFactory di Service Provider.

/**
* Register any application services.
*
* @return void
*/
public function register()
{
    $this->app->bind('search', SearchFactory::class);
}

nah setelah saling terhubung, saatnya membuat alias! masukan aliasnya ke config/app.php

'aliases' => [
   .........
   'Search' => App\Facades\Search::class,
]

Selesai, Saatnya kita test!

Berhasil! Custom facade berhasil kita buat, lalu setelah proses yang panjang dan membingungkan ini apa yang kita dapat?

Dengan Facade kita dapat membuat code yang lebih clean, tersusun, readable dan lainya, nah, di SearchFactory kamu bisa saja membuat method untuk search product, user, dll, misalnya Search::userById(1) atau Search::product('keyword') atau Search::repository('keyword') dan banyak lagi.

 

Referensi :

Full code dari artikel kali ini dapat kamu lihat di https://github.com/itskodinger/laravel-advanced-search

Topik:

Baca juga post berikut

Mempelajari Dasar HTML DOM Pada JavaScri...

Mengaktifkan Ekstensi Fileinfo Pada PHP

Rizal Fakhri
9 months ago  •  Posted by
Rizal Fakhri
Backend Developer @ Ultrack Technology Sdn Bhd

Pokoknya orangnya ganteng.

Dapatkan notifikasi untuk setiap artikel baru dan jadilah yang pertama tahu!