-
Notifications
You must be signed in to change notification settings - Fork 67
/
Compatibility.php
224 lines (195 loc) · 7.72 KB
/
Compatibility.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
<?php
/**
* Class Compatibility
*
* @package WooCommerce\Payments\Compatibility
*/
namespace WCPay\MultiCurrency;
use WC_Deposits;
use WC_Deposits_Product_Manager;
use WC_Order;
use WC_Order_Refund;
use WCPay\MultiCurrency\Compatibility\BaseCompatibility;
use WCPay\MultiCurrency\Compatibility\WooCommerceBookings;
use WCPay\MultiCurrency\Compatibility\WooCommerceFedEx;
use WCPay\MultiCurrency\Compatibility\WooCommerceNameYourPrice;
use WCPay\MultiCurrency\Compatibility\WooCommercePreOrders;
use WCPay\MultiCurrency\Compatibility\WooCommerceProductAddOns;
use WCPay\MultiCurrency\Compatibility\WooCommerceSubscriptions;
use WCPay\MultiCurrency\Compatibility\WooCommerceUPS;
use WCPay\MultiCurrency\Compatibility\WooCommerceDeposits;
use WCPay\MultiCurrency\Compatibility\WooCommercePointsAndRewards;
defined( 'ABSPATH' ) || exit;
/**
* Class that controls Multi-Currency Compatibility.
*/
class Compatibility extends BaseCompatibility {
/**
* Compatibility classes.
*
* @var array
*/
protected $compatibility_classes = [];
/**
* Init the class.
*
* @return void
*/
protected function init() {
add_action( 'init', [ $this, 'init_compatibility_classes' ], 11 );
if ( defined( 'DOING_CRON' ) ) {
add_filter( 'woocommerce_admin_sales_record_milestone_enabled', [ $this, 'attach_order_modifier' ] );
}
}
/**
* Initializes our compatibility classes.
*
* @return void
*/
public function init_compatibility_classes() {
if ( 1 < count( $this->multi_currency->get_enabled_currencies() ) ) {
$this->compatibility_classes[] = new WooCommerceBookings( $this->multi_currency, $this->utils, $this->multi_currency->get_frontend_currencies() );
$this->compatibility_classes[] = new WooCommerceFedEx( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommerceNameYourPrice( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommercePreOrders( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommerceProductAddOns( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommerceSubscriptions( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommerceUPS( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommerceDeposits( $this->multi_currency, $this->utils );
$this->compatibility_classes[] = new WooCommercePointsAndRewards( $this->multi_currency, $this->utils );
}
}
/**
* Returns the compatibility classes.
*
* @return array
*/
public function get_compatibility_classes(): array {
return $this->compatibility_classes;
}
/**
* Checks to see if the selected currency needs to be overridden.
*
* @return mixed Three letter currency code or false if not.
*/
public function override_selected_currency() {
return apply_filters( MultiCurrency::FILTER_PREFIX . 'override_selected_currency', false );
}
/**
* Deprecated method, please use should_disable_currency_switching.
*
* @return bool False if it shouldn't be hidden, true if it should.
*/
public function should_hide_widgets(): bool {
wc_deprecated_function( __FUNCTION__, '6.5.0', 'Compatibility::should_disable_currency_switching' );
return $this->should_disable_currency_switching();
}
/**
* Checks to see if currency switching should be disabled, such as the widgets and the automatic geolocation switching.
*
* @return bool False if no, true if yes.
*/
public function should_disable_currency_switching(): bool {
$return = false;
/**
* If the pay_for_order parameter is set, we disable currency switching.
*
* WooCommerce itself handles all the heavy lifting and verification on the Order Pay page, we just need to
* make sure the currency switchers are not displayed. This is due to once the order is created, the currency
* itself should remain static.
*/
if ( isset( $_GET['pay_for_order'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
$return = true;
}
// If someone has hooked into the deprecated filter, throw a notice and then apply the filtering.
if ( has_action( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets' ) ) {
wc_deprecated_hook( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', '6.5.0', MultiCurrency::FILTER_PREFIX . 'should_disable_currency_switching' );
$return = apply_filters( MultiCurrency::FILTER_PREFIX . 'should_hide_widgets', $return );
}
return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_disable_currency_switching', $return );
}
/**
* Checks to see if the coupon's amount should be converted.
*
* @param object $coupon Coupon object to test.
*
* @return bool True if it should be converted.
*/
public function should_convert_coupon_amount( $coupon = null ): bool {
if ( ! $coupon ) {
return true;
}
return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_convert_coupon_amount', true, $coupon );
}
/**
* Checks to see if the product's price should be converted.
*
* @param object $product Product object to test.
*
* @return bool True if it should be converted.
*/
public function should_convert_product_price( $product = null ): bool {
if ( ! $product ) {
return true;
}
return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_convert_product_price', true, $product );
}
/**
* Determines if the store currency should be returned or not.
*
* @return bool
*/
public function should_return_store_currency(): bool {
return apply_filters( MultiCurrency::FILTER_PREFIX . 'should_return_store_currency', false );
}
/**
* This filter is called when the best sales day logic is called. We use it to add another filter which will
* convert the order prices used in this inbox notification.
*
* @param bool $arg Whether or not the best sales day logic should execute. We will just return this as is to
* respect the existing behaviour.
*
* @return bool
*/
public function attach_order_modifier( $arg ) {
// Attach our filter to modify the order prices.
add_filter( 'woocommerce_order_query', [ $this, 'convert_order_prices' ] );
// This will be a bool value indication whether the best day logic should be run. Let's just return it as is.
return $arg;
}
/**
* When a request is made by the "Best Sales Day" Inbox notification, we want to hook into this and convert
* the order totals to the store default currency.
*
* @param WC_Order[]|WC_Order_Refund[] $results The results returned by the orders query.
*
* @return array|object of WC_Order objects
*/
public function convert_order_prices( $results ) {
$backtrace_calls = [
'Automattic\WooCommerce\Admin\Notes\NewSalesRecord::sum_sales_for_date',
'Automattic\WooCommerce\Admin\Notes\NewSalesRecord::possibly_add_note',
];
// If the results are not an array, or if the call we're expecting isn't in the backtrace, then just do nothing and return the results.
if ( ! is_array( $results ) || ! $this->utils->is_call_in_backtrace( $backtrace_calls ) ) {
return $results;
}
$default_currency = $this->multi_currency->get_default_currency();
if ( ! $default_currency ) {
return $results;
}
foreach ( $results as $order ) {
if ( ! $order ||
$order->get_currency() === $default_currency->get_code() ||
! $order->get_meta( '_wcpay_multi_currency_order_exchange_rate', true ) ||
$order->get_meta( '_wcpay_multi_currency_order_default_currency', true ) !== $default_currency->get_code()
) {
continue;
}
$exchange_rate = $order->get_meta( '_wcpay_multi_currency_order_exchange_rate', true );
$order->set_total( number_format( $order->get_total() * ( 1 / $exchange_rate ), wc_get_price_decimals() ) );
}
remove_filter( 'woocommerce_order_query', [ $this, 'convert_order_prices' ] );
return $results;
}
}