From 216d4791ce98092ba7ea7b58995365ae1990068e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 27 Feb 2017 21:41:27 +0100 Subject: [PATCH 1/2] Add an example of custom filter --- core/filters.md | 99 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 94 insertions(+), 5 deletions(-) diff --git a/core/filters.md b/core/filters.md index 6c88bc64129..369292c0a0b 100644 --- a/core/filters.md +++ b/core/filters.md @@ -396,15 +396,104 @@ 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: + +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: + +```php + Date: Tue, 28 Feb 2017 21:29:00 +0100 Subject: [PATCH 2/2] Fix @Simperfit's comments --- core/filters.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/filters.md b/core/filters.md index 369292c0a0b..b08f3f27547 100644 --- a/core/filters.md +++ b/core/filters.md @@ -398,7 +398,7 @@ interface. 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. +persistence system's internals - you have to create the filtering logic by yourself. ### Creating Custom Doctrine ORM Filters @@ -472,7 +472,7 @@ services: tags: [ { name: 'api_platform.filter', id: 'regexp' } ] ``` -Finally, add this filter to resources you want: +Finally, add this filter to resources you want to be filtered: ```php