Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save laudaikinhdi/be030a016e51f59e2c624e0d4d3a1c7d to your computer and use it in GitHub Desktop.
Save laudaikinhdi/be030a016e51f59e2c624e0d4d3a1c7d to your computer and use it in GitHub Desktop.

Revisions

  1. @MrPunyapal MrPunyapal created this gist Oct 27, 2023.
    62 changes: 62 additions & 0 deletions LaravelWhereLikeMacro.php
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    <?php

    use Illuminate\Support\ServiceProvider;
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Support\Arr;

    class AppServiceProvider extends ServiceProvider
    {
    // ...

    public function boot()
    {
    // Define the 'whereLike' macro
    Builder::macro('whereLike', function ($attributes, string $searchTerm) {
    $this->where(function (Builder $query) use ($attributes, $searchTerm) {
    foreach (Arr::wrap($attributes) as $attribute) {
    $query->when(
    // Check if the attribute is not an expression and contains a dot (indicating a related model)
    !($attribute instanceof \Illuminate\Contracts\Database\Query\Expression) &&
    str_contains((string) $attribute, '.'),
    function (Builder $query) use ($attribute, $searchTerm) {
    // Split the attribute into a relation and related attribute
    [$relation, $relatedAttribute] = explode('.', (string) $attribute);

    // Perform a 'LIKE' search on the related model's attribute
    $query->orWhereHas($relation, function (Builder $query) use ($relatedAttribute, $searchTerm) {
    $query->where($relatedAttribute, 'LIKE', "%{$searchTerm}%");
    });
    },
    function (Builder $query) use ($attribute, $searchTerm) {
    // Perform a 'LIKE' search on the current model's attribute
    // also attribute can be an expression
    $query->orWhere($attribute, 'LIKE', "%{$searchTerm}%");
    }
    );
    }
    });
    });
    }
    }


    // example of usage 👇

    Post::query()
    ->whereLike([
    'title',
    // search in the current model's 'title' attribute
    'description',
    // search in the current model's 'description' attribute
    'user.name',
    // search in the related model's 'name' attribute
    'user.email',
    // search in the related model's 'email' attribute
    DB::raw('DATE_FORMAT(created_at, "%d/%m/%Y")'),
    // search in the formatted 'created_at' attribute
    DB::raw('CONCAT(user.first_name, " ", user.last_name)'),
    // search in the concatenated 'first_name' and 'last_name' attributes
    ], request()->search)
    // search for the request's 'search' query parameter
    ->with('user')
    ->get();