Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save woogists/af60e9a3eb2a2ffadc67a0a8d04b77fa to your computer and use it in GitHub Desktop.
Save woogists/af60e9a3eb2a2ffadc67a0a8d04b77fa to your computer and use it in GitHub Desktop.
[General Snippets][Hide other shipping methods when “Free Shipping” is available] Show only free shipping in all states except exclusion list.
/**
* Hide ALL shipping options when free shipping is available and customer is NOT in certain states
*
* Change $excluded_states = array( 'AK','HI','GU','PR' ); to include all the states that DO NOT have free shipping
*/
add_filter( 'woocommerce_package_rates', 'hide_all_shipping_when_free_is_available' , 10, 2 );
/**
* Hide ALL Shipping option when free shipping is available
*
* @param array $available_methods
*/
function hide_all_shipping_when_free_is_available( $rates, $package ) {
$excluded_states = array( 'AK','HI','GU','PR' );
if( isset( $rates['free_shipping'] ) AND !in_array( WC()->customer->shipping_state, $excluded_states ) ) :
// Get Free Shipping array into a new array
$freeshipping = array();
$freeshipping = $rates['free_shipping'];
// Empty the $available_methods array
unset( $rates );
// Add Free Shipping back into $avaialble_methods
$rates = array();
$rates[] = $freeshipping;
endif;
if( isset( $rates['free_shipping'] ) AND in_array( WC()->customer->shipping_state, $excluded_states ) ) {
// remove free shipping option
unset( $rates['free_shipping'] );
}
return $rates;
}
@Rafo1994
Copy link

Rafo1994 commented Jun 19, 2024

Tried this code on WC 8.9.3. and it did not work. In $rates array, free shipping key was 'free_shipping:3' not 'free_shipping' as in code above, so think better thing is to loop through rates and check for 'method_id'. Also shipping_state was called incorrectly, getter method should be used instead. Code below worked for me:

add_filter( 'woocommerce_package_rates', 'hide_all_shipping_when_free_is_available' , 100, 2 );

function hide_all_shipping_when_free_is_available( $rates, $package ) {
	$excluded_states = array( 'HI' );
	
	$free = array();
	
	if( in_array( WC()->customer->get_shipping_state(), $excluded_states ) ) {
		foreach ( $rates as $rate_id => $rate ) {
			if ( 'free_shipping' === $rate->method_id ) {
				unset($rates[$rate_id]);
			}
		}

	} else {
		
		foreach ( $rates as $rate_id => $rate ) {
			if ( 'free_shipping' === $rate->method_id ) {
				$free[$rate_id] = $rate;
				break;
			}
		}
	}

	return ! empty( $free ) ? $free : $rates;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment