| @@ -9,10 +9,20 @@ | ||
| 9 | 9 | |
| 10 | 10 | if ( ! function_exists( 'disco_add_free_shipping_rate' ) ) { |
| 11 | 11 | |
| 12 | 12 | /** |
| 13 | - * Add free shipping rate to the package. If any campaign matches, then apply free shipping. | |
| 14 | - * | |
| 13 | + * Replace the package rates with free shipping when a campaign grants it. | |
| 14 | + * | |
| 15 | + * The paid rates are dropped rather than kept alongside a free one. Leaving | |
| 16 | + * them in place only offers free shipping, it does not apply it: WooCommerce | |
| 17 | + * keeps charging whichever rate is already chosen in the session, and the | |
| 18 | + * customer has to pick the free one by hand. That is impossible on the cart | |
| 19 | + * page unless the shipping calculator is enabled, so the same campaign looked | |
| 20 | + * applied at checkout and ignored in the cart. | |
| 21 | + * | |
| 22 | + * A free shipping method the merchant configured themselves is kept in | |
| 23 | + * preference to ours, so their own title and settings survive. | |
| 24 | + * | |
| 15 | 25 | * @param array $rates Array of rates found for the package. |
| 16 | 26 | * @return array |
| 17 | 27 | */ |
| 18 | 28 | function disco_add_free_shipping_rate( $rates ) { |
| @@ -21,20 +31,26 @@ | ||
| 21 | 31 | if ( ! $is_free_shipping ) { |
| 22 | 32 | return $rates; |
| 23 | 33 | } |
| 24 | 34 | |
| 35 | + $free_rates = array(); | |
| 36 | + | |
| 25 | 37 | foreach ( $rates as $rate_id => $rate ) { |
| 26 | - if ( 'free_shipping' === $rate->method_id ) { | |
| 27 | - return $rates; | |
| 38 | + if ( 'free_shipping' !== $rate->method_id ) { | |
| 39 | + continue; | |
| 28 | 40 | } |
| 41 | + | |
| 42 | + $free_rates[ $rate_id ] = $rate; | |
| 29 | 43 | } |
| 30 | 44 | |
| 31 | - // If free shipping is not available, override rates with free shipping | |
| 45 | + if ( ! empty( $free_rates ) ) { | |
| 46 | + return $free_rates; | |
| 47 | + } | |
| 48 | + | |
| 32 | 49 | // TODO: Add Label from campaign |
| 33 | - $free_shipping_rate = new WC_Shipping_Rate( 'disco_free_shipping', __( 'Free Shipping', 'disco' ), 0, array(), 'disco_free_shipping' ); | |
| 34 | - $rates['disco_free_shipping'] = $free_shipping_rate; | |
| 35 | - | |
| 36 | - return $rates; | |
| 50 | + return array( | |
| 51 | + 'disco_free_shipping' => new WC_Shipping_Rate( 'disco_free_shipping', __( 'Free Shipping', 'disco' ), 0, array(), 'disco_free_shipping' ), | |
| 52 | + ); | |
| 37 | 53 | } |
| 38 | 54 | |
| 39 | 55 | add_filter( 'woocommerce_package_rates', 'disco_add_free_shipping_rate', 100, 1 ); |
| 40 | 56 | } |