2
votes

I would like all of these shipping rates to be unset if all of the products in the cart have the specified shipping class, the rule I've managed to implement removed the rates if any of the products in the cart have the specified shipping class - I have tried as you'll see below.

Here is the working php:

//ROYAL MAIL ONLY FOR SPECIFIC PRODUCTS

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

function hide_table_shipping_for_shipping_class( $rates, $package ) {
$shipping_class_target = 137; 
$in_cart = false;
foreach( WC()->cart->cart_contents as $key => $values ) {

if( $values[ 'data' ]->get_shipping_class_id() === $shipping_class_target ) {
  $in_cart = true;
  break;
 } 
}
if( $in_cart ) {
 unset( $rates['mh_wc_table_rate_plus_85'] );
 unset( $rates['mh_wc_table_rate_plus_1' ] );
 unset( $rates['mh_wc_table_rate_plus_2' ] );
 unset( $rates['mh_wc_table_rate_plus_3' ] );
 unset( $rates['mh_wc_table_rate_plus_4' ] );
 unset( $rates['mh_wc_table_rate_plus_5' ] );
 unset( $rates['mh_wc_table_rate_plus_6' ] );
 unset( $rates['mh_wc_table_rate_plus_7' ] );
 unset( $rates['mh_wc_table_rate_plus_8' ] );
 unset( $rates['mh_wc_table_rate_plus_9' ] );
 unset( $rates['mh_wc_table_rate_plus_10' ] );
 unset( $rates['mh_wc_table_rate_plus_11' ] );
  unset( $rates['mh_wc_table_rate_plus_12' ] );
  unset( $rates['mh_wc_table_rate_plus_13' ] );
  unset( $rates['mh_wc_table_rate_plus_14' ] );
  unset( $rates['mh_wc_table_rate_plus_15' ] );
  unset( $rates['mh_wc_table_rate_plus_16' ] );
  unset( $rates['mh_wc_table_rate_plus_18' ] );
 unset( $rates['mh_wc_table_rate_plus_19' ] );
  unset( $rates['mh_wc_table_rate_plus_20' ] );
  unset( $rates['mh_wc_table_rate_plus_21' ] );
  unset( $rates['mh_wc_table_rate_plus_22' ] );
  unset( $rates['mh_wc_table_rate_plus_23' ] );
  unset( $rates['mh_wc_table_rate_plus_24' ] );
  unset( $rates['mh_wc_table_rate_plus_25' ] );
  unset( $rates['mh_wc_table_rate_plus_26' ] );
  unset( $rates['mh_wc_table_rate_plus_27' ] );
  unset( $rates['mh_wc_table_rate_plus_28' ] );
  unset( $rates['mh_wc_table_rate_plus_29' ] );
  unset( $rates['mh_wc_table_rate_plus_30' ] );
  unset( $rates['mh_wc_table_rate_plus_31' ] );
  unset( $rates['mh_wc_table_rate_plus_32' ] );
  unset( $rates['mh_wc_table_rate_plus_33' ] );
  unset( $rates['mh_wc_table_rate_plus_34' ] );
  unset( $rates['mh_wc_table_rate_plus_35' ] );
  unset( $rates['mh_wc_table_rate_plus_36' ] );
  unset( $rates['mh_wc_table_rate_plus_37' ] );
  unset( $rates['mh_wc_table_rate_plus_38' ] );
  unset( $rates['mh_wc_table_rate_plus_39' ] );
  unset( $rates['mh_wc_table_rate_plus_40' ] );
  unset( $rates['mh_wc_table_rate_plus_41' ] );
  unset( $rates['mh_wc_table_rate_plus_42' ] );
  unset( $rates['mh_wc_table_rate_plus_43' ] );
  unset( $rates['mh_wc_table_rate_plus_44' ] );
  unset( $rates['mh_wc_table_rate_plus_45' ] );
  unset( $rates['mh_wc_table_rate_plus_46' ] );
  unset( $rates['mh_wc_table_rate_plus_47' ] );
  unset( $rates['mh_wc_table_rate_plus_48' ] );
  unset( $rates['mh_wc_table_rate_plus_49' ] );
  unset( $rates['mh_wc_table_rate_plus_50' ] );
  unset( $rates['mh_wc_table_rate_plus_51' ] );
  unset( $rates['mh_wc_table_rate_plus_52' ] );
  unset( $rates['mh_wc_table_rate_plus_53' ] );
  unset( $rates['mh_wc_table_rate_plus_54' ] );
  unset( $rates['mh_wc_table_rate_plus_55' ] );
  unset( $rates['mh_wc_table_rate_plus_56' ] );
  unset( $rates['mh_wc_table_rate_plus_57' ] );
  unset( $rates['mh_wc_table_rate_plus_58' ] );
  unset( $rates['mh_wc_table_rate_plus_59' ] );
  unset( $rates['mh_wc_table_rate_plus_60' ] );
  unset( $rates['mh_wc_table_rate_plus_61' ] );
  unset( $rates['mh_wc_table_rate_plus_62' ] );
  unset( $rates['mh_wc_table_rate_plus_63' ] );
  unset( $rates['mh_wc_table_rate_plus_64' ] );
  unset( $rates['mh_wc_table_rate_plus_65' ] );
  unset( $rates['mh_wc_table_rate_plus_66' ] );
  unset( $rates['mh_wc_table_rate_plus_67' ] );
  unset( $rates['mh_wc_table_rate_plus_68' ] );
  unset( $rates['mh_wc_table_rate_plus_69' ] );
  unset( $rates['mh_wc_table_rate_plus_70' ] );
  unset( $rates['mh_wc_table_rate_plus_71' ] );
  unset( $rates['mh_wc_table_rate_plus_72' ] );
  unset( $rates['mh_wc_table_rate_plus_73' ] );
  unset( $rates['mh_wc_table_rate_plus_74' ] );
  unset( $rates['mh_wc_table_rate_plus_75' ] );
  unset( $rates['mh_wc_table_rate_plus_78' ] );
  unset( $rates['mh_wc_table_rate_plus_79' ] );
  unset( $rates['mh_wc_table_rate_plus_80' ] );
  unset( $rates['mh_wc_table_rate_plus_81' ] );
  unset( $rates['mh_wc_table_rate_plus_82' ] );
  unset( $rates['mh_wc_table_rate_plus_83' ] );
  unset( $rates['mh_wc_table_rate_plus_84' ] );
  unset( $rates['mh_wc_table_rate_plus_86' ] );
  unset( $rates['mh_wc_table_rate_plus_87' ] );
  unset( $rates['mh_wc_table_rate_plus_88' ] );
  unset( $rates['mh_wc_table_rate_plus_89' ] );
  unset( $rates['mh_wc_table_rate_plus_90' ] );
  unset( $rates['mh_wc_table_rate_plus_91' ] );
  unset( $rates['mh_wc_table_rate_plus_92' ] );
  unset( $rates['mh_wc_table_rate_plus_93' ] );
  unset( $rates['mh_wc_table_rate_plus_94' ] );
  unset( $rates['mh_wc_table_rate_plus_95' ] );
  unset( $rates['mh_wc_table_rate_plus_96' ] );
  unset( $rates['mh_wc_table_rate_plus_97' ] );
  unset( $rates['mh_wc_table_rate_plus_98' ] );
  unset( $rates['mh_wc_table_rate_plus_99' ] );
  unset( $rates['mh_wc_table_rate_plus_100' ] );
  unset( $rates['mh_wc_table_rate_plus_101' ] );
  unset( $rates['mh_wc_table_rate_plus_102' ] );
  unset( $rates['mh_wc_table_rate_plus_103' ] );
  unset( $rates['mh_wc_table_rate_plus_17' ] );
  unset( $rates['mh_wc_table_rate_plus_76' ] );
  unset( $rates['mh_wc_table_rate_plus_77' ] );
}
return $rates;
}

I have tried to create an exception by using the following:

foreach( WC()->cart->cart_contents as $key => $values ) {
    if( $values[ 'data' ]->get_shipping_class_id() == 0 ) { 
$in_cart = false;
break;
}
elseif( $values[ 'data' ]->get_shipping_class_id() === $shipping_class_target ) {
  $in_cart = true;
  break;
 } 
}
if( $in_cart ) {... etc

This did not work :(

FINAL using LoicTheAztec's edit (thank you):

add_filter( 'woocommerce_package_rates',              'hide_table_shipping_for_shipping_class', 10, 2 );
function hide_table_shipping_for_shipping_class( $rates, $package ) {

$targeted_class = 137; // <== Your targetted shipping class

// Loop through cart items to find out if any hasn't the targetted shipping class
foreach( WC()->cart->cart_contents as $key => $values ) {
    // IF One item is found without this shipping class
    if( $values[ 'data' ]->get_shipping_class_id() != $targeted_class ) {

##----- This is what I've added, I couldn't make it work in your nice clean format----##
unset( $rates['mh_wc_table_rate_plus_108' ] );
unset( $rates['mh_wc_table_rate_plus_107' ] );
unset( $rates['mh_wc_table_rate_plus_106' ] );
unset( $rates['mh_wc_table_rate_plus_105' ] );
unset( $rates['mh_wc_table_rate_plus_104' ] );

        return $rates; // <== FOUND! We exit returning all Shipping rates
    } 
}

## --------------------- REMOVING SHIPPING METHOD RATES IDS ---------------------- ##
##                 (when all cart items have the targeted shipping class)

// All shipping instance IDs to be removed
$instance_ids = array(
    '1', '2', '3', '4', '5', '6', '7', '8', '9', '10',
    '11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
    '21', '22', '23', '24', '25', '26', '27', '28', '29', '30',
    '31', '32', '33', '34', '35', '36', '37', '38', '39', '40',
    '41', '42', '43', '44', '45', '46', '47', '48', '49', '50',
    '51', '52', '53', '54', '55', '56', '57', '58', '59', '60',
    '61', '62', '63', '64', '65', '66', '67', '68', '69', '70',
    '71', '72', '73', '74', '75', '76', '77', '78', '79', '80',
    '81', '82', '83', '84', '85', '86', '87', '88', '89', '90',
    '91', '92', '93', '94', '95', '96', '97', '98', '99', '100',
    '101', '102', '103',
);

// Loop: Unsetting each shipping method rate Ids
foreach( $instance_ids as $instance_id )
    unset( $rates["mh_wc_table_rate_plus_$instance_id"] );

return $rates;

}

1

1 Answers

0
votes

Updated (corrected some errors)

You should try the following where I look for an item that has not the shipping class instead. Also I have revisited and compacted your code:

add_filter( 'woocommerce_package_rates',     'hide_table_shipping_for_shipping_class', 10, 2 );
function hide_table_shipping_for_shipping_class( $rates, $package ) {

    $targeted_class = 137; // <== Your targetted shipping class

    // Loop through cart items to find out if any hasn't the targetted shipping class
    foreach( WC()->cart->cart_contents as $key => $values ) {
        // IF One item is found without this shipping class
        if( $values[ 'data' ]->get_shipping_class_id() != $targeted_class ) {
            return $rates; // <== FOUND! We exit returning all Shipping rates
        } 
    }

    ## --------------------- REMOVING SHIPPING METHOD RATES IDS ---------------------- ##
    ##                 (when all cart items have the targeted shipping class)

    // All shipping instance IDs to be removed
    $instance_ids = array(
        '1', '2', '3', '4', '5', '6', '7', '8', '9', '10',
        '11', '12', '13', '14', '15', '16', '17', '18', '19', '20',
        '21', '22', '23', '24', '25', '26', '27', '28', '29', '30',
        '31', '32', '33', '34', '35', '36', '37', '38', '39', '40',
        '41', '42', '43', '44', '45', '46', '47', '48', '49', '50',
        '51', '52', '53', '54', '55', '56', '57', '58', '59', '60',
        '61', '62', '63', '64', '65', '66', '67', '68', '69', '70',
        '71', '72', '73', '74', '75', '76', '77', '78', '79', '80',
        '81', '82', '83', '84', '85', '86', '87', '88', '89', '90',
        '91', '92', '93', '94', '95', '96', '97', '98', '99', '100',
        '101', '102', '103',
    );

    // Loop: Unsetting each shipping method rate Ids
    foreach( $instance_ids as $id )
        unset( $rates['mh_wc_table_rate_plus_'.$id] );

    return $rates;
}

Code goes in function.php file of the active child theme (or active theme).

Tested and it should works for you.

Sometimes, you should may be need to refresh shipping methods:
1) Empty cart first.
2) Go to shipping Zones settings, then disable/save and re-enable/save the related shipping methods.

Answer based on: Hide shipping method for specific shipping classes in woocommerce