Skip to content

Commit 5511603

Browse files
authored
ResolveInfo::getFieldSelectionWithAliases() => now add instance types and the folded union types to the returned schema. (#1681)
1 parent 19b6429 commit 5511603

File tree

3 files changed

+281
-42
lines changed

3 files changed

+281
-42
lines changed

src/Type/Definition/ResolveInfo.php

Lines changed: 89 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,10 @@ public function getFieldSelection(int $depth = 0): array
221221
*
222222
* The result maps original field names to a map of selections for that field, including aliases.
223223
* For each of those selections, you can find the following keys:
224-
* - "args" contains the passed arguments for this field/alias
225-
* - "selectionSet" contains potential nested fields of this field/alias. The structure is recursive from here.
224+
* - "args" contains the passed arguments for this field/alias (not on an union inline fragment)
225+
* - "type" contains the related Type instance found (will be the same for all aliases of a field)
226+
* - "selectionSet" contains potential nested fields of this field/alias (only on ObjectType). The structure is recursive from here.
227+
* - "unions" contains potential object types contained in an UnionType (only on UnionType). The structure is recursive from here and will go through the selectionSet of the object types.
226228
*
227229
* Example:
228230
* {
@@ -235,71 +237,101 @@ public function getFieldSelection(int $depth = 0): array
235237
* alias1: nested {
236238
* nested1(myArg: 2, mySecondAg: "test")
237239
* }
240+
* myUnion(myArg: 3) {
241+
* ...on Nested {
242+
* nested1(myArg: 4)
243+
* }
244+
* ...on MyCustomObject {
245+
* nested3
246+
* }
247+
* }
238248
* }
239249
* }
240250
*
241-
* Given this ResolveInfo instance is a part of "root" field resolution, and $depth === 1,
251+
* Given this ResolveInfo instance is a part of root field resolution,
252+
* $depth === 1,
253+
* and fields "nested" represents an ObjectType named "Nested",
242254
* this method will return:
243255
* [
244256
* 'id' => [
245257
* 'id' => [
246258
* 'args' => [],
259+
* 'type' => GraphQL\Type\Definition\IntType Object ( ... )),
247260
* ],
248261
* ],
249262
* 'nested' => [
250263
* 'nested' => [
251264
* 'args' => [],
265+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
252266
* 'selectionSet' => [
253267
* 'nested1' => [
254268
* 'nested1' => [
255269
* 'args' => [
256270
* 'myArg' => 1,
257271
* ],
272+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
258273
* ],
259274
* 'nested1Bis' => [
260275
* 'args' => [],
276+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
261277
* ],
262278
* ],
263279
* ],
264-
* ],
265-
* 'alias1' => [
280+
* ],
281+
* ],
282+
* 'alias1' => [
283+
* 'alias1' => [
266284
* 'args' => [],
285+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
267286
* 'selectionSet' => [
268-
* 'nested1' => [
269-
* 'nested1' => [
270-
* 'args' => [
271-
* 'myArg' => 2,
272-
* 'mySecondAg' => "test,
273-
* ],
287+
* 'nested1' => [
288+
* 'nested1' => [
289+
* 'args' => [
290+
* 'myArg' => 2,
291+
* 'mySecondAg' => "test",
292+
* ],
293+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
274294
* ],
275-
* ],
276-
* ],
295+
* ],
296+
* ],
277297
* ],
278298
* ],
299+
* 'myUnion' => [
300+
* 'myUnion' => [
301+
* 'args' => [
302+
* 'myArg' => 3,
303+
* ],
304+
* 'type' => GraphQL\Type\Definition\UnionType Object ( ... )),
305+
* 'unions' => [
306+
* 'Nested' => [
307+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
308+
* 'selectionSet' => [
309+
* 'nested1' => [
310+
* 'nested1' => [
311+
* 'args' => [
312+
* 'myArg' => 4,
313+
* ],
314+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
315+
* ],
316+
* ],
317+
* ],
318+
* ],
319+
* 'MyCustomObject' => [
320+
* 'type' => GraphQL\Tests\Type\TestClasses\MyCustomType Object ( ... )),
321+
* 'selectionSet' => [
322+
* 'nested3' => [
323+
* 'nested3' => [
324+
* 'args' => [],
325+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
326+
* ],
327+
* ],
328+
* ],
329+
* ],
330+
* ],
331+
* ],
332+
* ],
279333
* ]
280334
*
281-
* This method does not consider conditional typed fragments.
282-
* Use it with care for fields of interface and union types.
283-
* You can still alias the union type fields with the same name in order to extract their corresponding args.
284-
*
285-
* Example:
286-
* {
287-
* root {
288-
* id
289-
* unionPerson {
290-
* ...on Child {
291-
* name
292-
* birthdate(format: "d/m/Y")
293-
* }
294-
* ...on Adult {
295-
* adultName: name
296-
* adultBirthDate: birthdate(format: "Y-m-d")
297-
* job
298-
* }
299-
* }
300-
* }
301-
* }
302-
*
303335
* @param int $depth How many levels to include in the output beyond the first
304336
*
305337
* @throws \Exception
@@ -416,6 +448,13 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
416448
$fieldType = $fieldDef->getType();
417449
$fields[$fieldName][$aliasName]['args'] = Values::getArgumentValues($fieldDef, $selection, $this->variableValues);
418450

451+
$innerType = $fieldType;
452+
if ($innerType instanceof WrappingType) {
453+
$innerType = $innerType->getInnermostType();
454+
}
455+
456+
$fields[$fieldName][$aliasName]['type'] = $innerType;
457+
419458
if ($descend <= 0) {
420459
continue;
421460
}
@@ -425,6 +464,11 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
425464
continue;
426465
}
427466

467+
if (is_a($innerType, UnionType::class)) {
468+
$fields[$fieldName][$aliasName]['unions'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
469+
continue;
470+
}
471+
428472
$fields[$fieldName][$aliasName]['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend - 1, $fieldType);
429473
} elseif ($selection instanceof FragmentSpreadNode) {
430474
$spreadName = $selection->name->value;
@@ -447,10 +491,16 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
447491
: $this->schema->getType($typeCondition->name->value);
448492
assert($fieldType instanceof Type, 'ensured by query validation');
449493

450-
$fields = array_merge_recursive(
451-
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
452-
$fields
453-
);
494+
if (is_a($parentType, UnionType::class)) {
495+
assert($fieldType instanceof NamedType, 'ensured by query validation');
496+
$fields[$fieldType->name()]['type'] = $fieldType;
497+
$fields[$fieldType->name()]['selectionSet'] = $this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType);
498+
} else {
499+
$fields = array_merge_recursive(
500+
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
501+
$fields
502+
);
503+
}
454504
}
455505
}
456506

0 commit comments

Comments
 (0)