PHPackages                             backfron/laravel-finder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Search &amp; Filtering](/categories/search)
4. /
5. backfron/laravel-finder

ActiveLibrary[Search &amp; Filtering](/categories/search)

backfron/laravel-finder
=======================

Build and handle complex Eloquent searchs easely.

2.1.0(11mo ago)147↓100%MITPHPPHP ^8.2

Since Oct 2Pushed 11mo ago1 watchersCompare

[ Source](https://github.com/backfron/laravel-finder)[ Packagist](https://packagist.org/packages/backfron/laravel-finder)[ Docs](https://github.com/backfron/laravel-finder)[ RSS](/packages/backfron-laravel-finder/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (3)Versions (9)Used By (0)

LaravelFinder
=============

[](#laravelfinder)

`backfron/laravel-finder` provides an easy way to build complex database searchs in a scalable way using ELoquent. If you have a form with a bunch of fields by which you must filter your data, LaravelFinder maybe suit your needs.

```
// Instead of something like these

$companies = (new App\Models\User)->newQuery();

if (request()->has('city')) {
    $companies->where('city', request('city'));
}

if (request()->has('status')) {
    $companies->where('status', request('status'));
}

if (request()->has('employess_number')) {
    $companies->where('employess_number', 'where('status', $status);
    }
}
```

Of course, you can modify the query to fit your needs. For example:

```
public static function apply(Builder $query, $status)
{
    return $query->where('status', 'LIKE', "{$status}%");
}
```

You can create as many Filters as you need. So for example imagine we created the filters: Status, UserOwnerId and FinishedAt. Then in your controller you can receive a request that includes those fileds in snake\_case version, and pass it to the `filters` static method of your Finder.

```
/*
IMAGINE THIS INCOMING REQUEST
[
    status => 'completed',
    user_owner_id => 123,
    finished_at => '2021-10-01',
]
*/

use App\Finders\Tasks\TaskFinder;

$tasks = TaskFinder::filters([
    'status' => request('status'),
    'user_owner_id' => request('user_owner_id'),
    'finished_at' => request('finished_at'),
])->get();
```

Under the hood, LaravelFinder will take the field names and will call the appropriate Filter. For `status` field the `Status` filter will be called, for `user_owner_id` field the UserOwnerId filter will be called, for the `finished_at` field the `FinishedAt` field will be called an so on.

After setting your filters, you can even call any method that you would normally call in your model instance, that means you can continue chaining Eloquent methods after applying your filters.

```
use App\Finders\Tasks\TaskFinder;
use Illuminate\Support\Facades\Auth;

$tasks = TaskFinder::filters([
    'status' => request('status'),
    'user_owner_id' => request('user_owner_id'),
    'finished_at' => request('finished_at'),
])
->where('user_id', Auth::id())
->get();
```

What happen if a field don't have a match Filter? No worries, by default LaravelFinder will ignore any field that don't match with any of the available filters. You can change these behavior by publishing the config file laravel-finder.php like these:

```
php artisan vendor:publish --tag=laravel-finder.config
```

And once the config file is published at `config/laravel-finder.php`, you may set to `false` the `ignore-unexisting-filters` key. When set to `false` LaravelFinder will throw an `Backfron\LaravelFinder\Exceptions\FilterNotFoundException` exception if you include a filter that don't exists yet.

You even can create your Finder and your filters in one command call.

```
php artisan make:finder TaskFinder --model=Task --filter=Status --filter=UserOwnerId --filter=FinishedAt
```

### Global filters

[](#global-filters)

If you want to apply a **global filter** to your query, you can do it through the `global` method and passing a Closure as parameter.

```
use App\Finders\Tasks\TaskFinder;
use Illuminate\Support\Facades\Auth;

$tasks = TaskFinder::global(function ($query) {
    $query->where('user_owner_id', Auth::id());
})
->filters([
    'status' => request('status'),
    'finished_at' => request('finished_at'),
])->get();
```

In case you want to use some of your created filters as a **global filter** you can do it like this:

```
use App\Finders\Tasks\TaskFinder;
use Illuminate\Support\Facades\Auth;
use App\Finders\Tasks\Filters\Status;

$tasks = TaskFinder::global(Status::class, 'completed')
->filters([
    'user_owner_id' => request('user_owner_id'),
    'finished_at' => request('finished_at'),
])->get();

// Or add many global filters at once
$tasks = TaskFinder::global([
    [Status::class, 'completed'],
    function ($query) {
        $query->where('user_owner_id', Auth::id());
    },
    // ..., MORE
    // ..., GLOBAL
    // ..., FILTERS
])
->filters([
    'finished_at' => request('finished_at'),
])->get();
```

TODO
----

[](#todo)

- Include in the filter file blueprint a condition to avoid the application of the filter if the parameter is empty.

Change log
----------

[](#change-log)

Please see the [changelog](changelog.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [contributing.md](contributing.md) for details and a todolist.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Jairo Ushiña](https://backfron.com)
- [All Contributors](../../contributors)

License
-------

[](#license)

Please see the [license file](license.md) for more information.

###  Health Score

37

—

LowBetter than 84% of packages

Maintenance51

Moderate activity, may be stable

Popularity10

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity68

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~215 days

Recently: every ~315 days

Total

7

Last Release

342d ago

Major Versions

1.1.1 → 2.0.02024-06-12

PHP version history (2 changes)1.0.1PHP ^8.0

2.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/4fe0ea7207e8118e6e8984b665a5164df0414ceaa0513dacd0555719eec98bf4?d=identicon)[jago86](/maintainers/jago86)

---

Top Contributors

[![jago86](https://avatars.githubusercontent.com/u/1690276?v=4)](https://github.com/jago86 "jago86 (22 commits)")

---

Tags

laravelLaravelFinder

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/backfron-laravel-finder/health.svg)

```
[![Health](https://phpackages.com/badges/backfron-laravel-finder/health.svg)](https://phpackages.com/packages/backfron-laravel-finder)
```

###  Alternatives

[baijunyao/laravel-scout-elasticsearch

Elasticsearch Driver for Laravel Scout

8023.6k1](/packages/baijunyao-laravel-scout-elasticsearch)[remoblaser/search

A simple to implement Search for your Application

101.5k](/packages/remoblaser-search)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
