Search code examples
phpwoocommerceproductvariantcatalog

WooCommerce custom Loop - Attribute filters not working


I'm having some issues with some Loop for Custom Catalog Listing.

The goal: have Simple Products and some Variant Products (depend on the attribute) listed on the catalog page;

I created a custom product loop using wc_get_products with the type array('simple', 'variation') but attribute filters like size or color don't work with this listing.

This is the code:

$category = get_queried_object();

  $currentCat = "";
  if ( $category->slug != NULL ){
    $currentCat = array($category->slug);
  }

  $paged                   = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
  $ordering                = WC()->query->get_catalog_ordering_args();
  $ordering['orderby']     = array_shift(explode(' ', $ordering['orderby']));
  $ordering['orderby']     = stristr($ordering['orderby'], 'price') ? 'meta_value_num' : $ordering['orderby'];
  $products_per_page       = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
  $list_products       = wc_get_products(array(
    'meta_key'             => '_price',
    'status'               => 'publish',
    'category'             => $currentCat,
    'type'                 => array('simple', 'variation'),
    'limit'                => $products_per_page,
    'page'                => $paged,
    'paginate'             => true,
    'return'               => 'ids',
    'orderby'              => $ordering['orderby'],
    'order'                => $ordering['order'],
  ));


$totalProducts = (array) $list_products->products;

wc_set_loop_prop('current_page', $paged);
wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
wc_set_loop_prop('page_template', get_page_template_slug());
wc_set_loop_prop('per_page', $products_per_page);
wc_set_loop_prop('total', $list_products->total);
wc_set_loop_prop('total_pages', $list_products->max_num_pages);
if($totalProducts) {
    do_action('woocommerce_before_shop_loop');
    woocommerce_product_loop_start();
        foreach($totalProducts as $productID) {
            $post_object = get_post($productID);
            setup_postdata($GLOBALS['post'] =& $post_object);
            wc_get_template_part('content', 'product');
        }
        wp_reset_postdata();
    woocommerce_product_loop_end();
    do_action('woocommerce_after_shop_loop');
} else {
    do_action('woocommerce_no_products_found');
}

Anyone can give me an hand, so that filters start working??


Solution

  • Just got the way to put it to work:

    1st I have a loop to get all the product ID's with a condition in the variations to confirm if a custom field (checkbox) is checked. This is mainly to get the total number of products to set up pagination.

    The Goal is to include only the Variations Checked on the Catalog Page.

    After, I'm doing a second loop, to get all products retrieved from the previous loop.

    Here is the working solution:

    if(!function_exists('wc_get_products')) {
        return;
      }
    
    function get_issues($term) {
        $hlterms = get_terms($term);
        foreach($hlterms as $term){
            // var_dump($term->taxonomy);
            return true;
        } 
    
    }
    
    // Get all Attribute Filters
    $outputFilters = "";
    foreach($_GET as $key => $querystring){
        if (strpos($key, 'filter') !== false) {
            $outputFilters = array();
            $newkey = str_replace("filter", "pa", $key);
            if (get_issues($newkey) === true){
                $outputFilters[$newkey] = $querystring;
            }
    
        }
    }
    
    // Check if in some Category
    $category = get_queried_object();
    
    $currentCat = "";
    if ( $_GET['product_cat'] != NULL ){
        $currentCat = $_GET['product_cat'];
    } else if ($category->slug != NULL){
        $currentCat = array($category->slug);
    }
    
    // 1st Loop to get total IDs
    $paged                   = (get_query_var('paged')) ? absint(get_query_var('paged')) : 1;
    $products_per_page       = apply_filters('loop_shop_per_page', wc_get_default_products_per_row() * wc_get_default_product_rows_per_page());
    $ordering['orderby'] = 'id';
    $args = array(
        'meta_key'             => '_price',
        'status'               => 'publish',
        'category'             => $currentCat,
        'type'                 => array('simple', 'variation'),
        'limit'                => 1000,
        'paginate'             => true,
        'return'               => 'ids',
    );
    
    if ($outputFilters != ""){
        $args = array_merge($args, $outputFilters);
    }
    
      $list_products = wc_get_products($args);
      $totalProducts = (array) $list_products->products;
    
      $productsIDS = array();
      foreach($totalProducts as $productID) {
        $product_s = wc_get_product( $productID );
        if ($product_s->product_type == 'simple') {
            array_push($productsIDS, $productID);       
        } else {
        if ($product_s->product_type == 'variation') {
            $showCatalog =  get_post_meta( $productID, '_showoncatalog', true );
            if ($showCatalog == "yes"){
                array_push($productsIDS, $productID);
            }
        }
      }
    }
    
    
    // Final loop 
    $args = array(
        'meta_key'             => '_price',
        'status'               => 'publish',
        'category'             => $currentCat,
        'type'                 => array('simple', 'variation'),
        'limit'                => $products_per_page,
        'page'                => $paged,
        'paginate'             => true,
        'return'               => 'ids',
        'orderby'              => $ordering['orderby'],
        'order'                => $ordering['order'],
        'include'              => $productsIDS,
    );
    
    if ($outputFilters != ""){
        $args = array_merge($args, $outputFilters);
    }
    
    $list_products = wc_get_products($args);
    
    $totalProducts = (array) $list_products->products;
    
    wc_set_loop_prop('current_page', $paged);
    wc_set_loop_prop('is_paginated', wc_string_to_bool(true));
    wc_set_loop_prop('page_template', get_page_template_slug());
    wc_set_loop_prop('per_page', $products_per_page);
    wc_set_loop_prop('total', $list_products->total);
    wc_set_loop_prop('total_pages', $list_products->max_num_pages);
    
    
    if($totalProducts) {
        do_action('woocommerce_before_shop_loop');
        woocommerce_product_loop_start();
            foreach($totalProducts as $productID) {
                $post_object = get_post($productID);
                setup_postdata($GLOBALS['post'] =& $post_object);
                wc_get_template_part('content', 'product');
    
            }
            wp_reset_postdata();
        woocommerce_product_loop_end();
        do_action('woocommerce_after_shop_loop');
      } else {
        do_action('woocommerce_no_products_found');
      }
    
    /**
     * Hook: woocommerce_after_shop_loop.
     *
     * @hooked woocommerce_pagination - 10
     */
    #do_action( 'woocommerce_after_shop_loop' );
    

    }