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 / class-wcml-cart.php
woocommerce-multilingual / inc Last commit date
admin-menus 2 weeks ago currencies 2 weeks ago template-classes 2 weeks ago translation-editor 2 weeks ago class-wcml-ajax-setup.php 2 weeks ago class-wcml-attributes.php 2 weeks ago class-wcml-capabilities.php 2 weeks ago class-wcml-cart-removed-items-widget.php 1 year ago class-wcml-cart-switch-lang-functions.php 2 weeks ago class-wcml-cart-sync-warnings.php 2 weeks ago class-wcml-cart.php 2 weeks ago class-wcml-comments.php 2 weeks ago class-wcml-compatibility.php 2 weeks ago class-wcml-coupons.php 2 weeks ago class-wcml-dependencies.php 2 weeks ago class-wcml-emails.php 2 weeks ago class-wcml-endpoints.php 2 weeks ago class-wcml-install.php 2 weeks ago class-wcml-languages-upgrader.php 2 weeks ago class-wcml-locale.php 2 weeks ago class-wcml-orders.php 2 weeks ago class-wcml-products-screen-options.php 2 weeks ago class-wcml-products.php 2 weeks ago class-wcml-reports.php 2 weeks ago class-wcml-requests.php 2 weeks ago class-wcml-resources.php 2 weeks ago class-wcml-store-pages.php 2 weeks ago class-wcml-terms.php 2 weeks ago class-wcml-tp-support.php 2 weeks ago class-wcml-troubleshooting.php 2 weeks ago class-wcml-upgrade.php 2 weeks ago class-wcml-url-translation.php 2 weeks ago class-wcml-wc-gateways.php 2 weeks ago class-wcml-wc-shipping.php 2 weeks ago class-wcml-wc-strings.php 2 weeks ago class-wcml-widgets.php 2 weeks ago constants.php 2 weeks ago functions-pure.php 2 weeks ago functions.php 2 weeks ago installer-loader.php 2 weeks ago missing-php-functions.php 2 weeks ago wcml-core-functions.php 2 weeks ago wcml-switch-lang-request.php 2 weeks ago
class-wcml-cart.php
663 lines
1 <?php
2
3 use function WCML\functions\isStandAlone;
4
5 class WCML_Cart {
6 private $woocommerce_wpml;
7 private $sitepress;
8 private $woocommerce;
9
10 public function __construct( woocommerce_wpml $woocommerce_wpml, \WPML\Core\ISitePress $sitepress, WooCommerce $woocommerce ) {
11 $this->woocommerce_wpml = $woocommerce_wpml;
12 $this->sitepress = $sitepress;
13 $this->woocommerce = $woocommerce;
14 }
15
16 public function add_hooks() {
17
18 if ( $this->is_clean_cart_enabled() ) {
19
20 $this->enqueue_dialog_ui();
21
22 add_action( 'wcml_removed_cart_items', [ $this, 'wcml_removed_cart_items_widget' ] );
23 add_action( 'wp_ajax_wcml_cart_clear_removed_items', [ $this, 'wcml_cart_clear_removed_items' ] );
24 add_action(
25 'wp_ajax_nopriv_wcml_cart_clear_removed_items',
26 [
27 $this,
28 'wcml_cart_clear_removed_items',
29 ]
30 );
31
32 if ( $this->is_clean_cart_enabled_for_currency_switch() ) {
33 add_filter( 'wcml_switch_currency_exception', [ $this, 'cart_switching_currency' ], 10, 4 );
34 add_action(
35 'wcml_before_switch_currency',
36 [
37 $this,
38 'switching_currency_empty_cart_if_needed',
39 ],
40 10,
41 2
42 );
43 }
44 } else {
45 add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', [ $this, 'wcml_refresh_fragments' ], 0 );
46 add_action( 'wp_ajax_woocommerce_add_to_cart', [ $this, 'wcml_refresh_fragments' ], 0 );
47 add_action(
48 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments',
49 [
50 $this,
51 'wcml_refresh_fragments',
52 ],
53 0
54 );
55 add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', [ $this, 'wcml_refresh_fragments' ], 0 );
56
57 add_action( 'woocommerce_before_checkout_process', [ $this, 'wcml_refresh_cart_total' ] );
58
59 if ( ! isStandAlone() ) {
60 add_action( 'woocommerce_before_calculate_totals', [ $this, 'woocommerce_calculate_totals' ], 100 );
61 add_filter( 'woocommerce_cart_item_data_to_validate', [ $this, 'validate_cart_item_data' ], 10, 2 );
62 add_filter( 'woocommerce_cart_item_product', [ $this, 'adjust_cart_item_product_name' ] );
63 add_filter( 'woocommerce_cart_item_permalink', [ $this, 'cart_item_permalink' ], 10, 2 );
64 add_filter( 'woocommerce_paypal_args', [ $this, 'filter_paypal_args' ] );
65 add_filter(
66 'woocommerce_add_to_cart_sold_individually_found_in_cart',
67 [
68 $this,
69 'add_to_cart_sold_individually_exception',
70 ],
71 10,
72 4
73 );
74 add_filter( 'woocommerce_cart_hash_key', [ $this, 'add_language_to_cart_hash_key' ] );
75 add_filter('woocommerce_cart_crosssell_ids', [ $this, 'convert_crosssell_ids' ] );
76 $this->localize_flat_rates_shipping_classes();
77 }
78 }
79 }
80
81 public function is_clean_cart_enabled() {
82
83 $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
84 $wpml_cookies_enabled = $this->sitepress->get_setting( $this->sitepress->get_wp_api()->constant( 'WPML_Cookie_Setting::COOKIE_SETTING_FIELD' ) );
85
86 if (
87 $wpml_cookies_enabled &&
88 (
89 (
90 $this->woocommerce_wpml->settings['enable_multi_currency'] === $this->sitepress->get_wp_api()->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' ) &&
91 $cart_sync_settings['currency_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' )
92 ) ||
93 $cart_sync_settings['lang_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' )
94 )
95 ) {
96 return true;
97 }
98
99 return false;
100 }
101
102 private function is_clean_cart_enabled_for_currency_switch() {
103
104 $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
105 $wpml_cookies_enabled = $this->sitepress->get_setting( $this->sitepress->get_wp_api()->constant( 'WPML_Cookie_Setting::COOKIE_SETTING_FIELD' ) );
106
107 if (
108 $wpml_cookies_enabled &&
109 $cart_sync_settings['currency_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' )
110 ) {
111 return true;
112 }
113
114 return false;
115 }
116
117 public function enqueue_dialog_ui() {
118
119 wp_enqueue_script( 'jquery-ui-dialog' );
120 wp_enqueue_style( 'wp-jquery-ui-dialog' );
121
122 }
123
124 public function wcml_removed_cart_items_widget( $args = [] ) {
125 if ( $this->woocommerce->session instanceof WC_Session ) {
126 $removed_cart_items = new WCML_Removed_Cart_Items_UI( $this->woocommerce_wpml, $this->sitepress, $this->woocommerce );
127 $preview = $removed_cart_items->get_view();
128
129 if ( ! isset( $args['echo'] ) || $args['echo'] ) {
130 echo $preview;
131 } else {
132 return $preview;
133 }
134 }
135
136 }
137
138 public function switching_currency_empty_cart_if_needed( $currency, $force_switch ) {
139 if ( $force_switch && $this->woocommerce_wpml->settings['cart_sync']['currency_switch'] == $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) ) {
140 $this->empty_cart_if_needed( 'currency_switch' );
141 $this->woocommerce->session->set( 'wcml_switched_type', 'currency' );
142 }
143 }
144
145 public function empty_cart_if_needed( $switching_type ) {
146
147 if ( $this->woocommerce_wpml->settings['cart_sync'][ $switching_type ] == $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) ) {
148 $removed_products = $this->woocommerce->session->get( 'wcml_removed_items' ) ? maybe_unserialize( $this->woocommerce->session->get( 'wcml_removed_items' ) ) : [];
149
150 foreach ( WC()->cart->get_cart_for_session() as $item_key => $cart ) {
151 if ( ! in_array( $cart['product_id'], $removed_products ) ) {
152 $removed_products[] = $cart['product_id'];
153 }
154 WC()->cart->remove_cart_item( $item_key );
155 }
156 if ( $this->woocommerce->session instanceof WC_Session ) {
157 $this->woocommerce->session->set( 'wcml_removed_items', serialize( $removed_products ) );
158 }
159 }
160 }
161
162 public function wcml_cart_clear_removed_items() {
163
164 $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
165 if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wcml_clear_removed_items' ) ) {
166 die( 'Invalid nonce' );
167 }
168
169 $this->woocommerce->session->__unset( 'wcml_removed_items' );
170 $this->woocommerce->session->__unset( 'wcml_switched_type' );
171 }
172
173 public function cart_switching_currency( $exc, $current_currency, $new_currency, $return = false ) {
174
175 $cart_for_session = false;
176 if ( WC()->cart instanceof WC_Cart ) {
177 $cart_for_session = array_filter( WC()->cart->get_cart_contents() );
178 }
179
180 if ( $this->woocommerce_wpml->settings['cart_sync']['currency_switch'] == WCML_CART_SYNC || empty( $cart_for_session ) ) {
181 return $exc;
182 }
183
184 $dialog_title = __( 'Switching currency?', 'woocommerce-multilingual' );
185 $confirmation_message = __( 'Your cart is not empty! After you switched the currency, all items from the cart will be removed and you have to add them again.', 'woocommerce-multilingual' );
186 /* translators: %s is a currency */
187 $stay_in = sprintf( __( 'Keep using %s', 'woocommerce-multilingual' ), $current_currency );
188 $switch_to = __( 'Proceed', 'woocommerce-multilingual' );
189
190 ob_start();
191 $this->cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $new_currency, $current_currency );
192 $html = ob_get_contents();
193 ob_end_clean();
194
195 if ( $return ) {
196 return [ 'prevent_switching' => $html ];
197 }
198
199 wp_send_json_success( [ 'prevent_switching' => $html ] );
200 }
201
202 public function cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $switch_to_value, $stay_in_value = false, $language_switch = false ) {
203 if ( apply_filters( 'wcml_hide_cart_alert_dialog', false ) ) {
204 $switching_type = $language_switch ? 'lang_switch' : 'currency_switch';
205 $this->empty_cart_if_needed( $switching_type );
206 return false;
207 }?>
208 <div id="wcml-cart-dialog-wrapper">
209 <div class="wcml-cart-dialog-confirm">
210 <p class="wcml-cart-dialog-title"><?php echo esc_attr( $dialog_title ); ?></p>
211 <p class="wcml-cart-dialog-content"><?php echo esc_html( $confirmation_message ); ?></p>
212 <div class="wcml-cart-dialog-buttons">
213 <button id="wcml-cart-dialog-switch" class="button"><?php echo esc_html( $switch_to ); ?></button>
214 <button id="wcml-cart-dialog-stay" class="button"><?php echo esc_html( $stay_in ); ?></button>
215 </div>
216 </div>
217 <style>
218 /* The Modal (background) */
219 #wcml-cart-dialog-wrapper {
220 position: fixed;
221 z-index: 1;
222 left: 0;
223 top: 0;
224 width: 100%;
225 height: 100%;
226 overflow: auto;
227 background-color: rgb(0,0,0);
228 background-color: rgba(0,0,0,0.7);
229 z-index: 10000;
230 }
231
232 /* Modal Content */
233 .wcml-cart-dialog-confirm {
234 background-color: #fefefe;
235 margin: 25% auto;
236 padding: 20px;
237 border: 1px solid #888;
238 width: 50%;
239 max-width: 560px;
240 }
241
242 .wcml-cart-dialog-title {
243 border-bottom: 1px solid #dcdcde;
244 font-size: 18px;
245 font-weight: 600;
246 padding: 0 0 10px;
247 }
248
249 .wcml-cart-dialog-buttons {
250 text-align: right;
251 }
252
253 .wcml-cart-dialog-buttons button {
254 color: #555;
255 font-size: 16px;
256 padding: 4px 8px;
257 margin: 0 3px;
258 }
259
260 .wcml-cart-dialog-buttons button:hover,
261 .wcml-cart-dialog-buttons button:focus {
262 color: #000;
263 cursor: pointer;
264 }
265 </style>
266
267 <script type="text/javascript">
268 (function(){
269 const modal = document.getElementById('wcml-cart-dialog-wrapper');
270
271 const btnStay = document.getElementById('wcml-cart-dialog-stay');
272 const btnSwitch = document.getElementById('wcml-cart-dialog-switch');
273
274 const removeAjaxSpinners = function() {
275 document.querySelectorAll('.wcml-spinner').forEach(function(spinner) {
276 spinner.remove();
277 });
278 }
279
280 const removeModal = function() {
281 modal.remove();
282
283 const scriptInsertedByAjax = document.getElementById('wcml-cart-dialog-script');
284
285 if (scriptInsertedByAjax) {
286 scriptInsertedByAjax.remove();
287 }
288 }
289
290 const restoreCurrencyInSwitchers = function() {
291 document.querySelectorAll('.wcml_currency_switcher').forEach(function(switcher) {
292 switcher.disabled = false;
293 switcher.value = '<?php echo esc_js( $stay_in_value ); ?>';
294 });
295 }
296
297 btnSwitch.onclick = function() {
298 removeModal();
299 <?php if ( $language_switch ) : ?>
300 window.location = '<?php echo esc_url( $switch_to_value, null, 'redirect' ); ?>';
301 <?php else : ?>
302 wcml_load_currency("<?php echo esc_js( $switch_to_value ); ?>", true);
303 removeAjaxSpinners();
304 <?php endif; ?>
305 }
306
307 btnStay.onclick = function() {
308 removeModal();
309 <?php if ( $language_switch ) : ?>
310 window.location = '<?php echo esc_url( $stay_in_value, null, 'redirect' ); ?>';
311 <?php else : ?>
312 removeAjaxSpinners();
313 restoreCurrencyInSwitchers();
314 document.addEventListener('click', wcml_switch_currency_handler);
315 <?php endif; ?>
316 }
317 })();
318 </script>
319 </div>
320 <?php
321 }
322
323 public function wcml_refresh_fragments() {
324 WC()->cart->calculate_totals();
325 }
326
327 public function woocommerce_calculate_totals( $cart, $currency = false ) {
328
329 $current_language = $this->sitepress->get_current_language();
330 $new_cart_data = [];
331
332 foreach ( $cart->cart_contents as $key => $cart_item ) {
333 $tr_product_id = apply_filters( 'wpml_object_id', $cart_item['product_id'], 'product', false, $current_language );
334 $tr_variation_id = null;
335 if ( isset( $cart_item['variation'] ) && is_array( $cart_item['variation'] ) ) {
336 $tr_variation_id = apply_filters( 'wpml_object_id', $cart_item['variation_id'], 'product_variation', false, $current_language );
337 foreach ( $cart_item['variation'] as $attr_key => $attribute ) {
338 $cart->cart_contents[ $key ]['variation'][ $attr_key ] = $this->get_cart_attribute_translation(
339 $attr_key,
340 $attribute,
341 $tr_variation_id,
342 $current_language,
343 $cart_item['product_id'],
344 $tr_product_id
345 );
346 }
347 }
348
349 if ( false !== $currency ) {
350 $cart->cart_contents[ $key ]['data']->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
351 }
352 $display_as_translated = $this->woocommerce_wpml->products->is_product_display_as_translated_post_type();
353 if ( $cart_item['product_id'] == $tr_product_id || ( $display_as_translated && ! $tr_product_id ) ) {
354 $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[ $key ], $key, $current_language );
355 $new_cart_data[ $key ]['data_hash'] = $this->get_data_cart_hash( $cart_item );
356 continue;
357 }
358
359 if ( isset( $cart->cart_contents[ $key ]['variation_id'] ) && $cart->cart_contents[ $key ]['variation_id'] ) {
360 if ( ! is_null( $tr_variation_id ) ) {
361 $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
362 $cart->cart_contents[ $key ]['variation_id'] = intval( $tr_variation_id );
363 $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_variation_id ) );
364 $cart->cart_contents[ $key ]['data']->set_parent_id( intval( $tr_product_id ) );
365 $cart->cart_contents[ $key ]['data']->set_name( get_the_title( $tr_variation_id ) );
366
367 $parent_data = $cart->cart_contents[ $key ]['data']->get_parent_data();
368 $parent_data['title'] = get_the_title( $tr_product_id );
369 $cart->cart_contents[ $key ]['data']->set_parent_data( $parent_data );
370 }
371 } else {
372 if ( ! is_null( $tr_product_id ) ) {
373 $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
374 $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
375 $cart->cart_contents[ $key ]['data']->set_name( get_the_title( $tr_product_id ) );
376 }
377 }
378
379 if ( ! is_null( $tr_product_id ) ) {
380
381 $new_key = $this->wcml_generate_cart_key( $cart->cart_contents, $key );
382 $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
383 $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
384 $new_cart_data[ $new_key ]['key'] = $new_key;
385 $new_cart_data[ $new_key ]['data_hash'] = $this->get_data_cart_hash( $new_cart_data[ $new_key ] );
386
387 $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
388 }
389 }
390
391 $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
392 $this->woocommerce->session->cart = $cart->cart_contents;
393 }
394
395 public function get_data_cart_hash( $cart_item ) {
396
397 $data_hash = '';
398
399 if ( function_exists( 'wc_get_cart_item_data_hash' ) ) {
400 $hash_product_object = wc_get_product( $cart_item['variation_id'] ?: $cart_item['product_id'] );
401 if ( $hash_product_object ) {
402 $data_hash = wc_get_cart_item_data_hash( $hash_product_object );
403 }
404 }
405
406 return $data_hash;
407 }
408
409 public function validate_cart_item_data( array $item_data, $product ) {
410
411 if ( $item_data['attributes'] ) {
412
413 $product_id = $product->get_parent_id();
414 $product_language = $this->sitepress->get_language_for_element( $product_id, 'post_' . $item_data['type'] );
415 $tr_product_id = apply_filters( 'wpml_object_id', $product_id, 'product', false, $product_language );
416
417 foreach ( $item_data['attributes'] as $key => $name ) {
418 $item_data['attributes'][ $key ] = $this->get_cart_attribute_translation( $key, $name, $product->get_id(), $product_language, $product_id, $tr_product_id );
419 }
420 }
421
422 return $item_data;
423 }
424
425 public function wcml_check_on_duplicate_products_in_cart( $cart_contents ) {
426
427 $exists_products = [];
428 remove_action( 'woocommerce_before_calculate_totals', [ $this, 'woocommerce_calculate_totals' ], 100 );
429
430 foreach ( $cart_contents as $key => $cart_content ) {
431 $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
432 if ( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ) {
433 continue;
434 }
435
436 $quantity = $cart_content['quantity'];
437
438 $search_key = $this->wcml_generate_cart_key( $cart_contents, $key );
439 if ( array_key_exists( $search_key, $exists_products ) ) {
440 unset( $cart_contents[ $key ] );
441 $cart_contents[ $exists_products[ $search_key ] ]['quantity'] = $cart_contents[ $exists_products[ $search_key ] ]['quantity'] + $quantity;
442 $this->woocommerce->cart->calculate_totals();
443 } else {
444 $exists_products[ $search_key ] = $key;
445 }
446 }
447
448 add_action( 'woocommerce_before_calculate_totals', [ $this, 'woocommerce_calculate_totals' ], 100 );
449
450 return $cart_contents;
451 }
452
453 public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ) {
454
455 $attr_translation = $attribute;
456
457 if ( ! empty( $attribute ) ) {
458
459 $taxonomy = $this->remove_attribute_prefix( $attr_key );
460
461 if ( taxonomy_exists( $taxonomy ) ) {
462 if ( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
463 $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
464 $trnsl_term_id = apply_filters( 'wpml_object_id', $term_id, $taxonomy, true, $current_language );
465 $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
466 $attr_translation = $term->slug;
467 }
468 } elseif ( $variation_id ) {
469 $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
470
471 if ( $trnsl_attr ) {
472 $attr_translation = $trnsl_attr;
473 } else {
474 $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
475 }
476 }
477 }
478
479 return $attr_translation;
480 }
481
482 protected function remove_attribute_prefix( $attr_key ) {
483 $taxonomy = $attr_key;
484
485 $attribute_prefix = 'attribute_';
486 if ( strpos( $attr_key, $attribute_prefix ) === 0 ) {
487 $taxonomy = substr( $attr_key, strlen( $attribute_prefix ) );
488 }
489
490 return $taxonomy;
491 }
492
493 public function wcml_generate_cart_key( $cart_contents, $key ) {
494 $cart_item_data = $this->get_cart_item_data_from_cart( $cart_contents[ $key ] );
495
496 return $this->woocommerce->cart->generate_cart_id(
497 $cart_contents[ $key ]['product_id'],
498 $cart_contents[ $key ]['variation_id'],
499 $cart_contents[ $key ]['variation'],
500 $cart_item_data
501 );
502 }
503
504 public function get_cart_item_data_from_cart( $cart_contents ) {
505 unset( $cart_contents['product_id'] );
506 unset( $cart_contents['variation_id'] );
507 unset( $cart_contents['variation'] );
508 unset( $cart_contents['quantity'] );
509 unset( $cart_contents['line_total'] );
510 unset( $cart_contents['line_subtotal'] );
511 unset( $cart_contents['line_tax'] );
512 unset( $cart_contents['line_subtotal_tax'] );
513 unset( $cart_contents['line_tax_data'] );
514 unset( $cart_contents['data'] );
515 unset( $cart_contents['key'] );
516
517 return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
518 }
519
520 public function wcml_refresh_cart_total() {
521 WC()->cart->calculate_totals();
522 }
523
524
525 public function localize_flat_rates_shipping_classes() {
526
527 if ( wp_doing_ajax() && isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_update_order_review' ) {
528 $shipping_methods = $this->woocommerce->shipping()->get_shipping_methods();
529 foreach ( $shipping_methods as $method ) {
530 if ( isset( $method->flat_rate_option ) ) {
531 add_filter( 'option_' . $method->flat_rate_option, [ $this, 'translate_shipping_class' ] );
532 }
533 }
534 }
535 }
536
537 public function translate_shipping_class( $rates ) {
538
539 if ( is_array( $rates ) ) {
540 foreach ( $rates as $shipping_class => $value ) {
541 $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( 'product_shipping_class', $shipping_class );
542
543 if ( $term_id && ! is_wp_error( $term_id ) ) {
544 $translated_term_id = apply_filters( 'wpml_object_id', $term_id, 'product_shipping_class', true );
545 if ( $translated_term_id != $term_id ) {
546 $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
547 unset( $rates[ $shipping_class ] );
548 $rates[ $term->slug ] = $value;
549
550 }
551 }
552 }
553 }
554
555 return $rates;
556 }
557
558 public function filter_paypal_args( $args ) {
559 $args['lc'] = $this->sitepress->get_current_language();
560
561 $wpml_settings = $this->sitepress->get_settings();
562 if ( $wpml_settings['language_negotiation_type'] == 3 ) {
563 $args['notify_url'] = str_replace( '%2F&', '&', $args['notify_url'] );
564 }
565
566 return $args;
567 }
568
569 public function add_to_cart_sold_individually_exception( $found_in_cart, $product_id, $variation_id, $cart_item_data ) {
570
571 $post_id = $product_id;
572 if ( $variation_id ) {
573 $post_id = $variation_id;
574 }
575
576 foreach ( WC()->cart->cart_contents as $cart_item ) {
577 if ( $this->sold_individually_product( $cart_item, $cart_item_data, $post_id ) ) {
578 $found_in_cart = true;
579 break;
580 }
581 }
582
583 return $found_in_cart;
584 }
585
586 public function sold_individually_product( $cart_item, $cart_item_data, $post_id ) {
587
588 $current_product_trid = $this->sitepress->get_element_trid( $post_id, 'post_' . get_post_type( $post_id ) );
589
590 if ( ! empty( $cart_item['variation_id'] ) ) {
591 $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['variation_id'], 'post_product_variation' );
592 } else {
593 $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['product_id'], 'post_product' );
594 }
595
596 if ( apply_filters( 'wcml_add_to_cart_sold_individually', true, $cart_item_data, $post_id, $cart_item['quantity'] ) &&
597 $current_product_trid == $cart_element_trid &&
598 $cart_item['quantity'] > 0
599 ) {
600 return true;
601 } else {
602 return false;
603 }
604 }
605
606 public function cart_item_permalink( $permalink, $cart_item ) {
607
608 if ( ! $this->sitepress->get_setting( 'auto_adjust_ids' ) ) {
609 $permalink = get_permalink( $cart_item['product_id'] );
610 }
611
612 return $permalink;
613 }
614
615 public function convert_cart_total_to_currency( $currency ) {
616 $total = WC()->cart->get_total( 'raw' );
617 $total_default = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $total );
618 $total_currency = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $total_default, $currency );
619
620 return $total_currency;
621 }
622
623 public function format_converted_cart_total_in_currency( $currency ) {
624 return $this->woocommerce_wpml->multi_currency->prices->format_price_in_currency( $this->convert_cart_total_to_currency( $currency ), $currency );
625 }
626
627 public function convert_cart_shipping_to_currency( $currency ) {
628 $shipping_amount_in_default_currency = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( WC()->cart->get_shipping_total() );
629
630 return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $shipping_amount_in_default_currency, $currency );
631 }
632
633 public function adjust_cart_item_product_name( $product ) {
634
635 $product_id = $product->get_id();
636
637 $current_product_id = wpml_object_id_filter( $product_id, get_post_type( $product_id ) );
638
639 if ( $current_product_id ) {
640 $product->set_name( wc_get_product( $current_product_id )->get_name() );
641 }
642
643 return $product;
644 }
645
646 public function add_language_to_cart_hash_key( $cart_hash_key ) {
647 return $cart_hash_key . '-' . $this->sitepress->get_current_language();
648 }
649
650 public function convert_crosssell_ids( $productIds ) {
651 $returnOriginal = $this->sitepress->is_display_as_translated_post_type( 'product' );
652
653 $convertId = function( $id ) use ( $returnOriginal ) {
654 return $this->sitepress->get_object_id( $id, 'product', $returnOriginal );
655 };
656
657 return wpml_collect( $productIds )
658 ->map( $convertId )
659 ->filter()
660 ->toArray();
661 }
662 }
663