[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
Comment:
Thanks for the patch, @jpdavoutian ! It looks like a step in the right
direction.
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 );
}}}
Questions:
- 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