Skip to content

Commit

Permalink
Merge branch 'mehdi-dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
mehdi-fathi committed Jun 29, 2024
2 parents c62fa5e + 4a47714 commit 1b557ee
Show file tree
Hide file tree
Showing 12 changed files with 293 additions and 148 deletions.
190 changes: 109 additions & 81 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ although we have a lot of features to make able you to implement your specific s
- [Query Builder](#query-builder-introduction)
- [Magic Methods](#magic-methods)
- [Request Filter](#request-filter)
- [Request Field Cast Filter](#request-field-cast-filter)
- [Response Filter](#response-filter)
- [Black List Detections](#black-list-detections)
- [Macro Methods](#macro-Methods)
Expand Down Expand Up @@ -226,70 +227,6 @@ User::setWhiteListFilter(['name']);
User::addWhiteListFilter('name');
```

### Use in Controller

Change your code the controller of the laravel project as like below example:

```php

namespace App\Http\Controllers;

/**
* Class UsersController.
*/
class UsersController
{

public function list()
{
if (!empty(request()->get('username'))) {

$users = User::ignoreRequest('perpage')
->filter()
->with('posts')
->orderByDesc('id')
->paginate(request()->get('perpage'),['*'],'page');

} else {
$users = User::filter(
['username' => ['mehdi','ali']]
)->with('posts')
->orderByDesc('id')
->paginate(10,['*'],'page');
}
}
}
```
-**Note** The Eloquent Filter config by default uses the query string to make queries in Laravel.
Although, you can set the collection data in the `filter` method Model for making your own custom condition without query string.

-**Note** Therefore you must unset yourself param as perpage. Just you can set page param for paginate this param ignore from the filter.

- You can ignore some request params via use of the bellow code.

```php

User::ignoreRequest(['perpage'])
->filter()
->paginate(request()->get('perpage'), ['*'], 'page');
```

Call `ignoreRequest` that will ignore some requests that you don't want to use in conditions of eloquent filter.
e.g: the perpage param will never be in the conditions eloquent filter.
it's related to the paginate method. `page` param ignore by default in Eloquent Filter of Laravel.

- You can filter some request params as acceptable filter.

```php

User::AcceptRequest(['username','id'])
->filter()
->paginate(request()->get('perpage'), ['*'], 'page');
```

Call `AcceptRequest` will accept requests in which you want to use in conditions Eloquent Filter.
e.g: `username` and `id` key will be in the conditions eloquent filter.

-**Note** Just in case, you must set `$whiteListFilter` in Models. Aim of the method avert to manipulation query string by a bad user.

### Simple Examples
Expand Down Expand Up @@ -835,7 +772,70 @@ currently , It's just a simple feature.

Magic methods are a collection of methods that you can use as a wrapper in the Eloquent Filter.
For example, serialize data before filtering or changing data in response and others.
Now Eloquent Filter have `serializeRequestFilter`,`ResponseFilter`.
Now Eloquent Filter have `serializeRequestFilter`,`ResponseFilter` and , etc.

### Request Methods

Call `ignoreRequest` (static scope) or `ignoreRequestFilter` will ignore some requests that you don't want to use in conditions of eloquent filter.

Change your code the controller of the laravel project as like below example:

```php

$users = User::ignoreRequest(['name'])
->filter()
->with('posts')
->orderByDesc('id')
->paginate(request()->get('perpage'),['*'],'page');

```

```php
$user = new User();
$users = $user->ignoreRequestFilter(['name','family'])
->filter()
->with('posts')
->orderByDesc('id')
->paginate(request()->get('perpage'),['*'],'page');

```

-**Note** The Eloquent Filter config by default uses the query string to make queries in Laravel.
Although, you can set the collection data in the `filter` method Model for making your own custom condition without query string.

-**Note** Therefore you must unset yourself param as perpage. Just you can set page param for paginate this param ignore from the filter.

- You can ignore some request params via use of the bellow code.

```php

User::ignoreRequest(['perpage'])
->filter()
->paginate(request()->get('perpage'), ['*'], 'page');
```

e.g: the `perpage` param will never be in the conditions eloquent filter.
It has to do with to the paginate method. `page` param ignore by default in Eloquent Filter of Laravel.

- You are able to filter some request params as acceptable filter`.

Calling `AcceptRequest` (static scope) or `acceptRequestFilter` will accept requests in which you want to use in conditions Eloquent Filter.
e.g: `username` and `id` key will be in the conditions eloquent filter.

```php
``
User::AcceptRequest(['username','id'])
->filter()
->paginate(request()->get('perpage'), ['*'], 'page');
```

```php

$user = new User();
$user->acceptRequestFilter(['username','id'])
->filter()
->paginate(request()->get('perpage'), ['*'], 'page');
```

### Request Filter

Expand All @@ -848,6 +848,11 @@ SerializeRequestFilter. You just implement `SerializeRequestFilter` method in yo
class User extends Model
{
use Filterable;

private static $whiteListFilter =[
'username'
];

public function serializeRequestFilter($request)
{
$request['username'] = trim($request['username']);
Expand All @@ -859,6 +864,30 @@ class User extends Model
As above code, you can modify every query params of the Model in the method `serializeRequestFilter` before running by Eloquent Filter.
That is a practical method when you want to set user_id or convert date or remove space and others.


### Request Field Cast Filter

Eloquent Filter requires a bunch of specific methods for each of the fields before going on filter process.
This feature has been implemented recently. By this `filterSet` + `field` method in your model, You
will be able to add some change for that particular field.

```php

class Category extends Model
{
use Filterable;

private static $whiteListFilter =[
'desc'
];

public function filterSetDesc($value)
{
return trim($value);
}
}
```

### Response Filter

Response Filter is an overriding method for changing response right after handle by Eloquent Filter. The method called
Expand Down Expand Up @@ -923,18 +952,18 @@ class UsersController

- Below is an order checking conditions list if you use name of them for set a black list.

| Name | Method eloquent | Example |
|-----------------------|-----------------|------------------------------------------|
| WhereCustomCondition | | Your declared custom method of Model |
| SpecialCondition | | support f_params, e.g: limit and order |
| WhereBetweenCondition | whereBetween | |
| WhereByOptCondition | where | where('column', ">", $value) |
| WhereLikeCondition | where | where('column', 'like', $value) |
| WhereInCondition | whereIn | whereIn('column', $value) |
| WhereOrCondition | orWhere | orWhere('column', $value) |
| WhereHas | WhereHas | |
| WhereDateCondition | whereDate | whereDate('column', $value) |
| where | where | where('column', $value) |
| Name | Method eloquent | Example |
|--------------------------|--------------------|--------------------------------------------------|
| WhereCustomCondition | | Your declared custom method of Model |
| SpecialCondition | | support f_params, e.g: limit and order |
| WhereBetweenCondition | whereBetween | |
| WhereByOptCondition | where | where('column', ">", $value) |
| WhereLikeCondition | where | where('column', 'like', $value) |
| WhereInCondition | whereIn | whereIn('column', $value) |
| WhereOrCondition | orWhere | orWhere('column', $value) |
| WhereHas | WhereHas | |
| WhereDateCondition | whereDate | whereDate('column', $value) |
| where | where | where('column', $value) |

- You are able to set on Model layer as well. `black_list_detections` array is used for this purpose.

Expand Down Expand Up @@ -966,11 +995,10 @@ class Car extends Model

e.g:


```php
$users = User::SetCustomDetection([WhereRelationLikeCondition::class])->filter();
echo $users->isUsedEloquentFilter(); // will true
echo $users->getDetectionsInjected(); // will showing a list array of injected objects
$users = User::SetCustomDetection([WhereRelationLikeCondition::class])->filter();
echo $users->isUsedEloquentFilter(); // will true
echo $users->getDetectionsInjected(); // will showing a list array of injected objects
```

## Contributing
Expand Down
8 changes: 8 additions & 0 deletions _ide_helper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Illuminate\Database\Query {
/**
* @method filter(array $filters) Apply filters to the query
*/
class Builder {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
*/
class EloquentModelBuilderWrapper implements QueryBuilderWrapperInterface
{
//todo I think there's no need to use this class for db query builder
/**
* @param mixed $builder
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,6 @@ public function apply($builder, array $ignore_request = null, array $accept_requ

$this->resolveDetections($detections_injected, $black_list_detections);

//todo !!!! We don't support getResponseFilter for the pure query. We can pass a callback for this purpose.
return $this->responseFilter->getResponse();
}

Expand Down
29 changes: 25 additions & 4 deletions src/QueryFilter/Core/FilterBuilder/IO/RequestFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,17 @@
*/
class RequestFilter
{

const CAST_METHOD_SIGN = 'filterSet';
/**
* @var
*/
protected $accept_request;
protected mixed $accept_request = null;

/**
* @var
*/
protected $ignore_request;
protected mixed $ignore_request = null;

/**
* @var array|null
Expand Down Expand Up @@ -93,8 +95,7 @@ public function getRequest(): ?array
/**
* @param array|null $ignore_request
* @param array|null $accept_request
* @param $builder_model
*
* @param $builder_model
* @return array|null
*/
public function setFilterRequests(array $ignore_request = null, array $accept_request = null, $builder_model): ?array
Expand All @@ -112,6 +113,9 @@ public function setFilterRequests(array $ignore_request = null, array $accept_re
}

foreach ($this->getRequest() as $name => $value) {

$value = $this->getCastedMethodValue($name, $builder_model, $value);

if (is_array($value) && !empty($builder_model) && method_exists($builder_model, $name)) {
if (HelperFilter::isAssoc($value)) {
unset($this->request[$name]);
Expand Down Expand Up @@ -229,4 +233,21 @@ public function getIgnoreRequest()
{
return $this->ignore_request;
}

/**
* @param int|string $name
* @param $builder_model
* @param mixed $value
* @return mixed
*/
private function getCastedMethodValue(int|string $name, $builder_model, mixed $value): mixed
{
$castMethod = SELF::CAST_METHOD_SIGN . $name;

if (!empty($builder_model) && method_exists($builder_model, $castMethod)) {
$value = $builder_model->{$castMethod}($value);
$this->request[$name] = $value;
}
return $value;
}
}
3 changes: 2 additions & 1 deletion src/QueryFilter/Core/FilterBuilder/QueryFilterBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function apply($builder, array $request = null, array $ignore_request = n
*/
private function buildExclusiveMacros(?array $detections_injected): void
{
//todo why it's limited to just Eloquent\Builder. We should consider this on db
\Illuminate\Database\Eloquent\Builder::macro('isUsedEloquentFilter', function () {
return config('eloquentFilter.enabled');
});
Expand All @@ -79,7 +80,7 @@ private function buildExclusiveMacros(?array $detections_injected): void
/**
* @return string
*/
public function getNameDriver()
public function getNameDriver(): string
{
$MainBuilderConditions = $this->queryFilterCore->getMainBuilderConditions();

Expand Down
27 changes: 22 additions & 5 deletions src/QueryFilter/ModelFilters/Filterable.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
/**
* Trait Filterable.
*
* @method static Type filter(?array $request = null)
* @method static Type ignoreRequest(?array $request = null)
* @method static Type acceptRequest(?array $request = null)
* @method static Type setCustomDetection(?array $object_custom_detect = null)
* @method static Type setBlackListDetection(?array $black_list_detections = null)
* @method static Builder filter(?array $request = null)
* @method static Builder ignoreRequest(?array $request = null)
* @method static Builder acceptRequest(?array $request = null)
* @method static Builder setCustomDetection(?array $object_custom_detect = null)
* @method static Builder setBlackListDetection(?array $black_list_detections = null)
*/
trait Filterable
{
Expand Down Expand Up @@ -61,17 +61,34 @@ public function scopeFilter($builder, ?array $request = null)
* @param array|null $request
*/
public function scopeIgnoreRequest($builder, ?array $request = null)
{
$this->ignoreRequestFilter($request);
}

public function ignoreRequestFilter(?array $request = null)
{
$this->ignore_request = $request;
return $this;
}

/**
* @param $builder
* @param array|null $request
*/
public function scopeAcceptRequest($builder, ?array $request = null)
{
$this->acceptRequestFilter($request);
}

/**
* @param array|null $request
* @return \eloquentFilter\QueryFilter\ModelFilters\Filterable
*/
public function acceptRequestFilter(?array $request = null)
{
$this->accept_request = $request;
return $this;

}

/**
Expand Down
Loading

0 comments on commit 1b557ee

Please sign in to comment.