WooCommerce Multilingual – run WooCommerce with WPML - Version 4.2.8

Version Description

  • Visual Bakery Composer compatibility issue - some strings displays in default language instead on user admin language
  • Variable product with local attributes displays all variations values set to "any" with "use translation if available or fallback to default language" enabled for products
  • Product Customizer produce error messages
  • WooCommerce Subscriptions -> 'From....' price is not converted to current currency
  • Global add-on filtered by category - does not work in second language
  • [Fatal Error] WooCommerce Subscriptions -> Resubscribe with no multi-currency enabled
  • Variation downloadable files not synchronized with Products Download Files setting in the native editor
  • Incorrect category count in second languages
  • WooCommerce Subscription incorrect recurring totals in secondary currency
  • Manually set price (2nd currency) -> adding product to manually created order results in price of the first currency being used
Download this release

Release Info

Developer sergey.r
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 4.2.8
Comparing to
See all releases

Code changes from version 4.2.7.1 to 4.2.8

changelog/4.2.7.1.md CHANGED
@@ -1,2 +1,2 @@
1
  # Fixes
2
- * [wcml-2266] Fatal error while updating to 4.2.7 with Woocommerce Bundles
1
  # Fixes
2
+ * [wcml-2266] Fixed fatal error while updating to 4.2.7 with Woocommerce Bundles
changelog/4.2.8.md ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fixes
2
+ * [wcml-2281] Visual Bakery Composer compatibility issue - some strings displays in default language instead on user admin language
3
+ * [wcml-2278] Variable product with local attributes displays all variations values set to "any" with "use translation if available or fallback to default language" enabled for products
4
+ * [wcml-2277] Product Customizer produce error messages
5
+ * [wcml-2276] WooCommerce Subscriptions -> 'From....' price is not converted to current currency
6
+ * [wcml-2275] Global add-on filtered by category - does not work in second language
7
+ * [wcml-2272] [Fatal Error] WooCommerce Subscriptions -> Resubscribe with no multi-currency enabled
8
+ * [wcml-2270] Variation downloadable files not synchronized with Products Download Files setting in the native editor
9
+ * [wcml-2265] Incorrect category count in second languages
10
+ * [wcml-2262] WooCommerce Subscription incorrect recurring totals in secondary currency
11
+ * [wcml-2261] Manually set price (2nd currency) -> adding product to manually created order results in price of the first currency being used
classes/order-property-filter/class-wcml-payment-method-filter.php CHANGED
@@ -12,7 +12,7 @@ class WCML_Payment_Method_Filter {
12
  }
13
 
14
  public function payment_method_string( $title, $object_id, $meta_key ) {
15
- if ( '_payment_method_title' === $meta_key && '' !== $title && $object_id && 'shop_order' === $this->get_post_type( $object_id ) ) {
16
  $payment_gateway = $this->get_payment_gateway( $object_id );
17
 
18
  if( isset( $_POST['payment_method'] ) && $payment_gateway->id !== $_POST['payment_method'] && WC()->payment_gateways() ){
12
  }
13
 
14
  public function payment_method_string( $title, $object_id, $meta_key ) {
15
+ if ( '_payment_method_title' === $meta_key && !empty( $title ) && $object_id && 'shop_order' === $this->get_post_type( $object_id ) ) {
16
  $payment_gateway = $this->get_payment_gateway( $object_id );
17
 
18
  if( isset( $_POST['payment_method'] ) && $payment_gateway->id !== $_POST['payment_method'] && WC()->payment_gateways() ){
compatibility/class-wcml-product-addons.php CHANGED
@@ -62,6 +62,11 @@ class WCML_Product_Addons {
62
  'filter_booking_addon_product_in_cart_contents'
63
  ), 20 );
64
 
 
 
 
 
 
65
  }
66
 
67
  /**
@@ -305,4 +310,24 @@ class WCML_Product_Addons {
305
  return $cart_item;
306
  }
307
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  }
62
  'filter_booking_addon_product_in_cart_contents'
63
  ), 20 );
64
 
65
+ add_filter( 'get_product_addons_global_query_args', array(
66
+ $this,
67
+ 'set_global_ids_in_query_args'
68
+ ) );
69
+
70
  }
71
 
72
  /**
310
  return $cart_item;
311
  }
312
 
313
+ public function set_global_ids_in_query_args( $args ) {
314
+
315
+ remove_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
316
+ remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
317
+ remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
318
+
319
+ $matched_addons_ids = wp_list_pluck( get_posts( $args ), 'ID' );
320
+
321
+ if ( $matched_addons_ids ) {
322
+ $args['include'] = $matched_addons_ids;
323
+ unset( $args['tax_query'] );
324
+ }
325
+
326
+ add_filter( 'get_terms_args', array( $this->sitepress, 'get_terms_args_filter' ), 10, 2 );
327
+ add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
328
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
329
+
330
+ return $args;
331
+ }
332
+
333
  }
compatibility/class-wcml-wc-subscriptions.php CHANGED
@@ -38,7 +38,6 @@ class WCML_WC_Subscriptions{
38
  'woocommerce_subscription_price_from'
39
  ), 10, 2 );
40
 
41
- add_filter( 'wcml_calculate_totals_exception', '__return_false' );
42
  }
43
 
44
  function init(){
@@ -256,7 +255,7 @@ class WCML_WC_Subscriptions{
256
 
257
  function woocommerce_subscription_price_from( $price, $product ){
258
 
259
- if( 'variable-subscription' === $product->get_type() ){
260
 
261
  $variation_id = $product->get_meta( '_min_price_variation_id', true );
262
 
@@ -279,7 +278,7 @@ class WCML_WC_Subscriptions{
279
  */
280
  function maybe_force_client_currency_for_resubscribe_subscription( ){
281
 
282
- if ( isset( $_GET['resubscribe'] ) || false !== ( $resubscribe_cart_item = wcs_cart_contains_resubscribe() ) ) {
283
  $subscription_id = ( isset( $_GET['resubscribe'] ) ) ? (int) $_GET['resubscribe'] : $resubscribe_cart_item['subscription_resubscribe']['subscription_id'];
284
 
285
  $subscription_currency = get_post_meta( $subscription_id, '_order_currency', true );
38
  'woocommerce_subscription_price_from'
39
  ), 10, 2 );
40
 
 
41
  }
42
 
43
  function init(){
255
 
256
  function woocommerce_subscription_price_from( $price, $product ){
257
 
258
+ if ( in_array( $product->get_type(), array( 'variable-subscription', 'subscription_variation' ) ) ) {
259
 
260
  $variation_id = $product->get_meta( '_min_price_variation_id', true );
261
 
278
  */
279
  function maybe_force_client_currency_for_resubscribe_subscription( ){
280
 
281
+ if ( wcml_is_multi_currency_on() && ( isset( $_GET['resubscribe'] ) || false !== ( $resubscribe_cart_item = wcs_cart_contains_resubscribe() ) ) ) {
282
  $subscription_id = ( isset( $_GET['resubscribe'] ) ) ? (int) $_GET['resubscribe'] : $resubscribe_cart_item['subscription_resubscribe']['subscription_id'];
283
 
284
  $subscription_currency = get_post_meta( $subscription_id, '_order_currency', true );
compatibility/class-wcml-wpb-vc.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * WPBakery Page Builder ( formerly Visual Composer ) Compatibility class
4
+ */
5
+
6
+ class WCML_Wpb_Vc {
7
+
8
+ function add_hooks() {
9
+
10
+ add_filter( 'wcml_is_localize_woocommerce_on_ajax', array( $this, 'is_localize_woocommerce_on_ajax' ), 10, 2 );
11
+ }
12
+
13
+ function is_localize_woocommerce_on_ajax( $localize, $action ) {
14
+
15
+ if ( 'vc_edit_form' === $action ) {
16
+ $localize = false;
17
+ }
18
+
19
+ return $localize;
20
+ }
21
+
22
+ }
inc/class-wcml-ajax-setup.php CHANGED
@@ -8,36 +8,43 @@ class WCML_Ajax_Setup{
8
  */
9
  private $sitepress;
10
 
11
- public function __construct( $sitepres ){
12
 
13
- $this->sitepress =& $sitepres;
 
 
 
14
 
15
- add_action( 'init', array( $this, 'init' ) );
16
- add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
17
 
18
- //@deprecated 3.9
19
- add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
20
 
21
  add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
22
  }
23
 
24
- public function init(){
25
- if (wpml_is_ajax()){
26
- do_action('wcml_localize_woocommerce_on_ajax');
27
- }
28
-
29
- add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
30
-
31
- add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
32
- add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
33
- add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
34
- add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
35
-
36
- add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
37
- add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
38
- add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
39
-
40
- }
 
 
 
 
41
 
42
  function filter_woocommerce_order_review(){
43
  global $woocommerce;
@@ -45,22 +52,13 @@ class WCML_Ajax_Setup{
45
  $woocommerce->load_plugin_textdomain();
46
  }
47
 
48
- function add_hidden_language_field(){
49
- if( function_exists('wpml_the_language_input_field') ){
50
- wpml_the_language_input_field();
51
- }else{
52
- global $sitepress;
53
- if (isset($sitepress) ) {
54
- return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
55
- }
56
- return null;
57
- }
58
- }
59
 
60
  function add_language_parameter_to_ajax_url($woocommerce_params){
61
- global $sitepress;
62
-
63
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
64
  $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
65
  }
66
 
@@ -68,13 +66,17 @@ class WCML_Ajax_Setup{
68
  }
69
 
70
  function filter_woocommerce_ajax_params($woocommerce_params){
71
- global $sitepress, $post;
72
- $value = array();
73
  $value = $woocommerce_params;
74
 
75
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
76
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
77
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
 
 
 
 
78
  }
79
 
80
  if(!isset($post->ID)){
@@ -105,7 +107,7 @@ class WCML_Ajax_Setup{
105
  } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
106
  $value['is_checkout'] = 1;
107
 
108
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
109
 
110
  } else if($ch_pages['translated_pay_page_id'] == $post->ID){
111
  $value['is_pay_page'] = 1;
@@ -114,18 +116,24 @@ class WCML_Ajax_Setup{
114
  return $value;
115
  }
116
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
 
118
- function wcml_localize_woocommerce_on_ajax(){
119
- if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
120
- return;
121
- }
122
 
123
- global $sitepress;
124
-
125
- $current_language = $sitepress->get_current_language();
126
-
127
- $sitepress->switch_lang($current_language, true);
128
- }
129
 
130
  /**
131
  * @param $endpoint string
8
  */
9
  private $sitepress;
10
 
11
+ public function __construct( SitePress $sitepress ) {
12
 
13
+ $this->sitepress = $sitepress;
14
+ }
15
+
16
+ public function add_hooks(){
17
 
18
+ add_action( 'init', array( $this, 'init' ) );
19
+ add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
20
 
21
+ //@deprecated 3.9 Use 'wcml_localize_woocommerce_on_ajax' instead
22
+ add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
23
 
24
  add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
25
  }
26
 
27
+ public function init() {
28
+ if ( wpml_is_ajax() ) {
29
+ do_action( 'wcml_localize_woocommerce_on_ajax' );
30
+ }
31
+
32
+ if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.3', '<' ) ) {
33
+ add_filter( 'woocommerce_params', array( $this, 'filter_woocommerce_ajax_params' ) );
34
+
35
+ add_filter( 'wc_checkout_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
36
+ add_filter( 'wc_cart', array( $this, 'add_language_parameter_to_ajax_url' ) );
37
+ add_filter( 'wc_cart_fragments_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
38
+ add_filter( 'wc_add_to_cart_params', array( $this, 'add_language_parameter_to_ajax_url' ) );
39
+ } else {
40
+ add_filter( 'woocommerce_get_script_data', array( $this, 'filter_woocommerce_ajax_params' ) );
41
+ }
42
+
43
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
44
+ add_action( 'woocommerce_checkout_order_review', array( $this, 'add_hidden_language_field' ) );
45
+ add_action( 'woocommerce_checkout_update_order_review', array( $this, 'filter_woocommerce_order_review' ), 9 );
46
+
47
+ }
48
 
49
  function filter_woocommerce_order_review(){
50
  global $woocommerce;
52
  $woocommerce->load_plugin_textdomain();
53
  }
54
 
55
+ function add_hidden_language_field() {
56
+ do_action( 'wpml_add_language_form_field' );
57
+ }
 
 
 
 
 
 
 
 
58
 
59
  function add_language_parameter_to_ajax_url($woocommerce_params){
60
+
61
+ if($this->sitepress->get_current_language() !== $this->sitepress->get_default_language()){
 
62
  $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
63
  }
64
 
66
  }
67
 
68
  function filter_woocommerce_ajax_params($woocommerce_params){
69
+ global $post;
70
+
71
  $value = $woocommerce_params;
72
 
73
+ if($this->sitepress->get_current_language() !== $this->sitepress->get_default_language()){
74
+ if( isset( $value['ajax_url'] ) ){
75
+ $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
76
+ if( isset( $value['checkout_url'] ) ){
77
+ $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
+ }
79
+ }
80
  }
81
 
82
  if(!isset($post->ID)){
107
  } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
108
  $value['is_checkout'] = 1;
109
 
110
+ $_SESSION['wpml_globalcart_language'] = $this->sitepress->get_current_language();
111
 
112
  } else if($ch_pages['translated_pay_page_id'] == $post->ID){
113
  $value['is_pay_page'] = 1;
116
  return $value;
117
  }
118
 
119
+ public function wcml_localize_woocommerce_on_ajax() {
120
+ $action = filter_var( $_POST['action'], FILTER_SANITIZE_STRING );
121
+ $is_ajax_action = $action
122
+ && in_array( $action,
123
+ array(
124
+ 'wcml_product_data',
125
+ 'wpml_translation_dialog_save_job',
126
+ 'edit-theme-plugin-file'
127
+ ),
128
+ true );
129
+ if ( $action && ( $is_ajax_action || ! apply_filters( 'wcml_is_localize_woocommerce_on_ajax', true, $action ) ) ) {
130
+ return;
131
+ }
132
 
133
+ $current_language = $this->sitepress->get_current_language();
 
 
 
134
 
135
+ $this->sitepress->switch_lang( $current_language, true );
136
+ }
 
 
 
 
137
 
138
  /**
139
  * @param $endpoint string
inc/class-wcml-attributes.php CHANGED
@@ -657,9 +657,12 @@ class WCML_Attributes{
657
  */
658
  private function get_attribute_term_translation_in_current_language( $attribute_taxonomy, $attribute_value ) {
659
 
660
- $term = get_term_by( 'slug', $attribute_value, $attribute_taxonomy );
 
 
 
661
 
662
- return $term->slug;
663
  }
664
 
665
 
657
  */
658
  private function get_attribute_term_translation_in_current_language( $attribute_taxonomy, $attribute_value ) {
659
 
660
+ if( taxonomy_exists( $attribute_taxonomy ) ){
661
+ $term = get_term_by( 'slug', $attribute_value, $attribute_taxonomy );
662
+ $attribute_value = $term->slug;
663
+ }
664
 
665
+ return $attribute_value;
666
  }
667
 
668
 
inc/class-wcml-cart.php CHANGED
@@ -398,7 +398,7 @@ class WCML_Cart {
398
  $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
399
  $attr_translation = $term->slug;
400
  }
401
- } else {
402
 
403
  $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
404
 
398
  $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
399
  $attr_translation = $term->slug;
400
  }
401
+ } elseif( $variation_id ) {
402
 
403
  $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
404
 
inc/class-wcml-compatibility.php CHANGED
@@ -235,6 +235,12 @@ class WCML_Compatibility {
235
  $this->etheme_blanco->add_hooks();
236
  }
237
 
 
 
 
 
 
 
238
  }
239
 
240
  }
235
  $this->etheme_blanco->add_hooks();
236
  }
237
 
238
+ // WPBakery Page Builder
239
+ if ( defined( 'WPB_VC_VERSION') ) {
240
+ $this->wpb_vc= new WCML_Wpb_Vc();
241
+ $this->wpb_vc->add_hooks();
242
+ }
243
+
244
  }
245
 
246
  }
inc/class-wcml-dependencies.php CHANGED
@@ -199,9 +199,9 @@ class WCML_Dependencies{
199
  return;
200
  }
201
 
202
- $message = sprintf('Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual');
203
  $message .= '<br /><br />';
204
- $message .= sprintf('Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual');
205
  $message .= '<br /><br />';
206
  $message .= '<a href="' . admin_url('options-permalink.php') . '">' . __('Permalink settings', 'woocommerce-multilingual') . '</a>';
207
  $message .= ' | ';
@@ -281,16 +281,16 @@ class WCML_Dependencies{
281
  }
282
 
283
  public function check_wpml_config(){
284
- global $sitepress_settings;
285
-
286
- if(empty($sitepress_settings)) return;
287
-
288
  $file = realpath(WCML_PLUGIN_PATH . '/wpml-config.xml');
289
  if(!file_exists($file)){
290
  $this->xml_config_errors[] = __('wpml-config.xml file missing from WooCommerce Multilingual folder.', 'woocommerce-multilingual');
291
  }else{
292
- $config = icl_xml2array(file_get_contents($file));
293
-
294
  if(isset($config['wpml-config'])){
295
 
296
  //custom-fields
@@ -302,21 +302,21 @@ class WCML_Dependencies{
302
  $cfs[] = $cf;
303
  }
304
  }
305
-
306
  if($cfs)
307
  foreach($cfs as $cf){
308
- if(!isset($sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']])) continue;
309
-
310
  $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']];
311
  $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ($cf['attr']['action'] == 'translate' ? 2: 0);
312
-
313
  if($effective_config_value != $correct_config_value){
314
  $this->xml_config_errors[] = sprintf(__('Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $cf['value'] . '</i>');
315
  }
316
  }
317
-
318
  }
319
-
320
  //custom-types
321
  if(isset($config['wpml-config']['custom-types'])){
322
  if(isset($config['wpml-config']['custom-types']['custom-type']['value'])){ //single
@@ -326,18 +326,24 @@ class WCML_Dependencies{
326
  $cts[] = $cf;
327
  }
328
  }
329
-
330
- if($cts)
331
- foreach($cts as $ct){
332
- if(!isset($sitepress_settings['custom_posts_sync_option'][$ct['value']])) continue;
333
- $effective_config_value = $sitepress_settings['custom_posts_sync_option'][$ct['value']];
334
- $correct_config_value = $ct['attr']['translate'];
335
-
336
- if($effective_config_value != $correct_config_value){
337
- $this->xml_config_errors[] = sprintf(__('Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $ct['value'] . '</i>');
338
- }
 
 
 
 
 
 
 
339
  }
340
-
341
  }
342
 
343
  //taxonomies
@@ -349,22 +355,26 @@ class WCML_Dependencies{
349
  $txs[] = $cf;
350
  }
351
  }
352
-
353
  if($txs)
354
  foreach($txs as $tx){
355
  if(!isset($sitepress_settings['taxonomies_sync_option'][$tx['value']])) continue;
356
  $effective_config_value = $sitepress_settings['taxonomies_sync_option'][$tx['value']];
357
  $correct_config_value = $tx['attr']['translate'];
358
-
 
 
 
 
359
  if($effective_config_value != $correct_config_value){
360
  $this->xml_config_errors[] = sprintf(__('Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $tx['value'] . '</i>');
361
  }
362
  }
363
-
364
  }
365
  }
366
  }
367
-
368
  }
369
 
370
  public function required_plugin_install_link($repository = 'wpml'){
199
  return;
200
  }
201
 
202
+ $message = __('Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual');
203
  $message .= '<br /><br />';
204
+ $message .= __('Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual');
205
  $message .= '<br /><br />';
206
  $message .= '<a href="' . admin_url('options-permalink.php') . '">' . __('Permalink settings', 'woocommerce-multilingual') . '</a>';
207
  $message .= ' | ';
281
  }
282
 
283
  public function check_wpml_config(){
284
+ global $sitepress_settings, $sitepress, $woocommerce_wpml;
285
+
286
+ if(empty($sitepress_settings) || ! $this->check() ) return;
287
+
288
  $file = realpath(WCML_PLUGIN_PATH . '/wpml-config.xml');
289
  if(!file_exists($file)){
290
  $this->xml_config_errors[] = __('wpml-config.xml file missing from WooCommerce Multilingual folder.', 'woocommerce-multilingual');
291
  }else{
292
+ $config = icl_xml2array(file_get_contents($file));
293
+
294
  if(isset($config['wpml-config'])){
295
 
296
  //custom-fields
302
  $cfs[] = $cf;
303
  }
304
  }
305
+
306
  if($cfs)
307
  foreach($cfs as $cf){
308
+ if(!isset($sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']])) continue;
309
+
310
  $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']];
311
  $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ($cf['attr']['action'] == 'translate' ? 2: 0);
312
+
313
  if($effective_config_value != $correct_config_value){
314
  $this->xml_config_errors[] = sprintf(__('Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $cf['value'] . '</i>');
315
  }
316
  }
317
+
318
  }
319
+
320
  //custom-types
321
  if(isset($config['wpml-config']['custom-types'])){
322
  if(isset($config['wpml-config']['custom-types']['custom-type']['value'])){ //single
326
  $cts[] = $cf;
327
  }
328
  }
329
+
330
+ if($cts){
331
+ foreach($cts as $ct){
332
+ if(!isset($sitepress_settings['custom_posts_sync_option'][$ct['value']])) continue;
333
+ $effective_config_value = $sitepress_settings['custom_posts_sync_option'][$ct['value']];
334
+ $correct_config_value = $ct['attr']['translate'];
335
+
336
+
337
+ if ('product' === $ct['value'] && $woocommerce_wpml->products->is_product_display_as_translated_post_type() ) {
338
+ $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED;
339
+ }
340
+
341
+
342
+ if($effective_config_value != $correct_config_value){
343
+ $this->xml_config_errors[] = sprintf(__('Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $ct['value'] . '</i>');
344
+ }
345
+ }
346
  }
 
347
  }
348
 
349
  //taxonomies
355
  $txs[] = $cf;
356
  }
357
  }
358
+
359
  if($txs)
360
  foreach($txs as $tx){
361
  if(!isset($sitepress_settings['taxonomies_sync_option'][$tx['value']])) continue;
362
  $effective_config_value = $sitepress_settings['taxonomies_sync_option'][$tx['value']];
363
  $correct_config_value = $tx['attr']['translate'];
364
+
365
+ if($sitepress->is_display_as_translated_taxonomy( $tx['value'] ) ){
366
+ $correct_config_value = WPML_CONTENT_TYPE_DISPLAY_AS_IF_TRANSLATED;
367
+ }
368
+
369
  if($effective_config_value != $correct_config_value){
370
  $this->xml_config_errors[] = sprintf(__('Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $tx['value'] . '</i>');
371
  }
372
  }
373
+
374
  }
375
  }
376
  }
377
+
378
  }
379
 
380
  public function required_plugin_install_link($repository = 'wpml'){
inc/class-wcml-terms.php CHANGED
@@ -64,9 +64,6 @@ class WCML_Terms{
64
 
65
  add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
66
  add_action( 'created_term_translation', array( $this, 'set_flag_to_sync' ), 10, 3 );
67
-
68
- add_action( 'updated_term_meta', array( $this, 'update_product_count_term' ), 10, 4 );
69
-
70
  }
71
 
72
  function admin_menu_setup(){
@@ -994,26 +991,6 @@ class WCML_Terms{
994
  return $this->wcml_get_term_by_id( $term_id, $taxonomy );
995
  }
996
 
997
- public function update_product_count_term( $meta_id, $object_id, $meta_key, $meta_value ){
998
-
999
- remove_action( 'updated_term_meta', array( $this, 'update_product_count_term'), 10, 4 );
1000
-
1001
- if( $meta_key === 'product_count_product_cat' ){
1002
-
1003
- $trid = $this->sitepress->get_element_trid( $object_id, 'tax_product_cat' );
1004
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
1005
-
1006
- if ($translations) foreach ( $translations as $translation ) {
1007
- if ( $translation->element_id != $object_id ) {
1008
- update_term_meta( $translation->element_id, $meta_key, $meta_value );
1009
- }
1010
- }
1011
-
1012
- }
1013
-
1014
- add_action( 'updated_term_meta', array( $this, 'update_product_count_term'), 10, 4 );
1015
- }
1016
-
1017
  public function is_translatable_wc_taxonomy( $taxonomy ) {
1018
  if ( in_array( $taxonomy, array( 'product_type', 'product_visibility' ), true ) ) {
1019
  return false;
64
 
65
  add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
66
  add_action( 'created_term_translation', array( $this, 'set_flag_to_sync' ), 10, 3 );
 
 
 
67
  }
68
 
69
  function admin_menu_setup(){
991
  return $this->wcml_get_term_by_id( $term_id, $taxonomy );
992
  }
993
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
994
  public function is_translatable_wc_taxonomy( $taxonomy ) {
995
  if ( in_array( $taxonomy, array( 'product_type', 'product_visibility' ), true ) ) {
996
  return false;
inc/class-woocommerce-wpml.php CHANGED
@@ -225,7 +225,8 @@ class woocommerce_wpml {
225
  $payment_method_filter = new WCML_Payment_Method_Filter();
226
  $payment_method_filter->add_hooks();
227
 
228
- new WCML_Ajax_Setup( $sitepress );
 
229
  new WCML_Fix_Copied_Custom_Fields_WPML353();
230
 
231
  WCML_Install::initialize( $this, $sitepress );
225
  $payment_method_filter = new WCML_Payment_Method_Filter();
226
  $payment_method_filter->add_hooks();
227
 
228
+ $wcml_ajax_setup = new WCML_Ajax_Setup( $sitepress );
229
+ $wcml_ajax_setup->add_hooks();
230
  new WCML_Fix_Copied_Custom_Fields_WPML353();
231
 
232
  WCML_Install::initialize( $this, $sitepress );
inc/currencies/class-wcml-multi-currency-orders.php CHANGED
@@ -35,6 +35,7 @@ class WCML_Multi_Currency_Orders {
35
  add_action( 'woocommerce_order_actions_start', array( $this, 'show_order_currency_selector' ) );
36
 
37
  add_filter( 'woocommerce_ajax_order_item', array( $this, 'filter_ajax_order_item' ), 10, 2 );
 
38
 
39
  add_action( 'wp_ajax_wcml_order_set_currency', array( $this, 'set_order_currency_on_ajax_update' ) );
40
 
@@ -254,14 +255,41 @@ class WCML_Multi_Currency_Orders {
254
  }
255
 
256
  public function filter_ajax_order_item( $item, $item_id ) {
257
- if ( ! get_post_meta( $_POST['order_id'], '_order_currency' ) ) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  $order_currency = $this->get_order_currency_cookie();
259
- } else {
260
- $order_currency = get_post_meta( $_POST['order_id'], '_order_currency', true );
261
  }
262
 
263
  $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( sanitize_text_field( $_POST['item_to_add'][0] ) );
264
- $custom_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
265
 
266
  if ( ! isset( $this->multi_currency->prices ) ) {
267
  $this->multi_currency->prices = new WCML_Multi_Currency_Prices( $this->multi_currency );
@@ -269,22 +297,23 @@ class WCML_Multi_Currency_Orders {
269
  $this->multi_currency->prices->prices_init();
270
  }
271
 
272
- if ( $custom_price ) {
273
- $item['line_subtotal'] = $custom_price;
274
- $item['line_total'] = $custom_price;
275
- } else {
276
- $item['line_subtotal'] = $this->multi_currency->prices->raw_price_filter( $item['line_subtotal'], $order_currency );
277
- $item['line_total'] = $this->multi_currency->prices->raw_price_filter( $item['line_total'], $order_currency );
278
  }
279
 
280
- wc_update_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
281
- $item['line_subtotal_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_subtotal_tax'], $order_currency );
282
- wc_update_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
283
- wc_update_order_item_meta( $item_id, '_line_total', $item['line_total'] );
284
- $item['line_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_tax'], $order_currency );
285
- wc_update_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
 
 
 
 
286
 
287
- return $item;
288
  }
289
 
290
  public function get_order_currency_cookie() {
35
  add_action( 'woocommerce_order_actions_start', array( $this, 'show_order_currency_selector' ) );
36
 
37
  add_filter( 'woocommerce_ajax_order_item', array( $this, 'filter_ajax_order_item' ), 10, 2 );
38
+ add_filter( 'woocommerce_order_get_items', array( $this, 'set_totals_for_order_items' ) );
39
 
40
  add_action( 'wp_ajax_wcml_order_set_currency', array( $this, 'set_order_currency_on_ajax_update' ) );
41
 
255
  }
256
 
257
  public function filter_ajax_order_item( $item, $item_id ) {
258
+
259
+ list( $item, $order_currency ) = $this->set_converted_totals_for_item( $item );
260
+
261
+ wc_update_order_item_meta( $item_id, '_line_subtotal', $item['line_subtotal'] );
262
+ $item['line_subtotal_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_subtotal_tax'], $order_currency );
263
+ wc_update_order_item_meta( $item_id, '_line_subtotal_tax', $item['line_subtotal_tax'] );
264
+ wc_update_order_item_meta( $item_id, '_line_total', $item['line_total'] );
265
+ $item['line_tax'] = $this->multi_currency->prices->convert_price_amount( $item['line_tax'], $order_currency );
266
+ wc_update_order_item_meta( $item_id, '_line_tax', $item['line_tax'] );
267
+
268
+ return $item;
269
+ }
270
+
271
+ public function set_totals_for_order_items( $items ) {
272
+
273
+ if ( isset( $_POST['action'] ) && 'woocommerce_add_order_item' === $_POST['action'] ) {
274
+
275
+ foreach ( $items as $item ) {
276
+ $this->set_converted_totals_for_item( $item );
277
+ }
278
+ }
279
+
280
+ return $items;
281
+ }
282
+
283
+ private function set_converted_totals_for_item( $item ) {
284
+
285
+ $order_currency = get_post_meta( $_POST['order_id'], '_order_currency', true );
286
+
287
+ if ( ! $order_currency ) {
288
  $order_currency = $this->get_order_currency_cookie();
 
 
289
  }
290
 
291
  $original_product_id = $this->woocommerce_wpml->products->get_original_product_id( sanitize_text_field( $_POST['item_to_add'][0] ) );
292
+ $converted_price = get_post_meta( $original_product_id, '_price_' . $order_currency, true );
293
 
294
  if ( ! isset( $this->multi_currency->prices ) ) {
295
  $this->multi_currency->prices = new WCML_Multi_Currency_Prices( $this->multi_currency );
297
  $this->multi_currency->prices->prices_init();
298
  }
299
 
300
+ if ( ! $converted_price ) {
301
+ $converted_price = $this->multi_currency->prices->raw_price_filter( $item['line_subtotal'], $order_currency );
302
+ $converted_price = $this->multi_currency->prices->raw_price_filter( $item['line_total'], $order_currency );
 
 
 
303
  }
304
 
305
+ if ( $item instanceof WC_Order_Item_Product ) {
306
+ if ( 'line_item' === $item->get_type() ) {
307
+ $item->set_subtotal( $converted_price );
308
+ $item->set_total( $converted_price );
309
+ $item->save();
310
+ }
311
+ } else {
312
+ $item['line_subtotal'] = $converted_price;
313
+ $item['line_total'] = $converted_price;
314
+ }
315
 
316
+ return array( $item, $order_currency );
317
  }
318
 
319
  public function get_order_currency_cookie() {
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -501,13 +501,12 @@ class WCML_Multi_Currency_Prices {
501
  return $cart_contents_total;
502
  }
503
 
504
- public function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $obj ) {
505
- global $woocommerce;
506
  remove_filter( 'woocommerce_cart_subtotal', array( $this, 'filter_woocommerce_cart_subtotal' ), 100, 3 );
507
- if ( apply_filters( 'wcml_calculate_totals_exception', true ) ) {
508
- $woocommerce->cart->calculate_totals();
509
- }
510
- $cart_subtotal = $woocommerce->cart->get_cart_subtotal( $compound );
511
  add_filter( 'woocommerce_cart_subtotal', array( $this, 'filter_woocommerce_cart_subtotal' ), 100, 3 );
512
 
513
  return $cart_subtotal;
501
  return $cart_contents_total;
502
  }
503
 
504
+ public function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart_object ) {
505
+
506
  remove_filter( 'woocommerce_cart_subtotal', array( $this, 'filter_woocommerce_cart_subtotal' ), 100, 3 );
507
+
508
+ $cart_subtotal = $cart_object->get_cart_subtotal( $compound );
509
+
 
510
  add_filter( 'woocommerce_cart_subtotal', array( $this, 'filter_woocommerce_cart_subtotal' ), 100, 3 );
511
 
512
  return $cart_subtotal;
inc/template-classes/status/class-wcml-status-taxonomies-ui.php CHANGED
@@ -3,11 +3,13 @@
3
  class WCML_Status_Taxonomies_UI extends WPML_Templates_Factory {
4
 
5
  private $woocommerce_wpml;
 
6
 
7
- function __construct( &$woocommerce_wpml ){
8
  parent::__construct();
9
 
10
- $this->woocommerce_wpml = $woocommerce_wpml;
 
11
  }
12
 
13
  public function get_model() {
@@ -41,7 +43,9 @@ class WCML_Status_Taxonomies_UI extends WPML_Templates_Factory {
41
  $taxonomies_data = array();
42
 
43
  foreach ( $taxonomies as $key => $taxonomy ) {
44
- if( !is_taxonomy_translated( $taxonomy ) ) continue;
 
 
45
  $taxonomies_data[$key]['tax'] = $taxonomy;
46
  $taxonomies_data[$key]['untranslated'] = $this->woocommerce_wpml->terms->get_untranslated_terms_number($taxonomy);
47
  $taxonomies_data[$key]['fully_trans'] = $this->woocommerce_wpml->terms->is_fully_translated($taxonomy);
3
  class WCML_Status_Taxonomies_UI extends WPML_Templates_Factory {
4
 
5
  private $woocommerce_wpml;
6
+ private $sitepress;
7
 
8
+ function __construct( $sitepress, $woocommerce_wpml ){
9
  parent::__construct();
10
 
11
+ $this->sitepress = $sitepress;
12
+ $this->woocommerce_wpml = $woocommerce_wpml;
13
  }
14
 
15
  public function get_model() {
43
  $taxonomies_data = array();
44
 
45
  foreach ( $taxonomies as $key => $taxonomy ) {
46
+ if ( ! is_taxonomy_translated( $taxonomy ) || $this->sitepress->is_display_as_translated_taxonomy( $taxonomy ) ) {
47
+ continue;
48
+ }
49
  $taxonomies_data[$key]['tax'] = $taxonomy;
50
  $taxonomies_data[$key]['untranslated'] = $this->woocommerce_wpml->terms->get_untranslated_terms_number($taxonomy);
51
  $taxonomies_data[$key]['fully_trans'] = $this->woocommerce_wpml->terms->is_fully_translated($taxonomy);
inc/template-classes/status/class-wcml-status-ui.php CHANGED
@@ -24,8 +24,7 @@ class WCML_Status_UI extends WPML_Templates_Factory {
24
  $WCML_Status_Status_UI = new WCML_Status_Status_UI( $this->sitepress );
25
  $WCML_Status_Config_Warnings_UI = new WCML_Status_Config_Warnings_UI( $this->sitepress, $this->woocommerce_wpml, $this->sitepress_settings );
26
  $WCML_Status_Store_Pages_UI = new WCML_Status_Store_Pages_UI( $this->sitepress, $this->woocommerce_wpml );
27
- $WCML_Status_Taxonomies_UI = new WCML_Status_Taxonomies_UI( $this->woocommerce_wpml );
28
- $WCML_Status_Products_UI = new WCML_Status_Products_UI( $this->woocommerce_wpml, $this->sitepress );
29
  $WCML_Status_Multi_Currencies_UI= new WCML_Status_Multi_Currencies_UI( $this->woocommerce_wpml );
30
 
31
  $model = array(
@@ -33,7 +32,6 @@ class WCML_Status_UI extends WPML_Templates_Factory {
33
  'conf_warnings' => $WCML_Status_Config_Warnings_UI->get_view(),
34
  'store_pages' => $WCML_Status_Store_Pages_UI->get_view(),
35
  'taxonomies' => $WCML_Status_Taxonomies_UI->get_view(),
36
- 'products' => $WCML_Status_Products_UI->get_view(),
37
  'multi_currency' => $WCML_Status_Multi_Currencies_UI->get_view(),
38
  'troubl_url' => admin_url( 'admin.php?page=wpml-wcml&tab=troubleshooting' ),
39
  'strings' => array(
@@ -41,6 +39,11 @@ class WCML_Status_UI extends WPML_Templates_Factory {
41
  )
42
  );
43
 
 
 
 
 
 
44
  return $model;
45
  }
46
 
24
  $WCML_Status_Status_UI = new WCML_Status_Status_UI( $this->sitepress );
25
  $WCML_Status_Config_Warnings_UI = new WCML_Status_Config_Warnings_UI( $this->sitepress, $this->woocommerce_wpml, $this->sitepress_settings );
26
  $WCML_Status_Store_Pages_UI = new WCML_Status_Store_Pages_UI( $this->sitepress, $this->woocommerce_wpml );
27
+ $WCML_Status_Taxonomies_UI = new WCML_Status_Taxonomies_UI( $this->sitepress, $this->woocommerce_wpml );
 
28
  $WCML_Status_Multi_Currencies_UI= new WCML_Status_Multi_Currencies_UI( $this->woocommerce_wpml );
29
 
30
  $model = array(
32
  'conf_warnings' => $WCML_Status_Config_Warnings_UI->get_view(),
33
  'store_pages' => $WCML_Status_Store_Pages_UI->get_view(),
34
  'taxonomies' => $WCML_Status_Taxonomies_UI->get_view(),
 
35
  'multi_currency' => $WCML_Status_Multi_Currencies_UI->get_view(),
36
  'troubl_url' => admin_url( 'admin.php?page=wpml-wcml&tab=troubleshooting' ),
37
  'strings' => array(
39
  )
40
  );
41
 
42
+ if ( ! $this->woocommerce_wpml->products->is_product_display_as_translated_post_type() ) {
43
+ $WCML_Status_Products_UI = new WCML_Status_Products_UI( $this->woocommerce_wpml, $this->sitepress );
44
+ $model['products'] = $WCML_Status_Products_UI->get_view();
45
+ }
46
+
47
  return $model;
48
  }
49
 
inc/translation-editor/class-wcml-editor-ui-product-job.php CHANGED
@@ -184,7 +184,7 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
184
 
185
  }else{
186
 
187
- $custom_fields_values = array_values( array_filter( get_post_meta($this->product_id, $custom_field , true ) ) );
188
 
189
  if( $custom_fields_values ){
190
  $cf_fields_group = new WPML_Editor_UI_Field_Group();
@@ -556,11 +556,11 @@ class WCML_Editor_UI_Product_Job extends WPML_Editor_UI_Job {
556
 
557
  }else{
558
 
559
- $custom_fields_values = array_values( array_filter( get_post_meta($this->product_id, $custom_field, true ) ) );
560
 
561
  if( $custom_fields_values ){
562
  if ( $translation_id ) {
563
- $translated_custom_field_values = array_values( array_filter( get_post_meta( $translation_id, $custom_field , true ) ) );
564
  }
565
  foreach( $custom_fields_values as $custom_field_index => $custom_field_val ){
566
 
184
 
185
  }else{
186
 
187
+ $custom_fields_values = array_values( array_filter( maybe_unserialize( get_post_meta($this->product_id, $custom_field , true ) ) ) );
188
 
189
  if( $custom_fields_values ){
190
  $cf_fields_group = new WPML_Editor_UI_Field_Group();
556
 
557
  }else{
558
 
559
+ $custom_fields_values = array_values( array_filter( maybe_unserialize( get_post_meta($this->product_id, $custom_field, true ) ) ) );
560
 
561
  if( $custom_fields_values ){
562
  if ( $translation_id ) {
563
+ $translated_custom_field_values = array_values( array_filter( maybe_unserialize( get_post_meta( $translation_id, $custom_field , true ) ) ) );
564
  }
565
  foreach( $custom_fields_values as $custom_field_index => $custom_field_val ){
566
 
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -49,7 +49,7 @@ class WCML_Synchronize_Product_Data{
49
 
50
  add_action( 'woocommerce_reduce_order_stock', array( $this, 'sync_product_stocks_reduce' ) );
51
  add_action( 'woocommerce_restore_order_stock', array( $this, 'sync_product_stocks_restore' ) );
52
- add_action( 'woocommerce_product_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 10, 2);
53
  add_action( 'woocommerce_variation_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 10, 2);
54
 
55
  add_filter( 'future_product', array( $this, 'set_schedule_for_translations'), 10, 2 );
@@ -84,16 +84,20 @@ class WCML_Synchronize_Product_Data{
84
  }
85
 
86
  // exceptions
87
- $ajax_call = ( !empty( $_POST[ 'icl_ajx_action' ] ) && $_POST[ 'icl_ajx_action' ] == 'make_duplicates' );
88
- $api_call = !empty( $wp->query_vars['wc-api-version'] );
89
- if (
90
- $post_type != 'product' ||
91
- ( empty( $original_product_id ) || isset( $_POST[ 'autosave' ] ) ) ||
92
- ( $pagenow != 'post.php' && $pagenow != 'post-new.php' && $pagenow != 'admin.php' && !$ajax_call && !$api_call ) ||
93
- ( isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] == 'trash' )
94
- ) {
95
- return;
96
- }
 
 
 
 
97
  // Remove filter to avoid double sync
98
  remove_action( 'save_post', array( $this, 'synchronize_products' ), PHP_INT_MAX, 2 );
99
 
@@ -364,6 +368,8 @@ class WCML_Synchronize_Product_Data{
364
  }
365
 
366
  update_post_meta( $translation_product_id, 'total_sales', $total_sales );
 
 
367
  }
368
  }
369
  }
@@ -379,10 +385,28 @@ class WCML_Synchronize_Product_Data{
379
  foreach ( $translations as $translation ) {
380
  if ( !$translation->original ) {
381
  update_post_meta( $translation->element_id, '_stock_status', $status );
 
 
382
  }
383
  }
384
  }
385
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
  }
387
 
388
  //sync product parent & post_status
49
 
50
  add_action( 'woocommerce_reduce_order_stock', array( $this, 'sync_product_stocks_reduce' ) );
51
  add_action( 'woocommerce_restore_order_stock', array( $this, 'sync_product_stocks_restore' ) );
52
+ add_action( 'woocommerce_product_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 100, 2);
53
  add_action( 'woocommerce_variation_set_stock_status', array($this, 'sync_stock_status_for_translations' ), 10, 2);
54
 
55
  add_filter( 'future_product', array( $this, 'set_schedule_for_translations'), 10, 2 );
84
  }
85
 
86
  // exceptions
87
+ $ajax_call = ( ! empty( $_POST['icl_ajx_action'] ) && 'make_duplicates' === $_POST['icl_ajx_action'] );
88
+ $api_call = ! empty( $wp->query_vars['wc-api-version'] );
89
+ $auto_draft = 'auto-draft' === $post->post_status;
90
+ $trashing = isset( $_GET['action'] ) && 'trash' === $_GET['action'];
91
+ if (
92
+ $post_type !== 'product' ||
93
+ empty( $original_product_id ) ||
94
+ isset( $_POST['autosave'] ) ||
95
+ ( $pagenow !== 'post.php' && $pagenow !== 'post-new.php' && $pagenow != 'admin.php' && ! $ajax_call && ! $api_call ) ||
96
+ $trashing ||
97
+ $auto_draft
98
+ ) {
99
+ return;
100
+ }
101
  // Remove filter to avoid double sync
102
  remove_action( 'save_post', array( $this, 'synchronize_products' ), PHP_INT_MAX, 2 );
103
 
368
  }
369
 
370
  update_post_meta( $translation_product_id, 'total_sales', $total_sales );
371
+
372
+ $this->wc_taxonomies_recount_after_stock_change( (int)$translation_product_id );
373
  }
374
  }
375
  }
385
  foreach ( $translations as $translation ) {
386
  if ( !$translation->original ) {
387
  update_post_meta( $translation->element_id, '_stock_status', $status );
388
+
389
+ $this->wc_taxonomies_recount_after_stock_change( (int)$translation->element_id );
390
  }
391
  }
392
  }
393
 
394
+ }
395
+
396
+ /**
397
+ * @param int $product_id
398
+ */
399
+ private function wc_taxonomies_recount_after_stock_change( $product_id ){
400
+
401
+ remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 );
402
+
403
+ wp_cache_delete( $product_id, 'product_cat_relationships' );
404
+ wp_cache_delete( $product_id, 'product_tag_relationships' );
405
+
406
+ wc_recount_after_stock_change( $product_id );
407
+
408
+ add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1, 1 );
409
+
410
  }
411
 
412
  //sync product parent & post_status
inc/translation-editor/class-wcml-translation-editor.php CHANGED
@@ -26,7 +26,7 @@ class WCML_Translation_Editor{
26
  add_filter( 'icl_post_alternative_languages', array( $this, 'hide_post_translation_links' ) );
27
 
28
  add_filter( 'manage_product_posts_columns', array( $this, 'add_languages_column' ), 100 );
29
- add_action( 'woocommerce_product_after_variable_attributes', array( $this, 'lock_variable_fields' ), 10, 3 );
30
 
31
  if( is_admin() ){
32
  add_filter( 'wpml_use_tm_editor', array( $this, 'force_woocommerce_native_editor'), 100 );
@@ -196,7 +196,7 @@ class WCML_Translation_Editor{
196
  return $new_columns;
197
  }
198
 
199
- public function lock_variable_fields( $loop, $variation_data, $variation ){
200
 
201
  $product_id = false;
202
 
@@ -225,11 +225,11 @@ class WCML_Translation_Editor{
225
  if ( $variations ) {
226
  foreach ($variations as $variation) {
227
  $variation_id = absint( $variation->ID );
228
- $original_id = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
229
  $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
230
  if( $custom_product_sync && $custom_product_sync == 'self' ) {
231
  $file_path_sync[ $variation_id ] = false;
232
- }elseif( $custom_product_sync && $custom_product_sync == 'auto' ){
233
  $file_path_sync[ $variation_id ] = true;
234
  }
235
  }
26
  add_filter( 'icl_post_alternative_languages', array( $this, 'hide_post_translation_links' ) );
27
 
28
  add_filter( 'manage_product_posts_columns', array( $this, 'add_languages_column' ), 100 );
29
+ add_action( 'woocommerce_product_after_variable_attributes', array( $this, 'lock_variable_fields' ), 10 );
30
 
31
  if( is_admin() ){
32
  add_filter( 'wpml_use_tm_editor', array( $this, 'force_woocommerce_native_editor'), 100 );
196
  return $new_columns;
197
  }
198
 
199
+ public function lock_variable_fields( $loop ){
200
 
201
  $product_id = false;
202
 
225
  if ( $variations ) {
226
  foreach ($variations as $variation) {
227
  $variation_id = absint( $variation->ID );
228
+ $original_id = $this->woocommerce_wpml->products->get_original_product_id( $variation_id );
229
  $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
230
  if( $custom_product_sync && $custom_product_sync == 'self' ) {
231
  $file_path_sync[ $variation_id ] = false;
232
+ }else{
233
  $file_path_sync[ $variation_id ] = true;
234
  }
235
  }
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multili
5
  License: GPLv2
6
  Requires at least: 3.9
7
  Tested up to: 4.9.1
8
- Stable tag: 4.2.7.1
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -142,8 +142,20 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
142
 
143
  == Changelog ==
144
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  = 4.2.7.1 =
146
- * Fatal error while updating to 4.2.7 with Woocommerce Bundles
147
 
148
  = 4.2.7 =
149
  * Translated attributes and "Display as translated" mode for products -> shows no variation in second language
5
  License: GPLv2
6
  Requires at least: 3.9
7
  Tested up to: 4.9.1
8
+ Stable tag: 4.2.8
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
142
 
143
  == Changelog ==
144
 
145
+ = 4.2.8 =
146
+ * Visual Bakery Composer compatibility issue - some strings displays in default language instead on user admin language
147
+ * Variable product with local attributes displays all variations values set to "any" with "use translation if available or fallback to default language" enabled for products
148
+ * Product Customizer produce error messages
149
+ * WooCommerce Subscriptions -> 'From....' price is not converted to current currency
150
+ * Global add-on filtered by category - does not work in second language
151
+ * [Fatal Error] WooCommerce Subscriptions -> Resubscribe with no multi-currency enabled
152
+ * Variation downloadable files not synchronized with Products Download Files setting in the native editor
153
+ * Incorrect category count in second languages
154
+ * WooCommerce Subscription incorrect recurring totals in secondary currency
155
+ * Manually set price (2nd currency) -> adding product to manually created order results in price of the first currency being used
156
+
157
  = 4.2.7.1 =
158
+ * Fixed fatal error while updating to 4.2.7 with Woocommerce Bundles
159
 
160
  = 4.2.7 =
161
  * Translated attributes and "Display as translated" mode for products -> shows no variation in second language
res/css/wcml-prices.css CHANGED
@@ -1 +1 @@
1
- .wcml_custom_prices_block{float:left;margin-top:10px;width:100%}#general_product_data .wcml_custom_prices_block{padding-left:10px}.wcml_custom_prices_options_block,.custom_prices_message_block{display:inline-block;width:100%}.wcml_custom_prices_manually_block_control{padding-left:10px}.wcml_custom_prices_options_block input.wcml_custom_prices_input,.wc-metaboxes-wrapper .wcml_custom_prices_options_block input.wcml_custom_prices_input,.wcml_custom_prices_manually_block input.wcml_schedule_input,.wc-metaboxes-wrapper .wcml_custom_prices_manually_block input.wcml_schedule_input{width:16px;clear:both;margin:2px 5px 2px 0;float:left}.wcml_custom_prices_options_block label,.wcml_schedule_options label{width:auto;margin:0;float:left}.custom_prices_message_block label{width:auto;margin:0;float:left;color:#9d261d}.wc-metaboxes-wrapper .wcml_custom_prices_manually_block .currency_blck>label,.wc-metaboxes-wrapper .wcml_automaticaly_prices_block label{clear:both}.currency_blck,.wcml_schedule_dates{clear:both}.wcml_custom_prices_manually_block,.wcml_automaticaly_prices_block,.wcml_schedule_dates{clear:both;display:none;padding-left:10px}.wcml_custom_prices_manually_block p,.wcml_automaticaly_prices_block p{clear:both;margin-top:0}.currency_blck{float:left;width:100%;margin-bottom:5px;border-bottom:1px solid #dfdfdf;padding:5px 0}.currency_blck>label{font-weight:bold;margin-left:0}.wcml_automaticaly_prices_block>label{font-weight:bold;margin-left:0}.wcml_schedule_manually_block_hide,.block_actions,.wcml_custom_prices_auto_block_hide{display:none}.wcml_custom_prices_manually_block_show,.wcml_custom_prices_manually_block_hide{display:none;clear:both;float:left}.wcml_no_price_message{font-style:italic;font-size:12px}.wcml_schedule{padding-left:12px;clear:both;float:left}.wcml_schedule_options{float:left}.wcml_schedule .wcml_schedule_options label,.woocommerce_variation .wcml_schedule .wcml_schedule_options label{width:200px}.woocommerce_options_panel .wcml_schedule_dates input.short{width:100px}.wcml_schedule label{margin:0}.woocommerce_variation .currency_blck label{float:left;display:inline-block;width:150px}.woocommerce_variation .currency_blck p{padding:5px 20px 5px 12px}.woocommerce_variation .currency_blck p input{width:50%;float:left;display:inline-block}.woocommerce_variation .wcml_schedule_dates input{float:left}.options_group.show_if_downloadable{clear:both}.wcml_price_error{display:none;background:#aa0000;color:#fff;font-size:12px;font-weight:bold;margin-left:5px;float:left;padding:1px 6px}
1
+ .wcml_custom_prices_block:after,.wcml_schedule_dates:after{content:'';display:block;clear:both}.wcml_custom_prices_block{margin:10px}.wcml_custom_prices_block input[type="text"]{float:none}.wcml_custom_prices_options_block label,.wcml_schedule_options label{display:block;float:none;width:auto;margin:0}.wcml_custom_prices_options_block input[type="radio"],.wcml_schedule_options input[type="radio"]{float:none}.wcml_custom_prices_options_block,.custom_prices_message_block{display:block}.wcml_custom_prices_manually_block_control{padding-left:10px}.currency_blck:not(:last-child){margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #eee}.custom_prices_message_block label{color:#9d261d}.wcml_custom_prices_manually_block,.wcml_automaticaly_prices_block,.wcml_schedule_dates{display:none;padding-left:20px;margin-top:10px}.wcml_custom_prices_manually_block p,.wcml_automaticaly_prices_block p{margin:0}.currency_blck>label,.wcml_automaticaly_prices_block>label{display:block;font-weight:bold;margin:0 0 5px 0;width:auto;float:none}.wcml_schedule_manually_block_hide,.block_actions,.wcml_custom_prices_auto_block_hide{display:none}.wcml_custom_prices_manually_block_show,.wcml_custom_prices_manually_block_hide{display:none;padding-left:10px}.wcml_no_price_message{font-style:italic;font-size:12px}.woocommerce_options_panel .wcml_schedule_dates input.short{width:100px}.woocommerce_variation .currency_blck p,.woocommerce_variation .wcml_automaticaly_prices_block p,.wcml_schedule{padding:5px 20px 5px 162px !important}.woocommerce_variation .currency_blck p>label,.woocommerce_variation .wcml_automaticaly_prices_block p>label,.wcml_schedule>label{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_variation .currency_blck p .wcml_schedule_dates input,.woocommerce_variation .wcml_automaticaly_prices_block p .wcml_schedule_dates input,.wcml_schedule .wcml_schedule_dates input{float:left}.wcml_price_error{display:none;max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:.5em 1px 0 -1em;z-index:9999999;color:#fff;font-size:.8em;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,0.2)}.wcml_price_error:after{content:'';display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}
templates/multi-currency/custom-prices.twig CHANGED
@@ -10,8 +10,9 @@
10
  {% else %}
11
  <div class="wcml_custom_prices_options_block">
12
 
13
- <input type="radio" name="_wcml_custom_prices[{{ product_id }}]" id="wcml_custom_prices_auto[{{ product_id }}]" value="0" class="wcml_custom_prices_input" {{ checked_calc_auto|raw }} />
14
- <label for="wcml_custom_prices_auto[{{ product_id }}]">{{ strings.calc_auto }}&nbsp;
 
15
  <span class="block_actions" {% if checked_calc_auto is not empty %} style="display: inline;" {% endif %}>(
16
  <a href="" class="wcml_custom_prices_auto_block_show" title="{{ strings.see_prices|e }}">{{ strings.show }}</a>
17
  <a href="" class="wcml_custom_prices_auto_block_hide">{{ strings.hide }}</a>
@@ -19,8 +20,10 @@
19
  </label>
20
 
21
 
22
- <input type="radio" name="_wcml_custom_prices[{{ product_id }}]" value="1" id="wcml_custom_prices_manually[{{ product_id }}]" class="wcml_custom_prices_input" {{ checked_calc_manually|raw }} />
23
- <label for="wcml_custom_prices_manually[{{ product_id }}]">{{ strings.set_manually }}</label>
 
 
24
  <div class="wcml_custom_prices_manually_block_control">
25
  <a {% if checked_calc_manually is not empty %} style="display:none" {% endif %} href="" class="wcml_custom_prices_manually_block_show">&raquo; {{ strings.enter_prices }}</a>
26
  <a style="display:none" href="" class="wcml_custom_prices_manually_block_hide">- {{ strings.hide_prices }}</a>
@@ -58,18 +61,22 @@
58
  <label>{{ strings.schedule }}</label>
59
  <div class="wcml_schedule_options">
60
 
61
- <input type="radio" name="_wcml_schedule[{{ currency.currency_code }}]{{ html_id }}"
62
- id="wcml_schedule_auto[{{ currency.currency_code }}]{{ html_id }}"
63
- value="0"
64
- class="wcml_schedule_input" {{ currency.schedule_auto_checked|raw }} />
65
- <label for="wcml_schedule_auto[{{ currency.currency_code }}]{{ html_id }}">{{ strings.same_as_def }}</label>
 
 
 
66
 
67
 
68
- <input type="radio" name="_wcml_schedule[{{ currency.currency_code }}]{{ html_id }}"
69
- value="1"
70
- id="wcml_schedule_manually[{{ currency.currency_code }}]{{ html_id }}"
71
- class="wcml_schedule_input" {{ currency.schedule_man_checked|raw }} />
72
- <label for="wcml_schedule_manually[{{ currency.currency_code }}]{{ html_id }}">{{ strings.set_dates }}
 
73
  <span class="block_actions">(
74
  <a href="" class="wcml_schedule_manually_block_show">{{ strings.schedule }}</a>
75
  <a href="" class="wcml_schedule_manually_block_hide">{{ strings.collapse }}</a>
10
  {% else %}
11
  <div class="wcml_custom_prices_options_block">
12
 
13
+ <label for="wcml_custom_prices_auto[{{ product_id }}]">
14
+ <input type="radio" name="_wcml_custom_prices[{{ product_id }}]" id="wcml_custom_prices_auto[{{ product_id }}]" value="0" class="wcml_custom_prices_input" {{ checked_calc_auto|raw }} />
15
+ {{ strings.calc_auto }}&nbsp;
16
  <span class="block_actions" {% if checked_calc_auto is not empty %} style="display: inline;" {% endif %}>(
17
  <a href="" class="wcml_custom_prices_auto_block_show" title="{{ strings.see_prices|e }}">{{ strings.show }}</a>
18
  <a href="" class="wcml_custom_prices_auto_block_hide">{{ strings.hide }}</a>
20
  </label>
21
 
22
 
23
+ <label for="wcml_custom_prices_manually[{{ product_id }}]">
24
+ <input type="radio" name="_wcml_custom_prices[{{ product_id }}]" value="1" id="wcml_custom_prices_manually[{{ product_id }}]" class="wcml_custom_prices_input" {{ checked_calc_manually|raw }} />
25
+ {{ strings.set_manually }}
26
+ </label>
27
  <div class="wcml_custom_prices_manually_block_control">
28
  <a {% if checked_calc_manually is not empty %} style="display:none" {% endif %} href="" class="wcml_custom_prices_manually_block_show">&raquo; {{ strings.enter_prices }}</a>
29
  <a style="display:none" href="" class="wcml_custom_prices_manually_block_hide">- {{ strings.hide_prices }}</a>
61
  <label>{{ strings.schedule }}</label>
62
  <div class="wcml_schedule_options">
63
 
64
+
65
+ <label for="wcml_schedule_auto[{{ currency.currency_code }}]{{ html_id }}">
66
+ <input type="radio" name="_wcml_schedule[{{ currency.currency_code }}]{{ html_id }}"
67
+ id="wcml_schedule_auto[{{ currency.currency_code }}]{{ html_id }}"
68
+ value="0"
69
+ class="wcml_schedule_input" {{ currency.schedule_auto_checked|raw }} />
70
+ {{ strings.same_as_def }}
71
+ </label>
72
 
73
 
74
+ <label for="wcml_schedule_manually[{{ currency.currency_code }}]{{ html_id }}">
75
+ <input type="radio" name="_wcml_schedule[{{ currency.currency_code }}]{{ html_id }}"
76
+ value="1"
77
+ id="wcml_schedule_manually[{{ currency.currency_code }}]{{ html_id }}"
78
+ class="wcml_schedule_input" {{ currency.schedule_man_checked|raw }} />
79
+ {{ strings.set_dates }}
80
  <span class="block_actions">(
81
  <a href="" class="wcml_schedule_manually_block_show">{{ strings.schedule }}</a>
82
  <a href="" class="wcml_schedule_manually_block_hide">{{ strings.collapse }}</a>
templates/status/conf-warn.twig CHANGED
@@ -28,7 +28,7 @@
28
  {% endif %}
29
 
30
  {% if xml_config_errors is not empty %}
31
- <li>
32
  <i class="otgs-ico-warning"></i>
33
  <strong>{{ strings.over_sett }}</strong>
34
  <p>
28
  {% endif %}
29
 
30
  {% if xml_config_errors is not empty %}
31
+ <li class="wcml_xml_config_warnings">
32
  <i class="otgs-ico-warning"></i>
33
  <strong>{{ strings.over_sett }}</strong>
34
  <p>
templates/status/products.twig CHANGED
@@ -1,4 +1,4 @@
1
- <div class="wcml-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.products_missing }}
1
+ <div class="wcml-section wc-products-section">
2
  <div class="wcml-section-header">
3
  <h3>
4
  {{ strings.products_missing }}
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit700c2931447cea63ebf64beae8bdd7e5::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit09db18301760424c7dcc21b33162e94c::getLoader();
vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit7553e033b450bd056d54dea34f8634ea::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInitc6092e313fbc70ad1c34def5310404b7::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -437,6 +437,7 @@ return array(
437
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
438
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
439
  'WCML_WooCommerce_Rest_API_Support' => $baseDir . '/inc/class-wcml-woocommerce-rest-api-support.php',
 
440
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
441
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
442
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
437
  'WCML_WPSEO' => $baseDir . '/compatibility/class-wcml-wpseo.php',
438
  'WCML_Widgets' => $baseDir . '/inc/class-wcml-widgets.php',
439
  'WCML_WooCommerce_Rest_API_Support' => $baseDir . '/inc/class-wcml-woocommerce-rest-api-support.php',
440
+ 'WCML_Wpb_Vc' => $baseDir . '/compatibility/class-wcml-wpb-vc.php',
441
  'WCML_YITH_WCQV' => $baseDir . '/compatibility/class-wcml-yith-wcqv.php',
442
  'WCML_gravityforms' => $baseDir . '/compatibility/class-wcml-gravityforms.php',
443
  'WCML_wcExporter' => $baseDir . '/compatibility/class-wcml-wcexporter.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit700c2931447cea63ebf64beae8bdd7e5
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit700c2931447cea63ebf64beae8bdd7e5
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit700c2931447cea63ebf64beae8bdd7e5', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit700c2931447cea63ebf64beae8bdd7e5', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit09db18301760424c7dcc21b33162e94c
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit09db18301760424c7dcc21b33162e94c', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit09db18301760424c7dcc21b33162e94c', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit09db18301760424c7dcc21b33162e94c::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInit7553e033b450bd056d54dea34f8634ea {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit7553e033b450bd056d54dea34f8634ea {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit7553e033b450bd056d54dea34f8634ea', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit7553e033b450bd056d54dea34f8634ea', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInitc6092e313fbc70ad1c34def5310404b7 {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitc6092e313fbc70ad1c34def5310404b7', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitc6092e313fbc70ad1c34def5310404b7', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'C' =>
@@ -469,6 +469,7 @@ class ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5
469
  'WCML_WPSEO' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpseo.php',
470
  'WCML_Widgets' => __DIR__ . '/../..' . '/inc/class-wcml-widgets.php',
471
  'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
 
472
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
473
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
474
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
@@ -482,10 +483,10 @@ class ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5
482
  public static function getInitializer(ClassLoader $loader)
483
  {
484
  return \Closure::bind(function () use ($loader) {
485
- $loader->prefixLengthsPsr4 = ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5::$prefixLengthsPsr4;
486
- $loader->prefixDirsPsr4 = ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5::$prefixDirsPsr4;
487
- $loader->prefixesPsr0 = ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5::$prefixesPsr0;
488
- $loader->classMap = ComposerStaticInit700c2931447cea63ebf64beae8bdd7e5::$classMap;
489
 
490
  }, null, ClassLoader::class);
491
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit09db18301760424c7dcc21b33162e94c
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'C' =>
469
  'WCML_WPSEO' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpseo.php',
470
  'WCML_Widgets' => __DIR__ . '/../..' . '/inc/class-wcml-widgets.php',
471
  'WCML_WooCommerce_Rest_API_Support' => __DIR__ . '/../..' . '/inc/class-wcml-woocommerce-rest-api-support.php',
472
+ 'WCML_Wpb_Vc' => __DIR__ . '/../..' . '/compatibility/class-wcml-wpb-vc.php',
473
  'WCML_YITH_WCQV' => __DIR__ . '/../..' . '/compatibility/class-wcml-yith-wcqv.php',
474
  'WCML_gravityforms' => __DIR__ . '/../..' . '/compatibility/class-wcml-gravityforms.php',
475
  'WCML_wcExporter' => __DIR__ . '/../..' . '/compatibility/class-wcml-wcexporter.php',
483
  public static function getInitializer(ClassLoader $loader)
484
  {
485
  return \Closure::bind(function () use ($loader) {
486
+ $loader->prefixLengthsPsr4 = ComposerStaticInit09db18301760424c7dcc21b33162e94c::$prefixLengthsPsr4;
487
+ $loader->prefixDirsPsr4 = ComposerStaticInit09db18301760424c7dcc21b33162e94c::$prefixDirsPsr4;
488
+ $loader->prefixesPsr0 = ComposerStaticInit09db18301760424c7dcc21b33162e94c::$prefixesPsr0;
489
+ $loader->classMap = ComposerStaticInit09db18301760424c7dcc21b33162e94c::$classMap;
490
 
491
  }, null, ClassLoader::class);
492
  }
wpml-woocommerce.php CHANGED
@@ -8,7 +8,7 @@
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
  Tested up to: 4.9
11
- Version: 4.2.7.1
12
  WC requires at least: 2.1.0
13
  WC tested up to: 3.2.5
14
  */
@@ -17,7 +17,7 @@ if ( defined( 'WCML_VERSION' ) ) {
17
  return;
18
  }
19
 
20
- define( 'WCML_VERSION', '4.2.7.1' );
21
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
22
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
23
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
  Tested up to: 4.9
11
+ Version: 4.2.8
12
  WC requires at least: 2.1.0
13
  WC tested up to: 3.2.5
14
  */
17
  return;
18
  }
19
 
20
+ define( 'WCML_VERSION', '4.2.8' );
21
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
22
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
23
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );