简体   繁体   中英

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.

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.

The bellow code snippet allows you hide the shipping methods based on shipping class. Detailed description is available here

add_filter('woocommerce_package_rates', 'wf_hide_shipping_method_based_on_shipping_class', 10, 2);

function wf_hide_shipping_method_based_on_shipping_class($available_shipping_methods, $package)
{
$hide_when_shipping_class_exist = array(
    42 => array(
        'free_shipping'
    )
);

$hide_when_shipping_class_not_exist = array(
    42 => array(
        'wf_shipping_ups:03',
        'wf_shipping_ups:02',
         'wf_shipping_ups:01'
    ),
    43 => array(
        'free_shipping'
    )
);


$shipping_class_in_cart = array();
foreach(WC()->cart->cart_contents as $key => $values) {
   $shipping_class_in_cart[] = $values['data']->get_shipping_class_id();
}

foreach($hide_when_shipping_class_exist as $class_id => $methods) {
    if(in_array($class_id, $shipping_class_in_cart)){
        foreach($methods as & $current_method) {
            unset($available_shipping_methods[$current_method]);
        }
    }
}
foreach($hide_when_shipping_class_not_exist as $class_id => $methods) {
    if(!in_array($class_id, $shipping_class_in_cart)){
        foreach($methods as & $current_method) {
            unset($available_shipping_methods[$current_method]);
        }
    }
}
return $available_shipping_methods;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM