PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Tuesday, February 8, 2022

[FIXED] Sort WooCommerce shipping options by ascending cost with free shipping at the end

 February 08, 2022     cart, php, shipping-method, woocommerce, wordpress     No comments   

Issue

I'm trying to sort woocommerce shipping options. I want to sort from lowest to highest price, but I need the free shipping options last.

I'm working from WooCommerce: Sort Shipping Costs from Low to High

How do I put 0 last?

add_filter( 'woocommerce_package_rates' , 'businessbloomer_sort_shipping_methods', 10, 2 );
   
function businessbloomer_sort_shipping_methods( $rates, $package ) {
    
    if ( empty( $rates ) ) return;
   
    if ( ! is_array( $rates ) ) return;
    
    uasort( $rates, function ( $a, $b ) { 
        if ( $a == $b ) return 0;
        return ( $a->cost < $b->cost ) ? -1 : 1; 
    } );
    
    return $rates;
   
    // NOTE: BEFORE TESTING EMPTY YOUR CART
       
}

Solution

The following will sort shipping options by cost from lower to higher with zero cost and empty cost last.

add_filter( 'woocommerce_package_rates' , 'sort_shipping_method_by_cost_zero_empty_cost_last', 10, 2 );
function sort_shipping_method_by_cost_zero_empty_cost_last( $rates, $package ) {
    if ( empty( $rates ) || ! is_array( $rates ) ) return;

    // Sort shipping methods based on cost
    uasort( $rates, function ( $a, $b ) {
        if ( $a == $b ) return 0;
        return ( $a->cost < $b->cost ) ? -1 : 1;
    } );

    $free = $zero = []; // Initializing

    // Loop through shipping rates
    foreach ( $rates as $rate_key => $rate ) {
        // For "free shipping" methods
        if ( 'free_shipping' === $rate->method_id ) {
            // set them on a separated array
            $free[$rate_key] = $rate;

            // Remove "Free shipping" method from $rates array
            unset($rates[$rate_key]);
        } 
        // For other shipping rates with zero cost
        elseif ( $rate->cost == 0 ) {
            // set them on a separated array
            $zero[$rate_key] = $rate;

            // Remove the current method from $rates array
            unset($rates[$rate_key]);
        }
    }

    // Merge zero cost and "free shipping" methods at the end if they exist
    return ! empty( $free ) || ! empty( $zero ) ? array_merge($rates, $zero, $free) : $rates;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Refresh the shipping caches:
1). This code is already saved on your function.php file.
2). In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.


Now the same thing ** with zero cost and empty cost first**:

add_filter( 'woocommerce_package_rates' , 'sort_shipping_method_by_cost_empty_zero_cost_first', 10, 2 );
function sort_shipping_method_by_cost_empty_zero_cost_first( $rates, $package ) {
    if ( empty( $rates ) || ! is_array( $rates ) ) return;

    // Sort shipping methods based on cost
    uasort( $rates, function ( $a, $b ) {
        if ( $a == $b ) return 0;
        return ( $a->cost < $b->cost ) ? -1 : 1;
    } );

    $free = $zero = []; // Initializing

    // Loop through shipping rates
    foreach ( $rates as $rate_key => $rate ) {
        // For "free shipping" methods
        if ( 'free_shipping' === $rate->method_id ) {
            // set them on a separated array
            $free[$rate_key] = $rate;

            // Remove "Free shipping" method from $rates array
            unset($rates[$rate_key]);
        } 
        // For other shipping rates with zero cost
        elseif ( $rate->cost == 0 ) {
            // set them on a separated array
            $zero[$rate_key] = $rate;

            // Remove the current method from $rates array
            unset($rates[$rate_key]);
        }
    }

    // Merge zero cost and "free shipping" methods at the end if they exist
    return ! empty( $free ) || ! empty( $zero ) ? array_merge($free, $zero, $rates) : $rates;
}

Code goes in functions.php file of your active child theme (or active theme). Tested and works.

Refresh the shipping caches:
1). This code is already saved on your function.php file.
2). In a shipping zone settings, disable / save any shipping method, then enable back / save.
You are done and you can test it.



Answered By - LoicTheAztec
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing