1

I want to enable or disable Shipping Methods, according to user role. I have tested various different codes and approaches, none of which have worked so far.

The current code: (source: stacklink )

add_filter( 'woocommerce_package_rates', 'hide_specific_shipping_method_based_on_user_role', 30, 2 );
function hide_shipping_method_based_on_user_role( $rates, $package ) {

    $shipping_id = 'shipmondo:3';

    foreach( $rates as $rate_key => $rate ){
        if( $rate->method_id === $shipping_id ){
            if( current_user_can( 'b2b' ) || ! is_user_logged_in()){
                unset($rates[$rate_key]);
                break;
            }
        }
    }
    return $rates;
}

(Have tested the original snippet as well, without changes, accept for the user role ) Does not work for me. I tested it with 'local_pickup' as well, It does work sometimes, but seems to be very sensitive to browser cache and session. Also what I need, is 3 methods which are called under the same name, but with a child number separating them: shipmondo:3, shipmondo:4, etc. (found in browser inspection under "Value") There is also something called ID, which looks like: 'shipping_method_0_shipmondo3' Dont know if I could use that instead, but it is kind of hard to figure out, when the code isn't updating correctly. The snippet is from 2018, so it could be an outdated thing, but the newer snippets I have found, are based on the same principale, and does not look to be doing it much different.

Also, why would the "|| ! is_user_logged_in()" be necessary? I only need to disable 2 out of 3 methods for a wholesale user, need not to effect any other roles, nor guests. Been fighting with this for days now.

Also, any advice on forcing Wordpress and Woocommerce to update, and not swim around in cache?

Thanks in advance.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
Pandusen
  • 97
  • 8

1 Answers1

4

You are confusing shipping method "Method Id" and shipping method "Rate Id". Also your code can be simplified. Try the following instead:

add_filter( 'woocommerce_package_rates', 'hide_specific_shipping_method_based_on_user_role', 100, 2 );
function hide_specific_shipping_method_based_on_user_role( $rates, $package ) {
    // Here define the shipping rate ID to hide
    $targeted_rate_id    = 'shipmondo:3'; // The shipping rate ID to hide
    $targeted_user_roles = array('b2b');  // The user roles to target (array)

    $current_user  = wp_get_current_user();
    $matched_roles = array_intersect($targeted_user_roles, $current_user->roles);

    if( ! empty($matched_roles) && isset($rates[$targeted_rate_id]) ) {
        unset($rates[$targeted_rate_id]);
    }
    return $rates;
}

Code goes in functions.php file of the active child theme (or active theme). It should work.

Don't forget to empty your cart, to clear shipping cached data.

LoicTheAztec
  • 229,944
  • 23
  • 356
  • 399
  • Hmm, this snippet turns off all shipping methods...?? btw, you might wanna add a semicolon to the "unset" line ;) But at least it is doing something. Thank you! – Pandusen Mar 18 '21 at 09:30
  • strange. I will do some further testing. For me, the user role b2b, has no available shipping methods, and all others have 3. – Pandusen Mar 18 '21 at 15:03
  • I dont know why, but this code isn't working for me. When I set this code, all shipping methods are gone, for all users. So it breaks shipping methods(for me). – Pandusen Mar 24 '21 at 11:39
  • 1
    @Pandusen Updated the code: This time it will work (empty your cart first). – LoicTheAztec Mar 24 '21 at 13:11
  • Thanx. That works! I changed it, to hide 2 methods for b2b, and hide 1 for everyone else, so that b2b has its own shipping method. It works perfectly, and seems solid as a rock. So it seems most of the wonkiness, was from the "current_user_can" – Pandusen Apr 05 '21 at 07:18