Search code examples
phpwordpresswoocommercehook-woocommerce

Attempting to List Product Categories along with the price range of their products


I'm trying to create a page where I display a list of categories and the price range of the products within those categories.

E.g

Headwear – £30-£150

Shoes – £35-£300

Where "Headwear" is the Product Category Name, "£30" is the lowest price of a product within that category and "£150" is the highest.

So far I have used the following code to list the categories, but not sure how to check for products within each and get the prices etc.

$order = 'asc';
$hide_empty = false ;
$cat_args = array(
    'orderby'    => $orderby,
    'order'      => $order,
    'hide_empty' => $hide_empty,
);
 
$product_categories = get_terms( 'product_cat', $cat_args );
 
if( !empty($product_categories) ){
    echo '
 
<ul>';
    foreach ($product_categories as $key => $category) {
        echo '
 
<li>';
        echo '<a href="'.get_term_link($category).'" >';
        echo $category->name;
        echo '</a>';
        echo '</li>';
    }
    echo '</ul>
 
 
';
}

I'm fairly inexperienced in Woocommerce so any help would be greatly appreciated


Solution

  • You can get the list of products by product category slug with the following snippet (source: https://www.businessbloomer.com/woocommerce-get-return-all-product-ids/):

       $all_ids = get_posts( array(
          'post_type' => 'product',
          'numberposts' => -1,
          'post_status' => 'publish',
          'fields' => 'ids',
          'tax_query' => array(
             array(
                'taxonomy' => 'product_cat',
                'field' => 'slug',
                'terms' => 'your_product_cat',
                'operator' => 'IN',
             )
          ),
       ));
    

    So, for each category, you can loop through products and find the least and most expensive:

    $min = PHP_FLOAT_MAX;
    $max = 0.00;
    foreach ( $all_ids as $id ) {
       $product = wc_get_product( $id );
       $min = $product->get_price() < $min ? $product->get_price() : $min;
       $max = $product->get_price() > $max ? $product->get_price() : $max;
    }
    

    All together with your code now:

    $order = 'asc';
    $hide_empty = false;
    $cat_args = array(
        'orderby' => $orderby,
        'order' => $order,
        'hide_empty' => $hide_empty,
    );   
    $product_categories = get_terms( 'product_cat', $cat_args );
    if ( ! empty( $product_categories ) ) {
        echo '<ul>';
        foreach ( $product_categories as $key => $category ) {
            $all_ids = get_posts( array(
                'post_type' => 'product',
                'numberposts' => -1,
                'post_status' => 'publish',
                'fields' => 'ids',
                'tax_query' => array(
                   array(
                      'taxonomy' => 'product_cat',
                      'field' => 'slug',
                      'terms' => $category->slug,
                      'operator' => 'IN',
                   )
                ),
            ));
            $min = PHP_FLOAT_MAX;
            $max = 0.00;
            foreach ( $all_ids as $id ) {
            $product = wc_get_product( $id );
               $min = wc_format_decimal( $product->get_price() ) < $min ? wc_format_decimal( $product->get_price() ) : $min;
               $max = wc_format_decimal( $product->get_price() ) > $max ? wc_format_decimal( $product->get_price() ) : $max;
            }
            echo '<li><a href="' . get_term_link( $category ) . '">';
            echo $category->name . ' - ' . wc_price( $min ) . '-' . wc_price( $max );
            echo '</a></li>';
        }
        echo '</ul>';
    }