PluginProbe
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO / 1.4.23
Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO v1.4.23
1.4.23 1.4.22 1.4.21 1.4.20 1.4.19 1.4.18 1.4.17 1.4.16 1.4.15 1.4.14 1.4.13 1.4.12 1.4.11 1.4.10 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.54 All 186 releases
disco / functions / shipping.php

shipping.php in Discount Rules for WooCommerce – Disco | Dynamic Pricing, Conditions, Bulk, Bundle, BOGO 1.4.23, at functions/shipping.php

109 lines 3.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // Ensure the file is not accessed directly.
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit;
6 }
7
8 use Disco\App\Disco;
9
10 if ( ! function_exists( 'disco_add_free_shipping_rate' ) ) {
11
12 /**
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 *
25 * @param array $rates Array of rates found for the package.
26 * @return array
27 */
28 function disco_add_free_shipping_rate( $rates ) {
29 $is_free_shipping = ( new Disco )->apply_free_shipping( WC()->cart );
30
31 if ( ! $is_free_shipping ) {
32 return $rates;
33 }
34
35 $free_rates = array();
36
37 foreach ( $rates as $rate_id => $rate ) {
38 if ( 'free_shipping' !== $rate->method_id ) {
39 continue;
40 }
41
42 $free_rates[ $rate_id ] = $rate;
43 }
44
45 if ( ! empty( $free_rates ) ) {
46 return $free_rates;
47 }
48
49 // TODO: Add Label from campaign
50 return array(
51 'disco_free_shipping' => new WC_Shipping_Rate( 'disco_free_shipping', __( 'Free Shipping', 'disco' ), 0, array(), 'disco_free_shipping' ),
52 );
53 }
54
55 add_filter( 'woocommerce_package_rates', 'disco_add_free_shipping_rate', 100, 1 );
56 }
57
58 if ( ! function_exists( 'disco_refresh_shipping_cache_on_cart_checkout' ) ) {
59
60 /**
61 * Force WooCommerce to recalculate shipping rates on the cart and checkout pages.
62 *
63 * Disco adds/removes the disco_free_shipping rate through the
64 * woocommerce_package_rates filter based on the current campaign state, but
65 * WooCommerce caches the calculated package rates in the customer session
66 * keyed by a hash of the cart contents only - campaign state is NOT part of
67 * that hash. So when a campaign is activated or deactivated, an existing
68 * session keeps serving the stale cached rates: a lingering disco_free_shipping
69 * rate after deactivation, or a chosen shipping method that no longer exists,
70 * which makes the shipping options appear hidden or broken until the cart
71 * contents change.
72 *
73 * Clearing this session's cached package rates whenever the cart or checkout
74 * page is viewed forces a fresh calculation that reflects the current campaign
75 * state, for this customer only (no global cache flush).
76 *
77 * @return void
78 */
79 function disco_refresh_shipping_cache_on_cart_checkout() {
80 if ( is_admin() || ! function_exists( 'is_cart' ) || ! function_exists( 'WC' ) ) {
81 return;
82 }
83
84 if ( ! is_cart() && ! is_checkout() ) {
85 return;
86 }
87
88 $session = WC()->session;
89 $cart = WC()->cart;
90
91 if ( ! $session instanceof WC_Session || ! $cart instanceof WC_Cart ) {
92 return;
93 }
94
95 // Invalidate the cached rates for every shipping package in this session.
96 // The package keys match the keys WooCommerce uses when it stores rates
97 // under 'shipping_for_package_{key}', so setting them to false makes
98 // WC_Shipping::calculate_shipping_for_package() recalculate instead of
99 // returning the stale cached rates.
100 foreach ( array_keys( $cart->get_shipping_packages() ) as $package_key ) {
101 $session->set( 'shipping_for_package_' . $package_key, false );
102 }
103
104 $cart->calculate_shipping();
105 }
106
107 add_action( 'template_redirect', 'disco_refresh_shipping_cache_on_cart_checkout' );
108 }
109