├── .editorconfig ├── CHANGELOG.md ├── CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── query_filters.php ├── src ├── Console │ └── Commands │ │ └── MakeQueryFiltersCommand.php ├── FiltersRecords.php ├── Providers │ └── QueryFiltersServiceProvider.php └── QueryFilters.php └── stubs ├── filter.stub └── query_filters.stub /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_size = 4 9 | indent_style = space 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All Notable changes to `query-filters` will be documented in this file. 4 | 5 | Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. 6 | 7 | 8 | ## 1.8.0 - 2021-05-18 9 | 10 | ### Changed 11 | - Minor adjustments to support Laravel Octane. 12 | 13 | 14 | ## 1.7.0 - 2021-01-14 15 | 16 | ### Added 17 | - Support for PHP 8. 18 | 19 | ### Changed 20 | - Migrated from Travis to GitHub actions. 21 | - Code style from PSR-2 to PSR-12. 22 | 23 | 24 | ## 1.6.0 - 2020-10-15 25 | 26 | ### Added 27 | - Support for Laravel 8. 28 | 29 | 30 | ## 1.5.0 - 2020-07-14 31 | 32 | ### Added 33 | - Values of filters can be validated: only filters that pass the validation are applied. 34 | 35 | 36 | ## 1.4.1 - 2020-03-04 37 | 38 | ### Added 39 | - Support for Laravel 7. 40 | 41 | 42 | ## 1.4.0 - 2019-09-22 43 | 44 | ### Added 45 | - The Artisan console command can generate classes populated with filters. 46 | - Automatic determination of implicit filters 47 | - Support for Laravel 6. 48 | - Method to retrieve the request that query filters are based on. 49 | 50 | ### Removed 51 | - Need to list implicit filters. 52 | 53 | 54 | ## 1.3.1 - 2017-08-16 55 | 56 | ### Fixed 57 | - Filters are considered implicit also if they have null values. 58 | 59 | 60 | ## 1.3.0 - 2017-08-15 61 | 62 | ### Added 63 | - Skip implicit filters by default. 64 | - Register implicit filters not to be skipped. 65 | 66 | 67 | ## 1.2.1 - 2016-11-19 68 | 69 | ### Removed 70 | - Support for PHP 5.5. 71 | 72 | 73 | ## 1.2.0 - 2016-11-19 74 | 75 | ### Added 76 | - Artisan command to generate query filters. 77 | - Configuration file to set the path of generated query filters. 78 | 79 | ## 1.1.0 - 2016-07-25 80 | 81 | ### Added 82 | - Static method to hydrate the filters from plain array. 83 | 84 | 85 | ## 1.0.0 - 2016-04-26 86 | 87 | ### Added 88 | - Abstract class to extend for implementing query filters. 89 | - Trait to let Eloquent models use in order to filter their records. 90 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. 4 | 5 | We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. 6 | 7 | Examples of unacceptable behavior by participants include: 8 | 9 | * The use of sexualized language or imagery 10 | * Personal attacks 11 | * Trolling or insulting/derogatory comments 12 | * Public or private harassment 13 | * Publishing other's private information, such as physical or electronic addresses, without explicit permission 14 | * Other unethical or unprofessional conduct. 15 | 16 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. 17 | 18 | This code of conduct applies both within project spaces and in public spaces when an individual is representing the project or its community in a direct capacity. Personal views, beliefs and values of individuals do not necessarily reflect those of the organisation or affiliated individuals and organisations. 19 | 20 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers. 21 | 22 | This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.2.0, available at [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) 23 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are **welcome** and will be fully **credited**. 4 | 5 | We accept contributions via Pull Requests on [Github](https://github.com/cerbero90/query-filters). 6 | 7 | 8 | ## Pull Requests 9 | 10 | - **[PSR-12 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-12-extended-coding-style-guide.md)** - The easiest way to apply the conventions is to install [PHP Code Sniffer](http://pear.php.net/package/PHP_CodeSniffer). 11 | 12 | - **Add tests!** - Your patch won't be accepted if it doesn't have tests. 13 | 14 | - **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. 15 | 16 | - **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. 17 | 18 | - **Create feature branches** - Don't ask us to pull from your master branch. 19 | 20 | - **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. 21 | 22 | - **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. 23 | 24 | 25 | ## Running Tests 26 | 27 | ``` bash 28 | $ composer test 29 | ``` 30 | 31 | 32 | **Happy coding**! 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Andrea Marco Sartori 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Query Filters 2 | 3 | [![Author][ico-author]][link-author] 4 | [![PHP Version][ico-php]][link-php] 5 | [![Laravel Version][ico-laravel]][link-laravel] 6 | [![Octane Compatibility][ico-octane]][link-octane] 7 | [![Build Status][ico-actions]][link-actions] 8 | [![Coverage Status][ico-scrutinizer]][link-scrutinizer] 9 | [![Quality Score][ico-code-quality]][link-code-quality] 10 | [![Latest Version][ico-version]][link-packagist] 11 | [![Software License][ico-license]](LICENSE.md) 12 | [![PSR-12][ico-psr12]][link-psr12] 13 | [![Total Downloads][ico-downloads]][link-downloads] 14 | 15 | [![SensioLabsInsight][ico-sensiolabs]][link-sensiolabs] 16 | 17 | Query Filters was fully inspired by [this lesson on Laracasts](https://laracasts.com/series/eloquent-techniques/episodes/4), it provides a simple way to filter Eloquent models based on query parameters of an HTTP request. 18 | 19 | ## Install 20 | 21 | Via Composer: 22 | 23 | ``` bash 24 | composer require cerbero/query-filters 25 | ``` 26 | 27 | If your version of Laravel is prior to 5.5, you can register this package service provider by adding the following line to the list of providers in `config/app.php`: 28 | 29 | ``` php 30 | 'providers' => [ 31 | ... 32 | Cerbero\QueryFilters\Providers\QueryFiltersServiceProvider::class, 33 | ] 34 | ``` 35 | 36 | This package includes a generator for query filter classes that by default are generated in `app/QueryFilters`. If you prefer a different path, you can set it in the `config/query_filters.php` file after running: 37 | 38 | ``` bash 39 | php artisan vendor:publish --tag=query_filters_config 40 | ``` 41 | 42 | ## Usage 43 | 44 | Imagine to have a route for indexing all actors stored in the database. This route accepts query parameters to filter records, for example: 45 | 46 | ``` 47 | /actors?won_oscar&acting=0&acted-in=2000 48 | ``` 49 | 50 | In this case the route will need to display only actors who won at least one Oscar, are no longer acting but acted in 2000. 51 | 52 | This can be achieved by generating a query filters class and optionally defining the allowed query parameters and related variable names via the following Artisan command: 53 | 54 | ``` bash 55 | php artisan make:query-filters ActorFilters 'won_oscar&acting=bool&acted-in=year' 56 | ``` 57 | 58 | That command will generate and populate with filters the `ActorFilters` class: 59 | 60 | ``` php 61 | use Cerbero\QueryFilters\QueryFilters; 62 | 63 | /** 64 | * Filter records based on query parameters. 65 | * 66 | */ 67 | class ActorFilters extends QueryFilters 68 | { 69 | /** 70 | * Filter records based on the query parameter "won_oscar" 71 | * 72 | * @return void 73 | */ 74 | public function wonOscar() 75 | { 76 | // $this->query 77 | } 78 | 79 | /** 80 | * Filter records based on the query parameter "acting" 81 | * 82 | * @param mixed $bool 83 | * @return void 84 | */ 85 | public function acting($bool) 86 | { 87 | // $this->query 88 | } 89 | 90 | /** 91 | * Filter records based on the query parameter "acted-in" 92 | * 93 | * @param mixed $year 94 | * @return void 95 | */ 96 | public function actedIn($year) 97 | { 98 | // $this->query 99 | } 100 | } 101 | ``` 102 | 103 | Please note how filter names are the equivalent camel case form of their related query parameters. 104 | 105 | Filters are only applied if their query parameter is present in the HTTP request with a non-empty value, unless they need no value to function (e.g. `won_oscar`). 106 | 107 | The `$query` property lets filters determine how queries change when they are applied: 108 | 109 | ``` php 110 | public function wonOscar() 111 | { 112 | $this->query->where('oscars', '>', 0); 113 | } 114 | 115 | public function acting($bool) 116 | { 117 | $this->query->where('acting', $bool); 118 | } 119 | 120 | public function actedIn($year) 121 | { 122 | $this->query->whereHas('movies', function ($movies) use ($year) { 123 | $movies->whereYear('release_date', '=', $year); 124 | }); 125 | } 126 | ``` 127 | 128 | After filters are defined, Eloquent models can apply them by using the `FiltersRecords` trait: 129 | 130 | ``` php 131 | use Cerbero\QueryFilters\FiltersRecords; 132 | use Illuminate\Database\Eloquent\Model; 133 | 134 | class Actor extends Model 135 | { 136 | use FiltersRecords; 137 | } 138 | ``` 139 | 140 | Finally in your route you can filter actors by calling the method `filterBy()` of your model and passing the query filters: 141 | 142 | ``` php 143 | use App\Actor; 144 | use App\QueryFilters\ActorFilters; 145 | 146 | ... 147 | 148 | public function index(ActorFilters $filters) 149 | { 150 | return Actor::filterBy($filters)->get(); 151 | } 152 | ``` 153 | 154 | Alternatively you can hydrate query filters from a plain array: 155 | 156 | ``` php 157 | use App\Actor; 158 | use App\QueryFilters\ActorFilters; 159 | use Illuminate\Http\Request; 160 | 161 | ... 162 | 163 | public function index(Request $request) 164 | { 165 | $filters = ActorFilters::hydrate($request->query()); 166 | 167 | return Actor::filterBy($filters)->get(); 168 | } 169 | ``` 170 | 171 | Sometimes you may want to silently skip filters if their value is not valid. Instead of setting validation rules in HTTP requests, you may define them in the query filters class. 172 | 173 | This avoids a failed validation to stop the filtering process and applies only valid filters while ignoring filters with values that do not pass the validation: 174 | 175 | ```php 176 | class ActorFilters extends QueryFilters 177 | { 178 | protected function getRules() 179 | { 180 | return [ 181 | 'acting' => 'bool', 182 | 'acted-in' => 'int|digits:4', 183 | ]; 184 | } 185 | } 186 | ``` 187 | 188 | ## Change log 189 | 190 | Please see [CHANGELOG](CHANGELOG.md) for more information what has changed recently. 191 | 192 | ## Testing 193 | 194 | ``` bash 195 | composer test 196 | ``` 197 | 198 | ## Contributing 199 | 200 | Please see [CONTRIBUTING](CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. 201 | 202 | ## Security 203 | 204 | If you discover any security related issues, please email andrea.marco.sartori@gmail.com instead of 205 | using the issue tracker. 206 | 207 | ## Credits 208 | 209 | - [Jeffrey Way](https://github.com/JeffreyWay) 210 | - [Laracasts](https://laracasts.com) 211 | - [Andrea Marco Sartori][link-author] 212 | - [All Contributors][link-contributors] 213 | 214 | ## License 215 | 216 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 217 | 218 | [ico-author]: https://img.shields.io/static/v1?label=author&message=cerbero90&color=50ABF1&logo=twitter&style=flat-square 219 | [ico-php]: https://img.shields.io/packagist/php-v/cerbero/query-filters?color=%234F5B93&logo=php&style=flat-square 220 | [ico-laravel]: https://img.shields.io/static/v1?label=laravel&message=%E2%89%A55.4&color=ff2d20&logo=laravel&style=flat-square 221 | [ico-octane]: https://img.shields.io/static/v1?label=octane&message=compatible&color=ff2d20&logo=laravel&style=flat-square 222 | [ico-version]: https://img.shields.io/packagist/v/cerbero/query-filters.svg?label=version&style=flat-square 223 | [ico-actions]: https://img.shields.io/github/workflow/status/cerbero90/query-filters/build?style=flat-square&logo=github 224 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square 225 | [ico-psr12]: https://img.shields.io/static/v1?label=compliance&message=PSR-12&color=blue&style=flat-square 226 | [ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/cerbero90/query-filters.svg?style=flat-square&logo=scrutinizer 227 | [ico-code-quality]: https://img.shields.io/scrutinizer/g/cerbero90/query-filters.svg?style=flat-square&logo=scrutinizer 228 | [ico-downloads]: https://img.shields.io/packagist/dt/cerbero/query-filters.svg?style=flat-square 229 | [ico-sensiolabs]: https://insight.sensiolabs.com/projects/fe5cb80b-d49f-46e6-b94b-79c6087b5c13/big.png 230 | 231 | [link-author]: https://twitter.com/cerbero90 232 | [link-php]: https://www.php.net 233 | [link-laravel]: https://laravel.com 234 | [link-octane]: https://github.com/laravel/octane 235 | [link-packagist]: https://packagist.org/packages/cerbero/query-filters 236 | [link-actions]: https://github.com/cerbero90/query-filters/actions?query=workflow%3Abuild 237 | [link-psr12]: https://www.php-fig.org/psr/psr-12/ 238 | [link-scrutinizer]: https://scrutinizer-ci.com/g/cerbero90/query-filters/code-structure 239 | [link-code-quality]: https://scrutinizer-ci.com/g/cerbero90/query-filters 240 | [link-downloads]: https://packagist.org/packages/cerbero/query-filters 241 | [link-sensiolabs]: https://insight.sensiolabs.com/projects/fe5cb80b-d49f-46e6-b94b-79c6087b5c13 242 | [link-contributors]: ../../contributors 243 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cerbero/query-filters", 3 | "type": "library", 4 | "description": "Filter Laravel Eloquent models based on query parameters.", 5 | "keywords": [ 6 | "cerbero", 7 | "query-filters", 8 | "laravel", 9 | "query", 10 | "filters", 11 | "eloquent" 12 | ], 13 | "homepage": "https://github.com/cerbero90/query-filters", 14 | "license": "MIT", 15 | "authors": [{ 16 | "name": "Andrea Marco Sartori", 17 | "email": "andrea.marco.sartori@gmail.com", 18 | "homepage": "https://github.com/cerbero90", 19 | "role": "Developer" 20 | }], 21 | "require": { 22 | "php": "^5.6||^7.0||^8.0", 23 | "illuminate/http": ">=5.4", 24 | "illuminate/database": ">=5.4", 25 | "illuminate/console": ">=5.4", 26 | "illuminate/support": ">=5.4" 27 | }, 28 | "require-dev": { 29 | "orchestra/testbench": ">=3.4", 30 | "phpunit/phpunit": ">=5.4", 31 | "squizlabs/php_codesniffer": "^3.0", 32 | "mockery/mockery": "^1.3" 33 | }, 34 | "autoload": { 35 | "psr-4": { 36 | "Cerbero\\QueryFilters\\": "src" 37 | } 38 | }, 39 | "autoload-dev": { 40 | "psr-4": { 41 | "Cerbero\\QueryFilters\\": "tests" 42 | } 43 | }, 44 | "scripts": { 45 | "test": "phpunit", 46 | "check-style": "phpcs --standard=PSR12 src tests", 47 | "fix-style": "phpcbf --standard=PSR12 src tests" 48 | }, 49 | "extra": { 50 | "branch-alias": { 51 | "dev-master": "1.0-dev" 52 | }, 53 | "laravel": { 54 | "providers": [ 55 | "Cerbero\\QueryFilters\\Providers\\QueryFiltersServiceProvider" 56 | ] 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /config/query_filters.php: -------------------------------------------------------------------------------- 1 | 'QueryFilters', 12 | ]; 13 | -------------------------------------------------------------------------------- /src/Console/Commands/MakeQueryFiltersCommand.php: -------------------------------------------------------------------------------- 1 | replaceFilters($stub); 78 | } 79 | 80 | /** 81 | * Replace filters for the given stub 82 | * 83 | * @param string $stub 84 | * @return string 85 | */ 86 | protected function replaceFilters($stub) 87 | { 88 | parse_str($this->argument('filters'), $rawFilters); 89 | 90 | if (empty($rawFilters)) { 91 | return str_replace('DummyFilters', PHP_EOL . ' //' . PHP_EOL, $stub); 92 | } 93 | 94 | $filters = ''; 95 | $filterStub = file_get_contents(__DIR__ . '/../../../stubs/filter.stub'); 96 | 97 | foreach ($rawFilters as $queryParameter => $parameterName) { 98 | $filterName = Str::camel($queryParameter); 99 | $parameterVariable = $parameterName === '' ? '' : '$' . $parameterName; 100 | $parameterDoc = $parameterName === '' ? '' : '@param mixed dummyParameter' . PHP_EOL . ' * '; 101 | $search = ['dummyQueryParameter', 'dummyParameterDoc', 'dummyFilter', 'dummyParameter']; 102 | $replace = [$queryParameter, $parameterDoc, $filterName, $parameterVariable]; 103 | $filters .= str_replace($search, $replace, $filterStub); 104 | } 105 | 106 | return str_replace('DummyFilters', $filters, $stub); 107 | } 108 | 109 | /** 110 | * Get the console command arguments. 111 | * 112 | * @return array 113 | */ 114 | protected function getArguments() 115 | { 116 | return [ 117 | ['name', InputArgument::REQUIRED, 'The name of the class'], 118 | ['filters', InputArgument::OPTIONAL, "The name of the filters e.g. 'won_oscar&acting=bool&acted-in=year'"], 119 | ]; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/FiltersRecords.php: -------------------------------------------------------------------------------- 1 | applyToQuery($query); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/Providers/QueryFiltersServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([ 23 | __DIR__ . '/../../config/query_filters.php' => config_path('query_filters.php'), 24 | ], 'query_filters_config'); 25 | 26 | // merge the published configuration with the package default one 27 | $this->mergeConfigFrom(__DIR__ . '/../../config/query_filters.php', 'query_filters'); 28 | 29 | // register console command when running Artisan 30 | if ($this->app->runningInConsole()) { 31 | $this->commands(MakeQueryFiltersCommand::class); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/QueryFilters.php: -------------------------------------------------------------------------------- 1 | request = $request; 53 | 54 | return $this; 55 | } 56 | 57 | /** 58 | * Retrieve the request that query filters are based on 59 | * 60 | * @return \Illuminate\Http\Request 61 | */ 62 | public function getRequest() 63 | { 64 | if (!isset($this->request)) { 65 | $this->request = RequestFacade::instance(); 66 | } 67 | 68 | return $this->request; 69 | } 70 | 71 | /** 72 | * Hydrate query filters from a plain array. 73 | * 74 | * @param array $queries 75 | * @return static 76 | */ 77 | public static function hydrate(array $queries) 78 | { 79 | $request = new Request($queries); 80 | 81 | return (new static())->setRequest($request); 82 | } 83 | 84 | /** 85 | * Apply filters based on query parameters. 86 | * 87 | * @param \Illuminate\Database\Eloquent\Builder $query 88 | * @return \Illuminate\Database\Eloquent\Builder 89 | */ 90 | public function applyToQuery(Builder $query) 91 | { 92 | $this->query = $query; 93 | 94 | foreach ($this->getRequest()->all() as $filter => $value) { 95 | if ($this->filterCanBeApplied($filter, $value)) { 96 | call_user_func([$this, Str::camel($filter)], $value); 97 | } 98 | } 99 | 100 | return $query; 101 | } 102 | 103 | /** 104 | * Determine whether the given filter can be applied with the provided value. 105 | * 106 | * @param string $filter 107 | * @param mixed $value 108 | * @return boolean 109 | */ 110 | protected function filterCanBeApplied($filter, $value) 111 | { 112 | $method = Str::camel($filter); 113 | 114 | // do not apply query filters that haven't been implemented 115 | if (!method_exists($this, $method)) { 116 | return false; 117 | } 118 | 119 | // apply query filters with valid values 120 | if ($value !== '' && $value !== null) { 121 | $data = $this->getRequest()->only($filter); 122 | $rules = Arr::only($this->getRules(), $filter); 123 | 124 | return !Validator::make($data, $rules)->fails(); 125 | } 126 | 127 | // apply query filters that don't need values (implicit filters) 128 | return (new ReflectionMethod($this, $method))->getNumberOfParameters() === 0; 129 | } 130 | 131 | /** 132 | * Retrieve the rules to validate filters value. 133 | * If a filter validation fails, the filter is not applied. 134 | * 135 | * @return array 136 | */ 137 | protected function getRules() 138 | { 139 | return []; 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /stubs/filter.stub: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Filter records based on the query parameter "dummyQueryParameter" 4 | * 5 | * dummyParameterDoc@return void 6 | */ 7 | public function dummyFilter(dummyParameter) 8 | { 9 | // $this->query 10 | } 11 | -------------------------------------------------------------------------------- /stubs/query_filters.stub: -------------------------------------------------------------------------------- 1 |