Last active
May 25, 2022 21:01
-
-
Save jasonbahl/f6cc5d3003a56edfb1362eba8857ba12 to your computer and use it in GitHub Desktop.
Parses a GraphQL Query and returns an array of Types that were requested
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Given the Schema and a query string, return a list of GraphQL Types that are being asked for | |
* by the query. | |
* | |
* @param Schema $schema The WPGraphQL Schema | |
* @param string $query The query string | |
* | |
* @return array | |
* @throws SyntaxError|Exception | |
*/ | |
public function get_query_types( $schema, $query ) { | |
if ( empty( $query ) || $schema === null ) { | |
return []; | |
} | |
try { | |
$ast = Parser::parse( $query ); | |
} catch ( SyntaxError $error ) { | |
return []; | |
} | |
$type_map = []; | |
$type_info = new TypeInfo( $schema ); | |
$visitor = [ | |
'enter' => function ( $node, $key, $parent, $path, $ancestors ) use ( $type_info, &$type_map, $schema ) { | |
$type_info->enter( $node ); | |
$type = $type_info->getType(); | |
if ( ! $type ) { | |
return; | |
} | |
$named_type = Type::getNamedType( $type ); | |
// determine if the field is returning a list of types | |
// or singular types | |
// @todo: this might still be too fragile. We might need to adjust for cases where we can have list_of( nonNull( type ) ), etc | |
$prefix = $named_type && ( $type->name === Type::listOf( $named_type )->name ) ? 'list:' : null; | |
if ( $named_type instanceof InterfaceType ) { | |
$possible_types = $schema->getPossibleTypes( $named_type ); | |
foreach ( $possible_types as $possible_type ) { | |
$type_map[] = $prefix . strtolower( $possible_type ); | |
} | |
} else if ( $named_type instanceof ObjectType ) { | |
$type_map[] = $prefix . strtolower( $named_type ); | |
} | |
}, | |
'leave' => function ( $node, $key, $parent, $path, $ancestors ) use ( $type_info ) { | |
$type_info->leave( $node ); | |
}, | |
]; | |
Visitor::visit( $ast, Visitor::visitWithTypeInfo( $type_info, $visitor ) ); | |
$map = array_values( array_unique( array_filter( $type_map ) ) ); | |
return apply_filters( 'graphql_cache_collection_get_query_types', $map, $schema, $query, $type_info ); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Given a graphql query, this returns an array of the Types being requested.
For example:
returns:
And:
returns:
NOTE:
For fields that return an interface, this gets all possible types and adds them to the list. So the
contentNodes
query, which returns a connection to theContentNode
Interface adds all the possible types to this list: