pre_get_posts – editing query, tax_query

So there’s a few things wrong with the code:

  1. You’re not using the query object that’s passed to the pre_get_posts hook, so you’re not modifying the actual query.
  2. Field is set to id instead of term_id.
  3. If you’re using IN as the operator, pass an array to terms.
  4. 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:

  1. The function accepts the $query variable and uses that the update the query.
  2. It uses term_id as the value for field.
  3. $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.
  4. It sanitizes the value of $_POST['networks'] with intval, 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.