Skip to content

StydeNet/laravel-query-filter

Repository files navigation

StydeForm

Query Filter

Latest Version on Packagist Quality Score Total Downloads

Let your users filter your database queries in a safe and easy way.

Installation

You can install the package via composer:

composer require styde/query-filter

Usage

You can use make:query to create a new QueryClass or you can use make:filter to create a new FilterClass.

Once these classes are created, you must be able to incorporate the logic that you require within them. Remember, the FilterClass serves as a filter for queries made from requests.

Something that you must bear in mind is that your Query class must be associated with the model for which you created it, this is vital so that your filters work otherwise you will get errors.

I will show you an example of use, thinking about the User model.

Command make:query
php artisan make:query UserQuery

This command will create a php file named User Query with the following structure.

<?php

namespace App\Queries;

use Styde\QueryFilter\QueryBuilder;

class UserQuery extends QueryBuilder
{
    //
}
Command make:query
php artisan make:query UserFilter

This command will create a php file named User Filter with the following structure.

<?php

namespace App\Filters;

use Styde\QueryFilter\AbstractFilter;

class UserFilter extends AbstractFilter
{
    /**
     * Get the validation rules that apply to the request filter.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            //
        ];
    }
}

Once you have created these classes you must associate the QueryClass to the model in question as follows. Also if you don't want to create a QueryClass you can use the BaseQuery Styde\LaravelQueryFilter\QueryBuilder from which the queries created by command extends.

<?php

namespace App\Models;

use App\Filters\UserFilter;
use App\Queries\UserQuery;

class User extends Authenticatable
{
    //

    // We associate the query
    public function newEloquentBuilder($query)
    {
        return new UserQuery($query);
    }

    // We associate the filter
    public function newQueryFilter()
    {
        return new UserFilter;
    }
}

or

<?php

namespace App\Models;

use App\Filters\UserFilter;
use Styde\QueryFilter\QueryBuilder;

class User extends Authenticatable
{
    //

    // We associate the query
    public function newEloquentBuilder($query)
    {
        return new QueryBuilder($query);
    }

    // We associate the filter
    public function newQueryFilter()
    {
        return new UserFilter;
    }
}

Once this is done, we are going to create a basic query filter and a basic query that will help us search for a user by email.

In your UserQuery file
<?php

namespace App\Queries;

use Styde\QueryFilter\QueryBuilder;

class UserQuery extends QueryBuilder
{
    public function findByEmail($email)
    {
        return $this->where(compact('email'))->first();
    }
}

Now you can use this query wherever you want in the following way:

// Anywhere in your project

$user = User::query()->findByEmail('[email protected]');
In your UserFilter file

Normally the filters are applied when we make a list of records, commonly the index method of our controller, we will use that case to explain the filters.

<?php

namespace App\Filters;

use Styde\QueryFilter\AbstractFilter;

class UserFilter extends AbstractFilter
{
    /**
     * Get the validation rules that apply to the request filter.
     *
     * @return array
     */
    public function rules(): array
    {
        return [
            'search' => 'filled'
        ];
    }

    public function search($query, $value)
    {
        return $query->where('email', 'like', "{$value}%")
            ->orWhere('name', 'like', "{$value}%");
    }
}

In your UserController

<?php

namespace App\Http\Controllers;

class UserController extends Controller
{
    public function index()
    {
        $users = User::query()->applyFilters()->paginate();

        return view('users.index', compact('users'));
    }
}

This way you are returning the filtered records.

Remember
  • The filters that are applied are the ones passed by the rules in UserFilter, if you want to add more filters you must, put in rules the name of the input that arrives in the request, and create a function in your filter with the name of the input in camelCase.

  • If you have more than one class of filters for the same model, you can apply it from the controller passing it as dependency injection, even if you want to pass your own values you can do it by passing an array of key => value as the second parameter.

Example

In your UserController

<?php

namespace App\Http\Controllers;

use Styde\QueryFilter\Support\Sortable;

class UserController extends Controller
{
    public function index()
    {
        $otherData = [...];

        $users = User::query()->applyFilters(new OtherUserFilter(), $otherData)->paginate();

        return view('users.index', compact('users'));
    }

    // If you want to use the sort functionality on a collection 
    // and not on paginated data, 
    // you need to inject or instantiate the sortable support class.

    public function index(Sortable $sortable)
    {
        $otherData = [...];

        $users = User::query()->applyFilters(new OtherUserFilter(), $otherData)->get();

        return view('users.index', compact('users', 'sortable'));
    }
}

Changelog

Please see CHANGELOG for more information what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security

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

Credits

License

The MIT License (MIT). Please see License File for more information.

Laravel Package Boilerplate

This package was generated using the Laravel Package Boilerplate.

About

Apply filters to your queries using eloquent.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages