WooCommerce Multilingual – run WooCommerce with WPML - Version 3.3.1

Version Description

  • Some strings were showing in the wrong language on the cart and checkout page.
  • Product category urls - in some cases the product category urls didnt work on sites with the default language different than English.
  • Products gallery images synchronization - sometimes, when synchronizing products "gallery images" and categories, the result was not updated correctly on the Troubleshooting page
  • Fixed issues related to WooCOmmerce Dynamic Pricing
  • Supoprt for translating WooCommerce 2.1+ endpoints
  • 'Continue Shopping' button pointing to the wrong url
  • Problem with short links
  • Fixed some issues with Table Rate Shipping
Download this release

Release Info

Developer mihaimihai
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 3.3.1
Comparing to
See all releases

Code changes from version 3.3 to 3.3.1

assets/css/management.css CHANGED
@@ -607,6 +607,7 @@ textarea[disabled] {
607
  .currency_value{
608
  float: left;
609
  margin-right: 3px;
 
610
  }
611
  .currency_value input[type=text]{
612
  width: 45px;
@@ -696,10 +697,11 @@ table.widefat.currency_table{
696
  .prod_image_show,.prod_image_hide,.prod_variations_show,.prod_variations_hide{
697
  cursor: pointer;
698
  }
 
699
  .wcml-error{
 
700
  color: red;
701
  display: inline-block;
702
- margin: 4px 0 0;
703
  }
704
  .troubleshoot_link_block{
705
  float: right;
@@ -863,8 +865,9 @@ table.widefat.currency_lang_table{
863
  overflow-y: visible;
864
  }
865
  .currency_table tr,
866
- .currency_lang_table tr{
867
- height: 59px;
 
868
  }
869
 
870
  .currency_table tr td{
@@ -879,9 +882,7 @@ table.widefat.currency_lang_table{
879
  padding-right: 0;
880
  padding-left: 0;
881
  }
882
- .currency_lang_table tr.default_currency{
883
- height: 60px;
884
- }
885
  .default_currency select{
886
  font-size: 10px;
887
  height: 24px;
@@ -910,6 +911,14 @@ table.widefat.currency_lang_table{
910
  height: 20px;
911
  line-height:20px;
912
  }
 
 
 
 
 
 
 
 
913
  /* Currency switcher*/
914
  #wcml_currencies_order{
915
  display: block;
607
  .currency_value{
608
  float: left;
609
  margin-right: 3px;
610
+
611
  }
612
  .currency_value input[type=text]{
613
  width: 45px;
697
  .prod_image_show,.prod_image_hide,.prod_variations_show,.prod_variations_hide{
698
  cursor: pointer;
699
  }
700
+ .currency_value .wcml-error,
701
  .wcml-error{
702
+ font-size: 10px;
703
  color: red;
704
  display: inline-block;
 
705
  }
706
  .troubleshoot_link_block{
707
  float: right;
865
  overflow-y: visible;
866
  }
867
  .currency_table tr,
868
+ .currency_lang_table tr,
869
+ .currency_lang_table tr.default_currency{
870
+ height: 64px;
871
  }
872
 
873
  .currency_table tr td{
882
  padding-right: 0;
883
  padding-left: 0;
884
  }
885
+
 
 
886
  .default_currency select{
887
  font-size: 10px;
888
  height: 24px;
911
  height: 20px;
912
  line-height:20px;
913
  }
914
+
915
+ .ext_rate,
916
+ .decimals_number,
917
+ .abstract_amount,
918
+ .currency_option_input{
919
+ width:50px;
920
+ }
921
+
922
  /* Currency switcher*/
923
  #wcml_currencies_order{
924
  display: block;
assets/js/scripts.js CHANGED
@@ -984,11 +984,22 @@ jQuery(document).ready(function($){
984
 
985
 
986
  $(document).on('click', '.wcml_currency_options_popup :submit', function(){
 
 
 
 
 
 
 
 
 
 
987
 
988
  $('.wcml_currency_options_popup :submit, .wcml_currency_options_popup :button').prop('disabled', true);
989
  var currency = $(this).data('currency');
990
 
991
  var ajaxLoader = $('<span class="spinner" style="position:absolute;margin-left:-30px;"></span>');
 
992
  ajaxLoader.show();
993
  $(this).parent().prepend(ajaxLoader);
994
 
@@ -1015,6 +1026,24 @@ jQuery(document).ready(function($){
1015
  })
1016
 
1017
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1018
  // expand|collapse for product images and product variations tables
1019
  $(document).on('click','.js-table-toggle',function(e){
1020
 
@@ -1091,7 +1120,7 @@ jQuery(document).ready(function($){
1091
  $(this).parent().addClass('on');
1092
  var index = $(this).closest('tr')[0].rowIndex;
1093
  $('.currency_languages select[rel="'+$(this).data('language')+'"]').append('<option value="'+$(this).data('currency')+'">'+$(this).data('currency')+'</option>');
1094
- update_currency_lang(1, $(this).data('language'), $(this).data('currency'), 0);
1095
  });
1096
 
1097
  $(document).on('click','.currency_languages a.off_btn',function(e){
@@ -1113,14 +1142,17 @@ jQuery(document).ready(function($){
1113
  var index = $(this).closest('tr')[0].rowIndex;
1114
 
1115
  if($('.currency_languages select[rel="'+$(this).data('language')+'"]').val() == $(this).data('currency')){
1116
- update_currency_lang(0,$(this).data('language'),$(this).data('currency'),1);
1117
  }else{
1118
- update_currency_lang(0,$(this).data('language'),$(this).data('currency'),0);
1119
  }
1120
  $('.currency_languages select[rel="'+$(this).data('language')+'"] option[value="'+$(this).data('currency')+'"]').remove();
1121
  });
1122
 
1123
- function update_currency_lang(value, lang, code, upd_def){
 
 
 
1124
  $.ajax({
1125
  type: 'post',
1126
  url: ajaxurl,
@@ -1135,6 +1167,9 @@ jQuery(document).ready(function($){
1135
  if(upd_def){
1136
  update_default_currency(lang,0);
1137
  }
 
 
 
1138
  }
1139
  });
1140
  }
984
 
985
 
986
  $(document).on('click', '.wcml_currency_options_popup :submit', function(){
987
+ var parent = $(this).closest('.wcml_currency_options_popup');
988
+
989
+ var chk_rate = check_on_numeric(parent,'.ext_rate');
990
+ var chk_deci = check_on_numeric(parent,'.decimals_number');
991
+ var chk_autosub = check_on_numeric(parent,'.abstract_amount');
992
+
993
+ if(chk_rate || chk_deci || chk_autosub){
994
+ return false;
995
+ }
996
+
997
 
998
  $('.wcml_currency_options_popup :submit, .wcml_currency_options_popup :button').prop('disabled', true);
999
  var currency = $(this).data('currency');
1000
 
1001
  var ajaxLoader = $('<span class="spinner" style="position:absolute;margin-left:-30px;"></span>');
1002
+
1003
  ajaxLoader.show();
1004
  $(this).parent().prepend(ajaxLoader);
1005
 
1026
  })
1027
 
1028
 
1029
+ function check_on_numeric(parent, elem){
1030
+ var messageContainer = $('<span class="wcml-error">');
1031
+
1032
+ if(!isNumber(parent.find(elem).val())){
1033
+ if(parent.find(elem).parent().find('.wcml-error').size() == 0){
1034
+ parent.find(elem).parent().append( messageContainer );
1035
+ messageContainer.text( parent.find(elem).data('message') );
1036
+ }
1037
+ return true;
1038
+ }else{
1039
+ if(parent.find(elem).parent().find('.wcml-error').size() > 0){
1040
+ parent.find(elem).parent().find('.wcml-error').remove();
1041
+ }
1042
+ return false;
1043
+ }
1044
+ }
1045
+
1046
+
1047
  // expand|collapse for product images and product variations tables
1048
  $(document).on('click','.js-table-toggle',function(e){
1049
 
1120
  $(this).parent().addClass('on');
1121
  var index = $(this).closest('tr')[0].rowIndex;
1122
  $('.currency_languages select[rel="'+$(this).data('language')+'"]').append('<option value="'+$(this).data('currency')+'">'+$(this).data('currency')+'</option>');
1123
+ update_currency_lang($(this),1,0);
1124
  });
1125
 
1126
  $(document).on('click','.currency_languages a.off_btn',function(e){
1142
  var index = $(this).closest('tr')[0].rowIndex;
1143
 
1144
  if($('.currency_languages select[rel="'+$(this).data('language')+'"]').val() == $(this).data('currency')){
1145
+ update_currency_lang($(this),0,1);
1146
  }else{
1147
+ update_currency_lang($(this),0,0);
1148
  }
1149
  $('.currency_languages select[rel="'+$(this).data('language')+'"] option[value="'+$(this).data('currency')+'"]').remove();
1150
  });
1151
 
1152
+ function update_currency_lang(elem, value, upd_def){
1153
+ $('input[name="general_options"]').attr('disabled','disabled');
1154
+ var lang = elem.data('language');
1155
+ var code = elem.data('currency');
1156
  $.ajax({
1157
  type: 'post',
1158
  url: ajaxurl,
1167
  if(upd_def){
1168
  update_default_currency(lang,0);
1169
  }
1170
+ },
1171
+ complete: function() {
1172
+ $('input[name="general_options"]').removeAttr('disabled');
1173
  }
1174
  });
1175
  }
compatibility/wc_dynamic_pricing.class.php CHANGED
@@ -4,31 +4,36 @@ class WCML_Dynamic_Pricing{
4
 
5
  function __construct(){
6
  if(!is_admin()){
7
- add_filter('init', array($this, 'filter_price'), 5);
8
  add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
  add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
  add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
  }
12
  }
13
 
14
- function filter_price(){
15
- if(class_exists('WC_Dynamic_Pricing_Simple_Membership')){
16
- $class = 'WC_Dynamic_Pricing_Simple_Membership';
17
- }elseif(class_exists('WC_Dynamic_Pricing_Simple_Category')){
18
- $class = 'WC_Dynamic_Pricing_Simple_Category';
19
- }elseif(class_exists('WC_Dynamic_Pricing_Simple_Group')){
20
- $class = 'WC_Dynamic_Pricing_Simple_Category';
21
- }
22
 
23
- $rules = $class::instance()->available_rulesets;
24
  if($rules){
25
  foreach($rules as $r_key=>$rule){
26
  if($rule['type'] == 'fixed_product'){
27
  $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
  }
29
  }
30
- $class::instance()->available_rulesets = $rules;
 
 
 
 
 
31
  }
 
 
32
  }
33
 
34
 
@@ -55,10 +60,12 @@ class WCML_Dynamic_Pricing{
55
 
56
 
57
  function dynamic_pricing_product_rules($rules){
58
- foreach($rules as $r_key=>$rule){
59
- foreach($rule['rules'] as $key=>$product_rule){
60
- if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
61
- $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
 
 
62
  }
63
  }
64
  }
4
 
5
  function __construct(){
6
  if(!is_admin()){
7
+ add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
  add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
  add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
  add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
  }
12
  }
13
 
14
+ function filter_price($modules){
15
+
16
+ foreach($modules as $mod_key=>$module){
17
+ if(isset($module->available_rulesets)){
18
+ $available_rulesets = $module->available_rulesets;
19
+ foreach($available_rulesets as $rule_key=>$available_ruleset){
20
+ $rules = $available_ruleset['rules'];
 
21
 
 
22
  if($rules){
23
  foreach($rules as $r_key=>$rule){
24
  if($rule['type'] == 'fixed_product'){
25
  $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
26
  }
27
  }
28
+ $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
29
+
30
+ }
31
+ }
32
+
33
+ }
34
  }
35
+
36
+ return $modules;
37
  }
38
 
39
 
60
 
61
 
62
  function dynamic_pricing_product_rules($rules){
63
+ if(is_array($rules)){
64
+ foreach($rules as $r_key=>$rule){
65
+ foreach($rule['rules'] as $key=>$product_rule){
66
+ if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
67
+ $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
68
+ }
69
  }
70
  }
71
  }
compatibility/wc_product_addons.class.php CHANGED
@@ -4,9 +4,10 @@ class WCML_Product_Addons{
4
 
5
  function __construct(){
6
 
7
- add_action('init', array($this, 'init'),9);
8
  add_filter('addons_product_terms',array($this,'addons_product_terms'));
9
  add_filter('product_addons_fields',array($this,'product_addons_filter'),10,2);
 
 
10
 
11
  global $pagenow;
12
  if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
@@ -16,12 +17,6 @@ class WCML_Product_Addons{
16
  add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
17
  }
18
 
19
- function init(){
20
- add_action('after_save_global_addons',array($this,'register_addons_strings'),10,2);
21
- add_action('after_update_product_addons',array($this,'register_addons_strings'),10,2);
22
- }
23
-
24
-
25
  function register_addons_strings($id,$addons){
26
  foreach($addons as $addon){
27
  //register name
4
 
5
  function __construct(){
6
 
 
7
  add_filter('addons_product_terms',array($this,'addons_product_terms'));
8
  add_filter('product_addons_fields',array($this,'product_addons_filter'),10,2);
9
+ add_action('after_save_global_addons',array($this,'register_addons_strings'),10,2);
10
+ add_action('after_update_product_addons',array($this,'register_addons_strings'),10,2);
11
 
12
  global $pagenow;
13
  if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
17
  add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
18
  }
19
 
 
 
 
 
 
 
20
  function register_addons_strings($id,$addons){
21
  foreach($addons as $addon){
22
  //register name
compatibility/wc_product_bundles.class.php CHANGED
@@ -5,10 +5,7 @@ class WCML_Product_Bundles{
5
  function __construct(){
6
  add_action('init', array($this, 'init'),9);
7
  add_action('wcml_gui_additional_box',array($this,'product_bundles_box'),10,3);
8
- }
9
 
10
- function init(){
11
- global $sitepress;
12
  add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
13
  add_action('wcml_extra_titles',array($this,'product_bundles_title'),10,1);
14
  add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,2);
@@ -17,6 +14,7 @@ class WCML_Product_Bundles{
17
  add_filter('wcml_update_cart_contents_lang_switch', array($this, 'cart_contents_bundle_update_lang_switch'), 10, 4);
18
  }
19
 
 
20
  // Sync Bundled product meta with translated values
21
  function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
22
  global $sitepress, $wpdb;
@@ -31,8 +29,9 @@ class WCML_Product_Bundles{
31
  $tr_ids[] = $tr_id;
32
 
33
  // Get original bundle settings
34
- $filter_variations = $custom_fields['filter_variations_'.$id][0] ?: 0;
35
  $filter_variations = $custom_fields['filter_variations_'.$id][0];
 
36
  $override_defaults = $custom_fields['override_defaults_'.$id][0];
37
  $bundle_quantity = $custom_fields['bundle_quantity_'.$id][0];
38
  $bundle_discount = $custom_fields['bundle_discount_'.$id][0];
@@ -41,6 +40,7 @@ class WCML_Product_Bundles{
41
  $product_title = $custom_fields['product_title_'.$id][0];
42
  $override_description = $custom_fields['override_description_'.$id][0];
43
  $product_description = $custom_fields['product_description_'.$id][0];
 
44
  $hide_filtered_variations = $custom_fields['hide_filtered_variations_'.$id][0];
45
  $visibility = $custom_fields['visibility_'.$id][0];
46
 
@@ -58,7 +58,9 @@ class WCML_Product_Bundles{
58
  delete_post_meta( $trnsl_product_id, 'visibility_'.$id );
59
 
60
  // Duplicate translated bundle settings
 
61
  update_post_meta( $trnsl_product_id, 'filter_variations_'.$tr_id, $filter_variations );
 
62
  update_post_meta( $trnsl_product_id, 'override_defaults_'.$tr_id, $override_defaults );
63
  update_post_meta( $trnsl_product_id, 'bundle_quantity_'.$tr_id, $bundle_quantity );
64
  update_post_meta( $trnsl_product_id, 'bundle_discount_'.$tr_id, $bundle_discount );
@@ -67,8 +69,9 @@ class WCML_Product_Bundles{
67
  update_post_meta( $trnsl_product_id, 'product_title_'.$tr_id, $product_title );
68
  update_post_meta( $trnsl_product_id, 'override_description_'.$tr_id, $override_description );
69
  update_post_meta( $trnsl_product_id, 'product_description_'.$tr_id, $product_description );
 
70
  update_post_meta( $trnsl_product_id, 'hide_filtered_variations_'.$tr_id, $hide_filtered_variations );
71
- update_post_meta( $trnsl_product_id, 'visibility_'.$tr_id, $hide_filtered_variations );
72
 
73
  }
74
 
@@ -78,6 +81,7 @@ class WCML_Product_Bundles{
78
  // Update _allowed_variations
79
  $tr_allowed_variations = array();
80
  $allowed_variations = maybe_unserialize(get_post_meta($original_product_id, '_allowed_variations', true));
 
81
  foreach($allowed_variations as $prod_id => $allowed_ids){
82
  $trans_prod_id = icl_object_id($prod_id, 'product', false, $lang);
83
  foreach($allowed_ids as $key => $var_id){
@@ -86,11 +90,14 @@ class WCML_Product_Bundles{
86
  }
87
  }
88
  update_post_meta($trnsl_product_id,'_allowed_variations',$tr_allowed_variations);
 
 
89
 
90
 
91
  // Update _bundle_defaults
92
  $tr_bundle_defaults = array();
93
  $bundle_defaults = maybe_unserialize(get_post_meta($original_product_id, '_bundle_defaults', true));
 
94
  foreach($bundle_defaults as $prod_id => $allowed_ids){
95
  $trans_prod_id = icl_object_id($prod_id, 'product', false, $lang);
96
  $tr_bundle_defaults[$trans_prod_id]=array();
@@ -100,7 +107,7 @@ class WCML_Product_Bundles{
100
  }
101
  }
102
  update_post_meta($trnsl_product_id,'_bundle_defaults',$tr_bundle_defaults);
103
-
104
  }
105
 
106
  // Update Bundle title and descritpion
5
  function __construct(){
6
  add_action('init', array($this, 'init'),9);
7
  add_action('wcml_gui_additional_box',array($this,'product_bundles_box'),10,3);
 
8
 
 
 
9
  add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
10
  add_action('wcml_extra_titles',array($this,'product_bundles_title'),10,1);
11
  add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,2);
14
  add_filter('wcml_update_cart_contents_lang_switch', array($this, 'cart_contents_bundle_update_lang_switch'), 10, 4);
15
  }
16
 
17
+
18
  // Sync Bundled product meta with translated values
19
  function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
20
  global $sitepress, $wpdb;
29
  $tr_ids[] = $tr_id;
30
 
31
  // Get original bundle settings
32
+ if(isset($custom_fields['filter_variations_'.$id][0]))
33
  $filter_variations = $custom_fields['filter_variations_'.$id][0];
34
+ if(isset($custom_fields['override_defaults_'.$id][0]))
35
  $override_defaults = $custom_fields['override_defaults_'.$id][0];
36
  $bundle_quantity = $custom_fields['bundle_quantity_'.$id][0];
37
  $bundle_discount = $custom_fields['bundle_discount_'.$id][0];
40
  $product_title = $custom_fields['product_title_'.$id][0];
41
  $override_description = $custom_fields['override_description_'.$id][0];
42
  $product_description = $custom_fields['product_description_'.$id][0];
43
+ if(isset($custom_fields['hide_filtered_variations_'.$id][0]))
44
  $hide_filtered_variations = $custom_fields['hide_filtered_variations_'.$id][0];
45
  $visibility = $custom_fields['visibility_'.$id][0];
46
 
58
  delete_post_meta( $trnsl_product_id, 'visibility_'.$id );
59
 
60
  // Duplicate translated bundle settings
61
+ if(isset($filter_variations))
62
  update_post_meta( $trnsl_product_id, 'filter_variations_'.$tr_id, $filter_variations );
63
+ if(isset($override_defaults))
64
  update_post_meta( $trnsl_product_id, 'override_defaults_'.$tr_id, $override_defaults );
65
  update_post_meta( $trnsl_product_id, 'bundle_quantity_'.$tr_id, $bundle_quantity );
66
  update_post_meta( $trnsl_product_id, 'bundle_discount_'.$tr_id, $bundle_discount );
69
  update_post_meta( $trnsl_product_id, 'product_title_'.$tr_id, $product_title );
70
  update_post_meta( $trnsl_product_id, 'override_description_'.$tr_id, $override_description );
71
  update_post_meta( $trnsl_product_id, 'product_description_'.$tr_id, $product_description );
72
+ if(isset($hide_filtered_variations))
73
  update_post_meta( $trnsl_product_id, 'hide_filtered_variations_'.$tr_id, $hide_filtered_variations );
74
+ update_post_meta( $trnsl_product_id, 'visibility_'.$tr_id, $visibility );
75
 
76
  }
77
 
81
  // Update _allowed_variations
82
  $tr_allowed_variations = array();
83
  $allowed_variations = maybe_unserialize(get_post_meta($original_product_id, '_allowed_variations', true));
84
+ if(is_array($allowed_variations)){
85
  foreach($allowed_variations as $prod_id => $allowed_ids){
86
  $trans_prod_id = icl_object_id($prod_id, 'product', false, $lang);
87
  foreach($allowed_ids as $key => $var_id){
90
  }
91
  }
92
  update_post_meta($trnsl_product_id,'_allowed_variations',$tr_allowed_variations);
93
+ }
94
+
95
 
96
 
97
  // Update _bundle_defaults
98
  $tr_bundle_defaults = array();
99
  $bundle_defaults = maybe_unserialize(get_post_meta($original_product_id, '_bundle_defaults', true));
100
+ if(is_array($bundle_defaults)){
101
  foreach($bundle_defaults as $prod_id => $allowed_ids){
102
  $trans_prod_id = icl_object_id($prod_id, 'product', false, $lang);
103
  $tr_bundle_defaults[$trans_prod_id]=array();
107
  }
108
  }
109
  update_post_meta($trnsl_product_id,'_bundle_defaults',$tr_bundle_defaults);
110
+ }
111
  }
112
 
113
  // Update Bundle title and descritpion
compatibility/wc_tab_manager.class.php CHANGED
@@ -23,7 +23,11 @@ class WCML_Tab_Manager{
23
  $trnsl_product_tabs = array();
24
  $i = 0;
25
  foreach($orig_prod_tabs as $key=>$orig_prod_tab){
26
-
 
 
 
 
27
  switch($orig_prod_tab['type']){
28
  case 'core':
29
  $default_language = $sitepress->get_default_language();
@@ -32,10 +36,10 @@ class WCML_Tab_Manager{
32
  if(isset($data['_product_tabs_'.$lang])){
33
  $title = $data['_product_tabs_'.$lang]['core_title'][$orig_prod_tab['id']];
34
  $heading = $data['_product_tabs_'.$lang]['core_heading'][$orig_prod_tab['id']];
35
- }else if(isset($_POST['product_tab_title'][$orig_prod_tab['position']])){
36
- $title = $_POST['product_tab_title'][$orig_prod_tab['position']];
37
- }else if(isset($_POST['product_tab_heading'][$orig_prod_tab['position']])){
38
- $heading = $_POST['product_tab_heading'][$orig_prod_tab['position']];
39
  }
40
 
41
  if($default_language != $lang){
@@ -77,18 +81,18 @@ class WCML_Tab_Manager{
77
  $title = $data['_product_tabs_'.$lang]['title'][$i];
78
  $content = $data['_product_tabs_'.$lang]['content'][$i];
79
  }else{
80
- if($_POST['product_tab_id'][$orig_prod_tab['position']]){
81
- $tab_id = $_POST['product_tab_id'][$orig_prod_tab['position']];
82
- }
83
 
84
- if(isset($_POST['product_tab_title'][$orig_prod_tab['position']])){
85
- $title = $_POST['product_tab_title'][$orig_prod_tab['position']];
86
  }else{
87
  $title = '';
88
  }
89
 
90
- if(isset($_POST['product_tab_content'][$orig_prod_tab['position']])){
91
- $content = $_POST['product_tab_content'][$orig_prod_tab['position']];
92
  }else{
93
  $content = '';
94
  }
23
  $trnsl_product_tabs = array();
24
  $i = 0;
25
  foreach($orig_prod_tabs as $key=>$orig_prod_tab){
26
+ foreach($_POST['product_tab_id'] as $tab_key=>$prod_tab_id){
27
+ if($prod_tab_id == $orig_prod_tab['id']){
28
+ $tab_position_id = $tab_key;
29
+ }
30
+ }
31
  switch($orig_prod_tab['type']){
32
  case 'core':
33
  $default_language = $sitepress->get_default_language();
36
  if(isset($data['_product_tabs_'.$lang])){
37
  $title = $data['_product_tabs_'.$lang]['core_title'][$orig_prod_tab['id']];
38
  $heading = $data['_product_tabs_'.$lang]['core_heading'][$orig_prod_tab['id']];
39
+ }else if(isset($_POST['product_tab_title'][$tab_position_id])){
40
+ $title = $_POST['product_tab_title'][$tab_position_id];
41
+ }else if(isset($_POST['product_tab_heading'][$tab_position_id])){
42
+ $heading = $_POST['product_tab_heading'][$tab_position_id];
43
  }
44
 
45
  if($default_language != $lang){
81
  $title = $data['_product_tabs_'.$lang]['title'][$i];
82
  $content = $data['_product_tabs_'.$lang]['content'][$i];
83
  }else{
84
+ // if($_POST['product_tab_id'][$orig_prod_tab['position']]){
85
+ // $tab_id = $_POST['product_tab_id'][$orig_prod_tab['position']];
86
+ // }
87
 
88
+ if(isset($_POST['product_tab_title'][$tab_position_id])){
89
+ $title = $_POST['product_tab_title'][$tab_position_id];
90
  }else{
91
  $title = '';
92
  }
93
 
94
+ if(isset($_POST['product_tab_content'][$tab_position_id])){
95
+ $content = $_POST['product_tab_content'][$tab_position_id];
96
  }else{
97
  $content = '';
98
  }
inc/ajax-setup.class.php CHANGED
@@ -16,18 +16,34 @@ class WCML_Ajax_Setup{
16
  }
17
 
18
  add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
 
 
 
 
 
 
19
  add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
20
  add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
21
 
22
  }
23
 
24
- function filter_woocommerce_order_review(){
25
  global $woocommerce;
26
  unload_textdomain('woocommerce');
27
  $woocommerce->load_plugin_textdomain();
28
 
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
31
  function filter_woocommerce_ajax_params($woocommerce_params){
32
  global $sitepress, $post;
33
  $value = array();
@@ -37,7 +53,7 @@ class WCML_Ajax_Setup{
37
  $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
38
  $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
39
  }
40
-
41
  if(!isset($post->ID)){
42
  return $value;
43
  }
16
  }
17
 
18
  add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
19
+
20
+ add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
21
+ add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
22
+ add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
23
+ add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
24
+
25
  add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
26
  add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
27
 
28
  }
29
 
30
+ function filter_woocommerce_order_review(){
31
  global $woocommerce;
32
  unload_textdomain('woocommerce');
33
  $woocommerce->load_plugin_textdomain();
34
 
35
  }
36
 
37
+ function add_language_parameter_to_ajax_url($woocommerce_params){
38
+ global $sitepress;
39
+
40
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
41
+ $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
42
+ }
43
+
44
+ return $woocommerce_params;
45
+ }
46
+
47
  function filter_woocommerce_ajax_params($woocommerce_params){
48
  global $sitepress, $post;
49
  $value = array();
53
  $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
54
  $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
55
  }
56
+
57
  if(!isset($post->ID)){
58
  return $value;
59
  }
inc/emails.class.php CHANGED
@@ -11,13 +11,14 @@ class WCML_Emails{
11
  function init(){
12
  //wrappers for email's header
13
  if(is_admin() && !defined( 'DOING_AJAX' )){
14
- add_action('woocommerce_order_status_completed_notification', array($this, 'email_heading_completed'),9);
15
- add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'email_heading_processing' ) );
16
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'email_heading_processing' ) );
17
  add_action('woocommerce_new_customer_note_notification', array($this, 'email_heading_note'),9);
18
  add_action('woocommerce_order_status_changed', array($this, 'comments_language'),10);
19
  }
20
 
 
 
 
21
  //wrappers for email's body
22
  add_action('woocommerce_before_resend_order_emails', array($this, 'email_header'));
23
  add_action('woocommerce_after_resend_order_email', array($this, 'email_footer'));
@@ -174,9 +175,8 @@ class WCML_Emails{
174
  if($subject)
175
  $woocommerce->mailer()->emails['WC_Email_New_Order']->subject = icl_t($subject[0]->context,'[woocommerce_new_order_settings]subject',$subject[0]->value);
176
 
177
-
178
-
179
  $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
 
180
  $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
181
  }
182
  $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
@@ -224,7 +224,6 @@ class WCML_Emails{
224
 
225
  function email_instructions($order, $sent_to_admin, $plain_text = false){
226
  global $woocommerce_wpml;
227
- $this->refresh_email_lang($order->id);
228
  $woocommerce_wpml->strings->translate_payment_instructions($order->payment_method);
229
  }
230
 
11
  function init(){
12
  //wrappers for email's header
13
  if(is_admin() && !defined( 'DOING_AJAX' )){
14
+ add_action('woocommerce_order_status_completed_notification', array($this, 'email_heading_completed'),9);
 
 
15
  add_action('woocommerce_new_customer_note_notification', array($this, 'email_heading_note'),9);
16
  add_action('woocommerce_order_status_changed', array($this, 'comments_language'),10);
17
  }
18
 
19
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'email_heading_processing' ) );
20
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'email_heading_processing' ) );
21
+
22
  //wrappers for email's body
23
  add_action('woocommerce_before_resend_order_emails', array($this, 'email_header'));
24
  add_action('woocommerce_after_resend_order_email', array($this, 'email_footer'));
175
  if($subject)
176
  $woocommerce->mailer()->emails['WC_Email_New_Order']->subject = icl_t($subject[0]->context,'[woocommerce_new_order_settings]subject',$subject[0]->value);
177
 
 
 
178
  $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
179
+
180
  $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
181
  }
182
  $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
224
 
225
  function email_instructions($order, $sent_to_admin, $plain_text = false){
226
  global $woocommerce_wpml;
 
227
  $woocommerce_wpml->strings->translate_payment_instructions($order->payment_method);
228
  }
229
 
inc/functions-troubleshooting.class.php CHANGED
@@ -13,6 +13,7 @@ class WCML_Troubleshooting{
13
  add_action('wp_ajax_trbl_gallery_images', array($this,'trbl_gallery_images'));
14
  add_action('wp_ajax_trbl_update_count', array($this,'trbl_update_count'));
15
  add_action('wp_ajax_trbl_sync_categories', array($this,'trbl_sync_categories'));
 
16
 
17
  }
18
 
@@ -49,10 +50,26 @@ class WCML_Troubleshooting{
49
  return $get_products_count;
50
  }
51
 
 
 
 
 
 
 
 
 
 
 
 
52
  function wcml_count_product_categories(){
53
  global $wpdb;
54
- $get_product_categories_count = $wpdb->get_var("SELECT count(t.term_taxonomy_id) FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL");
55
- return $get_product_categories_count;
 
 
 
 
 
56
  }
57
 
58
 
@@ -118,7 +135,10 @@ class WCML_Troubleshooting{
118
  $all_products = $wpdb->get_results($wpdb->prepare("SELECT p.* FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL ORDER BY p.ID LIMIT %d,5",$page*5));
119
 
120
  foreach($all_products as $product){
 
121
  $woocommerce_wpml->products->sync_product_gallery($product->ID);
 
 
122
  }
123
 
124
  echo 1;
@@ -139,6 +159,8 @@ class WCML_Troubleshooting{
139
  $all_categories = $wpdb->get_results($wpdb->prepare("SELECT t.term_taxonomy_id,t.term_id FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL ORDER BY t.term_taxonomy_id LIMIT %d,5",$page*5));
140
 
141
  foreach($all_categories as $category){
 
 
142
  $trid = $sitepress->get_element_trid($category->term_taxonomy_id,'tax_product_cat');
143
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
144
  $type = get_woocommerce_term_meta( $category->term_id, 'display_type',true);
@@ -149,6 +171,7 @@ class WCML_Troubleshooting{
149
  update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', icl_object_id($thumbnail_id,'attachment',true,$translation->language_code) );
150
  }
151
  }
 
152
 
153
  }
154
 
@@ -159,4 +182,47 @@ class WCML_Troubleshooting{
159
  }
160
 
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  }
13
  add_action('wp_ajax_trbl_gallery_images', array($this,'trbl_gallery_images'));
14
  add_action('wp_ajax_trbl_update_count', array($this,'trbl_update_count'));
15
  add_action('wp_ajax_trbl_sync_categories', array($this,'trbl_sync_categories'));
16
+ add_action('wp_ajax_trbl_duplicate_terms', array($this,'trbl_duplicate_terms'));
17
 
18
  }
19
 
50
  return $get_products_count;
51
  }
52
 
53
+ function wcml_count_products_for_gallery_sync(){
54
+ global $wpdb;
55
+ $all_products = $wpdb->get_results("SELECT p.ID FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL");
56
+ foreach($all_products as $key=>$product){
57
+ if(get_post_meta($product->ID,'gallery_sync',true)){
58
+ unset($all_products[$key]);
59
+ }
60
+ }
61
+ return count($all_products);
62
+ }
63
+
64
  function wcml_count_product_categories(){
65
  global $wpdb;
66
+ $get_product_categories = $wpdb->get_results("SELECT t.term_taxonomy_id FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL");
67
+ foreach($get_product_categories as $key=>$get_product_category){
68
+ if(get_option('wcml_sync_category_'.$get_product_category->term_taxonomy_id)){
69
+ unset($get_product_categories[$key]);
70
+ }
71
+ }
72
+ return count($get_product_categories);
73
  }
74
 
75
 
135
  $all_products = $wpdb->get_results($wpdb->prepare("SELECT p.* FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL ORDER BY p.ID LIMIT %d,5",$page*5));
136
 
137
  foreach($all_products as $product){
138
+ if(!get_post_meta($product->ID,'gallery_sync',true)){
139
  $woocommerce_wpml->products->sync_product_gallery($product->ID);
140
+ add_post_meta($product->ID,'gallery_sync',true);
141
+ }
142
  }
143
 
144
  echo 1;
159
  $all_categories = $wpdb->get_results($wpdb->prepare("SELECT t.term_taxonomy_id,t.term_id FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL ORDER BY t.term_taxonomy_id LIMIT %d,5",$page*5));
160
 
161
  foreach($all_categories as $category){
162
+ if(!get_option('wcml_sync_category_'.$category->term_taxonomy_id)){
163
+ add_option('wcml_sync_category_'.$category->term_taxonomy_id,true);
164
  $trid = $sitepress->get_element_trid($category->term_taxonomy_id,'tax_product_cat');
165
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
166
  $type = get_woocommerce_term_meta( $category->term_id, 'display_type',true);
171
  update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', icl_object_id($thumbnail_id,'attachment',true,$translation->language_code) );
172
  }
173
  }
174
+ }
175
 
176
  }
177
 
182
  }
183
 
184
 
185
+ function trbl_duplicate_terms(){
186
+ if(!wp_verify_nonce($_REQUEST['wcml_nonce'], 'trbl_duplicate_terms')){
187
+ die('Invalid nonce');
188
+ }
189
+ global $sitepress;
190
+
191
+ $attr = isset($_POST['attr'])?$_POST['attr']:false;
192
+
193
+ $terms = get_terms($attr,'hide_empty=0');
194
+ $i = 0;
195
+ $languages = $sitepress->get_active_languages();
196
+ foreach($terms as $term){
197
+ foreach($languages as $language){
198
+ $tr_id = icl_object_id($term->term_id, $attr, false, $language['code']);
199
+
200
+ if(is_null($tr_id)){
201
+ $term_args = array();
202
+ // hierarchy - parents
203
+ if ( is_taxonomy_hierarchical( $attr ) ) {
204
+ // fix hierarchy
205
+ if ( $term->parent ) {
206
+ $original_parent_translated = icl_object_id( $term->parent, $attr, false, $language['code'] );
207
+ if ( $original_parent_translated ) {
208
+ $term_args[ 'parent' ] = $original_parent_translated;
209
+ }
210
+ }
211
+ }
212
+
213
+ $new_term = wp_insert_term( $term->name.' @'.$language['code'], $attr, $term_args );
214
+ if ( $new_term && !is_wp_error( $new_term ) ) {
215
+ $tt_id = $sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $attr );
216
+ $sitepress->set_element_language_details( $new_term[ 'term_taxonomy_id' ], 'tax_' . $attr, $tt_id, $language['code'] );
217
+ }
218
+ }
219
+ }
220
+
221
+ }
222
+
223
+ echo 1;
224
+
225
+ die();
226
+ }
227
+
228
  }
inc/missing-php-functions.php CHANGED
@@ -38,7 +38,7 @@ if (get_magic_quotes_gpc()) {
38
  add_action('plugins_loaded', 'wcml_check_wpml_is_ajax');
39
 
40
  function wcml_check_wpml_is_ajax(){
41
- if(version_compare(preg_replace('#-(.+)$#', '', ICL_SITEPRESS_VERSION), '3.1.5', '<')){
42
 
43
  function wpml_is_ajax() {
44
  if ( defined( 'DOING_AJAX' ) ) {
38
  add_action('plugins_loaded', 'wcml_check_wpml_is_ajax');
39
 
40
  function wcml_check_wpml_is_ajax(){
41
+ if(defined('ICL_SITEPRESS_VERSION') && version_compare(preg_replace('#-(.+)$#', '', ICL_SITEPRESS_VERSION), '3.1.5', '<')){
42
 
43
  function wpml_is_ajax() {
44
  if ( defined( 'DOING_AJAX' ) ) {
inc/multi-currency-support.class.php CHANGED
@@ -353,7 +353,7 @@ class WCML_Multi_Currency_Support{
353
  function currency_options_wc_integration(){
354
  global $woocommerce_wpml;
355
 
356
- if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && empty($_GET['tab'])){
357
 
358
  wp_enqueue_style('wcml_wc', WCML_PLUGIN_URL . '/assets/css/wcml-wc-integration.css', array(), WCML_VERSION);
359
 
@@ -1073,7 +1073,12 @@ class WCML_Multi_Currency_Support{
1073
  function currency_switcher_shortcode($atts){
1074
  extract( shortcode_atts( array(), $atts ) );
1075
 
 
1076
  $this->currency_switcher($atts);
 
 
 
 
1077
  }
1078
 
1079
  function currency_switcher($args = array()){
353
  function currency_options_wc_integration(){
354
  global $woocommerce_wpml;
355
 
356
+ if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT && count($this->currencies) > 1 && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && (!isset($_GET['tab']) || (isset($_GET['tab']) && $_GET['tab'] == 'general'))){
357
 
358
  wp_enqueue_style('wcml_wc', WCML_PLUGIN_URL . '/assets/css/wcml-wc-integration.css', array(), WCML_VERSION);
359
 
1073
  function currency_switcher_shortcode($atts){
1074
  extract( shortcode_atts( array(), $atts ) );
1075
 
1076
+ ob_start();
1077
  $this->currency_switcher($atts);
1078
+ $html = ob_get_contents();
1079
+ ob_end_clean();
1080
+
1081
+ return $html;
1082
  }
1083
 
1084
  function currency_switcher($args = array()){
inc/products.class.php CHANGED
@@ -10,7 +10,7 @@ class WCML_Products{
10
 
11
  add_action('init', array($this, 'init'));
12
  add_action('init', array($this, 'wc_cart_widget_actions'));
13
- add_action('init', array($this, 'set_price_config'), 16); // After TM parses wpml-config.xml
14
 
15
  //add action for coupons data from WC_Coupon construct
16
  add_action('woocommerce_coupon_loaded',array($this,'wcml_coupon_loaded'));
@@ -105,6 +105,12 @@ class WCML_Products{
105
  require WPSEO_PATH . 'admin/class-metabox.php';
106
  }
107
 
 
 
 
 
 
 
108
  }
109
 
110
  function hide_multilingual_content_setup_box(){
@@ -697,6 +703,7 @@ class WCML_Products{
697
  }
698
 
699
  foreach ($all_meta as $key => $meta) {
 
700
  if(isset($settings['translation-management']['custom_fields_translation'][$key]) && $settings['translation-management']['custom_fields_translation'][$key] == 0){
701
  continue;
702
  }
@@ -1405,9 +1412,12 @@ class WCML_Products{
1405
  $default_language = $sitepress->get_default_language();
1406
  $current_language = $sitepress->get_current_language();
1407
  $duplicated_post_id = icl_object_id($post_id, 'product', false, $default_language);
 
1408
 
 
1409
  //sync product gallery
1410
  $this->sync_product_gallery($duplicated_post_id);
 
1411
 
1412
  //trnsl_interface option
1413
  if (!$woocommerce_wpml->settings['trnsl_interface'] && $default_language != $current_language) {
@@ -1478,10 +1488,6 @@ class WCML_Products{
1478
  // Remove filter to avoid double sync
1479
  remove_action('save_post', array($this, 'sync_post_action'), 11, 2);
1480
 
1481
- //media sync
1482
- update_post_meta($post_id, '_wpml_media_duplicate', 1);
1483
- update_post_meta($post_id, '_wpml_media_featured', 1);
1484
-
1485
  // pick posts to sync
1486
  $posts = array();
1487
  $translations = $sitepress->get_element_translations($language_details->trid, 'post_product');
@@ -1501,6 +1507,11 @@ class WCML_Products{
1501
  // Filter upsell products, crosell products and default attributes for translations
1502
  $this->duplicate_product_post_meta($duplicated_post_id,$post_id);
1503
 
 
 
 
 
 
1504
  //sync product parent
1505
  $tr_parent_id = icl_object_id(wp_get_post_parent_id($duplicated_post_id),'product',false,$lang);
1506
  $wpdb->update(
@@ -2534,7 +2545,7 @@ class WCML_Products{
2534
  }
2535
 
2536
  if(!is_null($tr_product_id)){
2537
- $cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', array(), $cart->cart_contents[$key]['product_id'], $cart->cart_contents[$key]['variation_id']);
2538
  $new_key = $woocommerce->cart->generate_cart_id( $cart->cart_contents[$key]['product_id'], $cart->cart_contents[$key]['variation_id'], $cart->cart_contents[$key]['variation'], $cart_item_data );
2539
  $cart->cart_contents = apply_filters('wcml_update_cart_contents_lang_switch',$cart->cart_contents,$key, $new_key,$current_language);
2540
  $new_cart_data[$new_key] = $cart->cart_contents[$key];
@@ -2582,6 +2593,17 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2582
  }
2583
  }
2584
 
 
 
 
 
 
 
 
 
 
 
 
2585
  function wcml_coupon_loaded($coupons_data){
2586
  global $sitepress;
2587
 
@@ -2606,18 +2628,21 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2606
  }
2607
 
2608
  foreach($coupons_data->product_categories as $cat_id){
2609
- $trid = $sitepress->get_element_trid($cat_id,'tax_product_cat');
 
2610
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
 
2611
  foreach($translations as $translation){
2612
- $product_categories_ids[] = $translation->element_id;
2613
  }
2614
  }
2615
 
2616
  foreach($coupons_data->exclude_product_categories as $cat_id){
2617
- $trid = $sitepress->get_element_trid($cat_id,'tax_product_cat');
 
2618
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
2619
  foreach($translations as $translation){
2620
- $exclude_product_categories_ids[] = $translation->element_id;
2621
  }
2622
  }
2623
 
@@ -2637,6 +2662,7 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2637
  foreach($all_products_taxonomies as $tax_key => $tax){
2638
  if($tax_key == 'product_type') continue;
2639
  $sitepress_settings["translation-management"]["taxonomies_readonly_config"][$tax_key] = 1;
 
2640
  $sitepress_settings["taxonomies_sync_option"][$tax_key] = 1;
2641
  }
2642
  $sitepress->save_settings($sitepress_settings);
@@ -2754,4 +2780,33 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2754
  }
2755
  }
2756
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2757
  }
10
 
11
  add_action('init', array($this, 'init'));
12
  add_action('init', array($this, 'wc_cart_widget_actions'));
13
+ add_action('init', array($this, 'set_price_config'), 9999); // After TM parses wpml-config.xml
14
 
15
  //add action for coupons data from WC_Coupon construct
16
  add_action('woocommerce_coupon_loaded',array($this,'wcml_coupon_loaded'));
105
  require WPSEO_PATH . 'admin/class-metabox.php';
106
  }
107
 
108
+ //update icl_translation table after change default language
109
+ add_action('icl_after_set_default_language',array($this,'after_set_default_language'),10,2);
110
+
111
+ // Override cached widget id
112
+ add_filter('woocommerce_cached_widget_id', array($this, 'override_cached_widget_id'));
113
+
114
  }
115
 
116
  function hide_multilingual_content_setup_box(){
703
  }
704
 
705
  foreach ($all_meta as $key => $meta) {
706
+ if ( in_array( $key, $this->yoast_seo_fields ) ) continue;
707
  if(isset($settings['translation-management']['custom_fields_translation'][$key]) && $settings['translation-management']['custom_fields_translation'][$key] == 0){
708
  continue;
709
  }
1412
  $default_language = $sitepress->get_default_language();
1413
  $current_language = $sitepress->get_current_language();
1414
  $duplicated_post_id = icl_object_id($post_id, 'product', false, $default_language);
1415
+ $wpml_media_options = maybe_unserialize(get_option('_wpml_media'));
1416
 
1417
+ if($wpml_media_options['new_content_settings']['duplicate_media']){
1418
  //sync product gallery
1419
  $this->sync_product_gallery($duplicated_post_id);
1420
+ }
1421
 
1422
  //trnsl_interface option
1423
  if (!$woocommerce_wpml->settings['trnsl_interface'] && $default_language != $current_language) {
1488
  // Remove filter to avoid double sync
1489
  remove_action('save_post', array($this, 'sync_post_action'), 11, 2);
1490
 
 
 
 
 
1491
  // pick posts to sync
1492
  $posts = array();
1493
  $translations = $sitepress->get_element_translations($language_details->trid, 'post_product');
1507
  // Filter upsell products, crosell products and default attributes for translations
1508
  $this->duplicate_product_post_meta($duplicated_post_id,$post_id);
1509
 
1510
+ if($wpml_media_options['new_content_settings']['duplicate_featured']){
1511
+ //sync feature image
1512
+ $this->sync_thumbnail_id($duplicated_post_id,$post_id, $lang);
1513
+ }
1514
+
1515
  //sync product parent
1516
  $tr_parent_id = icl_object_id(wp_get_post_parent_id($duplicated_post_id),'product',false,$lang);
1517
  $wpdb->update(
2545
  }
2546
 
2547
  if(!is_null($tr_product_id)){
2548
+ $cart_item_data = $this->get_cart_item_data_from_cart($cart->cart_contents[$key]);
2549
  $new_key = $woocommerce->cart->generate_cart_id( $cart->cart_contents[$key]['product_id'], $cart->cart_contents[$key]['variation_id'], $cart->cart_contents[$key]['variation'], $cart_item_data );
2550
  $cart->cart_contents = apply_filters('wcml_update_cart_contents_lang_switch',$cart->cart_contents,$key, $new_key,$current_language);
2551
  $new_cart_data[$new_key] = $cart->cart_contents[$key];
2593
  }
2594
  }
2595
 
2596
+ //get cart_item_data from existing cart array ( from session )
2597
+ function get_cart_item_data_from_cart($cart_contents){
2598
+ unset($cart_contents['product_id']);
2599
+ unset($cart_contents['variation_id']);
2600
+ unset($cart_contents['variation']);
2601
+ unset($cart_contents['quantity']);
2602
+ unset($cart_contents['data']);
2603
+
2604
+ return $cart_contents;
2605
+ }
2606
+
2607
  function wcml_coupon_loaded($coupons_data){
2608
  global $sitepress;
2609
 
2628
  }
2629
 
2630
  foreach($coupons_data->product_categories as $cat_id){
2631
+ $term = get_term($cat_id,'product_cat');
2632
+ $trid = $sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
2633
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
2634
+
2635
  foreach($translations as $translation){
2636
+ $product_categories_ids[] = $translation->term_id;
2637
  }
2638
  }
2639
 
2640
  foreach($coupons_data->exclude_product_categories as $cat_id){
2641
+ $term = get_term($cat_id,'product_cat');
2642
+ $trid = $sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
2643
  $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
2644
  foreach($translations as $translation){
2645
+ $exclude_product_categories_ids[] = $translation->term_id;
2646
  }
2647
  }
2648
 
2662
  foreach($all_products_taxonomies as $tax_key => $tax){
2663
  if($tax_key == 'product_type') continue;
2664
  $sitepress_settings["translation-management"]["taxonomies_readonly_config"][$tax_key] = 1;
2665
+ $iclTranslationManagement->settings['taxonomies_readonly_config'][$tax_key] = 1;
2666
  $sitepress_settings["taxonomies_sync_option"][$tax_key] = 1;
2667
  }
2668
  $sitepress->save_settings($sitepress_settings);
2780
  }
2781
  }
2782
 
2783
+
2784
+ function after_set_default_language( $code, $previous_code ){
2785
+ global $wpdb;
2786
+
2787
+ $wpdb->update(
2788
+ $wpdb->prefix.'icl_translations',
2789
+ array(
2790
+ 'source_language_code' => $code
2791
+ ),
2792
+ array(
2793
+ 'language_code' => $previous_code,
2794
+ 'element_type' => 'post_product'
2795
+ )
2796
+ );
2797
+
2798
+ //Use query to set source_language_code to NULL
2799
+ $wpdb->query("UPDATE {$wpdb->prefix}icl_translations SET source_language_code = NULL WHERE language_code = '".$code."' AND element_type = 'post_product'" );
2800
+
2801
+ }
2802
+
2803
+
2804
+ function override_cached_widget_id($widget_id){
2805
+
2806
+ if (defined('ICL_LANGUAGE_CODE')){
2807
+ $widget_id .= ':' . ICL_LANGUAGE_CODE;
2808
+ }
2809
+ return $widget_id;
2810
+ }
2811
+
2812
  }
inc/store-pages.class.php CHANGED
@@ -22,7 +22,7 @@ class WCML_Store_Pages{
22
  }
23
 
24
  // table rate shipping support
25
- if(defined('TABLE_RATE_SHIPPING_VERSION') && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
26
  add_filter('woocommerce_table_rate_query_rates_args', array($this, 'default_shipping_class_id'));
27
  }
28
 
@@ -71,8 +71,10 @@ class WCML_Store_Pages{
71
 
72
  $args['shipping_class_id'] = icl_object_id($args['shipping_class_id'], 'product_shipping_class', false, $sitepress->get_default_language());
73
 
 
74
  // use unfiltred cart price to compare against limits of different shipping methods
75
  $args['price'] = $woocommerce_wpml->multi_currency->unconvert_price_amount($args['price']);
 
76
 
77
  }
78
 
22
  }
23
 
24
  // table rate shipping support
25
+ if(defined('TABLE_RATE_SHIPPING_VERSION')){
26
  add_filter('woocommerce_table_rate_query_rates_args', array($this, 'default_shipping_class_id'));
27
  }
28
 
71
 
72
  $args['shipping_class_id'] = icl_object_id($args['shipping_class_id'], 'product_shipping_class', false, $sitepress->get_default_language());
73
 
74
+ if($woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
75
  // use unfiltred cart price to compare against limits of different shipping methods
76
  $args['price'] = $woocommerce_wpml->multi_currency->unconvert_price_amount($args['price']);
77
+ }
78
 
79
  }
80
 
inc/terms.class.php CHANGED
@@ -19,8 +19,10 @@ class WCML_Terms{
19
 
20
  add_action('updated_woocommerce_term_meta',array($this,'sync_term_order'), 100,4);
21
 
22
- add_filter('option_rewrite_rules', array($this, 'rewrite_rules_filter'), 3, 1); // high priority
23
 
 
 
24
  add_filter('term_link', array($this, 'translate_category_base'), 0, 3); // high priority
25
  //add_filter('term_link', array($this, 'translate_brand_link'), 10, 3);
26
 
@@ -74,9 +76,52 @@ class WCML_Terms{
74
  }
75
  }
76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  function rewrite_rules_filter($value){
78
  global $sitepress, $sitepress_settings, $wpdb, $wp_taxonomies,$woocommerce;
79
 
 
 
 
 
80
  $strings_language = $sitepress_settings['st']['strings_language'];
81
 
82
  if($sitepress->get_current_language() != $strings_language){
@@ -95,7 +140,7 @@ class WCML_Terms{
95
 
96
  $taxonomy_obj = get_taxonomy($taxonomy);
97
  $slug = isset($taxonomy_obj->rewrite['slug']) ? trim($taxonomy_obj->rewrite['slug'],'/') : false;
98
-
99
  if($slug && $sitepress->get_current_language() != $strings_language){
100
 
101
  $slug_translation = $wpdb->get_var($wpdb->prepare("
@@ -116,16 +161,17 @@ class WCML_Terms{
116
 
117
  }
118
 
 
 
119
  if($slug_translation){
120
 
121
  $buff_value = array();
122
  foreach((array)$value as $k=>$v){
123
 
124
- if($slug != $slug_translation){
125
- if(preg_match('#^[^/]*/?' . $slug . '/#', $k) && $slug != $slug_translation){
126
  $k = preg_replace('#^([^/]*)(/?)' . $slug . '/#', '$1$2' . $slug_translation . '/' , $k);
127
  }
128
- }
129
 
130
  $buff_value[$k] = $v;
131
 
@@ -135,7 +181,7 @@ class WCML_Terms{
135
  unset($buff_value);
136
 
137
  }
138
-
139
  }
140
 
141
  }
@@ -194,9 +240,44 @@ class WCML_Terms{
194
 
195
  }
196
 
197
- return $value;
198
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
 
202
  function _switch_wc_locale(){
19
 
20
  add_action('updated_woocommerce_term_meta',array($this,'sync_term_order'), 100,4);
21
 
22
+ add_filter('pre_update_option_rewrite_rules', array($this, 'pre_update_rewrite_rules'), 1, 1); // high priority
23
 
24
+ remove_filter('option_rewrite_rules', array('WPML_Slug_Translation', 'rewrite_rules_filter'), 1, 1); //remove filter from WPML and use WCML filter first
25
+ add_filter('option_rewrite_rules', array($this, 'rewrite_rules_filter'), 3, 1); // high priority
26
  add_filter('term_link', array($this, 'translate_category_base'), 0, 3); // high priority
27
  //add_filter('term_link', array($this, 'translate_brand_link'), 10, 3);
28
 
76
  }
77
  }
78
 
79
+ function pre_update_rewrite_rules($value){
80
+ global $sitepress, $sitepress_settings, $woocommerce, $woocommerce_wpml;
81
+
82
+ // force saving in strings language
83
+ // covers the case os using the default product category and tag bases and a default language that's not English
84
+ $strings_language = $sitepress_settings['st']['strings_language'];
85
+ if($sitepress->get_current_language() != $strings_language){
86
+
87
+ $permalinks = get_option( 'woocommerce_permalinks' );
88
+ if(empty($permalinks['category_base'])){
89
+ remove_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
90
+ $base_translated = _x( 'product-category', 'slug', 'woocommerce' );
91
+ add_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
92
+ $new_value = array();
93
+ foreach($value as $k => $v){
94
+ $k = preg_replace("#$base_translated/#", _x( 'product-category', 'slug', 'woocommerce' ) . '/', $k);
95
+ $new_value[$k] = $v;
96
+ }
97
+ $value = $new_value;
98
+ unset($new_value);
99
+ }
100
+ if(empty($permalinks['tag_base'])){
101
+ remove_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
102
+ $base_translated = _x( 'product-tag', 'slug', 'woocommerce' );
103
+ add_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
104
+ $new_value = array();
105
+ foreach($value as $k => $v){
106
+ $k = preg_replace("#$base_translated/#", _x( 'product-tag', 'slug', 'woocommerce' ) . '/', $k);
107
+ $new_value[$k] = $v;
108
+ }
109
+ $value = $new_value;
110
+ unset($new_value);
111
+ }
112
+
113
+ }
114
+
115
+ return $value;
116
+ }
117
+
118
  function rewrite_rules_filter($value){
119
  global $sitepress, $sitepress_settings, $wpdb, $wp_taxonomies,$woocommerce;
120
 
121
+ if(!empty($sitepress_settings['posts_slug_translation']['on'])){
122
+ add_filter('option_rewrite_rules', array('WPML_Slug_Translation', 'rewrite_rules_filter'), 1, 1);
123
+ }
124
+
125
  $strings_language = $sitepress_settings['st']['strings_language'];
126
 
127
  if($sitepress->get_current_language() != $strings_language){
140
 
141
  $taxonomy_obj = get_taxonomy($taxonomy);
142
  $slug = isset($taxonomy_obj->rewrite['slug']) ? trim($taxonomy_obj->rewrite['slug'],'/') : false;
143
+
144
  if($slug && $sitepress->get_current_language() != $strings_language){
145
 
146
  $slug_translation = $wpdb->get_var($wpdb->prepare("
161
 
162
  }
163
 
164
+
165
+
166
  if($slug_translation){
167
 
168
  $buff_value = array();
169
  foreach((array)$value as $k=>$v){
170
 
171
+ if($slug != $slug_translation && preg_match('#^[^/]*/?' . $slug . '/#', $k)){
172
+
173
  $k = preg_replace('#^([^/]*)(/?)' . $slug . '/#', '$1$2' . $slug_translation . '/' , $k);
174
  }
 
175
 
176
  $buff_value[$k] = $v;
177
 
181
  unset($buff_value);
182
 
183
  }
184
+
185
  }
186
 
187
  }
240
 
241
  }
242
 
 
243
 
244
+ //filter shop page rewrite slug
245
+ $cache_key = 'wcml_rewrite_shop_slug';
246
+
247
+ if($val = wp_cache_get($cache_key)){
248
+
249
+ $value = $val;
250
+
251
+ }else{
252
+
253
+ $current_shop_id = woocommerce_get_page_id( 'shop' );
254
+ $default_shop_id = icl_object_id( $current_shop_id, 'page', true, $sitepress->get_default_language() );
255
+
256
+ $current_slug = get_post( $current_shop_id )->post_name;
257
+ $default_slug = get_post( $default_shop_id )->post_name;
258
+
259
+
260
+ if( $current_slug != $default_slug ){
261
+ $buff_value = array();
262
+ foreach( (array) $value as $k => $v ){
263
+
264
+ if( $current_slug != $default_slug && preg_match( '#^[^/]*/?' . $default_slug . '/page/#', $k ) ){
265
 
266
+ $k = preg_replace( '#^([^/]*)(/?)' . $default_slug . '/#', '$1$2' . $current_slug . '/' , $k );
267
+ }
268
+
269
+ $buff_value[$k] = $v;
270
+
271
+ }
272
+
273
+ $value = $buff_value;
274
+ unset( $buff_value );
275
+ }
276
+
277
+ wp_cache_add($cache_key, $value);
278
+ }
279
+
280
+ return $value;
281
  }
282
 
283
  function _switch_wc_locale(){
inc/wc-strings.class.php CHANGED
@@ -7,6 +7,7 @@ class WCML_WC_Strings{
7
  add_action('init', array($this, 'init'));
8
  add_action('plugins_loaded', array($this, 'pre_init'));
9
  add_filter('query_vars', array($this, 'translate_query_var_for_product'));
 
10
 
11
  }
12
 
@@ -111,12 +112,7 @@ class WCML_WC_Strings{
111
  $permalinks = get_option( 'woocommerce_permalinks' );
112
  $product_permalink = empty( $permalinks['product_base'] ) ? _x( 'product', 'slug', 'woocommerce' ) : trim($permalinks['product_base'], '/');
113
 
114
-
115
- $translated_slug = $wpdb->get_var($wpdb->prepare("
116
- SELECT t.value FROM {$wpdb->prefix}icl_string_translations t
117
- JOIN {$wpdb->prefix}icl_strings s ON t.string_id = s.id
118
- WHERE s.name=%s AND s.value = %s AND t.language = %s",
119
- 'URL slug: ' . $product_permalink, $product_permalink, $sitepress->get_current_language()));
120
 
121
  if(isset($_GET[$translated_slug])){
122
  $buff = $_GET[$translated_slug];
@@ -129,6 +125,30 @@ class WCML_WC_Strings{
129
  return $public_query_vars;
130
  }
131
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  // Catch the default slugs for translation
133
  function translate_default_slug($translation, $text, $context, $domain) {
134
  global $sitepress_settings, $sitepress;
@@ -204,7 +224,7 @@ class WCML_WC_Strings{
204
  if (function_exists('icl_translate')) {
205
  $gateways = WC()->payment_gateways();
206
  foreach($gateways->payment_gateways as $key => $gateway){
207
- if($gateway->id == $id){
208
  WC_Payment_Gateways::instance()->payment_gateways[$key]->instructions = icl_translate('woocommerce', $gateway->id .'_gateway_instructions', $gateway->instructions);
209
  break;
210
  }
@@ -281,5 +301,15 @@ class WCML_WC_Strings{
281
  return $text;
282
  }
283
 
 
 
 
 
 
 
 
 
 
 
284
 
285
  }
7
  add_action('init', array($this, 'init'));
8
  add_action('plugins_loaded', array($this, 'pre_init'));
9
  add_filter('query_vars', array($this, 'translate_query_var_for_product'));
10
+ add_filter('wp_redirect', array($this, 'encode_shop_slug'),10,2);
11
 
12
  }
13
 
112
  $permalinks = get_option( 'woocommerce_permalinks' );
113
  $product_permalink = empty( $permalinks['product_base'] ) ? _x( 'product', 'slug', 'woocommerce' ) : trim($permalinks['product_base'], '/');
114
 
115
+ $translated_slug = $this->get_translated_product_base_by_lang(false,$product_permalink);
 
 
 
 
 
116
 
117
  if(isset($_GET[$translated_slug])){
118
  $buff = $_GET[$translated_slug];
125
  return $public_query_vars;
126
  }
127
 
128
+ function get_translated_product_base_by_lang($language = false, $product_permalink = false){
129
+ if(!$language){
130
+ global $sitepress;
131
+ $language = $sitepress->get_current_language();
132
+
133
+ }
134
+
135
+ if(!$product_permalink){
136
+ $permalinks = get_option( 'woocommerce_permalinks' );
137
+ $product_permalink = empty( $permalinks['product_base'] ) ? _x( 'product', 'slug', 'woocommerce' ) : trim($permalinks['product_base'], '/');
138
+ }
139
+
140
+ global $wpdb;
141
+
142
+ $translated_slug = $wpdb->get_var($wpdb->prepare("
143
+ SELECT t.value FROM {$wpdb->prefix}icl_string_translations t
144
+ JOIN {$wpdb->prefix}icl_strings s ON t.string_id = s.id
145
+ WHERE s.name=%s AND s.value = %s AND t.language = %s",
146
+ 'URL slug: ' . $product_permalink, $product_permalink, $language ));
147
+
148
+ return $translated_slug;
149
+
150
+ }
151
+
152
  // Catch the default slugs for translation
153
  function translate_default_slug($translation, $text, $context, $domain) {
154
  global $sitepress_settings, $sitepress;
224
  if (function_exists('icl_translate')) {
225
  $gateways = WC()->payment_gateways();
226
  foreach($gateways->payment_gateways as $key => $gateway){
227
+ if($gateway->id == $id && isset(WC_Payment_Gateways::instance()->payment_gateways[$key]->instructions)){
228
  WC_Payment_Gateways::instance()->payment_gateways[$key]->instructions = icl_translate('woocommerce', $gateway->id .'_gateway_instructions', $gateway->instructions);
229
  break;
230
  }
301
  return $text;
302
  }
303
 
304
+ function encode_shop_slug($location, $status){
305
+ if(get_post_type(get_query_var('p')) == 'product'){
306
+ global $sitepress;
307
+ $language = $sitepress->get_language_for_element(get_query_var('p'), 'post_product');
308
+ $base_slug = $this->get_translated_product_base_by_lang($language);
309
+
310
+ $location = str_replace($base_slug , urlencode($base_slug),$location);
311
+ }
312
+ return $location;
313
+ }
314
 
315
  }
menu/sub/custom-currency-options.php CHANGED
@@ -12,7 +12,7 @@
12
  <tr>
13
  <td align="right"><?php _e('Exchange Rate', 'wpml-wcml') ?></td>
14
  <td>
15
- <?php printf("1 %s = %s %s", $wc_currency, '<input name="currency_options[' . $code . '][rate]" type="number" style="width:50px" step="0.01" value="' . $currency['rate'] . '" />', $code) ?>
16
  </td>
17
  </tr>
18
  <tr>
@@ -44,15 +44,15 @@
44
  </tr>
45
  <tr>
46
  <td align="right"><?php _e('Thousand Separator', 'wpml-wcml') ?></td>
47
- <td><input name="currency_options[<?php echo $code ?>][thousand_sep]" type="text" style="width:50px;" value="<?php echo esc_attr($currency['thousand_sep']) ?>" /></td>
48
  </tr>
49
  <tr>
50
  <td align="right"><?php _e('Decimal Separator', 'wpml-wcml') ?></td>
51
- <td><input name="currency_options[<?php echo $code ?>][decimal_sep]" type="text" style="width:50px;" value="<?php echo esc_attr($currency['decimal_sep']) ?>" /></td>
52
  </tr>
53
  <tr>
54
  <td align="right"><?php _e('Number of Decimals', 'wpml-wcml') ?></td>
55
- <td><input name="currency_options[<?php echo $code ?>][num_decimals]" type="number" style="width:50px;" value="<?php echo esc_attr($currency['num_decimals']) ?>" min="0" step="1" /></td>
56
  </tr>
57
 
58
  <tr>
@@ -83,7 +83,7 @@
83
  <tr>
84
  <td align="right"><?php _e('Autosubtract amount', 'wpml-wcml') ?></td>
85
  <td>
86
- <input name="currency_options[<?php echo $code ?>][auto_subtract]" value="<?php echo $currency['auto_subtract'] ?>" type="number" value="0" style="width:50px;" />
87
  </td>
88
  </tr>
89
  </table>
12
  <tr>
13
  <td align="right"><?php _e('Exchange Rate', 'wpml-wcml') ?></td>
14
  <td>
15
+ <?php printf("1 %s = %s %s", $wc_currency, '<input name="currency_options[' . $code . '][rate]" type="number" class="ext_rate" step="0.01" value="' . $currency['rate'] . '" data-message="'. __( 'Only numeric', 'wpml-wcml' ) .'" />', $code) ?>
16
  </td>
17
  </tr>
18
  <tr>
44
  </tr>
45
  <tr>
46
  <td align="right"><?php _e('Thousand Separator', 'wpml-wcml') ?></td>
47
+ <td><input name="currency_options[<?php echo $code ?>][thousand_sep]" type="text" class="currency_option_input" value="<?php echo esc_attr($currency['thousand_sep']) ?>" /></td>
48
  </tr>
49
  <tr>
50
  <td align="right"><?php _e('Decimal Separator', 'wpml-wcml') ?></td>
51
+ <td><input name="currency_options[<?php echo $code ?>][decimal_sep]" type="text" class="currency_option_input" value="<?php echo esc_attr($currency['decimal_sep']) ?>" /></td>
52
  </tr>
53
  <tr>
54
  <td align="right"><?php _e('Number of Decimals', 'wpml-wcml') ?></td>
55
+ <td><input name="currency_options[<?php echo $code ?>][num_decimals]" type="number" class="decimals_number" value="<?php echo esc_attr($currency['num_decimals']) ?>" min="0" step="1" data-message="<?php _e( 'Only numeric', 'wpml-wcml' ); ?>" /></td>
56
  </tr>
57
 
58
  <tr>
83
  <tr>
84
  <td align="right"><?php _e('Autosubtract amount', 'wpml-wcml') ?></td>
85
  <td>
86
+ <input name="currency_options[<?php echo $code ?>][auto_subtract]" class="abstract_amount" value="<?php echo $currency['auto_subtract'] ?>" type="number" value="0" data-message="<?php _e( 'Only numeric', 'wpml-wcml' ); ?>" />
87
  </td>
88
  </tr>
89
  </table>
menu/sub/troubleshooting.php CHANGED
@@ -5,8 +5,10 @@ if(get_option('wcml_products_to_sync') === false ){
5
  }
6
 
7
  $prod_with_variations = $woocommerce_wpml->troubleshooting->wcml_count_products_with_variations();
8
- $prod_count = $woocommerce_wpml->troubleshooting->wcml_count_products();
9
  $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_categories();
 
 
10
  ?>
11
  <div class="wrap wcml_trblsh">
12
  <div id="icon-wpml" class="icon32"><br /></div>
@@ -48,12 +50,31 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
48
  <span class="cat_status"><?php echo $prod_categories_count; ?></span>&nbsp;<span><?php _e('left', 'wpml-wcml') ?></span>
49
  </label>
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  </li>
52
  <li>
53
  <button type="button" class="button-secondary" id="wcml_trbl"><?php _e('Start', 'wpml-wcml') ?></button>
54
  <input id="count_prod_variat" type="hidden" value="<?php echo $prod_with_variations; ?>"/>
55
  <input id="count_prod" type="hidden" value="<?php echo $prod_count; ?>"/>
56
  <input id="count_categories" type="hidden" value="<?php echo $prod_categories_count; ?>"/>
 
57
  <input id="sync_galerry_page" type="hidden" value="0"/>
58
  <input id="sync_category_page" type="hidden" value="0"/>
59
  <span class="wcml_spinner"></span>
@@ -78,8 +99,16 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
78
  sync_product_gallery();
79
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
80
  sync_product_categories();
 
 
81
  }
82
  });
 
 
 
 
 
 
83
  });
84
 
85
  function update_product_count(){
@@ -101,6 +130,8 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
101
  sync_product_gallery();
102
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
103
  sync_product_categories();
 
 
104
  }
105
  }
106
  });
@@ -123,6 +154,8 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
123
  sync_product_gallery();
124
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
125
  sync_product_categories();
 
 
126
  }else{
127
  jQuery('#wcml_trbl').removeAttr('disabled');
128
  jQuery('.wcml_spinner').hide();
@@ -157,6 +190,8 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
157
  if(jQuery('#count_prod').val() == 0){
158
  if(jQuery('#wcml_sync_categories').is(':checked')){
159
  sync_product_categories();
 
 
160
  }else{
161
  jQuery('#wcml_trbl').removeAttr('disabled');
162
  jQuery('.wcml_spinner').hide();
@@ -189,9 +224,13 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
189
  },
190
  success: function(response) {
191
  if(jQuery('#count_categories').val() == 0){
 
 
 
192
  jQuery('#wcml_trbl').removeAttr('disabled');
193
  jQuery('.wcml_spinner').hide();
194
  jQuery('#wcml_trbl').next().fadeOut();
 
195
  jQuery('.cat_status').html(0);
196
  }else{
197
  var left = jQuery('#count_categories').val()-5;
@@ -208,4 +247,33 @@ $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_
208
  });
209
  }
210
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
211
  </script>
5
  }
6
 
7
  $prod_with_variations = $woocommerce_wpml->troubleshooting->wcml_count_products_with_variations();
8
+ $prod_count = $woocommerce_wpml->troubleshooting->wcml_count_products_for_gallery_sync();
9
  $prod_categories_count = $woocommerce_wpml->troubleshooting->wcml_count_product_categories();
10
+
11
+ $all_products_taxonomies = get_taxonomies(array('object_type'=>array('product')),'objects');
12
  ?>
13
  <div class="wrap wcml_trblsh">
14
  <div id="icon-wpml" class="icon32"><br /></div>
50
  <span class="cat_status"><?php echo $prod_categories_count; ?></span>&nbsp;<span><?php _e('left', 'wpml-wcml') ?></span>
51
  </label>
52
 
53
+ </li>
54
+
55
+ <li>
56
+ <label>
57
+ <input type="checkbox" id="wcml_duplicate_terms" />
58
+ <?php _e('Duplicate terms ( please select attribute ):', 'wpml-wcml') ?>
59
+ <select id="attr_to_duplicate">
60
+ <?php
61
+ $terms_count = false;
62
+ foreach($all_products_taxonomies as $tax_key => $tax):
63
+ if(in_array($tax_key, array('product_type','product_cat','product_tag'))) continue;
64
+ if(!$terms_count) $terms_count = wp_count_terms($tax_key); ?>
65
+ <option value="<?php echo $tax_key; ?>" rel="<?php echo wp_count_terms($tax_key); ?>"><?php echo ucfirst($tax->labels->name); ?></option>
66
+ <?php endforeach; ?>
67
+ </select>
68
+ <span class="attr_status"><?php echo $terms_count; ?></span>&nbsp;<span><?php _e('left', 'wpml-wcml') ?></span>
69
+ </label>
70
+
71
  </li>
72
  <li>
73
  <button type="button" class="button-secondary" id="wcml_trbl"><?php _e('Start', 'wpml-wcml') ?></button>
74
  <input id="count_prod_variat" type="hidden" value="<?php echo $prod_with_variations; ?>"/>
75
  <input id="count_prod" type="hidden" value="<?php echo $prod_count; ?>"/>
76
  <input id="count_categories" type="hidden" value="<?php echo $prod_categories_count; ?>"/>
77
+ <input id="count_terms" type="hidden" value="<?php echo $terms_count; ?>"/>
78
  <input id="sync_galerry_page" type="hidden" value="0"/>
79
  <input id="sync_category_page" type="hidden" value="0"/>
80
  <span class="wcml_spinner"></span>
99
  sync_product_gallery();
100
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
101
  sync_product_categories();
102
+ }else if(jQuery('#wcml_duplicate_terms').is(':checked')){
103
+ duplicate_terms();
104
  }
105
  });
106
+
107
+ jQuery('#attr_to_duplicate').on('change',function(){
108
+ jQuery('.attr_status').html(jQuery(this).find('option:selected').attr('rel'))
109
+ jQuery('#count_terms').val(jQuery(this).find('option:selected').attr('rel'))
110
+ });
111
+
112
  });
113
 
114
  function update_product_count(){
130
  sync_product_gallery();
131
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
132
  sync_product_categories();
133
+ }else if(jQuery('#wcml_duplicate_terms').is(':checked')){
134
+ duplicate_terms();
135
  }
136
  }
137
  });
154
  sync_product_gallery();
155
  }else if(jQuery('#wcml_sync_categories').is(':checked')){
156
  sync_product_categories();
157
+ }else if(jQuery('#wcml_duplicate_terms').is(':checked')){
158
+ duplicate_terms();
159
  }else{
160
  jQuery('#wcml_trbl').removeAttr('disabled');
161
  jQuery('.wcml_spinner').hide();
190
  if(jQuery('#count_prod').val() == 0){
191
  if(jQuery('#wcml_sync_categories').is(':checked')){
192
  sync_product_categories();
193
+ }else if(jQuery('#wcml_duplicate_terms').is(':checked')){
194
+ duplicate_terms();
195
  }else{
196
  jQuery('#wcml_trbl').removeAttr('disabled');
197
  jQuery('.wcml_spinner').hide();
224
  },
225
  success: function(response) {
226
  if(jQuery('#count_categories').val() == 0){
227
+ if(jQuery('#wcml_duplicate_terms').is(':checked')){
228
+ duplicate_terms();
229
+ }else{
230
  jQuery('#wcml_trbl').removeAttr('disabled');
231
  jQuery('.wcml_spinner').hide();
232
  jQuery('#wcml_trbl').next().fadeOut();
233
+ }
234
  jQuery('.cat_status').html(0);
235
  }else{
236
  var left = jQuery('#count_categories').val()-5;
247
  });
248
  }
249
 
250
+ function duplicate_terms(){
251
+ jQuery.ajax({
252
+ type : "post",
253
+ url : ajaxurl,
254
+ data : {
255
+ action: "trbl_duplicate_terms",
256
+ wcml_nonce: "<?php echo wp_create_nonce('trbl_duplicate_terms'); ?>",
257
+ attr: jQuery('#attr_to_duplicate option:selected').val()
258
+ },
259
+ success: function(response) {
260
+ if(jQuery('#count_terms').val() == 0){
261
+ jQuery('#wcml_trbl').removeAttr('disabled');
262
+ jQuery('.wcml_spinner').hide();
263
+ jQuery('#wcml_trbl').next().fadeOut();
264
+ jQuery('.attr_status').html(0);
265
+ }else{
266
+ var left = jQuery('#count_terms').val()-5;
267
+ if(left < 0 ){
268
+ left = 0;
269
+ }
270
+ jQuery('.attr_status').html(left);
271
+ jQuery('#count_terms').val(left);
272
+
273
+ duplicate_terms();
274
+ }
275
+ }
276
+ });
277
+ }
278
+
279
  </script>
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilin
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.0
7
- Tested up to: 3.9
8
- Stable tag: 3.3
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -77,6 +77,16 @@ In order for the checkout and store pages to appear translated, you need to crea
77
 
78
  == Changelog ==
79
 
 
 
 
 
 
 
 
 
 
 
80
  = 3.3 =
81
  * Performance improvements: optimized database queries
82
  * Support rounding rules for converted prices
@@ -88,45 +98,45 @@ In order for the checkout and store pages to appear translated, you need to crea
88
  * Dependencies update: WooCommerce Multilingual requires WPML 3.1.5
89
  * Set language information for existing products when installing WCML the first time.
90
  * Do not allow disabling all currencies for a language
91
- * Removed 'clean up test content' and 'send to translation' dropdown on products editor page
92
  * Message about overwritten settings in wpml-config made more explicit
93
- * Lock 'Default variation' select field in product translations
94
  * After change shipping method on cart page we will see not translated strings
95
  * Fixed bug related to shipping cost calculation in multi-currency mode
96
  * With php magic quotes on, products translations with quotes have backslashes
97
  * Bug related to translation of grouped products � simple product not showing up on front end
98
- * Stock actions on the order page don't work correct with translated products
99
  * For Orders save attributes in default language and display them on order page in admin language
100
  * Attribute Label appearing untranslated in backend order
101
  * Memory issues on the Products tab when we have a large number of products
102
- * 'product-category' not translated in the default language.
103
- * 'WCML_Products' does not have a method 'translated_cart_item_name'
104
  * Order completed emails sent in default currency
105
  * Language suffix (e.g. @en) not hidden for product attributes on the front end
106
  * Quick edit functionality issues fixed
107
- * Fixed 'Call to undefined method WC_Session_Handler::get()'
108
- * Fatal error when updating the order status to 'complete'
109
  * Currency is not converted when you switch language until you refresh the page.
110
  * �Super Admin� not able to see the WCML menu
111
  * Checkout validation errors in default language instead of user language
112
- * Fixes for compatibility with Tab manager: Can't translate �Additional Information� tab title
113
  * Bug: SEO title & meta description changed to original
114
- * Bug: 404 on 'view my order' on secondary language using 'language name added as a parameter'
115
  * Bug: Permalink placeholders appear translated when using default language different than English
116
  * Fixes for compatibility with Table Rate shipping: shipping classes not decoded correctly in multi-currency mode
117
- * Bug: 'show all products' link on WCML products page points to the wrong page � no products
118
- * Bug fix: product page redirecting to homepage when the product post type slug was identical in different languages and 'language added as a parameter' was set
119
  * Bug fixes related to File paths functionality (WooComemrce 2.1.x)
120
  * Bug: Product parents not synced between translations (grouped products)
121
  * Bug: Grouped products title incomplete
122
  * Bug: Db Error when saving translation of variable products with custom attributes
123
  * Bug: WooCommerce translated product attributes with spaces not showing
124
- * Bug: Deactivated currency still appears if you maintain the default currency for that language to 'Keep'.
125
  * Bug: Incorrect shipping value on translated page
126
  * Bug: Reports for products including only products in the current language (WooCommerce 2.1.x)
127
  * Bug: WooCommerce translated product attributes with spaces not showing
128
  * Bug: Problems creating translations for shop pages when existing pages were trashed
129
- * Bug fix: Fatal error when Multi-currency is not enabled and 'Table Rate Shipping' plugin is active
130
  * Fixed bug in compatibility with Tab Manager
131
  * Bug fix: Cart strings falling to default language after updating chosen shipping method
132
  * Bug fix: Reports not including selected product/category translations
@@ -166,7 +176,7 @@ In order for the checkout and store pages to appear translated, you need to crea
166
  * Fixed bug: language names not localized on products editor page
167
  * Fixed bug: Can't set "Custom post type" to translate
168
  * Fixed bug: Translation fields not visible - In certain circumstances (e.g. search) the translation fields corresponding to the translated languages were missing
169
- * Fixed alignment for 'Update/Save' button in the products translation editor
170
  * Fixed bug: Default selection not copied to duplicate products
171
  * Fixed bug: Price doesn't change when change language on the cart page when set "I will manage the pricing in each currency myself"
172
  * Resolved one compatibility issue with Woosidebars
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.0
7
+ Tested up to: 3.9.1
8
+ Stable tag: 3.3.1
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
77
 
78
  == Changelog ==
79
 
80
+ = 3.3.1 =
81
+ * Some strings were showing in the wrong language on the cart and checkout page.
82
+ * Product category urls - in some cases the product category urls didn�t work on sites with the default language different than English.
83
+ * Products gallery images synchronization - sometimes, when synchronizing products "gallery images" and categories, the result was not updated correctly on the Troubleshooting page
84
+ * Fixed issues related to WooCOmmerce Dynamic Pricing
85
+ * Supoprt for translating WooCommerce 2.1+ endpoints
86
+ * 'Continue Shopping' button pointing to the wrong url
87
+ * Problem with short links
88
+ * Fixed some issues with Table Rate Shipping
89
+
90
  = 3.3 =
91
  * Performance improvements: optimized database queries
92
  * Support rounding rules for converted prices
98
  * Dependencies update: WooCommerce Multilingual requires WPML 3.1.5
99
  * Set language information for existing products when installing WCML the first time.
100
  * Do not allow disabling all currencies for a language
101
+ * Removed clean up test content and send to translation dropdown on products editor page
102
  * Message about overwritten settings in wpml-config made more explicit
103
+ * Lock Default variation select field in product translations
104
  * After change shipping method on cart page we will see not translated strings
105
  * Fixed bug related to shipping cost calculation in multi-currency mode
106
  * With php magic quotes on, products translations with quotes have backslashes
107
  * Bug related to translation of grouped products � simple product not showing up on front end
108
+ * Stock actions on the order page dont work correct with translated products
109
  * For Orders save attributes in default language and display them on order page in admin language
110
  * Attribute Label appearing untranslated in backend order
111
  * Memory issues on the Products tab when we have a large number of products
112
+ * product-category not translated in the default language.
113
+ * WCML_Products does not have a method translated_cart_item_name
114
  * Order completed emails sent in default currency
115
  * Language suffix (e.g. @en) not hidden for product attributes on the front end
116
  * Quick edit functionality issues fixed
117
+ * Fixed Call to undefined method WC_Session_Handler::get()
118
+ * Fatal error when updating the order status to complete
119
  * Currency is not converted when you switch language until you refresh the page.
120
  * �Super Admin� not able to see the WCML menu
121
  * Checkout validation errors in default language instead of user language
122
+ * Fixes for compatibility with Tab manager: Cant translate �Additional Information� tab title
123
  * Bug: SEO title & meta description changed to original
124
+ * Bug: 404 on view my order on secondary language using language name added as a parameter
125
  * Bug: Permalink placeholders appear translated when using default language different than English
126
  * Fixes for compatibility with Table Rate shipping: shipping classes not decoded correctly in multi-currency mode
127
+ * Bug: show all products link on WCML products page points to the wrong page � no products
128
+ * Bug fix: product page redirecting to homepage when the product post type slug was identical in different languages and language added as a parameter was set
129
  * Bug fixes related to File paths functionality (WooComemrce 2.1.x)
130
  * Bug: Product parents not synced between translations (grouped products)
131
  * Bug: Grouped products title incomplete
132
  * Bug: Db Error when saving translation of variable products with custom attributes
133
  * Bug: WooCommerce translated product attributes with spaces not showing
134
+ * Bug: Deactivated currency still appears if you maintain the default currency for that language to Keep�.
135
  * Bug: Incorrect shipping value on translated page
136
  * Bug: Reports for products including only products in the current language (WooCommerce 2.1.x)
137
  * Bug: WooCommerce translated product attributes with spaces not showing
138
  * Bug: Problems creating translations for shop pages when existing pages were trashed
139
+ * Bug fix: Fatal error when Multi-currency is not enabled and Table Rate Shipping plugin is active
140
  * Fixed bug in compatibility with Tab Manager
141
  * Bug fix: Cart strings falling to default language after updating chosen shipping method
142
  * Bug fix: Reports not including selected product/category translations
176
  * Fixed bug: language names not localized on products editor page
177
  * Fixed bug: Can't set "Custom post type" to translate
178
  * Fixed bug: Translation fields not visible - In certain circumstances (e.g. search) the translation fields corresponding to the translated languages were missing
179
+ * Fixed alignment for Update/Save button in the products translation editor
180
  * Fixed bug: Default selection not copied to duplicate products
181
  * Fixed bug: Price doesn't change when change language on the cart page when set "I will manage the pricing in each currency myself"
182
  * Resolved one compatibility issue with Woosidebars
woocommerce_wpml.class.php CHANGED
@@ -12,8 +12,17 @@ class woocommerce_wpml {
12
 
13
  var $missing;
14
 
 
 
15
  function __construct(){
16
  add_action('plugins_loaded', array($this, 'init'), 2);
 
 
 
 
 
 
 
17
  }
18
 
19
  function init(){
@@ -86,9 +95,14 @@ class woocommerce_wpml {
86
  //set translate product by default
87
  $this->translate_product_slug();
88
 
89
- if(is_admin() && ((isset($_GET['page']) && $_GET['page'] == 'wpml-wcml')
90
- || (($pagenow == 'edit.php' || $pagenow == 'post-new.php') && isset($_GET['post_type']) && ($_GET['post_type'] == 'shop_coupon' || $_GET['post_type'] == 'shop_order'))
91
- || ($pagenow == 'post.php' && isset($_GET['post']) && (get_post_type($_GET['post']) == 'shop_coupon' || get_post_type($_GET['post']) == 'shop_order')))){
 
 
 
 
 
92
  remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
93
  }
94
 
@@ -142,7 +156,7 @@ class woocommerce_wpml {
142
  $string_id = icl_register_string('WordPress', 'URL slug: ' . $slug, $slug);
143
  }
144
  foreach($active_languages as $language){
145
- if($language['code'] != $sitepress_settings['st']['strings_language']){
146
  $sitepress->switch_lang($language['code']);
147
  $context = 'slug';
148
  $domain = 'woocommerce';
@@ -551,4 +565,70 @@ class woocommerce_wpml {
551
  }
552
  }
553
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
554
  }
12
 
13
  var $missing;
14
 
15
+ var $endpoints_strings;
16
+
17
  function __construct(){
18
  add_action('plugins_loaded', array($this, 'init'), 2);
19
+
20
+ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
21
+ //endpoints hooks
22
+ add_action( 'plugins_loaded', array( $this, 'register_endpoints_translations' ), 2 );
23
+ add_action('icl_ajx_custom_call',array($this,'rewrite_rule_endpoints'), 11, 2);
24
+ add_action('woocommerce_settings_saved',array($this,'update_endpoints_rules'));
25
+ }
26
  }
27
 
28
  function init(){
95
  //set translate product by default
96
  $this->translate_product_slug();
97
 
98
+ if(is_admin() &&
99
+ (
100
+ (isset($_GET['page']) && $_GET['page'] == 'wpml-wcml') ||
101
+ (($pagenow == 'edit.php' || $pagenow == 'post-new.php') && isset($_GET['post_type']) && ($_GET['post_type'] == 'shop_coupon' || $_GET['post_type'] == 'shop_order')) ||
102
+ ($pagenow == 'post.php' && isset($_GET['post']) && (get_post_type($_GET['post']) == 'shop_coupon' || get_post_type($_GET['post']) == 'shop_order')) ||
103
+ (isset($_GET['page']) && $_GET['page'] == 'shipping_zones')
104
+ )
105
+ ){
106
  remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
107
  }
108
 
156
  $string_id = icl_register_string('WordPress', 'URL slug: ' . $slug, $slug);
157
  }
158
  foreach($active_languages as $language){
159
+ if(isset($sitepress_settings['st']) && $language['code'] != $sitepress_settings['st']['strings_language']){
160
  $sitepress->switch_lang($language['code']);
161
  $context = 'slug';
162
  $domain = 'woocommerce';
565
  }
566
  }
567
  }
568
+
569
+ function register_endpoints_translations(){
570
+ $wc_vars = WC()->query->query_vars;
571
+
572
+ $query_vars = array(
573
+ // Checkout actions
574
+ 'order-pay' => $this->get_endpoint_translation($wc_vars['order-pay']),
575
+ 'order-received' => $this->get_endpoint_translation($wc_vars['order-received']),
576
+
577
+ // My account actions
578
+ 'view-order' => $this->get_endpoint_translation($wc_vars['view-order']),
579
+ 'edit-account' => $this->get_endpoint_translation($wc_vars['edit-account']),
580
+ 'edit-address' => $this->get_endpoint_translation($wc_vars['edit-address']),
581
+ 'lost-password' => $this->get_endpoint_translation($wc_vars['lost-password']),
582
+ 'customer-logout' => $this->get_endpoint_translation($wc_vars['customer-logout']),
583
+ 'add-payment-method' => $this->get_endpoint_translation($wc_vars['add-payment-method']),
584
+ );
585
+
586
+ WC()->query->query_vars = $query_vars;
587
+
588
+ }
589
+
590
+ function get_endpoint_translation($endpoint){
591
+ global $wpdb;
592
+
593
+ $string = $wpdb->get_var($wpdb->prepare("SELECT id FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", 'Endpoint slug: ' . $endpoint, $endpoint));
594
+
595
+ if(!$string && function_exists('icl_register_string')){
596
+ icl_register_string('WordPress', 'Endpoint slug: ' . $endpoint, $endpoint);
597
+ }else{
598
+ $this->endpoints_strings[] = $string;
599
+ }
600
+
601
+ if(function_exists('icl_t')){
602
+ return icl_t('WordPress','Endpoint slug: '. $endpoint, $endpoint);
603
+ }else{
604
+ return $endpoint;
605
+ }
606
+
607
+
608
+ }
609
+
610
+ function rewrite_rule_endpoints($call, $data){
611
+ if($call == 'icl_st_save_translation' && in_array($data['icl_st_string_id'],$this->endpoints_strings)){
612
+ $this->add_endpoints();
613
+ }
614
+ }
615
+
616
+ function update_endpoints_rules(){
617
+ $this->add_endpoints();
618
+ }
619
+
620
+ function add_endpoints(){
621
+ global $wpdb;
622
+ //add endpoints and flush rules
623
+ foreach($this->endpoints_strings as $string_id){
624
+ $strings = $wpdb->get_results($wpdb->prepare("SELECT value FROM {$wpdb->prefix}icl_string_translations WHERE string_id = %s AND status = 1", $string_id));
625
+ foreach($strings as $string){
626
+ add_rewrite_endpoint( $string->value, EP_PAGES );
627
+ }
628
+ }
629
+ flush_rewrite_rules();
630
+ }
631
+
632
+
633
+
634
  }
wpml-woocommerce.php CHANGED
@@ -5,9 +5,10 @@
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
- Version: 3.3
9
  */
10
 
 
11
  if(defined('WCML_VERSION')) return;
12
  define('WCML_VERSION', '3.3');
13
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
@@ -37,4 +38,3 @@ require WCML_PLUGIN_PATH . '/inc/compatibility.class.php';
37
 
38
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
39
  $woocommerce_wpml = new woocommerce_wpml();
40
-
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
+ Version: 3.3.1
9
  */
10
 
11
+
12
  if(defined('WCML_VERSION')) return;
13
  define('WCML_VERSION', '3.3');
14
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
38
 
39
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
40
  $woocommerce_wpml = new woocommerce_wpml();