Sort WooCommerce Products while automatically put the Out of Stock items at the end of list

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

Sorting for WooCommerce Products is a simple process. The Advanced Post Types Order cover all possibilities to match any type of sorting, automated or manual drag&drop. The article at WooCommerce – Sort Products which belong to multiple categories descriebe the basics to get it started.

Already sorted WooCommerce products, are displayed accordingly on front side. Many shop owners chose to promote marketable items by sorting the list and put on top of everything else. This is a smart technique which greatly increase visibility and imply revenue excedent. Often, Out of Stock products can be a pain and require sort adjustments to lower priority in the list and show at the bottom of it.

The Advanced Post Types Order plugin can help with that, through a custom code it provides the automation process to put any products in the list which are Out of Order at the end of the list. The sort list will be kept as is (per administrator customization), only when displayed, the products with no stock will be moved at the end of the grid.

The following code can be included in theme functions.php or within a custom plugin:

     add_filter('apto/get_order_list', 'custom_wooc_apto_get_order_list', 10, 2);
    function custom_wooc_apto_get_order_list( $order_list, $sort_view_id )
        {
            
            //not for admin, only for Front Side
            if ( is_admin() )
                return $order_list;    
                
            global $APTO;
            
            //retrieve the sort post
            $sort_view_data     =   get_post($sort_view_id);
            $sortID             =   $sort_view_data->post_parent;   
            
            //check if is a woocommerce sort
            if ( ! $APTO->functions->is_woocommerce($sortID) )
                return $order_list;
            
            //identify the products out of stock
            $out_of_stock   =   array();
            
            foreach ( $order_list   as  $key    =>  $post_id ) 
                {
                    if ( get_post_meta($post_id, '_manage_stock', TRUE )    !=  'yes' )
                        continue;
                        
                    if ( get_post_meta($post_id, '_stock', TRUE)    <   1 )
                        {
                            $out_of_stock[] =   $post_id;
                            unset(  $order_list[$key] );
                        }
                }
                
            //re-index the keys
            $order_list =   array_values($order_list);
            
            //put the OutOf Stock at the end of list
            if ( count ( $out_of_stock )  >   0 )
                {
                    foreach (   $out_of_stock   as  $post_id    )
                        {
                            $order_list[]   =   $post_id;   
                        }
                }
            
            return $order_list;
            
        }

The above code works if Manage Stock is turned On. If the shop products does not use that and rely on Stock status the following code should be instead:

     add_filter('apto/get_order_list', 'custom_wooc_apto_get_order_list', 10, 2);
    function custom_wooc_apto_get_order_list( $order_list, $sort_view_id )
        {
            
            //not for admin, only for Front Side
            if ( is_admin() )
                return $order_list;    
                
            global $APTO;
            
            //retrieve the sort post
            $sort_view_data     =   get_post($sort_view_id);
            $sortID             =   $sort_view_data->post_parent;   
            
            //check if is a woocommerce sort
            if ( ! $APTO->functions->is_woocommerce($sortID) )
                return $order_list;
            
            //identify the products out of stock
            $out_of_stock   =   array();
            
            foreach ( $order_list   as  $key    =>  $post_id ) 
                {
                    if ( get_post_meta($post_id, '_stock_status', TRUE)    !=   'instock' )
	                    {
	                        $out_of_stock[] =   $post_id;
	                        unset(  $order_list[$key] );
	                    }
                }
                
            //re-index the keys
            $order_list =   array_values($order_list);
            
            //put the OutOf Stock at the end of list
            if ( count ( $out_of_stock )  >   0 )
                {
                    foreach (   $out_of_stock   as  $post_id    )
                        {
                            $order_list[]   =   $post_id;   
                        }
                }
            
            return $order_list;
            
        }