diff --git a/core/filters.md b/core/filters.md index 4dbfb01444a..8c8c41d1303 100644 --- a/core/filters.md +++ b/core/filters.md @@ -152,7 +152,7 @@ constant directly. The boolean filter allows you to search on boolean fields and values. -Syntax: `?property=[on|off|true|false|0|1]` +Syntax: `?property=[true|false|1|0]` You can either use TRUE or true, the parameters are case insensitive. @@ -422,15 +422,105 @@ It means that the filter will be **silently** ignored if the property: Custom filters can be written by implementing the `ApiPlatform\Core\Api\FilterInterface` interface. -If you use [custom data providers](data-providers.md), they must support filtering and be aware of active filters to work -properly. +API Platform provides a convenient way to create Doctrine ORM filters. If you use [custom data providers](data-providers.md), +you can still create filters by implementing the previously mentioned interface, but - as API Platform isn't aware of your +persistence system's internals - you have to create the filtering logic by yourself. ### Creating Custom Doctrine ORM Filters -Doctrine ORM filters must implement the `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\FilterInterface`. -They can interact directly with the Doctrine `QueryBuilder`. +Doctrine filters can access to the HTTP request (Symfony's `Request` object) and to the `QueryBuilder` instance used to +retrieve data from the database. They are only applied to collections. If you want to deal with the DQL query generated +to retrieve items, or don't need to access the HTTP request, [extensions](extensions.md) are the way to go. -A convenient abstract class is also shipped with the bundle: `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter` +A Doctrine ORM filter is basically a class implementing the `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\FilterInterface`. +API Platform includes a convenient abstract class implementing this interface and providing utility methods: `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter` + +In the following example, we create a class to filter a collection by applying a regexp to a property. The `REGEXP` DQL +function used in this example can be found in the [`DoctrineExtensions`](https://github.com/beberlei/DoctrineExtensions) +library. This library must be properly installed and registered to use this example (works only with MySQL). + +```php +generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters + $queryBuilder + ->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName)) + ->setParameter($parameterName, $value); + } + + // This function is only used to hook in documentation generators (supported by Swagger and Hydra) + public function getDescription(string $resourceClass): array + { + $description = []; + foreach ($this->properties as $property => $strategy) { + $description['regexp_'.$property] = [ + 'property' => $property, + 'type' => 'string', + 'required' => false, + 'swagger' => ['description' => 'Filter using a regex. This will appear in the Swagger documentation!'], + ]; + } + + return $description; + } +} +``` + +Then, register this filter as a service: + +```yaml +services: + 'AppBundle\Filter\RegexpFilter': + class: 'AppBundle\Filter\RegexpFilter' + autowire: true # See the next example for a plain old definition + tags: [ { name: 'api_platform.filter', id: 'regexp' } ] +``` + +In the previous example, the filter can be applied on any property. However, thanks to the `AbstractFilter` class, +it can also be enabled for some properties: + +```yaml +services: + 'AppBundle\Filter\RegexpFilter': + class: 'AppBundle\Filter\RegexpFilter' + arguments: [ '@doctrine', '@request_stack', '@?logger', { email: ~, anOtherProperty: ~ } ] + tags: [ { name: 'api_platform.filter', id: 'regexp' } ] +``` + +Finally, add this filter to resources you want to be filtered: + +```php + - +