2

I am trying to make custom filter for my woocommerce website. Everything is working fine in the shop page, but when I go to the archive page the filters are not working. I am recording each filter property in the URL address.

The code in the shop page is working, but in the archive page ( category ) its not working. Does anybody know how to manipulate the SQL query in the archive page ? My current code is:

function modify_query($query) {
    if(!is_admin() && $query->is_main_query() && $query->query_vars['post_type'] == 'product') {
        if(isset($_GET["fillter"])) {
            $arr[] = array(
                'taxonomy' => 'pc_filters',
                'field'    => 'term_id',
                'terms'    => $_GET["fillter"],
            );
            $query->set('tax_query', array(
                        'relation' => 'AND',
                            array($arr)
                        )
                    );          
            return $query;
        }
    }
}
add_action('pre_get_posts', 'modify_query');

But its working only in the shop page.

1

I'm not sure at first glance why this is only working on your home page and not your archive pages, but there are a few things wrong with the way this function is written. So, I've rewritten it for you below - using this instead might solve the problem if it was introducing an esoteric bug before.

A couple of things to note:

  • relation should not be used with tax_query when there is only one inner query (reference)
  • your tax_query was three arrays deep - it should only be two
  • as pre_get_posts is an action, there is no return value accepted (in this case, $query is passed by reference, so it doesn't need returning)
  • "filter" was misspelled as "fillter" (while this wouldn't have broken the code on its own, it could have mixed you up during testing if you used ?filter= in your query string)
  • I've also added sanitisation of the querystring variable you're bringing in, by way of absint() given it is a term_id

With that said, here's the simplified function:

function modify_query($query) {
  if( ! is_admin() && $query->is_main_query() && $query->query_vars['post_type'] == 'product') {
    if( isset( $_GET['filter'] ) ) {

      $query->set( 'tax_query', array (
        array(
          'taxonomy' => 'pc_filters',
          'field'    => 'term_id',
          'terms'    => absint( $_GET['filter'] ),
        )
      ));

    }
  }
}

add_action( 'pre_get_posts', 'modify_query' );

I haven't tested this, but it should do what you were intending in a slightly simpler way, which might solve your problem.

If this doesn't solve it, it might be due to the query that WooCommerce is using on the archive pages, in particular, the value of query_vars['post_type']. WooCommerce specifics are off-topic here and I'm not actually familiar with it myself, but as far as general WordPress goes, you could use print_r($query->query_vars); within the above function to see what you have to work with, and then modify accordingly. Alternatively, you could remove the post_type check altogether, although then this code would also apply to your general posts and pages which might not be what you're after.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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