tiagomichaelsousa/laravelfilters

Laravel Filters is a package that allows to filter eloquent models in a clean way.

v1.6.0 2024-09-03 15:49 UTC

This package is auto-updated.

Last update: 2024-11-03 16:24:33 UTC


README

Laravel Filters

Packagist Version Packagist Downloads Build Status Style Status Licence All Contributors Code Quality Code Coverage

Laravel Filters is a package based in a Laracasts video made by JeffreyWay. This package allows to filter eloquent models in a clean and simple way.

Installation

  1. Install the package via Composer:

    $ composer require tiagomichaelsousa/laravelfilters

    The package will automatically register its service provider.

  2. Optionally, publish the configuration file if you want to change any defaults:

    php artisan vendor:publish --provider="tiagomichaelsousa\LaravelFilters\LaravelFiltersServiceProvider" --tag="config"

Usage

Create the filter

$ php artisan make:filter <name>

This command will create a new filter class in the namespace defined on the configuration file.

Updating your Eloquent Models

Your models should use the Filterable trait, which has two scopes filter() and resolve().

use tiagomichaelsousa\LaravelFilters\Traits\Filterable;

class User extends Authenticatable
{
    use Filterable;
}

The filter() method receives the query builder and the instance of the class responsible for the filter methods.

The resolve() method works like an helper. It verifies if the request has the query string paginate=x and if its present it return the response with pagination, otherwise it will return the data.

Creating your Filters

When you make the request to an endpoint the QueryFilter class (that UserFilters extends from) verifies if there is any method with the name that you sent in the request query string.

The php artisan make:filter <name> comes with a default search method that you can delete if you want. When you make a request to /api/users?search=Foobar the QueryFilter class will call the search method because the key search is present in both the request and UserFilters class.

use tiagomichaelsousa\LaravelFilters\QueryFilters;

class UserFilters extends QueryFilters
{
    /**
     * Search all.
     *
     * @param  string  $query
     * @return Builder
     */
    public function search($value = '')
    {
        return $this->builder->where('name', 'like', '%' . $value . '%');
    }
}

The search method applies the queries to the builder instance. With that said you can combine multiple clauses. For example, if you want the search method to filter the data from the name and last_name fields on the db just add the orWhere clause.

/**
 * Search all.
 *
 * @param  string  $query
 * @return Builder
 */
public function search($value = '')
{
    return $this->builder
                ->where('name', 'like', '%' . $value . '%')
                ->orWhere('last_name', 'like', '%' . $value . '%');
}

If you want to add more filters, just add a new method to the class, put the logic for the filter and send it trough the request query string.

You can also filter data through eloquent relationships. For example, filter users from a country_code /api/users?country=PT

/**
 * Filter by country.
 *
 * @param  string $country
 * @return Builder
 */
public function country($country)
    {
    return $this->builder->whereHas('address', function ($query) use ($country) {
        $query->where('country_code', $country);
    });
}

Updating your Controllers

class UserControllerAPI extends Controller
{
    /**
     * Display a listing of the users.
     *
     * @param  \App\Filters\UserFilters  $filters
     * @return \App\Http\Resources\Collections\UserCollection
     */
    public function index(UserFilters $filters)
    {
        $users = User::filter($filters)->resolve();

        return new UserCollection($users);
    }

The filter() method can be called in every instance of a model that uses the Filterable Trait. So imagine that you have a model Meeting and this Meeting has many users. You can filter the users from the Meeting this way:

class MeetingUsersControllerAPI extends Controller
{
    /**
     * Display a listing of the users from a meeting.
     *
     * @param  \App\Filters\UserFilters  $filters
     * @return \App\Http\Resources\Collections\UserCollection
     */
    public function index(Meeting $meeting, UserFilters $filters)
    {
        $users = $meeting->users()->filter($filters)->resolve();

        return new UserCollection($users);
    }

A filter could be instantiated also by providing an associative array:

$users = User::filter(new UserFilters(['search' => 'john']))->resolve();

Change log

Please see the changelog for more information on what has changed recently.

Testing

$ composer test

With test coverage

$ composer test-report

Contributing

Please see contributing.md for details and a todolist.

Security

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

Credits

License

License MIT. Please see the license file for more information.

Code Of Conduct

Please see the code of conduct for more information.

Contributors ✨

Thanks goes to these wonderful people (emoji key):

This project follows the all-contributors specification. Contributions of any kind welcome!