{"id":13828325,"url":"https://github.com/aldemeery/sieve","last_synced_at":"2026-02-05T06:33:51.419Z","repository":{"id":54722636,"uuid":"174006912","full_name":"aldemeery/sieve","owner":"aldemeery","description":"A simple, clean and elegant way to filter Eloquent models.","archived":false,"fork":false,"pushed_at":"2025-03-13T03:18:28.000Z","size":184,"stargazers_count":136,"open_issues_count":0,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-11-04T02:19:33.741Z","etag":null,"topics":["eloquent","filter","filtration","laravel"],"latest_commit_sha":null,"homepage":null,"language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aldemeery.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-03-05T19:22:22.000Z","updated_at":"2025-09-22T18:59:02.000Z","dependencies_parsed_at":"2022-08-14T00:50:26.237Z","dependency_job_id":null,"html_url":"https://github.com/aldemeery/sieve","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/aldemeery/sieve","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldemeery%2Fsieve","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldemeery%2Fsieve/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldemeery%2Fsieve/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldemeery%2Fsieve/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aldemeery","download_url":"https://codeload.github.com/aldemeery/sieve/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aldemeery%2Fsieve/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29114910,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T05:31:32.482Z","status":"ssl_error","status_checked_at":"2026-02-05T05:31:29.075Z","response_time":65,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eloquent","filter","filtration","laravel"],"created_at":"2024-08-04T09:02:41.461Z","updated_at":"2026-02-05T06:33:51.403Z","avatar_url":"https://github.com/aldemeery.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"# Sieve - Clean \u0026 Easy Eloquent Filtration\n\n\u003cp\u003e\n\u003ca href=\"https://github.com/aldemeery/sieve/actions\"\u003e\u003cimg src=\"https://github.com/aldemeery/sieve/actions/workflows/tests.yml/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/aldemeery/sieve\"\u003e\u003cimg src=\"https://img.shields.io/packagist/dt/aldemeery/sieve?label=Downloads\" alt=\"Total Downloads\"\u003e\u003c/a\u003e\n\u003ca href=\"https://packagist.org/packages/aldemeery/sieve\"\u003e\u003cimg src=\"https://img.shields.io/packagist/v/aldemeery/sieve?label=Latest+Version\"\" alt=\"Latest Version\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/aldemeery/sieve/blob/master/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/packagist/l/aldemeery/sieve?label=License\"\" alt=\"License\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n* [Installation](#installation)\n* [Usage](#usage)\n  * [Creating Filters](#creating-filters)\n  * [Filtering](#filtering)\n  * [Mapping Values](#mapping-values)\n\nA minimalist, ultra-lightweight package for clean, intuitive query filtering.\n\nWith Sieve, your filtration logic is simplified from something like this:\n\n```php\npublic function index(Request $request)\n{\n    $query = Product::query();\n\n    if ($request-\u003ehas('color')) {\n        $query-\u003ewhere('color', $request-\u003eget('color'));\n    }\n\n    if ($request-\u003ehas('condition')) {\n        $query-\u003ewhere('condition', $request-\u003eget('condition'));\n    }\n\n    if ($request-\u003ehas('price')) {\n        $direction = $request-\u003eget('price') === 'highest' ? 'desc' : 'asc';\n        $query-\u003eorderBy('price', $direction);\n    }\n\n    return $query-\u003eget();\n}\n```\n\nto this:\n\n```php\npublic function index(Request $request)\n{\n    return Product::filter($request-\u003equery())-\u003eget();\n}\n```\n\n---\n\n## Installation\n\n\u003e [!IMPORTANT]\n\u003e This package requires Laravel 11.0 or higher and PHP 8.2 or higher.\n\nYou can install the package via composer:\n\n```bash\ncomposer require aldemeery/sieve\n```\n\n---\n\n## Usage\n\nEnabling filtration for a model is as easy as adding the `Aldemeery\\Sieve\\Concerns\\Filterable` trait to it:\n\n```php\nuse Aldemeery\\Sieve\\Concerns\\Filterable;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Product extends Model\n{\n    use Filterable;\n\n    // ...\n}\n```\nThe `Filterable` trait introduces a `filter` [local scope](https://laravel.com/docs/eloquent#local-scopes) to your model, which accepts an associative array for filtration:\n\n```php\npublic function index(Request $request)\n{\n    return Product::filter($request-\u003equery())-\u003eget();\n}\n```\n\nNow you're ready to create your filter classes.\n\n---\n\n### Creating filters\n\nTo create a filter, create a class that implements the `Aldemeery\\Sieve\\Contracts\\Filter` interface.\n\nYou can either create a filter class using the `make:filter` artisan command, which will place the filter in the `app/Http/Filters` directory.\nAlternatively, you can create a filter class manually and place it wherever you prefer:\n\n```bash\nphp artisan make:filter Product/ColorFilter\n```\n\nThis generates a `ColorFilter` class in the `app/Filters/Product` directory:\n\n```php\n\u003c?php\n\nnamespace App\\Filters\\Product;\n\nuse Aldemeery\\Sieve\\Contracts\\Filter;\nuse Illuminate\\Database\\Eloquent\\Builder;\n\n/** @implements Filter\u003c\\App\\Models\\Product\u003e */\nclass ColorFilter implements Filter\n{\n    public function map(mixed $value): mixed\n    {\n        return match ($value) {\n            default =\u003e $value,\n        };\n    }\n\n    public function apply(Builder $query, mixed $value): void\n    {\n        // $query-\u003ewhere('id', $value);\n    }\n}\n```\n\nHere, `apply` defines the filtration logic, while `map` can transform input values if needed before passing them to `apply`\n\n\u003e [!IMPORTANT]\n\u003e Before a value is passed to the `apply` method, it's first passed to the `map` method.\n\u003e\n\u003e If you do not need to map values into other values, you should just leave the `map` method as it is.\n\nCheck out this examples:\n\n```php\npublic function map(mixed $value): mixed\n{\n    return match ($value) {\n        'yes' =\u003e true,\n        'no' =\u003e false,\n        '1' =\u003e true,\n        '0' =\u003e true,\n        default =\u003e $value,\n    };\n}\n\npublic function apply(Builder $query, mixed $value): void\n{\n    // Assuming filter was called like this: Product::filter(['in_stock' =\u003e 'yes'])-\u003eget();\n    // Or like this: Product::filter(['in_stock' =\u003e '1'])-\u003eget();\n    // In both cases, $value would be `true`\n\n    $query-\u003ewhere('in_stock', $value);\n}\n```\n\nWith an instance of `Illuminate\\Database\\Eloquent\\Builder` passed to `apply`, you gain access to its full capabilities, allowing you to perform a wide range of operations:\n\n#### Example 1 - Ordering:\n\n```php\npublic function apply(Builder $query, mixed $value): void\n{\n    $query-\u003eorderBy('price', $value);\n}\n```\n\n#### Example 2 - Relations:\n\n```php\npublic function apply(Builder $query, mixed $value): void\n{\n    $query-\u003ewhereHas('category', function($query) use ($value): void {\n        $query-\u003ewhere('name', $value);\n    });\n}\n```\n\n---\n\n### Filtering\n\nOnce you have created your filters and defined your filtration logic, It's time now to actually use the filter, which can be done in two ways:\n- [Passing a filters array](#passing-a-filters-array) as a second parameter to the `filter` scope.\n- [Defining model filters](#defining-model-filters) inside the model itself.\n\n#### Passing a filters array:\n\nUse this when you want to apply a filter to a single query:\n\n```php\npublic function index(Request $request)\n{\n    return Product::filter($request-\u003equery(), [\n        // \"color\" here is the key to be used in the query string\n        // e.g. https://example.com/products?color=red\n        \"color\" =\u003e \\App\\Filters\\Product\\ColorFilter::class,\n    ])-\u003eget();\n}\n```\n\nIn the above example, the `ColorFilter` is applied *only* for this query.\n\n#### Defining model filters:\nAlternatively, if you want a filter to be associated with a model and applied every time the filter method is called, you can add a `filters` method to your model that returns an array mapping keys to their corresponding filter classes:\n\n```php\n\u003c?php\n\nnamespace App\\Models;\n\nuse Aldemeery\\Sieve\\Concerns\\Filterable;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass Product extends Model\n{\n    use Filterable;\n\n    /** @return array\u003cstring, string\u003e */\n    private function filters(): array\n    {\n        return [\n            'color' =\u003e \\App\\Filters\\Product\\ColorFilter::class,\n        ];\n    }\n}\n```\n\nNow everytime you call the `filter` method on the model, you will have the `ColorFilter` applied to your query:\n\n```php\npublic function index(Request $request)\n{\n    // The `ColorFilter` filter is applied.\n    return Product::filter($request-\u003equery())-\u003eget();\n}\n```\n\n\u003e [!IMPORTANT]\n\u003e Only filters with keys present in the data array will be applied. Any filters not included in the array will be ignored.\n\u003e\n\u003e For instance, if your filter array includes only the `color` key, only the corresponding `ColorFilter` will be executed, while any other filters will have no effect on the query.\n\n---\n\n### Mapping Values\nIn some cases, you may want to use more user-friendly values that do not directly correspond to the values needed for filtration.\nThis is where the map method comes in handy.\n\nBefore any value reaches the `apply` method, it is first processed by the map method.\nThis allows you to transform incoming values into something more meaningful for your application.\n\n#### Example:\nImagine you want to sort products by price but using the query string, but you prefer using labels like `..?price=lowest` or `..?price=highest` instead of technical terms like `..?price=asc` or `..?price=desc`.\n\nYou can achieve this by using the `map` method, as shown below:\n\n```php\n\u003c?php\n\nnamespace App\\Filters\\Product;\n\nuse Aldemeery\\Sieve\\Contracts\\Filter;\nuse Illuminate\\Database\\Eloquent\\Builder;\n\n/** @implements Filter\u003c\\App\\Models\\Product\u003e */\nclass PriceFilter implements Filter\n{\n    public function map(mixed $value): mixed\n    {\n        return match ($value) {\n            'lowest' =\u003e 'asc',\n            'highest' =\u003e 'desc',\n            default =\u003e $value,\n        };\n    }\n\n    public function apply(Builder $query, mixed $value): void\n    {\n        // After mapping, $value will be 'asc' for 'lowest' and 'desc' for 'highest'.\n        $query-\u003eorderBy('price', $value);\n    }\n}\n```\n\nWith this implementation, you can present a more intuitive interface to users while maintaining the necessary functionality for sorting in your queries.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldemeery%2Fsieve","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faldemeery%2Fsieve","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faldemeery%2Fsieve/lists"}