Fix default shipping method selection after rate changes (#44117)
* Change default unless local pickup is being used * Changelog
This commit is contained in:
parent
7f735714a4
commit
efe07e0ee2
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix default shipping method selection after rate changes.
|
|
@ -9,6 +9,7 @@
|
|||
*/
|
||||
|
||||
use Automattic\Jetpack\Constants;
|
||||
use Automattic\WooCommerce\StoreApi\Utilities\LocalPickupUtils;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
|
@ -446,24 +447,54 @@ function wc_get_chosen_shipping_method_for_package( $key, $package ) {
|
|||
* @since 3.2.0
|
||||
* @param int $key Key of package.
|
||||
* @param array $package Package data array.
|
||||
* @param string $chosen_method Chosen method id.
|
||||
* @param string $chosen_method Chosen shipping method. e.g. flat_rate:1.
|
||||
* @return string
|
||||
*/
|
||||
function wc_get_default_shipping_method_for_package( $key, $package, $chosen_method ) {
|
||||
$rate_keys = array_keys( $package['rates'] );
|
||||
$default = current( $rate_keys );
|
||||
$coupons = WC()->cart->get_coupons();
|
||||
foreach ( $coupons as $coupon ) {
|
||||
if ( $coupon->get_free_shipping() ) {
|
||||
foreach ( $rate_keys as $rate_key ) {
|
||||
if ( 0 === stripos( $rate_key, 'free_shipping' ) ) {
|
||||
$default = $rate_key;
|
||||
break;
|
||||
$chosen_method_id = current( explode( ':', $chosen_method ) );
|
||||
$rate_keys = array_keys( $package['rates'] );
|
||||
$chosen_method_exists = in_array( $chosen_method, $rate_keys, true );
|
||||
|
||||
/**
|
||||
* If the customer has selected local pickup, keep it selected if it's still in the package. We don't want to auto
|
||||
* toggle between shipping and pickup even if available shipping methods are changed.
|
||||
*
|
||||
* This is important for block based checkout where there is an explicit toggle between shipping and pickup.
|
||||
*/
|
||||
$local_pickup_method_ids = LocalPickupUtils::get_local_pickup_method_ids();
|
||||
$is_local_pickup_chosen = in_array( $chosen_method_id, $local_pickup_method_ids, true );
|
||||
|
||||
// Default to the first method in the package. This can be sorted in the backend by the merchant.
|
||||
$default = current( $rate_keys );
|
||||
|
||||
// Default to local pickup if its chosen already.
|
||||
if ( $chosen_method_exists && $is_local_pickup_chosen ) {
|
||||
$default = $chosen_method;
|
||||
|
||||
} else {
|
||||
// Check coupons to see if free shipping is available. If it is, we'll use that method as the default.
|
||||
$coupons = WC()->cart->get_coupons();
|
||||
foreach ( $coupons as $coupon ) {
|
||||
if ( $coupon->get_free_shipping() ) {
|
||||
foreach ( $rate_keys as $rate_key ) {
|
||||
if ( 0 === stripos( $rate_key, 'free_shipping' ) ) {
|
||||
$default = $rate_key;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Filters the default shipping method for a package.
|
||||
*
|
||||
* @since 3.2.0
|
||||
* @param string $default Default shipping method.
|
||||
* @param array $rates Shipping rates.
|
||||
* @param string $chosen_method Chosen method id.
|
||||
*/
|
||||
return apply_filters( 'woocommerce_shipping_chosen_method', $default, $package['rates'], $chosen_method );
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,6 @@ class ShippingController {
|
|||
add_filter( 'woocommerce_shipping_settings', array( $this, 'remove_shipping_settings' ) );
|
||||
add_filter( 'wc_shipping_enabled', array( $this, 'force_shipping_enabled' ), 100, 1 );
|
||||
add_filter( 'woocommerce_order_shipping_to_display', array( $this, 'show_local_pickup_details' ), 10, 2 );
|
||||
add_filter( 'woocommerce_shipping_chosen_method', array( $this, 'prevent_shipping_method_selection_changes' ), 20, 3 );
|
||||
|
||||
// This is required to short circuit `show_shipping` from class-wc-cart.php - without it, that function
|
||||
// returns based on the option's value in the DB and we can't override it any other way.
|
||||
|
@ -86,29 +85,6 @@ class ShippingController {
|
|||
add_action( 'rest_pre_serve_request', array( $this, 'track_local_pickup' ), 10, 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent changes in the selected shipping method when new rates are added or removed.
|
||||
*
|
||||
* If the chosen method exists within package rates, it is returned to maintain the selection.
|
||||
* Otherwise, the default rate is returned.
|
||||
*
|
||||
* @param string $default Default shipping method.
|
||||
* @param array $package_rates Associative array of available package rates.
|
||||
* @param string $chosen_method Previously chosen shipping method.
|
||||
*
|
||||
* @return string Chosen shipping method or default.
|
||||
*/
|
||||
public function prevent_shipping_method_selection_changes( $default, $package_rates, $chosen_method ) {
|
||||
|
||||
// If the chosen method exists in the package rates, return it.
|
||||
if ( $chosen_method && isset( $package_rates[ $chosen_method ] ) ) {
|
||||
return $chosen_method;
|
||||
}
|
||||
|
||||
// Otherwise, return the default method.
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the option to force shipping calculations NOT to wait until an address is entered, but only if the
|
||||
* Checkout page contains the Checkout Block.
|
||||
|
|
Loading…
Reference in New Issue