Skip to content

Commit

Permalink
add custom filtering documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
esbenp committed Apr 15, 2016
1 parent 6e99b81 commit fcf823b
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 4 deletions.
108 changes: 106 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ The examples will be of a hypothetical resource endpoint `/books` which will ret
each belonging to a `Author`.

```
Book 1-----n Author
Book n ----- 1 Author
```

### Available query parameters
Expand Down Expand Up @@ -167,7 +167,7 @@ filters | array | Array of filters (see syntax below)

Property | Value type | Description
-------- | ---------- | -----------
key | string | The property of the model to filter by
key | string | The property of the model to filter by (can also be custom filter)
value | mixed | The value to search for
operator | string | The filter operator to use (see different types below)
not | boolean | Negate the filter
Expand All @@ -193,6 +193,110 @@ null (string) | The property will be checked for NULL value

#### Custom filters

Remember our relationship `Books n ----- 1 Author`. Imagine your want to
filter books by `Author` name.

```json
[
{
"filters": [
{
"key": "author",
"value": "Optimus",
"operator": "sw"
}
]
}
]
```

Now that is all good, however there is no `author` property on our
model since it is a relationship. This would cause an error since
Eloquent would try to use a where clause on the non-existant `author`
property. We can fix this by implementing a custom filter. Where
ever you are using the `EloquentBuilderTrait` implement a function named
`filterAuthor`

```php
public function filterAuthor(Builder $query, $method, $clauseOperator, $value, $in)
{
if ($in) {
call_user_func([$query, $method], 'authors.name', $value);
} else {
call_user_func([$query, $method], 'authors.name', $clauseOperator, $value);
}
}
```

*Note:* It is important to note that a custom filter will look for a relationship with
the same name of the property. E.g. if trying to use a custom filter for a property
named `author` then Bruno will try to eagerload the `author` relationship from the
`Book` model.

**Custom filter function**

Argument | Description
-------- | -----------
$query | The Eloquent query builder
$method | The where method to use (`where`, `orWhere`, `whereIn`, `orWhereIn` etc.)
$clauseOperator | Can operator to use for non-in wheres (`!=`, `=`, `>` etc.)
$value | The filter value
$in | Boolean indicating whether or not this is an in-array filter

#### Examples

```json
[
{
"or": true,
"filters": [
{
"key": "author",
"value": "Optimus",
"operator": "sw"
},
{
"key": "author",
"value": "Prime",
"operator": "ew"
}
]
}
]
```

Books with authors whoose name start with `Optimus` or ends with `Prime`.

```json
[
{
"filters": [
{
"key": "author",
"value": "Brian",
"operator": "sw"
}
]
},
{
"filters": [
{
"key": "year",
"value": 1990,
"operator": "gt"
},
{
"key": "year",
"value": 2000,
"operator": "lt"
}
]
}
]
```

Books with authors whoose name start with Brian and which were published between years 1990 and 2000.

## Standards

This package is compliant with [PSR-1], [PSR-2] and [PSR-4]. If you notice compliance oversights,
Expand Down
4 changes: 2 additions & 2 deletions src/EloquentBuilderTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ protected function applyFilter(Builder $query, array $filter, $or = false, array
case 'ew':
$valueString = [
'ct' => '%'.$value.'%', // contains
'ew' => '%'.$value, // starts with
'sw' => $value.'%' // ends with
'ew' => '%'.$value, // ends with
'sw' => $value.'%' // starts with
];

$databaseField = DB::raw(sprintf('CAST(%s AS TEXT)', $key));
Expand Down

0 comments on commit fcf823b

Please sign in to comment.