Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
714 views
in Technique[技术] by (71.8m points)

php - Woocommerce, hide shipping method based on shipping class

I'm trying to hide all but one shipping method based on the shipping class, essentially forcing the FedEx overnight method when a product belonging to a specific class is selected.

I'm starting with this code, and modifying it as indicated below:

add_filter( 'woocommerce_available_shipping_methods', 'hide_shipping_based_on_class' ,    10, 1 );

function check_cart_for_share() {

// load the contents of the cart into an array.
global $woocommerce;
$cart = $woocommerce->cart->cart_contents;

$found = false;

// loop through the array looking for the tag you set. Switch to true if the tag is     found.
foreach ($cart as $array_item) {
$term_list = wp_get_post_terms( $array_item['product_id'], 'product_shipping_class', array( "fields" => "names" ) );

if (in_array("Frozen",$term_list)) {

      $found = true;
      break;
    }
}

return $found;

}

function hide_shipping_based_on_class( $available_methods ) {

// use the function above to check the cart for the tag.
if ( check_cart_for_share() ) {

// remove the rate you want
unset( $available_methods['canada_post,purolator,fedex:FEDEX_GROUND,fedex:GOUND_HOME_DELIVERY'] ); 
}

// return the available methods without the one you unset.
return $available_methods;

}

It doesn't seem to be hiding any shipping methods though. Not sure what I'm missing...

It's a multi-site installation, I'm testing it on the Canadian side at http://stjeans.harbourcitydevelopment.com

I'm running the Table Rate shipping module, as well as the FedEx, Purolator and Canada Post modules.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I had same issue and modyfing your code helped. One problem is that "woocommerce_available_shipping_methods" filter is deprecated from WooCommerce 2.1. So you have to use the new one: "woocommerce_package_rates". There is WooCommerce tutorial for similar task, too.

So, I changed filter hook, and when the condition is true, I iterate all shipping methods/rates, find the one I want to display to customer, create new array from it and return this array (with only one item).

I think your problem was (beside deprecated hook) mainly in wrong unset($available_methods[...]) line. It could not work like that.

So here is my code:

add_filter( 'woocommerce_package_rates', 'hide_shipping_based_on_class' ,    10, 2 );
function hide_shipping_based_on_class( $available_methods ) {
    if ( check_cart_for_share() ) {
        foreach($available_methods as $key=>$method) {
            if( strpos($key,'YOUR_METHOD_KEY') !== FALSE ) {
                $new_rates = array();
                $new_rates[$key] = $method;
                return $new_rates;
            }
        }
    }
    return $available_methods;
}

Warning! I found out that woocommerce_package_rates hook is not fired everytime, but only when you change items or quantity of items in your cart. Or it looks like that for me. Maybe those available rates are cached somehow for cart content.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...