Automatically order WooCommerce products based on attributes

Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInPrint this page

WooCommerce is a powerful e-commerce platform that allows you to create and manage an online store with ease. One of the key features of WooCommerce is the ability to customize and sort products based on various criteria. In this article, we’ll explore how to implement custom sorting for WooCommerce products, specifically focusing on sorting products by a custom attribute.

By default, WooCommerce provides sorting options based on factors like popularity, average rating, and the latest products. However, what if you want to prioritize products based on a custom attribute, such as a brand in our case? This is where the Advanced Post Types Order plugin comes into play.

So far you should already be familiarized with the powerful Automatic Order. Below is a custom function designed to work with the Advanced Post Types Order – Automatic Order. This function ensures that products with a specific attribute (in this case, “merk”) are prioritized at the beginning of the product list:

function _woocommerce_products_sort_by_attribute($post_list, $sort_view_id, $orderBy, $query)
{
    $ProductAttribute = 'pa_merk';

    $merk_list = array();

    // Loop through the list of products
    foreach ($post_list as $object_id) {
        // Check if the product has the "merk" attribute (taxonomy pa_merk)
        $product_merk = get_the_terms($object_id, $ProductAttribute);
        if (!empty($product_merk)) {
            $merk_list[] = $object_id;
        }
    }

    // Merge the merk_list with the original post_list, keeping only unique values
    $post_list = array_unique(array_merge($merk_list, $post_list));

    return $post_list;
}

Explanation of the code:

  • The $ProductAttribute variable holds the name of the product attribute (taxonomy) that you want to use for sorting, in this case, ‘pa_merk’. You should update accordingly to your local attribute.
  • The loop goes through each product in the $post_list and checks if it has the specified attribute (‘pa_merk’). If it does, the product ID is added to the $merk_list.
  • The final $post_list is then created by merging the unique values from $merk_list and the original $post_list.
  • This code ensures that products with the “merk” attribute come first in the list, followed by the remaining products in their original order. The use of array_unique helps to eliminate any duplicate values in the resulting array.

To order by a specific attribute taxonomy and orders them alphabetically by the attribute name, the following code can used:

    function _woocommerce_products_sort_by_attribute( $post_list, $sort_view_id, $orderBy, $query )
        {
            $ProductAttribute = 'pa_merk';

            $merk_list = array();
            $other_list = array();

            // Loop through the list of products
            foreach ($post_list as $object_id) 
                {
                    // Check if the product has the "merk" attribute (taxonomy pa_merk)
                    $product_merk = get_the_terms($object_id, $ProductAttribute);
                    if (!empty($product_merk)) {
                        $merk_list[$object_id] = $product_merk[0]->name; // Store in an associative array for sorting
                    } else {
                        $other_list[] = $object_id;
                    }
                }

            // Sort the merk_list alphabetically by attribute name
            asort($merk_list);

            // Merge the sorted merk_list with the other_list
            $post_list = array_merge(array_keys($merk_list), $other_list);

            return $post_list;  
        }

To prioritize items with the attribute name “Yale” at the top of the list while maintaining alphabetical order, the following code can be used:

function _woocommerce_products_sort_by_attribute($post_list, $sort_view_id, $orderBy, $query)
    {
        $ProductAttribute               = 'pa_merk';
        $ProductAttributePrioritize     = 'Yale';

        $yale_list = array();
        $merk_list = array();
        $other_list = array();

        // Loop through the list of products
        foreach ($post_list as $object_id) 
            {
                // Check if the product has the "merk" attribute (taxonomy pa_merk)
                $product_merk = get_the_terms($object_id, $ProductAttribute);

                if (!empty($product_merk)) {
                    $attribute_name = $product_merk[0]->name;

                    // Check if the attribute name is "Yale" and prioritize it
                    if ( $attribute_name === $ProductAttributePrioritize ) {
                        $yale_list[] = $object_id;
                    } else {
                        $merk_list[$object_id] = $attribute_name; // Store in an associative array for sorting
                    }
                } else {
                    $other_list[] = $object_id;
                }
            }

        // Sort the merk_list alphabetically by attribute name
        asort($merk_list);

        // Merge the Yale list, sorted merk_list, and other_list
        $post_list = array_merge($yale_list, array_keys($merk_list), $other_list);

        return $post_list;
    }

To arrange items by date in descending order, while maintaining the prominence of items in the ‘pa_merk’ field, with a priority for terms related to ‘Yale,’ you can make the following modifications to the code:

function _woocommerce_products_sort_by_attribute($post_list, $sort_view_id, $orderBy, $query)
    {
        // Sort the entire $post_list by date in descending order
        usort($post_list, function ($a, $b) {
            $date_a = get_post_time('U', false, $a);
            $date_b = get_post_time('U', false, $b);

            return $date_b - $date_a;
        });

        $ProductAttribute = 'pa_merk';
        $ProductAttributePrioritize = 'Yale';

        $yale_list = array();
        $merk_list = array();
        $other_list = array();

        // Loop through the sorted list of products
        foreach ($post_list as $object_id) {
            // Check if the product has the "merk" attribute (taxonomy pa_merk)
            $product_merk = get_the_terms($object_id, $ProductAttribute);

            if (!empty($product_merk)) {
                $attribute_name = $product_merk[0]->name;

                // Check if the attribute name is "Yale" and prioritize it
                if ($attribute_name === $ProductAttributePrioritize) {
                    $yale_list[] = $object_id;
                } else {
                    $merk_list[$object_id] = $attribute_name; // Store in an associative array for sorting
                }
            } else {
                $other_list[] = $object_id;
            }
        }

        // Sort the merk_list alphabetically by attribute name
        asort($merk_list);

        // Merge the sorted lists
        $post_list = array_merge($yale_list, array_keys($merk_list), $other_list);

        return $post_list;
    }

The custom code should be placed inside a file on /wp-content/mu-plugins/ folder.