Skip to content

Commit e551c5b

Browse files
authored
Merge pull request #201 from soyuka/master
Merge 2.0 on master
2 parents 2df3b50 + 20c3043 commit e551c5b

File tree

7 files changed

+187
-94
lines changed

7 files changed

+187
-94
lines changed

core/filters.md

Lines changed: 96 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,7 @@ constant directly.
152152

153153
The boolean filter allows you to search on boolean fields and values.
154154

155-
Syntax: `?property=[on|off|true|false|0|1]`
155+
Syntax: `?property=[true|false|1|0]`
156156

157157
You can either use TRUE or true, the parameters are case insensitive.
158158

@@ -422,15 +422,105 @@ It means that the filter will be **silently** ignored if the property:
422422
Custom filters can be written by implementing the `ApiPlatform\Core\Api\FilterInterface`
423423
interface.
424424

425-
If you use [custom data providers](data-providers.md), they must support filtering and be aware of active filters to work
426-
properly.
425+
API Platform provides a convenient way to create Doctrine ORM filters. If you use [custom data providers](data-providers.md),
426+
you can still create filters by implementing the previously mentioned interface, but - as API Platform isn't aware of your
427+
persistence system's internals - you have to create the filtering logic by yourself.
427428

428429
### Creating Custom Doctrine ORM Filters
429430

430-
Doctrine ORM filters must implement the `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\FilterInterface`.
431-
They can interact directly with the Doctrine `QueryBuilder`.
431+
Doctrine filters can access to the HTTP request (Symfony's `Request` object) and to the `QueryBuilder` instance used to
432+
retrieve data from the database. They are only applied to collections. If you want to deal with the DQL query generated
433+
to retrieve items, or don't need to access the HTTP request, [extensions](extensions.md) are the way to go.
432434

433-
A convenient abstract class is also shipped with the bundle: `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter`
435+
A Doctrine ORM filter is basically a class implementing the `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\FilterInterface`.
436+
API Platform includes a convenient abstract class implementing this interface and providing utility methods: `ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter`
437+
438+
In the following example, we create a class to filter a collection by applying a regexp to a property. The `REGEXP` DQL
439+
function used in this example can be found in the [`DoctrineExtensions`](https://github.com/beberlei/DoctrineExtensions)
440+
library. This library must be properly installed and registered to use this example (works only with MySQL).
441+
442+
```php
443+
<?php
444+
445+
// src/AppBundle/Filter/RegexpFilter.php
446+
447+
namespace AppBundle\Filter;
448+
449+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\AbstractFilter;
450+
use ApiPlatform\Core\Bridge\Doctrine\Orm\Util\QueryNameGeneratorInterface;
451+
use Doctrine\ORM\QueryBuilder;
452+
453+
final class RegexpFilter extends AbstractFilter
454+
{
455+
protected function filterProperty(string $property, $value, QueryBuilder $queryBuilder, QueryNameGeneratorInterface $queryNameGenerator, string $resourceClass, string $operationName = null)
456+
{
457+
$parameterName = $queryNameGenerator->generateParameterName($property); // Generate a unique parameter name to avoid collisions with other filters
458+
$queryBuilder
459+
->andWhere(sprintf('REGEXP(o.%s, :%s) = 1', $property, $parameterName))
460+
->setParameter($parameterName, $value);
461+
}
462+
463+
// This function is only used to hook in documentation generators (supported by Swagger and Hydra)
464+
public function getDescription(string $resourceClass): array
465+
{
466+
$description = [];
467+
foreach ($this->properties as $property => $strategy) {
468+
$description['regexp_'.$property] = [
469+
'property' => $property,
470+
'type' => 'string',
471+
'required' => false,
472+
'swagger' => ['description' => 'Filter using a regex. This will appear in the Swagger documentation!'],
473+
];
474+
}
475+
476+
return $description;
477+
}
478+
}
479+
```
480+
481+
Then, register this filter as a service:
482+
483+
```yaml
484+
services:
485+
'AppBundle\Filter\RegexpFilter':
486+
class: 'AppBundle\Filter\RegexpFilter'
487+
autowire: true # See the next example for a plain old definition
488+
tags: [ { name: 'api_platform.filter', id: 'regexp' } ]
489+
```
490+
491+
In the previous example, the filter can be applied on any property. However, thanks to the `AbstractFilter` class,
492+
it can also be enabled for some properties:
493+
494+
```yaml
495+
services:
496+
'AppBundle\Filter\RegexpFilter':
497+
class: 'AppBundle\Filter\RegexpFilter'
498+
arguments: [ '@doctrine', '@request_stack', '@?logger', { email: ~, anOtherProperty: ~ } ]
499+
tags: [ { name: 'api_platform.filter', id: 'regexp' } ]
500+
```
501+
502+
Finally, add this filter to resources you want to be filtered:
503+
504+
```php
505+
<?php
506+
507+
// src/AppBundle/Entity/Offer.php
508+
509+
namespace AppBundle\Entity;
510+
511+
use ApiPlatform\Core\Annotation\ApiResource;
512+
513+
/**
514+
* @ApiResource(attributes={"filters"={"regexp"}})
515+
*/
516+
class Offer
517+
{
518+
// ...
519+
}
520+
```
521+
522+
You can now enable this filter using URLs like `http://example.com/offers?regexp_email=^[FOO]`. This new filter will also
523+
appear in Swagger and Hydra documentations.
434524

435525
### Overriding Extraction of Properties from the Request
436526

core/getting-started.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ API Platform Core is able to automatically expose entities mapped as "API resour
5656
operations.
5757
To expose your entities, you can use Docblock annotations, XML and YAML configuration files.
5858
59-
Here is an example of entities mapped using annotations which will be exposed trough a REST API:
59+
Here is an example of entities mapped using annotations which will be exposed through a REST API:
6060
6161
```php
6262
<?php
@@ -138,7 +138,7 @@ class Offer
138138
}
139139
```
140140

141-
It is the minimal configuration required to expose `Product` and `Offer` entities as JSON-LD documents trough an hypermedia
141+
It is the minimal configuration required to expose `Product` and `Offer` entities as JSON-LD documents through an hypermedia
142142
web API.
143143

144144
If you are familiar with the Symfony ecosystem, you noticed that entity classes are also mapped with Doctrine ORM annotations
@@ -173,7 +173,10 @@ As an alternative to annotations, you can map entity classes using XML or YAML:
173173
<!-- src/AppBundle/Resources/config/api_resources/resources.xml -->
174174

175175
<?xml version="1.0" encoding="UTF-8" ?>
176-
<resources>
176+
<resources xmlns="https://api-platform.com/schema/metadata"
177+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
178+
xsi:schemaLocation="https://api-platform.com/schema/metadata
179+
https://api-platform.com/schema/metadata/metadata-2.0.xsd">
177180
<resource class="AppBundle\Entity\Product" />
178181
<resource
179182
class="AppBundle\Entity\Offer"

core/serialization-groups-and-relations.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,7 @@ In the following JSON document, the relation from a book to an author is represe
136136
### Normalization
137137

138138
To improve the application's performance, it is sometimes necessary to avoid issuing extra HTTP requests. It is possible
139-
to embed related objects (or only some of their properties) directly in the parent response trough serialization groups.
139+
to embed related objects (or only some of their properties) directly in the parent response through serialization groups.
140140
By using the following serialization groups annotations (`@Groups`), a JSON representation of the author is embedded in
141141
the book response:
142142

@@ -239,7 +239,7 @@ class Book
239239

240240
The following rules apply when denormalizating embedded relations:
241241

242-
* If a `@id` key is present in the embedded resource, the object corresponding to the given URI will be retrieved trough
242+
* If a `@id` key is present in the embedded resource, the object corresponding to the given URI will be retrieved through
243243
the data provider and any changes in the embedded relation will be applied to that object.
244244
* If no `@id` key exists, a new object will be created containing data provided in the embedded JSON document.
245245

deployment/heroku.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Deploying an API Platform App on Heroku
22

33
[Heroku](http://heroku.com) is a popular, fast, scalable and reliable *Platform As A Service* (PaaS). As Heroku offers a
4-
free plan including database support trough [Heroku Postgres](https://www.heroku.com/postgres), it's
4+
free plan including database support through [Heroku Postgres](https://www.heroku.com/postgres), it's
55
a very convenient way to experiment with the API Platform.
66

77
The API Platform Heroku integration also supports MySQL databases provided by [the ClearDB add-on](https://addons.heroku.com/cleardb).

deployment/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
As an API Platform application is basically a standard Symfony application, [all Symfony deployment cookbooks](http://symfony.com/doc/current/cookbook/deployment/index.html)
44
apply.
55

6-
However, API Platform also provide facilities to deploy applications trough containers and Platforms as a Service (PaaS):
6+
However, API Platform also provide facilities to deploy applications through containers and Platforms as a Service (PaaS):
77

88
* [Deploying an API Platform App on Heroku](heroku.md)
99
* [Using API Platform with Docker](docker.md)

distribution/testing.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ the API without having to write a single line of PHP.
2121
Feature: Manage books and their reviews
2222
In order to manage books and their reviews
2323
As a client software developer
24-
I need to be able to retrieve, create, update and delete them trough the API.
24+
I need to be able to retrieve, create, update and delete them through the API.
2525
2626
# the "@createSchema" annotation provided by API Platform creates a temporary SQLite database for testing the API
2727
@createSchema
@@ -162,10 +162,10 @@ Clear the cache of the `test` environment:
162162

163163
$ docker-compose exec web bin/console cache:clear --env=test
164164

165-
Then run:
165+
Then run:
166166

167167
$ docker-compose run --rm web vendor/bin/behat`.
168-
168+
169169
Everything should be green now. Your Linked Data API is now specified and tested thanks to Behat!
170170

171171
You may also be interested by those alternative testing tools (not included in the API Platform distribution):

0 commit comments

Comments
 (0)