PluginProbe ʕ •ᴥ•ʔ
WPML Multilingual & Multicurrency for WooCommerce / 5.5.7
WPML Multilingual & Multicurrency for WooCommerce v5.5.7
5.5.7 5.3.8 5.3.9 5.4.3 5.4.4 5.4.5 5.5.1 5.5.1.1 5.5.2.2 5.5.2.3 5.5.3 5.5.3.1 5.5.4 5.5.5 5.5.6 trunk 0.9 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.2 2.3 2.3.1 2.3.2 3.0 3.0.1 3.1 3.2 3.2.1 3.2.2 3.3 3.3.1 3.3.2 3.3.3 3.3.4 3.4 3.4.1 3.4.2 3.4.3 3.5 3.5.1 3.5.2 3.5.3 3.5.4 3.5.5 3.6 3.6.1 3.6.10 3.6.11 3.6.2 3.6.3 3.6.4 3.6.5 3.6.5.1 3.6.6 3.6.7 3.6.8 3.6.9 3.7 3.7.1 3.7.10 3.7.11 3.7.12 3.7.13 3.7.14 3.7.15 3.7.16 3.7.2 3.7.3 3.7.4 3.7.5 3.7.6 3.7.7 3.7.8 3.7.9 3.8.0 3.8.1 3.8.2 3.8.3 3.8.4 3.8.5 3.8.6 3.9.0 3.9.1 3.9.1.1 3.9.2 3.9.3 3.9.4 3.9.5 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.10.4 4.11.2 4.11.3.2 4.11.5 4.11.6 4.12.1 4.12.4 4.12.5 4.12.6 4.2.0 4.2.0.1 4.2.1 4.2.1.1 4.2.10 4.2.2 4.2.3 4.2.4 4.2.5 4.2.6 4.2.7 4.2.7.1 4.2.8 4.2.8.1 4.2.9 4.3.0 4.3.1 4.3.2 4.3.2.1 4.3.3 4.3.4 4.3.5 4.3.6 4.3.7 4.4.0 4.4.1 4.4.2 4.4.2.1 4.5.0 4.6.0 4.6.1 4.6.2 4.6.2.1 4.6.3 4.6.5 4.6.6 4.6.7 4.7.0 4.7.1 4.7.2 4.7.3 4.7.4 4.7.5 4.7.6 4.7.7 4.7.8 4.7.9 4.8.0 4.9.0 4.9.1 5.0.1 5.0.2 5.1.1 5.1.2 5.1.3 5.2.0 5.2.1 5.3.2 5.3.3.1 5.3.4 5.3.5 5.3.6 5.3.7
woocommerce-multilingual / inc / currencies / class-wcml-multi-currency-shipping.php
woocommerce-multilingual / inc / currencies Last commit date
currency-switcher 4 weeks ago class-wcml-custom-prices.php 4 weeks ago class-wcml-multi-currency-configuration.php 4 weeks ago class-wcml-multi-currency-coupons.php 1 year ago class-wcml-multi-currency-install.php 4 weeks ago class-wcml-multi-currency-orders.php 4 weeks ago class-wcml-multi-currency-prices.php 4 weeks ago class-wcml-multi-currency-reports.php 4 weeks ago class-wcml-multi-currency-resources.php 4 weeks ago class-wcml-multi-currency-shipping.php 4 weeks ago class-wcml-multi-currency-table-rate-shipping.php 4 weeks ago class-wcml-multi-currency.php 4 weeks ago class-wcml-price-filter.php 4 weeks ago class-wcml-w3tc-multi-currency.php 4 weeks ago
class-wcml-multi-currency-shipping.php
228 lines
1 <?php
2
3 use WCML\Multicurrency\Shipping\ShippingModeProvider as ManualCost;
4
5 class WCML_Multi_Currency_Shipping {
6
7 const CACHE_PERSISTENT_GROUP = 'converted_shipping_cost';
8
9 private $multi_currency;
10 private $wpdb;
11
12 const PRIORITY_SHIPPING = 10;
13
14 private $wcShippingCostInMcList = [];
15
16 public function __construct( WCML_Multi_Currency $multi_currency, wpdb $wpdb ) {
17
18 $this->multi_currency = $multi_currency;
19 $this->wpdb = $wpdb;
20 wp_cache_add_non_persistent_groups( self::CACHE_PERSISTENT_GROUP );
21 }
22
23 public function add_hooks() {
24
25 $rates = $this->wpdb->get_results( "SELECT * FROM {$this->wpdb->prefix}woocommerce_shipping_zone_methods WHERE method_id IN ('flat_rate', 'local_pickup', 'free_shipping')" );
26 foreach ( $rates as $method ) {
27 $option_name = self::getShippingOptionName( $method->method_id, $method->instance_id );
28 add_filter( 'option_' . $option_name, [ $this, 'convert_shipping_method_cost_settings' ] );
29 }
30
31 add_action( 'wcml_shipping_cost_in_mc', [ $this, 'action_shipping_cost_in_mc' ] );
32 add_filter( 'wcml_shipping_price_amount', [ $this, 'shipping_price_filter' ] );
33 add_filter( 'wcml_shipping_free_min_amount', [ $this, 'shipping_free_min_amount' ], 10, 2 );
34
35 add_filter( 'woocommerce_evaluate_shipping_cost_args', [ $this, 'woocommerce_evaluate_shipping_cost_args' ], 10, 3 );
36
37 add_filter( 'woocommerce_shipping_packages', [ $this, 'convert_shipping_taxes' ], self::PRIORITY_SHIPPING );
38
39 add_filter( 'woocommerce_shipping_packages', [
40 $this,
41 'applyShippingRoundingRules'
42 ], \WCML_Multi_Currency_Shipping::PRIORITY_SHIPPING + 1 );
43
44 add_filter( 'woocommerce_package_rates', [ $this, 'convert_shipping_costs_in_package_rates' ] );
45 }
46
47 public function action_shipping_cost_in_mc( $wcShippingMethod ) {
48 $this->wcShippingCostInMcList[] = $wcShippingMethod;
49 }
50
51 private function isManualPricingEnabledForThisRate( $rate ): bool {
52 return ManualCost::get( $rate->method_id )->isManualPricingEnabled( $rate );
53 }
54
55 public function convert_shipping_costs_in_package_rates( $rates ) {
56
57 $client_currency = $this->multi_currency->get_client_currency();
58
59 foreach ( $rates as $rate_id => $rate ) {
60
61 $cache_key = $rate_id;
62 $cached_converted_shipping_cost = wp_cache_get( $cache_key, self::CACHE_PERSISTENT_GROUP );
63
64 if ( $cached_converted_shipping_cost ) {
65 $rate->cost = $cached_converted_shipping_cost;
66 } elseif ( isset( $rate->cost ) && $rate->cost ) {
67 if ( ! $this->isManualPricingEnabledForThisRate( $rate ) ) {
68 $rate->cost = $this->multi_currency->prices->raw_price_filter( $rate->cost, $client_currency );
69 }
70 wp_cache_set( $cache_key, $rate->cost, self::CACHE_PERSISTENT_GROUP );
71 }
72 }
73
74 return $rates;
75 }
76
77 public function convert_shipping_method_cost_settings( $settings ) {
78
79 $has_free_shipping_coupon = false;
80 if ( null !== WC()->cart && $coupons = WC()->cart->get_coupons() ) {
81 foreach ( $coupons as $coupon ) {
82
83 if (
84 $coupon->is_valid() &&
85 (
86 method_exists( $coupon, 'get_free_shipping' ) ?
87 $coupon->get_free_shipping() :
88 $coupon->enable_free_shipping()
89 )
90 ) {
91 $has_free_shipping_coupon = true;
92 }
93 }
94 }
95
96 if ( ! empty( $settings['requires'] ) ) {
97
98 if (
99 $settings['requires'] === 'min_amount' ||
100 $settings['requires'] === 'either' ||
101 ( $settings['requires'] === 'both' && $has_free_shipping_coupon )
102 ) {
103 $settings['min_amount'] = apply_filters( 'wcml_shipping_free_min_amount', $settings['min_amount'], $settings );
104 }
105 }
106
107 return $settings;
108 }
109
110 public function woocommerce_evaluate_shipping_cost_args( $args, $sum, $WC_Shipping_Method ) {
111 if ( in_array( $WC_Shipping_Method, $this->wcShippingCostInMcList, true ) ) {
112 return $args;
113 }
114
115 $args['cost'] = $this->multi_currency->prices->unconvert_price_amount( $args['cost'] );
116
117 return $args;
118 }
119
120 public function convert_shipping_taxes( $packages ) {
121 if ( wc_tax_enabled() ) {
122 foreach ( $packages as $package_id => $package ) {
123 if ( isset( $package['rates'] ) ) {
124 foreach ( $package['rates'] as $rate_id => $rate ) {
125 if ( $rate->get_shipping_tax() > 0 ) {
126 $packages[ $package_id ]['rates'][ $rate_id ]->taxes =
127 WC_Tax::calc_shipping_tax( $packages[ $package_id ]['rates'][ $rate_id ]->cost, WC_Tax::get_shipping_tax_rates() );
128 }
129 }
130 }
131 }
132 }
133
134 return $packages;
135 }
136
137 public function applyShippingRoundingRules( $packages ) {
138 foreach ( $packages as $packageKey => $package ) {
139 foreach ( $package['rates'] as $rateKey => $rate ) {
140 $packages[ $packageKey ]['rates'][ $rateKey ] = $this->roundingShippingCostIncludingTax( $rate );
141 }
142 }
143
144 return $packages;
145 }
146
147 public function shipping_price_filter( $price ) {
148
149 $price = $this->multi_currency->prices->raw_price_filter( $price, $this->multi_currency->get_client_currency() );
150
151 return $price;
152
153 }
154
155 public function shipping_free_min_amount( $price, $settings ) {
156 if ( ManualCost::get( 'free_shipping' )->isManualPricingEnabled( $settings ) ) {
157 $price = ManualCost::get( 'free_shipping' )->getMinimalOrderAmountValue( $price, $settings, $this->multi_currency->get_client_currency() );
158 } else {
159 $price = $this->multi_currency->prices->raw_price_filter( $price, $this->multi_currency->get_client_currency() );
160 }
161 return $price;
162
163 }
164
165 public static function getShippingOptionName( $methodId, $instanceId ) {
166 return sprintf( 'woocommerce_%s_%d_settings', $methodId, $instanceId );
167 }
168
169 private function is_cart_prices_exclude_tax(): bool {
170 return ! wc_tax_enabled() || 'excl' === get_option( 'woocommerce_tax_display_cart' );
171 }
172
173 private function is_cart_prices_include_tax(): bool {
174 return wc_tax_enabled() || 'incl' === get_option( 'woocommerce_tax_display_cart' );
175 }
176
177 private function roundingShippingCostIncludingTax( $shippingRate ) {
178 $shippingCosts = floatval( $shippingRate->get_cost() );
179 $shippingTaxes = floatval( $shippingRate->get_shipping_tax() );
180
181 if ( 0.0 === $shippingCosts ) {
182 return $shippingRate;
183 }
184
185 if ( $this->is_cart_prices_exclude_tax() ) {
186 $priceWithRounding = $this->applyRoundingRules( $shippingCosts );
187
188 $shippingRate->set_cost( $priceWithRounding );
189 if ( $shippingTaxes > 0 ) {
190 $shippingRate->set_taxes( $this->calculateTaxForCost( $priceWithRounding ) );
191 }
192
193 return $shippingRate;
194 }
195
196 if ( $this->is_cart_prices_include_tax() ) {
197 $priceStandard = $shippingCosts + $shippingTaxes;
198 $priceWithRounding = $this->applyRoundingRules( $priceStandard );
199
200 if ( $priceWithRounding !== $priceStandard ) {
201 $tax = $shippingTaxes / $shippingCosts;
202 $newCost = $priceWithRounding / ( 1 + $tax );
203
204 $shippingRate->set_cost( $newCost );
205 if ( $shippingTaxes > 0 ) {
206 $shippingRate->set_taxes( $this->calculateTaxForCost( $newCost ) );
207 }
208
209 return $shippingRate;
210 }
211 }
212
213 return $shippingRate;
214 }
215
216 private function applyRoundingRules( $price ) {
217 return $this->multi_currency->prices->apply_rounding_rules( $price );
218 }
219
220 private function calculateTaxForCost( $price ): array {
221 if ( ! wc_tax_enabled() ) {
222 return [];
223 }
224
225 return \WC_Tax::calc_shipping_tax( $price, \WC_Tax::get_shipping_tax_rates() );
226 }
227 }
228