admin管理员组文章数量:1278722
I'm working on a website with a search feature that allows users to search through a lot of post meta. There is a specific search pattern that I would like to forcibly return no results for. The WP_Query technically will find results in the database, but I'd like to override that somehow to force it to return no results to trigger the if( $example->have_posts() )
to fail.
Is there some sort of parameter I can pass to WP_Query like 'force_no_results' => true
that will force it to return no results?
I'm working on a website with a search feature that allows users to search through a lot of post meta. There is a specific search pattern that I would like to forcibly return no results for. The WP_Query technically will find results in the database, but I'd like to override that somehow to force it to return no results to trigger the if( $example->have_posts() )
to fail.
Is there some sort of parameter I can pass to WP_Query like 'force_no_results' => true
that will force it to return no results?
3 Answers
Reset to default 38Try
'post__in' => array(0)
Simple and to the point.
Update:
'post__in' => empty( $include ) ? [ 0 ] : $include,
Curiously there is no clean/explicit way to short circuit WP_Query
.
If it's main query you might work something out around WP->parse_request()
, there seems to be relatively recent (3.5) do_parse_request
filter there.
But for WP_Query
itself dirty hacks are usually in order, such as short-circuiting SQL query by adding AND 1=0
via posts_where
filter, etc.
The problems on set a query parameter to unexistent value are 2:
- The query will run, so even if you already know will be no results there is a little performance price to pay
- WordPress queries has 19 different
'posts_*'
filter hooks ('posts_where'
,'post_join'
, etc..) that act on query, so you can never be sure that even setting unexistent param the query return no results, a simpleOR
clause returned by a filter make return something.
You need a little bit hardcore routine to be sure a query return no result and there is no (or very minimun) performance issue.
To trigger that routine, you can use every method, technically you can pass any argument to WP_Query
, event arguments that doesn't exists.
So if you like something like 'force_no_results' => true
, you can use it like so:
$a = new WP_Query( array( 's' => 'foo', 'force_no_results' => true ) );
and add a callback running on 'pre_get_posts'
that do the hard work:
add_action( 'pre_get_posts', function( $q ) {
if (array_key_exists('force_no_results', $q->query) && $q->query['force_no_results']) {
$q->query = $q->query_vars = array();
$added = array();
$filters = array(
'where', 'where_paged', 'join', 'join_paged', 'groupby', 'orderby', 'distinct',
'limits', 'fields', 'request', 'clauses', 'where_request', 'groupby_request',
'join_request', 'orderby_request', 'distinct_request','fields_request',
'limits_request', 'clauses_request'
);
// remove all possible interfering filter and save for later restore
foreach ( $filters as $f ) {
if ( isset($GLOBALS['wp_filter']["posts_{$f}"]) ) {
$added["posts_{$f}"] = $GLOBALS['wp_filter']["posts_{$f}"];
unset($GLOBALS['wp_filter']["posts_{$f}"]);
}
}
// be sure filters are not suppressed
$q->set( 'suppress_filters', FALSE );
$done = 0;
// use a filter to return a non-sense request
add_filter('posts_request', function( $r ) use( &$done ) {
if ( $done === 0 ) { $done = 1;
$r = "SELECT ID FROM {$GLOBALS['wpdb']->posts} WHERE 0 = 1";
}
return $r;
});
// restore any filter that was added and we removed
add_filter('posts_results', function( $posts ) use( &$done, $added ) {
if ( $done === 1 ) { $done = 2;
foreach ( $added as $hook => $filters ) {
$GLOBALS['wp_filter'][$hook] = $filters;
}
}
return $posts;
});
}
}, PHP_INT_MAX );
What this code does is run on 'pre_get_posts'
as late as possible. If the argument 'force_no_results' is present in the query, then:
- first remove all possible filters that can interfere with the query, and store them inside an helper array
- after be sure the filter are triggered, adda filter that return this kind of request:
SELECT ID FROM wp_posts WHERE 0 = 1
once all filters are removed, there is no possibilities this query is changed and it is very fast, and has no result for sure - immediately after this query is ran, all original filters (if there were any) are restored and all subsequent queries will works as expected.
本文标签: wp queryCan I force WPQuery to return no results
版权声明:本文标题:wp query - Can I force WP_Query to return no results? 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741273394a2369589.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
WP_Query()
to return no results may or may not be the best way to answer that question. It also might be helpful if you would describe the search pattern that you want to be unqueryable. Knowing the search pattern might help ferret out a solution. – Chip Bennett Commented Apr 9, 2014 at 14:51