Skip to content

Commit aeb56d1

Browse files
committed
Ability to receive list of requested fields from ResolveInfo (recursively)
1 parent 74b922c commit aeb56d1

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

src/Type/Definition/ResolveInfo.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,10 @@
33

44
use GraphQL\Language\AST\Field;
55
use GraphQL\Language\AST\FragmentDefinition;
6+
use GraphQL\Language\AST\FragmentSpread;
67
use GraphQL\Language\AST\OperationDefinition;
8+
use GraphQL\Language\AST\Selection;
9+
use GraphQL\Language\AST\SelectionSet;
710
use GraphQL\Schema;
811
use GraphQL\Utils;
912

@@ -58,4 +61,64 @@ public function __construct(array $values)
5861
{
5962
Utils::assign($this, $values);
6063
}
64+
65+
/**
66+
* Helper method that returns names of all fields selected in query for $this->fieldName up to $depth levels
67+
*
68+
*
69+
* query AppHomeRoute{viewer{id,..._0c28183ce}} fragment _0c28183ce on Viewer{id,profile{firstName,id,locations{id}}}
70+
* Example:
71+
* query MyQuery{
72+
* {
73+
* root {
74+
* id,
75+
* nested {
76+
* nested1
77+
* nested2 {
78+
* nested3
79+
* }
80+
* }
81+
* }
82+
* }
83+
*
84+
* Given this ResolveInfo instance is a part of "root" field resolution, and $depth === 1, method will return:
85+
* [
86+
* 'id' => true,
87+
* 'nested' => [
88+
* nested1 => true,
89+
* nested2 => true
90+
* ]
91+
* ]
92+
*
93+
* @param int $depth How many levels to include in output
94+
* @return array
95+
*/
96+
public function getFieldSelection($depth = 0)
97+
{
98+
/** @var Field $fieldAST */
99+
$fieldAST = $this->fieldASTs[0];
100+
return $this->foldSelectionSet($fieldAST->selectionSet, $depth);
101+
}
102+
103+
private function foldSelectionSet(SelectionSet $selectionSet, $descend)
104+
{
105+
$fields = [];
106+
107+
foreach ($selectionSet->selections as $selectionAST) {
108+
if ($selectionAST instanceof Field) {
109+
$fields[$selectionAST->name->value] = $descend > 0 && !empty($selectionAST->selectionSet)
110+
? $this->foldSelectionSet($selectionAST->selectionSet, --$descend)
111+
: true;
112+
} else if ($selectionAST instanceof FragmentSpread) {
113+
$spreadName = $selectionAST->name->value;
114+
if (isset($this->fragments[$spreadName])) {
115+
/** @var FragmentDefinition $fragment */
116+
$fragment = $this->fragments[$spreadName];
117+
$fields += $this->foldSelectionSet($fragment->selectionSet, $descend);
118+
}
119+
}
120+
}
121+
122+
return $fields;
123+
}
61124
}

0 commit comments

Comments
 (0)