WooCommerce Multilingual – run WooCommerce with WPML - Version 3.3.3

Version Description

  • Compatibility with WooCommerce 2.2.x
  • Auto-download WooCommerce translations for active and new languages
  • Page titles translations for WooCommerce pages taken from WooCommerce Multilingual .mo files
  • Product base, product category slug, product tag slug and product attribute bases will always have to be translated via String Translation (not using WooCommerce translations from the mo files)
  • Added warning message on settings page when product base not translated to all languages
  • Fixed: Base currency format ignored after adding additional currency
  • Fixed: Shipping class names were displayed wrong on the WooCommerce settings page when switching the admin language
  • Fixed: WooCommerce pages were not working correctly after changing the default language
  • Fixed: WooCommerce native interface doesn't copy the variations prices
Download this release

Release Info

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

Code changes from version 3.3.2 to 3.3.3

assets/js/scripts.js CHANGED
@@ -69,11 +69,11 @@ jQuery(document).ready(function($){
69
  element.text(textClosed);
70
  }else {
71
  if($table.size() > 0){
72
- //set def data
73
- $table.find('input').each(function(){
74
  element.data('def',element.val());
75
- });
76
- $table.closest('.outer').show();
77
  element.text(textOpened);
78
  }else{
79
  //load product data
@@ -93,7 +93,7 @@ jQuery(document).ready(function($){
93
  alert(response.error);
94
  }else{
95
  //update status block
96
- $(response.html).insertAfter(parent).css('display','inline-block');
97
 
98
  //set def data
99
  $table.find('input').each(function(){
@@ -414,23 +414,23 @@ jQuery(document).ready(function($){
414
 
415
  });
416
 
417
- $(document).on('click','.cleditorButton',function(){
418
- if($(this).closest('.cleditorMain').find('textarea').is(':visible')){
419
- $(this).closest('.cleditorMain').find('textarea').hide();
420
- $(this).closest('.cleditorMain').find('iframe').show();
421
- }else{
422
- $(this).closest('.cleditorMain').find('textarea').show();
423
- $(this).closest('.cleditorMain').find('iframe').hide();
424
- }
425
- });
426
 
427
  $(document).on('click','.wcml_close_cross,.wcml_popup_cancel',function(){
428
  $(".wcml_fade").hide();
429
- // if(tinyMCE.activeEditor != null){
430
- // if($(this).closest('.wcml_editor').find('textarea.wcml_content_tr').size() >0){
431
- // tinyMCE.activeEditor.setContent($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
432
- // }
433
- // }
434
  $(this).closest('.wcml_editor').css('display','none');
435
  $(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').val($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
436
  });
69
  element.text(textClosed);
70
  }else {
71
  if($table.size() > 0){
72
+ //set def data
73
+ $table.find('input').each(function(){
74
  element.data('def',element.val());
75
+ });
76
+ $table.closest('.outer').show();
77
  element.text(textOpened);
78
  }else{
79
  //load product data
93
  alert(response.error);
94
  }else{
95
  //update status block
96
+ $(response.html).insertAfter(parent).css('display','table-row');
97
 
98
  //set def data
99
  $table.find('input').each(function(){
414
 
415
  });
416
 
417
+ $(document).on('click','.cleditorButton',function(){
418
+ if($(this).closest('.cleditorMain').find('textarea').is(':visible')){
419
+ $(this).closest('.cleditorMain').find('textarea').hide();
420
+ $(this).closest('.cleditorMain').find('iframe').show();
421
+ }else{
422
+ $(this).closest('.cleditorMain').find('textarea').show();
423
+ $(this).closest('.cleditorMain').find('iframe').hide();
424
+ }
425
+ });
426
 
427
  $(document).on('click','.wcml_close_cross,.wcml_popup_cancel',function(){
428
  $(".wcml_fade").hide();
429
+ if(tinyMCE.activeEditor != null){
430
+ if($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').size() >0){
431
+ tinyMCE.activeEditor.setContent($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
432
+ }
433
+ }
434
  $(this).closest('.wcml_editor').css('display','none');
435
  $(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').val($(this).closest('.wcml_editor').find('.wcml_editor_translation textarea').data('def'));
436
  });
compatibility/wc_extra_product_options.class.php ADDED
@@ -0,0 +1,122 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Extra_Product_Options{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'get_tm_product_terms', array( $this, 'filter_product_terms' ) );
8
+
9
+ add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
10
+
11
+ add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
12
+
13
+ add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
14
+ add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
15
+ }
16
+
17
+ function register_options_strings( $meta_id, $id, $meta_key, $options ){
18
+ if( $meta_key != 'tm_meta' )
19
+ return false;
20
+
21
+ $this->filter_options( $options, $id, 'register' );
22
+
23
+ }
24
+
25
+ function product_options_filter( $null, $object_id, $meta_key, $single ){
26
+ static $no_filter = false;
27
+
28
+ if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
29
+ $no_filter = true;
30
+
31
+ $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
32
+
33
+ $options = $this->filter_options( $options, $object_id, 'translate' );
34
+
35
+ $no_filter = false;
36
+ }
37
+
38
+ return isset( $options ) ? array( $options ) : $null;
39
+ }
40
+
41
+ function filter_options( $options, $id, $action ){
42
+
43
+ if( !isset( $options[ 'tmfbuilder' ] ) ){
44
+ return $options;
45
+ }
46
+
47
+ global $sitepress;
48
+ $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
49
+
50
+ $id = icl_object_id( $id, get_post_type( $id ), true, $sitepress->get_default_language() );
51
+
52
+ foreach( $options[ 'tmfbuilder' ] as $key => $values ){
53
+ foreach( $keys_to_translate as $key_text ){
54
+ if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
55
+ foreach( $values as $value_key => $value ){
56
+ if( $value ){
57
+ if( $action == 'register'){
58
+ icl_register_string( 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
59
+ }else{
60
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = icl_t('wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value);
61
+ }
62
+ }
63
+
64
+ }
65
+ }
66
+ }
67
+
68
+ //convert prices
69
+ if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
70
+ foreach( $values as $value_key => $value ){
71
+ if( $value ){
72
+ if( is_array( $value ) ){
73
+ foreach( $value as $key_price => $price ){
74
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price, $id );
75
+ }
76
+ }else{
77
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value, $id );
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ return $options;
86
+ }
87
+
88
+
89
+ function filter_product_terms( $product_terms ){
90
+ global $sitepress,$wpdb;
91
+
92
+ $translated_terms = array();
93
+
94
+ foreach($product_terms as $key => $product_term){
95
+ $tr_id = icl_object_id( $key, 'product_cat', true, $sitepress->get_default_language() );
96
+
97
+ $translated_terms[$tr_id] = $wpdb->get_row( $wpdb->prepare("
98
+ SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $tr_id, 'product_cat' ) );
99
+
100
+ }
101
+
102
+
103
+ return $translated_terms;
104
+ }
105
+
106
+ function inf_translate_strings(){
107
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
108
+ $this->inf_message( 'Options Form' );
109
+ }
110
+
111
+ function inf_translate_product_page_strings(){
112
+ $this->inf_message( 'Product' );
113
+ }
114
+
115
+ function inf_message( $text ){
116
+ $message = '<div><p class="icl_cyan_box">';
117
+ $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'wpml-wcml'), $text, 'admin.php?page=wpml-string-translation/menu/string-translation.php&context=wc_extra_product_options');
118
+ $message .= '</p></div>';
119
+
120
+ echo $message;
121
+ }
122
+ }
compatibility/wc_sensei.class.php CHANGED
@@ -196,9 +196,9 @@ class WCML_sensei{
196
  if( $comment_id != $translation->element_id ){
197
  wp_delete_comment( $translation->element_id, true );
198
  }
199
- }
200
 
201
- }
202
 
203
 
204
  }
196
  if( $comment_id != $translation->element_id ){
197
  wp_delete_comment( $translation->element_id, true );
198
  }
199
+ }
200
 
201
+ }
202
 
203
 
204
  }
inc/compatibility.class.php CHANGED
@@ -63,7 +63,7 @@ class WCML_Compatibility {
63
  require_once WCML_PLUGIN_PATH . '/compatibility/wc_exporter.class.php';
64
  $this->wc_exporter = new WCML_wcExporter();
65
  }
66
-
67
  //Gravity Forms
68
  if(class_exists('GFForms')){
69
  require_once WCML_PLUGIN_PATH . '/compatibility/gravityforms.class.php';
@@ -76,6 +76,12 @@ class WCML_Compatibility {
76
  $this->sensei = new WCML_sensei();
77
  }
78
 
 
 
 
 
 
 
79
  }
80
 
81
  }
63
  require_once WCML_PLUGIN_PATH . '/compatibility/wc_exporter.class.php';
64
  $this->wc_exporter = new WCML_wcExporter();
65
  }
66
+
67
  //Gravity Forms
68
  if(class_exists('GFForms')){
69
  require_once WCML_PLUGIN_PATH . '/compatibility/gravityforms.class.php';
76
  $this->sensei = new WCML_sensei();
77
  }
78
 
79
+ //Extra Product Options
80
+ if(class_exists('TM_Extra_Product_Options')){
81
+ require_once WCML_PLUGIN_PATH . '/compatibility/wc_extra_product_options.class.php';
82
+ $this->extra_product_options = new WCML_Extra_Product_Options();
83
+ }
84
+
85
  }
86
 
87
  }
inc/emails.class.php CHANGED
@@ -43,7 +43,7 @@ class WCML_Emails{
43
  add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'admin_email' ), 9 );
44
 
45
  add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
46
- }
47
 
48
  /**
49
  * Translate WooCommerce emails.
43
  add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'admin_email' ), 9 );
44
 
45
  add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
46
+ }
47
 
48
  /**
49
  * Translate WooCommerce emails.
inc/endpoints.class.php CHANGED
@@ -77,7 +77,7 @@ class WCML_Endpoints{
77
  }
78
  flush_rewrite_rules();
79
  }
80
-
81
  function endpoint_permalink_filter( $p, $pid ){
82
  global $wp,$sitepress,$post;
83
 
77
  }
78
  flush_rewrite_rules();
79
  }
80
+
81
  function endpoint_permalink_filter( $p, $pid ){
82
  global $wp,$sitepress,$post;
83
 
inc/multi-currency-support.class.php CHANGED
@@ -50,7 +50,7 @@ class WCML_Multi_Currency_Support{
50
  }else{
51
  if(is_ajax() && $this->get_client_currency() != get_option('woocommerce_currency')){
52
  if(isset($_REQUEST['action'])){
53
- $ajax_actions = apply_filters('wcml_multi_currency_is_ajax', array('woocommerce_get_refreshed_fragments', 'woocommerce_update_order_review', 'woocommerce-checkout', 'woocommerce_checkout', 'woocommerce_add_to_cart'));
54
  if(version_compare($GLOBALS['woocommerce']->version, '2.1', '>=')){
55
  $ajax_actions[] = 'woocommerce_update_shipping_method';
56
  }
@@ -87,19 +87,19 @@ class WCML_Multi_Currency_Support{
87
  add_filter('woocommerce_table_rate_query_rates', array($this, 'table_rate_shipping_rates'));
88
  add_filter('woocommerce_table_rate_instance_settings', array($this, 'table_rate_instance_settings'));
89
  }
90
-
91
 
92
  add_filter('option_woocommerce_price_thousand_sep', array($this, 'filter_currency_thousand_sep_option'));
93
  add_filter('option_woocommerce_price_decimal_sep', array($this, 'filter_currency_decimal_sep_option'));
94
  add_filter('option_woocommerce_price_num_decimals', array($this, 'filter_currency_num_decimals_option'));
95
-
96
  //filters for wc-widget-price-filter
97
  add_filter( 'woocommerce_price_filter_results', array( $this, 'filter_price_filter_results' ), 10, 3 );
98
  add_filter( 'woocommerce_price_filter_widget_amount', array( $this, 'filter_price_filter_widget_amount' ) );
99
-
100
  }
101
-
102
- add_filter( 'option_woocommerce_currency_pos', array( $this, 'filter_currency_position_option' ) );
103
  add_filter( 'woocommerce_get_formatted_order_total', array( $this, 'filter_get_formatted_order_total' ), 10, 2 );
104
  add_action( 'woocommerce_view_order', array( $this, 'filter_view_order' ), 9 );
105
 
@@ -506,19 +506,23 @@ class WCML_Multi_Currency_Support{
506
  }
507
 
508
  function filter_currency_position_option($value){
509
- if( is_ajax() && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
 
 
510
  $currency_code = $_COOKIE[ '_wcml_order_currency' ];
 
 
511
  }else{
512
  $currency_code = $this->client_currency;
513
  }
514
 
515
- if(isset($this->currencies[$currency_code]['position']) &&
516
  in_array($this->currencies[$currency_code]['position'], array('left', 'right', 'left_space', 'right_space'))){
517
  $value = $this->currencies[$currency_code]['position'];
518
  }
519
  return $value;
520
  }
521
-
522
  function filter_get_formatted_order_total($formatted_total, $object ){
523
  $client_currency_buff = $this->client_currency;
524
  $this->client_currency = $object->get_order_currency();
@@ -529,7 +533,7 @@ class WCML_Multi_Currency_Support{
529
 
530
  return $formatted_total;
531
  }
532
-
533
  function filter_view_order( $order_id ){
534
  $currency_code = get_post_meta( $order_id, '_order_currency', true );
535
 
@@ -1168,8 +1172,8 @@ class WCML_Multi_Currency_Support{
1168
  function register_styles(){
1169
  wp_register_style('currency-switcher', WCML_PLUGIN_URL . '/assets/css/currency-switcher.css', null, WCML_VERSION);
1170
  wp_enqueue_style('currency-switcher');
1171
- }
1172
-
1173
 
1174
  function filter_price_filter_results( $matched_products, $min, $max ){
1175
  global $woocommerce_wpml,$wpdb;
50
  }else{
51
  if(is_ajax() && $this->get_client_currency() != get_option('woocommerce_currency')){
52
  if(isset($_REQUEST['action'])){
53
+ $ajax_actions = apply_filters('wcml_multi_currency_is_ajax', array('woocommerce_get_refreshed_fragments', 'woocommerce_update_order_review', 'woocommerce-checkout', 'woocommerce_checkout', 'woocommerce_add_to_cart'));
54
  if(version_compare($GLOBALS['woocommerce']->version, '2.1', '>=')){
55
  $ajax_actions[] = 'woocommerce_update_shipping_method';
56
  }
87
  add_filter('woocommerce_table_rate_query_rates', array($this, 'table_rate_shipping_rates'));
88
  add_filter('woocommerce_table_rate_instance_settings', array($this, 'table_rate_instance_settings'));
89
  }
90
+
91
 
92
  add_filter('option_woocommerce_price_thousand_sep', array($this, 'filter_currency_thousand_sep_option'));
93
  add_filter('option_woocommerce_price_decimal_sep', array($this, 'filter_currency_decimal_sep_option'));
94
  add_filter('option_woocommerce_price_num_decimals', array($this, 'filter_currency_num_decimals_option'));
95
+
96
  //filters for wc-widget-price-filter
97
  add_filter( 'woocommerce_price_filter_results', array( $this, 'filter_price_filter_results' ), 10, 3 );
98
  add_filter( 'woocommerce_price_filter_widget_amount', array( $this, 'filter_price_filter_widget_amount' ) );
99
+
100
  }
101
+
102
+ add_filter('option_woocommerce_currency_pos', array($this, 'filter_currency_position_option'));
103
  add_filter( 'woocommerce_get_formatted_order_total', array( $this, 'filter_get_formatted_order_total' ), 10, 2 );
104
  add_action( 'woocommerce_view_order', array( $this, 'filter_view_order' ), 9 );
105
 
506
  }
507
 
508
  function filter_currency_position_option($value){
509
+ global $pagenow;
510
+
511
+ if( ( is_ajax() || ( $pagenow == 'post-new.php' && isset( $_GET['post_type'] ) && $_GET['post_type'] == 'shop_order' ) ) && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
512
  $currency_code = $_COOKIE[ '_wcml_order_currency' ];
513
+ }elseif( isset($_GET['post']) && get_post_type($_GET['post']) == 'shop_order'){
514
+ $currency_code = get_post_meta( $_GET['post'], '_order_currency', true );
515
  }else{
516
  $currency_code = $this->client_currency;
517
  }
518
 
519
+ if(isset($this->currencies[$currency_code]['position']) && get_option('woocommerce_currency') != $currency_code &&
520
  in_array($this->currencies[$currency_code]['position'], array('left', 'right', 'left_space', 'right_space'))){
521
  $value = $this->currencies[$currency_code]['position'];
522
  }
523
  return $value;
524
  }
525
+
526
  function filter_get_formatted_order_total($formatted_total, $object ){
527
  $client_currency_buff = $this->client_currency;
528
  $this->client_currency = $object->get_order_currency();
533
 
534
  return $formatted_total;
535
  }
536
+
537
  function filter_view_order( $order_id ){
538
  $currency_code = get_post_meta( $order_id, '_order_currency', true );
539
 
1172
  function register_styles(){
1173
  wp_register_style('currency-switcher', WCML_PLUGIN_URL . '/assets/css/currency-switcher.css', null, WCML_VERSION);
1174
  wp_enqueue_style('currency-switcher');
1175
+ }
1176
+
1177
 
1178
  function filter_price_filter_results( $matched_products, $min, $max ){
1179
  global $woocommerce_wpml,$wpdb;
inc/multi-currency.class.php CHANGED
@@ -57,7 +57,7 @@ class WCML_WC_MultiCurrency{
57
 
58
  // use correct order currency on order detail page
59
  add_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
60
-
61
 
62
  //new order currency/language switchers
63
  add_action( 'woocommerce_process_shop_order_meta', array( $this, 'process_shop_order_meta'), 10, 2 );
@@ -67,7 +67,7 @@ class WCML_WC_MultiCurrency{
67
 
68
  add_action( 'wp_ajax_wcml_order_set_currency', array( $this, 'set_order_currency' ) );
69
  add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
70
-
71
  }
72
 
73
  // reports
@@ -116,9 +116,9 @@ class WCML_WC_MultiCurrency{
116
 
117
  function apply_rounding_rules($price, $currency = false ){
118
  global $woocommerce_wpml;
119
-
120
  if( !$currency )
121
- $currency = $this->get_client_currency();
122
  $currency_options = $woocommerce_wpml->settings['currency_options'][$currency];
123
 
124
  if($currency_options['rounding'] != 'disabled'){
@@ -164,7 +164,7 @@ class WCML_WC_MultiCurrency{
164
  return $price;
165
 
166
  }
167
-
168
  function apply_currency_position( $price, $currency_code ){
169
  global $woocommerce_wpml;
170
  $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
@@ -203,7 +203,7 @@ class WCML_WC_MultiCurrency{
203
 
204
  }
205
 
206
- function convert_price_amount($amount, $currency = false){
207
 
208
  if(empty($currency)){
209
  $currency = $this->get_client_currency();
@@ -218,7 +218,7 @@ class WCML_WC_MultiCurrency{
218
  if(in_array($currency, $this->currencies_without_cents)){
219
 
220
  if(version_compare(PHP_VERSION, '5.3.0') >= 0){
221
- $amount = round($amount, 0, PHP_ROUND_HALF_UP);
222
  }else{
223
  if($amount - floor($amount) < 0.5){
224
  $amount = floor($amount);
@@ -233,12 +233,16 @@ class WCML_WC_MultiCurrency{
233
  $amount = 0;
234
  }
235
 
 
 
 
 
236
  return $amount;
237
 
238
  }
239
 
240
  // convert back to default currency
241
- function unconvert_price_amount($amount, $currency = false){
242
 
243
  if(empty($currency)){
244
  $currency = $this->get_client_currency();
@@ -255,7 +259,7 @@ class WCML_WC_MultiCurrency{
255
  if(in_array($currency, $this->currencies_without_cents)){
256
 
257
  if(version_compare(PHP_VERSION, '5.3.0') >= 0){
258
- $amount = round($amount, 0, PHP_ROUND_HALF_UP);
259
  }else{
260
  if($amount - floor($amount) < 0.5){
261
  $amount = floor($amount);
@@ -272,6 +276,10 @@ class WCML_WC_MultiCurrency{
272
 
273
  }
274
 
 
 
 
 
275
  return $amount;
276
 
277
  }
@@ -440,29 +448,31 @@ class WCML_WC_MultiCurrency{
440
  }
441
 
442
  function _use_order_currency_symbol($currency){
443
-
444
  if(!function_exists('get_current_screen')){
445
  return $currency;
446
  }
447
 
448
  $current_screen = get_current_screen();
449
-
450
  remove_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
451
  if(!empty($current_screen) && $current_screen->id == 'shop_order'){
452
 
453
  $the_order = new WC_Order( get_the_ID() );
454
  if($the_order && method_exists($the_order, 'get_order_currency')){
455
-
456
- $currency = get_woocommerce_currency_symbol($the_order->get_order_currency());
457
-
 
 
458
  }
459
 
460
- }elseif( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_add_order_item' && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
461
 
462
  $currency = get_woocommerce_currency_symbol($_COOKIE[ '_wcml_order_currency' ]);
463
 
464
  }
465
-
466
  add_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
467
 
468
  return $currency;
@@ -579,7 +589,7 @@ class WCML_WC_MultiCurrency{
579
 
580
  }
581
  }
582
-
583
  function admin_reports_query_filter($query){
584
  global $wpdb;
585
 
@@ -599,9 +609,9 @@ class WCML_WC_MultiCurrency{
599
  }
600
 
601
  function reports_currency_dropdown(){
602
-
603
  $orders_currencies = $this->get_orders_currencies();
604
- $currencies = get_woocommerce_currencies();
605
 
606
  // remove temporary
607
  remove_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
@@ -611,9 +621,9 @@ class WCML_WC_MultiCurrency{
611
  <select id="dropdown_shop_report_currency">
612
  <?php if(empty($orders_currencies)): ?>
613
  <option value=""><?php _e('Currency - no orders found', 'wpml-wcml') ?></option>
614
- <?php else: ?>
615
  <?php foreach($orders_currencies as $currency => $count): ?>
616
- <option value="<?php echo $currency ?>" <?php selected( $currency, $this->reports_currency ); ?>><?php
617
  printf("%s (%s)", $currencies[$currency], get_woocommerce_currency_symbol($currency)) ?></option>
618
  <?php endforeach; ?>
619
  <?php endif; ?>
@@ -626,7 +636,7 @@ class WCML_WC_MultiCurrency{
626
  add_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
627
 
628
  }
629
-
630
  function order_currency_dropdown($order_id){
631
  if( !get_post_meta( $order_id, '_order_currency') ){
632
  global $woocommerce_wpml, $sitepress;
@@ -672,20 +682,28 @@ class WCML_WC_MultiCurrency{
672
  url: ajaxurl,
673
  type: 'post',
674
  dataType: 'json',
675
- data: {action: 'wcml_order_set_currency', order_id: woocommerce_admin_meta_boxes.post_id, currency: jQuery('#dropdown_shop_order_currency').val(), prev_currency: getCookie('_wcml_order_currency'),wcml_nonce: '".$wcml_order_set_currency_nonce."' },
676
  success: function( response ){
677
  if(typeof response.error !== 'undefined'){
678
  alert(response.error);
679
  }else{
680
- jQuery.each(response, function(index, value) {
681
- var item = jQuery('tr[data-order_item_id = '+index+']');
682
- item.attr('data-unit_subtotal',value.line_subtotal);
683
- item.attr('data-unit_total',value.line_total);
684
- item.find('.view .amount').html(value.display_total);
685
- item.find('.line_cost .edit .line_subtotal').val(value.line_subtotal);
686
- item.find('.line_cost .edit .line_total').val(value.line_total);
687
- });
688
- }
 
 
 
 
 
 
 
 
689
  }
690
  })
691
  });
@@ -734,31 +752,73 @@ class WCML_WC_MultiCurrency{
734
 
735
  //update order items price
736
  if( isset ( $_POST[ 'order_id' ] ) ){
737
- global $wpdb;
738
 
739
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = '%d'" , $_POST[ 'order_id' ] ) );
740
 
741
  $return = array();
742
 
 
 
 
 
 
 
 
 
 
 
 
 
 
743
  foreach($items as $item){
744
- $line_subtotal = $this->unconvert_price_amount( wc_get_order_item_meta( $item->order_item_id, '_line_subtotal', true ), $_POST[ 'prev_currency' ]) ;
745
- $line_subtotal_tax = $this->unconvert_price_amount( wc_get_order_item_meta( $item->order_item_id, '_line_subtotal_tax', true ), $_POST[ 'prev_currency' ]);
746
- $line_total = $this->unconvert_price_amount( wc_get_order_item_meta( $item->order_item_id, '_line_total', true ), $_POST[ 'prev_currency' ]);
747
- $line_tax = $this->unconvert_price_amount( wc_get_order_item_meta( $item->order_item_id, '_line_tax', true ), $_POST[ 'prev_currency' ]);
748
 
749
- $line_subtotal = $this->apply_rounding_rules( $this->convert_price_amount( $line_subtotal, $_POST[ 'currency' ] ), $_POST[ 'currency' ] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
750
  wc_update_order_item_meta( $item->order_item_id, '_line_subtotal', $line_subtotal );
751
- wc_update_order_item_meta( $item->order_item_id, '_line_subtotal_tax', $this->convert_price_amount( $line_subtotal_tax, $_POST[ 'currency' ] ) );
752
- $line_total = $this->apply_rounding_rules( $this->convert_price_amount( $line_total, $_POST[ 'currency' ] ), $_POST[ 'currency' ] );
753
  wc_update_order_item_meta( $item->order_item_id, '_line_total', $line_total );
754
- wc_update_order_item_meta( $item->order_item_id, '_line_tax', $this->convert_price_amount( $line_tax, $_POST[ 'currency' ] ) );
 
 
 
 
755
 
756
- $return[$item->order_item_id]['line_subtotal'] = $line_subtotal;
757
- $return[$item->order_item_id]['line_total'] = $line_total;
758
- $return[$item->order_item_id]['display_total'] = $this->apply_currency_position( $line_total, $_POST[ 'currency' ] );
 
 
 
759
 
 
 
 
 
 
760
  }
761
 
 
 
 
 
 
 
 
762
  echo json_encode($return);
763
 
764
  }
57
 
58
  // use correct order currency on order detail page
59
  add_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
60
+
61
 
62
  //new order currency/language switchers
63
  add_action( 'woocommerce_process_shop_order_meta', array( $this, 'process_shop_order_meta'), 10, 2 );
67
 
68
  add_action( 'wp_ajax_wcml_order_set_currency', array( $this, 'set_order_currency' ) );
69
  add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
70
+
71
  }
72
 
73
  // reports
116
 
117
  function apply_rounding_rules($price, $currency = false ){
118
  global $woocommerce_wpml;
119
+
120
  if( !$currency )
121
+ $currency = $this->get_client_currency();
122
  $currency_options = $woocommerce_wpml->settings['currency_options'][$currency];
123
 
124
  if($currency_options['rounding'] != 'disabled'){
164
  return $price;
165
 
166
  }
167
+
168
  function apply_currency_position( $price, $currency_code ){
169
  global $woocommerce_wpml;
170
  $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
203
 
204
  }
205
 
206
+ function convert_price_amount($amount, $currency = false, $decimals_num = 0, $decimal_sep = '.', $thousand_sep = ',' ){
207
 
208
  if(empty($currency)){
209
  $currency = $this->get_client_currency();
218
  if(in_array($currency, $this->currencies_without_cents)){
219
 
220
  if(version_compare(PHP_VERSION, '5.3.0') >= 0){
221
+ $amount = round($amount, $decimals_num, PHP_ROUND_HALF_UP);
222
  }else{
223
  if($amount - floor($amount) < 0.5){
224
  $amount = floor($amount);
233
  $amount = 0;
234
  }
235
 
236
+ if( $decimals_num ){
237
+ $amount = number_format( (float)$amount, $decimals_num, $decimal_sep, $thousand_sep );
238
+ }
239
+
240
  return $amount;
241
 
242
  }
243
 
244
  // convert back to default currency
245
+ function unconvert_price_amount($amount, $currency = false, $decimals_num = 0, $decimal_sep = '.', $thousand_sep = ','){
246
 
247
  if(empty($currency)){
248
  $currency = $this->get_client_currency();
259
  if(in_array($currency, $this->currencies_without_cents)){
260
 
261
  if(version_compare(PHP_VERSION, '5.3.0') >= 0){
262
+ $amount = round($amount, $decimals_num, PHP_ROUND_HALF_UP);
263
  }else{
264
  if($amount - floor($amount) < 0.5){
265
  $amount = floor($amount);
276
 
277
  }
278
 
279
+ if( $decimals_num ){
280
+ $amount = number_format( (float)$amount, $decimals_num, $decimal_sep, $thousand_sep );
281
+ }
282
+
283
  return $amount;
284
 
285
  }
448
  }
449
 
450
  function _use_order_currency_symbol($currency){
451
+
452
  if(!function_exists('get_current_screen')){
453
  return $currency;
454
  }
455
 
456
  $current_screen = get_current_screen();
457
+
458
  remove_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
459
  if(!empty($current_screen) && $current_screen->id == 'shop_order'){
460
 
461
  $the_order = new WC_Order( get_the_ID() );
462
  if($the_order && method_exists($the_order, 'get_order_currency')){
463
+ if( !$the_order->get_order_currency() && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
464
+ $currency = get_woocommerce_currency_symbol($_COOKIE[ '_wcml_order_currency' ]);
465
+ }else{
466
+ $currency = get_woocommerce_currency_symbol($the_order->get_order_currency());
467
+ }
468
  }
469
 
470
+ }elseif( isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'woocommerce_add_order_item', 'woocommerce_calc_line_taxes', 'woocommerce_save_order_items' ) ) && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
471
 
472
  $currency = get_woocommerce_currency_symbol($_COOKIE[ '_wcml_order_currency' ]);
473
 
474
  }
475
+
476
  add_filter('woocommerce_currency_symbol', array($this, '_use_order_currency_symbol'));
477
 
478
  return $currency;
589
 
590
  }
591
  }
592
+
593
  function admin_reports_query_filter($query){
594
  global $wpdb;
595
 
609
  }
610
 
611
  function reports_currency_dropdown(){
612
+
613
  $orders_currencies = $this->get_orders_currencies();
614
+ $currencies = get_woocommerce_currencies();
615
 
616
  // remove temporary
617
  remove_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
621
  <select id="dropdown_shop_report_currency">
622
  <?php if(empty($orders_currencies)): ?>
623
  <option value=""><?php _e('Currency - no orders found', 'wpml-wcml') ?></option>
624
+ <?php else: ?>
625
  <?php foreach($orders_currencies as $currency => $count): ?>
626
+ <option value="<?php echo $currency ?>" <?php selected( $currency, $this->reports_currency ); ?>><?php
627
  printf("%s (%s)", $currencies[$currency], get_woocommerce_currency_symbol($currency)) ?></option>
628
  <?php endforeach; ?>
629
  <?php endif; ?>
636
  add_filter('woocommerce_currency_symbol', array($this, '_set_reports_currency_symbol'));
637
 
638
  }
639
+
640
  function order_currency_dropdown($order_id){
641
  if( !get_post_meta( $order_id, '_order_currency') ){
642
  global $woocommerce_wpml, $sitepress;
682
  url: ajaxurl,
683
  type: 'post',
684
  dataType: 'json',
685
+ data: {action: 'wcml_order_set_currency', order_id: woocommerce_admin_meta_boxes.post_id, currency: jQuery('#dropdown_shop_order_currency').val(), prev_currency: getCookie('_wcml_order_currency'), shipp: jQuery('.wc-order-totals tr:nth-child(1) .amount').html(), disc: jQuery('#_order_discount').val(), total: jQuery('#_order_total').val(), refund: jQuery('.wc-order-totals tr:nth-child(4) .amount').html(), wcml_nonce: '".$wcml_order_set_currency_nonce."' },
686
  success: function( response ){
687
  if(typeof response.error !== 'undefined'){
688
  alert(response.error);
689
  }else{
690
+ if(typeof response.items !== 'undefined'){
691
+ jQuery.each(response.items, function(index, value) {
692
+ var item = jQuery('tr[data-order_item_id = '+index+']');
693
+ item.attr('data-unit_subtotal',value.line_subtotal);
694
+ item.attr('data-unit_total',value.line_total);
695
+ item.find('.view .amount').html(value.display_total);
696
+ item.find('.line_cost .edit .line_subtotal').val(value.line_subtotal);
697
+ item.find('.line_cost .edit .line_total').val(value.line_total);
698
+ });
699
+ }
700
+ jQuery('.wc-order-totals tr:nth-child(1) .amount').html(response.shipp);
701
+ jQuery('.wc-order-totals tr:nth-child(2) .amount').html(response.disc_disp);
702
+ jQuery('.wc-order-totals tr:nth-child(3) .amount').html(response.total_disp);
703
+ jQuery('.wc-order-totals tr:nth-child(4) .amount').html(response.refund);
704
+ jQuery('#_order_discount').val(response.disc);
705
+ jQuery('#_order_total').val(response.total);
706
+ }
707
  }
708
  })
709
  });
752
 
753
  //update order items price
754
  if( isset ( $_POST[ 'order_id' ] ) ){
755
+ global $wpdb,$woocommerce_wpml;
756
 
757
  $items = $wpdb->get_results( $wpdb->prepare( "SELECT order_item_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_id = '%d'" , $_POST[ 'order_id' ] ) );
758
 
759
  $return = array();
760
 
761
+ $currencies = $woocommerce_wpml->multi_currency_support->get_currencies();
762
+
763
+ if(isset($currencies[$_POST[ 'currency' ]])){
764
+ $currency_info = $currencies[$_POST[ 'currency' ]];
765
+ $decimals_num = $currency_info['num_decimals'];
766
+ $decimal_sep = $currency_info['decimal_sep'];
767
+ $thousand_sep = $currency_info['thousand_sep'];
768
+ }else{
769
+ $decimals_num = get_option('woocommerce_price_num_decimals');
770
+ $decimal_sep = get_option('woocommerce_price_decimal_sep');
771
+ $thousand_sep = get_option('woocommerce_price_thousand_sep');
772
+ }
773
+
774
  foreach($items as $item){
 
 
 
 
775
 
776
+ $line_subtotal = wc_get_order_item_meta( $item->order_item_id, '_line_subtotal', true ) ;
777
+ $line_subtotal_tax = wc_get_order_item_meta( $item->order_item_id, '_line_subtotal_tax', true );
778
+ $line_total = wc_get_order_item_meta( $item->order_item_id, '_line_total', true );
779
+ $line_tax = wc_get_order_item_meta( $item->order_item_id, '_line_tax', true );
780
+
781
+ if( $_POST[ 'prev_currency' ] != 'false' ){
782
+ $line_subtotal = $this->unconvert_price_amount( $line_subtotal, $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep ) ;
783
+ $line_subtotal_tax = $this->unconvert_price_amount( $line_subtotal_tax, $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep );
784
+ $line_total = $this->unconvert_price_amount( $line_total, $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep );
785
+ $line_tax = $this->unconvert_price_amount( $line_tax, $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep );
786
+ }
787
+
788
+
789
+
790
+ $line_subtotal = $this->apply_rounding_rules( $this->convert_price_amount( $line_subtotal, $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] );
791
  wc_update_order_item_meta( $item->order_item_id, '_line_subtotal', $line_subtotal );
792
+ wc_update_order_item_meta( $item->order_item_id, '_line_subtotal_tax', $this->convert_price_amount( $line_subtotal_tax, $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ) );
793
+ $line_total = $this->apply_rounding_rules( $this->convert_price_amount( $line_total, $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] );
794
  wc_update_order_item_meta( $item->order_item_id, '_line_total', $line_total );
795
+ wc_update_order_item_meta( $item->order_item_id, '_line_tax', $this->convert_price_amount( $line_tax, $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ) );
796
+
797
+ $return['items'][$item->order_item_id]['line_subtotal'] = $line_subtotal;
798
+ $return['items'][$item->order_item_id]['line_total'] = $line_total;
799
+ $return['items'][$item->order_item_id]['display_total'] = $this->apply_currency_position( $line_total, $_POST[ 'currency' ] );
800
 
801
+ }
802
+
803
+ $shipp = (float) preg_replace('/[^0-9.]*/','',$_POST[ 'shipp' ]);
804
+ $disc = $_POST[ 'disc' ] ;
805
+ $total = $_POST[ 'total' ] ;
806
+ $refund = (float) preg_replace('/[^0-9.]*/','',$_POST[ 'refund' ]);
807
 
808
+ if( $_POST[ 'prev_currency' ] != 'false' ){
809
+ $shipp = $this->unconvert_price_amount( $shipp , $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep ) ;
810
+ $disc = $this->unconvert_price_amount( $disc , $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep ) ;
811
+ $total = $this->unconvert_price_amount( $total , $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep ) ;
812
+ $refund = $this->unconvert_price_amount( $refund , $_POST[ 'prev_currency' ], $decimals_num, $decimal_sep, $thousand_sep ) ;
813
  }
814
 
815
+ $return['shipp'] = $this->apply_currency_position( $this->apply_rounding_rules( $this->convert_price_amount( $shipp , $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] ), $_POST[ 'currency' ] );
816
+ $return['disc'] = $this->apply_rounding_rules( $this->convert_price_amount( $disc , $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] );
817
+ $return['disc_disp'] = $this->apply_currency_position( $return['disc'], $_POST[ 'currency' ] );
818
+ $return['total'] = $this->apply_rounding_rules( $this->convert_price_amount( $total , $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] );
819
+ $return['total_disp'] = $this->apply_currency_position( $return['total'], $_POST[ 'currency' ] );
820
+ $return['refund'] = $this->apply_currency_position( $this->apply_rounding_rules( $this->convert_price_amount( $refund, $_POST[ 'currency' ], $decimals_num, $decimal_sep, $thousand_sep ), $_POST[ 'currency' ] ), $_POST[ 'currency' ] );
821
+
822
  echo json_encode($return);
823
 
824
  }
inc/products.class.php CHANGED
@@ -49,7 +49,7 @@ class WCML_Products{
49
  add_action('admin_head', array($this, 'hide_multilingual_content_setup_box'));
50
 
51
  add_action('woocommerce_duplicate_product',array($this,'woocommerce_duplicate_product'),10,2);
52
-
53
  }else{
54
  add_filter('woocommerce_json_search_found_products', array($this, 'filter_found_products_by_language'));
55
  }
@@ -522,6 +522,7 @@ class WCML_Products{
522
  $args['post_title'] = $data['title_' . $language];
523
  $args['post_content'] = $data['content_' . $language];
524
  $args['post_excerpt'] = $data['excerpt_' . $language];
 
525
  $product_parent = icl_object_id($orig_product->post_parent, 'product', false, $language);
526
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
527
  $_POST['to_lang'] = $language;
@@ -623,7 +624,7 @@ class WCML_Products{
623
 
624
  //duplicate product attrs
625
  $orig_product_attrs = $this->get_product_atributes($original_product_id);
626
- add_post_meta($tr_product_id,'_product_attributes',$orig_product_attrs);
627
 
628
  $this->sync_default_product_attr($original_product_id, $tr_product_id, $lang);
629
  //sync media
@@ -1139,9 +1140,9 @@ class WCML_Products{
1139
  $original_up_sells = maybe_unserialize( get_post_meta( $product_id, '_upsell_ids', true ) );
1140
  $trnsl_up_sells = array();
1141
  if($original_up_sells)
1142
- foreach( $original_up_sells as $original_up_sell_product ){
1143
- $trnsl_up_sells[] = icl_object_id( $original_up_sell_product, 'post_'.get_post_type( $original_up_sell_product ), false, $lang );
1144
- }
1145
 
1146
  update_post_meta( $tr_product_id, '_upsell_ids', $trnsl_up_sells );
1147
 
@@ -1149,9 +1150,9 @@ class WCML_Products{
1149
  $original_cross_sells = maybe_unserialize( get_post_meta( $product_id, '_crosssell_ids', true ) );
1150
  $trnsl_cross_sells = array();
1151
  if( $original_cross_sells )
1152
- foreach( $original_cross_sells as $original_cross_sell_product ){
1153
- $trnsl_cross_sells[] = icl_object_id( $original_cross_sell_product, 'post_'.get_post_type( $original_cross_sell_product ), false, $lang );
1154
- }
1155
  update_post_meta( $tr_product_id, '_crosssell_ids', $trnsl_cross_sells );
1156
 
1157
  //sync grouped products
@@ -1233,7 +1234,7 @@ class WCML_Products{
1233
  $prod_lang = $sitepress->get_language_for_element($_GET['post'],'post_product');
1234
  }
1235
 
1236
- if(!$woocommerce_wpml->settings['trnsl_interface'] && $pagenow == 'post.php' && isset($_GET['post']) && $default_lang != $prod_lang && get_post_type($_GET['post'])=='product'){
1237
  add_action('admin_notices', array($this, 'inf_editing_product_in_non_default_lang'));
1238
  }
1239
 
@@ -1454,15 +1455,9 @@ class WCML_Products{
1454
  $this->sync_product_gallery($duplicated_post_id);
1455
  }
1456
 
1457
- //trnsl_interface option
1458
- if (!$woocommerce_wpml->settings['trnsl_interface'] && $default_language != $current_language) {
1459
- return;
1460
- }
1461
-
1462
  // check its a product
1463
  $post_type = get_post_type($post_id);
1464
 
1465
-
1466
  //set trid for variations
1467
  if ($post_type == 'product_variation') {
1468
  $var_lang = $sitepress->get_language_for_element(wp_get_post_parent_id($post_id),'post_product');
@@ -1480,6 +1475,7 @@ class WCML_Products{
1480
  if (empty($duplicated_post_id) || isset($_POST['autosave'])) {
1481
  return;
1482
  }
 
1483
  if($pagenow != 'post.php' && $pagenow != 'post-new.php' && $pagenow != 'admin.php' && !$ajax_call){
1484
  return;
1485
  }
@@ -1487,6 +1483,19 @@ class WCML_Products{
1487
  return;
1488
  }
1489
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1490
  // get language code
1491
  $language_details = $sitepress->get_element_language_details($post_id, 'post_product');
1492
  if ($pagenow == 'admin.php' && empty($language_details)) {
@@ -1519,10 +1528,6 @@ class WCML_Products{
1519
  }
1520
  }
1521
 
1522
- // If we reach this point, we go ahead with sync.
1523
- // Remove filter to avoid double sync
1524
- remove_action('save_post', array($this, 'sync_post_action'), 11, 2);
1525
-
1526
  // pick posts to sync
1527
  $posts = array();
1528
  $translations = $sitepress->get_element_translations($language_details->trid, 'post_product');
@@ -1547,25 +1552,12 @@ class WCML_Products{
1547
  $this->sync_thumbnail_id($duplicated_post_id,$post_id, $lang);
1548
  }
1549
 
1550
- //sync product parent
1551
- $tr_parent_id = icl_object_id(wp_get_post_parent_id($duplicated_post_id),'product',false,$lang);
1552
- $wpdb->update(
1553
- $wpdb->posts,
1554
- array(
1555
- 'post_parent' => is_null($tr_parent_id)?0:$tr_parent_id
1556
- ),
1557
- array( 'id' => $post_id )
1558
- );
1559
-
1560
-
1561
-
1562
 
1563
  $this->sync_product_taxonomies($duplicated_post_id,$post_id,$lang);
1564
 
1565
  $this->sync_default_product_attr($duplicated_post_id,$post_id,$lang);
1566
 
1567
- //synchronize term data, postmeta (Woocommerce "global" product attributes and custom attributes)
1568
-
1569
  //get "_product_attributes" from original product
1570
  $orig_product_attrs = $this->get_product_atributes($duplicated_post_id);
1571
  $trnsl_product_attrs = $this->get_product_atributes($post_id);
@@ -1577,16 +1569,29 @@ class WCML_Products{
1577
 
1578
  update_post_meta($post_id, '_product_attributes', $orig_product_attrs);
1579
 
1580
-
1581
-
1582
  // synchronize post variations
1583
- $this->sync_product_variations($duplicated_post_id,$post_id,$lang);
1584
  $this->sync_linked_products($duplicated_post_id,$post_id,$lang);
1585
  }
1586
 
1587
  $this->sync_product_variations_custom_prices($duplicated_post_id);
1588
  }
1589
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1590
  function update_custom_prices($post_id,$regular_price,$sale_price,$schedule,$date_from,$date_to,$code){
1591
  $price = '';
1592
  update_post_meta($post_id,'_regular_price_'.$code,$regular_price);
@@ -2384,15 +2389,15 @@ class WCML_Products{
2384
 
2385
  function remove_language_options(){
2386
  global $WPML_media,$typenow;
2387
- if( defined('WPML_MEDIA_VERSION') && $typenow == 'product' ){
2388
- remove_action( 'icl_post_languages_options_after', array( $WPML_media, 'language_options' ) );
2389
  add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
2390
  }
2391
  }
2392
 
2393
  function media_inputs(){
2394
- echo '<input name="icl_duplicate_attachments" type="hidden" value="1" />';
2395
- echo '<input name="icl_duplicate_featured_image" type="hidden" value="1" />';
2396
  }
2397
 
2398
  function icl_pro_translation_completed($tr_product_id) {
@@ -2723,7 +2728,7 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2723
  function woocommerce_duplicate_product($new_id, $post){
2724
  global $sitepress,$wpdb;
2725
 
2726
- $sitepress->set_element_language_details( $new_id, 'post_' . $post->post_type, false, $sitepress->get_current_language() );
2727
  $new_trid = $sitepress->get_element_trid( $new_id, 'post_' . $post->post_type );
2728
 
2729
 
@@ -2745,7 +2750,7 @@ function get_cart_attribute_translation($taxonomy,$attribute,$product_id,$tr_pro
2745
  }
2746
  }
2747
  }
2748
-
2749
  }
2750
 
2751
 
49
  add_action('admin_head', array($this, 'hide_multilingual_content_setup_box'));
50
 
51
  add_action('woocommerce_duplicate_product',array($this,'woocommerce_duplicate_product'),10,2);
52
+
53
  }else{
54
  add_filter('woocommerce_json_search_found_products', array($this, 'filter_found_products_by_language'));
55
  }
522
  $args['post_title'] = $data['title_' . $language];
523
  $args['post_content'] = $data['content_' . $language];
524
  $args['post_excerpt'] = $data['excerpt_' . $language];
525
+ $args['post_status'] = $orig_product->post_status;
526
  $product_parent = icl_object_id($orig_product->post_parent, 'product', false, $language);
527
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
528
  $_POST['to_lang'] = $language;
624
 
625
  //duplicate product attrs
626
  $orig_product_attrs = $this->get_product_atributes($original_product_id);
627
+ update_post_meta($tr_product_id,'_product_attributes',$orig_product_attrs);
628
 
629
  $this->sync_default_product_attr($original_product_id, $tr_product_id, $lang);
630
  //sync media
1140
  $original_up_sells = maybe_unserialize( get_post_meta( $product_id, '_upsell_ids', true ) );
1141
  $trnsl_up_sells = array();
1142
  if($original_up_sells)
1143
+ foreach( $original_up_sells as $original_up_sell_product ){
1144
+ $trnsl_up_sells[] = icl_object_id( $original_up_sell_product, 'post_'.get_post_type( $original_up_sell_product ), false, $lang );
1145
+ }
1146
 
1147
  update_post_meta( $tr_product_id, '_upsell_ids', $trnsl_up_sells );
1148
 
1150
  $original_cross_sells = maybe_unserialize( get_post_meta( $product_id, '_crosssell_ids', true ) );
1151
  $trnsl_cross_sells = array();
1152
  if( $original_cross_sells )
1153
+ foreach( $original_cross_sells as $original_cross_sell_product ){
1154
+ $trnsl_cross_sells[] = icl_object_id( $original_cross_sell_product, 'post_'.get_post_type( $original_cross_sell_product ), false, $lang );
1155
+ }
1156
  update_post_meta( $tr_product_id, '_crosssell_ids', $trnsl_cross_sells );
1157
 
1158
  //sync grouped products
1234
  $prod_lang = $sitepress->get_language_for_element($_GET['post'],'post_product');
1235
  }
1236
 
1237
+ if(!$woocommerce_wpml->settings['trnsl_interface'] && $pagenow == 'post.php' && isset($_GET['post']) && $default_lang!=$prod_lang && get_post_type($_GET['post'])=='product'){
1238
  add_action('admin_notices', array($this, 'inf_editing_product_in_non_default_lang'));
1239
  }
1240
 
1455
  $this->sync_product_gallery($duplicated_post_id);
1456
  }
1457
 
 
 
 
 
 
1458
  // check its a product
1459
  $post_type = get_post_type($post_id);
1460
 
 
1461
  //set trid for variations
1462
  if ($post_type == 'product_variation') {
1463
  $var_lang = $sitepress->get_language_for_element(wp_get_post_parent_id($post_id),'post_product');
1475
  if (empty($duplicated_post_id) || isset($_POST['autosave'])) {
1476
  return;
1477
  }
1478
+
1479
  if($pagenow != 'post.php' && $pagenow != 'post-new.php' && $pagenow != 'admin.php' && !$ajax_call){
1480
  return;
1481
  }
1483
  return;
1484
  }
1485
 
1486
+ // If we reach this point, we go ahead with sync.
1487
+ // Remove filter to avoid double sync
1488
+ remove_action('save_post', array($this, 'sync_post_action'), 11, 2);
1489
+
1490
+ //trnsl_interface option
1491
+ if (!$woocommerce_wpml->settings['trnsl_interface'] && $default_language != $current_language) {
1492
+
1493
+ $this->sync_status_and_parent( $duplicated_post_id, $post_id, $current_language );
1494
+ $this->sync_product_data( $duplicated_post_id, $post_id, $current_language );
1495
+
1496
+ return;
1497
+ }
1498
+
1499
  // get language code
1500
  $language_details = $sitepress->get_element_language_details($post_id, 'post_product');
1501
  if ($pagenow == 'admin.php' && empty($language_details)) {
1528
  }
1529
  }
1530
 
 
 
 
 
1531
  // pick posts to sync
1532
  $posts = array();
1533
  $translations = $sitepress->get_element_translations($language_details->trid, 'post_product');
1552
  $this->sync_thumbnail_id($duplicated_post_id,$post_id, $lang);
1553
  }
1554
 
1555
+ $this->sync_status_and_parent( $duplicated_post_id, $post_id, $lang );
 
 
 
 
 
 
 
 
 
 
 
1556
 
1557
  $this->sync_product_taxonomies($duplicated_post_id,$post_id,$lang);
1558
 
1559
  $this->sync_default_product_attr($duplicated_post_id,$post_id,$lang);
1560
 
 
 
1561
  //get "_product_attributes" from original product
1562
  $orig_product_attrs = $this->get_product_atributes($duplicated_post_id);
1563
  $trnsl_product_attrs = $this->get_product_atributes($post_id);
1569
 
1570
  update_post_meta($post_id, '_product_attributes', $orig_product_attrs);
1571
 
 
 
1572
  // synchronize post variations
1573
+ $this->sync_product_variations($duplicated_post_id,$post_id,$lang);
1574
  $this->sync_linked_products($duplicated_post_id,$post_id,$lang);
1575
  }
1576
 
1577
  $this->sync_product_variations_custom_prices($duplicated_post_id);
1578
  }
1579
 
1580
+ //sync product parent & post_status
1581
+ function sync_status_and_parent( $duplicated_post_id, $post_id, $lang ){
1582
+ global $wpdb;
1583
+
1584
+ $tr_parent_id = icl_object_id( wp_get_post_parent_id( $duplicated_post_id ), 'product', false, $lang );
1585
+ $wpdb->update(
1586
+ $wpdb->posts,
1587
+ array(
1588
+ 'post_parent' => is_null( $tr_parent_id )? 0 : $tr_parent_id,
1589
+ 'post_status' => get_post_status( $duplicated_post_id )
1590
+ ),
1591
+ array( 'id' => $post_id )
1592
+ );
1593
+ }
1594
+
1595
  function update_custom_prices($post_id,$regular_price,$sale_price,$schedule,$date_from,$date_to,$code){
1596
  $price = '';
1597
  update_post_meta($post_id,'_regular_price_'.$code,$regular_price);
2389
 
2390
  function remove_language_options(){
2391
  global $WPML_media,$typenow;
2392
+ if(defined('WPML_MEDIA_VERSION') && $typenow == 'product'){
2393
+ remove_action('icl_post_languages_options_after',array($WPML_media,'language_options'));
2394
  add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
2395
  }
2396
  }
2397
 
2398
  function media_inputs(){
2399
+ echo '<input name="icl_duplicate_attachments" type="hidden" value="1" />';
2400
+ echo '<input name="icl_duplicate_featured_image" type="hidden" value="1" />';
2401
  }
2402
 
2403
  function icl_pro_translation_completed($tr_product_id) {
2728
  function woocommerce_duplicate_product($new_id, $post){
2729
  global $sitepress,$wpdb;
2730
 
2731
+ $sitepress->set_element_language_details($new_id, 'post_' . $post->post_type, false, $sitepress->get_current_language());
2732
  $new_trid = $sitepress->get_element_trid( $new_id, 'post_' . $post->post_type );
2733
 
2734
 
2750
  }
2751
  }
2752
  }
2753
+
2754
  }
2755
 
2756
 
inc/store-pages.class.php CHANGED
@@ -7,6 +7,8 @@ class WCML_Store_Pages{
7
  add_action('init', array($this, 'init'));
8
  add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
9
  add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
 
 
10
  // Translate shop page ids
11
  $this->add_filter_to_get_shop_translated_page_id();
12
  }
@@ -18,7 +20,7 @@ class WCML_Store_Pages{
18
  add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
19
  add_filter('parse_request', array($this, 'adjust_shop_page'));
20
  }
21
-
22
  add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
23
 
24
  if (isset($_POST['create_pages']) && wp_verify_nonce($_POST['wcml_nonce'], 'create_pages')) {
@@ -37,8 +39,8 @@ class WCML_Store_Pages{
37
 
38
  $this->localize_flat_rates_shipping_classes();
39
 
40
- }
41
-
42
  function switch_pages_language( $pages ){
43
  global $sitepress,$wpdb;
44
 
@@ -46,7 +48,7 @@ class WCML_Store_Pages{
46
 
47
  return $pages;
48
  }
49
-
50
  function install_pages_action( $pages ){
51
  global $sitepress,$wpdb;
52
 
@@ -219,37 +221,48 @@ class WCML_Store_Pages{
219
  __('View Order','wpml-wcml'),
220
  __('Shop','wpml-wcml'));
221
 
222
- if ($miss_lang) {
223
  $wp_rewrite = new WP_Rewrite();
224
- $current_language = $sitepress->get_current_language();
225
-
226
- $check_pages = apply_filters('wcml_wc_installed_pages', array(
227
- 'woocommerce_shop_page_id',
228
- 'woocommerce_cart_page_id',
229
- 'woocommerce_checkout_page_id',
230
- 'woocommerce_myaccount_page_id'
231
- ));
232
-
233
  if(in_array($sitepress->get_default_language(), $miss_lang['codes'])){
234
- $miss_lang['codes'] = array_merge(array($sitepress->get_default_language()), array_diff($miss_lang['codes'], array($sitepress->get_default_language())));
235
- }
236
-
237
  foreach ($miss_lang['codes'] as $mis_lang) {
238
  $args = array();
239
 
 
 
 
 
240
  foreach ($check_pages as $page) {
241
-
242
-
243
  $orig_id = get_option($page);
244
  $trnsl_id = icl_object_id($orig_id, 'page', false, $mis_lang);
245
 
246
  if ($orig_id && (is_null($trnsl_id) || get_post_status($trnsl_id) != 'publish')) {
247
  $orig_page = get_post($orig_id);
248
- unload_textdomain('woocommerce');
249
- $sitepress->switch_lang($mis_lang);
250
- $woocommerce->load_plugin_textdomain();
251
 
252
- $args['post_title'] = __($orig_page->post_title, 'woocommerce');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
  $args['post_type'] = $orig_page->post_type;
254
  $args['post_content'] = $orig_page->post_content;
255
  $args['post_excerpt'] = $orig_page->post_excerpt;
@@ -263,21 +276,23 @@ class WCML_Store_Pages{
263
 
264
  if(get_post_status($trnsl_id) == 'trash' && $mis_lang == $sitepress->get_default_language()){
265
  update_option($page, $new_page_id);
266
- }
267
-
268
- $trid = $sitepress->get_element_trid($orig_id, 'post_' . $orig_page->post_type);
269
- $sitepress->set_element_language_details($new_page_id, 'post_' . $orig_page->post_type, $trid, $mis_lang);
270
  if(!is_null($trnsl_id)){
271
- $sitepress->set_element_language_details($trnsl_id, 'post_' . $orig_page->post_type, false, $mis_lang);
272
  }
273
- $sitepress->switch_lang($current_language);
 
 
 
 
274
  }
275
  }
276
- unload_textdomain('woocommerce');
277
- $sitepress->switch_lang($mis_lang);
278
- $woocommerce->load_plugin_textdomain();
279
  }
280
-
281
  wp_redirect(admin_url('admin.php?page=wpml-wcml')); exit;
282
  }
283
  }
@@ -288,12 +303,7 @@ class WCML_Store_Pages{
288
  */
289
  function get_missing_store_pages() {
290
 
291
- $check_pages = apply_filters('wcml_wc_installed_pages', array(
292
- 'woocommerce_shop_page_id',
293
- 'woocommerce_cart_page_id',
294
- 'woocommerce_checkout_page_id',
295
- 'woocommerce_myaccount_page_id'
296
- ));
297
 
298
  $missing_lang = '';
299
 
@@ -379,5 +389,36 @@ class WCML_Store_Pages{
379
  }
380
  return $rates;
381
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
 
383
  }
7
  add_action('init', array($this, 'init'));
8
  add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
9
  add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
10
+ //update wc pages ids after change default language or create new if not exists
11
+ add_action( 'icl_after_set_default_language', array( $this, 'after_set_default_language' ), 10, 2 );
12
  // Translate shop page ids
13
  $this->add_filter_to_get_shop_translated_page_id();
14
  }
20
  add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
21
  add_filter('parse_request', array($this, 'adjust_shop_page'));
22
  }
23
+
24
  add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
25
 
26
  if (isset($_POST['create_pages']) && wp_verify_nonce($_POST['wcml_nonce'], 'create_pages')) {
39
 
40
  $this->localize_flat_rates_shipping_classes();
41
 
42
+ }
43
+
44
  function switch_pages_language( $pages ){
45
  global $sitepress,$wpdb;
46
 
48
 
49
  return $pages;
50
  }
51
+
52
  function install_pages_action( $pages ){
53
  global $sitepress,$wpdb;
54
 
221
  __('View Order','wpml-wcml'),
222
  __('Shop','wpml-wcml'));
223
 
224
+ if ($miss_lang) {
225
  $wp_rewrite = new WP_Rewrite();
226
+
227
+ $check_pages = $this->get_wc_pages();
228
+
 
 
 
 
 
 
229
  if(in_array($sitepress->get_default_language(), $miss_lang['codes'])){
230
+ $miss_lang['codes'] = array_merge(array($sitepress->get_default_language()), array_diff($miss_lang['codes'], array($sitepress->get_default_language())));
231
+ }
232
+
233
  foreach ($miss_lang['codes'] as $mis_lang) {
234
  $args = array();
235
 
236
+ unload_textdomain('wpml-wcml');
237
+ $sitepress->switch_lang($mis_lang);
238
+ $woocommerce_wpml->load_locale();
239
+
240
  foreach ($check_pages as $page) {
 
 
241
  $orig_id = get_option($page);
242
  $trnsl_id = icl_object_id($orig_id, 'page', false, $mis_lang);
243
 
244
  if ($orig_id && (is_null($trnsl_id) || get_post_status($trnsl_id) != 'publish')) {
245
  $orig_page = get_post($orig_id);
 
 
 
246
 
247
+ switch( $page ){
248
+ case 'woocommerce_shop_page_id':
249
+ $page_title = __( 'Shop', 'wpml-wcml');
250
+ break;
251
+ case 'woocommerce_cart_page_id':
252
+ $page_title = __( 'Cart', 'wpml-wcml');
253
+ break;
254
+ case 'woocommerce_checkout_page_id':
255
+ $page_title = __( 'Checkout', 'wpml-wcml');
256
+ break;
257
+ case 'woocommerce_myaccount_page_id':
258
+ $page_title = __( 'My Account', 'wpml-wcml');
259
+ break;
260
+ default:
261
+ $page_title = __( $orig_page->post_title, 'wpml-wcml');
262
+ break;
263
+ }
264
+
265
+ $args['post_title'] = $page_title;
266
  $args['post_type'] = $orig_page->post_type;
267
  $args['post_content'] = $orig_page->post_content;
268
  $args['post_excerpt'] = $orig_page->post_excerpt;
276
 
277
  if(get_post_status($trnsl_id) == 'trash' && $mis_lang == $sitepress->get_default_language()){
278
  update_option($page, $new_page_id);
279
+ }
280
+
 
 
281
  if(!is_null($trnsl_id)){
282
+ $sitepress->set_element_language_details($trnsl_id, 'post_page', false, $mis_lang);
283
  }
284
+
285
+ $trid = $sitepress->get_element_trid($orig_id, 'post_page');
286
+ $sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
287
+
288
+
289
  }
290
  }
291
+ unload_textdomain('wpml-wcml');
292
+ $sitepress->switch_lang($sitepress->get_default_language());
293
+ $woocommerce_wpml->load_locale();
294
  }
295
+
296
  wp_redirect(admin_url('admin.php?page=wpml-wcml')); exit;
297
  }
298
  }
303
  */
304
  function get_missing_store_pages() {
305
 
306
+ $check_pages = $this->get_wc_pages();
 
 
 
 
 
307
 
308
  $missing_lang = '';
309
 
389
  }
390
  return $rates;
391
  }
392
+
393
+ function get_wc_pages(){
394
+ return apply_filters('wcml_wc_installed_pages', array(
395
+ 'woocommerce_shop_page_id',
396
+ 'woocommerce_cart_page_id',
397
+ 'woocommerce_checkout_page_id',
398
+ 'woocommerce_myaccount_page_id'
399
+ ));
400
+ }
401
+
402
+ function after_set_default_language( $code, $previous_code ){
403
+ global $wpdb;
404
+ $this->create_missing_store_pages();
405
+
406
+ $pages = $this->get_wc_pages();
407
+
408
+ foreach( $pages as $page ){
409
+
410
+ if( $page_id = get_option($page) ){
411
+ $trnsl_id = icl_object_id( $page_id, 'page', false, $code );
412
+ if( !is_null( $trnsl_id ) ){
413
+ $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => $page ) );
414
+ }
415
+ }
416
+
417
+ }
418
+
419
+ // Clear any unwanted data
420
+ wc_delete_product_transients();
421
+ delete_transient( 'woocommerce_cache_excluded_uris' );
422
+ }
423
 
424
  }
inc/terms.class.php CHANGED
@@ -52,6 +52,7 @@ class WCML_Terms{
52
  add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
53
  //filter coupons terms in admin
54
  add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
 
55
 
56
  add_filter('woocommerce_attribute',array($this, 'hide_language_suffix'));
57
 
@@ -83,7 +84,7 @@ class WCML_Terms{
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 && is_array( $value ) ){
86
-
87
  $permalinks = get_option( 'woocommerce_permalinks' );
88
  if(empty($permalinks['category_base']) && $value){
89
  remove_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
@@ -265,7 +266,7 @@ class WCML_Terms{
265
  foreach( (array) $value as $k => $v ){
266
 
267
  if( $current_slug != $default_slug && preg_match( '#^[^/]*/?' . $default_slug . '/page/#', $k ) ){
268
-
269
  $k = preg_replace( '#^([^/]*)(/?)' . $default_slug . '/#', '$1$2' . $current_slug . '/' , $k );
270
  }
271
 
@@ -318,49 +319,32 @@ class WCML_Terms{
318
  $permalinks = get_option( 'woocommerce_permalinks' );
319
  $base = $taxonomy == 'product_tag' ? $permalinks['tag_base'] : ($taxonomy == 'product_cat' ? $permalinks['category_base'] : $permalinks['attribute_base']);
320
 
 
 
 
321
  if($base === ''){
322
- // handle exception - default woocommerce category and tag bases used
323
- // get translation from WooCommerce mo files?
324
-
325
- $base_sl = $taxonomy == 'product_tag' ? 'product-tag' : 'product-category'; // strings language
326
- if($term_language->language_code == $strings_language){
327
- $base = _x($base_sl, 'slug', 'woocommerce');
328
- $base_translated = $base_sl;
329
- }else{
330
- $base = _x($base_sl, 'slug', 'woocommerce');
331
-
332
- $mo_file = $woocommerce->plugin_path() . '/i18n/languages/woocommerce-' . $sitepress->get_locale($term_language->language_code) .'.mo';
333
- if(file_exists($mo_file)){
334
- $mo = new MO();
335
- $mo->import_from_file( $mo_file );
336
- $base_translated = $mo->translate($base_sl, 'slug');
337
- }else{
338
- $base_translated = $base_sl;
339
- }
340
-
341
- }
342
- }else{
343
 
344
- $string_identifier = $taxonomy == 'product_tag' || $taxonomy == 'product_cat' ? $taxonomy : 'attribute';
345
- //
346
- if($term_language->language_code != $strings_language){
347
- $base_translated = $wpdb->get_var("
348
- SELECT t.value
349
- FROM {$wpdb->prefix}icl_strings s
350
- JOIN {$wpdb->prefix}icl_string_translations t ON t.string_id = s.id
351
- WHERE s.value='". esc_sql($base)."'
352
- AND s.language = '{$strings_language}'
353
- AND s.name LIKE 'Url {$string_identifier} slug:%'
354
- AND t.language = '{$term_language->language_code}'
355
- ");
356
-
357
- }else{
358
- $base_translated = $base;
359
- }
360
  }
361
 
362
  if(!empty($base_translated) && $base_translated != $base){
363
-
364
  $buff = $wp_rewrite->extra_permastructs[$taxonomy]['struct'];
365
  $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = str_replace($base, $base_translated, $wp_rewrite->extra_permastructs[$taxonomy]['struct']);
366
  $no_recursion_flag = true;
@@ -921,6 +905,24 @@ class WCML_Terms{
921
  add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
922
  $sitepress->switch_lang($current_language);
923
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
924
  return $terms;
925
  }
926
 
52
  add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
53
  //filter coupons terms in admin
54
  add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
55
+ add_filter('get_terms',array($this,'filter_shipping_classes_terms'),10,3);
56
 
57
  add_filter('woocommerce_attribute',array($this, 'hide_language_suffix'));
58
 
84
  // covers the case os using the default product category and tag bases and a default language that's not English
85
  $strings_language = $sitepress_settings['st']['strings_language'];
86
  if($sitepress->get_current_language() != $strings_language && is_array( $value ) ){
87
+
88
  $permalinks = get_option( 'woocommerce_permalinks' );
89
  if(empty($permalinks['category_base']) && $value){
90
  remove_filter('gettext_with_context', array($woocommerce_wpml->strings, 'category_base_in_strings_language'), 99, 3);
266
  foreach( (array) $value as $k => $v ){
267
 
268
  if( $current_slug != $default_slug && preg_match( '#^[^/]*/?' . $default_slug . '/page/#', $k ) ){
269
+
270
  $k = preg_replace( '#^([^/]*)(/?)' . $default_slug . '/#', '$1$2' . $current_slug . '/' , $k );
271
  }
272
 
319
  $permalinks = get_option( 'woocommerce_permalinks' );
320
  $base = $taxonomy == 'product_tag' ? $permalinks['tag_base'] : ($taxonomy == 'product_cat' ? $permalinks['category_base'] : $permalinks['attribute_base']);
321
 
322
+
323
+ $string_identifier = $taxonomy == 'product_tag' || $taxonomy == 'product_cat' ? $taxonomy : 'attribute';
324
+
325
  if($base === ''){
326
+ $base = $taxonomy == 'product_tag' ? 'product-tag' : 'product-category'; // strings language
327
+ icl_register_string('URL ' . $taxonomy . ' slugs - ' . $base, 'Url ' . $string_identifier . ' slug: ' . $base, $base, array('language' => 'en'));
328
+ }
329
+
330
+ //
331
+ if($term_language->language_code != $strings_language){
332
+ $base_translated = $wpdb->get_var("
333
+ SELECT t.value
334
+ FROM {$wpdb->prefix}icl_strings s
335
+ JOIN {$wpdb->prefix}icl_string_translations t ON t.string_id = s.id
336
+ WHERE s.value='". esc_sql($base)."'
337
+ AND s.language = '{$strings_language}'
338
+ AND s.name LIKE 'Url {$string_identifier} slug:%'
339
+ AND t.language = '{$term_language->language_code}'
340
+ ");
 
 
 
 
 
 
341
 
342
+ }else{
343
+ $base_translated = $base;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
344
  }
345
 
346
  if(!empty($base_translated) && $base_translated != $base){
347
+
348
  $buff = $wp_rewrite->extra_permastructs[$taxonomy]['struct'];
349
  $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = str_replace($base, $base_translated, $wp_rewrite->extra_permastructs[$taxonomy]['struct']);
350
  $no_recursion_flag = true;
905
  add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
906
  $sitepress->switch_lang($current_language);
907
  }
908
+
909
+ return $terms;
910
+ }
911
+
912
+ function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
913
+ global $sitepress;
914
+
915
+ if( is_admin() && in_array( 'product_shipping_class', $taxonomies) && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'shipping' ){
916
+ remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
917
+ $current_language = $sitepress->get_current_language();
918
+ $sitepress->switch_lang($sitepress->get_default_language());
919
+ add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
920
+ $terms = get_terms( $taxonomies, $args );
921
+ remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
922
+ add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
923
+ $sitepress->switch_lang($current_language);
924
+ }
925
+
926
  return $terms;
927
  }
928
 
inc/upgrade.class.php CHANGED
@@ -282,8 +282,5 @@ class WCML_Upgrade{
282
  $wpdb->query("DROP TABLE `{$wpdb->prefix}icl_currencies`");
283
 
284
  }
285
-
286
-
287
-
288
-
289
  }
282
  $wpdb->query("DROP TABLE `{$wpdb->prefix}icl_currencies`");
283
 
284
  }
285
+
 
 
 
286
  }
inc/wc-strings.class.php CHANGED
@@ -109,8 +109,7 @@ class WCML_WC_Strings{
109
  global $wpdb, $sitepress, $sitepress_settings;
110
 
111
  if($sitepress->get_current_language() != $sitepress_settings['st']['strings_language']){
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
 
@@ -133,8 +132,7 @@ class WCML_WC_Strings{
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;
@@ -142,8 +140,8 @@ class WCML_WC_Strings{
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
 
@@ -312,4 +310,29 @@ class WCML_WC_Strings{
312
  return $location;
313
  }
314
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
315
  }
109
  global $wpdb, $sitepress, $sitepress_settings;
110
 
111
  if($sitepress->get_current_language() != $sitepress_settings['st']['strings_language']){
112
+ $product_permalink = $this->product_permalink_slug();
 
113
 
114
  $translated_slug = $this->get_translated_product_base_by_lang(false,$product_permalink);
115
 
132
  }
133
 
134
  if(!$product_permalink){
135
+ $product_permalink = $this->product_permalink_slug();
 
136
  }
137
 
138
  global $wpdb;
140
  $translated_slug = $wpdb->get_var($wpdb->prepare("
141
  SELECT t.value FROM {$wpdb->prefix}icl_string_translations t
142
  JOIN {$wpdb->prefix}icl_strings s ON t.string_id = s.id
143
+ WHERE s.name=%s AND s.value = %s AND t.language = %s AND t.status = %d",
144
+ 'URL slug: ' . $product_permalink, $product_permalink, $language, ICL_STRING_TRANSLATION_COMPLETE ));
145
 
146
  return $translated_slug;
147
 
310
  return $location;
311
  }
312
 
313
+
314
+ function get_missed_product_slag_translations_languages(){
315
+ global $sitepress,$wpdb,$sitepress_settings;
316
+
317
+ $slug = $this->product_permalink_slug();
318
+ $default_language = $sitepress->get_default_language();
319
+
320
+ $slug_translation_languages = $wpdb->get_col($wpdb->prepare("SELECT tr.language FROM {$wpdb->prefix}icl_strings AS s LEFT JOIN {$wpdb->prefix}icl_string_translations AS tr ON s.id = tr.string_id WHERE s.name = %s AND s.value = %s AND tr.status = %s", 'URL slug: ' . $slug, $slug, ICL_STRING_TRANSLATION_COMPLETE));
321
+ $miss_slug_lang = array();
322
+ foreach( $sitepress->get_active_languages() as $lang_info ){
323
+ if( !in_array( $lang_info['code'], $slug_translation_languages ) && $lang_info['code'] != $sitepress_settings['st']['strings_language'] ){
324
+ $miss_slug_lang[] = ucfirst($lang_info['display_name']);
325
+ }
326
+ }
327
+
328
+ return $miss_slug_lang;
329
+ }
330
+
331
+
332
+ function product_permalink_slug(){
333
+ $permalinks = get_option( 'woocommerce_permalinks' );
334
+ $slug = empty( $permalinks['product_base'] ) ? 'product' : trim($permalinks['product_base'], '/');
335
+
336
+ return $slug;
337
+ }
338
  }
menu/management.php CHANGED
@@ -38,7 +38,12 @@ if(isset($_GET['tab'])){
38
  <?php endif; ?>
39
  <a class="nav-tab <?php echo $current_tab == 'products' ? 'nav-tab-active' : ''; ?>" href="admin.php?page=wpml-wcml&tab=products"><?php _e('Products', 'wpml-wcml') ?></a>
40
  <?php foreach($products_and_variation_taxonomies as $tax_key => $tax): if(!$sitepress->is_translated_taxonomy($tax_key)) continue; ?>
41
- <a class="nav-tab <?php echo (isset($_GET['tab']) && $_GET['tab'] == $tax_key)?'nav-tab-active':''; ?>" href="admin.php?page=wpml-wcml&tab=<?php echo $tax_key; ?>"><?php echo $tax->labels->name ?></a>
 
 
 
 
 
42
  <?php endforeach; ?>
43
  <?php foreach($all_products_taxonomies as $tax_key => $tax): if(!$sitepress->is_translated_taxonomy($tax_key) || $tax_key == 'product_type') continue; ?>
44
  <a class="js-tax-tab-<?php echo $tax_key ?> nav-tab <?php echo (isset($_GET['tab']) && $_GET['tab'] == $tax_key)?'nav-tab-active':''; ?>" href="admin.php?page=wpml-wcml&tab=<?php echo $tax_key; ?>" <?php if(!WCML_Terms::is_fully_translated($tax_key)): ?>title="<?php esc_attr_e('You have untranslated terms!', 'wpml-wcml'); ?>"<?php endif;?>>
38
  <?php endif; ?>
39
  <a class="nav-tab <?php echo $current_tab == 'products' ? 'nav-tab-active' : ''; ?>" href="admin.php?page=wpml-wcml&tab=products"><?php _e('Products', 'wpml-wcml') ?></a>
40
  <?php foreach($products_and_variation_taxonomies as $tax_key => $tax): if(!$sitepress->is_translated_taxonomy($tax_key)) continue; ?>
41
+ <a class="nav-tab <?php echo (isset($_GET['tab']) && $_GET['tab'] == $tax_key)?'nav-tab-active':''; ?>" href="admin.php?page=wpml-wcml&tab=<?php echo $tax_key; ?>" <?php if(!WCML_Terms::is_fully_translated($tax_key)): ?>title="<?php esc_attr_e('You have untranslated terms!', 'wpml-wcml'); ?>"<?php endif;?>>
42
+ <?php echo $tax->labels->name ?>
43
+ <?php if(!WCML_Terms::is_fully_translated($tax_key)): ?>
44
+ &nbsp;<i class="icon-warning-sign"></i>
45
+ <?php endif; ?>
46
+ </a>
47
  <?php endforeach; ?>
48
  <?php foreach($all_products_taxonomies as $tax_key => $tax): if(!$sitepress->is_translated_taxonomy($tax_key) || $tax_key == 'product_type') continue; ?>
49
  <a class="js-tax-tab-<?php echo $tax_key ?> nav-tab <?php echo (isset($_GET['tab']) && $_GET['tab'] == $tax_key)?'nav-tab-active':''; ?>" href="admin.php?page=wpml-wcml&tab=<?php echo $tax_key; ?>" <?php if(!WCML_Terms::is_fully_translated($tax_key)): ?>title="<?php esc_attr_e('You have untranslated terms!', 'wpml-wcml'); ?>"<?php endif;?>>
menu/sub/products.php CHANGED
@@ -44,7 +44,7 @@ $woocommerce_wpml->update_settings();
44
  <select class="wcml_product_category">
45
  <option value="0"><?php _e('Any category', 'wpml-wcml'); ?></option>
46
  <?php
47
- $product_categories = get_terms('product_cat',array('hide_empty' => 0));
48
  foreach ($product_categories as $category) {
49
  $selected = (isset($_GET['cat']) && $_GET['cat'] == $category->term_taxonomy_id)?'selected="selected"':'';
50
  echo '<option value="'.$category->term_taxonomy_id.'" '.$selected.'>'.$category->name.'</option>';
@@ -62,9 +62,7 @@ $woocommerce_wpml->update_settings();
62
  <?php
63
  $all_statuses = get_post_stati();
64
  //unset unnecessary statuses
65
- unset($all_statuses['trash']);
66
- unset($all_statuses['auto-draft']);
67
- unset($all_statuses['inherit']);
68
  ?>
69
  <select class="wcml_product_status">
70
  <option value="all"><?php _e('All statuses', 'wpml-wcml'); ?></option>
44
  <select class="wcml_product_category">
45
  <option value="0"><?php _e('Any category', 'wpml-wcml'); ?></option>
46
  <?php
47
+ $product_categories = $wpdb->get_results($wpdb->prepare("SELECT tt.term_taxonomy_id,tt.term_id,t.name FROM $wpdb->term_taxonomy AS tt LEFT JOIN $wpdb->terms AS t ON tt.term_id = t.term_id LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = tt.term_taxonomy_id WHERE tt.taxonomy = 'product_cat' AND icl.element_type= 'tax_product_cat' AND icl.language_code = %s",$default_language));
48
  foreach ($product_categories as $category) {
49
  $selected = (isset($_GET['cat']) && $_GET['cat'] == $category->term_taxonomy_id)?'selected="selected"':'';
50
  echo '<option value="'.$category->term_taxonomy_id.'" '.$selected.'>'.$category->name.'</option>';
62
  <?php
63
  $all_statuses = get_post_stati();
64
  //unset unnecessary statuses
65
+ unset( $all_statuses['trash'], $all_statuses['auto-draft'], $all_statuses['inherit'], $all_statuses['wc-pending'], $all_statuses['wc-processing'], $all_statuses['wc-on-hold'], $all_statuses['wc-completed'], $all_statuses['wc-cancelled'], $all_statuses['wc-refunded'], $all_statuses['wc-failed'] );
 
 
66
  ?>
67
  <select class="wcml_product_status">
68
  <option value="all"><?php _e('All statuses', 'wpml-wcml'); ?></option>
menu/sub/settings.php CHANGED
@@ -1,4 +1,6 @@
1
- <?php global $sitepress_settings, $sitepress; ?>
 
 
2
 
3
  <div class="wcml-section">
4
  <div class="wcml-section-header">
@@ -37,7 +39,11 @@
37
  </div> <!-- .wcml-section -->
38
 
39
 
40
- <?php if($sitepress->get_default_language() != 'en' && ($sitepress_settings['st']['strings_language'] != 'en' || empty($woocommerce_wpml->settings['dismiss_non_default_language_warning'])) || !empty($woocommerce_wpml->dependencies->xml_config_errors)): ?>
 
 
 
 
41
  <div class="wcml-section">
42
  <div class="wcml-section-header">
43
  <h3>
@@ -47,7 +53,14 @@
47
  </div>
48
 
49
  <div class="wcml-section-content">
50
- <?php if($sitepress->get_default_language() != 'en'): ?>
 
 
 
 
 
 
 
51
 
52
  <?php if($sitepress_settings['st']['strings_language'] != 'en'): ?>
53
  <p><i class="icon-warning-sign"></i><strong><?php _e('Attention required: probable problem with URLs in different languages', 'wpml-wcml') ?></strong></p>
@@ -560,7 +573,7 @@
560
  JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
561
  WHERE m.meta_key='_custom_conversion_rate' AND t.language_code = %s
562
  ORDER BY m.post_id desc
563
- ", $sitepress->get_default_language()));
564
 
565
  if($posts){
566
  echo "<script>
1
+ <?php global $sitepress_settings, $sitepress;
2
+ $default_language = $sitepress->get_default_language();
3
+ ?>
4
 
5
  <div class="wcml-section">
6
  <div class="wcml-section-header">
39
  </div> <!-- .wcml-section -->
40
 
41
 
42
+ <?php
43
+ $miss_slug_lang = $woocommerce_wpml->strings->get_missed_product_slag_translations_languages();
44
+ $prod_slug = $woocommerce_wpml->strings->product_permalink_slug();
45
+
46
+ if($default_language != 'en' && ($sitepress_settings['st']['strings_language'] != 'en' || empty($woocommerce_wpml->settings['dismiss_non_default_language_warning'])) || !empty($woocommerce_wpml->dependencies->xml_config_errors) || !empty($miss_slug_lang) ): ?>
47
  <div class="wcml-section">
48
  <div class="wcml-section-header">
49
  <h3>
53
  </div>
54
 
55
  <div class="wcml-section-content">
56
+
57
+ <?php if( !empty( $miss_slug_lang ) ): ?>
58
+
59
+ <p><i class="icon-warning-sign"></i><?php printf(__("Your product permalink base is not translated in %s. The urls for the translated products will not work. Go to the %sString Translation%s to translate.", 'wpml-wcml'), '<b>'. implode(', ',$miss_slug_lang).'</b>' ,'<a href="'.admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&search='.$prod_slug.'&context=WordPress').'">', '</a>') ?> </p>
60
+
61
+ <?php endif;?>
62
+
63
+ <?php if($default_language != 'en'): ?>
64
 
65
  <?php if($sitepress_settings['st']['strings_language'] != 'en'): ?>
66
  <p><i class="icon-warning-sign"></i><strong><?php _e('Attention required: probable problem with URLs in different languages', 'wpml-wcml') ?></strong></p>
573
  JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
574
  WHERE m.meta_key='_custom_conversion_rate' AND t.language_code = %s
575
  ORDER BY m.post_id desc
576
+ ", $default_language));
577
 
578
  if($posts){
579
  echo "<script>
menu/sub/troubleshooting.php CHANGED
@@ -59,7 +59,6 @@ unset($all_products_taxonomies['product_type'],$all_products_taxonomies['product
59
  <?php _e('Duplicate terms ( please select attribute ):', 'wpml-wcml') ?>
60
  <select id="attr_to_duplicate" <?php echo !count($all_products_taxonomies)?'disabled="disabled"':''; ?>>
61
  <?php
62
- var_dump(count($all_products_taxonomies));
63
  $terms_count = false;
64
  if(!count($all_products_taxonomies)){ ?>
65
  <option value="0" ><?php _e('none', 'wpml-wcml'); ?></option>
59
  <?php _e('Duplicate terms ( please select attribute ):', 'wpml-wcml') ?>
60
  <select id="attr_to_duplicate" <?php echo !count($all_products_taxonomies)?'disabled="disabled"':''; ?>>
61
  <?php
 
62
  $terms_count = false;
63
  if(!count($all_products_taxonomies)){ ?>
64
  <option value="0" ><?php _e('none', 'wpml-wcml'); ?></option>
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.0
7
  Tested up to: 4.0
8
- Stable tag: 3.3.2
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -77,6 +77,17 @@ In order for the checkout and store pages to appear translated, you need to crea
77
 
78
  == Changelog ==
79
 
 
 
 
 
 
 
 
 
 
 
 
80
  = 3.3.2 =
81
  * Fixed: 'Language warning' appears when editing product translations using the native WooCommerce editor
82
  * Fixed: Variation cannot be added to an existing order
5
  License: GPLv2
6
  Requires at least: 3.0
7
  Tested up to: 4.0
8
+ Stable tag: 3.3.3
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
77
 
78
  == Changelog ==
79
 
80
+ = 3.3.3 =
81
+ * Compatibility with WooCommerce 2.2.x
82
+ * Auto-download WooCommerce translations for active and new languages
83
+ * Page titles translations for WooCommerce pages taken from WooCommerce Multilingual .mo files
84
+ * Product base, product category slug, product tag slug and product attribute bases will always have to be translated via String Translation (not using WooCommerce translations from the mo files)
85
+ * Added warning message on settings page when product base not translated to all languages
86
+ * Fixed: Base currency format ignored after adding additional currency
87
+ * Fixed: Shipping class names were displayed wrong on the WooCommerce settings page when switching the admin language
88
+ * Fixed: WooCommerce pages were not working correctly after changing the default language
89
+ * Fixed: WooCommerce native interface doesn't copy the variations prices
90
+
91
  = 3.3.2 =
92
  * Fixed: 'Language warning' appears when editing product translations using the native WooCommerce editor
93
  * Fixed: Variation cannot be added to an existing order
woocommerce_wpml.class.php CHANGED
@@ -12,7 +12,8 @@ class woocommerce_wpml {
12
  var $missing;
13
 
14
  function __construct(){
15
- add_action('plugins_loaded', array($this, 'init'), 2);
 
16
 
17
  $this->endpoints = new WCML_Endpoints;
18
  }
@@ -23,8 +24,6 @@ class woocommerce_wpml {
23
  $this->settings = $this->get_settings();
24
 
25
  $this->dependencies = new WCML_Dependencies;
26
-
27
- add_action('init', array($this, 'load_css_and_js'));
28
  add_action('admin_menu', array($this, 'menu'));
29
 
30
  if(!$this->dependencies->check()){
@@ -52,7 +51,7 @@ class woocommerce_wpml {
52
  $this->troubleshooting = new WCML_Troubleshooting();
53
  $this->compatibility = new WCML_Compatibility();
54
  $this->strings = new WCML_WC_Strings;
55
-
56
 
57
  if(isset($_GET['page']) && $_GET['page'] == 'wc-reports'){
58
  require_once WCML_PLUGIN_PATH . '/inc/reports.class.php';
@@ -95,7 +94,7 @@ class woocommerce_wpml {
95
  (isset($_GET['page']) && $_GET['page'] == 'shipping_zones') || ( isset($_GET['page']) && $_GET['page'] == 'product_attributes')
96
  )
97
  ){
98
- remove_action( 'wp_before_admin_bar_render', array( $sitepress, 'admin_language_switcher' ) );
99
  }
100
 
101
  if((($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'product') || (($pagenow == 'post-new.php' || $pagenow == 'edit.php') && isset($_GET['post_type']) && $_GET['post_type'] == 'product'))
@@ -106,6 +105,8 @@ class woocommerce_wpml {
106
 
107
  add_action('wp_ajax_wcml_update_setting_ajx', array($this, 'update_setting_ajx'));
108
 
 
 
109
  }
110
 
111
  function translate_product_slug(){
@@ -115,59 +116,22 @@ class woocommerce_wpml {
115
  return;
116
  }
117
  $permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
118
- $slug = get_option('woocommerce_product_slug') != false ? get_option('woocommerce_product_slug') : 'product';
119
 
120
- $string = $wpdb->get_row($wpdb->prepare("SELECT id,status FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", 'URL slug: ' . $slug, $slug));
121
 
 
 
122
  if(!$string){
123
  icl_register_string('WordPress', 'URL slug: ' . $slug, $slug);
124
- $string = $wpdb->get_row($wpdb->prepare("SELECT id,status FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", 'URL slug: ' . $slug, $slug));
125
  }
126
-
127
- if(isset($sitepress_settings['posts_slug_translation']['types'])){
128
- $iclsettings['posts_slug_translation']['types'] = $sitepress_settings['posts_slug_translation']['types'];
129
- }
130
-
131
- if(!empty($permalinks['product_base']) && isset($sitepress_settings['posts_slug_translation']['types'][$slug])){
132
- $iclsettings['posts_slug_translation']['types'][$slug] = 0;
133
- $sitepress->save_settings($iclsettings);
134
- }
135
-
136
- $string_id = $string->id;
137
- $translations = icl_get_string_translations_by_id( $string_id );
138
-
139
- //get translations from .mo files
140
- $current_language = $sitepress->get_current_language();
141
- $default_language = $sitepress->get_default_language();
142
- $active_languages = $sitepress->get_active_languages();
143
-
144
- foreach( $active_languages as $language ){
145
- if( !isset( $translations[ $language['code'] ] ) && isset($sitepress_settings['st'] ) && $language['code'] != $sitepress_settings['st']['strings_language'] ){
146
- $sitepress->switch_lang($language['code']);
147
- $context = 'slug';
148
- $domain = 'woocommerce';
149
- $woocommerce->load_plugin_textdomain();
150
- $string_text = _x( $slug, $context, $domain );
151
- unload_textdomain($domain);
152
- icl_add_string_translation($string_id,$language['code'],$string_text,ICL_STRING_TRANSLATION_COMPLETE,null);
153
- $sitepress->switch_lang($current_language);
154
- }
155
- }
156
- $woocommerce->load_plugin_textdomain();
157
-
158
- if( $string->status != ICL_STRING_TRANSLATION_COMPLETE ){
159
- $wpdb->update(
160
- $wpdb->prefix.'icl_strings',
161
- array(
162
- 'status' => ICL_STRING_TRANSLATION_COMPLETE
163
- ),
164
- array( 'id' => $string_id )
165
- );
166
  }
167
 
168
- $iclsettings['posts_slug_translation']['on'] = 1;
169
- $iclsettings['posts_slug_translation']['types'][$slug] = 1;
170
- $sitepress->save_settings( $iclsettings );
171
  }
172
 
173
  function get_settings(){
@@ -251,6 +215,13 @@ class woocommerce_wpml {
251
  $this->settings['set_up'] = 1;
252
  $this->update_settings();
253
 
 
 
 
 
 
 
 
254
  }
255
 
256
  require_once WCML_PLUGIN_PATH . '/inc/multi-currency.class.php';
@@ -337,7 +308,7 @@ class woocommerce_wpml {
337
  }else{
338
  global $wpdb,$sitepress_settings,$sitepress;
339
  $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
340
- if(isset($sitepress_settings['st']['strings_language']) && !empty($user_lang_pairs[$sitepress->get_default_language()])){
341
  add_menu_page(__('WooCommerce Multilingual','wpml-wcml'),
342
  __('WooCommerce Multilingual','wpml-wcml'), 'wpml_operate_woocommerce_multilingual',
343
  'wpml-wcml', array($this, 'menu_content'), ICL_PLUGIN_URL . '/res/img/icon16.png');
@@ -376,34 +347,34 @@ class woocommerce_wpml {
376
  if( in_array($_GET['page'], array('wpml-wcml',basename(WCML_PLUGIN_PATH).'/menu/sub/troubleshooting.php',basename(WCML_PLUGIN_PATH).'/menu/plugins.php'))) {
377
 
378
 
379
- if ( !wp_style_is( 'toolset-font-awesome', 'registered' ) ) { // check if style are already registered
380
- wp_register_style('toolset-font-awesome', WCML_PLUGIN_URL . '/assets/css/font-awesome.min.css', null, WCML_VERSION); // register if not
381
- }
382
- wp_register_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array('toolset-font-awesome'), WCML_VERSION);
383
- wp_register_style('cleditor', WCML_PLUGIN_URL . '/assets/css/jquery.cleditor.css', null, WCML_VERSION);
384
- wp_register_script('wcml-tm-scripts', WCML_PLUGIN_URL . '/assets/js/scripts.js', array('jquery', 'jquery-ui-resizable'), WCML_VERSION);
385
- wp_register_script('jquery-cookie', WCML_PLUGIN_URL . '/assets/js/jquery.cookie.js', array('jquery'), WCML_VERSION);
386
- wp_register_script('cleditor', WCML_PLUGIN_URL . '/assets/js/jquery.cleditor.min.js', array('jquery'), WCML_VERSION);
387
-
388
- wp_enqueue_style('toolset-font-awesome'); // enqueue styles
389
- wp_enqueue_style('wpml-wcml');
390
- wp_enqueue_style('cleditor');
391
- wp_enqueue_style('wp-pointer');
392
-
393
- wp_enqueue_media();
394
- wp_enqueue_script('wcml-tm-scripts');
395
- wp_enqueue_script('jquery-cookie');
396
- wp_enqueue_script('cleditor');
397
- wp_enqueue_script('suggest');
398
- wp_enqueue_script('wp-pointer');
399
-
 
 
 
 
 
 
400
 
401
- wp_localize_script('wcml-tm-scripts', 'wcml_settings',
402
- array(
403
- 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
404
- )
405
- );
406
-
407
  //load wp-editor srcipts
408
  wp_enqueue_script('word-count');
409
  wp_enqueue_script('editor');
@@ -524,23 +495,26 @@ class woocommerce_wpml {
524
  global $wpdb, $sitepress_settings;
525
 
526
  if(isset($value['product_base']) && $value['product_base']){
527
- icl_register_string('URL slugs - ' . trim($value['product_base'] ,'/'), 'Url slug: ' . trim($value['product_base'] ,'/'), trim($value['product_base'] ,'/'));
528
  // only register. it'll have to be translated via the string translation
529
  }
530
 
531
- if(isset($value['category_base']) && $value['category_base']){
532
- icl_register_string('URL product_cat slugs - ' . trim($value['category_base'] ,'/'), 'Url product_cat slug: ' . trim($value['category_base'] ,'/'), trim($value['category_base'] ,'/'));
533
- }
534
 
535
- if(isset($value['tag_base']) && $value['tag_base']){
536
- icl_register_string('URL product_tag slugs - ' . trim($value['tag_base'] ,'/'), 'Url product_tag slug: ' . trim($value['tag_base'] ,'/'), trim($value['tag_base'] ,'/'));
537
- }
538
 
539
  if(isset($value['attribute_base']) && $value['attribute_base']){
540
  icl_register_string('URL attribute slugs - ' . trim($value['attribute_base'] ,'/'), 'Url attribute slug: ' . trim($value['attribute_base'] ,'/'), trim($value['attribute_base'] ,'/'));
541
  }
542
 
543
- $value['product_base'] = trim($value['product_base'], '/');
 
 
 
 
 
544
 
545
  return $value;
546
 
@@ -566,4 +540,57 @@ class woocommerce_wpml {
566
  }
567
  }
568
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
569
  }
12
  var $missing;
13
 
14
  function __construct(){
15
+ add_action('init', array($this, 'init'),2);
16
+ add_action('init', array($this, 'load_css_and_js'));
17
 
18
  $this->endpoints = new WCML_Endpoints;
19
  }
24
  $this->settings = $this->get_settings();
25
 
26
  $this->dependencies = new WCML_Dependencies;
 
 
27
  add_action('admin_menu', array($this, 'menu'));
28
 
29
  if(!$this->dependencies->check()){
51
  $this->troubleshooting = new WCML_Troubleshooting();
52
  $this->compatibility = new WCML_Compatibility();
53
  $this->strings = new WCML_WC_Strings;
54
+
55
 
56
  if(isset($_GET['page']) && $_GET['page'] == 'wc-reports'){
57
  require_once WCML_PLUGIN_PATH . '/inc/reports.class.php';
94
  (isset($_GET['page']) && $_GET['page'] == 'shipping_zones') || ( isset($_GET['page']) && $_GET['page'] == 'product_attributes')
95
  )
96
  ){
97
+ remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
98
  }
99
 
100
  if((($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'product') || (($pagenow == 'post-new.php' || $pagenow == 'edit.php') && isset($_GET['post_type']) && $_GET['post_type'] == 'product'))
105
 
106
  add_action('wp_ajax_wcml_update_setting_ajx', array($this, 'update_setting_ajx'));
107
 
108
+ //load WC translations
109
+ add_action( 'icl_update_active_languages', array( $this, 'download_woocommerce_translations_for_active_languages' ) );
110
  }
111
 
112
  function translate_product_slug(){
116
  return;
117
  }
118
  $permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
 
119
 
120
+ $slug = get_option('woocommerce_product_slug') != false ? get_option('woocommerce_product_slug') : 'product';
121
 
122
+ $string = $wpdb->get_row($wpdb->prepare("SELECT id, status FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", 'URL slug: ' . $slug, $slug));
123
+
124
  if(!$string){
125
  icl_register_string('WordPress', 'URL slug: ' . $slug, $slug);
126
+ $string = $wpdb->get_row($wpdb->prepare("SELECT id, status FROM {$wpdb->prefix}icl_strings WHERE name = %s AND value = %s ", 'URL slug: ' . $slug, $slug));
127
  }
128
+
129
+ if(empty($sitepress_settings['posts_slug_translation']['on']) || empty($sitepress_settings['posts_slug_translation']['types'][$slug])){
130
+ $iclsettings['posts_slug_translation']['on'] = 1;
131
+ $iclsettings['posts_slug_translation']['types'][$slug] = 1;
132
+ $sitepress->save_settings($iclsettings);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
133
  }
134
 
 
 
 
135
  }
136
 
137
  function get_settings(){
215
  $this->settings['set_up'] = 1;
216
  $this->update_settings();
217
 
218
+
219
+ }
220
+
221
+ if(empty($this->settings['downloaded_translations_for_wc'])){ //from 3.3.3
222
+ $this->download_woocommerce_translations_for_active_languages();
223
+ $this->settings['downloaded_translations_for_wc'] = 1;
224
+ $this->update_settings();
225
  }
226
 
227
  require_once WCML_PLUGIN_PATH . '/inc/multi-currency.class.php';
308
  }else{
309
  global $wpdb,$sitepress_settings,$sitepress;
310
  $user_lang_pairs = get_user_meta(get_current_user_id(), $wpdb->prefix.'language_pairs', true);
311
+ if( !empty( $user_lang_pairs[$sitepress->get_default_language()] ) ){
312
  add_menu_page(__('WooCommerce Multilingual','wpml-wcml'),
313
  __('WooCommerce Multilingual','wpml-wcml'), 'wpml_operate_woocommerce_multilingual',
314
  'wpml-wcml', array($this, 'menu_content'), ICL_PLUGIN_URL . '/res/img/icon16.png');
347
  if( in_array($_GET['page'], array('wpml-wcml',basename(WCML_PLUGIN_PATH).'/menu/sub/troubleshooting.php',basename(WCML_PLUGIN_PATH).'/menu/plugins.php'))) {
348
 
349
 
350
+ if ( !wp_style_is( 'toolset-font-awesome', 'registered' ) ) { // check if style are already registered
351
+ wp_register_style('toolset-font-awesome', WCML_PLUGIN_URL . '/assets/css/font-awesome.min.css', null, WCML_VERSION); // register if not
352
+ }
353
+ wp_register_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array('toolset-font-awesome'), WCML_VERSION);
354
+ wp_register_style('cleditor', WCML_PLUGIN_URL . '/assets/css/jquery.cleditor.css', null, WCML_VERSION);
355
+ wp_register_script('wcml-tm-scripts', WCML_PLUGIN_URL . '/assets/js/scripts.js', array('jquery', 'jquery-ui-core', 'jquery-ui-resizable'), WCML_VERSION);
356
+ wp_register_script('jquery-cookie', WCML_PLUGIN_URL . '/assets/js/jquery.cookie.js', array('jquery'), WCML_VERSION);
357
+ wp_register_script('cleditor', WCML_PLUGIN_URL . '/assets/js/jquery.cleditor.min.js', array('jquery'), WCML_VERSION);
358
+
359
+ wp_enqueue_style('toolset-font-awesome'); // enqueue styles
360
+ wp_enqueue_style('wpml-wcml');
361
+ wp_enqueue_style('cleditor');
362
+ wp_enqueue_style('wp-pointer');
363
+
364
+ wp_enqueue_media();
365
+ wp_enqueue_script('wcml-tm-scripts');
366
+ wp_enqueue_script('jquery-cookie');
367
+ wp_enqueue_script('cleditor');
368
+ wp_enqueue_script('suggest');
369
+ wp_enqueue_script('wp-pointer');
370
+
371
+
372
+ wp_localize_script('wcml-tm-scripts', 'wcml_settings',
373
+ array(
374
+ 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
375
+ )
376
+ );
377
 
 
 
 
 
 
 
378
  //load wp-editor srcipts
379
  wp_enqueue_script('word-count');
380
  wp_enqueue_script('editor');
495
  global $wpdb, $sitepress_settings;
496
 
497
  if(isset($value['product_base']) && $value['product_base']){
498
+ icl_register_string('WordPress', 'Url slug: ' . trim($value['product_base'] ,'/'), trim($value['product_base'] ,'/'));
499
  // only register. it'll have to be translated via the string translation
500
  }
501
 
502
+ $category_base = !empty($value['category_base']) ? trim($value['category_base'], '/') : 'product-category';
503
+ icl_register_string('URL product_cat slugs - ' . $category_base, 'Url product_cat slug: ' . $category_base, $category_base );
 
504
 
505
+ $tag_base = !empty($value['tag_base']) ? trim($value['tag_base'], '/') : 'product-tag';
506
+ icl_register_string('URL product_tag slugs - ' . $tag_base, 'Url product_tag slug: ' . $tag_base, $tag_base);
 
507
 
508
  if(isset($value['attribute_base']) && $value['attribute_base']){
509
  icl_register_string('URL attribute slugs - ' . trim($value['attribute_base'] ,'/'), 'Url attribute slug: ' . trim($value['attribute_base'] ,'/'), trim($value['attribute_base'] ,'/'));
510
  }
511
 
512
+ if(isset($value['product_base']) && !$value['product_base']){
513
+ $value['product_base'] = get_option('woocommerce_product_slug') != false ? get_option('woocommerce_product_slug') : 'product';
514
+ }else{
515
+ $value['product_base'] = trim($value['product_base'], '/');
516
+ }
517
+
518
 
519
  return $value;
520
 
540
  }
541
  }
542
 
543
+ //download translations for WC
544
+ function download_woocommerce_translations( $lang_code ){
545
+ global $sitepress;
546
+
547
+ $locale = $sitepress->get_locale( $lang_code );
548
+
549
+ if( $locale != 'en_US' ){
550
+ $sitepress->switch_lang( $lang_code );
551
+
552
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
553
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
554
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
555
+
556
+ $url = 'update-core.php?action=do-translation-upgrade';
557
+ $nonce = 'upgrade-translations';
558
+ $title = '';
559
+ $context = WP_LANG_DIR;
560
+ $wc_upgrader_class = new WC_Language_Pack_Upgrader();
561
+
562
+ $upgrader = new Language_Pack_Upgrader( new Automatic_Upgrader_Skin( compact( 'url', 'nonce', 'title', 'context' ) ) ); // use Language_Pack_Upgrader_Skin instead of Automatic_Upgrader_Skin to display upgrade process
563
+
564
+ $upgr_object = array();
565
+ $upgr_object[0] = new stdClass();
566
+ $upgr_object[0]->type = 'plugin';
567
+ $upgr_object[0]->slug = 'woocommerce';
568
+ $upgr_object[0]->language = $locale;
569
+ $upgr_object[0]->version = WC_VERSION;
570
+ $upgr_object[0]->updated = date('Y-m-d H:i:s');
571
+ $upgr_object[0]->package = $wc_upgrader_class->get_language_package_uri();
572
+ $upgr_object[0]->autoupdate = 1;
573
+
574
+ $upgrader->bulk_upgrade( $upgr_object );
575
+ }
576
+
577
+ }
578
+
579
+
580
+ function download_woocommerce_translations_for_active_languages(){
581
+ global $sitepress;
582
+
583
+ $active_languages = $sitepress->get_active_languages();
584
+
585
+ $current_language = $sitepress->get_current_language();
586
+
587
+ foreach( $active_languages as $language ){
588
+
589
+ $this->download_woocommerce_translations( $language['code'] );
590
+
591
+ }
592
+
593
+ $sitepress->switch_lang( $current_language );
594
+ }
595
+
596
  }
wpml-woocommerce.php CHANGED
@@ -3,14 +3,14 @@
3
  Plugin Name: WooCommerce Multilingual
4
  Plugin URI: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
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.2
9
  */
10
 
11
 
12
  if(defined('WCML_VERSION')) return;
13
- define('WCML_VERSION', '3.3.2');
14
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
15
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
16
  define('WCML_PLUGIN_URL', plugins_url() . '/' . WCML_PLUGIN_FOLDER);
@@ -38,4 +38,18 @@ require WCML_PLUGIN_PATH . '/inc/compatibility.class.php';
38
  require WCML_PLUGIN_PATH . '/inc/endpoints.class.php';
39
 
40
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
 
 
 
 
 
41
  $woocommerce_wpml = new woocommerce_wpml();
 
 
 
 
 
 
 
 
 
3
  Plugin Name: WooCommerce Multilingual
4
  Plugin URI: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
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: OnTheGoSystems
7
+ Author URI: http://www.onthegosystems.com/
8
+ Version: 3.3.3
9
  */
10
 
11
 
12
  if(defined('WCML_VERSION')) return;
13
+ define('WCML_VERSION', '3.3.3');
14
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
15
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
16
  define('WCML_PLUGIN_URL', plugins_url() . '/' . WCML_PLUGIN_FOLDER);
38
  require WCML_PLUGIN_PATH . '/inc/endpoints.class.php';
39
 
40
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
41
+
42
+
43
+ function wpml_wcml_startup() {
44
+ global $woocommerce_wpml;
45
+
46
  $woocommerce_wpml = new woocommerce_wpml();
47
+ }
48
+
49
+ if ( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ) {
50
+ //@since WPML 3.2 Create instance of WPML_String_Translation using dependencies hook
51
+ add_action( 'wpml_load_dependencies', 'wpml_wcml_startup', 10000 );
52
+ } else {
53
+ //@since 3.3.2 Create instance of WPML_String_Translation using a late 'plugins_loaded' action
54
+ add_action('plugins_loaded', 'wpml_wcml_startup', 10000);
55
+ }