For some reason using pre_get_posts isn't filtering the products properly on the Shop page. I can tell the hook is being called on the proper page because if I print the $query variable it only shows on the page I want it to. However, the tax_query doesn't seem to be filtering properly.

The shop page is set to show categories. I would like to have it where if $_SESSION['mid'] is set, then it will only show that category on the Shop page. I know that the proper value is being passed because I can see it in the print of $query.


function shop_filter_cat($query) {
    if (!is_admin() && isset($_SESSION['mid']) && is_post_type_archive( 'product' ) && $query->is_main_query()) {
        $query->set('tax_query', array( // Include only products from merchant with ID = $_SESSION['mid']
            array (
                'taxonomy' => 'product_cat',
                'field' => 'slug',
                'terms' => $_SESSION['mid'],
                'operator' => 'IN'
    // print_r($query);
  • change field from slug to term_id if $_SESSION['mid'] is numeric value 'field' => 'term_id' Mar 14, 2017 at 5:03
  • it's not a numeric value, i'm actually using the slug. However, for the sake of testing I tried switching to term_id and using the category's tag_id. Still no luck.
    – Patrick H.
    Mar 14, 2017 at 16:51

1 Answer 1


I figured out what the issue was. The page was displaying categories/subcategories and not the items themselves. This meant that woocommerce_product_subcategories() was the one filtering and that uses a different hook.

Here is what I added to my functions.php file.

add_filter( 'get_terms', 'get_subcategory_terms', 10, 3 );

function get_subcategory_terms( $terms, $taxonomies, $args ) {

  $new_terms = array();

  // if a product category and on the shop page
  if ( in_array( 'product_cat', $taxonomies ) && ! is_admin() && is_shop() && isset($_SESSION['mid'])  ) {

    foreach ( $terms as $key => $term ) {

      if ( in_array( $term->slug, array( $_SESSION['mid'] ) ) ) {
        $new_terms[] = $term;


    $terms = $new_terms;

  return $terms;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.