Skip to content

Commit 54fbc44

Browse files
committed
ResolveInfo::getFieldSelectionWithAliases() => now add instance types and the folded union types to the returned schema.
1 parent e0db1f6 commit 54fbc44

File tree

3 files changed

+286
-46
lines changed

3 files changed

+286
-46
lines changed

src/Type/Definition/ResolveInfo.php

+97-45
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,79 +237,107 @@ 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, $depth === 1, and nested represent an ObjectType with a configured name "Nested",
242252
* this method will return:
243253
* [
244254
* 'id' => [
245255
* 'id' => [
246256
* 'args' => [],
257+
* 'type' => GraphQL\Type\Definition\IntType Object ( ... )),
247258
* ],
248259
* ],
249260
* 'nested' => [
250261
* 'nested' => [
251262
* 'args' => [],
263+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
252264
* 'selectionSet' => [
253265
* 'nested1' => [
254266
* 'nested1' => [
255267
* 'args' => [
256268
* 'myArg' => 1,
257269
* ],
270+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
258271
* ],
259272
* 'nested1Bis' => [
260273
* 'args' => [],
274+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
261275
* ],
262276
* ],
263277
* ],
264-
* ],
265-
* 'alias1' => [
278+
* ],
279+
* ],
280+
* 'alias1' => [
281+
* 'alias1' => [
266282
* 'args' => [],
283+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
267284
* 'selectionSet' => [
268-
* 'nested1' => [
269-
* 'nested1' => [
270-
* 'args' => [
271-
* 'myArg' => 2,
272-
* 'mySecondAg' => "test,
273-
* ],
285+
* 'nested1' => [
286+
* 'nested1' => [
287+
* 'args' => [
288+
* 'myArg' => 2,
289+
* 'mySecondAg' => "test,
290+
* ],
291+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
274292
* ],
275-
* ],
276-
* ],
293+
* ],
294+
* ],
277295
* ],
278296
* ],
297+
* 'myUnion' => [
298+
* 'myUnion' => [
299+
* 'args' => [
300+
* 'myArg' => 3
301+
* ],
302+
* 'type' => GraphQL\Type\Definition\UnionType Object ( ... )),
303+
* 'unions' => [
304+
* 'Nested' => [
305+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
306+
* 'selectionSet' => [
307+
* 'nested1' => [
308+
* 'nested1' => [
309+
* 'args' => [
310+
* 'myArg' => 4
311+
* ],
312+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
313+
* ],
314+
* ],
315+
* ],
316+
* ],
317+
* 'MyCustomObject' => [
318+
* 'type' => GraphQL\Tests\Type\TestClasses\MyCustomType Object ( ... )),
319+
* 'selectionSet' => [
320+
* 'nested3' => [
321+
* 'nested3' => [
322+
* 'args' => [],
323+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
324+
* ],
325+
* ],
326+
* ],
327+
* ],
328+
* ],
329+
* ],
330+
* ],
279331
* ]
280332
*
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-
*
303333
* @param int $depth How many levels to include in the output beyond the first
304334
*
305-
* @throws \Exception
335+
* @return array<string, mixed>
336+
*
306337
* @throws Error
307338
* @throws InvariantViolation
308339
*
309-
* @return array<string, mixed>
310-
*
340+
* @throws \Exception
311341
* @api
312342
*/
313343
public function getFieldSelectionWithAliases(int $depth = 0): array
@@ -416,6 +446,13 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
416446
$fieldType = $fieldDef->getType();
417447
$fields[$fieldName][$aliasName]['args'] = Values::getArgumentValues($fieldDef, $selection, $this->variableValues);
418448

449+
$innerType = $fieldType;
450+
if ($innerType instanceof WrappingType) {
451+
$innerType = $innerType->getInnermostType();
452+
}
453+
454+
$fields[$fieldName][$aliasName]['type'] = $innerType;
455+
419456
if ($descend <= 0) {
420457
continue;
421458
}
@@ -425,6 +462,11 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
425462
continue;
426463
}
427464

465+
if (is_a($innerType, UnionType::class)) {
466+
$fields[$fieldName][$aliasName]['unions'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
467+
continue;
468+
}
469+
428470
$fields[$fieldName][$aliasName]['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend - 1, $fieldType);
429471
} elseif ($selection instanceof FragmentSpreadNode) {
430472
$spreadName = $selection->name->value;
@@ -434,7 +476,7 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
434476
}
435477

436478
$fieldType = $this->schema->getType($fragment->typeCondition->name->value);
437-
assert($fieldType instanceof Type, 'ensured by query validation');
479+
assert($fieldType instanceof Type, 'ensured by query validation 2');
438480

439481
$fields = \array_merge_recursive(
440482
$this->foldSelectionWithAlias($fragment->selectionSet, $descend, $fieldType),
@@ -445,12 +487,22 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
445487
$fieldType = $typeCondition === null
446488
? $parentType
447489
: $this->schema->getType($typeCondition->name->value);
448-
assert($fieldType instanceof Type, 'ensured by query validation');
449-
450-
$fields = \array_merge_recursive(
451-
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
452-
$fields
453-
);
490+
assert($fieldType instanceof Type, 'ensured by query validation 3');
491+
492+
if (is_a($parentType, UnionType::class)) {
493+
$nestedSelectionSet = $selection->selectionSet;
494+
if ($nestedSelectionSet === null) {
495+
continue;
496+
}
497+
498+
$fields[$fieldType->name()]['type'] = $fieldType;
499+
$fields[$fieldType->name()]['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
500+
} else {
501+
$fields = \array_merge_recursive(
502+
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
503+
$fields
504+
);
505+
}
454506
}
455507
}
456508

0 commit comments

Comments
 (0)