So there’s a few things wrong with the code:
- You’re not using the query object that’s passed to the pre_get_posts hook, so you’re not modifying the actual query.
- Field is set to
id
instead ofterm_id
. - If you’re using
IN
as the operator, pass an array to terms. - You’re not sanitizing the value of $_POST[‘networks’]. You might be ok without it, since WordPress shouldn’t let anything too nasty happen, but it’s a good idea to at least ensure that the values are the correct type.
This version of the function addresses these issues:
function my_query_by_selected_networks( $query ) {
if ( is_admin() ) {
return;
}
if ( $query->is_main_query() && $query->is_post_type_archive( 'profiles' ) ) {
if ( isset( $_POST['networks'] ) ) {
if ( is_array( $_POST['networks'] ) ) {
$networks = array_map( 'intval', $_POST['networks'])
} else {
$networks = array( intval( $_POST['networks'] ) );
}
$tax_query = $query->get( 'tax_query' ) ?: array();
$tax_query[] = array(
'taxonomy' => 'networks',
'field' => 'term_id',
'terms' => $networks,
'operator' => 'IN',
);
$query->set( 'tax_query', $tax_query );
}
}
}
add_action( 'pre_get_posts', 'my_query_by_selected_networks' );
Note:
- The function accepts the
$query
variable and uses that the update the query. - It uses
term_id
as the value forfield
. $networks
, the value passed to the tax query is left as an array, or made an array if$_POST['networks']
isn’t already an array.- It sanitizes the value of
$_POST['networks']
withintval
, making sure that$networks
is an array of integers, which is what the tax query expects.
Additionally, I modified the tax_query code so that it doesn’t entirely replace any tax queries that could be made by other plugins. It does this by checking if there’s already a tax query and adding on to it if there is. This is probably unnecessary, but it’s a habit of mine.
EDIT: As per Tom’s suggestion I’ve added in $query->is_main_query()
, to make sure that we’re only modifying the main loop, so this doesn’t go and affect things like widgets and menus etc. I also added a bit at the top to bail if we’re in the admin, since we don’t want to modify back-end queries.
Also, custom_archive
is a very generic name for a function, and could easily be shared by other plugins or WordPress itself. It’s a good idea to be more descriptive, but most importantly, you should prefix functions with something unique to your theme or plugin to avoid conflicts. In my example it’s just my_
. I suggest replacing it, since my_
is a common example prefix.