No "main query" on WooCommerce shop page

Viewed 87

I'm trying to add filters to both the shop page and product category pages in WooCommerce to allow users to filter the product list by product_tag.

First I hook into woocommerce_before_shop_loop to output a list of tags before the products list

public function render_category_tag_id_filters(): void {
    // Get a list of all product IDs
    if ( is_shop() ) {
        $product_ids = wc_get_products(
            [
                'limit'  => PHP_INT_MAX,
                'return' => 'ids',
            ]
        );

    // Get a list of product IDs in this category
    } else if ( is_product_category() ) {
        $product_cat = get_query_var( 'product_cat' );
        $product_ids = wc_get_products(
            [
                'category' => $product_cat,
                'limit' => PHP_INT_MAX,
                'return'   => 'ids',
            ]
        );

    // Don't continue
    } else {
        return;
    }

    // Render template part here etc. etc.
}
add_action( 'woocommerce_before_shop_loop', [ $this, 'render_category_tag_id_filters' ] );

Clicking on the filters builds up a comma separated list of product_tag IDs in a query var that looks like...

/product-category/candles/?tag_ids=31,32,35

Then I'm hooking into woocommerce_product_query_tax_query to filter the main product list using the values from the query var

public function apply_category_tag_id_filters( array $tax_query, \WC_Query $wc_query ): array {
    // Abort if not the main query
    if(
        ! ( $wc_query->get_main_query() instanceof \WP_Query )
        || ! $wc_query->get_main_query()->is_main_query()
    ) {
        return $tax_query;
    }

    // Get the filter tag IDs
    $filter_tag_ids = $this->get_category_filter_tag_ids();
    if (
        ! is_array( $filter_tag_ids )
        || 0 === count( $filter_tag_ids )
    ) {
        return $tax_query;
    }

    //
    $tax_query[] = array(
        'taxonomy' => 'product_tag',
        'field'    => 'term_id',
        'terms'    =>  $filter_tag_ids,
        'operator' => 'AND',
    );

    //
    return $tax_query;
}

This is where I'm coming unstuck. It works perfectly on the product category pages. The problem is that none of the queries on the main shop page seem to be flagged as the main query. That means that my filter function quits out early. If I remove the check for the main query it works but my list of tag filters at the top of the page is also filtered by the active tag ID

Is this a bug? Am I not targeting the main query correctly?

0 Answers
Related