Skip to content

Commit c0ddfa0

Browse files
committed
Update filter.md
1 parent 9956bb8 commit c0ddfa0

File tree

1 file changed

+46
-59
lines changed

1 file changed

+46
-59
lines changed

core/filters.md

Lines changed: 46 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,33 @@
11
# Filters
22

3-
The bundle provides a generic system to apply filters on collections. Useful filters
4-
for the Doctrine ORM are provided with the bundle. However the filter system is
5-
extensible enough to let you create custom filters that would fit your specific needs
6-
and for any data provider.
3+
API Platform Core provides a generic system to apply filters on collections. Useful filters for the Doctrine ORM are provided
4+
with the library. You can also create custom filters that would fit your specific needs.
5+
You can also add filtering support to your custom [data providers](data-providers.md) by implementing interfaces provided
6+
by the library.
77

88
By default, all filters are disabled. They must be enabled explicitly.
99

10-
When a filter is enabled, it is automatically documented as a `hydra:search` property
11-
in collection returns. It also automatically appears in the NelmioApiDoc documentation
12-
if this bundle is active.
10+
When a filter is enabled, it is automatically documented as a `hydra:search` property in the collection response. It also
11+
automatically appears in the [NelmioApiDoc documentation](nelmio-api-doc.md) if it is available.
1312

1413
## Search filter
1514

16-
If Doctrine ORM support is enabled, adding filters is as easy as adding an entry
17-
in your `app/config/services.yml` file and adding a Attributes in your entity.
15+
If Doctrine ORM support is enabled, adding filters is as easy as registering a filter service in your `app/config/services.yml`
16+
file and adding an attribute to your resource configuration.
1817

19-
The search filter supports `exact`, `partial`, `start`, `end`, and `word_start` matching strategies.
20-
- `partial` strategy uses `LIKE %text%` to search for fields that containing the text.
21-
- `start` strategy uses `LIKE text%` to search for fields that starts with text.
22-
- `end` strategy uses `LIKE %text` to search for fields that ends with text.
23-
- `word_start` strategy uses `LIKE text% OR LIKE % text%` to search for fields that contains the word starting with `text`.
18+
The search filter supports `exact`, `partial`, `start`, `end`, and `word_start` matching strategies:
2419

25-
Prepend the letter `i` to the filter if you want it to be case insensitive. For example `ipartial` or `iexact`. Note that this will use the `LOWER` function and **will** impact performances if there is no [*function-based index*](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search).
20+
* `partial` strategy uses `LIKE %text%` to search for fields that containing the text.
21+
* `start` strategy uses `LIKE text%` to search for fields that starts with text.
22+
* `end` strategy uses `LIKE %text` to search for fields that ends with text.
23+
* `word_start` strategy uses `LIKE text% OR LIKE % text%` to search for fields that contains the word starting with `text`.
24+
25+
Prepend the letter `i` to the filter if you want it to be case insensitive. For example `ipartial` or `iexact`. Note that
26+
this will use the `LOWER` function and **will** impact performances if there is no [*function-based index*](http://use-the-index-luke.com/sql/where-clause/functions/case-insensitive-search).
27+
28+
Case insensitivity may already be enforced at the database level depending on the [collation](https://en.wikipedia.org/wiki/Collation)
29+
used. If you are using MySQL, note that the commonly used `utf8_unicode_ci` collation (and its sibling `utf8mb4_unicode_ci`)
30+
are already case insensitive, as indicated by the `_ci` part in their names.
2631

2732
In the following example, we will see how to allow the filtering of a list of e-commerce offers:
2833

@@ -37,7 +42,6 @@ services:
3742
```
3843
3944
```php
40-
<?php
4145
// src/AppBundle/Entity/Offer.php
4246

4347
namespace AppBundle\Entity;
@@ -70,22 +74,19 @@ services:
7074
tags: [ { name: 'api_platform.filter', id: 'offer.search' } ]
7175
```
7276
73-
With this service definition, it is possible to find all offers belonging to the
74-
product identified by a given IRI.
77+
With this service definition, it is possible to find all offers belonging to the product identified by a given IRI.
7578
Try the following: `http://localhost:8000/api/offers?product=/api/products/12`
7679
Using a numeric ID is also supported: `http://localhost:8000/api/offers?product=12`
7780

78-
Previous URLs will return all offers for the product having the following IRI as
79-
JSON-LD identifier (`@id`): `http://localhost:8000/api/products/12`.
81+
Previous URLs will return all offers for the product having the following IRI as JSON-LD identifier (`@id`): `http://localhost:8000/api/products/12`.
8082

8183
## Date filter
8284

8385
The date filter allows to filter a collection by date intervals.
8486

8587
Syntax: `?property[<after|before>]=value`
8688

87-
The value can take any date format supported by the [`\DateTime()`](http://php.net/manual/en/datetime.construct.php)
88-
class.
89+
The value can take any date format supported by the [`\DateTime` constructor](http://php.net/manual/en/datetime.construct.php).
8990

9091
As others filters, the date filter must be explicitly enabled:
9192

@@ -121,12 +122,12 @@ class Offer
121122
The date filter is able to deal with date properties having `null` values.
122123
Four behaviors are available at the property level of the filter:
123124

124-
| Description | Strategy to set |
125-
|--------------------------------------|-------------------------------------------------------------------------------|
126-
| Use the default behavior of the DBMS | `null` |
127-
| Exclude items | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::EXCLUDE_NULL` (`0`) |
128-
| Consider items as oldest | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::INCLUDE_NULL_BEFORE` (`1`) |
129-
| Consider items as youngest | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::INCLUDE_NULL_AFTER` (`2`) |
125+
Description | Strategy to set
126+
-------------------------------------|------------------------------------------------------------------------------------
127+
Use the default behavior of the DBMS | `null`
128+
Exclude items | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::EXCLUDE_NULL` (`exclude_null`)
129+
Consider items as oldest | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::INCLUDE_NULL_BEFORE` (`include_null_before`)
130+
Consider items as youngest | `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::INCLUDE_NULL_AFTER` (`include_null_after`)
130131

131132
For instance, exclude entries with a property value of `null`, with the following service definition:
132133

@@ -136,12 +137,12 @@ For instance, exclude entries with a property value of `null`, with the followin
136137
services:
137138
offer.date_filter:
138139
parent: 'api_platform.doctrine.orm.date_filter'
139-
arguments: [ { dateProperty: ~ } ]
140+
arguments: [ { dateProperty: 'exclude_null' } ]
140141
tags: [ { name: 'api_platform.filter', id: 'offer.date' } ]
141142
```
142143

143-
If you use another service definition format than YAML, you can use the
144-
`ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::EXCLUDE_NULL` constant directly.
144+
If you use a service definition format other than YAML, you can use the `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\DateFilter::EXCLUDE_NULL`
145+
constant directly.
145146

146147
## Order filter
147148

@@ -177,10 +178,11 @@ class Offer
177178
}
178179
```
179180

180-
Given that the collection endpoint is `/offers`, you can filter offers by name in
181-
ascending order and then by ID in descending order with the following query: `/offers?order[name]=desc&order[id]=asc`.
181+
Given that the collection endpoint is `/offers`, you can filter offers by name in ascending order and then by ID in descending
182+
order with the following query: `/offers?order[name]=desc&order[id]=asc`.
182183

183-
By default, whenever the query does not specify the direction explicitly (e.g: `/offers?order[name]&order[id]`), filters will not be applied unless you configure a default order direction to use:
184+
By default, whenever the query does not specify the direction explicitly (e.g: `/offers?order[name]&order[id]`), filters
185+
will not be applied unless you configure a default order direction to use:
184186

185187
```yaml
186188
# app/config/services.yml
@@ -230,7 +232,7 @@ class Offer
230232

231233
Given that the collection endpoint is `/offers`, you can filter offers by boolean with the following query: `/offers?isAvailableGenericallyInMyCountry=true`.
232234

233-
It will return all offers with `isAvailableGenericallyInMyCountry` equals true
235+
It will return all offers where `isAvailableGenericallyInMyCountry` equals `true`.
234236

235237
## Numeric Filter
236238

@@ -285,9 +287,8 @@ api_platform:
285287

286288
## Filtering on nested properties
287289

288-
Sometimes, you need to be able to perform filtering based on some linked resources
289-
(on the other side of a relation). All built-in filters support nested properties
290-
using the dot (`.`) syntax, e.g.:
290+
Sometimes, you need to be able to perform filtering based on some linked resources (on the other side of a relation). All
291+
built-in filters support nested properties using the dot (`.`) syntax, e.g.:
291292

292293
```yaml
293294
# app/config/services.yml
@@ -309,10 +310,9 @@ or order offers by the product's release date: `http://localhost:8000/api/offers
309310

310311
## Enabling a filter for all properties of a resource
311312

312-
As we have seen in previous examples, properties where filters can be applied must be
313-
explicitly declared. But if you don't care about security and performance (ex:
314-
an API with restricted access), it's also possible to enable builtin filters for
315-
all properties:
313+
As we have seen in previous examples, properties where filters can be applied must be explicitly declared. If you don't
314+
care about security and performance (e.g. an API with restricted access), it is also possible to enable built-in filters
315+
for all properties:
316316

317317
```yaml
318318
# app/config/services.yml
@@ -343,8 +343,8 @@ It means that the filter will be **silently** ignored if the property:
343343
Custom filters can be written by implementing the `ApiPlatform\Core\Api\FilterInterface`
344344
interface.
345345

346-
If you use [custom data providers](data-providers.md), they must support filtering and be aware of active filters to
347-
work properly.
346+
If you use [custom data providers](data-providers.md), they must support filtering and be aware of active filters to work
347+
properly.
348348

349349
### Creating custom Doctrine ORM filters
350350

@@ -355,12 +355,10 @@ A convenient abstract class is also shipped with the bundle: `ApiPlatform\Core\B
355355

356356
### Overriding extraction of properties from the request
357357

358-
You can change the way the filter parameters are extracted from the request. This can be done by extending the parent
359-
filter class and overriding the `extractProperties(\Symfony\Component\HttpFoundation\Request $request)`
358+
You can change the way the filter parameters are extracted from the request. This can be done by overriding the `extractProperties(\Symfony\Component\HttpFoundation\Request $request)`
360359
method.
361360

362-
In the following example, we will completely change the syntax of the order filter
363-
to be the following: `?filter[order][property]`
361+
In the following example, we will completely change the syntax of the order filter to be the following: `?filter[order][property]`
364362

365363
```php
366364
// src/AppBundle/Filter/CustomOrderFilter.php
@@ -390,16 +388,5 @@ services:
390388
tags: [ { name: 'api_platform.filter', id: 'offer.order' } ]
391389
```
392390

393-
Beware: in [some cases](https://github.com/dunglas/DunglasApiBundle/issues/157#issuecomment-119576010) you may have to use double slashes in the class path to make it work:
394-
395-
```
396-
# app/config/services.yml
397-
398-
services:
399-
offer.custom_order_filter:
400-
class: 'AppBundle\Filter\CustomOrderFilter'
401-
tags: [ { name: 'api_platform.filter', id: 'offer.order' } ]
402-
```
403-
404391
Previous chapter: [Data providers](data-providers.md)<br>
405392
Next chapter: [Serialization groups and relations](serialization-groups-and-relations.md)

0 commit comments

Comments
 (0)