[wp-trac] [WordPress Trac] #36687: Feature to override WP_Query to provide results from other source

WordPress Trac noreply at wordpress.org
Fri May 13 19:43:20 UTC 2016

#36687: Feature to override WP_Query to provide results from other source
 Reporter:  jpdavoutian            |       Owner:
     Type:  feature request        |      Status:  new
 Priority:  normal                 |   Milestone:  Future Release
Component:  Query                  |     Version:
 Severity:  normal                 |  Resolution:
 Keywords:  has-patch 2nd-opinion  |     Focuses:
Changes (by boonebgorges):

 * keywords:  has-patch => has-patch 2nd-opinion


 Thanks for the patch, @jpdavoutian ! It looks like a step in the right

 To my mind, a query parameter like 'external' doesn't seem like the best
 way to do this. First of all, 'external' is not really descriptive of
 what's happening here: it's really about disabling `WP_Query`'s database
 query. In your case, this is useful because you're getting your posts from
 an *external* source, but that seems to me to be a step removed. In any
 case, regardless of the name, a boolean flag like 'external' feels weird
 because presumably you will want to provide the posts themselves in the
 `$this->posts` array. Which means that you'd have to hook to
 `pre_get_posts` or something like that. So my feeling is that this feature
 should be implemented as a filter, since you'll have to use a filter
 callback no matter what.

 See [attachment:36687.diff] for my iteration on
 [attachment:query.php.patch]. I've changed the name to `posts_pre_query`.
 Filter it and return anything other than `null` to bypass the database
 queries. I've left most of the logic in the `fields=ids` etc blocks, with
 the expectation that if you filtering `posts_pre_query`, you'll check
 `fields` first and be sure to return the correct kind of data.

 In order to make the improvement fully useful, I think it's necessary to
 have a more direct way to override WP's `set_found_posts()` logic -
 presumably, this info is going to come from the same place as your `posts`
 array. I've implemented this by adding a bail condition to
 `set_found_posts()`. We could consider something more sophisticated than
 this, but it does the trick.

 Here's a sample implementation:

 function wp36687_do_external_posts_query( $posts, WP_Query $query ) {
     $response = wp_remote_get( 'https://my-remote-data-store/foo/bar' );

     if ( 200 === wp_remote_response_code( $response ) ) {
         $response_body = wp_remote_retrieve_body( $response );

         // Assuming the API response is a JSON object containing
 `post_ids` and an int `found_posts`
         $response_body = json_decode( $response_body );

         $posts = $response_body->post_ids;
         $query->found_posts = $response_body->found_posts;

     return $posts;
 add_filter( 'posts_pre_query', 'wp36687_do_external_posts_query', 10, 2 );


 - Does this seem like a sufficiently general technique for using external
 data in `WP_Query`? Are there pieces that need to be flexible that are
 not, using this technique? Use cases that aren't covered?
 - Is `posts_pre_query` a reasonable filter name?

Ticket URL: <https://core.trac.wordpress.org/ticket/36687#comment:8>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform

More information about the wp-trac mailing list