posts_wherefilter-hookWP 1.5.0

Allows you to change the WHERE clause of an SQL query used to retrieve posts with WP_Query.

The filter lets you modify queries and create custom conditions that determine which posts are selected in a particular situation.

posts_where fires before the pagination query is set, so use it only for changes unrelated to pagination. To make changes that also affect pagination, use the similar posts_where_paged filter, which fires after the pagination query is set.

Before changing a query, add conditions that precisely identify the page or event on which it should be changed. The filter fires whenever WP_Query runs and can alter queries where no change is intended. A query change for one page can otherwise affect every page.

Notes

suppress_filters

To disable all WP_Query filters that modify an SQL query, set suppress_filters=true. WP_Query then bypasses filters such as:

posts_where
posts_join
posts_where_paged
posts_groupby
posts_join_paged
posts_distinct
post_limits
posts_fields
posts_request
posts_results
the_posts
and so on.

The get_posts() function sets suppress_filters = true by default, so query filters do not affect it. Example:

// Function that modifies the query.
function useless_condition ( $where ) {
	return $where . ' AND 1=1 ';
}

// Attach the function to posts_where.
add_filter( 'posts_where' , 'useless_condition' );

// Retrieve posts and allow the custom filters to run.
// suppress_filters is true by default in get_posts().
$posts = get_posts( array( 'suppress_filters' => FALSE ) );

Usage

add_filter( 'posts_where', 'wp_kama_posts_where_filter' );

/**
 * Function for `posts_where` filter-hook.
 * 
 * @param string $where The WHERE clause of the query.
 *
 * @return string
 */
function wp_kama_posts_where_filter( $where ){

	// filter...
	return $where;
}
$where(string)
Part of the current SQL query. For example: WHERE post_status = 'publish' AND post_author = '1'.
$wp_query(WP_Query)
WP_Query instance passed by reference.

Examples

#1 Restrict the post query in the admin area

Suppose there is a book post type with an author taxonomy. A dropdown of authors (taxonomy terms) was created with the restrict_manage_posts action hook. When an author is selected and Filter is clicked, the books by that author should be retrieved. The author name is placed in the $_GET['author_restrict_posts'] variable. The query can be changed with posts_where using that variable:

add_filter( 'posts_where' , 'posts_where' );

function posts_where( $where ) {

	if( is_admin() ) {
		global $wpdb;

		if (
			isset( $_GET['author_restrict_posts'] ) &&
			!empty( $_GET['author_restrict_posts'] ) &&
			intval( $_GET['author_restrict_posts'] ) != 0
		) {
			$author = intval( $_GET['author_restrict_posts'] );

			$where .= " AND ID IN (SELECT object_id FROM {$wpdb->term_relationships} WHERE term_taxonomy_id=$author )";
		}
	}
	return $where;
}

#2 Query posts with IDs greater than 350

function modify_posts_where( $where ) {
	return $where . ' AND ID > 350';
}

// Add the condition.
add_filter( 'posts_where', 'modify_posts_where' );

// Run the query.
$posts = new WP_Query( [
	'post_type'      => 'post',
	'posts_per_page' => - 1,
	// Other required parameters.
] );

// Remove the condition so it does not affect other WP_Query calls.
remove_filter( 'posts_where', 'modify_posts_where' );

Changelog

Since 1.5.0 Introduced.

Where the hook is called

WP_Query::get_posts()
posts_where
wp-includes/class-wp-query.php 2796
$where = apply_filters_ref_array( 'posts_where', array( $where, &$this ) );

Where the hook is used in WordPress

Usage not found.