QueryInfoExtractor
in package
Extracts a unified query info tree from a GraphQL ResolveInfo.
The resulting array captures the full query structure: fields, arguments, sub-selections, inline fragments, and named fragment spreads.
Structure rules:
- Leaf field (no args, no sub-selection) => true
- Field with sub-selections => nested associative array
- Field arguments => '__args' reserved key
- Inline fragments with a type condition => '...TypeName' prefix key
- Inline fragments without a type condition and named fragment spreads => expanded inline (merged into the parent as siblings of the other selections), matching how GraphQL evaluates them
- Top-level query args included via '__args'
Table of Contents
- extract_from_info() : array<string|int, mixed>
- Extract query info from a resolver's ResolveInfo and top-level args.
- build_field_entry() : array<string|int, mixed>|bool
- Build the entry for a single field node.
- expand_fragment() : array<string|int, mixed>|null
- Expand a named fragment into its query info tree, memoizing the result.
- extract_selection_set() : array<string|int, mixed>
- Recursive worker behind {@see self::extract()}.
- merge_selections() : array<string|int, mixed>
- Recursively merge two selection trees produced by extract()/build_field_entry().
- resolve_argument_value() : mixed
- Resolve the value of a single argument node, handling variables.
Methods
extract_from_info()
Extract query info from a resolver's ResolveInfo and top-level args.
public
static extract_from_info(ResolveInfo $info, array<string|int, mixed> $args) : array<string|int, mixed>
Parameters
- $info : ResolveInfo
-
The GraphQL resolve info.
- $args : array<string|int, mixed>
-
The top-level query arguments.
Return values
array<string|int, mixed> — The unified query info tree.build_field_entry()
Build the entry for a single field node.
private
static build_field_entry(FieldNode $field, array<string|int, mixed> $variable_values, array<string, FragmentDefinitionNode> $fragments, array<string, array<string|int, mixed>> &$expanded_fragments) : array<string|int, mixed>|bool
Parameters
- $field : FieldNode
-
The field node.
- $variable_values : array<string|int, mixed>
-
Variable values for resolving arguments.
- $fragments : array<string, FragmentDefinitionNode>
-
Named fragment definitions from the document.
- $expanded_fragments : array<string, array<string|int, mixed>>
-
Memoized fragment expansions, keyed by fragment name.
Return values
array<string|int, mixed>|bool — True for leaf fields, associative array otherwise.expand_fragment()
Expand a named fragment into its query info tree, memoizing the result.
private
static expand_fragment(string $name, array<string|int, mixed> $variable_values, array<string, FragmentDefinitionNode> $fragments, array<string, array<string|int, mixed>> &$expanded_fragments) : array<string|int, mixed>|null
Parameters
- $name : string
-
The fragment name.
- $variable_values : array<string|int, mixed>
-
Variable values for resolving arguments.
- $fragments : array<string, FragmentDefinitionNode>
-
Named fragment definitions from the document.
- $expanded_fragments : array<string, array<string|int, mixed>>
-
Memoized expansions, keyed by fragment name.
Return values
array<string|int, mixed>|null — The expanded tree, or null when the fragment is not defined.extract_selection_set()
Recursive worker behind {@see self::extract()}.
private
static extract_selection_set(SelectionSetNode|null $selection_set, array<string|int, mixed> $variable_values, array<string, FragmentDefinitionNode> $fragments, array<string, array<string|int, mixed>> &$expanded_fragments) : array<string|int, mixed>
Named fragments are expanded once per extract() call and the result is reused for every further spread, so the work stays proportional to the size of the document. This runs after validation, whose limits don't bound how often a fragment is spread.
Parameters
- $selection_set : SelectionSetNode|null
-
The selection set to process.
- $variable_values : array<string|int, mixed>
-
Variable values for resolving arguments.
- $fragments : array<string, FragmentDefinitionNode>
-
Named fragment definitions from the document.
- $expanded_fragments : array<string, array<string|int, mixed>>
-
Memoized expansions, keyed by fragment name. Passed by reference so the whole walk shares one cache.
Return values
array<string|int, mixed> — The query info tree for the selection set.merge_selections()
Recursively merge two selection trees produced by extract()/build_field_entry().
private
static merge_selections(array<string|int, mixed> $a, array<string|int, mixed> $b) : array<string|int, mixed>
Used wherever selections from different sources are combined under
the same key (notably: named fragment spreads expanded inline). Matches
GraphQL's selection-set merge semantics — overlapping fields have their
sub-selections unioned rather than one replacing the other, which a
shallow array_merge would do.
Rules:
- Key only in one side: kept verbatim.
- Both sides arrays: recurse, unioning children.
- One array, one
true(leaf): keep the array — it carries the sub-selection detail, and its presence already implies the field was requested. - Both
true: keeptrue. -
__argscollisions (same field with different argument values): the second operand wins. Conflicting field args are a GraphQL validation error upstream of us, so this path is defensive.
Parameters
- $a : array<string|int, mixed>
-
First selection tree.
- $b : array<string|int, mixed>
-
Second selection tree, merged into $a.
Return values
array<string|int, mixed> — The merged tree.resolve_argument_value()
Resolve the value of a single argument node, handling variables.
private
static resolve_argument_value(ArgumentNode $arg, array<string|int, mixed> $variable_values) : mixed
Parameters
- $arg : ArgumentNode
-
The argument node.
- $variable_values : array<string|int, mixed>
-
Variable values.
