0

I need to hide a shipping method depending on if a discount code is used or not. But I don't find how to hide a shipping method in the order confirmation page. I saw that answer but it does nothing, I tried this code to verify:

add_filter( 'woocommerce_package_rates', 'custom_shipping_rates', 100, 2 );
function custom_shipping_rates( $rates, $package ) {
    exit();
}

Which should block page display but the page is well loaded.

EDIT: The filter is never called because wordpress uses stored rates in class-wc-shipping.php:

if ( ! is_array( $stored_rates ) || $package_hash !== $stored_rates['package_hash'] || 'yes' === get_option( 'woocommerce_shipping_debug_mode', 'no' ) ) 
{
            
...
            // Filter the calculated rates.
            $package['rates'] = apply_filters( 'woocommerce_package_rates', 
           $package['rates'], $package );
...
} 
else
{
            $package['rates'] = $stored_rates['rates'];
}
Andy
  • 4,901
  • 5
  • 35
  • 57
Entretoize
  • 2,124
  • 3
  • 23
  • 44

2 Answers2

0

That code should actually work unless you have an old wc version. You can verify if that hook exist by searching for it in /plugins/woocommerce code base. If you don't find it, then something is wrong with the updates.

If you find it and your code still doesn't work, then the only other reason is that you placed that snipped of code in a point that never get fired or you simple come too late.

Could you please add where and how you placed that code so that we can see better what is going on?

Edit:

if you look above the snipped you copied you will see:

// Get rates stored in the WC session data for this package.
$wc_session_key = 'shipping_for_package_' . $package_key ;
$stored_rates   = WC()->session->get( $wc_session_key );

which makes me think that is a session-related thing. So in order to fully test you need to either open the website with another browser, empty your browser cache + cookie or use an anonymous browser session

Diego
  • 1,610
  • 1
  • 14
  • 26
  • I put this code in my theme functions.php where other filters work perfectly. My wordpress is up to date (5.5.1). I also delete cache to be sure. – Entretoize Oct 07 '20 at 08:49
  • I just find that wordpress uses $stored_rates['rates']; instead of recalculating then it doesn't call the woocommerce_package_rates filter. Is there another filter ? – Entretoize Oct 07 '20 at 08:57
  • Ok, but I need it not to be session related. – Entretoize Oct 07 '20 at 14:48
  • There's some confusion in the air, it is and it will be session related. What i'm trying to say is that you need to clear once your cache/cookies or change browser to see if your code is working. After that, all the new session's will have the right shipping_rates as you will define in your hook code – Diego Oct 07 '20 at 14:54
  • I understood but I need a dynamic thing, if the user adds a specific discount code I must have a specific shipping method, if it remove the code the shipping method must change. – Entretoize Oct 07 '20 at 15:26
0

There's a trick to disable the usage of cache, I limited it to the "update order review" action that way:

if (preg_match('#update_order_review#i',$_SERVER['REQUEST_URI']))
{
    add_filter('transient_shipping-transient-version', function($value, $name) 
    { 
        return false; 
    }, 10, 2);
}

add_filter( 'woocommerce_package_rates', 'custom_shipping_rates', 100, 2 );
function custom_shipping_rates( $rates, $package )
{
    //get coupons
    $reduc=WC()->cart->get_coupons();
    $hidemr=isset($reduc['thediscountcode']);

    if ($hidemr)
    {
        foreach($rates as $k=>$v)
        {
            if (preg_match('#MethodLabelToHide#i',$v->get_label()))
                unset($rates[$k]);
        }
    }
    
    return $rates;
}
Entretoize
  • 2,124
  • 3
  • 23
  • 44