Skip to content
Advertisement

WooCommerce Filter products with ACF and Product Category

I am using WooCommerce to display a product loop and have built out a filter for the same loop. The filter uses acf meta which the values are pulled directly from the query string. The meta_query is working as expected, however the tax_query seems to be not ineffective. I need some assistance as to why my tax_query is not producing the correct results.

function custom_pre_get_posts_query( $q ) {

  $selected_seats = array();
  if (isset($_GET['seats']) && $_GET['seats'] != 'all') {
    $selected_seats = $_GET['seats'];
  }  

  $selected_event_type = array();
  if (isset($_GET['event_type']) && $_GET['event_type'] != 'event_all') {
    $selected_event_type = $_GET['event_type'];
  }
  
  $selected_location = array();
  if (isset($_GET['location']) && $_GET['location'] != 'location_all') {
    $selected_location = $_GET['location'];
  }
  
  $tax_query = (array) $q->get( 'meta_query' );
  $tax_query[] = array(
        'tax_query' => array(
          'taxonomy' => 'product_category',
          'field'     => 'slug',
          'operator' => 'IN',
          'terms' => $selected_location 
          //terms' => array( $selected_location )
        ),
        'meta_query'    => array(
          'relation'        => 'AND',
          // Select in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'seats',
            'value'     => $selected_seats,
            'compare'   => 'IN',
          ),
          // Checkbox in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'event_type',
            'value'     => $selected_event_type,
            'compare'   => 'LIKE',
          ),
          array(
            'key'       => 'car_categories',
            'value'     => $selected_category,
            'compare'   => 'LIKE',
          ),
        ),
        
  );

  // Special query for category
  $selected_category = array();
  if (isset($_GET['category'])) {
    $selected_category = $_GET['category'];
  }  
  $selected_category_query= array(
    'relation'      => 'OR',
  );
  foreach($selected_category as $category){
    array_push($selected_category_query,array(
      'key'     => 'car_categories',
      'value'       =>$category,
      'compare'     => 'LIKE',
    ));
  }
  $tax_query[] = array(
    'meta_query'    => $selected_category_query,
  );
  $q->set( 'meta_query', $tax_query );
}
add_action( 'woocommerce_product_query', 'custom_pre_get_posts_query' );  

a var_dump of $tax_query results in:

array(2) {
  [0]=>
  array(2) {
    ["tax_query"]=>
    array(4) {
      ["taxonomy"]=>
      string(11) "product_cat"
      ["field"]=>
      string(2) "id"
      ["terms"]=>
      array(1) {
        [0]=>
        int(75)
      }
      ["operator"]=>
      string(2) "IN"
    }
    ["meta_query"]=>
    array(4) {
      ["relation"]=>
      string(3) "AND"
      [0]=>
      array(3) {
        ["key"]=>
        string(5) "seats"
        ["value"]=>
        array(0) {
        }
        ["compare"]=>
        string(2) "IN"
      }
      [1]=>
      array(3) {
        ["key"]=>
        string(10) "event_type"
        ["value"]=>
        array(0) {
        }
        ["compare"]=>
        string(4) "LIKE"
      }
      [2]=>
      array(3) {
        ["key"]=>
        string(14) "car_categories"
        ["value"]=>
        NULL
        ["compare"]=>
        string(4) "LIKE"
      }
    }
  }
  [1]=>
  array(1) {
    ["meta_query"]=>
    array(1) {
      ["relation"]=>
      string(2) "OR"
    }
  }
}

Advertisement

Answer

I wanna try to be clear as possible here:

You are gonna set your $meta_query_args and your $tax_query_args in different keys:

Your meta_query will be set like:

$meta_query_args = array(
     'relation'        => 'AND',
          // Select in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'seats',
            'value'     => $selected_seats,
            'compare'   => 'IN',
          ),
          // Checkbox in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'event_type',
            'value'     => $selected_event_type,
            'compare'   => 'LIKE',
          ),
          array(
            'key'       => 'car_categories',
            'value'     => $selected_category,
            'compare'   => 'LIKE',
          ),
  );
$q->set( 'meta_query', $meta_query_args );

Your tax_query args will be set like: (Modify accordingly to your needs.)

$tax_query_args = array(
     'relation' => 'AND', // AND , OR (Do not use with a single inner taxonomy array)
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => array( 'action', 'comedy' ),
        ),
        //optionally if you are trying to query more than one taxonomy
        array(
            'taxonomy' => 'custom_tax_whatever',
            'field'    => 'term_id',
            'terms'    => array( 103, 115, 206 ),
        ),
  );
$q->set( 'tax_query', $tax_query_args );

your final query should look like this more or less for the meta_query and tax_query keys:

array(
  'tax_query' => array(
     'relation' => 'AND', // AND , OR (Do not use with a single inner taxonomy array)
        array(
            'taxonomy' => 'product_cat',
            'field'    => 'slug',
            'terms'    => array( 'action', 'comedy' ),
        ),
        //optionally if you are trying to query more than one taxonomy
        array(
            'taxonomy' => 'custom_tax_whatever',
            'field'    => 'term_id',
            'terms'    => array( 103, 115, 206 ),
        ),
  ),
  'meta_query' => array(
     'relation'        => 'AND',
          // Select in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'seats',
            'value'     => $selected_seats,
            'compare'   => 'IN',
          ),
          // Checkbox in ACF, doesn't need to do array cause only one filter will apply at one time
          array(
            'key'       => 'event_type',
            'value'     => $selected_event_type,
            'compare'   => 'LIKE',
          ),
          array(
            'key'       => 'car_categories',
            'value'     => $selected_category,
            'compare'   => 'LIKE',
          ),
  )
);

PD: I have not tested it, but should be good for what you want to achieve.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement