Fix ResolveInfo::getFieldSelection() when using multiple fragments on the same field.

This commit is contained in:
Jeremiah VALERIE 2016-05-18 15:36:45 +02:00
parent de4eba7077
commit be46b14441
3 changed files with 71 additions and 4 deletions

View File

@ -95,9 +95,14 @@ class ResolveInfo
*/ */
public function getFieldSelection($depth = 0) public function getFieldSelection($depth = 0)
{ {
$fields = [];
/** @var Field $fieldAST */ /** @var Field $fieldAST */
$fieldAST = $this->fieldASTs[0]; foreach ($this->fieldASTs as $fieldAST) {
return $this->foldSelectionSet($fieldAST->selectionSet, $depth); $fields = array_merge_recursive($fields, $this->foldSelectionSet($fieldAST->selectionSet, $depth));
}
return $fields;
} }
private function foldSelectionSet(SelectionSet $selectionSet, $descend) private function foldSelectionSet(SelectionSet $selectionSet, $descend)

View File

@ -302,6 +302,57 @@ class StarWarsQueryTest extends \PHPUnit_Framework_TestCase
$this->assertValidQuery($query, $expected); $this->assertValidQuery($query, $expected);
} }
function testFragmentWithProjection()
{
$query = '
query UseFragment {
human(id: "1003") {
name
...fa
...fb
}
}
fragment fa on Character {
friends {
id
}
}
fragment fb on Character {
friends {
name
}
}
';
$expected = [
'human' => [
'name' => 'Leia Organa',
'friends' => [
[
'name' => 'Luke Skywalker',
'id' => '1000'
],
[
'name' => 'Han Solo',
'id' => '1002'
],
[
'name' => 'C-3PO',
'id' => '2000'
],
[
'name' => 'R2-D2',
'id' => '2001'
]
]
]
];
$this->assertValidQuery($query, $expected);
}
// Using __typename to find the type of an object // Using __typename to find the type of an object
public function testVerifyThatR2D2IsADroid() public function testVerifyThatR2D2IsADroid()
{ {

View File

@ -16,6 +16,7 @@ use GraphQL\Type\Definition\EnumType;
use GraphQL\Type\Definition\InterfaceType; use GraphQL\Type\Definition\InterfaceType;
use GraphQL\Type\Definition\NonNull; use GraphQL\Type\Definition\NonNull;
use GraphQL\Type\Definition\ObjectType; use GraphQL\Type\Definition\ObjectType;
use GraphQL\Type\Definition\ResolveInfo;
use GraphQL\Type\Definition\Type; use GraphQL\Type\Definition\Type;
/** /**
@ -161,8 +162,18 @@ class StarWarsSchema
'friends' => [ 'friends' => [
'type' => Type::listOf($characterInterface), 'type' => Type::listOf($characterInterface),
'description' => 'The friends of the human, or an empty list if they have none.', 'description' => 'The friends of the human, or an empty list if they have none.',
'resolve' => function ($human) { 'resolve' => function ($human, $args, ResolveInfo $info) {
return StarWarsData::getFriends($human); $fieldSelection = $info->getFieldSelection();
$fieldSelection['id'] = true;
$friends = array_map(
function($friend) use ($fieldSelection) {
return array_intersect_key($friend, $fieldSelection);
},
StarWarsData::getFriends($human)
);
return $friends;
}, },
], ],
'appearsIn' => [ 'appearsIn' => [