Skip to content

Commit 4fb1694

Browse files
authored
Merge pull request #3172 from jasonbahl/feat/3159-eagerly-load-types-for-introspection-only
fix: only `eagerlyLoadType` on introspection requests
2 parents 56db113 + 5095d41 commit 4fb1694

File tree

12 files changed

+144
-47
lines changed

12 files changed

+144
-47
lines changed

cli/wp-cli.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,16 @@ public function generate_static_schema( $args, $assoc_args ) {
3939
* Generate the Schema
4040
*/
4141
WP_CLI::line( 'Getting the Schema...' );
42+
43+
// Set the introspection query flag
44+
WPGraphQL::set_is_introspection_query( true );
45+
46+
// Get the schema
4247
$schema = WPGraphQL::get_schema();
4348

49+
// Reset the introspection query flag
50+
WPGraphQL::set_is_introspection_query( false );
51+
4452
/**
4553
* Format the Schema
4654
*/

src/Registry/TypeRegistry.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use GraphQL\Error\Error;
66
use GraphQL\Type\Definition\Type;
7+
use WPGraphQL;
78
use WPGraphQL\Data\DataSource;
89
use WPGraphQL\Mutation\CommentCreate;
910
use WPGraphQL\Mutation\CommentDelete;
@@ -407,10 +408,10 @@ public function init_type_registry( self $type_registry ) {
407408
*
408409
* @var \WP_Post_Type[] $allowed_post_types
409410
*/
410-
$allowed_post_types = \WPGraphQL::get_allowed_post_types( 'objects' );
411+
$allowed_post_types = WPGraphQL::get_allowed_post_types( 'objects' );
411412

412413
/** @var \WP_Taxonomy[] $allowed_taxonomies */
413-
$allowed_taxonomies = \WPGraphQL::get_allowed_taxonomies( 'objects' );
414+
$allowed_taxonomies = WPGraphQL::get_allowed_taxonomies( 'objects' );
414415

415416
foreach ( $allowed_post_types as $post_type_object ) {
416417
PostObject::register_types( $post_type_object );
@@ -714,7 +715,7 @@ public function register_type( string $type_name, $config ): void {
714715
return $this->prepare_type( $type_name, $config );
715716
};
716717

717-
if ( is_array( $config ) && isset( $config['eagerlyLoadType'] ) && true === $config['eagerlyLoadType'] && ! isset( $this->eager_type_map[ $this->format_key( $type_name ) ] ) ) {
718+
if ( WPGraphQL::is_introspection_query() && is_array( $config ) && isset( $config['eagerlyLoadType'] ) && true === $config['eagerlyLoadType'] && ! isset( $this->eager_type_map[ $this->format_key( $type_name ) ] ) ) {
718719
$this->eager_type_map[ $this->format_key( $type_name ) ] = $this->format_key( $type_name );
719720
}
720721
}

src/Request.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -151,9 +151,6 @@ public function __construct( array $data = [] ) {
151151
// Get the Type Registry
152152
$this->type_registry = \WPGraphQL::get_type_registry();
153153

154-
// Get the Schema
155-
$this->schema = \WPGraphQL::get_schema();
156-
157154
// Get the App Context
158155
$this->app_context = \WPGraphQL::get_app_context();
159156

@@ -292,6 +289,9 @@ private function before_execute(): void {
292289
$this->do_action( $this->params );
293290
}
294291

292+
// Get the Schema
293+
$this->schema = \WPGraphQL::get_schema();
294+
295295
/**
296296
* This action runs before execution of a GraphQL request (regardless if it's a single or batch request)
297297
*

src/Utils/QueryAnalyzer.php

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
class QueryAnalyzer {
3333

3434
/**
35-
* @var \GraphQL\Type\Schema
35+
* @var \WPGraphQL\WPSchema|null
3636
*/
3737
protected $schema;
3838

@@ -107,6 +107,17 @@ class QueryAnalyzer {
107107
*/
108108
protected $is_enabled_for_query;
109109

110+
/**
111+
* @param \WPGraphQL\Request $request The GraphQL request being executed
112+
*/
113+
public function __construct( Request $request ) {
114+
$this->request = $request;
115+
$this->runtime_nodes = [];
116+
$this->models = [];
117+
$this->list_types = [];
118+
$this->queried_types = [];
119+
}
120+
110121
/**
111122
* Checks whether the Query Analyzer is enabled on the site.
112123
*
@@ -133,15 +144,17 @@ public static function is_enabled(): bool {
133144
}
134145

135146
/**
136-
* @param \WPGraphQL\Request $request The GraphQL request being executed
147+
* Get the GraphQL Schema.
148+
* If the schema is not set, it will be set.
149+
*
150+
* @throws \Exception
137151
*/
138-
public function __construct( Request $request ) {
139-
$this->request = $request;
140-
$this->schema = $request->schema;
141-
$this->runtime_nodes = [];
142-
$this->models = [];
143-
$this->list_types = [];
144-
$this->queried_types = [];
152+
public function get_schema(): ?WPSchema {
153+
if ( ! $this->schema ) {
154+
$this->schema = WPGraphQL::get_schema();
155+
}
156+
157+
return $this->schema;
145158
}
146159

147160
/**
@@ -256,9 +269,9 @@ public function determine_graphql_keys( ?string $query, ?string $operation, ?arr
256269

257270
// if there's a query (either saved or part of the request params)
258271
// get the GraphQL Types being asked for by the query
259-
$this->list_types = $this->set_list_types( $this->schema, $query );
260-
$this->queried_types = $this->set_query_types( $this->schema, $query );
261-
$this->models = $this->set_query_models( $this->schema, $query );
272+
$this->list_types = $this->set_list_types( $this->get_schema(), $query );
273+
$this->queried_types = $this->set_query_types( $this->get_schema(), $query );
274+
$this->models = $this->set_query_models( $this->get_schema(), $query );
262275

263276
/**
264277
* @param \WPGraphQL\Utils\QueryAnalyzer $query_analyzer The instance of the query analyzer
@@ -352,7 +365,7 @@ public static function get_wrapped_field_type( Type $type, FieldDefinition $fiel
352365
}
353366

354367
if ( $type instanceof NonNull || $type instanceof ListOfType ) {
355-
if ( $type instanceof ListOfType && isset( $parent_type->name ) ) {
368+
if ( $type instanceof ListOfType && ! empty( $parent_type->name ) ) {
356369
$is_list_type = true;
357370
}
358371

src/WPGraphQL.php

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ final class WPGraphQL {
6262
/**
6363
* @var bool
6464
*/
65-
protected static $is_graphql_request;
65+
protected static $is_graphql_request = false;
66+
67+
/**
68+
* @var bool
69+
*/
70+
protected static $is_introspection_query = false;
6671

6772
/**
6873
* The instance of the WPGraphQL object
@@ -140,12 +145,32 @@ public static function set_is_graphql_request( $is_graphql_request = false ) {
140145
}
141146

142147
/**
143-
* @return bool
148+
* Whether the request is a graphql request or not
144149
*/
145-
public static function is_graphql_request() {
150+
public static function is_graphql_request(): bool {
146151
return self::$is_graphql_request;
147152
}
148153

154+
/**
155+
* Set whether the request is an introspection query or not
156+
*
157+
* @param bool $is_introspection_query
158+
*
159+
* @since todo
160+
*/
161+
public static function set_is_introspection_query( bool $is_introspection_query = false ): void {
162+
self::$is_introspection_query = $is_introspection_query;
163+
}
164+
165+
/**
166+
* Whether the request is an introspection query or not (query for __type or __schema)
167+
*
168+
* @since todo
169+
*/
170+
public static function is_introspection_query(): bool {
171+
return self::$is_introspection_query;
172+
}
173+
149174
/**
150175
* Sets up actions to run at certain spots throughout WordPress and the WPGraphQL execution
151176
* cycle
@@ -203,6 +228,7 @@ static function () {
203228

204229
// Throw an exception
205230
add_action( 'do_graphql_request', [ $this, 'min_php_version_check' ] );
231+
add_action( 'do_graphql_request', [ $this, 'introspection_check' ], 10, 4 );
206232

207233
// Initialize Admin functionality
208234
add_action( 'after_setup_theme', [ $this, 'init_admin' ] );
@@ -219,6 +245,41 @@ static function () {
219245
);
220246
}
221247

248+
/**
249+
* @param ?string $query The GraphQL query
250+
* @param ?string $operation The name of the operation
251+
* @param ?array<mixed> $variables Variables to be passed to your GraphQL
252+
* request
253+
* @param \GraphQL\Server\OperationParams $params The Operation Params. This includes any
254+
* extra params,
255+
*
256+
* @throws \GraphQL\Error\SyntaxError
257+
* @throws \Exception
258+
*/
259+
public function introspection_check( ?string $query, ?string $operation, ?array $variables, \GraphQL\Server\OperationParams $params ): void {
260+
261+
if ( empty( $query ) ) {
262+
return;
263+
}
264+
265+
$ast = \GraphQL\Language\Parser::parse( $query );
266+
$is_introspection = false;
267+
268+
\GraphQL\Language\Visitor::visit(
269+
$ast,
270+
[
271+
'Field' => static function ( \GraphQL\Language\AST\FieldNode $node ) use ( &$is_introspection ) {
272+
if ( '__schema' === $node->name->value || '__type' === $node->name->value ) {
273+
$is_introspection = true;
274+
return \GraphQL\Language\Visitor::stop();
275+
}
276+
},
277+
]
278+
);
279+
280+
self::set_is_introspection_query( $is_introspection );
281+
}
282+
222283
/**
223284
* Check if the minimum PHP version requirement is met before execution begins.
224285
*
@@ -233,7 +294,7 @@ public function min_php_version_check() {
233294
throw new \Exception(
234295
esc_html(
235296
sprintf(
236-
// translators: %1$s is the current PHP version, %2$s is the minimum required PHP version.
297+
// translators: %1$s is the current PHP version, %2$s is the minimum required PHP version.
237298
__( 'The server\'s current PHP version %1$s is lower than the WPGraphQL minimum required version: %2$s', 'wp-graphql' ),
238299
PHP_VERSION,
239300
GRAPHQL_MIN_PHP_VERSION

tests/wpunit/AccessFunctionsTest.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2376,13 +2376,11 @@ public function testRegisterFieldWithNonExistingTypeReturnsErrorWhenFieldIsRefer
23762376
$this->expectedField( 'users', self::NOT_NULL ),
23772377
] );
23782378

2379-
// The third query should throw a GraphQL\Error calling out the fact that the field is referencing a non-existent type
23802379
$this->expectException( GraphQL\Error\Error::class );
23812380
$this->expectExceptionMessageMatches( "/non-existent/" );
23822381

23832382
$actual_three = $this->graphql([
23842383
'query' => $query_three
23852384
]);
2386-
23872385
}
23882386
}

tests/wpunit/AssertValidSchemaTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ public function testValidSchema() {
2727
public function testSchema() {
2828
try {
2929
$request = new \WPGraphQL\Request();
30-
$request->schema->assertValid();
30+
31+
$schema = WPGraphQL::get_schema();
32+
$schema->assertValid();
3133

3234
// Assert true upon success.
3335
$this->assertTrue( true );

tests/wpunit/CustomPostTypeTest.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1690,15 +1690,19 @@ public function testRegisterCustomPostTypeWithUnderscoresInGraphqlNameHasValidSc
16901690
// register the post type with underscore in the graphql_single_name / graphql_plural_name
16911691
register_post_type( 'with_underscore', $args );
16921692

1693-
$request = new \WPGraphQL\Request();
1693+
new \WPGraphQL\Request();
16941694

1695-
// clean up
1696-
unregister_post_type( 'with_underscore' );
1695+
$schema = WPGraphQL::get_schema();
1696+
1697+
$this->assertTrue( $schema->hasType( 'With_underscore' ) );
16971698

1698-
$request->schema->assertValid();
1699+
$schema->assertValid();
16991700

17001701
// Assert true upon success.
17011702
$this->assertTrue( true );
1703+
1704+
// clean up
1705+
unregister_post_type( 'with_underscore' );
17021706
}
17031707

17041708
public function testRegisterPostTypeWithoutGraphqlPluralNameIsValid() {
@@ -1730,7 +1734,9 @@ public function testRegisterPostTypeWithoutGraphqlPluralNameIsValid() {
17301734
);
17311735

17321736
$request = new \WPGraphQL\Request();
1733-
$request->schema->assertValid();
1737+
$schema = WPGraphQL::get_schema();
1738+
$schema->assertValid();
1739+
$this->assertTrue( $schema->hasType( 'NoPlural' ) );
17341740

17351741
self::assertQuerySuccessful(
17361742
$actual,
@@ -1757,12 +1763,18 @@ public function testRegisterPostTypeWithoutGraphqlSingleOrPluralNameDoesntInvali
17571763

17581764
// assert that the schema is still valid, even though the tax
17591765
// didn't provide the single/plural name (it will be left out of the schema)
1760-
$request = new \WPGraphQL\Request();
1761-
$request->schema->assertValid();
1766+
new \WPGraphQL\Request();
1767+
$schema = WPGraphQL::get_schema();
1768+
$schema->assertValid();
1769+
1770+
$map = array_keys( $schema->getTypeMap() );
1771+
1772+
$this->assertTrue( in_array( 'BootstrapPost', $map, true ) );
1773+
$this->assertTrue( ! in_array( 'CptNoSinglePlural', $map, true ) );
17621774

17631775
// Cleanup
17641776
unregister_post_type( 'cpt_no_single_plural' );
1765-
$this->clearSchema();
1777+
17661778
}
17671779

17681780
public function testRegisterPostTypeWithUnderscoresAsGraphqlSingleName() {

tests/wpunit/CustomTaxonomyTest.php

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,7 +1229,8 @@ public function testRegisterCustomPostTypeWithUnderscoresInGraphqlNameHasValidSc
12291229

12301230
unregister_taxonomy( 'with_underscore' );
12311231

1232-
$request->schema->assertValid();
1232+
$schema = WPGraphQL::get_schema();
1233+
$schema->assertValid();
12331234

12341235
// Assert true upon success.
12351236
$this->assertTrue( true );
@@ -1247,7 +1248,8 @@ public function testRegisterTaxonomyWithoutGraphqlPluralNameIsValid() {
12471248
);
12481249

12491250
$request = new \WPGraphQL\Request();
1250-
$request->schema->assertValid();
1251+
$schema = WPGraphQL::get_schema();
1252+
$schema->assertValid();
12511253

12521254
$query = '
12531255
{
@@ -1290,7 +1292,8 @@ public function testRegisterTaxonomyWithoutGraphqlSingleOrPluralNameDoesntInvali
12901292
// assert that the schema is still valid, even though the tax
12911293
// didn't provide the single/plural name (it will be left out of the schema)
12921294
$request = new \WPGraphQL\Request();
1293-
$request->schema->assertValid();
1295+
$schema = WPGraphQL::get_schema();
1296+
$schema->assertValid();
12941297

12951298
unregister_taxonomy( 'tax_no_single_plural' );
12961299
}

tests/wpunit/InterfaceTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ interfaceOnlyField
117117
public function testSchemaIsValid() {
118118
try {
119119
$request = new \WPGraphQL\Request();
120-
$request->schema->assertValid();
120+
$schema = WPGraphQL::get_schema();
121+
$schema->assertValid();
121122

122123
// Assert true upon success.
123124
$this->assertTrue( true );

0 commit comments

Comments
 (0)