Skip to content

Commit

Permalink
[graphql] Add graphql filter with multiple values (api-platform#2070)
Browse files Browse the repository at this point in the history
* add falling test for filter with multiple values

* update graphql filter to support multiple values

* replace array prefix by _list suffix
  • Loading branch information
ArnoudThibaut authored and dunglas committed Jul 6, 2018
1 parent 681e4b5 commit 01da289
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 4 deletions.
25 changes: 25 additions & 0 deletions features/graphql/filters.feature
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,28 @@ Feature: Collections filtering
And the header "Content-Type" should be equal to "application/json"
And the JSON node "data.dummies.edges[0].node.name" should be equal to "Dummy #2"
And the JSON node "data.dummies.edges[1].node.name" should be equal to "Dummy #1"

@createSchema
Scenario: Retrieve a collection filtered using the related search filter with two values and exact strategy
Given there are 3 dummy objects with relatedDummy
When I send the following GraphQL request:
"""
{
dummies(relatedDummy_name_list: ["RelatedDummy #1", "RelatedDummy #2"]) {
edges {
node {
id
name
relatedDummy {
name
}
}
}
}
}
"""
Then the response status code should be 200
And the header "Content-Type" should be equal to "application/json"
And the JSON node "data.dummies.edges" should have 2 element
And the JSON node "data.dummies.edges[0].node.relatedDummy.name" should be equal to "RelatedDummy #1"
And the JSON node "data.dummies.edges[1].node.relatedDummy.name" should be equal to "RelatedDummy #2"
7 changes: 5 additions & 2 deletions src/GraphQl/Resolver/Factory/CollectionResolverFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,16 @@ private function getSubresource(string $rootClass, array $rootResolvedFields, ar
private function getNormalizedFilters(array $args): array
{
$filters = $args;

foreach ($filters as $name => $value) {
if (\is_array($value)) {
if (strpos($name, '_list')) {
$name = substr($name, 0, \strlen($name) - \strlen('_list'));
}
$filters[$name] = $this->getNormalizedFilters($value);
continue;
}

if (strpos($name, '_')) {
if (\is_string($name) && strpos($name, '_')) {
// Gives a chance to relations/nested fields.
$filters[str_replace('_', '.', $name)] = $value;
}
Expand Down
7 changes: 5 additions & 2 deletions src/GraphQl/Type/SchemaBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -231,12 +231,15 @@ private function getResourceFieldConfiguration(string $resourceClass, ResourceMe
$filterType = \in_array($value['type'], Type::$builtinTypes, true) ? new Type($value['type'], $nullable) : new Type('object', $nullable, $value['type']);
$graphqlFilterType = $this->convertType($filterType, false, null, $depth);

if ('[]' === $newKey = substr($key, -2)) {
$key = $newKey;
if ('[]' === substr($key, -2)) {
$graphqlFilterType = GraphQLType::listOf($graphqlFilterType);
$key = substr($key, 0, -2).'_list';
}

parse_str($key, $parsed);
if (array_key_exists($key, $parsed) && \is_array($parsed[$key])) {
$parsed = [$key => ''];
}
array_walk_recursive($parsed, function (&$value) use ($graphqlFilterType) {
$value = $graphqlFilterType;
});
Expand Down

0 comments on commit 01da289

Please sign in to comment.