Skip to content

Commit 60feb7a

Browse files
committed
Prepare v15.20.0 release
1 parent 5511603 commit 60feb7a

File tree

5 files changed

+107
-61
lines changed

5 files changed

+107
-61
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ You can find and compare releases at the [GitHub release page](https://github.co
99

1010
## Unreleased
1111

12+
## v15.20.0
13+
14+
### Added
15+
16+
- Add keys `type` and `unions` to `ResolveInfo::getFieldSelectionWithAliases` result https://github.com/webonyx/graphql-php/pull/1681
17+
1218
## v15.19.1
1319

1420
### Fixed

docs/class-reference.md

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -473,8 +473,10 @@ function getFieldSelection(int $depth = 0): array
473473
*
474474
* The result maps original field names to a map of selections for that field, including aliases.
475475
* For each of those selections, you can find the following keys:
476-
* - "args" contains the passed arguments for this field/alias
477-
* - "selectionSet" contains potential nested fields of this field/alias. The structure is recursive from here.
476+
* - "args" contains the passed arguments for this field/alias (not on an union inline fragment)
477+
* - "type" contains the related Type instance found (will be the same for all aliases of a field)
478+
* - "selectionSet" contains potential nested fields of this field/alias (only on ObjectType). The structure is recursive from here.
479+
* - "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.
478480
*
479481
* Example:
480482
* {
@@ -487,71 +489,101 @@ function getFieldSelection(int $depth = 0): array
487489
* alias1: nested {
488490
* nested1(myArg: 2, mySecondAg: "test")
489491
* }
492+
* myUnion(myArg: 3) {
493+
* ...on Nested {
494+
* nested1(myArg: 4)
495+
* }
496+
* ...on MyCustomObject {
497+
* nested3
498+
* }
499+
* }
490500
* }
491501
* }
492502
*
493-
* Given this ResolveInfo instance is a part of "root" field resolution, and $depth === 1,
503+
* Given this ResolveInfo instance is a part of root field resolution,
504+
* $depth === 1,
505+
* and fields "nested" represents an ObjectType named "Nested",
494506
* this method will return:
495507
* [
496508
* 'id' => [
497509
* 'id' => [
498510
* 'args' => [],
511+
* 'type' => GraphQL\Type\Definition\IntType Object ( ... )),
499512
* ],
500513
* ],
501514
* 'nested' => [
502515
* 'nested' => [
503516
* 'args' => [],
517+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
504518
* 'selectionSet' => [
505519
* 'nested1' => [
506520
* 'nested1' => [
507521
* 'args' => [
508522
* 'myArg' => 1,
509523
* ],
524+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
510525
* ],
511526
* 'nested1Bis' => [
512527
* 'args' => [],
528+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
513529
* ],
514530
* ],
515531
* ],
516-
* ],
517-
* 'alias1' => [
532+
* ],
533+
* ],
534+
* 'alias1' => [
535+
* 'alias1' => [
518536
* 'args' => [],
537+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
519538
* 'selectionSet' => [
520-
* 'nested1' => [
521-
* 'nested1' => [
522-
* 'args' => [
523-
* 'myArg' => 2,
524-
* 'mySecondAg' => "test,
525-
* ],
539+
* 'nested1' => [
540+
* 'nested1' => [
541+
* 'args' => [
542+
* 'myArg' => 2,
543+
* 'mySecondAg' => "test",
544+
* ],
545+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
526546
* ],
527-
* ],
528-
* ],
547+
* ],
548+
* ],
529549
* ],
530550
* ],
551+
* 'myUnion' => [
552+
* 'myUnion' => [
553+
* 'args' => [
554+
* 'myArg' => 3,
555+
* ],
556+
* 'type' => GraphQL\Type\Definition\UnionType Object ( ... )),
557+
* 'unions' => [
558+
* 'Nested' => [
559+
* 'type' => GraphQL\Type\Definition\ObjectType Object ( ... )),
560+
* 'selectionSet' => [
561+
* 'nested1' => [
562+
* 'nested1' => [
563+
* 'args' => [
564+
* 'myArg' => 4,
565+
* ],
566+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
567+
* ],
568+
* ],
569+
* ],
570+
* ],
571+
* 'MyCustomObject' => [
572+
* 'type' => GraphQL\Tests\Type\TestClasses\MyCustomType Object ( ... )),
573+
* 'selectionSet' => [
574+
* 'nested3' => [
575+
* 'nested3' => [
576+
* 'args' => [],
577+
* 'type' => GraphQL\Type\Definition\StringType Object ( ... )),
578+
* ],
579+
* ],
580+
* ],
581+
* ],
582+
* ],
583+
* ],
584+
* ],
531585
* ]
532586
*
533-
* This method does not consider conditional typed fragments.
534-
* Use it with care for fields of interface and union types.
535-
* You can still alias the union type fields with the same name in order to extract their corresponding args.
536-
*
537-
* Example:
538-
* {
539-
* root {
540-
* id
541-
* unionPerson {
542-
* ...on Child {
543-
* name
544-
* birthdate(format: "d/m/Y")
545-
* }
546-
* ...on Adult {
547-
* adultName: name
548-
* adultBirthDate: birthdate(format: "Y-m-d")
549-
* job
550-
* }
551-
* }
552-
* }
553-
* }
554-
*
555587
* @param int $depth How many levels to include in the output beyond the first
556588
*
557589
* @throws \Exception

src/Type/Definition/EnumType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -136,11 +136,11 @@ public function serialize($value)
136136
return $lookup[$value]->name;
137137
}
138138

139-
if (is_a($value, \BackedEnum::class)) {
139+
if ($value instanceof \BackedEnum) {
140140
return $value->name;
141141
}
142142

143-
if (is_a($value, \UnitEnum::class)) {
143+
if ($value instanceof \UnitEnum) {
144144
return $value->name;
145145
}
146146

src/Type/Definition/ResolveInfo.php

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,8 @@ public function getFieldSelectionWithAliases(int $depth = 0): array
349349
foreach ($this->fieldNodes as $fieldNode) {
350350
$selectionSet = $fieldNode->selectionSet;
351351
if ($selectionSet !== null) {
352-
$fieldType = $this->parentType->getField($fieldNode->name->value)
353-
->getType();
352+
$field = $this->parentType->getField($fieldNode->name->value);
353+
$fieldType = $field->getType();
354354

355355
$fields = array_merge_recursive(
356356
$fields,
@@ -441,19 +441,22 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
441441
if ($fieldName === Introspection::TYPE_NAME_FIELD_NAME) {
442442
continue;
443443
}
444-
445444
assert($parentType instanceof HasFieldsType, 'ensured by query validation');
446445

446+
$aliasInfo = &$fields[$fieldName][$aliasName];
447+
447448
$fieldDef = $parentType->getField($fieldName);
449+
450+
$aliasInfo['args'] = Values::getArgumentValues($fieldDef, $selection, $this->variableValues);
451+
448452
$fieldType = $fieldDef->getType();
449-
$fields[$fieldName][$aliasName]['args'] = Values::getArgumentValues($fieldDef, $selection, $this->variableValues);
450453

451-
$innerType = $fieldType;
452-
if ($innerType instanceof WrappingType) {
453-
$innerType = $innerType->getInnermostType();
454+
$namedFieldType = $fieldType;
455+
if ($namedFieldType instanceof WrappingType) {
456+
$namedFieldType = $namedFieldType->getInnermostType();
454457
}
455458

456-
$fields[$fieldName][$aliasName]['type'] = $innerType;
459+
$aliasInfo['type'] = $namedFieldType;
457460

458461
if ($descend <= 0) {
459462
continue;
@@ -464,12 +467,12 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
464467
continue;
465468
}
466469

467-
if (is_a($innerType, UnionType::class)) {
468-
$fields[$fieldName][$aliasName]['unions'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
470+
if ($namedFieldType instanceof UnionType) {
471+
$aliasInfo['unions'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend, $fieldType);
469472
continue;
470473
}
471474

472-
$fields[$fieldName][$aliasName]['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend - 1, $fieldType);
475+
$aliasInfo['selectionSet'] = $this->foldSelectionWithAlias($nestedSelectionSet, $descend - 1, $fieldType);
473476
} elseif ($selection instanceof FragmentSpreadNode) {
474477
$spreadName = $selection->name->value;
475478
$fragment = $this->fragments[$spreadName] ?? null;
@@ -491,16 +494,18 @@ private function foldSelectionWithAlias(SelectionSetNode $selectionSet, int $des
491494
: $this->schema->getType($typeCondition->name->value);
492495
assert($fieldType instanceof Type, 'ensured by query validation');
493496

494-
if (is_a($parentType, UnionType::class)) {
497+
if ($parentType instanceof UnionType) {
495498
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-
);
499+
$fieldTypeInfo = &$fields[$fieldType->name()];
500+
$fieldTypeInfo['type'] = $fieldType;
501+
$fieldTypeInfo['selectionSet'] = $this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType);
502+
continue;
503503
}
504+
505+
$fields = array_merge_recursive(
506+
$this->foldSelectionWithAlias($selection->selectionSet, $descend, $fieldType),
507+
$fields
508+
);
504509
}
505510
}
506511

tests/Type/ResolveInfoTest.php

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -737,21 +737,24 @@ public function testGetFieldSelectionWithAliases(): void
737737
};
738738

739739
$myCustomWithObjectType = new CustomWithObject();
740-
// retrieve the instance from the parent type in order to don't instantiate twice the same type in the same schema
740+
741+
// retrieve the instance from the parent type in order to not instantiate the same type twice in the same schema
741742
$fields = $myCustomWithObjectType->config['fields'];
742-
assert(is_array($fields), 'ensured by type config');
743+
assert(is_array($fields), 'see CustomWithObject::__construct');
743744
$myCustomType = $fields['customA'];
745+
744746
$levelUnion = new UnionType([
745747
'name' => 'CustomOrOther',
746748
'types' => [
747749
$myCustomType,
748750
$myCustomWithObjectType,
749751
],
750-
'resolveType' => function ($value) use ($myCustomType, $myCustomWithObjectType): ObjectType {
751-
switch (get_class($value)) {
752+
'resolveType' => function (object $value) use ($myCustomType, $myCustomWithObjectType): ObjectType {
753+
$valueClass = get_class($value);
754+
switch ($valueClass) {
752755
case MyCustomType::class: return $myCustomType;
753756
case CustomWithObject::class: return $myCustomWithObjectType;
754-
default: throw new Error('Unexpected union type');
757+
default: throw new Error("Can not determine type for value of class {$valueClass}.");
755758
}
756759
},
757760
]);

0 commit comments

Comments
 (0)