wp-graphql / wp-graphql

:rocket: GraphQL API for WordPress
https://www.wpgraphql.com
GNU General Public License v3.0
3.66k stars 443 forks source link

Acquiring the WP_Query instance within a wp-graphql filter causes post hooks to fire again #2715

Closed ToughCrab24 closed 5 months ago

ToughCrab24 commented 1 year ago

Description

When acquiring the WP_Query instance inside of wp-graphql filters, it causes post hooks such as posts_pre_query to fire a second time within the wp-graphql request lifecyle.

Example

function filter_graphql_connection_page_info(
  $page_info,
  AbstractConnectionResolver $resolver,
) {
  $query = $resolver->get_query();
  return $query->query_args;
}

add_filter(
  'graphql_connection_page_info',
  ['filter_graphql_connection_page_info'],
  10,
  2
);

Explanation

In the case the AbstractConnectionResolver is an instance of PostObjectConnectionResolver we can see that the WP_Query class is instantiated

https://github.com/wp-graphql/wp-graphql/blob/9ee971695cdb848d7b51afdd2df837bdf111df76/src/Data/Connection/PostObjectConnectionResolver.php#L94-L107

Digging into WordPress core we can see the side-effect of instantiating a new instance of WP_Query calls $this->query( $query ) in its constructor and then calls $this->get_posts()

https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-query.php#L3787

This results in applying the posts_pre_query and other hooks https://github.com/WordPress/WordPress/blob/master/wp-includes/class-wp-query.php#L3136

Steps to reproduce

Define hooks:

function filter_graphql_connection_page_info(
  $page_info,
  AbstractConnectionResolver $resolver,
) {
  $query = $resolver->get_query();
  return $query->query_args;
}

add_filter(
  'graphql_connection_page_info',
  ['filter_graphql_connection_page_info'],
  10,
  2
);

function filter_posts_pre_query($posts, WP_Query $query) {
   graphql_debug("Triggered posts_pre_query");
   return $posts;
}

add_filter('posts_pre_query', 'filter_posts_pre_query', 10, 2);

With wp-graphql debug enabled run the query

{
  posts {
    nodes {
      title
    }
  }
}

Additional context

No response

WPGraphQL Version

1.13.8

WordPress Version

6.1.1

PHP Version

7.4 & 8

Additional enviornment details

Observed in wp-graphql-offset-pagination https://github.com/valu-digital/wp-graphql-offset-pagination/blob/master/src/Loader.php#L128

Please confirm that you have searched existing issues in the repo.

Please confirm that you have disabled ALL plugins except for WPGraphQL.

ToughCrab24 commented 1 year ago

Related to https://github.com/wp-graphql/wp-graphql/issues/2696