WooCommerce Multilingual – run WooCommerce with WPML - Version 4.0.4

Version Description

  • Bug fix: empty shipping class was shown on the Quick Editor when using WooCommerce Table Rate Shipping
  • Bug fix: the Translation Editor could not save the same slug for translations of the same product
  • Bug fix: sales by product reports were inorect when filterign by languages including a dash character in their code
  • Bug fix: as of version 4.0.2 the option to use custom settings for translations download files was not always working
  • Bug fix: a PHP fatal error was shown when WooCommerce Multilingual was active but WooCommerce was not active
  • Bug fix: global attributes of variations were not copied to transltions when using the native interface to edit product translations
  • Bug fix: it was not possible to add multiple bookings in the cart at one time (when using WooCommerce Bookings)
  • Bug fix: custom URL parameters were not preserved when switching the language on the shop page
  • Fixed various incompatibilities with PHP 7.1
Download this release

Release Info

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

Code changes from version 4.0.3 to 4.0.4

Files changed (52) hide show
  1. compatibility/class-wcml-adventure-tours.php +1 -1
  2. compatibility/class-wcml-bookings.php +27 -7
  3. compatibility/class-wcml-composite-products.php +1 -1
  4. compatibility/class-wcml-pip.php +1 -1
  5. compatibility/class-wcml-product-bundles.php +1 -1
  6. compatibility/class-wcml-table-rate-shipping.php +19 -2
  7. inc/abstracts/class-wcml-exchange-rate-service.php +110 -110
  8. inc/admin-menus/class-wcml-admin-menus.php +296 -296
  9. inc/admin-menus/class-wcml-links.php +24 -24
  10. inc/admin-menus/class-wcml-pointers.php +81 -81
  11. inc/admin-menus/class-wcml-setup.php +352 -352
  12. inc/class-wcml-ajax-setup.php +159 -159
  13. inc/class-wcml-attributes.php +462 -403
  14. inc/class-wcml-capabilities.php +32 -32
  15. inc/class-wcml-cart-removed-items-widget.php +27 -27
  16. inc/class-wcml-cart.php +440 -444
  17. inc/class-wcml-compatibility.php +175 -175
  18. inc/class-wcml-coupons.php +87 -87
  19. inc/class-wcml-dependencies.php +345 -345
  20. inc/class-wcml-emails.php +488 -488
  21. inc/class-wcml-endpoints.php +285 -286
  22. inc/class-wcml-fix-copied-custom-fields-wpml353.php +39 -39
  23. inc/class-wcml-install.php +263 -263
  24. inc/class-wcml-languages-upgrader.php +300 -300
  25. inc/class-wcml-locale.php +61 -61
  26. inc/class-wcml-media.php +183 -183
  27. inc/class-wcml-orders.php +381 -381
  28. inc/class-wcml-products-screen-options.php +46 -46
  29. inc/class-wcml-products.php +540 -505
  30. inc/class-wcml-reports.php +267 -267
  31. inc/class-wcml-requests.php +86 -86
  32. inc/class-wcml-resources.php +243 -243
  33. inc/class-wcml-store-pages.php +614 -594
  34. inc/class-wcml-terms.php +968 -968
  35. inc/class-wcml-tp-support.php +316 -316
  36. inc/class-wcml-troubleshooting.php +248 -248
  37. inc/class-wcml-upgrade.php +531 -531
  38. inc/class-wcml-url-translation.php +821 -821
  39. inc/class-wcml-wc-gateways.php +186 -186
  40. inc/class-wcml-wc-shipping.php +227 -227
  41. inc/class-wcml-wc-strings.php +470 -470
  42. inc/class-wcml-widgets.php +25 -25
  43. inc/class-wcml-woocommerce-rest-api-support.php +412 -412
  44. inc/class-wcml-xdomain-data.php +92 -92
  45. inc/class-woocommerce-wpml.php +291 -291
  46. inc/constants.php +13 -13
  47. inc/currencies/class-wcml-admin-currency-selector.php +166 -166
  48. inc/currencies/class-wcml-currencies.php +23 -23
  49. inc/currencies/class-wcml-currency-switcher-widget.php +24 -24
  50. inc/currencies/class-wcml-currency-switcher.php +184 -180
  51. inc/currencies/class-wcml-custom-prices.php +472 -520
  52. inc/currencies/class-wcml-exchange-rates.php +0 -273
compatibility/class-wcml-adventure-tours.php CHANGED
@@ -71,7 +71,7 @@ class WCML_Adventure_tours{
71
 
72
  $trnsl_tour_tabs_meta['tour_badge'] = $tour_tabs_meta['tour_badge'];
73
 
74
- update_post_meta( $product_translation->element_id, '_bto_data', $trnsl_tour_tabs_meta);
75
 
76
  }
77
 
71
 
72
  $trnsl_tour_tabs_meta['tour_badge'] = $tour_tabs_meta['tour_badge'];
73
 
74
+ update_post_meta( $product_translation->element_id, 'tour_tabs_meta', $trnsl_tour_tabs_meta);
75
 
76
  }
77
 
compatibility/class-wcml-bookings.php CHANGED
@@ -180,6 +180,8 @@ class WCML_Bookings {
180
 
181
  add_filter( 'wpml_tm_dashboard_translatable_types', array( $this, 'hide_bookings_type_on_tm_dashboard' ) );
182
 
 
 
183
  }
184
 
185
  function wcml_price_field_after_booking_base_cost( $post_id ) {
@@ -996,7 +998,7 @@ class WCML_Bookings {
996
  $product_id = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int)$_GET['post'] : false;
997
 
998
  if( $product_id && get_post_type( $product_id ) === 'product' ){
999
- $product_type = Deprecated_WC_Functions::get_product_type( $product_id );
1000
 
1001
  if ( ( $product_type === 'booking' || $product_type === $external_product_type ) || $pagenow == 'post-new.php' ) {
1002
 
@@ -1227,7 +1229,7 @@ class WCML_Bookings {
1227
  }
1228
 
1229
  function custom_box_html( $obj, $product_id, $data ) {
1230
- if ( Deprecated_WC_Functions::get_product_type( $product_id ) !== 'booking' ) {
1231
  return;
1232
  }
1233
 
@@ -1290,7 +1292,7 @@ class WCML_Bookings {
1290
 
1291
  function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1292
 
1293
- if ( Deprecated_WC_Functions::get_product_type( $product_id ) !== 'booking' ) {
1294
  return $data;
1295
  }
1296
 
@@ -1768,7 +1770,7 @@ class WCML_Bookings {
1768
  function append_persons_to_translation_package( $package, $post ) {
1769
 
1770
  if ( $post->post_type == 'product' ) {
1771
- $product_type = Deprecated_WC_Functions::get_product_type( $post->ID );
1772
 
1773
  if ( $product_type === 'booking' ) {
1774
 
@@ -1803,7 +1805,7 @@ class WCML_Bookings {
1803
  function save_person_translation( $post_id, $data, $job ) {
1804
  $person_translations = array();
1805
 
1806
- if ( Deprecated_WC_Functions::get_product_type( $post_id ) === 'booking' ) {
1807
 
1808
  foreach ( $data as $value ) {
1809
 
@@ -1870,7 +1872,7 @@ class WCML_Bookings {
1870
  if ( $post->post_type == 'product' ) {
1871
  $product = wc_get_product( $post->ID );
1872
 
1873
- $product_type = Deprecated_WC_Functions::get_product_type( $post->ID );
1874
 
1875
  if ( $product_type === 'booking' && $product->has_resources() ) {
1876
 
@@ -1897,7 +1899,7 @@ class WCML_Bookings {
1897
  function save_resource_translation( $post_id, $data, $job ) {
1898
  $resource_translations = array();
1899
 
1900
- if ( Deprecated_WC_Functions::get_product_type( $post_id ) === 'booking' ) {
1901
 
1902
  foreach ( $data as $value ) {
1903
 
@@ -2249,4 +2251,22 @@ class WCML_Bookings {
2249
 
2250
  }
2251
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2252
  }
180
 
181
  add_filter( 'wpml_tm_dashboard_translatable_types', array( $this, 'hide_bookings_type_on_tm_dashboard' ) );
182
 
183
+ add_filter( 'wcml_add_to_cart_sold_individually', array( $this, 'add_to_cart_sold_individually' ), 10, 4 );
184
+
185
  }
186
 
187
  function wcml_price_field_after_booking_base_cost( $post_id ) {
998
  $product_id = $pagenow == 'post.php' && isset( $_GET['post'] ) ? (int)$_GET['post'] : false;
999
 
1000
  if( $product_id && get_post_type( $product_id ) === 'product' ){
1001
+ $product_type = WooCommerce_Functions_Wrapper::get_product_type( $product_id );
1002
 
1003
  if ( ( $product_type === 'booking' || $product_type === $external_product_type ) || $pagenow == 'post-new.php' ) {
1004
 
1229
  }
1230
 
1231
  function custom_box_html( $obj, $product_id, $data ) {
1232
+ if ( WooCommerce_Functions_Wrapper::get_product_type( $product_id ) !== 'booking' ) {
1233
  return;
1234
  }
1235
 
1292
 
1293
  function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1294
 
1295
+ if ( WooCommerce_Functions_Wrapper::get_product_type( $product_id ) !== 'booking' ) {
1296
  return $data;
1297
  }
1298
 
1770
  function append_persons_to_translation_package( $package, $post ) {
1771
 
1772
  if ( $post->post_type == 'product' ) {
1773
+ $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
1774
 
1775
  if ( $product_type === 'booking' ) {
1776
 
1805
  function save_person_translation( $post_id, $data, $job ) {
1806
  $person_translations = array();
1807
 
1808
+ if ( WooCommerce_Functions_Wrapper::get_product_type( $post_id ) === 'booking' ) {
1809
 
1810
  foreach ( $data as $value ) {
1811
 
1872
  if ( $post->post_type == 'product' ) {
1873
  $product = wc_get_product( $post->ID );
1874
 
1875
+ $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
1876
 
1877
  if ( $product_type === 'booking' && $product->has_resources() ) {
1878
 
1899
  function save_resource_translation( $post_id, $data, $job ) {
1900
  $resource_translations = array();
1901
 
1902
+ if ( WooCommerce_Functions_Wrapper::get_product_type( $post_id ) === 'booking' ) {
1903
 
1904
  foreach ( $data as $value ) {
1905
 
2251
 
2252
  }
2253
 
2254
+ public function add_to_cart_sold_individually( $sold_indiv, $cart_item_data, $product_id, $quantity ){
2255
+
2256
+ if( isset( $cart_item_data[ 'booking' ] ) ){
2257
+ $sold_indiv = false;
2258
+ foreach( WC()->cart->cart_contents as $cart_item ){
2259
+ if(
2260
+ isset( $cart_item[ 'booking' ] ) &&
2261
+ $cart_item[ 'booking' ][ '_start_date' ] == $cart_item_data[ 'booking' ][ '_start_date' ] &&
2262
+ $cart_item[ 'booking' ][ '_end_date' ] == $cart_item_data[ 'booking' ][ '_end_date' ]
2263
+ ){
2264
+ $sold_indiv = true;
2265
+ }
2266
+ }
2267
+ }
2268
+
2269
+ return $sold_indiv;
2270
+ }
2271
+
2272
  }
compatibility/class-wcml-composite-products.php CHANGED
@@ -448,7 +448,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
448
  function load_assets( ){
449
  global $pagenow;
450
 
451
- if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && Deprecated_WC_Functions::get_product_type( $_GET[ 'post' ] ) === 'composite' ) || $pagenow == 'post-new.php' ){
452
  wp_register_script( 'wcml-composite-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-composite.js', array( 'jquery' ), WCML_VERSION );
453
  wp_enqueue_script( 'wcml-composite-js' );
454
 
448
  function load_assets( ){
449
  global $pagenow;
450
 
451
+ if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && WooCommerce_Functions_Wrapper::get_product_type( $_GET[ 'post' ] ) === 'composite' ) || $pagenow == 'post-new.php' ){
452
  wp_register_script( 'wcml-composite-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-composite.js', array( 'jquery' ), WCML_VERSION );
453
  wp_enqueue_script( 'wcml-composite-js' );
454
 
compatibility/class-wcml-pip.php CHANGED
@@ -77,7 +77,7 @@ class WCML_Pip{
77
 
78
  $the_order = new WC_Order( $pip_order_id );
79
  if( $the_order ){
80
- $currency = Deprecated_WC_Functions::get_order_currency( $the_order );
81
 
82
  if( !$currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
83
  $currency = $_COOKIE[ '_wcml_order_currency' ];
77
 
78
  $the_order = new WC_Order( $pip_order_id );
79
  if( $the_order ){
80
+ $currency = WooCommerce_Functions_Wrapper::get_order_currency( $the_order );
81
 
82
  if( !$currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
83
  $currency = $_COOKIE[ '_wcml_order_currency' ];
compatibility/class-wcml-product-bundles.php CHANGED
@@ -327,7 +327,7 @@ class WCML_Product_Bundles{
327
 
328
  function resync_bundle_clean( $cart ) {
329
  foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
330
- if ( isset( $cart_item[ 'bundled_items' ] ) && Deprecated_WC_Functions::get_product_type( $cart_item[ 'product_id' ] ) === 'bundle' ) {
331
  if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
332
  unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
333
  }
327
 
328
  function resync_bundle_clean( $cart ) {
329
  foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
330
+ if ( isset( $cart_item[ 'bundled_items' ] ) && WooCommerce_Functions_Wrapper::get_product_type( $cart_item[ 'product_id' ] ) === 'bundle' ) {
331
  if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
332
  unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
333
  }
compatibility/class-wcml-table-rate-shipping.php CHANGED
@@ -76,10 +76,25 @@ class WCML_Table_Rate_Shipping {
76
  public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
77
  global $icl_adjust_id_url_filter_off, $pagenow;
78
 
79
- if( $pagenow != 'post.php' && ( get_post_type( $post_id ) == 'product' || get_post_type( $post_id ) == 'product_variation' ) && $taxonomy == 'product_shipping_class' ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
  foreach ( $terms as $k => $term ) {
82
- $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $this->sitepress->get_default_language() );
 
83
 
84
  $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
85
  $icl_adjust_id_url_filter_off = true;
@@ -88,6 +103,8 @@ class WCML_Table_Rate_Shipping {
88
 
89
  $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
90
  }
 
 
91
  }
92
 
93
  return $terms;
76
  public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
77
  global $icl_adjust_id_url_filter_off, $pagenow;
78
 
79
+ if( $terms && $pagenow != 'post.php' && ( get_post_type( $post_id ) == 'product' || get_post_type( $post_id ) == 'product_variation' ) && $taxonomy == 'product_shipping_class' ){
80
+
81
+ if( is_admin() ){
82
+ $shipp_class_language = $this->woocommerce_wpml->products->get_original_product_language( $post_id );
83
+ }else {
84
+ $shipp_class_language = $this->sitepress->get_default_language();
85
+ }
86
+
87
+ $cache_key = md5( json_encode ( $terms ) );
88
+ $cache_key .= ":".$post_id.$shipp_class_language;
89
+
90
+ $cache_group = 'trnsl_shipping_class';
91
+ $cache_terms = wp_cache_get( $cache_key, $cache_group );
92
+
93
+ if( $cache_terms ) return $cache_terms;
94
 
95
  foreach ( $terms as $k => $term ) {
96
+
97
+ $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $shipp_class_language );
98
 
99
  $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
100
  $icl_adjust_id_url_filter_off = true;
103
 
104
  $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
105
  }
106
+
107
+ wp_cache_set ( $cache_key, $terms, $cache_group );
108
  }
109
 
110
  return $terms;
inc/abstracts/class-wcml-exchange-rate-service.php CHANGED
@@ -1,111 +1,111 @@
1
- <?php
2
-
3
- abstract class WCML_Exchange_Rate_Service{
4
-
5
- private $id;
6
- private $name;
7
- private $url;
8
- private $api_url;
9
-
10
- private $settings = array();
11
-
12
- protected $api_key = '';
13
-
14
- const REQUIRES_KEY = false;
15
-
16
- public function __construct( $id, $name, $api_url, $url = '' ) {
17
-
18
- $this->id = $id;
19
- $this->name = $name;
20
- $this->api_url = $api_url;
21
- $this->url = $url;
22
-
23
- $this->settings = get_option('wcml_exchange_rate_service_' . $this->id, array() );
24
-
25
- if( $this->is_key_required() ){
26
- $this->api_key = $this->get_setting( 'api-key' );
27
- }
28
-
29
- }
30
-
31
- public function get_name(){
32
- return $this->name;
33
- }
34
-
35
- public function get_url(){
36
- return $this->url;
37
- }
38
-
39
- /**
40
- * @param $from
41
- * @param $to
42
- * @return mixed
43
- */
44
- public abstract function get_rates( $from, $to );
45
-
46
- /**
47
- * @return array
48
- */
49
- public function get_settings(){
50
- return $this->settings;
51
- }
52
-
53
- /**
54
- *
55
- */
56
- private function save_settings(){
57
- update_option('wcml_exchange_rate_service_' . $this->id, $this->settings);
58
- }
59
-
60
- /**
61
- * @param $key string
62
- * @return mixed|null
63
- */
64
- public function get_setting( $key ){
65
- return isset( $this->settings[$key] ) ? $this->settings[$key] : null;
66
- }
67
-
68
- /**
69
- * @param $key string
70
- * @param $value mixed
71
- */
72
- public function save_setting( $key, $value ){
73
- $this->settings[$key] = $value;
74
- $this->save_settings();
75
- }
76
-
77
- /**
78
- * @return bool
79
- */
80
- public function is_key_required(){
81
- return static::REQUIRES_KEY;
82
- }
83
-
84
- /**
85
- * @param $error_message string
86
- */
87
- public function save_last_error( $error_message ){
88
- $this->save_setting( 'last_error',
89
- array(
90
- 'text' => $error_message,
91
- 'time' => date_i18n( 'F j, Y g:i a', current_time( 'timestamp' ) )
92
- )
93
- );
94
- }
95
-
96
- /**
97
- *
98
- */
99
- public function clear_last_error(){
100
- $this->save_setting( 'last_error', false );
101
- }
102
-
103
- /**
104
- * @return mixed
105
- */
106
- public function get_last_error(){
107
- return isset( $this->settings['last_error'] ) ? $this->settings['last_error'] : false;
108
- }
109
-
110
-
111
  }
1
+ <?php
2
+
3
+ abstract class WCML_Exchange_Rate_Service{
4
+
5
+ private $id;
6
+ private $name;
7
+ private $url;
8
+ private $api_url;
9
+
10
+ private $settings = array();
11
+
12
+ protected $api_key = '';
13
+
14
+ const REQUIRES_KEY = false;
15
+
16
+ public function __construct( $id, $name, $api_url, $url = '' ) {
17
+
18
+ $this->id = $id;
19
+ $this->name = $name;
20
+ $this->api_url = $api_url;
21
+ $this->url = $url;
22
+
23
+ $this->settings = get_option('wcml_exchange_rate_service_' . $this->id, array() );
24
+
25
+ if( $this->is_key_required() ){
26
+ $this->api_key = $this->get_setting( 'api-key' );
27
+ }
28
+
29
+ }
30
+
31
+ public function get_name(){
32
+ return $this->name;
33
+ }
34
+
35
+ public function get_url(){
36
+ return $this->url;
37
+ }
38
+
39
+ /**
40
+ * @param $from
41
+ * @param $to
42
+ * @return mixed
43
+ */
44
+ public abstract function get_rates( $from, $to );
45
+
46
+ /**
47
+ * @return array
48
+ */
49
+ public function get_settings(){
50
+ return $this->settings;
51
+ }
52
+
53
+ /**
54
+ *
55
+ */
56
+ private function save_settings(){
57
+ update_option('wcml_exchange_rate_service_' . $this->id, $this->settings);
58
+ }
59
+
60
+ /**
61
+ * @param $key string
62
+ * @return mixed|null
63
+ */
64
+ public function get_setting( $key ){
65
+ return isset( $this->settings[$key] ) ? $this->settings[$key] : null;
66
+ }
67
+
68
+ /**
69
+ * @param $key string
70
+ * @param $value mixed
71
+ */
72
+ public function save_setting( $key, $value ){
73
+ $this->settings[$key] = $value;
74
+ $this->save_settings();
75
+ }
76
+
77
+ /**
78
+ * @return bool
79
+ */
80
+ public function is_key_required(){
81
+ return static::REQUIRES_KEY;
82
+ }
83
+
84
+ /**
85
+ * @param $error_message string
86
+ */
87
+ public function save_last_error( $error_message ){
88
+ $this->save_setting( 'last_error',
89
+ array(
90
+ 'text' => $error_message,
91
+ 'time' => date_i18n( 'F j, Y g:i a', current_time( 'timestamp' ) )
92
+ )
93
+ );
94
+ }
95
+
96
+ /**
97
+ *
98
+ */
99
+ public function clear_last_error(){
100
+ $this->save_setting( 'last_error', false );
101
+ }
102
+
103
+ /**
104
+ * @return mixed
105
+ */
106
+ public function get_last_error(){
107
+ return isset( $this->settings['last_error'] ) ? $this->settings['last_error'] : false;
108
+ }
109
+
110
+
111
  }
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -1,297 +1,297 @@
1
- <?php
2
-
3
- class WCML_Admin_Menus{
4
-
5
- private static $woocommerce_wpml;
6
- private static $sitepress;
7
- private static $wpdb;
8
-
9
- public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
- self::$woocommerce_wpml =& $woocommerce_wpml;
11
- self::$sitepress =& $sitepress;
12
- self::$wpdb =& $wpdb;
13
-
14
- add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
15
-
16
- if( self::is_page_without_admin_language_switcher() ){
17
- self::remove_wpml_admin_language_switcher();
18
- }
19
-
20
- if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
- add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
22
- add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
23
- add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
24
- }
25
-
26
- add_filter( 'woocommerce_prevent_admin_access', array( __CLASS__, 'check_user_admin_access' ) );
27
-
28
- add_action( 'admin_head', array( __CLASS__, 'add_menu_warning' ) );
29
- }
30
-
31
- public static function register_menus(){
32
- global $WPML_Translation_Management;
33
-
34
- if( self::$woocommerce_wpml->check_dependencies || class_exists( 'WooCommerce' ) ) {
35
-
36
- add_submenu_page(
37
- 'woocommerce',
38
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
39
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
40
- 'wpml_operate_woocommerce_multilingual',
41
- 'wpml-wcml',
42
- array( __CLASS__, 'render_menus' )
43
- );
44
-
45
- if( !current_user_can('wpml_manage_woocommerce_multilingual') && current_user_can('wpml_operate_woocommerce_multilingual') ) {
46
- //force add translations-queue page for shop manager
47
- $wp_api = self::$sitepress->get_wp_api();
48
- if (!$wp_api->current_user_can('wpml_manage_translation_management')) {
49
- $wp_api->add_submenu_page(null,
50
- __('Translations', 'wpml-translation-management'), __('Translations', 'wpml-translation-management'),
51
- 'wpml_operate_woocommerce_multilingual', WPML_TM_FOLDER . '/menu/translations-queue.php', array($WPML_Translation_Management, 'translation_queue_page'));
52
- }
53
- }
54
- } else {
55
-
56
- add_menu_page(
57
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
58
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
59
- 'wpml_manage_woocommerce_multilingual',
60
- 'wpml-wcml',
61
- array( __CLASS__, 'render_menus' ),
62
- WCML_PLUGIN_URL . '/res/images/icon16.png'
63
- );
64
-
65
- }
66
- }
67
-
68
- public static function render_menus(){
69
-
70
- if( self::$woocommerce_wpml->check_dependencies ){
71
- $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
72
- $menus_wrap->show();
73
- }else{
74
- global $sitepress;
75
- $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
76
- $plugins_wrap->show();
77
- }
78
-
79
- }
80
-
81
- private static function is_page_without_admin_language_switcher(){
82
- global $pagenow;
83
-
84
- $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
85
- $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
86
- $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
87
-
88
- $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
89
- $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
90
- $get_post_type &&
91
- in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
92
- $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
93
- in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
94
- $is_shipping_zones = $get_page == 'shipping_zones';
95
- $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
96
-
97
-
98
- return is_admin() && (
99
- $is_page_wpml_wcml ||
100
- $is_new_order_or_coupon ||
101
- $is_edit_order_or_coupon ||
102
- $is_shipping_zones ||
103
- $is_attributes_page
104
- );
105
-
106
- }
107
-
108
- public static function remove_wpml_admin_language_switcher(){
109
-
110
- remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
111
-
112
- }
113
-
114
- public static function documentation_links() {
115
- global $post, $pagenow;
116
-
117
- if ( is_null( $post ) )
118
- return;
119
-
120
- $get_post_type = get_post_type( $post->ID );
121
-
122
- if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
123
- $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
124
- sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
125
- 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
126
- __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
127
- '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
128
- ) . '</p></div>';
129
- $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
130
- ?>
131
- <script type="text/javascript">
132
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
133
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
134
- jQuery(".quick_hide a").on('click', function () {
135
- jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
136
- });
137
-
138
- //lock feature for translations
139
- jQuery(document).on('click', '.featured a', function () {
140
- if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
141
- return false;
142
- }
143
-
144
- });
145
- </script>
146
- <?php
147
- }
148
-
149
- if ( isset($_GET['taxonomy']) ) {
150
- $pos = strpos( $_GET['taxonomy'], 'pa_' );
151
-
152
- if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
153
- $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
154
- __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
155
- ?>
156
- <script type="text/javascript">
157
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
158
- </script>
159
- <?php
160
- }
161
- }
162
-
163
- if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
164
-
165
- $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
166
- __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
167
- ?>
168
- <script type="text/javascript">
169
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
170
- </script>
171
- <?php
172
- }
173
- }
174
-
175
- public static function hide_multilingual_content_setup_box(){
176
- remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
177
- remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
178
- }
179
-
180
- public static function restrict_admin_with_redirect() {
181
- global $pagenow;
182
-
183
- $default_lang = self::$sitepress->get_default_language();
184
- $current_lang = self::$sitepress->get_current_language();
185
-
186
- if(
187
- ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
188
- ( $pagenow == 'admin.php' &&
189
- isset( $_GET[ 'action' ] ) &&
190
- $_GET[ 'action'] == 'duplicate_product' &&
191
- isset( $_GET[ 'post' ] )
192
- )
193
- ){
194
- $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
195
- }
196
-
197
- if(
198
- !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
199
- $pagenow == 'post.php' &&
200
- isset( $_GET[ 'post' ] )&&
201
- get_post_type( $_GET[ 'post' ] ) == 'product' &&
202
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
203
- {
204
- add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
205
- }
206
-
207
- if(
208
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
209
- $pagenow == 'post.php' &&
210
- !is_ajax() &&
211
- isset( $_GET[ 'post' ] ) &&
212
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
213
- get_post_type( $_GET[ 'post' ] ) == 'product'
214
- ) {
215
- if(
216
- !isset( $_GET[ 'action' ] ) ||
217
- ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
218
- ) {
219
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
220
- exit;
221
- }
222
- }
223
-
224
- if(
225
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
226
- $pagenow == 'admin.php' &&
227
- isset( $_GET[ 'action' ] ) &&
228
- $_GET[ 'action' ] == 'duplicate_product' &&
229
- $default_lang != $prod_lang )
230
- {
231
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
232
- exit;
233
- }
234
- }
235
-
236
- public static function inf_editing_product_in_non_default_lang(){
237
- if( !self::$woocommerce_wpml->settings[ 'dismiss_tm_warning' ] ) {
238
- $url = $_SERVER['REQUEST_URI'];
239
-
240
- $message = '<div class="message error otgs-is-dismissible"><p>';
241
- $message .= sprintf(
242
- __('The recommended way to translate WooCommerce products is using the
243
- %sWooCommerce Multilingual products translation%s page.
244
- Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
245
- 'woocommerce-multilingual'),
246
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=products') . '">', '</a></strong>');
247
- $message .= '</p><a class="notice-dismiss" href="' . $url . '&wcml_action=dismiss_tm_warning"><span class="screen-reader-text">' . __('Dismiss', 'woocommerce-multilingual') . '</a>';
248
- $message .= '</div>';
249
-
250
- echo $message;
251
- }
252
- }
253
-
254
- public static function check_user_admin_access( $prevent_access ){
255
-
256
- if( self::$woocommerce_wpml->check_dependencies ){
257
- $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
258
- if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
259
- return false;
260
- }
261
- }
262
-
263
- return $prevent_access;
264
- }
265
-
266
- public static function add_menu_warning(){
267
- global $submenu, $menu;
268
-
269
- if (
270
- class_exists( 'woocommerce' ) &&
271
- (
272
- empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
273
- (
274
- empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
275
- self::$woocommerce_wpml->settings['set_up_wizard_splash']
276
- )
277
- )
278
- ) {
279
- if( isset( $submenu[ 'woocommerce' ] ) ){
280
- foreach( $submenu[ 'woocommerce' ] as $key => $menu_item ) {
281
- if ( $menu_item[ 0 ] == __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ) ) {
282
- $submenu[ 'woocommerce' ][ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
283
- break;
284
- }
285
- }
286
- }
287
-
288
- foreach( $menu as $key => $menu_item ) {
289
- if ( $menu_item[ 0 ] == __( 'WooCommerce', 'woocommerce' ) ) {
290
- $menu[ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
291
- break;
292
- }
293
- }
294
- }
295
- }
296
-
297
  }
1
+ <?php
2
+
3
+ class WCML_Admin_Menus{
4
+
5
+ private static $woocommerce_wpml;
6
+ private static $sitepress;
7
+ private static $wpdb;
8
+
9
+ public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
+ self::$woocommerce_wpml =& $woocommerce_wpml;
11
+ self::$sitepress =& $sitepress;
12
+ self::$wpdb =& $wpdb;
13
+
14
+ add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
15
+
16
+ if( self::is_page_without_admin_language_switcher() ){
17
+ self::remove_wpml_admin_language_switcher();
18
+ }
19
+
20
+ if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
+ add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
22
+ add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
23
+ add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
24
+ }
25
+
26
+ add_filter( 'woocommerce_prevent_admin_access', array( __CLASS__, 'check_user_admin_access' ) );
27
+
28
+ add_action( 'admin_head', array( __CLASS__, 'add_menu_warning' ) );
29
+ }
30
+
31
+ public static function register_menus(){
32
+ global $WPML_Translation_Management;
33
+
34
+ if( self::$woocommerce_wpml->check_dependencies || class_exists( 'WooCommerce' ) ) {
35
+
36
+ add_submenu_page(
37
+ 'woocommerce',
38
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
39
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
40
+ 'wpml_operate_woocommerce_multilingual',
41
+ 'wpml-wcml',
42
+ array( __CLASS__, 'render_menus' )
43
+ );
44
+
45
+ if( !current_user_can('wpml_manage_woocommerce_multilingual') && current_user_can('wpml_operate_woocommerce_multilingual') ) {
46
+ //force add translations-queue page for shop manager
47
+ $wp_api = self::$sitepress->get_wp_api();
48
+ if (!$wp_api->current_user_can('wpml_manage_translation_management')) {
49
+ $wp_api->add_submenu_page(null,
50
+ __('Translations', 'wpml-translation-management'), __('Translations', 'wpml-translation-management'),
51
+ 'wpml_operate_woocommerce_multilingual', WPML_TM_FOLDER . '/menu/translations-queue.php', array($WPML_Translation_Management, 'translation_queue_page'));
52
+ }
53
+ }
54
+ } else {
55
+
56
+ add_menu_page(
57
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
58
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
59
+ 'wpml_manage_woocommerce_multilingual',
60
+ 'wpml-wcml',
61
+ array( __CLASS__, 'render_menus' ),
62
+ WCML_PLUGIN_URL . '/res/images/icon16.png'
63
+ );
64
+
65
+ }
66
+ }
67
+
68
+ public static function render_menus(){
69
+
70
+ if( self::$woocommerce_wpml->check_dependencies ){
71
+ $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
72
+ $menus_wrap->show();
73
+ }else{
74
+ global $sitepress;
75
+ $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
76
+ $plugins_wrap->show();
77
+ }
78
+
79
+ }
80
+
81
+ private static function is_page_without_admin_language_switcher(){
82
+ global $pagenow;
83
+
84
+ $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
85
+ $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
86
+ $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
87
+
88
+ $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
89
+ $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
90
+ $get_post_type &&
91
+ in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
92
+ $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
93
+ in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
94
+ $is_shipping_zones = $get_page == 'shipping_zones';
95
+ $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
96
+
97
+
98
+ return is_admin() && (
99
+ $is_page_wpml_wcml ||
100
+ $is_new_order_or_coupon ||
101
+ $is_edit_order_or_coupon ||
102
+ $is_shipping_zones ||
103
+ $is_attributes_page
104
+ );
105
+
106
+ }
107
+
108
+ public static function remove_wpml_admin_language_switcher(){
109
+
110
+ remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
111
+
112
+ }
113
+
114
+ public static function documentation_links() {
115
+ global $post, $pagenow;
116
+
117
+ if ( is_null( $post ) )
118
+ return;
119
+
120
+ $get_post_type = get_post_type( $post->ID );
121
+
122
+ if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
123
+ $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
124
+ sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
125
+ 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
126
+ __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
127
+ '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
128
+ ) . '</p></div>';
129
+ $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
130
+ ?>
131
+ <script type="text/javascript">
132
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
133
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
134
+ jQuery(".quick_hide a").on('click', function () {
135
+ jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
136
+ });
137
+
138
+ //lock feature for translations
139
+ jQuery(document).on('click', '.featured a', function () {
140
+ if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
141
+ return false;
142
+ }
143
+
144
+ });
145
+ </script>
146
+ <?php
147
+ }
148
+
149
+ if ( isset($_GET['taxonomy']) ) {
150
+ $pos = strpos( $_GET['taxonomy'], 'pa_' );
151
+
152
+ if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
153
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
154
+ __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
155
+ ?>
156
+ <script type="text/javascript">
157
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
158
+ </script>
159
+ <?php
160
+ }
161
+ }
162
+
163
+ if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
164
+
165
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
166
+ __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
167
+ ?>
168
+ <script type="text/javascript">
169
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
170
+ </script>
171
+ <?php
172
+ }
173
+ }
174
+
175
+ public static function hide_multilingual_content_setup_box(){
176
+ remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
177
+ remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
178
+ }
179
+
180
+ public static function restrict_admin_with_redirect() {
181
+ global $pagenow;
182
+
183
+ $default_lang = self::$sitepress->get_default_language();
184
+ $current_lang = self::$sitepress->get_current_language();
185
+
186
+ if(
187
+ ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
188
+ ( $pagenow == 'admin.php' &&
189
+ isset( $_GET[ 'action' ] ) &&
190
+ $_GET[ 'action'] == 'duplicate_product' &&
191
+ isset( $_GET[ 'post' ] )
192
+ )
193
+ ){
194
+ $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
195
+ }
196
+
197
+ if(
198
+ !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
199
+ $pagenow == 'post.php' &&
200
+ isset( $_GET[ 'post' ] )&&
201
+ get_post_type( $_GET[ 'post' ] ) == 'product' &&
202
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
203
+ {
204
+ add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
205
+ }
206
+
207
+ if(
208
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
209
+ $pagenow == 'post.php' &&
210
+ !is_ajax() &&
211
+ isset( $_GET[ 'post' ] ) &&
212
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
213
+ get_post_type( $_GET[ 'post' ] ) == 'product'
214
+ ) {
215
+ if(
216
+ !isset( $_GET[ 'action' ] ) ||
217
+ ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
218
+ ) {
219
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
220
+ exit;
221
+ }
222
+ }
223
+
224
+ if(
225
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
226
+ $pagenow == 'admin.php' &&
227
+ isset( $_GET[ 'action' ] ) &&
228
+ $_GET[ 'action' ] == 'duplicate_product' &&
229
+ $default_lang != $prod_lang )
230
+ {
231
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
232
+ exit;
233
+ }
234
+ }
235
+
236
+ public static function inf_editing_product_in_non_default_lang(){
237
+ if( !self::$woocommerce_wpml->settings[ 'dismiss_tm_warning' ] ) {
238
+ $url = $_SERVER['REQUEST_URI'];
239
+
240
+ $message = '<div class="message error otgs-is-dismissible"><p>';
241
+ $message .= sprintf(
242
+ __('The recommended way to translate WooCommerce products is using the
243
+ %sWooCommerce Multilingual products translation%s page.
244
+ Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
245
+ 'woocommerce-multilingual'),
246
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=products') . '">', '</a></strong>');
247
+ $message .= '</p><a class="notice-dismiss" href="' . $url . '&wcml_action=dismiss_tm_warning"><span class="screen-reader-text">' . __('Dismiss', 'woocommerce-multilingual') . '</a>';
248
+ $message .= '</div>';
249
+
250
+ echo $message;
251
+ }
252
+ }
253
+
254
+ public static function check_user_admin_access( $prevent_access ){
255
+
256
+ if( self::$woocommerce_wpml->check_dependencies ){
257
+ $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
258
+ if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
259
+ return false;
260
+ }
261
+ }
262
+
263
+ return $prevent_access;
264
+ }
265
+
266
+ public static function add_menu_warning(){
267
+ global $submenu, $menu;
268
+
269
+ if (
270
+ class_exists( 'woocommerce' ) &&
271
+ (
272
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
273
+ (
274
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
275
+ self::$woocommerce_wpml->settings['set_up_wizard_splash']
276
+ )
277
+ )
278
+ ) {
279
+ if( isset( $submenu[ 'woocommerce' ] ) ){
280
+ foreach( $submenu[ 'woocommerce' ] as $key => $menu_item ) {
281
+ if ( $menu_item[ 0 ] == __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ) ) {
282
+ $submenu[ 'woocommerce' ][ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
283
+ break;
284
+ }
285
+ }
286
+ }
287
+
288
+ foreach( $menu as $key => $menu_item ) {
289
+ if ( $menu_item[ 0 ] == __( 'WooCommerce', 'woocommerce' ) ) {
290
+ $menu[ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ }
296
+
297
  }
inc/admin-menus/class-wcml-links.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
-
3
- class WCML_Links {
4
-
5
- public static function generate_tracking_link( $link, $term = false, $content = false, $id = false ) {
6
-
7
- $params = '?utm_source=wcml-admin&utm_medium=plugin&utm_term=';
8
- $params .= $term ? $term : 'WPML';
9
- $params .= '&utm_content=';
10
- $params .= $content ? $content : 'required-plugins';
11
- $params .= '&utm_campaign=WCML';
12
-
13
- if ( $id ) {
14
- $params .= $id;
15
- }
16
- return $link . $params;
17
-
18
- }
19
-
20
- public static function filter_woocommerce_redirect_location( $link ) {
21
- global $sitepress;
22
- return html_entity_decode( $sitepress->convert_url( $link ) );
23
- }
24
-
25
  }
1
+ <?php
2
+
3
+ class WCML_Links {
4
+
5
+ public static function generate_tracking_link( $link, $term = false, $content = false, $id = false ) {
6
+
7
+ $params = '?utm_source=wcml-admin&utm_medium=plugin&utm_term=';
8
+ $params .= $term ? $term : 'WPML';
9
+ $params .= '&utm_content=';
10
+ $params .= $content ? $content : 'required-plugins';
11
+ $params .= '&utm_campaign=WCML';
12
+
13
+ if ( $id ) {
14
+ $params .= $id;
15
+ }
16
+ return $link . $params;
17
+
18
+ }
19
+
20
+ public static function filter_woocommerce_redirect_location( $link ) {
21
+ global $sitepress;
22
+ return html_entity_decode( $sitepress->convert_url( $link ) );
23
+ }
24
+
25
  }
inc/admin-menus/class-wcml-pointers.php CHANGED
@@ -1,82 +1,82 @@
1
- <?php
2
-
3
- class WCML_Pointers{
4
-
5
- public function __construct(){
6
- add_action( 'admin_head', array( $this, 'setup') );
7
- }
8
-
9
- public function setup(){
10
- $current_screen = get_current_screen();
11
-
12
- if( empty($current_screen) ) {
13
- return;
14
- }
15
-
16
- $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
17
- $section = isset( $_GET['section'] ) ? $_GET['section'] : '';
18
- wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
19
-
20
- if( $current_screen->id == 'edit-product' ){
21
- add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
22
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'shipping' && $section == 'classes' ){
23
- add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
24
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && ( $tab == 'general' || empty($tab) ) ){
25
- add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
26
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'account'){
27
- add_filter( 'woocommerce_account_settings', array( $this, 'add_endpoints_translation_link' ) );
28
- }
29
-
30
- }
31
-
32
- public function add_products_translation_link(){
33
- $link = admin_url('admin.php?page=wpml-wcml');
34
- $name = __('Translate WooCommerce products', 'woocommerce-multilingual');
35
- wp_enqueue_style( 'wcml-pointers');
36
- ?>
37
- <script type="text/javascript">
38
- jQuery(".subsubsub").append('<a class="button button-small button-wpml wcml-pointer-products_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
39
- </script>
40
- <?php
41
- }
42
-
43
- public function add_shipping_classes_translation_link(){
44
- $link = admin_url('admin.php?page=wpml-wcml&tab=product_shipping_class');
45
- $name = __('Translate shipping classes', 'woocommerce-multilingual');
46
- wp_enqueue_style( 'wcml-pointers');
47
- ?>
48
- <script type="text/javascript">
49
- jQuery(".wc-shipping-classes").before('<a class="button button-small button-wpml wcml-pointer-shipping_classes_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
50
- </script>
51
- <?php
52
- }
53
-
54
- public function add_multi_currency_link( $settings ){
55
- $link = admin_url('admin.php?page=wpml-wcml&tab=multi-currency');
56
- $name = __('Configure multi-currency for multilingual sites', 'woocommerce-multilingual');
57
- wp_enqueue_style( 'wcml-pointers');
58
- foreach( $settings as $key => $value ){
59
- if( $value['id'] == 'pricing_options' && isset( $value['desc'] ) ){
60
-
61
- $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
62
- }
63
- }
64
-
65
- return $settings;
66
- }
67
-
68
- public function add_endpoints_translation_link( $settings ){
69
- $link = admin_url('admin.php?page=wpml-wcml&tab=slugs');
70
- $name = __('Translate endpoints', 'woocommerce-multilingual');
71
- wp_enqueue_style( 'wcml-pointers');
72
- foreach( $settings as $key => $value ){
73
- if( $value['id'] == 'account_endpoint_options' && isset( $value['desc'] ) ){
74
-
75
- $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
76
- }
77
- }
78
-
79
- return $settings;
80
- }
81
-
82
  }
1
+ <?php
2
+
3
+ class WCML_Pointers{
4
+
5
+ public function __construct(){
6
+ add_action( 'admin_head', array( $this, 'setup') );
7
+ }
8
+
9
+ public function setup(){
10
+ $current_screen = get_current_screen();
11
+
12
+ if( empty($current_screen) ) {
13
+ return;
14
+ }
15
+
16
+ $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
17
+ $section = isset( $_GET['section'] ) ? $_GET['section'] : '';
18
+ wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
19
+
20
+ if( $current_screen->id == 'edit-product' ){
21
+ add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
22
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'shipping' && $section == 'classes' ){
23
+ add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
24
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && ( $tab == 'general' || empty($tab) ) ){
25
+ add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
26
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'account'){
27
+ add_filter( 'woocommerce_account_settings', array( $this, 'add_endpoints_translation_link' ) );
28
+ }
29
+
30
+ }
31
+
32
+ public function add_products_translation_link(){
33
+ $link = admin_url('admin.php?page=wpml-wcml');
34
+ $name = __('Translate WooCommerce products', 'woocommerce-multilingual');
35
+ wp_enqueue_style( 'wcml-pointers');
36
+ ?>
37
+ <script type="text/javascript">
38
+ jQuery(".subsubsub").append('<a class="button button-small button-wpml wcml-pointer-products_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
39
+ </script>
40
+ <?php
41
+ }
42
+
43
+ public function add_shipping_classes_translation_link(){
44
+ $link = admin_url('admin.php?page=wpml-wcml&tab=product_shipping_class');
45
+ $name = __('Translate shipping classes', 'woocommerce-multilingual');
46
+ wp_enqueue_style( 'wcml-pointers');
47
+ ?>
48
+ <script type="text/javascript">
49
+ jQuery(".wc-shipping-classes").before('<a class="button button-small button-wpml wcml-pointer-shipping_classes_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
50
+ </script>
51
+ <?php
52
+ }
53
+
54
+ public function add_multi_currency_link( $settings ){
55
+ $link = admin_url('admin.php?page=wpml-wcml&tab=multi-currency');
56
+ $name = __('Configure multi-currency for multilingual sites', 'woocommerce-multilingual');
57
+ wp_enqueue_style( 'wcml-pointers');
58
+ foreach( $settings as $key => $value ){
59
+ if( $value['id'] == 'pricing_options' && isset( $value['desc'] ) ){
60
+
61
+ $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
62
+ }
63
+ }
64
+
65
+ return $settings;
66
+ }
67
+
68
+ public function add_endpoints_translation_link( $settings ){
69
+ $link = admin_url('admin.php?page=wpml-wcml&tab=slugs');
70
+ $name = __('Translate endpoints', 'woocommerce-multilingual');
71
+ wp_enqueue_style( 'wcml-pointers');
72
+ foreach( $settings as $key => $value ){
73
+ if( $value['id'] == 'account_endpoint_options' && isset( $value['desc'] ) ){
74
+
75
+ $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
76
+ }
77
+ }
78
+
79
+ return $settings;
80
+ }
81
+
82
  }
inc/admin-menus/class-wcml-setup.php CHANGED
@@ -1,353 +1,353 @@
1
- <?php
2
-
3
- class WCML_Setup {
4
-
5
- private $step;
6
- private $woocommerce_wpml;
7
- private $sitepress;
8
- private $next_step = false;
9
-
10
-
11
- public function __construct( &$woocommerce_wpml, &$sitepress ){
12
-
13
- $this->woocommerce_wpml =& $woocommerce_wpml;
14
- $this->sitepress =& $sitepress;
15
-
16
- $this->setup_redirect();
17
-
18
- $this->steps = array(
19
- 'introduction' => array(
20
- 'name' => __( 'Introduction', 'woocommerce-multilingual' ),
21
- 'view' => array( $this, 'setup_introduction' ),
22
- 'handler' => ''
23
- ),
24
- 'store-pages' => array(
25
- 'name' => __( 'Store Pages', 'woocommerce-multilingual' ),
26
- 'view' => array( $this, 'setup_store_pages' ),
27
- 'handler' => array( $this, 'install_store_pages' ),
28
- ),
29
- 'attributes' => array(
30
- 'name' => __( 'Global Attributes', 'woocommerce-multilingual' ),
31
- 'view' => array( $this, 'setup_attributes' ),
32
- 'handler' => array( $this, 'save_attributes' )
33
- ),
34
- 'multi-currency' => array(
35
- 'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
36
- 'view' => array( $this, 'setup_multi_currency' ),
37
- 'handler' => array( $this, 'save_multi_currency' )
38
- ),
39
- 'ready' => array(
40
- 'name' => __( 'Ready!', 'woocommerce-multilingual' ),
41
- 'view' => array( $this, 'setup_ready' ),
42
- 'handler' => ''
43
- )
44
- );
45
-
46
- if( current_user_can( 'manage_options' ) ) {
47
- if ( isset( $_GET['page'] ) && $_GET['page'] === 'wcml-setup' ) {
48
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
49
- }
50
- add_action( 'admin_init', array($this, 'setup_wizard') );
51
-
52
- add_action( 'admin_init', array($this, 'handle_steps'), 0 );
53
- add_filter( 'wp_redirect', array($this, 'redirect_filters') );
54
- }
55
-
56
- if( !$this->has_completed() ){
57
- add_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
58
- add_action( 'admin_init', array( $this, 'skip_setup' ), 1 );
59
- }
60
-
61
- }
62
-
63
- private function setup_redirect(){
64
-
65
- if ( get_transient( '_wcml_activation_redirect' ) ) {
66
- delete_transient( '_wcml_activation_redirect' );
67
-
68
- $woocommerce_notices = get_option( 'woocommerce_admin_notices', array() );
69
- $woocommerce_setup_not_run = in_array( 'install', $woocommerce_notices );
70
-
71
- if (
72
- ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], array( 'wcml-setup' ) ) ) ||
73
- is_network_admin() ||
74
- isset( $_GET['activate-multi'] ) ||
75
- ! current_user_can( 'manage_options' ) ||
76
- $woocommerce_setup_not_run
77
- ) {
78
- return;
79
- }
80
-
81
- if( !$this->has_completed()){
82
- wp_safe_redirect( admin_url( 'index.php?page=wcml-setup' ) );
83
- exit;
84
- }
85
- }
86
- }
87
-
88
- public function admin_menus() {
89
- add_dashboard_page( '', '', 'manage_options', 'wcml-setup', '' );
90
- }
91
-
92
- public function setup_wizard_notice(){
93
- wp_enqueue_style( 'wcml-setup-wizard-notice', WCML_PLUGIN_URL . '/res/css/wcml-setup-wizard-notice.css' );
94
- ?>
95
- <div id="wcml-setup-wizard" class="updated message wpml-message">
96
- <p>
97
- <strong><?php _e('Prepare your WooCommerce store to run multilingual!', 'woocommerce-multilingual'); ?></strong><br />
98
- <?php _e('We need to help you with a few steps to turn your WooCommerce store multilingual. These steps include:', 'woocommerce-multilingual'); ?>
99
- <ul class="wcml-notice-list">
100
- <li><?php _e("Translating the 'store' pages", 'woocommerce-multilingual'); ?></li>
101
- <li><?php _e("Choosing which attributes to make translatable", 'woocommerce-multilingual'); ?></li>
102
- <li><?php _e("Choosing if you need multiple currencies", 'woocommerce-multilingual'); ?></li>
103
- </ul>
104
- </p>
105
- <p class="submit">
106
- <a href="<?php echo esc_url( admin_url('admin.php?page=wcml-setup') ); ?>" class="button-primary"><?php _e('Start the Setup Wizard', 'woocommerce-multilingual') ?></a>
107
- <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcml-setup-skip', 1 ), 'wcml_setup_skip_nonce', '_wcml_setup_nonce' ) ); ?>" class="button-secondary skip"><?php _e('Skip', 'woocommerce-multilingual') ?></a>
108
- </p>
109
- </div>
110
- <?php
111
- }
112
-
113
- public function skip_setup(){
114
-
115
- if ( isset( $_GET['wcml-setup-skip'] ) && isset( $_GET['_wcml_setup_nonce'] ) ) {
116
- if ( ! wp_verify_nonce( $_GET['_wcml_setup_nonce'], 'wcml_setup_skip_nonce' ) ) {
117
- wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-multilingual' ) );
118
- }
119
-
120
- if ( ! current_user_can( 'manage_options' ) ) {
121
- wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
122
- }
123
-
124
- $this->complete_setup();
125
- remove_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
126
-
127
- delete_transient( '_wcml_activation_redirect' );
128
- }
129
-
130
- }
131
-
132
- public function complete_setup(){
133
- $this->woocommerce_wpml->settings['set_up_wizard_run'] = 1;
134
- $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
135
- $this->woocommerce_wpml->update_settings();
136
- }
137
-
138
- public function has_completed(){
139
-
140
- return !empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] );
141
-
142
- }
143
-
144
- public function splash_wizard_on_wcml_pages(){
145
-
146
- if( isset( $_GET['src'] ) && $_GET['src'] == 'setup_later' ){
147
- $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
148
- $this->woocommerce_wpml->update_settings();
149
- }
150
-
151
- if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && !$this->has_completed() && empty( $this->woocommerce_wpml->settings['set_up_wizard_splash'] )){
152
- wp_redirect('admin.php?page=wcml-setup');
153
- exit;
154
- }
155
- }
156
-
157
- public function setup_wizard() {
158
-
159
- $this->splash_wizard_on_wcml_pages();
160
-
161
- if ( empty( $_GET['page'] ) || 'wcml-setup' !== $_GET['page'] ) {
162
- return;
163
- }
164
-
165
- $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
166
-
167
- wp_enqueue_style( 'wcml-setup', WCML_PLUGIN_URL . '/res/css/wcml-setup.css', array( 'dashicons', 'install' ), WCML_VERSION );
168
- wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array('jquery'), WCML_VERSION );
169
-
170
- $this->setup_header();
171
- $this->setup_steps();
172
- $this->setup_content();
173
- $this->setup_footer();
174
-
175
- if( $this->step == 'ready' ){
176
- $this->complete_setup();
177
- }
178
-
179
- exit;
180
- }
181
-
182
- private function setup_header() {
183
- set_current_screen('wcml-setup');
184
- ?>
185
- <!DOCTYPE html>
186
- <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
187
- <head>
188
- <meta name="viewport" content="width=device-width" />
189
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
190
- <title><?php _e( 'WooCommerce Multilingual &rsaquo; Setup Wizard', 'woocommerce-multilingual' ); ?></title>
191
- <?php wp_print_scripts( 'wcml-setup' ); ?>
192
- <?php do_action( 'admin_print_styles' ); ?>
193
- <?php do_action( 'admin_head' ); ?>
194
- </head>
195
- <body class="wcml-setup wp-core-ui">
196
- <h1 id="wcml-logo"><a href="https://wpml.org/woocommerce-multilingual"><img src="<?php echo WCML_PLUGIN_URL ?>/res/images/banner-772x120.png" alt="WooCommerce Multilingual" /></a></h1>
197
-
198
- <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
199
- <form class="wcml-setup-form" method="post">
200
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( $this->step ) ?>" />
201
- <input type="hidden" name="handle_step" value="<?php echo $this->step ?>" />
202
- <?php endif; ?>
203
- <?php
204
- }
205
-
206
- private function setup_content(){
207
-
208
- echo '<div class="wcml-setup-content">';
209
- call_user_func( $this->steps[ $this->step ]['view'] );
210
- echo '</div>';
211
-
212
- }
213
-
214
- private function setup_footer() {
215
- ?>
216
- <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
217
- </form>
218
- <?php endif ?>
219
- </body>
220
- </html>
221
- <?php
222
- }
223
-
224
- private function setup_steps() {
225
-
226
- $steps = array_keys( $this->steps );
227
- $step_index = array_search( $this->step, $steps );
228
- $this->next_step = isset( $steps[$step_index + 1] ) ? $steps[$step_index + 1] : '';
229
-
230
- $ouput_steps = $this->steps;
231
- array_shift( $ouput_steps );
232
- ?>
233
- <ol class="wcml-setup-steps">
234
- <?php foreach ( $ouput_steps as $step_key => $step ) : ?>
235
- <li class="<?php
236
- if ( $step_key === $this->step ) {
237
- echo 'active';
238
- } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
239
- echo 'done';
240
- }
241
- ?>"><?php echo esc_html( $step['name'] ); ?></li>
242
- <?php endforeach; ?>
243
- </ol>
244
- <?php
245
- }
246
-
247
- private function next_step_url(){
248
- $url = admin_url('admin.php?page=wcml-setup&step=' . $this->next_step );
249
- return $url;
250
- }
251
-
252
- public function setup_introduction(){
253
- $ui = new WCML_Setup_Introduction_UI( $this->woocommerce_wpml, $this->next_step_url() );
254
- echo $ui->get_view();
255
- }
256
-
257
- public function setup_store_pages(){
258
-
259
- $ui = new WCML_Setup_Store_Pages_UI( $this->woocommerce_wpml, $this->sitepress, $this->next_step_url() );
260
- echo $ui->get_view();
261
- }
262
-
263
- public function setup_attributes(){
264
- $ui = new WCML_Setup_Attributes_UI( $this->woocommerce_wpml, $this->next_step_url() );
265
- echo $ui->get_view();
266
- }
267
-
268
- public function setup_multi_currency(){
269
- $ui = new WCML_Setup_Multi_Currency_UI( $this->woocommerce_wpml, $this->next_step_url() );
270
- echo $ui->get_view();
271
- }
272
-
273
- public function setup_ready(){
274
- $ui = new WCML_Setup_Ready_UI( $this->woocommerce_wpml );
275
- echo $ui->get_view();
276
- }
277
-
278
-
279
- public function redirect_filters( $url ){
280
-
281
- if( isset($_POST['next_step_url']) && $_POST['next_step_url'] ){
282
- $url = sanitize_text_field( $_POST['next_step_url'] );
283
- }
284
-
285
- return $url;
286
- }
287
-
288
-
289
- private function get_handler( $step ){
290
- $handler = !empty( $this->steps[ $step ]['handler'] ) ? $this->steps[ $step ]['handler'] : '';
291
- return $handler;
292
-
293
- }
294
-
295
- public function handle_steps(){
296
-
297
- if( isset( $_POST[ 'handle_step' ] ) && $_POST['nonce'] == wp_create_nonce( $_POST[ 'handle_step' ] ) ){
298
-
299
- $step_name = sanitize_text_field( $_POST[ 'handle_step' ] );
300
-
301
- if( $handler = $this->get_handler( $step_name )){
302
- call_user_func( $handler, $_POST );
303
- }
304
-
305
- }
306
-
307
- }
308
-
309
- /**
310
- * handler
311
- */
312
- public function save_attributes( $data ){
313
-
314
- if ( isset( $data['attributes'] ) ) {
315
- $this->woocommerce_wpml->attributes->set_translatable_attributes( $data['attributes'] );
316
- }
317
-
318
- }
319
-
320
- /**
321
- * handler
322
- */
323
- public function save_multi_currency( $data ){
324
-
325
- if( empty( $this->woocommerce_wpml->multi_currency )){
326
- $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
327
- }
328
-
329
- if( !empty( $data['enabled'] ) ){
330
- $this->woocommerce_wpml->multi_currency->enable();
331
- } else{
332
- $this->woocommerce_wpml->multi_currency->disable();
333
- }
334
-
335
- }
336
-
337
- /**
338
- * handler
339
- */
340
- public function install_store_pages( $data ){
341
-
342
- if( !empty( $data['create_pages'] ) ) {
343
- $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
344
- }elseif( !empty( $data['install_missing_pages'] ) ){
345
- WC_Install::create_pages();
346
- $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
347
- }
348
-
349
- }
350
-
351
-
352
-
353
  }
1
+ <?php
2
+
3
+ class WCML_Setup {
4
+
5
+ private $step;
6
+ private $woocommerce_wpml;
7
+ private $sitepress;
8
+ private $next_step = false;
9
+
10
+
11
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
12
+
13
+ $this->woocommerce_wpml =& $woocommerce_wpml;
14
+ $this->sitepress =& $sitepress;
15
+
16
+ $this->setup_redirect();
17
+
18
+ $this->steps = array(
19
+ 'introduction' => array(
20
+ 'name' => __( 'Introduction', 'woocommerce-multilingual' ),
21
+ 'view' => array( $this, 'setup_introduction' ),
22
+ 'handler' => ''
23
+ ),
24
+ 'store-pages' => array(
25
+ 'name' => __( 'Store Pages', 'woocommerce-multilingual' ),
26
+ 'view' => array( $this, 'setup_store_pages' ),
27
+ 'handler' => array( $this, 'install_store_pages' ),
28
+ ),
29
+ 'attributes' => array(
30
+ 'name' => __( 'Global Attributes', 'woocommerce-multilingual' ),
31
+ 'view' => array( $this, 'setup_attributes' ),
32
+ 'handler' => array( $this, 'save_attributes' )
33
+ ),
34
+ 'multi-currency' => array(
35
+ 'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
36
+ 'view' => array( $this, 'setup_multi_currency' ),
37
+ 'handler' => array( $this, 'save_multi_currency' )
38
+ ),
39
+ 'ready' => array(
40
+ 'name' => __( 'Ready!', 'woocommerce-multilingual' ),
41
+ 'view' => array( $this, 'setup_ready' ),
42
+ 'handler' => ''
43
+ )
44
+ );
45
+
46
+ if( current_user_can( 'manage_options' ) ) {
47
+ if ( isset( $_GET['page'] ) && $_GET['page'] === 'wcml-setup' ) {
48
+ add_action( 'admin_menu', array( $this, 'admin_menus' ) );
49
+ }
50
+ add_action( 'admin_init', array($this, 'setup_wizard') );
51
+
52
+ add_action( 'admin_init', array($this, 'handle_steps'), 0 );
53
+ add_filter( 'wp_redirect', array($this, 'redirect_filters') );
54
+ }
55
+
56
+ if( !$this->has_completed() ){
57
+ add_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
58
+ add_action( 'admin_init', array( $this, 'skip_setup' ), 1 );
59
+ }
60
+
61
+ }
62
+
63
+ private function setup_redirect(){
64
+
65
+ if ( get_transient( '_wcml_activation_redirect' ) ) {
66
+ delete_transient( '_wcml_activation_redirect' );
67
+
68
+ $woocommerce_notices = get_option( 'woocommerce_admin_notices', array() );
69
+ $woocommerce_setup_not_run = in_array( 'install', $woocommerce_notices );
70
+
71
+ if (
72
+ ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], array( 'wcml-setup' ) ) ) ||
73
+ is_network_admin() ||
74
+ isset( $_GET['activate-multi'] ) ||
75
+ ! current_user_can( 'manage_options' ) ||
76
+ $woocommerce_setup_not_run
77
+ ) {
78
+ return;
79
+ }
80
+
81
+ if( !$this->has_completed()){
82
+ wp_safe_redirect( admin_url( 'index.php?page=wcml-setup' ) );
83
+ exit;
84
+ }
85
+ }
86
+ }
87
+
88
+ public function admin_menus() {
89
+ add_dashboard_page( '', '', 'manage_options', 'wcml-setup', '' );
90
+ }
91
+
92
+ public function setup_wizard_notice(){
93
+ wp_enqueue_style( 'wcml-setup-wizard-notice', WCML_PLUGIN_URL . '/res/css/wcml-setup-wizard-notice.css' );
94
+ ?>
95
+ <div id="wcml-setup-wizard" class="updated message wpml-message">
96
+ <p>
97
+ <strong><?php _e('Prepare your WooCommerce store to run multilingual!', 'woocommerce-multilingual'); ?></strong><br />
98
+ <?php _e('We need to help you with a few steps to turn your WooCommerce store multilingual. These steps include:', 'woocommerce-multilingual'); ?>
99
+ <ul class="wcml-notice-list">
100
+ <li><?php _e("Translating the 'store' pages", 'woocommerce-multilingual'); ?></li>
101
+ <li><?php _e("Choosing which attributes to make translatable", 'woocommerce-multilingual'); ?></li>
102
+ <li><?php _e("Choosing if you need multiple currencies", 'woocommerce-multilingual'); ?></li>
103
+ </ul>
104
+ </p>
105
+ <p class="submit">
106
+ <a href="<?php echo esc_url( admin_url('admin.php?page=wcml-setup') ); ?>" class="button-primary"><?php _e('Start the Setup Wizard', 'woocommerce-multilingual') ?></a>
107
+ <a href="<?php echo esc_url( wp_nonce_url( add_query_arg( 'wcml-setup-skip', 1 ), 'wcml_setup_skip_nonce', '_wcml_setup_nonce' ) ); ?>" class="button-secondary skip"><?php _e('Skip', 'woocommerce-multilingual') ?></a>
108
+ </p>
109
+ </div>
110
+ <?php
111
+ }
112
+
113
+ public function skip_setup(){
114
+
115
+ if ( isset( $_GET['wcml-setup-skip'] ) && isset( $_GET['_wcml_setup_nonce'] ) ) {
116
+ if ( ! wp_verify_nonce( $_GET['_wcml_setup_nonce'], 'wcml_setup_skip_nonce' ) ) {
117
+ wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-multilingual' ) );
118
+ }
119
+
120
+ if ( ! current_user_can( 'manage_options' ) ) {
121
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
122
+ }
123
+
124
+ $this->complete_setup();
125
+ remove_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
126
+
127
+ delete_transient( '_wcml_activation_redirect' );
128
+ }
129
+
130
+ }
131
+
132
+ public function complete_setup(){
133
+ $this->woocommerce_wpml->settings['set_up_wizard_run'] = 1;
134
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
135
+ $this->woocommerce_wpml->update_settings();
136
+ }
137
+
138
+ public function has_completed(){
139
+
140
+ return !empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] );
141
+
142
+ }
143
+
144
+ public function splash_wizard_on_wcml_pages(){
145
+
146
+ if( isset( $_GET['src'] ) && $_GET['src'] == 'setup_later' ){
147
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
148
+ $this->woocommerce_wpml->update_settings();
149
+ }
150
+
151
+ if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && !$this->has_completed() && empty( $this->woocommerce_wpml->settings['set_up_wizard_splash'] )){
152
+ wp_redirect('admin.php?page=wcml-setup');
153
+ exit;
154
+ }
155
+ }
156
+
157
+ public function setup_wizard() {
158
+
159
+ $this->splash_wizard_on_wcml_pages();
160
+
161
+ if ( empty( $_GET['page'] ) || 'wcml-setup' !== $_GET['page'] ) {
162
+ return;
163
+ }
164
+
165
+ $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
166
+
167
+ wp_enqueue_style( 'wcml-setup', WCML_PLUGIN_URL . '/res/css/wcml-setup.css', array( 'dashicons', 'install' ), WCML_VERSION );
168
+ wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array('jquery'), WCML_VERSION );
169
+
170
+ $this->setup_header();
171
+ $this->setup_steps();
172
+ $this->setup_content();
173
+ $this->setup_footer();
174
+
175
+ if( $this->step == 'ready' ){
176
+ $this->complete_setup();
177
+ }
178
+
179
+ exit;
180
+ }
181
+
182
+ private function setup_header() {
183
+ set_current_screen('wcml-setup');
184
+ ?>
185
+ <!DOCTYPE html>
186
+ <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
187
+ <head>
188
+ <meta name="viewport" content="width=device-width" />
189
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
190
+ <title><?php _e( 'WooCommerce Multilingual &rsaquo; Setup Wizard', 'woocommerce-multilingual' ); ?></title>
191
+ <?php wp_print_scripts( 'wcml-setup' ); ?>
192
+ <?php do_action( 'admin_print_styles' ); ?>
193
+ <?php do_action( 'admin_head' ); ?>
194
+ </head>
195
+ <body class="wcml-setup wp-core-ui">
196
+ <h1 id="wcml-logo"><a href="https://wpml.org/woocommerce-multilingual"><img src="<?php echo WCML_PLUGIN_URL ?>/res/images/banner-772x120.png" alt="WooCommerce Multilingual" /></a></h1>
197
+
198
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
199
+ <form class="wcml-setup-form" method="post">
200
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( $this->step ) ?>" />
201
+ <input type="hidden" name="handle_step" value="<?php echo $this->step ?>" />
202
+ <?php endif; ?>
203
+ <?php
204
+ }
205
+
206
+ private function setup_content(){
207
+
208
+ echo '<div class="wcml-setup-content">';
209
+ call_user_func( $this->steps[ $this->step ]['view'] );
210
+ echo '</div>';
211
+
212
+ }
213
+
214
+ private function setup_footer() {
215
+ ?>
216
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
217
+ </form>
218
+ <?php endif ?>
219
+ </body>
220
+ </html>
221
+ <?php
222
+ }
223
+
224
+ private function setup_steps() {
225
+
226
+ $steps = array_keys( $this->steps );
227
+ $step_index = array_search( $this->step, $steps );
228
+ $this->next_step = isset( $steps[$step_index + 1] ) ? $steps[$step_index + 1] : '';
229
+
230
+ $ouput_steps = $this->steps;
231
+ array_shift( $ouput_steps );
232
+ ?>
233
+ <ol class="wcml-setup-steps">
234
+ <?php foreach ( $ouput_steps as $step_key => $step ) : ?>
235
+ <li class="<?php
236
+ if ( $step_key === $this->step ) {
237
+ echo 'active';
238
+ } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
239
+ echo 'done';
240
+ }
241
+ ?>"><?php echo esc_html( $step['name'] ); ?></li>
242
+ <?php endforeach; ?>
243
+ </ol>
244
+ <?php
245
+ }
246
+
247
+ private function next_step_url(){
248
+ $url = admin_url('admin.php?page=wcml-setup&step=' . $this->next_step );
249
+ return $url;
250
+ }
251
+
252
+ public function setup_introduction(){
253
+ $ui = new WCML_Setup_Introduction_UI( $this->woocommerce_wpml, $this->next_step_url() );
254
+ echo $ui->get_view();
255
+ }
256
+
257
+ public function setup_store_pages(){
258
+
259
+ $ui = new WCML_Setup_Store_Pages_UI( $this->woocommerce_wpml, $this->sitepress, $this->next_step_url() );
260
+ echo $ui->get_view();
261
+ }
262
+
263
+ public function setup_attributes(){
264
+ $ui = new WCML_Setup_Attributes_UI( $this->woocommerce_wpml, $this->next_step_url() );
265
+ echo $ui->get_view();
266
+ }
267
+
268
+ public function setup_multi_currency(){
269
+ $ui = new WCML_Setup_Multi_Currency_UI( $this->woocommerce_wpml, $this->next_step_url() );
270
+ echo $ui->get_view();
271
+ }
272
+
273
+ public function setup_ready(){
274
+ $ui = new WCML_Setup_Ready_UI( $this->woocommerce_wpml );
275
+ echo $ui->get_view();
276
+ }
277
+
278
+
279
+ public function redirect_filters( $url ){
280
+
281
+ if( isset($_POST['next_step_url']) && $_POST['next_step_url'] ){
282
+ $url = sanitize_text_field( $_POST['next_step_url'] );
283
+ }
284
+
285
+ return $url;
286
+ }
287
+
288
+
289
+ private function get_handler( $step ){
290
+ $handler = !empty( $this->steps[ $step ]['handler'] ) ? $this->steps[ $step ]['handler'] : '';
291
+ return $handler;
292
+
293
+ }
294
+
295
+ public function handle_steps(){
296
+
297
+ if( isset( $_POST[ 'handle_step' ] ) && $_POST['nonce'] == wp_create_nonce( $_POST[ 'handle_step' ] ) ){
298
+
299
+ $step_name = sanitize_text_field( $_POST[ 'handle_step' ] );
300
+
301
+ if( $handler = $this->get_handler( $step_name )){
302
+ call_user_func( $handler, $_POST );
303
+ }
304
+
305
+ }
306
+
307
+ }
308
+
309
+ /**
310
+ * handler
311
+ */
312
+ public function save_attributes( $data ){
313
+
314
+ if ( isset( $data['attributes'] ) ) {
315
+ $this->woocommerce_wpml->attributes->set_translatable_attributes( $data['attributes'] );
316
+ }
317
+
318
+ }
319
+
320
+ /**
321
+ * handler
322
+ */
323
+ public function save_multi_currency( $data ){
324
+
325
+ if( empty( $this->woocommerce_wpml->multi_currency )){
326
+ $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
327
+ }
328
+
329
+ if( !empty( $data['enabled'] ) ){
330
+ $this->woocommerce_wpml->multi_currency->enable();
331
+ } else{
332
+ $this->woocommerce_wpml->multi_currency->disable();
333
+ }
334
+
335
+ }
336
+
337
+ /**
338
+ * handler
339
+ */
340
+ public function install_store_pages( $data ){
341
+
342
+ if( !empty( $data['create_pages'] ) ) {
343
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
344
+ }elseif( !empty( $data['install_missing_pages'] ) ){
345
+ WC_Install::create_pages();
346
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
347
+ }
348
+
349
+ }
350
+
351
+
352
+
353
  }
inc/class-wcml-ajax-setup.php CHANGED
@@ -1,159 +1,159 @@
1
- <?php
2
-
3
-
4
- class WCML_Ajax_Setup{
5
-
6
- /**
7
- * @var SitePress
8
- */
9
- private $sitepress;
10
-
11
- public function __construct( $sitepres ){
12
-
13
- $this->sitepress =& $sitepres;
14
-
15
- add_action( 'init', array( $this, 'init' ) );
16
- add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
17
-
18
- //@deprecated 3.9
19
- add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
20
-
21
- add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
22
- }
23
-
24
- public function init(){
25
- if (wpml_is_ajax()){
26
- do_action('wcml_localize_woocommerce_on_ajax');
27
- }
28
-
29
- add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
30
-
31
- add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
32
- add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
33
- add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
34
- add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
35
-
36
- add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
37
- add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
38
- add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
39
-
40
- }
41
-
42
- function filter_woocommerce_order_review(){
43
- global $woocommerce;
44
- unload_textdomain('woocommerce');
45
- $woocommerce->load_plugin_textdomain();
46
- }
47
-
48
- function add_hidden_language_field(){
49
- if( function_exists('wpml_the_language_input_field') ){
50
- wpml_the_language_input_field();
51
- }else{
52
- global $sitepress;
53
- if (isset($sitepress) ) {
54
- return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
55
- }
56
- return null;
57
- }
58
- }
59
-
60
- function add_language_parameter_to_ajax_url($woocommerce_params){
61
- global $sitepress;
62
-
63
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
64
- $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
65
- }
66
-
67
- return $woocommerce_params;
68
- }
69
-
70
- function filter_woocommerce_ajax_params($woocommerce_params){
71
- global $sitepress, $post;
72
- $value = array();
73
- $value = $woocommerce_params;
74
-
75
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
76
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
77
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
- }
79
-
80
- if(!isset($post->ID)){
81
- return $value;
82
- }
83
-
84
- $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
85
-
86
- if(empty($ch_pages)){
87
-
88
- $ch_pages = array(
89
-
90
- 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
91
- 'pay_page_id' => get_option('woocommerce_pay_page_id'),
92
- 'cart_page_id' => get_option('woocommerce_cart_page_id'));
93
-
94
- $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
95
- $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
96
- $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
97
-
98
- }
99
-
100
- wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
101
-
102
- if($ch_pages['translated_cart_page_id'] == $post->ID){
103
- $value['is_cart'] = 1;
104
- $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
105
- } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
106
- $value['is_checkout'] = 1;
107
-
108
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
109
-
110
- } else if($ch_pages['translated_pay_page_id'] == $post->ID){
111
- $value['is_pay_page'] = 1;
112
- }
113
-
114
- return $value;
115
- }
116
-
117
-
118
- function wcml_localize_woocommerce_on_ajax(){
119
- if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
120
- return;
121
- }
122
-
123
- global $sitepress;
124
-
125
- $current_language = $sitepress->get_current_language();
126
-
127
- $sitepress->switch_lang($current_language, true);
128
- }
129
-
130
- /**
131
- * @param $endpoint string
132
- *
133
- * Adds a language parameter to the url when different domains for each language are used
134
- *
135
- * @return string
136
- */
137
- public function add_language_to_endpoint( $endpoint ){
138
-
139
- $is_per_domain = WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
140
- if( $is_per_domain && $this->sitepress->get_current_language() != $this->sitepress->get_default_language() ){
141
-
142
- $endpoint = add_query_arg('lang', $this->sitepress->get_current_language(), remove_query_arg( 'lang', $endpoint ) );
143
- $endpoint = urldecode($endpoint);
144
-
145
- }
146
-
147
- return $endpoint;
148
- }
149
-
150
-
151
- /**
152
- * @deprecated 3.9
153
- */
154
- function localize_woocommerce_on_ajax(){
155
- $this->wcml_localize_woocommerce_on_ajax();
156
- }
157
-
158
-
159
- }
1
+ <?php
2
+
3
+
4
+ class WCML_Ajax_Setup{
5
+
6
+ /**
7
+ * @var SitePress
8
+ */
9
+ private $sitepress;
10
+
11
+ public function __construct( $sitepres ){
12
+
13
+ $this->sitepress =& $sitepres;
14
+
15
+ add_action( 'init', array( $this, 'init' ) );
16
+ add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
17
+
18
+ //@deprecated 3.9
19
+ add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
20
+
21
+ add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
22
+ }
23
+
24
+ public function init(){
25
+ if (wpml_is_ajax()){
26
+ do_action('wcml_localize_woocommerce_on_ajax');
27
+ }
28
+
29
+ add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
30
+
31
+ add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
32
+ add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
33
+ add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
34
+ add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
35
+
36
+ add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
37
+ add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
38
+ add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
39
+
40
+ }
41
+
42
+ function filter_woocommerce_order_review(){
43
+ global $woocommerce;
44
+ unload_textdomain('woocommerce');
45
+ $woocommerce->load_plugin_textdomain();
46
+ }
47
+
48
+ function add_hidden_language_field(){
49
+ if( function_exists('wpml_the_language_input_field') ){
50
+ wpml_the_language_input_field();
51
+ }else{
52
+ global $sitepress;
53
+ if (isset($sitepress) ) {
54
+ return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
55
+ }
56
+ return null;
57
+ }
58
+ }
59
+
60
+ function add_language_parameter_to_ajax_url($woocommerce_params){
61
+ global $sitepress;
62
+
63
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
64
+ $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
65
+ }
66
+
67
+ return $woocommerce_params;
68
+ }
69
+
70
+ function filter_woocommerce_ajax_params($woocommerce_params){
71
+ global $sitepress, $post;
72
+ $value = array();
73
+ $value = $woocommerce_params;
74
+
75
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
76
+ $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
77
+ $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
+ }
79
+
80
+ if(!isset($post->ID)){
81
+ return $value;
82
+ }
83
+
84
+ $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
85
+
86
+ if(empty($ch_pages)){
87
+
88
+ $ch_pages = array(
89
+
90
+ 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
91
+ 'pay_page_id' => get_option('woocommerce_pay_page_id'),
92
+ 'cart_page_id' => get_option('woocommerce_cart_page_id'));
93
+
94
+ $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
95
+ $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
96
+ $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
97
+
98
+ }
99
+
100
+ wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
101
+
102
+ if($ch_pages['translated_cart_page_id'] == $post->ID){
103
+ $value['is_cart'] = 1;
104
+ $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
105
+ } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
106
+ $value['is_checkout'] = 1;
107
+
108
+ $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
109
+
110
+ } else if($ch_pages['translated_pay_page_id'] == $post->ID){
111
+ $value['is_pay_page'] = 1;
112
+ }
113
+
114
+ return $value;
115
+ }
116
+
117
+
118
+ function wcml_localize_woocommerce_on_ajax(){
119
+ if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
120
+ return;
121
+ }
122
+
123
+ global $sitepress;
124
+
125
+ $current_language = $sitepress->get_current_language();
126
+
127
+ $sitepress->switch_lang($current_language, true);
128
+ }
129
+
130
+ /**
131
+ * @param $endpoint string
132
+ *
133
+ * Adds a language parameter to the url when different domains for each language are used
134
+ *
135
+ * @return string
136
+ */
137
+ public function add_language_to_endpoint( $endpoint ){
138
+
139
+ $is_per_domain = WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
140
+ if( $is_per_domain && $this->sitepress->get_current_language() != $this->sitepress->get_default_language() ){
141
+
142
+ $endpoint = add_query_arg('lang', $this->sitepress->get_current_language(), remove_query_arg( 'lang', $endpoint ) );
143
+ $endpoint = urldecode($endpoint);
144
+
145
+ }
146
+
147
+ return $endpoint;
148
+ }
149
+
150
+
151
+ /**
152
+ * @deprecated 3.9
153
+ */
154
+ function localize_woocommerce_on_ajax(){
155
+ $this->wcml_localize_woocommerce_on_ajax();
156
+ }
157
+
158
+
159
+ }
inc/class-wcml-attributes.php CHANGED
@@ -1,404 +1,463 @@
1
- <?php
2
-
3
- class WCML_Attributes{
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
- private $wpdb;
8
-
9
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
10
- $this->woocommerce_wpml = $woocommerce_wpml;
11
- $this->sitepress = $sitepress;
12
- $this->wpdb = $wpdb;
13
-
14
- add_action( 'init', array( $this, 'init' ) );
15
-
16
- add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), 100, 2 );
17
- add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
18
-
19
- if( isset( $_POST['icl_ajx_action'] ) && $_POST['icl_ajx_action'] == 'icl_custom_tax_sync_options' ){
20
- $this->icl_custom_tax_sync_options();
21
- }
22
-
23
- }
24
-
25
- public function init(){
26
-
27
- $is_attr_page = apply_filters( 'wcml_is_attributes_page', isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
28
-
29
- if( $is_attr_page ){
30
-
31
- add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
32
-
33
- if( isset( $_POST[ 'save_attribute' ] ) && isset( $_GET[ 'edit' ] ) ){
34
- $this->set_attribute_readonly_config( $_GET[ 'edit' ], $_POST );
35
- }
36
- }
37
-
38
- }
39
-
40
- public function not_translatable_html(){
41
- $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
42
-
43
- $attr_is_tnaslt = new WCML_Not_Translatable_Attributes( $attr_id, $this->woocommerce_wpml );
44
- $attr_is_tnaslt->show();
45
- }
46
-
47
- public function get_attribute_terms( $attribute ){
48
-
49
- return $this->wpdb->get_results($this->wpdb->prepare("
50
- SELECT * FROM {$this->wpdb->term_taxonomy} x JOIN {$this->wpdb->terms} t ON x.term_id = t.term_id WHERE x.taxonomy = %s", $attribute ) );
51
-
52
- }
53
-
54
- public function set_attribute_readonly_config( $id, $attribute ){
55
-
56
- $is_translatable = isset( $_POST[ 'wcml-is-translatable-attr' ] ) ? 1 : 0;
57
- $attribute_name = wc_attribute_taxonomy_name( $attribute['attribute_name'] );
58
- if( $is_translatable === 0 ){
59
- //delete all translated attributes terms if "Translatable?" option un-checked
60
- $this->delete_translated_attribute_terms( $attribute_name );
61
- $this->set_variations_to_use_original_attributes( $attribute_name );
62
- $this->set_original_attributes_for_products( $attribute_name );
63
- }
64
- $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
65
- }
66
-
67
- public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
68
- $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
69
- $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
70
-
71
- $this->woocommerce_wpml->terms->update_terms_translated_status( $attribute_name );
72
- }
73
-
74
- public function set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable ){
75
- $wcml_settings = $this->woocommerce_wpml->get_settings();
76
- $wcml_settings[ 'attributes_settings' ][ $attribute_name ] = $is_translatable;
77
- $this->woocommerce_wpml->update_settings( $wcml_settings );
78
- }
79
-
80
- public function set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable ){
81
-
82
- $sync_settings = $this->sitepress->get_setting( 'taxonomies_sync_option', array() );
83
- $sync_settings[ $attribute_name ] = $is_translatable;
84
- $this->sitepress->set_setting( 'taxonomies_sync_option', $sync_settings, true );
85
- $this->sitepress->verify_taxonomy_translations( $attribute_name );
86
- }
87
-
88
- public function delete_translated_attribute_terms( $attribute ){
89
- $terms = $this->get_attribute_terms( $attribute );
90
-
91
- foreach( $terms as $term ){
92
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
93
- if( $term_language_details && $term_language_details->source_language_code ){
94
- wp_delete_term( $term->term_id, $attribute );
95
- }
96
- }
97
-
98
- }
99
-
100
- public function set_variations_to_use_original_attributes( $attribute ){
101
- $terms = $this->get_attribute_terms( $attribute );
102
-
103
- foreach( $terms as $term ){
104
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
105
- if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
106
- $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
107
-
108
- foreach( $variations as $variation ){
109
- //update taxonomy in translation of variation
110
- foreach( $this->sitepress->get_active_languages() as $language ){
111
-
112
- $trnsl_variation_id = apply_filters( 'translate_object_id', $variation->post_id, 'product_variation', false, $language['code'] );
113
- if( !is_null( $trnsl_variation_id ) ){
114
- update_post_meta( $trnsl_variation_id, 'attribute_'.$attribute, $term->slug );
115
- }
116
- }
117
- }
118
- }
119
- }
120
- }
121
-
122
- public function set_original_attributes_for_products( $attribute ){
123
-
124
- $terms = $this->get_attribute_terms( $attribute );
125
- $cleared_products = array();
126
- foreach( $terms as $term ) {
127
- $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
128
- if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
129
- $args = array(
130
- 'tax_query' => array(
131
- array(
132
- 'taxonomy' => $attribute,
133
- 'field' => 'slug',
134
- 'terms' => $term->slug
135
- )
136
- )
137
- );
138
-
139
- $products = get_posts($args);
140
-
141
- foreach( $products as $product ){
142
-
143
- foreach( $this->sitepress->get_active_languages() as $language ) {
144
-
145
- $trnsl_product_id = apply_filters( 'translate_object_id', $product->ID, 'product', false, $language['code'] );
146
-
147
- if ( !is_null( $trnsl_product_id ) ) {
148
- if( !in_array( $trnsl_product_id, $trnsl_product_id ) ){
149
- wp_delete_object_term_relationships( $trnsl_product_id, $attribute );
150
- $cleared_products[] = $trnsl_product_id;
151
- }
152
- wp_set_object_terms( $trnsl_product_id, $term->slug, $attribute, true );
153
- }
154
- }
155
- }
156
- }
157
- }
158
- }
159
-
160
-
161
- public function is_translatable_attribute( $attr_name ){
162
-
163
- if( !isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ){
164
- $this->set_attribute_config_in_settings( $attr_name, 1 );
165
- }
166
-
167
- return isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ? $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] : 1;
168
- }
169
-
170
- public function get_translatable_attributes(){
171
- $attributes = wc_get_attribute_taxonomies();
172
-
173
- $translatable_attributes = array();
174
- foreach( $attributes as $attribute ){
175
- if( $this->is_translatable_attribute( wc_attribute_taxonomy_name( $attribute->attribute_name ) ) ){
176
- $translatable_attributes[] = $attribute;
177
- }
178
- }
179
-
180
- return $translatable_attributes;
181
- }
182
-
183
- public function set_translatable_attributes( $attributes ){
184
-
185
- foreach( $attributes as $name => $is_translatable ){
186
-
187
- $attribute_name = wc_attribute_taxonomy_name( $name );
188
- $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
189
-
190
- }
191
- }
192
-
193
- public function sync_product_attr( $original_product_id, $tr_product_id, $language = false, $data = false ){
194
-
195
- //get "_product_attributes" from original product
196
- $orig_product_attrs = $this->get_product_atributes( $original_product_id );
197
- $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
198
-
199
- $trnsl_labels = get_post_meta( $tr_product_id, 'attr_label_translations', true );
200
-
201
- foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
202
- $sanitized_key = sanitize_title( $orig_product_attr[ 'name' ] );
203
- if( $sanitized_key != $key ) {
204
- $orig_product_attrs_buff = $orig_product_attrs[ $key ];
205
- unset( $orig_product_attrs[ $key ] );
206
- $orig_product_attrs[ $sanitized_key ] = $orig_product_attrs_buff;
207
- $key_to_save = $sanitized_key;
208
- }else{
209
- $key_to_save = $key;
210
- }
211
- if ( $data ){
212
- if ( isset( $data[ md5( $key ) ] ) && !empty( $data[ md5( $key ) ] ) && !is_array( $data[ md5( $key ) ] ) ) {
213
- //get translation values from $data
214
- $orig_product_attrs[ $key_to_save ][ 'value' ] = $data[ md5( $key ) ];
215
- } else {
216
- $orig_product_attrs[ $key_to_save ][ 'value' ] = '';
217
- }
218
-
219
- if ( isset( $data[ md5( $key . '_name' ) ] ) && !empty( $data[ md5( $key . '_name' ) ] ) && !is_array( $data[ md5( $key . '_name' ) ] ) ) {
220
- //get translation values from $data
221
- $trnsl_labels[ $language ][ $key_to_save ] = stripslashes( $data[ md5( $key . '_name' ) ] );
222
- } else {
223
- $trnsl_labels[ $language ][ $key_to_save ] = '';
224
- }
225
- }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
226
- if( isset( $trnsl_product_attrs[ $key ] ) ){
227
- $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
228
- }else{
229
- unset ( $orig_product_attrs[ $key_to_save ] );
230
- }
231
- }
232
- }
233
-
234
- update_post_meta( $tr_product_id, 'attr_label_translations', $trnsl_labels );
235
- //update "_product_attributes"
236
- update_post_meta( $tr_product_id, '_product_attributes', $orig_product_attrs );
237
- }
238
-
239
- public function get_product_atributes( $product_id ){
240
- $attributes = get_post_meta( $product_id, '_product_attributes', true );
241
- if( !is_array( $attributes ) ){
242
- $attributes = array();
243
- }
244
- return $attributes;
245
- }
246
-
247
- public function sync_default_product_attr( $orig_post_id, $transl_post_id, $lang ){
248
- $original_default_attributes = get_post_meta( $orig_post_id, '_default_attributes', true );
249
- if( !empty( $original_default_attributes ) ){
250
- $unserialized_default_attributes = array();
251
- foreach(maybe_unserialize( $original_default_attributes ) as $attribute => $default_term_slug ){
252
- // get the correct language
253
- if ( substr( $attribute, 0, 3 ) == 'pa_' ) {
254
- //attr is taxonomy
255
- if( $this->is_translatable_attribute( $attribute ) ){
256
- $default_term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $attribute, $default_term_slug );
257
- $tr_id = apply_filters( 'translate_object_id', $default_term_id, $attribute, false, $lang );
258
-
259
- if( $tr_id ){
260
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
261
- $unserialized_default_attributes[ $attribute ] = $translated_term->slug;
262
- }
263
- }else{
264
- $unserialized_default_attributes[ $attribute ] = $default_term_slug;
265
- }
266
- }else{
267
- //custom attr
268
- $orig_product_attributes = get_post_meta( $orig_post_id, '_product_attributes', true );
269
- $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
270
-
271
- if( isset( $unserialized_orig_product_attributes[ $attribute ] ) ){
272
- $orig_attr_values = explode( '|', $unserialized_orig_product_attributes[ $attribute ][ 'value' ] );
273
-
274
- foreach( $orig_attr_values as $key => $orig_attr_value ){
275
- $orig_attr_value_sanitized = strtolower( sanitize_title ( $orig_attr_value ) );
276
-
277
- if( $orig_attr_value_sanitized == $default_term_slug || trim( $orig_attr_value ) == trim( $default_term_slug ) ){
278
- $tnsl_product_attributes = get_post_meta( $transl_post_id, '_product_attributes', true );
279
- $unserialized_tnsl_product_attributes = maybe_unserialize( $tnsl_product_attributes );
280
-
281
- if( isset( $unserialized_tnsl_product_attributes[ $attribute ] ) ){
282
- $trnsl_attr_values = explode( '|', $unserialized_tnsl_product_attributes[ $attribute ][ 'value' ] );
283
-
284
- if( $orig_attr_value_sanitized == $default_term_slug ){
285
- $trnsl_attr_value = strtolower( sanitize_title( trim( $trnsl_attr_values[ $key ] ) ) );
286
- }else{
287
- $trnsl_attr_value = trim( $trnsl_attr_values[ $key ] );
288
- }
289
- $unserialized_default_attributes[ $attribute ] = $trnsl_attr_value;
290
- }
291
- }
292
- }
293
- }
294
- }
295
- }
296
-
297
- $data = array( 'meta_value' => maybe_serialize( $unserialized_default_attributes ) );
298
- }else{
299
- $data = array( 'meta_value' => maybe_serialize( array() ) );
300
- }
301
-
302
- $where = array( 'post_id' => $transl_post_id, 'meta_key' => '_default_attributes' );
303
- $this->wpdb->update( $this->wpdb->postmeta, $data, $where );
304
- }
305
-
306
- /*
307
- * get attribute translation
308
- */
309
- public function get_custom_attribute_translation( $product_id, $attribute_key, $attribute, $lang_code ){
310
- $tr_post_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $lang_code );
311
- $transl = array();
312
- if( $tr_post_id ){
313
- if( !$attribute[ 'is_taxonomy' ] ){
314
- $tr_attrs = get_post_meta($tr_post_id, '_product_attributes', true);
315
- if( $tr_attrs ){
316
- foreach( $tr_attrs as $key => $tr_attr ) {
317
- if( $attribute_key == $key ){
318
- $transl[ 'value' ] = $tr_attr[ 'value' ];
319
- $trnsl_labels = maybe_unserialize( get_post_meta( $tr_post_id, 'attr_label_translations', true ) );
320
-
321
- if( isset( $trnsl_labels[ $lang_code ][ $attribute_key ] ) ){
322
- $transl[ 'name' ] = $trnsl_labels[ $lang_code ][ $attribute_key ];
323
- }else{
324
- $transl[ 'name' ] = $tr_attr[ 'name' ];
325
- }
326
- return $transl;
327
- }
328
- }
329
- }
330
- return false;
331
- }
332
- }
333
- return false;
334
- }
335
-
336
- /*
337
- * Get custom attribute translation
338
- * Returned translated attribute or original if missed
339
- */
340
- public function get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute ){
341
- $orig_product_attributes = get_post_meta( $product_id, '_product_attributes', true );
342
- $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
343
-
344
- foreach( $unserialized_orig_product_attributes as $orig_attr_key => $orig_product_attribute ){
345
- $orig_attr_key = urldecode( $orig_attr_key );
346
- if( strtolower( $taxonomy ) == $orig_attr_key ){
347
- $values = explode( '|', $orig_product_attribute[ 'value' ] );
348
-
349
- foreach( $values as $key_id => $value ){
350
- if( trim( $value," " ) == $attribute ){
351
- $attr_key_id = $key_id;
352
- }
353
- }
354
- }
355
- }
356
-
357
- $trnsl_product_attributes = get_post_meta( $tr_product_id, '_product_attributes', true );
358
- $unserialized_trnsl_product_attributes = maybe_unserialize( $trnsl_product_attributes );
359
- $taxonomy = sanitize_title( $taxonomy );
360
- $trnsl_attr_values = explode( '|', $unserialized_trnsl_product_attributes[ $taxonomy ][ 'value' ] );
361
-
362
- if( isset( $attr_key_id ) && isset( $trnsl_attr_values[ $attr_key_id ] ) ){
363
- return trim( $trnsl_attr_values[ $attr_key_id ] );
364
- }
365
-
366
- return $attribute;
367
- }
368
-
369
- public function filter_product_attributes_for_translation( $translated, $key ){
370
- $translated = $translated
371
- ? preg_match('#^(?!field-_product_attributes-(.+)-(.+)-(?!value|name))#', $key) : 0;
372
-
373
- return $translated;
374
- }
375
-
376
- public function icl_custom_tax_sync_options(){
377
- foreach( $_POST['icl_sync_tax'] as $taxonomy => $value){
378
- if ( substr( $taxonomy, 0, 3 ) == 'pa_' ) {
379
- $this->set_attribute_config_in_wcml_settings( $taxonomy , $value);
380
- }
381
- }
382
-
383
- }
384
-
385
- public function is_attributes_fully_translated(){
386
-
387
- $product_attributes = $this->get_translatable_attributes();
388
-
389
- $fully_translated = true;
390
-
391
- if( $product_attributes ){
392
- foreach( $product_attributes as $attribute ){
393
- $is_fully_translated = $this->woocommerce_wpml->terms->is_fully_translated( 'pa_' . $attribute->attribute_name );
394
- if( !$is_fully_translated ){
395
- $fully_translated = false;
396
- break;
397
- }
398
- }
399
- }
400
-
401
- return $fully_translated;
402
- }
403
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
404
  }
1
+ <?php
2
+
3
+ class WCML_Attributes{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+ private $wpdb;
8
+
9
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+ $this->wpdb = $wpdb;
13
+
14
+ add_action( 'init', array( $this, 'init' ) );
15
+
16
+ add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), 100, 2 );
17
+ add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
18
+
19
+ if( isset( $_POST['icl_ajx_action'] ) && $_POST['icl_ajx_action'] == 'icl_custom_tax_sync_options' ){
20
+ $this->icl_custom_tax_sync_options();
21
+ }
22
+
23
+ }
24
+
25
+ public function init(){
26
+
27
+ $is_attr_page = apply_filters( 'wcml_is_attributes_page', isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
28
+
29
+ if( $is_attr_page ){
30
+
31
+ add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
32
+
33
+ if( isset( $_POST[ 'save_attribute' ] ) && isset( $_GET[ 'edit' ] ) ){
34
+ $this->set_attribute_readonly_config( $_GET[ 'edit' ], $_POST );
35
+ }
36
+ }
37
+
38
+ }
39
+
40
+ public function not_translatable_html(){
41
+ $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
42
+
43
+ $attr_is_tnaslt = new WCML_Not_Translatable_Attributes( $attr_id, $this->woocommerce_wpml );
44
+ $attr_is_tnaslt->show();
45
+ }
46
+
47
+ public function get_attribute_terms( $attribute ){
48
+
49
+ return $this->wpdb->get_results($this->wpdb->prepare("
50
+ SELECT * FROM {$this->wpdb->term_taxonomy} x JOIN {$this->wpdb->terms} t ON x.term_id = t.term_id WHERE x.taxonomy = %s", $attribute ) );
51
+
52
+ }
53
+
54
+ public function set_attribute_readonly_config( $id, $attribute ){
55
+
56
+ $is_translatable = isset( $_POST[ 'wcml-is-translatable-attr' ] ) ? 1 : 0;
57
+ $attribute_name = wc_attribute_taxonomy_name( $attribute['attribute_name'] );
58
+ if( $is_translatable === 0 ){
59
+ //delete all translated attributes terms if "Translatable?" option un-checked
60
+ $this->delete_translated_attribute_terms( $attribute_name );
61
+ $this->set_variations_to_use_original_attributes( $attribute_name );
62
+ $this->set_original_attributes_for_products( $attribute_name );
63
+ }
64
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
65
+ }
66
+
67
+ public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
68
+ $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
69
+ $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
70
+
71
+ $this->woocommerce_wpml->terms->update_terms_translated_status( $attribute_name );
72
+ }
73
+
74
+ public function set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable ){
75
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
76
+ $wcml_settings[ 'attributes_settings' ][ $attribute_name ] = $is_translatable;
77
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
78
+ }
79
+
80
+ public function set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable ){
81
+
82
+ $sync_settings = $this->sitepress->get_setting( 'taxonomies_sync_option', array() );
83
+ $sync_settings[ $attribute_name ] = $is_translatable;
84
+ $this->sitepress->set_setting( 'taxonomies_sync_option', $sync_settings, true );
85
+ $this->sitepress->verify_taxonomy_translations( $attribute_name );
86
+ }
87
+
88
+ public function delete_translated_attribute_terms( $attribute ){
89
+ $terms = $this->get_attribute_terms( $attribute );
90
+
91
+ foreach( $terms as $term ){
92
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
93
+ if( $term_language_details && $term_language_details->source_language_code ){
94
+ wp_delete_term( $term->term_id, $attribute );
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+ public function set_variations_to_use_original_attributes( $attribute ){
101
+ $terms = $this->get_attribute_terms( $attribute );
102
+
103
+ foreach( $terms as $term ){
104
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
105
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
106
+ $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
107
+
108
+ foreach( $variations as $variation ){
109
+ //update taxonomy in translation of variation
110
+ foreach( $this->sitepress->get_active_languages() as $language ){
111
+
112
+ $trnsl_variation_id = apply_filters( 'translate_object_id', $variation->post_id, 'product_variation', false, $language['code'] );
113
+ if( !is_null( $trnsl_variation_id ) ){
114
+ update_post_meta( $trnsl_variation_id, 'attribute_'.$attribute, $term->slug );
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ public function set_original_attributes_for_products( $attribute ){
123
+
124
+ $terms = $this->get_attribute_terms( $attribute );
125
+ $cleared_products = array();
126
+ foreach( $terms as $term ) {
127
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
128
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
129
+ $args = array(
130
+ 'tax_query' => array(
131
+ array(
132
+ 'taxonomy' => $attribute,
133
+ 'field' => 'slug',
134
+ 'terms' => $term->slug
135
+ )
136
+ )
137
+ );
138
+
139
+ $products = get_posts($args);
140
+
141
+ foreach( $products as $product ){
142
+
143
+ foreach( $this->sitepress->get_active_languages() as $language ) {
144
+
145
+ $trnsl_product_id = apply_filters( 'translate_object_id', $product->ID, 'product', false, $language['code'] );
146
+
147
+ if ( !is_null( $trnsl_product_id ) ) {
148
+ if( !in_array( $trnsl_product_id, $trnsl_product_id ) ){
149
+ wp_delete_object_term_relationships( $trnsl_product_id, $attribute );
150
+ $cleared_products[] = $trnsl_product_id;
151
+ }
152
+ wp_set_object_terms( $trnsl_product_id, $term->slug, $attribute, true );
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+
161
+ public function is_translatable_attribute( $attr_name ){
162
+
163
+ if( !isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ){
164
+ $this->set_attribute_config_in_settings( $attr_name, 1 );
165
+ }
166
+
167
+ return isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ? $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] : 1;
168
+ }
169
+
170
+ public function get_translatable_attributes(){
171
+ $attributes = wc_get_attribute_taxonomies();
172
+
173
+ $translatable_attributes = array();
174
+ foreach( $attributes as $attribute ){
175
+ if( $this->is_translatable_attribute( wc_attribute_taxonomy_name( $attribute->attribute_name ) ) ){
176
+ $translatable_attributes[] = $attribute;
177
+ }
178
+ }
179
+
180
+ return $translatable_attributes;
181
+ }
182
+
183
+ public function set_translatable_attributes( $attributes ){
184
+
185
+ foreach( $attributes as $name => $is_translatable ){
186
+
187
+ $attribute_name = wc_attribute_taxonomy_name( $name );
188
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
189
+
190
+ }
191
+ }
192
+
193
+ public function sync_product_attr( $original_product_id, $tr_product_id, $language = false, $data = false ){
194
+
195
+ //get "_product_attributes" from original product
196
+ $orig_product_attrs = $this->get_product_atributes( $original_product_id );
197
+ $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
198
+
199
+ $trnsl_labels = $this->get_attr_label_translations( $tr_product_id );
200
+
201
+ foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
202
+ $sanitized_key = sanitize_title( $orig_product_attr[ 'name' ] );
203
+ if( $sanitized_key != $key ) {
204
+ $orig_product_attrs_buff = $orig_product_attrs[ $key ];
205
+ unset( $orig_product_attrs[ $key ] );
206
+ $orig_product_attrs[ $sanitized_key ] = $orig_product_attrs_buff;
207
+ $key_to_save = $sanitized_key;
208
+ }else{
209
+ $key_to_save = $key;
210
+ }
211
+ if ( $data ){
212
+ if ( isset( $data[ md5( $key ) ] ) && !empty( $data[ md5( $key ) ] ) && !is_array( $data[ md5( $key ) ] ) ) {
213
+ //get translation values from $data
214
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = $data[ md5( $key ) ];
215
+ } else {
216
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = '';
217
+ }
218
+
219
+ if ( isset( $data[ md5( $key . '_name' ) ] ) && !empty( $data[ md5( $key . '_name' ) ] ) && !is_array( $data[ md5( $key . '_name' ) ] ) ) {
220
+ //get translation values from $data
221
+ $trnsl_labels[ $language ][ $key_to_save ] = stripslashes( $data[ md5( $key . '_name' ) ] );
222
+ } else {
223
+ $trnsl_labels[ $language ][ $key_to_save ] = '';
224
+ }
225
+ }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
226
+ if( isset( $trnsl_product_attrs[ $key ] ) ){
227
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
228
+ }else{
229
+ unset ( $orig_product_attrs[ $key_to_save ] );
230
+ }
231
+ }
232
+ }
233
+
234
+ update_post_meta( $tr_product_id, 'attr_label_translations', $trnsl_labels );
235
+ //update "_product_attributes"
236
+ update_post_meta( $tr_product_id, '_product_attributes', $orig_product_attrs );
237
+ }
238
+
239
+ public function get_product_atributes( $product_id ){
240
+ $attributes = get_post_meta( $product_id, '_product_attributes', true );
241
+ if( !is_array( $attributes ) ){
242
+ $attributes = array();
243
+ }
244
+ return $attributes;
245
+ }
246
+
247
+ public function get_attr_label_translations( $product_id ){
248
+ $trnsl_labels = get_post_meta( $product_id, 'attr_label_translations', true );
249
+ if( !is_array( $trnsl_labels ) ){
250
+ $trnsl_labels = array();
251
+ }
252
+
253
+ return $trnsl_labels;
254
+ }
255
+
256
+ public function sync_default_product_attr( $orig_post_id, $transl_post_id, $lang ){
257
+ $original_default_attributes = get_post_meta( $orig_post_id, '_default_attributes', true );
258
+ if( !empty( $original_default_attributes ) ){
259
+ $unserialized_default_attributes = array();
260
+ foreach(maybe_unserialize( $original_default_attributes ) as $attribute => $default_term_slug ){
261
+ // get the correct language
262
+ if ( substr( $attribute, 0, 3 ) == 'pa_' ) {
263
+ //attr is taxonomy
264
+ if( $this->is_translatable_attribute( $attribute ) ){
265
+ $default_term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $attribute, $default_term_slug );
266
+ $tr_id = apply_filters( 'translate_object_id', $default_term_id, $attribute, false, $lang );
267
+
268
+ if( $tr_id ){
269
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
270
+ $unserialized_default_attributes[ $attribute ] = $translated_term->slug;
271
+ }
272
+ }else{
273
+ $unserialized_default_attributes[ $attribute ] = $default_term_slug;
274
+ }
275
+ }else{
276
+ //custom attr
277
+ $orig_product_attributes = get_post_meta( $orig_post_id, '_product_attributes', true );
278
+ $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
279
+
280
+ if( isset( $unserialized_orig_product_attributes[ $attribute ] ) ){
281
+ $orig_attr_values = explode( '|', $unserialized_orig_product_attributes[ $attribute ][ 'value' ] );
282
+
283
+ foreach( $orig_attr_values as $key => $orig_attr_value ){
284
+ $orig_attr_value_sanitized = strtolower( sanitize_title ( $orig_attr_value ) );
285
+
286
+ if( $orig_attr_value_sanitized == $default_term_slug || trim( $orig_attr_value ) == trim( $default_term_slug ) ){
287
+ $tnsl_product_attributes = get_post_meta( $transl_post_id, '_product_attributes', true );
288
+ $unserialized_tnsl_product_attributes = maybe_unserialize( $tnsl_product_attributes );
289
+
290
+ if( isset( $unserialized_tnsl_product_attributes[ $attribute ] ) ){
291
+ $trnsl_attr_values = explode( '|', $unserialized_tnsl_product_attributes[ $attribute ][ 'value' ] );
292
+
293
+ if( $orig_attr_value_sanitized == $default_term_slug ){
294
+ $trnsl_attr_value = strtolower( sanitize_title( trim( $trnsl_attr_values[ $key ] ) ) );
295
+ }else{
296
+ $trnsl_attr_value = trim( $trnsl_attr_values[ $key ] );
297
+ }
298
+ $unserialized_default_attributes[ $attribute ] = $trnsl_attr_value;
299
+ }
300
+ }
301
+ }
302
+ }
303
+ }
304
+ }
305
+
306
+ $data = array( 'meta_value' => maybe_serialize( $unserialized_default_attributes ) );
307
+ }else{
308
+ $data = array( 'meta_value' => maybe_serialize( array() ) );
309
+ }
310
+
311
+ $where = array( 'post_id' => $transl_post_id, 'meta_key' => '_default_attributes' );
312
+ $this->wpdb->update( $this->wpdb->postmeta, $data, $where );
313
+ }
314
+
315
+ /*
316
+ * get attribute translation
317
+ */
318
+ public function get_custom_attribute_translation( $product_id, $attribute_key, $attribute, $lang_code ){
319
+ $tr_post_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $lang_code );
320
+ $transl = array();
321
+ if( $tr_post_id ){
322
+ if( !$attribute[ 'is_taxonomy' ] ){
323
+ $tr_attrs = get_post_meta($tr_post_id, '_product_attributes', true);
324
+ if( $tr_attrs ){
325
+ foreach( $tr_attrs as $key => $tr_attr ) {
326
+ if( $attribute_key == $key ){
327
+ $transl[ 'value' ] = $tr_attr[ 'value' ];
328
+ $trnsl_labels = $this->get_attr_label_translations( $tr_post_id );
329
+
330
+ if( isset( $trnsl_labels[ $lang_code ][ $attribute_key ] ) ){
331
+ $transl[ 'name' ] = $trnsl_labels[ $lang_code ][ $attribute_key ];
332
+ }else{
333
+ $transl[ 'name' ] = $tr_attr[ 'name' ];
334
+ }
335
+ return $transl;
336
+ }
337
+ }
338
+ }
339
+ return false;
340
+ }
341
+ }
342
+ return false;
343
+ }
344
+
345
+ /*
346
+ * Get custom attribute translation
347
+ * Returned translated attribute or original if missed
348
+ */
349
+ public function get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute ){
350
+ $orig_product_attributes = get_post_meta( $product_id, '_product_attributes', true );
351
+ $unserialized_orig_product_attributes = maybe_unserialize( $orig_product_attributes );
352
+
353
+ foreach( $unserialized_orig_product_attributes as $orig_attr_key => $orig_product_attribute ){
354
+ $orig_attr_key = urldecode( $orig_attr_key );
355
+ if( strtolower( $taxonomy ) == $orig_attr_key ){
356
+ $values = explode( '|', $orig_product_attribute[ 'value' ] );
357
+
358
+ foreach( $values as $key_id => $value ){
359
+ if( trim( $value," " ) == $attribute ){
360
+ $attr_key_id = $key_id;
361
+ }
362
+ }
363
+ }
364
+ }
365
+
366
+ $trnsl_product_attributes = get_post_meta( $tr_product_id, '_product_attributes', true );
367
+ $unserialized_trnsl_product_attributes = maybe_unserialize( $trnsl_product_attributes );
368
+ $taxonomy = sanitize_title( $taxonomy );
369
+ $trnsl_attr_values = explode( '|', $unserialized_trnsl_product_attributes[ $taxonomy ][ 'value' ] );
370
+
371
+ if( isset( $attr_key_id ) && isset( $trnsl_attr_values[ $attr_key_id ] ) ){
372
+ return trim( $trnsl_attr_values[ $attr_key_id ] );
373
+ }
374
+
375
+ return $attribute;
376
+ }
377
+
378
+ public function filter_product_attributes_for_translation( $translated, $key ){
379
+ $translated = $translated
380
+ ? preg_match('#^(?!field-_product_attributes-(.+)-(.+)-(?!value|name))#', $key) : 0;
381
+
382
+ return $translated;
383
+ }
384
+
385
+ public function icl_custom_tax_sync_options(){
386
+ foreach( $_POST['icl_sync_tax'] as $taxonomy => $value){
387
+ if ( substr( $taxonomy, 0, 3 ) == 'pa_' ) {
388
+ $this->set_attribute_config_in_wcml_settings( $taxonomy , $value);
389
+ }
390
+ }
391
+
392
+ }
393
+
394
+ public function is_attributes_fully_translated(){
395
+
396
+ $product_attributes = $this->get_translatable_attributes();
397
+
398
+ $fully_translated = true;
399
+
400
+ if( $product_attributes ){
401
+ foreach( $product_attributes as $attribute ){
402
+ $is_fully_translated = $this->woocommerce_wpml->terms->is_fully_translated( 'pa_' . $attribute->attribute_name );
403
+ if( !$is_fully_translated ){
404
+ $fully_translated = false;
405
+ break;
406
+ }
407
+ }
408
+ }
409
+
410
+ return $fully_translated;
411
+ }
412
+
413
+ public function get_translated_variation_attribute_post_meta( $meta_value, $meta_key, $original_variation_id, $variation_id, $lang ){
414
+
415
+ $original_product_attr = get_post_meta( wp_get_post_parent_id( $original_variation_id ), '_product_attributes', true );
416
+ $tr_product_attr = get_post_meta( wp_get_post_parent_id( $variation_id ), '_product_attributes', true );
417
+
418
+ $tax = wc_sanitize_taxonomy_name ( substr( $meta_key, 10 ) );
419
+ if( taxonomy_exists( $tax ) ){
420
+ $attid = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $meta_value );
421
+ if( $this->is_translatable_attribute( $tax ) && $attid ){
422
+
423
+ $term_obj = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $attid, $tax );
424
+ $trnsl_term_id = apply_filters( 'translate_object_id', $term_obj->term_id, $tax, false, $lang );
425
+
426
+ if( $trnsl_term_id ) {
427
+ $trnsl_term_obj = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $tax );
428
+ $meta_value = $trnsl_term_obj->slug;
429
+ }
430
+ }
431
+ }else{
432
+ if( !isset( $original_product_attr[ $tax ] ) ){
433
+ $tax = sanitize_title( $tax );
434
+ }
435
+
436
+ if( isset( $original_product_attr[ $tax ] ) ){
437
+ if( isset( $tr_product_attr[ $tax ] ) ){
438
+ $values_arrs = array_map( 'trim', explode( '|', $original_product_attr[ $tax ][ 'value' ] ) );
439
+ $values_arrs_tr = array_map( 'trim', explode( '|', $tr_product_attr[ $tax ][ 'value' ] ) );
440
+
441
+ foreach( $values_arrs as $key => $value ){
442
+ $value_sanitized = sanitize_title( $value );
443
+ if(
444
+ ( $value_sanitized == strtolower( urldecode( $meta_value ) ) ||
445
+ strtolower( $value_sanitized ) == $meta_value ||
446
+ $value == $meta_value )
447
+ && isset( $values_arrs_tr[ $key ] ) )
448
+ {
449
+ $meta_value = $values_arrs_tr[ $key ];
450
+ }
451
+ }
452
+ }
453
+ }
454
+ $meta_key = 'attribute_'.$tax;
455
+ }
456
+
457
+ return array(
458
+ 'meta_value' => $meta_value,
459
+ 'meta_key' => $meta_key
460
+ );
461
+ }
462
+
463
  }
inc/class-wcml-capabilities.php CHANGED
@@ -1,33 +1,33 @@
1
- <?php
2
-
3
- class WCML_Capabilities{
4
-
5
- public static function set_up_capabilities(){
6
-
7
- $role = get_role( 'administrator' );
8
- if($role){
9
- $role->add_cap( 'wpml_manage_woocommerce_multilingual' );
10
- $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
11
- }
12
-
13
- $role = get_role( 'super_admin' );
14
- if($role){
15
- $role->add_cap( 'wpml_manage_woocommerce_multilingual' );
16
- $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
17
- }
18
-
19
- $super_admins = get_super_admins();
20
- foreach ($super_admins as $admin) {
21
- $user = new WP_User( $admin );
22
- $user->add_cap( 'wpml_manage_woocommerce_multilingual' );
23
- $user->add_cap( 'wpml_operate_woocommerce_multilingual' );
24
- }
25
-
26
- $role = get_role( 'shop_manager' );
27
- if($role){
28
- $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
29
- }
30
-
31
- }
32
-
33
  }
1
+ <?php
2
+
3
+ class WCML_Capabilities{
4
+
5
+ public static function set_up_capabilities(){
6
+
7
+ $role = get_role( 'administrator' );
8
+ if($role){
9
+ $role->add_cap( 'wpml_manage_woocommerce_multilingual' );
10
+ $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
11
+ }
12
+
13
+ $role = get_role( 'super_admin' );
14
+ if($role){
15
+ $role->add_cap( 'wpml_manage_woocommerce_multilingual' );
16
+ $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
17
+ }
18
+
19
+ $super_admins = get_super_admins();
20
+ foreach ($super_admins as $admin) {
21
+ $user = new WP_User( $admin );
22
+ $user->add_cap( 'wpml_manage_woocommerce_multilingual' );
23
+ $user->add_cap( 'wpml_operate_woocommerce_multilingual' );
24
+ }
25
+
26
+ $role = get_role( 'shop_manager' );
27
+ if($role){
28
+ $role->add_cap( 'wpml_operate_woocommerce_multilingual' );
29
+ }
30
+
31
+ }
32
+
33
  }
inc/class-wcml-cart-removed-items-widget.php CHANGED
@@ -1,28 +1,28 @@
1
- <?php
2
-
3
- class WCML_Cart_Removed_Items_Widget extends WP_Widget {
4
-
5
- function __construct() {
6
-
7
- $widget_opt = array(
8
- 'description' => __( 'Shows a list of the products that existed in the cart before the cart is reset on the front end after switching the language or the currency. It will be hidden when there are no products to show.', 'woocommerce-multilingual' ),
9
- );
10
-
11
- parent::__construct(
12
- 'wcml_cart_deleted_items',
13
- __( 'Products before cart reset', 'woocommerce-multilingual' ),
14
- $widget_opt
15
- );
16
-
17
- }
18
-
19
- function widget( $args, $instance ) {
20
-
21
- echo $args[ 'before_widget' ];
22
-
23
- do_action( 'wcml_removed_cart_items' );
24
-
25
- echo $args[ 'after_widget' ];
26
- }
27
-
28
  }
1
+ <?php
2
+
3
+ class WCML_Cart_Removed_Items_Widget extends WP_Widget {
4
+
5
+ function __construct() {
6
+
7
+ $widget_opt = array(
8
+ 'description' => __( 'Shows a list of the products that existed in the cart before the cart is reset on the front end after switching the language or the currency. It will be hidden when there are no products to show.', 'woocommerce-multilingual' ),
9
+ );
10
+
11
+ parent::__construct(
12
+ 'wcml_cart_deleted_items',
13
+ __( 'Products before cart reset', 'woocommerce-multilingual' ),
14
+ $widget_opt
15
+ );
16
+
17
+ }
18
+
19
+ function widget( $args, $instance ) {
20
+
21
+ echo $args[ 'before_widget' ];
22
+
23
+ do_action( 'wcml_removed_cart_items' );
24
+
25
+ echo $args[ 'after_widget' ];
26
+ }
27
+
28
  }
inc/class-wcml-cart.php CHANGED
@@ -1,445 +1,441 @@
1
- <?php
2
- class WCML_Cart
3
- {
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
- private $woocommerce;
8
-
9
- public function __construct( &$woocommerce_wpml, &$sitepress, &$woocommerce )
10
- {
11
- $this->woocommerce_wpml = $woocommerce_wpml;
12
- $this->sitepress = $sitepress;
13
- $this->woocommerce = $woocommerce;
14
-
15
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR || $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'lang_switch' ] == WCML_CART_CLEAR ){
16
- $this->enqueue_dialog_ui();
17
-
18
- add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
19
- add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
20
- add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
21
-
22
- add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 3 );
23
- add_action( 'wcml_before_switch_currency', array( $this, 'switching_currency_empty_cart_if_needed' ), 10, 2 );
24
- }
25
- else{
26
- //cart widget
27
- add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
28
- add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
29
- add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
30
- add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
31
-
32
- //cart
33
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
34
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ), 10 );
35
- add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
36
- add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
37
-
38
- add_filter('woocommerce_paypal_args', array($this, 'filter_paypal_args'));
39
- add_filter( 'woocommerce_add_to_cart_sold_individually_quantity', array( $this, 'woocommerce_add_to_cart_sold_individually_quantity' ), 10, 3 );
40
-
41
- $this->localize_flat_rates_shipping_classes();
42
- }
43
-
44
- }
45
-
46
- public function enqueue_dialog_ui(){
47
-
48
- wp_enqueue_script( 'jquery-ui-dialog' );
49
- wp_enqueue_style( 'wp-jquery-ui-dialog' );
50
-
51
- }
52
-
53
- public function wcml_removed_cart_items_widget( $args = array() ){
54
-
55
- if( !empty( $this->woocommerce->session ) ){
56
- $removed_cart_items = new WCML_Removed_Cart_Items_UI( $args, $this->woocommerce_wpml, $this->sitepress, $this->woocommerce );
57
- $preview = $removed_cart_items->get_view();
58
-
59
- if ( !isset($args['echo']) || $args['echo'] ) {
60
- echo $preview;
61
- } else {
62
- return $preview;
63
- }
64
- }
65
-
66
- }
67
-
68
- public function switching_currency_empty_cart_if_needed( $currency, $force_switch ){
69
- if( $force_switch && $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR ) {
70
- $this->empty_cart_if_needed('currency_switch');
71
- $this->woocommerce->session->set('wcml_switched_type', 'currency');
72
- }
73
- }
74
-
75
- public function empty_cart_if_needed( $switching_type ){
76
-
77
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ $switching_type ] == WCML_CART_CLEAR ){
78
- $removed_products = $this->woocommerce->session->get( 'wcml_removed_items' ) ? maybe_unserialize( $this->woocommerce->session->get( 'wcml_removed_items' ) ) : array();
79
-
80
- foreach( WC()->cart->get_cart_for_session() as $item_key => $cart ){
81
- if( !in_array( $cart[ 'product_id' ], $removed_products ) ){
82
- $removed_products[] = $cart[ 'product_id' ];
83
- }
84
- WC()->cart->remove_cart_item( $item_key );
85
- }
86
-
87
- if( !empty( $this->woocommerce->session ) ){
88
- $this->woocommerce->session->set( 'wcml_removed_items', serialize( $removed_products ) );
89
- }
90
- }
91
- }
92
-
93
- public function wcml_cart_clear_removed_items( ){
94
-
95
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
96
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_clear_removed_items')){
97
- die('Invalid nonce');
98
- }
99
-
100
- $this->woocommerce->session->__unset( 'wcml_removed_items' );
101
- $this->woocommerce->session->__unset( 'wcml_switched_type' );
102
- }
103
-
104
- public function cart_switching_currency( $exc, $current_currency, $new_currency, $return = false ){
105
-
106
- $cart_for_session = WC()->cart->get_cart_for_session();
107
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_SYNC || empty( $cart_for_session ) ){
108
- return $exc;
109
- }
110
-
111
- $dialog_title = __( 'Switching currency?', 'woocommerce-multilingual');
112
- $confirmation_message = __( 'Your cart is not empty! After you switched the currency, all items from the cart will be removed and you have to add them again.', 'woocommerce-multilingual');
113
- $stay_in = sprintf( __( 'Keep using %s', 'woocommerce-multilingual'), $current_currency );
114
- $switch_to = __( 'Proceed', 'woocommerce-multilingual');
115
-
116
- ob_start();
117
- $this->cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $new_currency, $current_currency );
118
- $html = ob_get_contents();
119
- ob_end_clean();
120
-
121
- if( $return ){
122
- return array( 'prevent_switching' => $html );
123
- }else{
124
- echo json_encode( array( 'prevent_switching' => $html ) );
125
- }
126
-
127
- return true;
128
- }
129
-
130
- public function cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $switch_to_value, $stay_in_value = false, $language_switch = false ){
131
- ?>
132
- <div id="wcml-cart-dialog-confirm" title="<?php echo $dialog_title ?>">
133
- <p><?php echo $confirmation_message; ?></p>
134
- </div>
135
-
136
- <script type="text/javascript">
137
- jQuery( document).ready( function(){
138
- jQuery( "#wcml-cart-dialog-confirm" ).dialog({
139
- resizable: false,
140
- draggable: false,
141
- height: "auto",
142
- width: 500,
143
- modal: true,
144
- closeOnEscape: false,
145
- dialogClass: "wcml-cart-dialog",
146
- open: function(event, ui) {
147
- jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
148
- },
149
- buttons: {
150
- "<?php echo $switch_to; ?>": function() {
151
- jQuery( this ).dialog( "close" );
152
- <?php if( $language_switch ): ?>
153
- window.location = '<?php echo $switch_to_value; ?>';
154
- <?php else: ?>
155
- jQuery('.wcml_currency_switcher').parent().find('img').remove();
156
- wcml_load_currency( "<?php echo $switch_to_value; ?>", true );
157
- <?php endif; ?>
158
-
159
- },
160
- "<?php echo $stay_in; ?>": function() {
161
- jQuery( this ).dialog( "close" );
162
- <?php if( $language_switch ): ?>
163
- window.location = '<?php echo $stay_in_value; ?>';
164
- <?php else: ?>
165
- jQuery('.wcml_currency_switcher').parent().find('img').remove();
166
- jQuery('.wcml_currency_switcher').removeAttr('disabled');
167
- jQuery('.wcml_currency_switcher').val( '<?php echo $stay_in_value; ?>' );
168
- <?php endif; ?>
169
- }
170
- }
171
- });
172
- });
173
- </script>
174
- <?php
175
- }
176
-
177
- public function wcml_refresh_fragments(){
178
- WC()->cart->calculate_totals();
179
- $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
180
- }
181
-
182
- /*
183
- * Update cart and cart session when switch language
184
- */
185
- public function woocommerce_calculate_totals( $cart, $currency = false ){
186
-
187
- $current_language = $this->sitepress->get_current_language();
188
- $new_cart_data = array();
189
-
190
- foreach( $cart->cart_contents as $key => $cart_item ){
191
- $tr_product_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', false, $current_language );
192
- //translate custom attr labels in cart object
193
-
194
- if( version_compare( WC_VERSION , '2.7', '<' ) && isset( $cart_item[ 'data' ]->product_attributes ) ){
195
- foreach( $cart_item[ 'data' ]->product_attributes as $attr_key => $product_attribute ){
196
- if( isset( $product_attribute[ 'is_taxonomy' ]) && !$product_attribute[ 'is_taxonomy' ] ){
197
- $cart->cart_contents[ $key ][ 'data' ]->product_attributes[ $attr_key ][ 'name' ] = $this->woocommerce_wpml->strings->translated_attribute_label(
198
- $product_attribute[ 'name' ],
199
- $product_attribute[ 'name' ],
200
- $tr_product_id );
201
- }
202
- }
203
- }
204
-
205
- //translate custom attr value in cart object
206
- if( isset( $cart_item[ 'variation' ] ) && is_array( $cart_item[ 'variation' ] ) ){
207
- foreach( $cart_item[ 'variation' ] as $attr_key => $attribute ){
208
- $cart->cart_contents[ $key ][ 'variation' ][ $attr_key ] = $this->get_cart_attribute_translation(
209
- $attr_key,
210
- $attribute,
211
- $cart_item[ 'variation_id' ],
212
- $current_language,
213
- $cart_item[ 'product_id' ],
214
- $tr_product_id
215
- );
216
- }
217
- }
218
-
219
- if( $currency !== false ){
220
- $cart->cart_contents[ $key ][ 'data' ]->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
221
- }
222
-
223
- if( $cart_item[ 'product_id' ] == $tr_product_id ){
224
- $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[$key], $key, $current_language );
225
- continue;
226
- }
227
-
228
- if( isset( $cart->cart_contents[ $key ][ 'variation_id' ] ) && $cart->cart_contents[ $key ][ 'variation_id' ] ){
229
- $tr_variation_id = apply_filters( 'translate_object_id', $cart_item[ 'variation_id' ], 'product_variation', false, $current_language );
230
- if( !is_null( $tr_variation_id ) ){
231
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
232
- $cart->cart_contents[ $key ][ 'variation_id' ] = intval( $tr_variation_id );
233
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
234
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
235
- }
236
- }else{
237
- if( !is_null( $tr_product_id ) ){
238
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
239
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
240
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
241
- }
242
- }
243
-
244
- if( !is_null( $tr_product_id ) ){
245
-
246
- $new_key = $this->wcml_generate_cart_key( $cart->cart_contents, $key );
247
- $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
248
- $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
249
-
250
- $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
251
- }
252
- }
253
-
254
- $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
255
- $this->woocommerce->session->cart = $cart->cart_contents;
256
- return $cart->cart_contents;
257
- }
258
-
259
- public function wcml_check_on_duplicate_products_in_cart( $cart_contents ){
260
-
261
- $exists_products = array();
262
- remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
263
-
264
- foreach( $cart_contents as $key => $cart_content ){
265
- $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
266
- if( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ){
267
- continue;
268
- }
269
-
270
- $quantity = $cart_content['quantity'];
271
-
272
- $search_key = $this->wcml_generate_cart_key( $cart_contents, $key );
273
- if( array_key_exists( $search_key, $exists_products ) ){
274
- unset( $cart_contents[ $key ] );
275
- $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] = $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] + $quantity;
276
- $this->woocommerce->cart->calculate_totals();
277
- }else{
278
- $exists_products[ $search_key ] = $key;
279
- }
280
- }
281
-
282
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
283
- return $cart_contents;
284
- }
285
-
286
- public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ){
287
-
288
- $attr_translation = $attribute;
289
-
290
- if( !empty( $attribute ) ){
291
- //delete 'attribute_' at the beginning
292
- $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
293
-
294
- if( taxonomy_exists( $taxonomy ) ){
295
- if( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
296
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
297
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
298
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
299
- $attr_translation = $term->slug;
300
- }
301
- }else{
302
-
303
- $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
304
-
305
- if( $trnsl_attr ){
306
- $attr_translation = $trnsl_attr;
307
- }else{
308
- $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
309
- }
310
- }
311
- }
312
-
313
- return $attr_translation;
314
- }
315
-
316
- public function wcml_generate_cart_key( $cart_contents, $key ){
317
- $cart_item_data = $this->get_cart_item_data_from_cart( $cart_contents[ $key ] );
318
-
319
- return $this->woocommerce->cart->generate_cart_id(
320
- $cart_contents[ $key ][ 'product_id' ],
321
- $cart_contents[ $key ][ 'variation_id' ],
322
- $cart_contents[ $key ][ 'variation' ],
323
- (array) apply_filters( 'woocommerce_add_cart_item_data',
324
- $cart_item_data,
325
- $cart_contents[ $key ][ 'product_id' ],
326
- $cart_contents[ $key ][ 'variation_id' ]
327
- )
328
- );
329
- }
330
-
331
- //get cart_item_data from existing cart array ( from session )
332
- public function get_cart_item_data_from_cart( $cart_contents ){
333
- unset( $cart_contents[ 'product_id' ] );
334
- unset( $cart_contents[ 'variation_id' ] );
335
- unset( $cart_contents[ 'variation' ] );
336
- unset( $cart_contents[ 'quantity' ] );
337
- unset( $cart_contents[ 'line_total' ] );
338
- unset( $cart_contents[ 'line_subtotal' ] );
339
- unset( $cart_contents[ 'line_tax' ] );
340
- unset( $cart_contents[ 'line_subtotal_tax' ] );
341
- unset( $cart_contents[ 'line_tax_data' ] );
342
- unset( $cart_contents[ 'data' ] );
343
-
344
- return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
345
- }
346
-
347
- public function translate_cart_contents( $item ) {
348
- // translate the product id and product data
349
- $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
350
- if ($item[ 'variation_id' ]) {
351
- $item[ 'variation_id' ] = apply_filters( 'translate_object_id',$item[ 'variation_id' ], 'product_variation', true );
352
- }
353
- $product_id = $item[ 'variation_id' ] ? $item[ 'variation_id' ] : $item[ 'product_id' ];
354
- $item[ 'data' ]->post->post_title = get_the_title( $product_id );
355
-
356
- return $item;
357
- }
358
-
359
- public function translate_cart_subtotal( $cart ) {
360
-
361
- if( isset( $_SERVER['REQUEST_URI'] ) ){
362
- //special case: check if attachment loading
363
- $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
364
-
365
- foreach( $attachments as $attachment ){
366
- $match = preg_match( '/\.'.$attachment.'$/', $_SERVER['REQUEST_URI'] );
367
- if( !empty( $match ) ){
368
- return false;
369
- }
370
- }
371
- }
372
-
373
- if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
374
- $cart->calculate_totals();
375
- }
376
-
377
- }
378
-
379
- // refresh cart total to return correct price from WC object
380
- public function wcml_refresh_cart_total() {
381
- WC()->cart->calculate_totals();
382
- }
383
-
384
-
385
- public function localize_flat_rates_shipping_classes(){
386
-
387
- if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
388
- $this->woocommerce->shipping->load_shipping_methods();
389
- $shipping_methods = $this->woocommerce->shipping->get_shipping_methods();
390
- foreach($shipping_methods as $method){
391
- if(isset($method->flat_rate_option)){
392
- add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
393
- }
394
- }
395
-
396
- }
397
- }
398
-
399
- public function translate_shipping_class($rates){
400
-
401
- if(is_array($rates)){
402
- foreach($rates as $shipping_class => $value){
403
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
404
-
405
- if($term_id && !is_wp_error($term_id)){
406
- $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
407
- if($translated_term_id != $term_id){
408
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
409
- unset($rates[$shipping_class]);
410
- $rates[$term->slug] = $value;
411
-
412
- }
413
- }
414
- }
415
- }
416
- return $rates;
417
- }
418
-
419
- public function filter_paypal_args( $args ) {
420
- $args['lc'] = $this->sitepress->get_current_language();
421
-
422
- //filter URL when default permalinks uses
423
- $wpml_settings = $this->sitepress->get_settings();
424
- if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
425
- $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
426
- }
427
-
428
- return $args;
429
- }
430
-
431
- public function woocommerce_add_to_cart_sold_individually_quantity( $qt, $quantity, $product_id ){
432
-
433
- //check if product already added to cart in another language
434
- $current_product_trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
435
-
436
- foreach( WC()->cart->cart_contents as $cart_item ){
437
- $cart_element_trid = $this->sitepress->get_element_trid( $cart_item[ 'product_id' ], 'post_product' );
438
- if( $current_product_trid == $cart_element_trid && $cart_item[ 'quantity' ] > 0 ){
439
- throw new Exception( sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', wc_get_cart_url(), __( 'View cart', 'woocommerce' ), sprintf( __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), get_the_title( $product_id ) ) ) );
440
- }
441
- }
442
-
443
- return $qt;
444
- }
445
  }
1
+ <?php
2
+ class WCML_Cart
3
+ {
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+ private $woocommerce;
8
+
9
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$woocommerce )
10
+ {
11
+ $this->woocommerce_wpml = $woocommerce_wpml;
12
+ $this->sitepress = $sitepress;
13
+ $this->woocommerce = $woocommerce;
14
+
15
+ if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR || $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'lang_switch' ] == WCML_CART_CLEAR ){
16
+ $this->enqueue_dialog_ui();
17
+
18
+ add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
19
+ add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
20
+ add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
21
+
22
+ add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 3 );
23
+ add_action( 'wcml_before_switch_currency', array( $this, 'switching_currency_empty_cart_if_needed' ), 10, 2 );
24
+ }
25
+ else{
26
+ //cart widget
27
+ add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
28
+ add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
29
+ add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
30
+ add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
31
+
32
+ //cart
33
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
34
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ), 10 );
35
+ add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
36
+ add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
37
+
38
+ add_filter('woocommerce_paypal_args', array($this, 'filter_paypal_args'));
39
+ add_filter( 'woocommerce_add_to_cart_sold_individually_quantity', array( $this, 'woocommerce_add_to_cart_sold_individually_quantity' ), 10, 5 );
40
+
41
+ $this->localize_flat_rates_shipping_classes();
42
+ }
43
+
44
+ }
45
+
46
+ public function enqueue_dialog_ui(){
47
+
48
+ wp_enqueue_script( 'jquery-ui-dialog' );
49
+ wp_enqueue_style( 'wp-jquery-ui-dialog' );
50
+
51
+ }
52
+
53
+ public function wcml_removed_cart_items_widget( $args = array() ){
54
+
55
+ if( !empty( $this->woocommerce->session ) ){
56
+ $removed_cart_items = new WCML_Removed_Cart_Items_UI( $args, $this->woocommerce_wpml, $this->sitepress, $this->woocommerce );
57
+ $preview = $removed_cart_items->get_view();
58
+
59
+ if ( !isset($args['echo']) || $args['echo'] ) {
60
+ echo $preview;
61
+ } else {
62
+ return $preview;
63
+ }
64
+ }
65
+
66
+ }
67
+
68
+ public function switching_currency_empty_cart_if_needed( $currency, $force_switch ){
69
+ if( $force_switch && $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR ) {
70
+ $this->empty_cart_if_needed('currency_switch');
71
+ $this->woocommerce->session->set('wcml_switched_type', 'currency');
72
+ }
73
+ }
74
+
75
+ public function empty_cart_if_needed( $switching_type ){
76
+
77
+ if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ $switching_type ] == WCML_CART_CLEAR ){
78
+ $removed_products = $this->woocommerce->session->get( 'wcml_removed_items' ) ? maybe_unserialize( $this->woocommerce->session->get( 'wcml_removed_items' ) ) : array();
79
+
80
+ foreach( WC()->cart->get_cart_for_session() as $item_key => $cart ){
81
+ if( !in_array( $cart[ 'product_id' ], $removed_products ) ){
82
+ $removed_products[] = $cart[ 'product_id' ];
83
+ }
84
+ WC()->cart->remove_cart_item( $item_key );
85
+ }
86
+
87
+ if( !empty( $this->woocommerce->session ) ){
88
+ $this->woocommerce->session->set( 'wcml_removed_items', serialize( $removed_products ) );
89
+ }
90
+ }
91
+ }
92
+
93
+ public function wcml_cart_clear_removed_items( ){
94
+
95
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
96
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_clear_removed_items')){
97
+ die('Invalid nonce');
98
+ }
99
+
100
+ $this->woocommerce->session->__unset( 'wcml_removed_items' );
101
+ $this->woocommerce->session->__unset( 'wcml_switched_type' );
102
+ }
103
+
104
+ public function cart_switching_currency( $exc, $current_currency, $new_currency, $return = false ){
105
+
106
+ $cart_for_session = WC()->cart->get_cart_for_session();
107
+ if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_SYNC || empty( $cart_for_session ) ){
108
+ return $exc;
109
+ }
110
+
111
+ $dialog_title = __( 'Switching currency?', 'woocommerce-multilingual');
112
+ $confirmation_message = __( 'Your cart is not empty! After you switched the currency, all items from the cart will be removed and you have to add them again.', 'woocommerce-multilingual');
113
+ $stay_in = sprintf( __( 'Keep using %s', 'woocommerce-multilingual'), $current_currency );
114
+ $switch_to = __( 'Proceed', 'woocommerce-multilingual');
115
+
116
+ ob_start();
117
+ $this->cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $new_currency, $current_currency );
118
+ $html = ob_get_contents();
119
+ ob_end_clean();
120
+
121
+ if( $return ){
122
+ return array( 'prevent_switching' => $html );
123
+ }else{
124
+ echo json_encode( array( 'prevent_switching' => $html ) );
125
+ }
126
+
127
+ return true;
128
+ }
129
+
130
+ public function cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $switch_to_value, $stay_in_value = false, $language_switch = false ){
131
+ ?>
132
+ <div id="wcml-cart-dialog-confirm" title="<?php echo $dialog_title ?>">
133
+ <p><?php echo $confirmation_message; ?></p>
134
+ </div>
135
+
136
+ <script type="text/javascript">
137
+ jQuery( document).ready( function(){
138
+ jQuery( "#wcml-cart-dialog-confirm" ).dialog({
139
+ resizable: false,
140
+ draggable: false,
141
+ height: "auto",
142
+ width: 500,
143
+ modal: true,
144
+ closeOnEscape: false,
145
+ dialogClass: "wcml-cart-dialog",
146
+ open: function(event, ui) {
147
+ jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
148
+ },
149
+ buttons: {
150
+ "<?php echo $switch_to; ?>": function() {
151
+ jQuery( this ).dialog( "close" );
152
+ <?php if( $language_switch ): ?>
153
+ window.location = '<?php echo $switch_to_value; ?>';
154
+ <?php else: ?>
155
+ jQuery('.wcml_currency_switcher').parent().find('img').remove();
156
+ wcml_load_currency( "<?php echo $switch_to_value; ?>", true );
157
+ <?php endif; ?>
158
+
159
+ },
160
+ "<?php echo $stay_in; ?>": function() {
161
+ jQuery( this ).dialog( "close" );
162
+ <?php if( $language_switch ): ?>
163
+ window.location = '<?php echo $stay_in_value; ?>';
164
+ <?php else: ?>
165
+ jQuery('.wcml_currency_switcher').parent().find('img').remove();
166
+ jQuery('.wcml_currency_switcher').removeAttr('disabled');
167
+ jQuery('.wcml_currency_switcher').val( '<?php echo $stay_in_value; ?>' );
168
+ <?php endif; ?>
169
+ }
170
+ }
171
+ });
172
+ });
173
+ </script>
174
+ <?php
175
+ }
176
+
177
+ public function wcml_refresh_fragments(){
178
+ WC()->cart->calculate_totals();
179
+ $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
180
+ }
181
+
182
+ /*
183
+ * Update cart and cart session when switch language
184
+ */
185
+ public function woocommerce_calculate_totals( $cart, $currency = false ){
186
+
187
+ $current_language = $this->sitepress->get_current_language();
188
+ $new_cart_data = array();
189
+
190
+ foreach( $cart->cart_contents as $key => $cart_item ){
191
+ $tr_product_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', false, $current_language );
192
+ //translate custom attr labels in cart object
193
+
194
+ if( version_compare( WC_VERSION , '2.7', '<' ) && isset( $cart_item[ 'data' ]->product_attributes ) ){
195
+ foreach( $cart_item[ 'data' ]->product_attributes as $attr_key => $product_attribute ){
196
+ if( isset( $product_attribute[ 'is_taxonomy' ]) && !$product_attribute[ 'is_taxonomy' ] ){
197
+ $cart->cart_contents[ $key ][ 'data' ]->product_attributes[ $attr_key ][ 'name' ] = $this->woocommerce_wpml->strings->translated_attribute_label(
198
+ $product_attribute[ 'name' ],
199
+ $product_attribute[ 'name' ],
200
+ $tr_product_id );
201
+ }
202
+ }
203
+ }
204
+
205
+ //translate custom attr value in cart object
206
+ if( isset( $cart_item[ 'variation' ] ) && is_array( $cart_item[ 'variation' ] ) ){
207
+ foreach( $cart_item[ 'variation' ] as $attr_key => $attribute ){
208
+ $cart->cart_contents[ $key ][ 'variation' ][ $attr_key ] = $this->get_cart_attribute_translation(
209
+ $attr_key,
210
+ $attribute,
211
+ $cart_item[ 'variation_id' ],
212
+ $current_language,
213
+ $cart_item[ 'product_id' ],
214
+ $tr_product_id
215
+ );
216
+ }
217
+ }
218
+
219
+ if( $currency !== false ){
220
+ $cart->cart_contents[ $key ][ 'data' ]->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
221
+ }
222
+
223
+ if( $cart_item[ 'product_id' ] == $tr_product_id ){
224
+ $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[$key], $key, $current_language );
225
+ continue;
226
+ }
227
+
228
+ if( isset( $cart->cart_contents[ $key ][ 'variation_id' ] ) && $cart->cart_contents[ $key ][ 'variation_id' ] ){
229
+ $tr_variation_id = apply_filters( 'translate_object_id', $cart_item[ 'variation_id' ], 'product_variation', false, $current_language );
230
+ if( !is_null( $tr_variation_id ) ){
231
+ $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
232
+ $cart->cart_contents[ $key ][ 'variation_id' ] = intval( $tr_variation_id );
233
+ $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
234
+ $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
235
+ }
236
+ }else{
237
+ if( !is_null( $tr_product_id ) ){
238
+ $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
239
+ $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
240
+ $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
241
+ }
242
+ }
243
+
244
+ if( !is_null( $tr_product_id ) ){
245
+
246
+ $new_key = $this->wcml_generate_cart_key( $cart->cart_contents, $key );
247
+ $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
248
+ $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
249
+
250
+ $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
251
+ }
252
+ }
253
+
254
+ $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
255
+ $this->woocommerce->session->cart = $cart->cart_contents;
256
+ return $cart->cart_contents;
257
+ }
258
+
259
+ public function wcml_check_on_duplicate_products_in_cart( $cart_contents ){
260
+
261
+ $exists_products = array();
262
+ remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
263
+
264
+ foreach( $cart_contents as $key => $cart_content ){
265
+ $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
266
+ if( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ){
267
+ continue;
268
+ }
269
+
270
+ $quantity = $cart_content['quantity'];
271
+
272
+ $search_key = $this->wcml_generate_cart_key( $cart_contents, $key );
273
+ if( array_key_exists( $search_key, $exists_products ) ){
274
+ unset( $cart_contents[ $key ] );
275
+ $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] = $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] + $quantity;
276
+ $this->woocommerce->cart->calculate_totals();
277
+ }else{
278
+ $exists_products[ $search_key ] = $key;
279
+ }
280
+ }
281
+
282
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
283
+ return $cart_contents;
284
+ }
285
+
286
+ public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ){
287
+
288
+ $attr_translation = $attribute;
289
+
290
+ if( !empty( $attribute ) ){
291
+ //delete 'attribute_' at the beginning
292
+ $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
293
+
294
+ if( taxonomy_exists( $taxonomy ) ){
295
+ if( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
296
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
297
+ $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
298
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
299
+ $attr_translation = $term->slug;
300
+ }
301
+ }else{
302
+
303
+ $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
304
+
305
+ if( $trnsl_attr ){
306
+ $attr_translation = $trnsl_attr;
307
+ }else{
308
+ $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
309
+ }
310
+ }
311
+ }
312
+
313
+ return $attr_translation;
314
+ }
315
+
316
+ public function wcml_generate_cart_key( $cart_contents, $key ){
317
+ $cart_item_data = $this->get_cart_item_data_from_cart( $cart_contents[ $key ] );
318
+
319
+ return $this->woocommerce->cart->generate_cart_id(
320
+ $cart_contents[ $key ][ 'product_id' ],
321
+ $cart_contents[ $key ][ 'variation_id' ],
322
+ $cart_contents[ $key ][ 'variation' ],
323
+ $cart_item_data
324
+ );
325
+ }
326
+
327
+ //get cart_item_data from existing cart array ( from session )
328
+ public function get_cart_item_data_from_cart( $cart_contents ){
329
+ unset( $cart_contents[ 'product_id' ] );
330
+ unset( $cart_contents[ 'variation_id' ] );
331
+ unset( $cart_contents[ 'variation' ] );
332
+ unset( $cart_contents[ 'quantity' ] );
333
+ unset( $cart_contents[ 'line_total' ] );
334
+ unset( $cart_contents[ 'line_subtotal' ] );
335
+ unset( $cart_contents[ 'line_tax' ] );
336
+ unset( $cart_contents[ 'line_subtotal_tax' ] );
337
+ unset( $cart_contents[ 'line_tax_data' ] );
338
+ unset( $cart_contents[ 'data' ] );
339
+
340
+ return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
341
+ }
342
+
343
+ public function translate_cart_contents( $item ) {
344
+ // translate the product id and product data
345
+ $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
346
+ if ($item[ 'variation_id' ]) {
347
+ $item[ 'variation_id' ] = apply_filters( 'translate_object_id',$item[ 'variation_id' ], 'product_variation', true );
348
+ }
349
+ $product_id = $item[ 'variation_id' ] ? $item[ 'variation_id' ] : $item[ 'product_id' ];
350
+ $item[ 'data' ]->post->post_title = get_the_title( $product_id );
351
+
352
+ return $item;
353
+ }
354
+
355
+ public function translate_cart_subtotal( $cart ) {
356
+
357
+ if( isset( $_SERVER['REQUEST_URI'] ) ){
358
+ //special case: check if attachment loading
359
+ $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
360
+
361
+ foreach( $attachments as $attachment ){
362
+ $match = preg_match( '/\.'.$attachment.'$/', $_SERVER['REQUEST_URI'] );
363
+ if( !empty( $match ) ){
364
+ return false;
365
+ }
366
+ }
367
+ }
368
+
369
+ if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
370
+ $cart->calculate_totals();
371
+ }
372
+
373
+ }
374
+
375
+ // refresh cart total to return correct price from WC object
376
+ public function wcml_refresh_cart_total() {
377
+ WC()->cart->calculate_totals();
378
+ }
379
+
380
+
381
+ public function localize_flat_rates_shipping_classes(){
382
+
383
+ if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
384
+ $this->woocommerce->shipping->load_shipping_methods();
385
+ $shipping_methods = $this->woocommerce->shipping->get_shipping_methods();
386
+ foreach($shipping_methods as $method){
387
+ if(isset($method->flat_rate_option)){
388
+ add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
389
+ }
390
+ }
391
+
392
+ }
393
+ }
394
+
395
+ public function translate_shipping_class($rates){
396
+
397
+ if(is_array($rates)){
398
+ foreach($rates as $shipping_class => $value){
399
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
400
+
401
+ if($term_id && !is_wp_error($term_id)){
402
+ $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
403
+ if($translated_term_id != $term_id){
404
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
405
+ unset($rates[$shipping_class]);
406
+ $rates[$term->slug] = $value;
407
+
408
+ }
409
+ }
410
+ }
411
+ }
412
+ return $rates;
413
+ }
414
+
415
+ public function filter_paypal_args( $args ) {
416
+ $args['lc'] = $this->sitepress->get_current_language();
417
+
418
+ //filter URL when default permalinks uses
419
+ $wpml_settings = $this->sitepress->get_settings();
420
+ if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
421
+ $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
422
+ }
423
+
424
+ return $args;
425
+ }
426
+
427
+ public function woocommerce_add_to_cart_sold_individually_quantity( $qt, $quantity, $product_id, $variation_id, $cart_item_data ){
428
+
429
+ //check if product already added to cart in another language
430
+ $current_product_trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
431
+
432
+ foreach( WC()->cart->cart_contents as $cart_item ){
433
+ $cart_element_trid = $this->sitepress->get_element_trid( $cart_item[ 'product_id' ], 'post_product' );
434
+ if( apply_filters( 'wcml_add_to_cart_sold_individually', true, $cart_item_data, $product_id, $quantity ) && $current_product_trid == $cart_element_trid && $cart_item[ 'quantity' ] > 0 ){
435
+ throw new Exception( sprintf( '<a href="%s" class="button wc-forward">%s</a> %s', wc_get_cart_url(), __( 'View cart', 'woocommerce' ), sprintf( __( 'You cannot add another "%s" to your cart.', 'woocommerce' ), get_the_title( $product_id ) ) ) );
436
+ }
437
+ }
438
+
439
+ return $qt;
440
+ }
 
 
 
 
441
  }
inc/class-wcml-compatibility.php CHANGED
@@ -1,176 +1,176 @@
1
- <?php
2
-
3
- class WCML_Compatibility {
4
-
5
- /**
6
- * @var SitePress
7
- */
8
- public $sitepress;
9
-
10
- /**
11
- * @var woocommerce_wpml
12
- */
13
- public $woocommerce_wpml;
14
-
15
- /**
16
- * @var wpdb
17
- */
18
- public $wpdb;
19
-
20
- function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
21
- $this->sitepress = $sitepress;
22
- $this->woocommerce_wpml = $woocommerce_wpml;
23
- $this->wpdb = $wpdb;
24
- $this->init();
25
-
26
- }
27
-
28
- function init(){
29
- //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
30
-
31
- //WooCommerce Tab Manager plugin
32
- if(class_exists('WC_Tab_Manager')){
33
- global $woocommerce;
34
- $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb );
35
- }
36
-
37
- //WooCommerce Table Rate Shipping plugin
38
- if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
- $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
40
- }
41
-
42
- //WooCommerce Subscriptions
43
- if(class_exists('WC_Subscriptions')){
44
- $this->wp_subscriptions = new WCML_WC_Subscriptions();
45
- }
46
-
47
- //WooCommerce Name Your Price
48
- if(class_exists('WC_Name_Your_Price')){
49
- $this->name_your_price = new WCML_WC_Name_Your_Price();
50
- }
51
-
52
- //Product Bundle
53
- if(class_exists('WC_Product_Bundle')){
54
- $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml );
55
- }
56
-
57
- // WooCommerce Variation Swatches and Photos
58
- if(class_exists('WC_SwatchesPlugin')){
59
- $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
60
- }
61
-
62
- // Product Add-ons
63
- if(class_exists( 'Product_Addon_Display' )){
64
- $this->product_addons = new WCML_Product_Addons( $this->sitepress );
65
- }
66
-
67
- // Product Per Product Shipping
68
- if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
69
- new WCML_Per_Product_Shipping();
70
- }
71
- //Store Exporter plugin
72
- if(defined('WOO_CE_PATH')){
73
- $this->wc_exporter = new WCML_wcExporter();
74
- }
75
-
76
- //Gravity Forms
77
- if(class_exists('GFForms')){
78
- $this->gravityforms = new WCML_gravityforms();
79
- }
80
-
81
- //Sensei WooThemes
82
- if(class_exists('WooThemes_Sensei')){
83
- $this->sensei = new WCML_sensei();
84
- }
85
-
86
- //Extra Product Options
87
- if(class_exists('TM_Extra_Product_Options')){
88
- $this->extra_product_options = new WCML_Extra_Product_Options();
89
- }
90
-
91
- // Dynamic Pricing
92
- if ( class_exists('WC_Dynamic_Pricing') ) {
93
- $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
94
- }
95
-
96
- // WooCommerce Bookings
97
- if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
98
- $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $this->wpdb );
99
-
100
- // WooCommerce Accommodation Bookings
101
- if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
102
- $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
103
- }
104
- }
105
-
106
- // WooCommerce Checkout Field Editor
107
- if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
108
- $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
109
- }
110
-
111
- if (class_exists('WC_Bulk_Stock_Management')) {
112
- $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
113
- }
114
-
115
- // WooCommerce Advanced Ajax Layered Navigation
116
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
117
- if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
118
- $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
119
- }
120
-
121
- if ( is_plugin_active( 'woocommerce-ajax-cart/wooajaxcart.php' ) ) {
122
- $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
123
- }
124
-
125
- // woocommerce composite products
126
- if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
127
- $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml );
128
- }
129
-
130
- // woocommerce checkout addons
131
- if (function_exists('init_woocommerce_checkout_add_ons')) {
132
- $this->wc_checkout_addons = new WCML_Checkout_Addons();
133
- }
134
-
135
- // woocommerce checkout addons
136
- if ( wp_get_theme() == 'Flatsome' ) {
137
- $this->flatsome = new WCML_Flatsome();
138
- }
139
-
140
- if (class_exists('WC_Mix_and_Match')) {
141
- $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
142
- }
143
-
144
- if ( defined( 'WPSEO_VERSION') ) {
145
- $this->wpseo = new WCML_WPSEO();
146
- }
147
-
148
- //Adventure Tours theme
149
- if( function_exists( 'adventure_tours_check' ) ){
150
- $this->adventure_tours = new WCML_Adventure_tours();
151
- }
152
-
153
- //Aurum Theme
154
- if( wp_get_theme() == 'Aurum' ){
155
- new WCML_Aurum();
156
- }
157
-
158
- // Visual Products Configurator
159
- if( class_exists( 'Vpc' ) ){
160
- $this->vpc = new WCML_Vpc();
161
- }
162
-
163
- // WooCommerce Show Single Variations
164
- if( defined( 'JCK_WSSV_PATH' ) ){
165
- new WCML_JCK_WSSV();
166
- }
167
-
168
- // WooCommerce Print Invoices
169
- if( class_exists( 'WC_PIP' ) ){
170
- $this->pip = new WCML_Pip();
171
- }
172
-
173
-
174
- }
175
-
176
  }
1
+ <?php
2
+
3
+ class WCML_Compatibility {
4
+
5
+ /**
6
+ * @var SitePress
7
+ */
8
+ public $sitepress;
9
+
10
+ /**
11
+ * @var woocommerce_wpml
12
+ */
13
+ public $woocommerce_wpml;
14
+
15
+ /**
16
+ * @var wpdb
17
+ */
18
+ public $wpdb;
19
+
20
+ function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
21
+ $this->sitepress = $sitepress;
22
+ $this->woocommerce_wpml = $woocommerce_wpml;
23
+ $this->wpdb = $wpdb;
24
+ $this->init();
25
+
26
+ }
27
+
28
+ function init(){
29
+ //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
30
+
31
+ //WooCommerce Tab Manager plugin
32
+ if(class_exists('WC_Tab_Manager')){
33
+ global $woocommerce;
34
+ $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb );
35
+ }
36
+
37
+ //WooCommerce Table Rate Shipping plugin
38
+ if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
+ $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
40
+ }
41
+
42
+ //WooCommerce Subscriptions
43
+ if(class_exists('WC_Subscriptions')){
44
+ $this->wp_subscriptions = new WCML_WC_Subscriptions();
45
+ }
46
+
47
+ //WooCommerce Name Your Price
48
+ if(class_exists('WC_Name_Your_Price')){
49
+ $this->name_your_price = new WCML_WC_Name_Your_Price();
50
+ }
51
+
52
+ //Product Bundle
53
+ if(class_exists('WC_Product_Bundle')){
54
+ $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml );
55
+ }
56
+
57
+ // WooCommerce Variation Swatches and Photos
58
+ if(class_exists('WC_SwatchesPlugin')){
59
+ $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
60
+ }
61
+
62
+ // Product Add-ons
63
+ if(class_exists( 'Product_Addon_Display' )){
64
+ $this->product_addons = new WCML_Product_Addons( $this->sitepress );
65
+ }
66
+
67
+ // Product Per Product Shipping
68
+ if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
69
+ new WCML_Per_Product_Shipping();
70
+ }
71
+ //Store Exporter plugin
72
+ if(defined('WOO_CE_PATH')){
73
+ $this->wc_exporter = new WCML_wcExporter();
74
+ }
75
+
76
+ //Gravity Forms
77
+ if(class_exists('GFForms')){
78
+ $this->gravityforms = new WCML_gravityforms();
79
+ }
80
+
81
+ //Sensei WooThemes
82
+ if(class_exists('WooThemes_Sensei')){
83
+ $this->sensei = new WCML_sensei();
84
+ }
85
+
86
+ //Extra Product Options
87
+ if(class_exists('TM_Extra_Product_Options')){
88
+ $this->extra_product_options = new WCML_Extra_Product_Options();
89
+ }
90
+
91
+ // Dynamic Pricing
92
+ if ( class_exists('WC_Dynamic_Pricing') ) {
93
+ $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
94
+ }
95
+
96
+ // WooCommerce Bookings
97
+ if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
98
+ $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $this->wpdb );
99
+
100
+ // WooCommerce Accommodation Bookings
101
+ if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
102
+ $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
103
+ }
104
+ }
105
+
106
+ // WooCommerce Checkout Field Editor
107
+ if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
108
+ $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
109
+ }
110
+
111
+ if (class_exists('WC_Bulk_Stock_Management')) {
112
+ $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
113
+ }
114
+
115
+ // WooCommerce Advanced Ajax Layered Navigation
116
+ include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
117
+ if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
118
+ $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
119
+ }
120
+
121
+ if ( is_plugin_active( 'woocommerce-ajax-cart/wooajaxcart.php' ) ) {
122
+ $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
123
+ }
124
+
125
+ // woocommerce composite products
126
+ if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
127
+ $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml );
128
+ }
129
+
130
+ // woocommerce checkout addons
131
+ if (function_exists('init_woocommerce_checkout_add_ons')) {
132
+ $this->wc_checkout_addons = new WCML_Checkout_Addons();
133
+ }
134
+
135
+ // woocommerce checkout addons
136
+ if ( wp_get_theme() == 'Flatsome' ) {
137
+ $this->flatsome = new WCML_Flatsome();
138
+ }
139
+
140
+ if (class_exists('WC_Mix_and_Match')) {
141
+ $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
142
+ }
143
+
144
+ if ( defined( 'WPSEO_VERSION') ) {
145
+ $this->wpseo = new WCML_WPSEO();
146
+ }
147
+
148
+ //Adventure Tours theme
149
+ if( function_exists( 'adventure_tours_check' ) ){
150
+ $this->adventure_tours = new WCML_Adventure_tours();
151
+ }
152
+
153
+ //Aurum Theme
154
+ if( wp_get_theme() == 'Aurum' ){
155
+ new WCML_Aurum();
156
+ }
157
+
158
+ // Visual Products Configurator
159
+ if( class_exists( 'Vpc' ) ){
160
+ $this->vpc = new WCML_Vpc();
161
+ }
162
+
163
+ // WooCommerce Show Single Variations
164
+ if( defined( 'JCK_WSSV_PATH' ) ){
165
+ new WCML_JCK_WSSV();
166
+ }
167
+
168
+ // WooCommerce Print Invoices
169
+ if( class_exists( 'WC_PIP' ) ){
170
+ $this->pip = new WCML_Pip();
171
+ }
172
+
173
+
174
+ }
175
+
176
  }
inc/class-wcml-coupons.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
-
3
- class WCML_Coupons{
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
-
8
- public function __construct( &$woocommerce_wpml, &$sitepress ){
9
- $this->woocommerce_wpml = $woocommerce_wpml;
10
- $this->sitepress = $sitepress;
11
-
12
- add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
13
- add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
14
- }
15
-
16
- public function wcml_coupon_loaded( $coupons_data ){
17
-
18
- $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
19
-
20
- $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
21
- $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
22
- $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
23
- $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
24
-
25
- $product_ids = array();
26
- $exclude_product_ids = array();
27
- $product_categories_ids = array();
28
- $exclude_product_categories_ids = array();
29
-
30
- foreach( $coupon_product_ids as $prod_id ){
31
- $post_type = get_post_field( 'post_type', $prod_id );
32
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
33
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
34
- foreach( $translations as $translation ){
35
- $product_ids[] = $translation->element_id;
36
- }
37
- }
38
- foreach( $coupon_excluded_product_ids as $prod_id ){
39
- $post_type = get_post_field( 'post_type', $prod_id );
40
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
41
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
42
- foreach( $translations as $translation ){
43
- $exclude_product_ids[] = $translation->element_id;
44
- }
45
- }
46
-
47
- foreach( $coupon_product_categories as $cat_id ){
48
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
49
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
50
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
51
-
52
- foreach( $translations as $translation ){
53
- $product_categories_ids[] = $translation->term_id;
54
- }
55
- }
56
-
57
- foreach( $coupon_excluded_product_categories as $cat_id ){
58
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
59
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
60
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
61
- foreach( $translations as $translation ){
62
- $exclude_product_categories_ids[] = $translation->term_id;
63
- }
64
- }
65
-
66
- if( $wc_27_coupons ){
67
- $coupons_data->set_product_ids( $product_ids );
68
- $coupons_data->set_excluded_product_ids( $exclude_product_ids );
69
- $coupons_data->set_product_categories( $product_categories_ids );
70
- $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
71
- } else {
72
- $coupons_data->product_ids = $product_ids;
73
- $coupons_data->exclude_product_ids = $exclude_product_ids;
74
- $coupons_data->product_categories = $product_categories_ids;
75
- $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
76
- }
77
-
78
- return $coupons_data;
79
- }
80
-
81
- public function icl_adjust_terms_filtering(){
82
- if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
83
- global $icl_adjust_id_url_filter_off;
84
- $icl_adjust_id_url_filter_off = true;
85
- }
86
- }
87
-
88
  }
1
+ <?php
2
+
3
+ class WCML_Coupons{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+
8
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
9
+ $this->woocommerce_wpml = $woocommerce_wpml;
10
+ $this->sitepress = $sitepress;
11
+
12
+ add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
13
+ add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
14
+ }
15
+
16
+ public function wcml_coupon_loaded( $coupons_data ){
17
+
18
+ $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
19
+
20
+ $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
21
+ $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
22
+ $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
23
+ $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
24
+
25
+ $product_ids = array();
26
+ $exclude_product_ids = array();
27
+ $product_categories_ids = array();
28
+ $exclude_product_categories_ids = array();
29
+
30
+ foreach( $coupon_product_ids as $prod_id ){
31
+ $post_type = get_post_field( 'post_type', $prod_id );
32
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
33
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
34
+ foreach( $translations as $translation ){
35
+ $product_ids[] = $translation->element_id;
36
+ }
37
+ }
38
+ foreach( $coupon_excluded_product_ids as $prod_id ){
39
+ $post_type = get_post_field( 'post_type', $prod_id );
40
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
41
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
42
+ foreach( $translations as $translation ){
43
+ $exclude_product_ids[] = $translation->element_id;
44
+ }
45
+ }
46
+
47
+ foreach( $coupon_product_categories as $cat_id ){
48
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
49
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
50
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
51
+
52
+ foreach( $translations as $translation ){
53
+ $product_categories_ids[] = $translation->term_id;
54
+ }
55
+ }
56
+
57
+ foreach( $coupon_excluded_product_categories as $cat_id ){
58
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
59
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
60
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
61
+ foreach( $translations as $translation ){
62
+ $exclude_product_categories_ids[] = $translation->term_id;
63
+ }
64
+ }
65
+
66
+ if( $wc_27_coupons ){
67
+ $coupons_data->set_product_ids( $product_ids );
68
+ $coupons_data->set_excluded_product_ids( $exclude_product_ids );
69
+ $coupons_data->set_product_categories( $product_categories_ids );
70
+ $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
71
+ } else {
72
+ $coupons_data->product_ids = $product_ids;
73
+ $coupons_data->exclude_product_ids = $exclude_product_ids;
74
+ $coupons_data->product_categories = $product_categories_ids;
75
+ $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
76
+ }
77
+
78
+ return $coupons_data;
79
+ }
80
+
81
+ public function icl_adjust_terms_filtering(){
82
+ if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
83
+ global $icl_adjust_id_url_filter_off;
84
+ $icl_adjust_id_url_filter_off = true;
85
+ }
86
+ }
87
+
88
  }
inc/class-wcml-dependencies.php CHANGED
@@ -1,346 +1,346 @@
1
- <?php
2
-
3
- class WCML_Dependencies{
4
-
5
-
6
- private $missing = array();
7
- private $err_message = '';
8
- private $allok = true;
9
-
10
- function __construct(){
11
-
12
- if(is_admin()){
13
- add_action('wp_ajax_wcml_fix_strings_language', array($this, 'fix_strings_language')); // TODO: remove after WPML release with support strings in different languages
14
-
15
- add_action('init', array($this, 'check_wpml_config'), 100);
16
- }
17
-
18
-
19
- }
20
-
21
- function check(){
22
- global $woocommerce_wpml, $sitepress, $woocommerce;
23
-
24
- if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE || is_null( $sitepress ) || !class_exists('SitePress')){
25
- $this->missing['WPML'] = WCML_Links::generate_tracking_link('https://wpml.org/');
26
- $this->allok = false;
27
- } elseif(version_compare(ICL_SITEPRESS_VERSION, '3.4', '<')){
28
- add_action('admin_notices', array($this, '_old_wpml_warning'));
29
- $this->allok = false;
30
- }
31
-
32
- if(!class_exists('woocommerce')){
33
- $this->missing['WooCommerce'] = 'http://www.woothemes.com/woocommerce/';
34
- $this->allok = false;
35
- }elseif( ( defined('WC_VERSION') && version_compare( WC_VERSION , '2.1', '<' ) ) || ( isset( $woocommerce->version ) && version_compare( $woocommerce->version , '2.1', '<' ) ) ){
36
- add_action('admin_notices', array($this, '_old_wc_warning'));
37
- $this->allok = false;
38
- }
39
-
40
- if(!defined('WPML_TM_VERSION')){
41
- $this->missing['WPML Translation Management'] = WCML_Links::generate_tracking_link('https://wpml.org/');
42
- $this->allok = false;
43
- }elseif(version_compare(WPML_TM_VERSION, '1.9', '<')){
44
- add_action('admin_notices', array($this, '_old_wpml_tm_warning'));
45
- $this->allok = false;
46
- }
47
-
48
- if(!defined('WPML_ST_VERSION')){
49
- $this->missing['WPML String Translation'] = WCML_Links::generate_tracking_link('https://wpml.org/');
50
- $this->allok = false;
51
- }elseif(version_compare(WPML_ST_VERSION, '2.0', '<')){
52
- add_action('admin_notices', array($this, '_old_wpml_st_warning'));
53
- $this->allok = false;
54
- }
55
-
56
- if(!defined('WPML_MEDIA_VERSION')){
57
- $this->missing['WPML Media'] = WCML_Links::generate_tracking_link('https://wpml.org/');
58
- $this->allok = false;
59
- }elseif(version_compare(WPML_MEDIA_VERSION, '2.1', '<')){
60
- add_action('admin_notices', array($this, '_old_wpml_media_warning'));
61
- $this->allok = false;
62
- }
63
-
64
- if ($this->missing) {
65
- add_action('admin_notices', array($this, '_missing_plugins_warning'));
66
- }
67
-
68
- if($this->allok){
69
- $this->check_for_incompatible_permalinks();
70
- }
71
-
72
- if(isset($sitepress)){
73
- $this->allok = $this->allok & $sitepress->setup();
74
- }else{
75
- $this->load_twig_support();
76
- }
77
-
78
- return $this->allok;
79
- }
80
-
81
- /**
82
- * Adds admin notice.
83
- */
84
- public function _old_wpml_warning(){
85
- ?>
86
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior %s.',
87
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '3.4'); ?></p></div>
88
- <?php }
89
-
90
- function _old_wc_warning(){
91
- ?>
92
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">Woocommerce</a> versions prior %s.',
93
- 'woocommerce-multilingual'), 'http://www.woothemes.com/woocommerce/', '2.1' ); ?></p></div>
94
- <?php }
95
-
96
- public function _old_wpml_tm_warning(){
97
- ?>
98
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML Translation Management</a> versions prior %s.',
99
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '1.9'); ?></p></div>
100
- <?php }
101
-
102
- public function _old_wpml_st_warning(){
103
- ?>
104
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML String Translation</a> versions prior %s.',
105
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.0'); ?></p></div>
106
- <?php }
107
-
108
- public function _old_wpml_media_warning(){
109
- ?>
110
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML Media</a> versions prior %s.',
111
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.1'); ?></p></div>
112
- <?php }
113
-
114
-
115
- /**
116
- * Adds admin notice.
117
- */
118
- public function _missing_plugins_warning(){
119
-
120
- $missing = '';
121
- $counter = 0;
122
- foreach ($this->missing as $title => $url) {
123
- $counter ++;
124
- if ($counter == sizeof($this->missing)) {
125
- $sep = '';
126
- } elseif ($counter == sizeof($this->missing) - 1) {
127
- $sep = ' ' . __('and', 'woocommerce-multilingual') . ' ';
128
- } else {
129
- $sep = ', ';
130
- }
131
- $missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep;
132
- } ?>
133
-
134
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires %s in order to work.', 'woocommerce-multilingual'), $missing); ?></p></div>
135
- <?php
136
- }
137
-
138
- /**
139
- * For all the urls to work we need either:
140
- * 1) the shop page slug must be the same in all languages
141
- * 2) or the shop prefix disabled in woocommerce settings
142
- * one of these must be true for product urls to work
143
- * if none of these are true, display a warning message
144
- */
145
- private function check_for_incompatible_permalinks() {
146
- global $sitepress, $sitepress_settings, $pagenow;
147
-
148
- // WooCommerce 2.x specific checks
149
- $permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
150
- if (empty($permalinks['product_base'])) {
151
- return;
152
- }
153
-
154
- $message = sprintf('Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual');
155
- $message .= '<br /><br />';
156
- $message .= sprintf('Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual');
157
- $message .= '<br /><br />';
158
- $message .= '<a href="' . admin_url('options-permalink.php') . '">' . __('Permalink settings', 'woocommerce-multilingual') . '</a>';
159
- $message .= ' | ';
160
- $message .= '<a href="' . admin_url('admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options') . '">' . __('Configure products slug translation', 'woocommerce-multilingual') . '</a>';
161
-
162
-
163
- // Check if translated shop pages have the same slug (only 1.x)
164
- $allsame = true;
165
- if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
166
- } else {
167
- $shop_page_id = get_option('woocommerce_shop_page_id', false);
168
- if (!empty($shop_page_id)) {
169
- $slug = @get_post($shop_page_id)->post_name;
170
- $languages = $sitepress->get_active_languages();
171
- if (sizeof($languages) < 2) {
172
- return;
173
- }
174
- foreach ($languages as $language) {
175
- if ($language['code'] != $sitepress->get_default_language()) {
176
- $translated_shop_page_id = apply_filters( 'translate_object_id',$shop_page_id, 'page', false, $language['code']);
177
- if (!empty($translated_shop_page_id)) {
178
- $translated_slug = get_post($translated_shop_page_id)->post_name;
179
- if (!empty($translated_slug) && $translated_slug != $slug) {
180
- $allsame = false;
181
- break;
182
- }
183
- }
184
- }
185
- }
186
- }
187
- }
188
-
189
- // Check if slug translation is enabled
190
- $compatible = true;
191
- $permalink_structure = get_option('permalink_structure');
192
- if ( empty($permalink_structure)
193
- && !empty($sitepress_settings['posts_slug_translation']['on'])
194
- && !empty($sitepress_settings['posts_slug_translation']['types'])
195
- && $sitepress_settings['posts_slug_translation']['types']['product']) {
196
- $compatible = false;
197
- }
198
-
199
- // display messages
200
- if (!$allsame) {
201
- $this->err_message = '<div class="message error"><p>'.printf(__('If you want different slugs for shop pages (%s/%s), you need to disable the shop prefix for products in <a href="%s">WooCommerce Settings</a>', 'woocommerce-multilingual'),
202
- $slug, $translated_slug, admin_url("admin.php?page=woocommerce_settings&tab=pages")).'</p></div>';
203
- add_action('admin_notices', array($this,'plugin_notice_message'));
204
- }
205
-
206
- if (!$compatible && ($pagenow == 'options-permalink.php' || (isset($_GET['page']) && $_GET['page'] == 'wpml-wcml'))) {
207
- $this->err_message = '<div class="message error"><p>'.$message.' </p></div>';
208
- add_action('admin_notices', array($this,'plugin_notice_message'));
209
- }
210
- }
211
-
212
- public function plugin_notice_message(){
213
- echo $this->err_message;
214
- }
215
-
216
- public function fix_strings_language(){
217
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
218
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_fix_strings_language')){
219
- die('Invalid nonce');
220
- }
221
-
222
- $ret = array();
223
-
224
- $ret['_wpnonce'] = wp_create_nonce('icl_sw_form');
225
-
226
- $ret['success_1'] = '&nbsp;' . sprintf(__('Finished! You can visit the %sstrings translation%s screen to translate the strings now.', 'woocommerce-multilingual'), '<a href="' . admin_url('admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php') . '">', '</a>');
227
-
228
-
229
- echo json_encode($ret);
230
-
231
- exit;
232
-
233
- }
234
-
235
- public function check_wpml_config(){
236
- global $sitepress_settings;
237
-
238
- if(empty($sitepress_settings)) return;
239
-
240
- $file = realpath(WCML_PLUGIN_PATH . '/wpml-config.xml');
241
- if(!file_exists($file)){
242
- $this->xml_config_errors[] = __('wpml-config.xml file missing from WooCommerce Multilingual folder.', 'woocommerce-multilingual');
243
- }else{
244
- $config = icl_xml2array(file_get_contents($file));
245
-
246
- if(isset($config['wpml-config'])){
247
-
248
- //custom-fields
249
- if(isset($config['wpml-config']['custom-fields'])){
250
- if(isset($config['wpml-config']['custom-fields']['custom-field']['value'])){ //single
251
- $cfs[] = $config['wpml-config']['custom-fields']['custom-field'];
252
- }else{
253
- foreach($config['wpml-config']['custom-fields']['custom-field'] as $cf){
254
- $cfs[] = $cf;
255
- }
256
- }
257
-
258
- if($cfs)
259
- foreach($cfs as $cf){
260
- if(!isset($sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']])) continue;
261
-
262
- $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']];
263
- $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ($cf['attr']['action'] == 'translate' ? 2: 0);
264
-
265
- if($effective_config_value != $correct_config_value){
266
- $this->xml_config_errors[] = sprintf(__('Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $cf['value'] . '</i>');
267
- }
268
- }
269
-
270
- }
271
-
272
- //custom-types
273
- if(isset($config['wpml-config']['custom-types'])){
274
- if(isset($config['wpml-config']['custom-types']['custom-type']['value'])){ //single
275
- $cts[] = $config['wpml-config']['custom-types']['custom-type'];
276
- }else{
277
- foreach($config['wpml-config']['custom-types']['custom-type'] as $cf){
278
- $cts[] = $cf;
279
- }
280
- }
281
-
282
- if($cts)
283
- foreach($cts as $ct){
284
- if(!isset($sitepress_settings['custom_posts_sync_option'][$ct['value']])) continue;
285
- $effective_config_value = $sitepress_settings['custom_posts_sync_option'][$ct['value']];
286
- $correct_config_value = $ct['attr']['translate'];
287
-
288
- if($effective_config_value != $correct_config_value){
289
- $this->xml_config_errors[] = sprintf(__('Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $ct['value'] . '</i>');
290
- }
291
- }
292
-
293
- }
294
-
295
- //taxonomies
296
- if(isset($config['wpml-config']['taxonomies'])){
297
- if(isset($config['wpml-config']['taxonomies']['taxonomy']['value'])){ //single
298
- $txs[] = $config['wpml-config']['taxonomies']['taxonomy'];
299
- }else{
300
- foreach($config['wpml-config']['taxonomies']['taxonomy'] as $cf){
301
- $txs[] = $cf;
302
- }
303
- }
304
-
305
- if($txs)
306
- foreach($txs as $tx){
307
- if(!isset($sitepress_settings['taxonomies_sync_option'][$tx['value']])) continue;
308
- $effective_config_value = $sitepress_settings['taxonomies_sync_option'][$tx['value']];
309
- $correct_config_value = $tx['attr']['translate'];
310
-
311
- if($effective_config_value != $correct_config_value){
312
- $this->xml_config_errors[] = sprintf(__('Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $tx['value'] . '</i>');
313
- }
314
- }
315
-
316
- }
317
- }
318
- }
319
-
320
- }
321
-
322
- public function required_plugin_install_link($repository = 'wpml'){
323
-
324
- if( class_exists('WP_Installer_API') ){
325
- $url = WP_Installer_API::get_product_installer_link($repository);
326
- }else{
327
- $url = WCML_Links::generate_tracking_link('https://wpml.org/');
328
- }
329
-
330
- return $url;
331
- }
332
-
333
- /**
334
- * The support for the Twig templates comes from WPML by default
335
- * When WPML is not active, WCML will load it
336
- */
337
- private function load_twig_support(){
338
-
339
- if ( !class_exists( 'Twig_Autoloader' ) ){
340
- Twig_Autoloader::register();
341
- }
342
-
343
- }
344
-
345
- }
346
 
1
+ <?php
2
+
3
+ class WCML_Dependencies{
4
+
5
+
6
+ private $missing = array();
7
+ private $err_message = '';
8
+ private $allok = true;
9
+
10
+ function __construct(){
11
+
12
+ if(is_admin()){
13
+ add_action('wp_ajax_wcml_fix_strings_language', array($this, 'fix_strings_language')); // TODO: remove after WPML release with support strings in different languages
14
+
15
+ add_action('init', array($this, 'check_wpml_config'), 100);
16
+ }
17
+
18
+
19
+ }
20
+
21
+ function check(){
22
+ global $woocommerce_wpml, $sitepress, $woocommerce;
23
+
24
+ if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE || is_null( $sitepress ) || !class_exists('SitePress')){
25
+ $this->missing['WPML'] = WCML_Links::generate_tracking_link('https://wpml.org/');
26
+ $this->allok = false;
27
+ } elseif(version_compare(ICL_SITEPRESS_VERSION, '3.4', '<')){
28
+ add_action('admin_notices', array($this, '_old_wpml_warning'));
29
+ $this->allok = false;
30
+ }
31
+
32
+ if(!class_exists('woocommerce')){
33
+ $this->missing['WooCommerce'] = 'http://www.woothemes.com/woocommerce/';
34
+ $this->allok = false;
35
+ }elseif( ( defined('WC_VERSION') && version_compare( WC_VERSION , '2.1', '<' ) ) || ( isset( $woocommerce->version ) && version_compare( $woocommerce->version , '2.1', '<' ) ) ){
36
+ add_action('admin_notices', array($this, '_old_wc_warning'));
37
+ $this->allok = false;
38
+ }
39
+
40
+ if(!defined('WPML_TM_VERSION')){
41
+ $this->missing['WPML Translation Management'] = WCML_Links::generate_tracking_link('https://wpml.org/');
42
+ $this->allok = false;
43
+ }elseif(version_compare(WPML_TM_VERSION, '1.9', '<')){
44
+ add_action('admin_notices', array($this, '_old_wpml_tm_warning'));
45
+ $this->allok = false;
46
+ }
47
+
48
+ if(!defined('WPML_ST_VERSION')){
49
+ $this->missing['WPML String Translation'] = WCML_Links::generate_tracking_link('https://wpml.org/');
50
+ $this->allok = false;
51
+ }elseif(version_compare(WPML_ST_VERSION, '2.0', '<')){
52
+ add_action('admin_notices', array($this, '_old_wpml_st_warning'));
53
+ $this->allok = false;
54
+ }
55
+
56
+ if(!defined('WPML_MEDIA_VERSION')){
57
+ $this->missing['WPML Media'] = WCML_Links::generate_tracking_link('https://wpml.org/');
58
+ $this->allok = false;
59
+ }elseif(version_compare(WPML_MEDIA_VERSION, '2.1', '<')){
60
+ add_action('admin_notices', array($this, '_old_wpml_media_warning'));
61
+ $this->allok = false;
62
+ }
63
+
64
+ if ($this->missing) {
65
+ add_action('admin_notices', array($this, '_missing_plugins_warning'));
66
+ }
67
+
68
+ if($this->allok){
69
+ $this->check_for_incompatible_permalinks();
70
+ }
71
+
72
+ if(isset($sitepress)){
73
+ $this->allok = $this->allok & $sitepress->setup();
74
+ }else{
75
+ $this->load_twig_support();
76
+ }
77
+
78
+ return $this->allok;
79
+ }
80
+
81
+ /**
82
+ * Adds admin notice.
83
+ */
84
+ public function _old_wpml_warning(){
85
+ ?>
86
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML</a> versions prior %s.',
87
+ 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '3.4'); ?></p></div>
88
+ <?php }
89
+
90
+ function _old_wc_warning(){
91
+ ?>
92
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">Woocommerce</a> versions prior %s.',
93
+ 'woocommerce-multilingual'), 'http://www.woothemes.com/woocommerce/', '2.1' ); ?></p></div>
94
+ <?php }
95
+
96
+ public function _old_wpml_tm_warning(){
97
+ ?>
98
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML Translation Management</a> versions prior %s.',
99
+ 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '1.9'); ?></p></div>
100
+ <?php }
101
+
102
+ public function _old_wpml_st_warning(){
103
+ ?>
104
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML String Translation</a> versions prior %s.',
105
+ 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.0'); ?></p></div>
106
+ <?php }
107
+
108
+ public function _old_wpml_media_warning(){
109
+ ?>
110
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It is not compatible with <a href="%s">WPML Media</a> versions prior %s.',
111
+ 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.1'); ?></p></div>
112
+ <?php }
113
+
114
+
115
+ /**
116
+ * Adds admin notice.
117
+ */
118
+ public function _missing_plugins_warning(){
119
+
120
+ $missing = '';
121
+ $counter = 0;
122
+ foreach ($this->missing as $title => $url) {
123
+ $counter ++;
124
+ if ($counter == sizeof($this->missing)) {
125
+ $sep = '';
126
+ } elseif ($counter == sizeof($this->missing) - 1) {
127
+ $sep = ' ' . __('and', 'woocommerce-multilingual') . ' ';
128
+ } else {
129
+ $sep = ', ';
130
+ }
131
+ $missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep;
132
+ } ?>
133
+
134
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires %s in order to work.', 'woocommerce-multilingual'), $missing); ?></p></div>
135
+ <?php
136
+ }
137
+
138
+ /**
139
+ * For all the urls to work we need either:
140
+ * 1) the shop page slug must be the same in all languages
141
+ * 2) or the shop prefix disabled in woocommerce settings
142
+ * one of these must be true for product urls to work
143
+ * if none of these are true, display a warning message
144
+ */
145
+ private function check_for_incompatible_permalinks() {
146
+ global $sitepress, $sitepress_settings, $pagenow;
147
+
148
+ // WooCommerce 2.x specific checks
149
+ $permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
150
+ if (empty($permalinks['product_base'])) {
151
+ return;
152
+ }
153
+
154
+ $message = sprintf('Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual');
155
+ $message .= '<br /><br />';
156
+ $message .= sprintf('Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual');
157
+ $message .= '<br /><br />';
158
+ $message .= '<a href="' . admin_url('options-permalink.php') . '">' . __('Permalink settings', 'woocommerce-multilingual') . '</a>';
159
+ $message .= ' | ';
160
+ $message .= '<a href="' . admin_url('admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#icl_custom_posts_sync_options') . '">' . __('Configure products slug translation', 'woocommerce-multilingual') . '</a>';
161
+
162
+
163
+ // Check if translated shop pages have the same slug (only 1.x)
164
+ $allsame = true;
165
+ if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
166
+ } else {
167
+ $shop_page_id = get_option('woocommerce_shop_page_id', false);
168
+ if (!empty($shop_page_id)) {
169
+ $slug = @get_post($shop_page_id)->post_name;
170
+ $languages = $sitepress->get_active_languages();
171
+ if (sizeof($languages) < 2) {
172
+ return;
173
+ }
174
+ foreach ($languages as $language) {
175
+ if ($language['code'] != $sitepress->get_default_language()) {
176
+ $translated_shop_page_id = apply_filters( 'translate_object_id',$shop_page_id, 'page', false, $language['code']);
177
+ if (!empty($translated_shop_page_id)) {
178
+ $translated_slug = get_post($translated_shop_page_id)->post_name;
179
+ if (!empty($translated_slug) && $translated_slug != $slug) {
180
+ $allsame = false;
181
+ break;
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ // Check if slug translation is enabled
190
+ $compatible = true;
191
+ $permalink_structure = get_option('permalink_structure');
192
+ if ( empty($permalink_structure)
193
+ && !empty($sitepress_settings['posts_slug_translation']['on'])
194
+ && !empty($sitepress_settings['posts_slug_translation']['types'])
195
+ && $sitepress_settings['posts_slug_translation']['types']['product']) {
196
+ $compatible = false;
197
+ }
198
+
199
+ // display messages
200
+ if (!$allsame) {
201
+ $this->err_message = '<div class="message error"><p>'.printf(__('If you want different slugs for shop pages (%s/%s), you need to disable the shop prefix for products in <a href="%s">WooCommerce Settings</a>', 'woocommerce-multilingual'),
202
+ $slug, $translated_slug, admin_url("admin.php?page=woocommerce_settings&tab=pages")).'</p></div>';
203
+ add_action('admin_notices', array($this,'plugin_notice_message'));
204
+ }
205
+
206
+ if (!$compatible && ($pagenow == 'options-permalink.php' || (isset($_GET['page']) && $_GET['page'] == 'wpml-wcml'))) {
207
+ $this->err_message = '<div class="message error"><p>'.$message.' </p></div>';
208
+ add_action('admin_notices', array($this,'plugin_notice_message'));
209
+ }
210
+ }
211
+
212
+ public function plugin_notice_message(){
213
+ echo $this->err_message;
214
+ }
215
+
216
+ public function fix_strings_language(){
217
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
218
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_fix_strings_language')){
219
+ die('Invalid nonce');
220
+ }
221
+
222
+ $ret = array();
223
+
224
+ $ret['_wpnonce'] = wp_create_nonce('icl_sw_form');
225
+
226
+ $ret['success_1'] = '&nbsp;' . sprintf(__('Finished! You can visit the %sstrings translation%s screen to translate the strings now.', 'woocommerce-multilingual'), '<a href="' . admin_url('admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php') . '">', '</a>');
227
+
228
+
229
+ echo json_encode($ret);
230
+
231
+ exit;
232
+
233
+ }
234
+
235
+ public function check_wpml_config(){
236
+ global $sitepress_settings;
237
+
238
+ if(empty($sitepress_settings)) return;
239
+
240
+ $file = realpath(WCML_PLUGIN_PATH . '/wpml-config.xml');
241
+ if(!file_exists($file)){
242
+ $this->xml_config_errors[] = __('wpml-config.xml file missing from WooCommerce Multilingual folder.', 'woocommerce-multilingual');
243
+ }else{
244
+ $config = icl_xml2array(file_get_contents($file));
245
+
246
+ if(isset($config['wpml-config'])){
247
+
248
+ //custom-fields
249
+ if(isset($config['wpml-config']['custom-fields'])){
250
+ if(isset($config['wpml-config']['custom-fields']['custom-field']['value'])){ //single
251
+ $cfs[] = $config['wpml-config']['custom-fields']['custom-field'];
252
+ }else{
253
+ foreach($config['wpml-config']['custom-fields']['custom-field'] as $cf){
254
+ $cfs[] = $cf;
255
+ }
256
+ }
257
+
258
+ if($cfs)
259
+ foreach($cfs as $cf){
260
+ if(!isset($sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']])) continue;
261
+
262
+ $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']];
263
+ $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ($cf['attr']['action'] == 'translate' ? 2: 0);
264
+
265
+ if($effective_config_value != $correct_config_value){
266
+ $this->xml_config_errors[] = sprintf(__('Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $cf['value'] . '</i>');
267
+ }
268
+ }
269
+
270
+ }
271
+
272
+ //custom-types
273
+ if(isset($config['wpml-config']['custom-types'])){
274
+ if(isset($config['wpml-config']['custom-types']['custom-type']['value'])){ //single
275
+ $cts[] = $config['wpml-config']['custom-types']['custom-type'];
276
+ }else{
277
+ foreach($config['wpml-config']['custom-types']['custom-type'] as $cf){
278
+ $cts[] = $cf;
279
+ }
280
+ }
281
+
282
+ if($cts)
283
+ foreach($cts as $ct){
284
+ if(!isset($sitepress_settings['custom_posts_sync_option'][$ct['value']])) continue;
285
+ $effective_config_value = $sitepress_settings['custom_posts_sync_option'][$ct['value']];
286
+ $correct_config_value = $ct['attr']['translate'];
287
+
288
+ if($effective_config_value != $correct_config_value){
289
+ $this->xml_config_errors[] = sprintf(__('Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $ct['value'] . '</i>');
290
+ }
291
+ }
292
+
293
+ }
294
+
295
+ //taxonomies
296
+ if(isset($config['wpml-config']['taxonomies'])){
297
+ if(isset($config['wpml-config']['taxonomies']['taxonomy']['value'])){ //single
298
+ $txs[] = $config['wpml-config']['taxonomies']['taxonomy'];
299
+ }else{
300
+ foreach($config['wpml-config']['taxonomies']['taxonomy'] as $cf){
301
+ $txs[] = $cf;
302
+ }
303
+ }
304
+
305
+ if($txs)
306
+ foreach($txs as $tx){
307
+ if(!isset($sitepress_settings['taxonomies_sync_option'][$tx['value']])) continue;
308
+ $effective_config_value = $sitepress_settings['taxonomies_sync_option'][$tx['value']];
309
+ $correct_config_value = $tx['attr']['translate'];
310
+
311
+ if($effective_config_value != $correct_config_value){
312
+ $this->xml_config_errors[] = sprintf(__('Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $tx['value'] . '</i>');
313
+ }
314
+ }
315
+
316
+ }
317
+ }
318
+ }
319
+
320
+ }
321
+
322
+ public function required_plugin_install_link($repository = 'wpml'){
323
+
324
+ if( class_exists('WP_Installer_API') ){
325
+ $url = WP_Installer_API::get_product_installer_link($repository);
326
+ }else{
327
+ $url = WCML_Links::generate_tracking_link('https://wpml.org/');
328
+ }
329
+
330
+ return $url;
331
+ }
332
+
333
+ /**
334
+ * The support for the Twig templates comes from WPML by default
335
+ * When WPML is not active, WCML will load it
336
+ */
337
+ private function load_twig_support(){
338
+
339
+ if ( !class_exists( 'Twig_Autoloader' ) ){
340
+ Twig_Autoloader::register();
341
+ }
342
+
343
+ }
344
+
345
+ }
346
 
inc/class-wcml-emails.php CHANGED
@@ -1,489 +1,489 @@
1
- <?php
2
- class WCML_Emails{
3
-
4
- private $order_id = false;
5
- private $locale = false;
6
- private $woocommerce_wpml;
7
- private $sitepress;
8
-
9
- function __construct( &$woocommerce_wpml, &$sitepress ) {
10
- $this->woocommerce_wpml = $woocommerce_wpml;
11
- $this->sitepress = $sitepress;
12
- add_action( 'init', array( $this, 'init' ) );
13
- }
14
-
15
- function init(){
16
- global $pagenow;
17
- //wrappers for email's header
18
- if(is_admin() && !defined( 'DOING_AJAX' )){
19
- add_action('woocommerce_order_status_completed_notification', array($this, 'email_heading_completed'),9);
20
- add_action('woocommerce_order_status_changed', array($this, 'comments_language'),10);
21
- }
22
-
23
- add_action('woocommerce_new_customer_note_notification', array($this, 'email_heading_note'),9);
24
- add_action('wp_ajax_woocommerce_mark_order_complete',array($this,'email_refresh_in_ajax'),9);
25
-
26
- add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'email_heading_processing' ) );
27
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'email_heading_processing' ) );
28
-
29
- //wrappers for email's body
30
- add_action('woocommerce_before_resend_order_emails', array($this, 'email_header'));
31
- add_action('woocommerce_after_resend_order_email', array($this, 'email_footer'));
32
-
33
- //filter string language before for emails
34
- add_filter('icl_current_string_language',array($this,'icl_current_string_language'),10 ,2);
35
-
36
- //change order status
37
- add_action('woocommerce_order_status_completed',array($this,'refresh_email_lang_complete'),9);
38
- add_action('woocommerce_order_status_pending_to_processing_notification',array($this,'refresh_email_lang'),9);
39
- add_action('woocommerce_order_status_pending_to_on-hold_notification',array($this,'refresh_email_lang'),9);
40
- add_action('woocommerce_new_customer_note',array($this,'refresh_email_lang'),9);
41
-
42
-
43
- add_action('woocommerce_order_partially_refunded_notification', array($this,'email_heading_refund'), 9);
44
- add_action('woocommerce_order_partially_refunded_notification', array($this,'refresh_email_lang'), 9);
45
-
46
-
47
- //new order admins email
48
- add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
49
- add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
50
- add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
51
- add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
52
- add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
53
- add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
54
- add_action( 'woocommerce_before_resend_order_emails', array( $this, 'backend_new_order_admin_email' ), 9 );
55
-
56
- add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
57
-
58
- add_filter( 'plugin_locale', array( $this, 'set_locale_for_emails' ), 10, 2 );
59
-
60
-
61
- if( is_admin() && $pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'email' ){
62
- add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
63
- $this->set_emails_string_language();
64
- }
65
-
66
- add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
67
-
68
- if(
69
- (
70
- !isset( $_GET['post_type'] ) ||
71
- $_GET['post_type'] != 'shop_order'
72
- ) &&
73
- (
74
- !isset( $_GET[ 'action' ] ) ||
75
- !in_array( $_GET['action'] , array( 'woocommerce_mark_order_complete', 'woocommerce_mark_order_status', 'mark_processing' ) )
76
- )
77
- ){
78
- add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
79
- }
80
- }
81
-
82
- function email_refresh_in_ajax(){
83
- if( isset( $_GET[ 'order_id' ] ) ){
84
- $this->refresh_email_lang( $_GET[ 'order_id' ] );
85
- $this->email_heading_completed( $_GET[ 'order_id' ], true );
86
- }
87
- }
88
-
89
- function refresh_email_lang_complete( $order_id ){
90
-
91
- $this->order_id = $order_id;
92
- $this->refresh_email_lang( $order_id );
93
- $this->email_heading_completed( $order_id, true );
94
- }
95
-
96
- /**
97
- * Translate WooCommerce emails.
98
- *
99
- * @global type $sitepress
100
- * @global type $order_id
101
- * @return type
102
- */
103
- function email_header( $order ) {
104
-
105
- if( is_array( $order ) ) {
106
- $order = $order[ 'order_id' ];
107
- } elseif( is_object( $order ) ) {
108
- $order = $order->id;
109
- }
110
-
111
- $this->refresh_email_lang( $order );
112
- }
113
-
114
-
115
- function refresh_email_lang( $order_id ){
116
-
117
- if ( is_array( $order_id ) ) {
118
- if ( isset( $order_id[ 'order_id' ] ) ) {
119
- $order_id = $order_id[ 'order_id' ];
120
- } else {
121
- return;
122
- }
123
- }
124
-
125
- $lang = get_post_meta( $order_id, 'wpml_language', true );
126
- if( !empty( $lang ) ){
127
- $this->change_email_language( $lang );
128
- }
129
- }
130
-
131
- /**
132
- * After email translation switch language to default.
133
- */
134
- function email_footer() {
135
- $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
136
- }
137
-
138
- function comments_language(){
139
- $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
140
-
141
- }
142
-
143
- function email_heading_completed( $order_id, $no_checking = false ){
144
- global $woocommerce;
145
- if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
146
-
147
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading' );
148
-
149
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject' );
150
-
151
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading_downloadable' );
152
-
153
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject_downloadable' );
154
-
155
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
156
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
157
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
158
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
159
- }
160
- }
161
-
162
- function email_heading_processing($order_id){
163
- global $woocommerce;
164
- if( class_exists( 'WC_Email_Customer_Processing_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Processing_Order' ] ) ){
165
-
166
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_processing_order_settings', '[woocommerce_customer_processing_order_settings]heading' );
167
-
168
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_processing_order_settings', '[woocommerce_customer_processing_order_settings]subject' );
169
-
170
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
171
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
172
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
173
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
174
- }
175
- }
176
-
177
- function email_heading_note($args){
178
- global $woocommerce;
179
-
180
- if( class_exists( 'WC_Email_Customer_Note' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
181
-
182
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]heading' );
183
-
184
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]subject' );
185
-
186
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
187
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
188
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
189
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
190
- }
191
- }
192
-
193
- function email_heading_refund( $order_id, $refund_id = null ){
194
- global $woocommerce;
195
- if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
196
-
197
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
198
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
199
- '[woocommerce_customer_refunded_order_settings]heading_partial' );
200
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
201
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
202
- '[woocommerce_customer_refunded_order_settings]subject_partial' );
203
-
204
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
205
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
206
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
207
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
208
-
209
- }
210
- }
211
-
212
-
213
- function new_order_admin_email($order_id){
214
- global $woocommerce;
215
- if( isset( $woocommerce->mailer()->emails[ 'WC_Email_New_Order' ] ) ){
216
- $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
217
- foreach($recipients as $recipient){
218
- $user = get_user_by('email',$recipient);
219
- if($user){
220
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
221
- }else{
222
- $user_lang = get_post_meta($order_id, 'wpml_language', true );
223
- }
224
-
225
- $this->change_email_language( $user_lang );
226
-
227
- $woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading' );
228
-
229
- $woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject' );
230
-
231
- $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
232
-
233
- $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
234
- }
235
- $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
236
- $this->refresh_email_lang($order_id);
237
- }
238
- }
239
-
240
- public function backend_new_order_admin_email( $order_id ){
241
- if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
242
- $this->new_order_admin_email( $order_id );
243
- }
244
- }
245
-
246
- function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
247
- if( $meta_key == '_payment_method_title' ){
248
-
249
- $payment_method = get_post_meta( $object_id, '_payment_method', true );
250
-
251
- if( $payment_method ){
252
-
253
- $payment_gateways = WC()->payment_gateways->payment_gateways();
254
- if( isset( $payment_gateways[ $payment_method ] ) ){
255
- $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
256
-
257
- return $title;
258
- }
259
- }
260
-
261
-
262
- }
263
- return $check;
264
- }
265
-
266
- function filter_formatted_items( $formatted_meta, $object ){
267
-
268
- if( isset( $object->product->variation_id ) ){
269
-
270
- $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
271
-
272
- if( !is_null( $current_prod_variation_id ) ) {
273
-
274
- foreach( $formatted_meta as $key => $formatted_var ){
275
-
276
- if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
277
-
278
- $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
279
-
280
- if( taxonomy_exists( $attribute ) ){
281
- $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
282
- $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
283
-
284
- if( $tr_id ){
285
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
286
- $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
287
- }
288
-
289
- }else{
290
-
291
- $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $formatted_var[ 'key' ], array('is_taxonomy' => false), $this->sitepress->get_current_language() );
292
-
293
- if ( false !== $custom_attr_trnsl ) {
294
- $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
295
- }
296
- }
297
- }
298
- }
299
- }
300
- }
301
-
302
- return $formatted_meta;
303
-
304
- }
305
-
306
- function change_email_language($lang){
307
- global $woocommerce;
308
- $this->sitepress->switch_lang($lang,true);
309
- $this->locale = $this->sitepress->get_locale( $lang );
310
- unload_textdomain('woocommerce');
311
- unload_textdomain( 'default' );
312
- global $wp_locale;
313
- $wp_locale = new WP_Locale();
314
-
315
- $woocommerce->load_plugin_textdomain();
316
- load_default_textdomain( $this->locale );
317
- }
318
-
319
- function admin_string_return_cached( $value, $option ){
320
- if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
321
- return false;
322
-
323
- return $value;
324
- }
325
-
326
- function wcml_get_translated_email_string( $context, $name ){
327
-
328
- if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
329
- global $wpdb;
330
-
331
- $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
332
-
333
- return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
334
- }else{
335
-
336
- return apply_filters( 'wpml_translate_single_string', false, $context, $name );
337
-
338
- }
339
-
340
- }
341
-
342
- function icl_current_string_language( $current_language, $name ){
343
- $order_id = false;
344
-
345
- if( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['post_type']) && $_POST['post_type'] == 'shop_order' && isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] != 'send_email_new_order' ){
346
- $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
347
- }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
348
- $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
349
- }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
350
- $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
351
- }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
352
- $order_id = $this->order_id;
353
- }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
354
- $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
355
- }elseif( empty( $_POST ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'email' && substr( $name, 0, 12 ) == '[woocommerce' ){
356
- $email_string = explode( ']', str_replace( '[', '', $name ) );
357
- $email_option = get_option( $email_string[ 0 ], true );
358
- $context = 'admin_texts_'.$email_string[ 0 ];
359
-
360
- $current_language = $this->woocommerce_wpml->strings->get_string_language( $email_option[ $email_string[ 1 ] ], $context, $name );
361
- }
362
-
363
- $order_id = apply_filters( 'wcml_send_email_order_id', $order_id );
364
-
365
- if( $order_id ){
366
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
367
- if( $order_language ){
368
- $current_language = $order_language;
369
- }else{
370
- $current_language = $this->sitepress->get_current_language();
371
- }
372
- }
373
-
374
- return apply_filters( 'wcml_email_language', $current_language, $order_id );
375
- }
376
-
377
- // set correct locale code for emails
378
- function set_locale_for_emails( $locale, $domain ){
379
-
380
- if( $domain == 'woocommerce' && $this->locale ){
381
- $locale = $this->locale;
382
- }
383
-
384
- return $locale;
385
- }
386
-
387
- function show_language_links_for_wc_emails(){
388
-
389
- $emails_options = array(
390
- 'woocommerce_new_order_settings',
391
- 'woocommerce_cancelled_order_settings',
392
- 'woocommerce_failed_order_settings',
393
- 'woocommerce_customer_on_hold_order_settings',
394
- 'woocommerce_customer_processing_order_settings',
395
- 'woocommerce_customer_completed_order_settings',
396
- 'woocommerce_customer_refunded_order_settings',
397
- 'woocommerce_customer_invoice_settings',
398
- 'woocommerce_customer_note_settings',
399
- 'woocommerce_customer_reset_password_settings',
400
- 'woocommerce_customer_new_account_settings'
401
- );
402
-
403
- $text_keys = array(
404
- 'subject',
405
- 'heading',
406
- 'subject_downloadable',
407
- 'heading_downloadable',
408
- 'subject_full',
409
- 'subject_partial',
410
- 'heading_full',
411
- 'heading_partial',
412
- 'subject_paid',
413
- 'heading_paid'
414
- );
415
-
416
-
417
- foreach( $emails_options as $emails_option ) {
418
-
419
- $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
420
- $section_name = str_replace( '_settings', '', $section_name );
421
- if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
422
-
423
- $option_settings = get_option( $emails_option );
424
- foreach ($option_settings as $setting_key => $setting_value) {
425
- if ( in_array( $setting_key, $text_keys ) ) {
426
- $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
427
-
428
- $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
429
- $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
430
- if( is_null( $language ) ) {
431
- $language = $this->sitepress->get_default_language();
432
- }
433
-
434
- $lang_selector->render( array(
435
- 'id' => $emails_option.'_'.$setting_key.'_language_selector',
436
- 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
437
- 'selected' => $language,
438
- 'show_please_select' => false,
439
- 'echo' => true,
440
- 'style' => 'width: 18%;float: left'
441
- )
442
- );
443
-
444
- $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
445
- ?>
446
- <script>
447
- var input = jQuery('input[name="<?php echo $input_name ?>"]');
448
- if (input.length) {
449
- input.parent().append('<div class="translation_controls"></div>');
450
- input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
451
- jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
452
- }
453
- </script>
454
- <?php }
455
- }
456
- }
457
- }
458
- }
459
-
460
- function set_emails_string_language(){
461
-
462
- foreach( $_POST as $key => $language ){
463
-
464
- if( substr( $key, 0, 9 ) == 'wcml_lang' ){
465
-
466
- $email_string = explode( '-', $key );
467
-
468
- if( isset( $email_string[2] ) ){
469
-
470
- $email_key = str_replace( '_settings', '', $email_string[1] );
471
- $email_key .= '_'.$email_string[2];
472
-
473
- $email_settings = get_option( $email_string[1], true );
474
- $opt_string_value = $email_settings[ $email_string[2] ];
475
-
476
- $string_value = isset( $_POST[ $email_key ] ) ? $_POST[ $email_key ] : $opt_string_value;
477
-
478
- $context = 'admin_texts_'.$email_string[1];
479
- $name = '['.$email_string[1].']'.$email_string[2];
480
-
481
- do_action('wpml_register_single_string', $context, $name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
482
-
483
- $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $name, $language );
484
- }
485
- }
486
- }
487
- }
488
-
489
  }
1
+ <?php
2
+ class WCML_Emails{
3
+
4
+ private $order_id = false;
5
+ private $locale = false;
6
+ private $woocommerce_wpml;
7
+ private $sitepress;
8
+
9
+ function __construct( &$woocommerce_wpml, &$sitepress ) {
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+ add_action( 'init', array( $this, 'init' ) );
13
+ }
14
+
15
+ function init(){
16
+ global $pagenow;
17
+ //wrappers for email's header
18
+ if(is_admin() && !defined( 'DOING_AJAX' )){
19
+ add_action('woocommerce_order_status_completed_notification', array($this, 'email_heading_completed'),9);
20
+ add_action('woocommerce_order_status_changed', array($this, 'comments_language'),10);
21
+ }
22
+
23
+ add_action('woocommerce_new_customer_note_notification', array($this, 'email_heading_note'),9);
24
+ add_action('wp_ajax_woocommerce_mark_order_complete',array($this,'email_refresh_in_ajax'),9);
25
+
26
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'email_heading_processing' ) );
27
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'email_heading_processing' ) );
28
+
29
+ //wrappers for email's body
30
+ add_action('woocommerce_before_resend_order_emails', array($this, 'email_header'));
31
+ add_action('woocommerce_after_resend_order_email', array($this, 'email_footer'));
32
+
33
+ //filter string language before for emails
34
+ add_filter('icl_current_string_language',array($this,'icl_current_string_language'),10 ,2);
35
+
36
+ //change order status
37
+ add_action('woocommerce_order_status_completed',array($this,'refresh_email_lang_complete'),9);
38
+ add_action('woocommerce_order_status_pending_to_processing_notification',array($this,'refresh_email_lang'),9);
39
+ add_action('woocommerce_order_status_pending_to_on-hold_notification',array($this,'refresh_email_lang'),9);
40
+ add_action('woocommerce_new_customer_note',array($this,'refresh_email_lang'),9);
41
+
42
+
43
+ add_action('woocommerce_order_partially_refunded_notification', array($this,'email_heading_refund'), 9);
44
+ add_action('woocommerce_order_partially_refunded_notification', array($this,'refresh_email_lang'), 9);
45
+
46
+
47
+ //new order admins email
48
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
49
+ add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
50
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
51
+ add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
52
+ add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
53
+ add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
54
+ add_action( 'woocommerce_before_resend_order_emails', array( $this, 'backend_new_order_admin_email' ), 9 );
55
+
56
+ add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
57
+
58
+ add_filter( 'plugin_locale', array( $this, 'set_locale_for_emails' ), 10, 2 );
59
+
60
+
61
+ if( is_admin() && $pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'email' ){
62
+ add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
63
+ $this->set_emails_string_language();
64
+ }
65
+
66
+ add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
67
+
68
+ if(
69
+ (
70
+ !isset( $_GET['post_type'] ) ||
71
+ $_GET['post_type'] != 'shop_order'
72
+ ) &&
73
+ (
74
+ !isset( $_GET[ 'action' ] ) ||
75
+ !in_array( $_GET['action'] , array( 'woocommerce_mark_order_complete', 'woocommerce_mark_order_status', 'mark_processing' ) )
76
+ )
77
+ ){
78
+ add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
79
+ }
80
+ }
81
+
82
+ function email_refresh_in_ajax(){
83
+ if( isset( $_GET[ 'order_id' ] ) ){
84
+ $this->refresh_email_lang( $_GET[ 'order_id' ] );
85
+ $this->email_heading_completed( $_GET[ 'order_id' ], true );
86
+ }
87
+ }
88
+
89
+ function refresh_email_lang_complete( $order_id ){
90
+
91
+ $this->order_id = $order_id;
92
+ $this->refresh_email_lang( $order_id );
93
+ $this->email_heading_completed( $order_id, true );
94
+ }
95
+
96
+ /**
97
+ * Translate WooCommerce emails.
98
+ *
99
+ * @global type $sitepress
100
+ * @global type $order_id
101
+ * @return type
102
+ */
103
+ function email_header( $order ) {
104
+
105
+ if( is_array( $order ) ) {
106
+ $order = $order[ 'order_id' ];
107
+ } elseif( is_object( $order ) ) {
108
+ $order = $order->id;
109
+ }
110
+
111
+ $this->refresh_email_lang( $order );
112
+ }
113
+
114
+
115
+ function refresh_email_lang( $order_id ){
116
+
117
+ if ( is_array( $order_id ) ) {
118
+ if ( isset( $order_id[ 'order_id' ] ) ) {
119
+ $order_id = $order_id[ 'order_id' ];
120
+ } else {
121
+ return;
122
+ }
123
+ }
124
+
125
+ $lang = get_post_meta( $order_id, 'wpml_language', true );
126
+ if( !empty( $lang ) ){
127
+ $this->change_email_language( $lang );
128
+ }
129
+ }
130
+
131
+ /**
132
+ * After email translation switch language to default.
133
+ */
134
+ function email_footer() {
135
+ $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
136
+ }
137
+
138
+ function comments_language(){
139
+ $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
140
+
141
+ }
142
+
143
+ function email_heading_completed( $order_id, $no_checking = false ){
144
+ global $woocommerce;
145
+ if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
146
+
147
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading' );
148
+
149
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject' );
150
+
151
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->heading_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]heading_downloadable' );
152
+
153
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->subject_downloadable = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_completed_order_settings', '[woocommerce_customer_completed_order_settings]subject_downloadable' );
154
+
155
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
156
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
157
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
158
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
159
+ }
160
+ }
161
+
162
+ function email_heading_processing($order_id){
163
+ global $woocommerce;
164
+ if( class_exists( 'WC_Email_Customer_Processing_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Processing_Order' ] ) ){
165
+
166
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_processing_order_settings', '[woocommerce_customer_processing_order_settings]heading' );
167
+
168
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_processing_order_settings', '[woocommerce_customer_processing_order_settings]subject' );
169
+
170
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
171
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
172
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
173
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
174
+ }
175
+ }
176
+
177
+ function email_heading_note($args){
178
+ global $woocommerce;
179
+
180
+ if( class_exists( 'WC_Email_Customer_Note' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
181
+
182
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]heading' );
183
+
184
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_note_settings', '[woocommerce_customer_note_settings]subject' );
185
+
186
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
187
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
188
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
189
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
190
+ }
191
+ }
192
+
193
+ function email_heading_refund( $order_id, $refund_id = null ){
194
+ global $woocommerce;
195
+ if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
196
+
197
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
198
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
199
+ '[woocommerce_customer_refunded_order_settings]heading_partial' );
200
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
201
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
202
+ '[woocommerce_customer_refunded_order_settings]subject_partial' );
203
+
204
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
205
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
206
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
207
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
208
+
209
+ }
210
+ }
211
+
212
+
213
+ function new_order_admin_email($order_id){
214
+ global $woocommerce;
215
+ if( isset( $woocommerce->mailer()->emails[ 'WC_Email_New_Order' ] ) ){
216
+ $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
217
+ foreach($recipients as $recipient){
218
+ $user = get_user_by('email',$recipient);
219
+ if($user){
220
+ $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
221
+ }else{
222
+ $user_lang = get_post_meta($order_id, 'wpml_language', true );
223
+ }
224
+
225
+ $this->change_email_language( $user_lang );
226
+
227
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading' );
228
+
229
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject' );
230
+
231
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
232
+
233
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
234
+ }
235
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
236
+ $this->refresh_email_lang($order_id);
237
+ }
238
+ }
239
+
240
+ public function backend_new_order_admin_email( $order_id ){
241
+ if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
242
+ $this->new_order_admin_email( $order_id );
243
+ }
244
+ }
245
+
246
+ function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
247
+ if( $meta_key == '_payment_method_title' ){
248
+
249
+ $payment_method = get_post_meta( $object_id, '_payment_method', true );
250
+
251
+ if( $payment_method ){
252
+
253
+ $payment_gateways = WC()->payment_gateways->payment_gateways();
254
+ if( isset( $payment_gateways[ $payment_method ] ) ){
255
+ $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
256
+
257
+ return $title;
258
+ }
259
+ }
260
+
261
+
262
+ }
263
+ return $check;
264
+ }
265
+
266
+ function filter_formatted_items( $formatted_meta, $object ){
267
+
268
+ if( isset( $object->product->variation_id ) ){
269
+
270
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
271
+
272
+ if( !is_null( $current_prod_variation_id ) ) {
273
+
274
+ foreach( $formatted_meta as $key => $formatted_var ){
275
+
276
+ if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
277
+
278
+ $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
279
+
280
+ if( taxonomy_exists( $attribute ) ){
281
+ $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
282
+ $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
283
+
284
+ if( $tr_id ){
285
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
286
+ $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
287
+ }
288
+
289
+ }else{
290
+
291
+ $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $formatted_var[ 'key' ], array('is_taxonomy' => false), $this->sitepress->get_current_language() );
292
+
293
+ if ( false !== $custom_attr_trnsl ) {
294
+ $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
295
+ }
296
+ }
297
+ }
298
+ }
299
+ }
300
+ }
301
+
302
+ return $formatted_meta;
303
+
304
+ }
305
+
306
+ function change_email_language($lang){
307
+ global $woocommerce;
308
+ $this->sitepress->switch_lang($lang,true);
309
+ $this->locale = $this->sitepress->get_locale( $lang );
310
+ unload_textdomain('woocommerce');
311
+ unload_textdomain( 'default' );
312
+ global $wp_locale;
313
+ $wp_locale = new WP_Locale();
314
+
315
+ $woocommerce->load_plugin_textdomain();
316
+ load_default_textdomain( $this->locale );
317
+ }
318
+
319
+ function admin_string_return_cached( $value, $option ){
320
+ if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
321
+ return false;
322
+
323
+ return $value;
324
+ }
325
+
326
+ function wcml_get_translated_email_string( $context, $name ){
327
+
328
+ if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
329
+ global $wpdb;
330
+
331
+ $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
332
+
333
+ return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
334
+ }else{
335
+
336
+ return apply_filters( 'wpml_translate_single_string', false, $context, $name );
337
+
338
+ }
339
+
340
+ }
341
+
342
+ function icl_current_string_language( $current_language, $name ){
343
+ $order_id = false;
344
+
345
+ if( isset($_POST['action']) && $_POST['action'] == 'editpost' && isset($_POST['post_type']) && $_POST['post_type'] == 'shop_order' && isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] != 'send_email_new_order' ){
346
+ $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
347
+ }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
348
+ $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
349
+ }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
350
+ $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
351
+ }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
352
+ $order_id = $this->order_id;
353
+ }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
354
+ $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
355
+ }elseif( empty( $_POST ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'email' && substr( $name, 0, 12 ) == '[woocommerce' ){
356
+ $email_string = explode( ']', str_replace( '[', '', $name ) );
357
+ $email_option = get_option( $email_string[ 0 ], true );
358
+ $context = 'admin_texts_'.$email_string[ 0 ];
359
+
360
+ $current_language = $this->woocommerce_wpml->strings->get_string_language( $email_option[ $email_string[ 1 ] ], $context, $name );
361
+ }
362
+
363
+ $order_id = apply_filters( 'wcml_send_email_order_id', $order_id );
364
+
365
+ if( $order_id ){
366
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
367
+ if( $order_language ){
368
+ $current_language = $order_language;
369
+ }else{
370
+ $current_language = $this->sitepress->get_current_language();
371
+ }
372
+ }
373
+
374
+ return apply_filters( 'wcml_email_language', $current_language, $order_id );
375
+ }
376
+
377
+ // set correct locale code for emails
378
+ function set_locale_for_emails( $locale, $domain ){
379
+
380
+ if( $domain == 'woocommerce' && $this->locale ){
381
+ $locale = $this->locale;
382
+ }
383
+
384
+ return $locale;
385
+ }
386
+
387
+ function show_language_links_for_wc_emails(){
388
+
389
+ $emails_options = array(
390
+ 'woocommerce_new_order_settings',
391
+ 'woocommerce_cancelled_order_settings',
392
+ 'woocommerce_failed_order_settings',
393
+ 'woocommerce_customer_on_hold_order_settings',
394
+ 'woocommerce_customer_processing_order_settings',
395
+ 'woocommerce_customer_completed_order_settings',
396
+ 'woocommerce_customer_refunded_order_settings',
397
+ 'woocommerce_customer_invoice_settings',
398
+ 'woocommerce_customer_note_settings',
399
+ 'woocommerce_customer_reset_password_settings',
400
+ 'woocommerce_customer_new_account_settings'
401
+ );
402
+
403
+ $text_keys = array(
404
+ 'subject',
405
+ 'heading',
406
+ 'subject_downloadable',
407
+ 'heading_downloadable',
408
+ 'subject_full',
409
+ 'subject_partial',
410
+ 'heading_full',
411
+ 'heading_partial',
412
+ 'subject_paid',
413
+ 'heading_paid'
414
+ );
415
+
416
+
417
+ foreach( $emails_options as $emails_option ) {
418
+
419
+ $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
420
+ $section_name = str_replace( '_settings', '', $section_name );
421
+ if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
422
+
423
+ $option_settings = get_option( $emails_option );
424
+ foreach ($option_settings as $setting_key => $setting_value) {
425
+ if ( in_array( $setting_key, $text_keys ) ) {
426
+ $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
427
+
428
+ $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
429
+ $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
430
+ if( is_null( $language ) ) {
431
+ $language = $this->sitepress->get_default_language();
432
+ }
433
+
434
+ $lang_selector->render( array(
435
+ 'id' => $emails_option.'_'.$setting_key.'_language_selector',
436
+ 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
437
+ 'selected' => $language,
438
+ 'show_please_select' => false,
439
+ 'echo' => true,
440
+ 'style' => 'width: 18%;float: left'
441
+ )
442
+ );
443
+
444
+ $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
445
+ ?>
446
+ <script>
447
+ var input = jQuery('input[name="<?php echo $input_name ?>"]');
448
+ if (input.length) {
449
+ input.parent().append('<div class="translation_controls"></div>');
450
+ input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
451
+ jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
452
+ }
453
+ </script>
454
+ <?php }
455
+ }
456
+ }
457
+ }
458
+ }
459
+
460
+ function set_emails_string_language(){
461
+
462
+ foreach( $_POST as $key => $language ){
463
+
464
+ if( substr( $key, 0, 9 ) == 'wcml_lang' ){
465
+
466
+ $email_string = explode( '-', $key );
467
+
468
+ if( isset( $email_string[2] ) ){
469
+
470
+ $email_key = str_replace( '_settings', '', $email_string[1] );
471
+ $email_key .= '_'.$email_string[2];
472
+
473
+ $email_settings = get_option( $email_string[1], true );
474
+ $opt_string_value = $email_settings[ $email_string[2] ];
475
+
476
+ $string_value = isset( $_POST[ $email_key ] ) ? $_POST[ $email_key ] : $opt_string_value;
477
+
478
+ $context = 'admin_texts_'.$email_string[1];
479
+ $name = '['.$email_string[1].']'.$email_string[2];
480
+
481
+ do_action('wpml_register_single_string', $context, $name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
482
+
483
+ $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $name, $language );
484
+ }
485
+ }
486
+ }
487
+ }
488
+
489
  }
inc/class-wcml-endpoints.php CHANGED
@@ -1,286 +1,285 @@
1
- <?php
2
-
3
- class WCML_Endpoints{
4
-
5
- var $endpoints_strings = array();
6
-
7
- function __construct(){
8
-
9
- add_action( 'icl_ajx_custom_call', array( $this, 'rewrite_rule_endpoints' ), 11, 2 );
10
- add_action( 'woocommerce_update_options', array( $this, 'add_endpoints' ) );
11
- add_filter( 'pre_update_option_rewrite_rules', array( $this, 'update_rewrite_rules' ), 100, 2 );
12
-
13
- add_filter( 'page_link', array( $this, 'endpoint_permalink_filter' ), 10, 2 ); //after WPML
14
-
15
- if( !is_admin() ){
16
- //endpoints hooks
17
- $this->maybe_flush_rules();
18
- $this->register_endpoints_translations();
19
-
20
-
21
- add_filter('pre_get_posts', array($this, 'check_if_endpoint_exists'));
22
- }
23
-
24
- add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
25
-
26
- add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings') );
27
- }
28
-
29
-
30
- function register_endpoints_translations(){
31
-
32
- if( !class_exists( 'woocommerce' ) || !defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) return false;
33
-
34
- $wc_vars = WC()->query->query_vars;
35
-
36
- if ( !empty( $wc_vars ) ){
37
- $query_vars = array(
38
- // Checkout actions
39
- 'order-pay' => $this->get_endpoint_translation( 'order-pay', $wc_vars['order-pay'] ),
40
- 'order-received' => $this->get_endpoint_translation( 'order-received', $wc_vars['order-received'] ),
41
-
42
- // My account actions
43
- 'view-order' => $this->get_endpoint_translation( 'view-order', $wc_vars['view-order'] ),
44
- 'edit-account' => $this->get_endpoint_translation( 'edit-account', $wc_vars['edit-account'] ),
45
- 'edit-address' => $this->get_endpoint_translation( 'edit-address', $wc_vars['edit-address'] ),
46
- 'lost-password' => $this->get_endpoint_translation( 'lost-password', $wc_vars['lost-password'] ),
47
- 'customer-logout' => $this->get_endpoint_translation( 'customer-logout', $wc_vars['customer-logout'] ),
48
- 'add-payment-method' => $this->get_endpoint_translation( 'add-payment-method', $wc_vars['add-payment-method'] )
49
- );
50
-
51
- if( isset( $wc_vars['orders'] ) ) $query_vars[ 'orders' ] = $this->get_endpoint_translation( 'orders', $wc_vars['orders'] );
52
- if( isset( $wc_vars['downloads'] ) ) $query_vars[ 'downloads' ] = $this->get_endpoint_translation( 'downloads', $wc_vars['downloads'] );
53
- if( isset( $wc_vars['payment-methods'] ) ) $query_vars[ 'payment-methods' ] = $this->get_endpoint_translation( 'payment-methods', $wc_vars['payment-methods'] );
54
- if( isset( $wc_vars['delete-payment-method'] ) ) $query_vars[ 'delete-payment-method' ] = $this->get_endpoint_translation( 'delete-payment-method', $wc_vars['delete-payment-method'] );
55
- if( isset( $wc_vars['set-default-payment-method'] ) ) $query_vars[ 'set-default-payment-method' ] = $this->get_endpoint_translation( 'set-default-payment-method', $wc_vars['set-default-payment-method'] );
56
-
57
- $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
58
-
59
- $query_vars = array_merge( $wc_vars , $query_vars );
60
- WC()->query->query_vars = $query_vars;
61
-
62
- }
63
-
64
- }
65
-
66
- function get_endpoint_translation( $key, $endpoint, $language = null ){
67
-
68
- $this->register_endpoint_string( $key, $endpoint );
69
-
70
- if( function_exists('icl_t') ){
71
- $trnsl = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', $key, $language );
72
-
73
- if( !empty( $trnsl ) ){
74
- return $trnsl;
75
- }else{
76
- return $endpoint;
77
- }
78
- }else{
79
- return $endpoint;
80
- }
81
- }
82
-
83
- public function register_endpoint_string( $key, $endpoint ){
84
-
85
- $string = icl_get_string_id( $endpoint, 'WooCommerce Endpoints', $key );
86
-
87
- if( !$string && function_exists( 'icl_register_string' ) ){
88
- do_action( 'wpml_register_single_string', 'WooCommerce Endpoints', $key, $endpoint );
89
- }else{
90
- $this->endpoints_strings[] = $string;
91
- }
92
-
93
- }
94
-
95
- function rewrite_rule_endpoints( $call, $data ){
96
-
97
- if( $call == 'icl_st_save_translation' && in_array( $data['icl_st_string_id'], $this->endpoints_strings ) ){
98
- $this->add_endpoints();
99
- $this->flush_rules_for_endpoints_translations();
100
- }
101
- }
102
-
103
- function flush_rules_for_endpoints_translations( ){
104
- add_option( 'flush_rules_for_endpoints_translations', true );
105
- }
106
-
107
- function maybe_flush_rules(){
108
- if( get_option( 'flush_rules_for_endpoints_translations' ) ){
109
- WC()->query->init_query_vars();
110
- WC()->query->add_endpoints();
111
- flush_rewrite_rules();
112
- delete_option( 'flush_rules_for_endpoints_translations' );
113
- }
114
- }
115
-
116
- function update_rewrite_rules( $value, $old_value ){
117
- $this->add_endpoints();
118
- $this->flush_rules_for_endpoints_translations();
119
-
120
- return $value;
121
- }
122
-
123
- function add_endpoints(){
124
- if( !isset( $this->endpoints_strings ) )
125
- return;
126
-
127
- global $wpdb;
128
- //add endpoints and flush rules
129
- foreach( $this->endpoints_strings as $string_id ){
130
-
131
- $string_translations = icl_get_string_translations_by_id( $string_id );
132
-
133
- foreach( $string_translations as $string ){
134
- add_rewrite_endpoint( $string['value'], EP_ROOT | EP_PAGES );
135
- }
136
- }
137
-
138
- }
139
-
140
- function endpoint_permalink_filter( $p, $pid ){
141
- global $post;
142
-
143
- if( isset($post->ID) && !is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.2', '>=' ) && defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE ){
144
- global $wp,$sitepress;
145
-
146
- $current_lang = $sitepress->get_current_language();
147
- $page_lang = $sitepress->get_language_for_element( $post->ID, 'post_page');
148
- if( $current_lang != $page_lang && apply_filters( 'translate_object_id', $pid, 'page', false, $page_lang ) == $post->ID ){
149
-
150
- $endpoints = WC()->query->get_query_vars();
151
-
152
- foreach( $endpoints as $key => $endpoint ){
153
- if( isset($wp->query_vars[$key]) ){
154
- if( $key === 'order-pay' ){
155
- $endpoint = get_option( 'woocommerce_checkout_pay_endpoint' );
156
- $p .= isset( $_SERVER[ 'QUERY_STRING' ] ) ? '?'.$_SERVER[ 'QUERY_STRING' ] : '';
157
- }elseif( $key === 'order-received' ){
158
- $endpoint = get_option( 'woocommerce_checkout_order_received_endpoint' );
159
- }else{
160
- $endpoint = get_option( 'woocommerce_myaccount_'.str_replace( '-','_',$key).'_endpoint' );
161
- }
162
-
163
- $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
164
-
165
- $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
166
- }
167
- }
168
- }
169
- }
170
-
171
- return $p;
172
- }
173
-
174
- function get_endpoint_url($endpoint, $value = '', $permalink = '', $page_lang = false ){
175
- global $sitepress;
176
-
177
- if( $page_lang ){
178
- $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
179
- $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
180
-
181
- if( $edit_address_shipping == urldecode( $value ) ){
182
- $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
183
- }elseif( $edit_address_billing == urldecode( $value ) ){
184
- $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
185
- }
186
-
187
- }
188
-
189
-
190
- if ( get_option( 'permalink_structure' ) ) {
191
- if ( strstr( $permalink, '?' ) ) {
192
- $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
193
- $permalink = current( explode( '?', $permalink ) );
194
- } else {
195
- $query_string = '';
196
- }
197
- $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
198
- } else {
199
- $url = add_query_arg( $endpoint, $value, $permalink );
200
- }
201
- return $url;
202
- }
203
-
204
- /*
205
- * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
206
- */
207
- function check_if_endpoint_exists($q){
208
- global $wp_query;
209
-
210
- $my_account_id = wc_get_page_id('myaccount');
211
-
212
- $current_id = $q->query_vars['page_id'];
213
- if(!$current_id){
214
- $current_id = $q->queried_object_id;
215
- }
216
-
217
- if( !$q->is_404 && $current_id == $my_account_id && $q->is_page ){
218
-
219
- $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI']) );
220
- $endpoints = WC()->query->get_query_vars();
221
- $endpoint_in_url = urldecode( end( $uri_vars ) );
222
-
223
- $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
224
- $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
225
-
226
- if( urldecode( $q->query['pagename'] ) != $endpoint_in_url && !in_array( $endpoint_in_url,$endpoints ) && is_numeric( $endpoint_in_url ) && !in_array( urldecode( prev( $uri_vars ) ) ,$q->query_vars ) ){
227
- $wp_query->set_404();
228
- status_header(404);
229
- include( get_query_template( '404' ) );
230
- die();
231
- }
232
-
233
- }
234
-
235
- }
236
-
237
- function get_translated_edit_address_slug( $slug, $language = false ){
238
- global $woocommerce_wpml;
239
-
240
- $strings_language = $woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: '.$slug );
241
-
242
- if( $strings_language == $language ){
243
- return $slug;
244
- }
245
-
246
- $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: '.$slug, $language );
247
-
248
- if( $translated_slug == $slug ){
249
-
250
- if( $language ){
251
- $translated_slug = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug'. chr(4) .$slug, $language );
252
- }else{
253
- $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
254
- }
255
-
256
- }
257
-
258
- return $translated_slug;
259
- }
260
-
261
- function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ){
262
-
263
- // return translated edit account slugs
264
- if( isset( WC()->query->query_vars[ 'edit-address' ] ) && isset( WC()->query->query_vars[ 'edit-address' ] ) == $endpoint && in_array( $value, array('shipping','billing'))){
265
- remove_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
266
- $url = wc_get_endpoint_url( 'edit-address', $this->get_translated_edit_address_slug( $value ) );
267
- add_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
268
-
269
-
270
- }
271
-
272
- return $url;
273
- }
274
-
275
- public function update_original_endpoints_strings(){
276
-
277
- foreach( WC()->query->query_vars as $endpoint_key => $endpoint ){
278
-
279
- $this->register_endpoint_string( $endpoint_key, $endpoint );
280
-
281
- }
282
-
283
- }
284
-
285
-
286
- }
1
+ <?php
2
+
3
+ class WCML_Endpoints{
4
+
5
+ var $endpoints_strings = array();
6
+
7
+ function __construct(){
8
+
9
+ add_action( 'icl_ajx_custom_call', array( $this, 'rewrite_rule_endpoints' ), 11, 2 );
10
+ add_action( 'woocommerce_update_options', array( $this, 'add_endpoints' ) );
11
+ add_filter( 'pre_update_option_rewrite_rules', array( $this, 'update_rewrite_rules' ), 100, 2 );
12
+
13
+ add_filter( 'page_link', array( $this, 'endpoint_permalink_filter' ), 10, 2 ); //after WPML
14
+
15
+ if( !is_admin() ){
16
+ //endpoints hooks
17
+ $this->maybe_flush_rules();
18
+ $this->register_endpoints_translations();
19
+
20
+
21
+ add_filter('pre_get_posts', array($this, 'check_if_endpoint_exists'));
22
+ }
23
+
24
+ add_filter( 'woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url' ), 10, 4 );
25
+
26
+ add_filter( 'woocommerce_settings_saved', array( $this, 'update_original_endpoints_strings') );
27
+ }
28
+
29
+
30
+ function register_endpoints_translations( $language = null ){
31
+
32
+ if( !class_exists( 'woocommerce' ) || !defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) return false;
33
+
34
+ $wc_vars = WC()->query->query_vars;
35
+
36
+ if ( !empty( $wc_vars ) ){
37
+ $query_vars = array(
38
+ // Checkout actions
39
+ 'order-pay' => $this->get_endpoint_translation( 'order-pay', $wc_vars['order-pay'], $language ),
40
+ 'order-received' => $this->get_endpoint_translation( 'order-received', $wc_vars['order-received'], $language ),
41
+
42
+ // My account actions
43
+ 'view-order' => $this->get_endpoint_translation( 'view-order', $wc_vars['view-order'], $language ),
44
+ 'edit-account' => $this->get_endpoint_translation( 'edit-account', $wc_vars['edit-account'], $language ),
45
+ 'edit-address' => $this->get_endpoint_translation( 'edit-address', $wc_vars['edit-address'], $language ),
46
+ 'lost-password' => $this->get_endpoint_translation( 'lost-password', $wc_vars['lost-password'], $language ),
47
+ 'customer-logout' => $this->get_endpoint_translation( 'customer-logout', $wc_vars['customer-logout'], $language ),
48
+ 'add-payment-method' => $this->get_endpoint_translation( 'add-payment-method', $wc_vars['add-payment-method'], $language )
49
+ );
50
+
51
+ if( isset( $wc_vars['orders'] ) ) $query_vars[ 'orders' ] = $this->get_endpoint_translation( 'orders', $wc_vars['orders'], $language );
52
+ if( isset( $wc_vars['downloads'] ) ) $query_vars[ 'downloads' ] = $this->get_endpoint_translation( 'downloads', $wc_vars['downloads'], $language );
53
+ if( isset( $wc_vars['payment-methods'] ) ) $query_vars[ 'payment-methods' ] = $this->get_endpoint_translation( 'payment-methods', $wc_vars['payment-methods'], $language );
54
+ if( isset( $wc_vars['delete-payment-method'] ) ) $query_vars[ 'delete-payment-method' ] = $this->get_endpoint_translation( 'delete-payment-method', $wc_vars['delete-payment-method'], $language );
55
+ if( isset( $wc_vars['set-default-payment-method'] ) ) $query_vars[ 'set-default-payment-method' ] = $this->get_endpoint_translation( 'set-default-payment-method', $wc_vars['set-default-payment-method'], $language );
56
+
57
+ $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
58
+
59
+ $query_vars = array_merge( $wc_vars , $query_vars );
60
+ WC()->query->query_vars = $query_vars;
61
+
62
+ }
63
+
64
+ return WC()->query->query_vars;
65
+ }
66
+
67
+ function get_endpoint_translation( $key, $endpoint, $language = null ){
68
+
69
+ $this->register_endpoint_string( $key, $endpoint );
70
+
71
+ if( function_exists('icl_t') ){
72
+ $trnsl = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', $key, $language );
73
+
74
+ if( !empty( $trnsl ) ){
75
+ return $trnsl;
76
+ }else{
77
+ return $endpoint;
78
+ }
79
+ }else{
80
+ return $endpoint;
81
+ }
82
+ }
83
+
84
+ public function register_endpoint_string( $key, $endpoint ){
85
+
86
+ $string = icl_get_string_id( $endpoint, 'WooCommerce Endpoints', $key );
87
+
88
+ if( !$string && function_exists( 'icl_register_string' ) ){
89
+ do_action( 'wpml_register_single_string', 'WooCommerce Endpoints', $key, $endpoint );
90
+ }else{
91
+ $this->endpoints_strings[] = $string;
92
+ }
93
+
94
+ }
95
+
96
+ function rewrite_rule_endpoints( $call, $data ){
97
+
98
+ if( $call == 'icl_st_save_translation' && in_array( $data['icl_st_string_id'], $this->endpoints_strings ) ){
99
+ $this->add_endpoints();
100
+ $this->flush_rules_for_endpoints_translations();
101
+ }
102
+ }
103
+
104
+ function flush_rules_for_endpoints_translations( ){
105
+ add_option( 'flush_rules_for_endpoints_translations', true );
106
+ }
107
+
108
+ function maybe_flush_rules(){
109
+ if( get_option( 'flush_rules_for_endpoints_translations' ) ){
110
+ WC()->query->init_query_vars();
111
+ WC()->query->add_endpoints();
112
+ flush_rewrite_rules();
113
+ delete_option( 'flush_rules_for_endpoints_translations' );
114
+ }
115
+ }
116
+
117
+ function update_rewrite_rules( $value, $old_value ){
118
+ $this->add_endpoints();
119
+ $this->flush_rules_for_endpoints_translations();
120
+
121
+ return $value;
122
+ }
123
+
124
+ function add_endpoints(){
125
+ if( !isset( $this->endpoints_strings ) )
126
+ return;
127
+
128
+ global $wpdb;
129
+ //add endpoints and flush rules
130
+ foreach( $this->endpoints_strings as $string_id ){
131
+
132
+ $string_translations = icl_get_string_translations_by_id( $string_id );
133
+
134
+ foreach( $string_translations as $string ){
135
+ add_rewrite_endpoint( $string['value'], EP_ROOT | EP_PAGES );
136
+ }
137
+ }
138
+
139
+ }
140
+
141
+ function endpoint_permalink_filter( $p, $pid ){
142
+ global $post;
143
+
144
+ if( isset($post->ID) && !is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.2', '>=' ) && defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE ){
145
+ global $wp,$sitepress;
146
+
147
+ $current_lang = $sitepress->get_current_language();
148
+ $page_lang = $sitepress->get_language_for_element( $post->ID, 'post_page');
149
+ if( $current_lang != $page_lang && apply_filters( 'translate_object_id', $pid, 'page', false, $page_lang ) == $post->ID ){
150
+
151
+ $endpoints = WC()->query->get_query_vars();
152
+
153
+ foreach( $endpoints as $key => $endpoint ){
154
+ if( isset($wp->query_vars[$key]) ){
155
+ if( $key === 'order-pay' ){
156
+ $endpoint = get_option( 'woocommerce_checkout_pay_endpoint' );
157
+ $p .= isset( $_SERVER[ 'QUERY_STRING' ] ) ? '?'.$_SERVER[ 'QUERY_STRING' ] : '';
158
+ }elseif( $key === 'order-received' ){
159
+ $endpoint = get_option( 'woocommerce_checkout_order_received_endpoint' );
160
+ }else{
161
+ $endpoint = get_option( 'woocommerce_myaccount_'.str_replace( '-','_',$key).'_endpoint' );
162
+ }
163
+
164
+ $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
165
+
166
+ $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
167
+ }
168
+ }
169
+ }
170
+ }
171
+
172
+ return $p;
173
+ }
174
+
175
+ function get_endpoint_url($endpoint, $value = '', $permalink = '', $page_lang = false ){
176
+ global $sitepress;
177
+
178
+ if( $page_lang ){
179
+ $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
180
+ $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
181
+
182
+ if( $edit_address_shipping == urldecode( $value ) ){
183
+ $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
184
+ }elseif( $edit_address_billing == urldecode( $value ) ){
185
+ $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
186
+ }
187
+
188
+ }
189
+
190
+
191
+ if ( get_option( 'permalink_structure' ) ) {
192
+ if ( strstr( $permalink, '?' ) ) {
193
+ $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
194
+ $permalink = current( explode( '?', $permalink ) );
195
+ } else {
196
+ $query_string = '';
197
+ }
198
+ $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
199
+ } else {
200
+ $url = add_query_arg( $endpoint, $value, $permalink );
201
+ }
202
+ return $url;
203
+ }
204
+
205
+ /*
206
+ * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
207
+ */
208
+ function check_if_endpoint_exists($q){
209
+ global $wp_query;
210
+
211
+ $my_account_id = wc_get_page_id('myaccount');
212
+
213
+ $current_id = $q->query_vars['page_id'];
214
+ if(!$current_id){
215
+ $current_id = $q->queried_object_id;
216
+ }
217
+
218
+ if( !$q->is_404 && $current_id == $my_account_id && $q->is_page ){
219
+
220
+ $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI']) );
221
+ $endpoints = WC()->query->get_query_vars();
222
+ $endpoint_in_url = urldecode( end( $uri_vars ) );
223
+
224
+ $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
225
+ $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
226
+
227
+ if( urldecode( $q->query['pagename'] ) != $endpoint_in_url && !in_array( $endpoint_in_url,$endpoints ) && is_numeric( $endpoint_in_url ) && !in_array( urldecode( prev( $uri_vars ) ) ,$q->query_vars ) ){
228
+ $wp_query->set_404();
229
+ status_header(404);
230
+ include( get_query_template( '404' ) );
231
+ die();
232
+ }
233
+
234
+ }
235
+
236
+ }
237
+
238
+ function get_translated_edit_address_slug( $slug, $language = false ){
239
+ global $woocommerce_wpml;
240
+
241
+ $strings_language = $woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: '.$slug );
242
+
243
+ if( $strings_language == $language ){
244
+ return $slug;
245
+ }
246
+
247
+ $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: '.$slug, $language );
248
+
249
+ if( $translated_slug == $slug ){
250
+
251
+ if( $language ){
252
+ $translated_slug = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug'. chr(4) .$slug, $language );
253
+ }else{
254
+ $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
255
+ }
256
+
257
+ }
258
+
259
+ return $translated_slug;
260
+ }
261
+
262
+ function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ){
263
+
264
+ // return translated edit account slugs
265
+ if( isset( WC()->query->query_vars[ 'edit-address' ] ) && WC()->query->query_vars[ 'edit-address' ] == $endpoint && in_array( $value, array('shipping','billing'))){
266
+ remove_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
267
+ $url = wc_get_endpoint_url( 'edit-address', $this->get_translated_edit_address_slug( $value ) );
268
+ add_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
269
+ }
270
+
271
+ return $url;
272
+ }
273
+
274
+ public function update_original_endpoints_strings(){
275
+
276
+ foreach( WC()->query->query_vars as $endpoint_key => $endpoint ){
277
+
278
+ $this->register_endpoint_string( $endpoint_key, $endpoint );
279
+
280
+ }
281
+
282
+ }
283
+
284
+
285
+ }
 
inc/class-wcml-fix-copied-custom-fields-wpml353.php CHANGED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- class WCML_Fix_Copied_Custom_Fields_WPML353{
4
-
5
- public function __construct(){
6
- //@TODO review after WPML 3.6
7
- if ( is_admin() && version_compare( ICL_SITEPRESS_VERSION, '3.5.3', '>=' ) && version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
8
- add_action( 'added_post_meta', array(
9
- $this,
10
- 'fix_copied_custom_fields'
11
- ), 10, 4 );
12
- }
13
-
14
- }
15
-
16
- public function fix_copied_custom_fields( $mid, $object_id, $meta_key, $_meta_value ) {
17
- global $wpdb;
18
-
19
- if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ) ) ) {
20
-
21
- $meta_keys_to_fix = array(
22
- '_price',
23
- '_regular_price',
24
- '_sale_price',
25
- '_sku'
26
- );
27
-
28
- if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
29
-
30
- if ( is_null( $_meta_value ) ) {
31
- $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_id' => $mid ) );
32
- }
33
-
34
- }
35
-
36
- }
37
-
38
- }
39
-
40
  }
1
+ <?php
2
+
3
+ class WCML_Fix_Copied_Custom_Fields_WPML353{
4
+
5
+ public function __construct(){
6
+ //@TODO review after WPML 3.6
7
+ if ( is_admin() && version_compare( ICL_SITEPRESS_VERSION, '3.5.3', '>=' ) && version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
8
+ add_action( 'added_post_meta', array(
9
+ $this,
10
+ 'fix_copied_custom_fields'
11
+ ), 10, 4 );
12
+ }
13
+
14
+ }
15
+
16
+ public function fix_copied_custom_fields( $mid, $object_id, $meta_key, $_meta_value ) {
17
+ global $wpdb;
18
+
19
+ if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ) ) ) {
20
+
21
+ $meta_keys_to_fix = array(
22
+ '_price',
23
+ '_regular_price',
24
+ '_sale_price',
25
+ '_sku'
26
+ );
27
+
28
+ if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
29
+
30
+ if ( is_null( $_meta_value ) ) {
31
+ $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_id' => $mid ) );
32
+ }
33
+
34
+ }
35
+
36
+ }
37
+
38
+ }
39
+
40
  }
inc/class-wcml-install.php CHANGED
@@ -1,264 +1,264 @@
1
- <?php
2
-
3
- class WCML_Install{
4
-
5
- public static function initialize( &$woocommerce_wpml, &$sitepress ) {
6
-
7
- if( is_admin() ) {
8
-
9
- // Install routine
10
- if ( empty( $woocommerce_wpml->settings['set_up'] ) ) { // from 3.2
11
-
12
- if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
13
- //global term ordering resync when moving to >= 3.3.x
14
- add_action( 'init', array( $woocommerce_wpml->terms, 'sync_term_order_globally' ), 20 );
15
- }
16
-
17
- if ( ! isset( $woocommerce_wpml->settings['wc_admin_options_saved'] ) ) {
18
- self::handle_admin_texts();
19
- $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
20
- }
21
-
22
- if ( ! isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
23
- $woocommerce_wpml->settings['trnsl_interface'] = 1;
24
- }
25
-
26
- if ( ! isset( $woocommerce_wpml->settings['products_sync_date'] ) ) {
27
- $woocommerce_wpml->settings['products_sync_date'] = 1;
28
- }
29
-
30
- if ( ! isset( $woocommerce_wpml->settings['products_sync_order'] ) ) {
31
- $woocommerce_wpml->settings['products_sync_order'] = 1;
32
- }
33
-
34
- if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
35
- $woocommerce_wpml->settings['display_custom_prices'] = 0;
36
- }
37
-
38
- if ( ! isset( $woocommerce_wpml->settings['sync_taxonomies_checked'] ) ) {
39
- $woocommerce_wpml->terms->check_if_sync_terms_needed();
40
- $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
41
- }
42
-
43
- WCML_Capabilities::set_up_capabilities();
44
-
45
- self:: set_language_information( $sitepress );
46
- self:: check_product_type_terms();
47
-
48
- set_transient( '_wcml_activation_redirect', 1, 30 );
49
-
50
- // Before the setup wizard redirects from plugins.php, allow WPML to scan the wpml-config.xml file
51
- WPML_Config::load_config_run();
52
-
53
- $woocommerce_wpml->settings['set_up'] = 1;
54
- $woocommerce_wpml->update_settings();
55
-
56
- }
57
-
58
- if ( empty( $woocommerce_wpml->settings['downloaded_translations_for_wc'] ) ) { //from 3.3.3
59
- $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
60
- $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
61
- $woocommerce_wpml->update_settings();
62
- }
63
-
64
- if ( empty( $woocommerce_wpml->settings[ 'rewrite_rules_flashed' ] ) ) {
65
- flush_rewrite_rules();
66
- $woocommerce_wpml->settings['rewrite_rules_flashed'] = 1;
67
- }
68
-
69
- add_filter( 'wpml_tm_dashboard_translatable_types', array(
70
- __CLASS__,
71
- 'hide_variation_type_on_tm_dashboard'
72
- ) );
73
-
74
- new WCML_Setup( $woocommerce_wpml, $sitepress );
75
- if ( ! empty( $woocommerce_wpml->settings['set_up_wizard_run'] ) ) {
76
- add_action( 'admin_notices', array( __CLASS__, 'admin_notice_after_install' ) );
77
- }
78
-
79
- $translated_product_type_terms = WCML_Install::translated_product_type_terms();
80
- if ( !empty( $translated_product_type_terms ) ) {
81
- add_action( 'admin_notices', array( __CLASS__, 'admin_translated_product_type_terms_notice' ) );
82
- }elseif( $sitepress->is_translated_taxonomy( 'product_type' ) ){
83
- add_action( 'admin_notices', array( __CLASS__, 'admin_translated_product_type_notice' ) );
84
- }
85
-
86
- }
87
-
88
- }
89
-
90
- private static function set_language_information( &$sitepress ){
91
- global $wpdb;
92
-
93
- $def_lang = $sitepress->get_default_language();
94
- //set language info for products
95
- $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
96
- foreach($products as $product){
97
- $exist = $sitepress->get_language_for_element($product->ID,'post_product');
98
- if(!$exist){
99
- $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
100
- }
101
- }
102
-
103
- //set language info for taxonomies
104
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
105
- foreach($terms as $term){
106
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
107
- if(!$exist){
108
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
109
- }
110
- }
111
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
112
- foreach($terms as $term){
113
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
114
- if(!$exist){
115
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
116
- }
117
- }
118
-
119
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
120
- foreach($terms as $term){
121
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
122
- if(!$exist){
123
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
124
- }
125
- }
126
- }
127
-
128
- //handle situation when product_type terms translated before activating WCML
129
- public static function check_product_type_terms(){
130
- global $wpdb;
131
- //check if terms were translated
132
- $translations = self::translated_product_type_terms();
133
-
134
- if( $translations ){
135
- foreach( $translations as $translation ){
136
- if( !is_null( $translation->source_language_code ) ){
137
- //check relationships
138
- $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
139
- if( $term_relationships ){
140
- $orig_term = $wpdb->get_var( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type' AND trid = %d AND source_language_code IS NULL", $translation->trid ) );
141
- if( $orig_term ){
142
- foreach( $term_relationships as $term_relationship ){
143
- $wpdb->update(
144
- $wpdb->term_relationships,
145
- array(
146
- 'term_taxonomy_id' => $orig_term
147
- ),
148
- array(
149
- 'object_id' => $term_relationship->object_id,
150
- 'term_taxonomy_id' => $translation->element_id
151
- )
152
- );
153
- }
154
- }
155
- }
156
- $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
157
-
158
- if( $term_id ){
159
- $wpdb->delete(
160
- $wpdb->terms,
161
- array(
162
- 'term_id' => $term_id
163
- )
164
- );
165
-
166
- $wpdb->delete(
167
- $wpdb->term_taxonomy,
168
- array(
169
- 'term_taxonomy_id' => $translation->element_id
170
- )
171
- );
172
- }
173
- }
174
- }
175
-
176
- foreach( $translations as $translation ){
177
- $wpdb->delete(
178
- $wpdb->prefix . 'icl_translations',
179
- array(
180
- 'translation_id' => $translation->translation_id
181
- )
182
- );
183
- }
184
- }
185
- }
186
-
187
- public static function translated_product_type_terms(){
188
- global $wpdb;
189
- //check if terms were translated
190
- $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
191
-
192
- return $translations;
193
- }
194
-
195
- private static function handle_admin_texts(){
196
- if(class_exists('woocommerce')){
197
- //emails texts
198
- $emails = new WC_Emails();
199
- foreach($emails->emails as $email){
200
- $option_name = $email->plugin_id.$email->id.'_settings';
201
- if(!get_option($option_name)){
202
- add_option($option_name,$email->settings);
203
- }
204
- }
205
- }
206
- }
207
-
208
- public static function admin_notice_after_install(){
209
- global $woocommerce_wpml;
210
-
211
- if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
212
-
213
- $url = $_SERVER['REQUEST_URI'];
214
- $pos = strpos($url, '?');
215
-
216
- if($pos !== false){
217
- $url .= '&wcml_action=dismiss';
218
- } else {
219
- $url .= '?wcml_action=dismiss';
220
- }
221
- ?>
222
- <div id="message" class="updated message fade otgs-is-dismissible">
223
- <p>
224
- <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
225
- </p>
226
- <p>
227
- <a class="button-primary align-right" href="<?php echo WCML_Links::generate_tracking_link('https://wpml.org/documentation/related-projects/woocommerce-multilingual/','woocommerce-multilingual','documentation'); ?>" target="_blank">
228
- <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
229
- </a>
230
- </p>
231
- <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
232
- </div>
233
- <?php
234
- }
235
- }
236
-
237
- public static function admin_translated_product_type_notice(){ ?>
238
-
239
- <div id="message" class="updated error">
240
- <p>
241
- <?php printf(__("We detected a problem in your WPML configuration: the %sproduct_type%s taxonomy is set as translatable and this would cause problems with translated products. You can fix this in the %sMultilingual Content Setup page%s.", 'woocommerce-multilingual'), '<i>', '</i>','<a href="' . admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#ml-content-setup-sec-8' ) . '">','</a>'); ?>
242
- </p>
243
- </div>
244
-
245
- <?php
246
- }
247
-
248
- public static function admin_translated_product_type_terms_notice(){ ?>
249
-
250
- <div id="message" class="updated error">
251
- <p>
252
- <?php printf(__("We detected that the %sproduct_type%s field was set incorrectly for some product translations. This happened because the product_type taxonomy was translated. You can fix this in the WooCommerce Multilingual %stroubleshooting page%s.", 'woocommerce-multilingual'), '<i>', '</i>','<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=troubleshooting' ) . '">','</a>'); ?>
253
- </p>
254
- </div>
255
-
256
- <?php
257
- }
258
-
259
- public static function hide_variation_type_on_tm_dashboard( $types ){
260
- unset( $types['product_variation'] );
261
- return $types;
262
- }
263
-
264
  }
1
+ <?php
2
+
3
+ class WCML_Install{
4
+
5
+ public static function initialize( &$woocommerce_wpml, &$sitepress ) {
6
+
7
+ if( is_admin() ) {
8
+
9
+ // Install routine
10
+ if ( empty( $woocommerce_wpml->settings['set_up'] ) ) { // from 3.2
11
+
12
+ if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
13
+ //global term ordering resync when moving to >= 3.3.x
14
+ add_action( 'init', array( $woocommerce_wpml->terms, 'sync_term_order_globally' ), 20 );
15
+ }
16
+
17
+ if ( ! isset( $woocommerce_wpml->settings['wc_admin_options_saved'] ) ) {
18
+ self::handle_admin_texts();
19
+ $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
20
+ }
21
+
22
+ if ( ! isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
23
+ $woocommerce_wpml->settings['trnsl_interface'] = 1;
24
+ }
25
+
26
+ if ( ! isset( $woocommerce_wpml->settings['products_sync_date'] ) ) {
27
+ $woocommerce_wpml->settings['products_sync_date'] = 1;
28
+ }
29
+
30
+ if ( ! isset( $woocommerce_wpml->settings['products_sync_order'] ) ) {
31
+ $woocommerce_wpml->settings['products_sync_order'] = 1;
32
+ }
33
+
34
+ if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
35
+ $woocommerce_wpml->settings['display_custom_prices'] = 0;
36
+ }
37
+
38
+ if ( ! isset( $woocommerce_wpml->settings['sync_taxonomies_checked'] ) ) {
39
+ $woocommerce_wpml->terms->check_if_sync_terms_needed();
40
+ $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
41
+ }
42
+
43
+ WCML_Capabilities::set_up_capabilities();
44
+
45
+ self:: set_language_information( $sitepress );
46
+ self:: check_product_type_terms();
47
+
48
+ set_transient( '_wcml_activation_redirect', 1, 30 );
49
+
50
+ // Before the setup wizard redirects from plugins.php, allow WPML to scan the wpml-config.xml file
51
+ WPML_Config::load_config_run();
52
+
53
+ $woocommerce_wpml->settings['set_up'] = 1;
54
+ $woocommerce_wpml->update_settings();
55
+
56
+ }
57
+
58
+ if ( empty( $woocommerce_wpml->settings['downloaded_translations_for_wc'] ) ) { //from 3.3.3
59
+ $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
60
+ $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
61
+ $woocommerce_wpml->update_settings();
62
+ }
63
+
64
+ if ( empty( $woocommerce_wpml->settings[ 'rewrite_rules_flashed' ] ) ) {
65
+ flush_rewrite_rules();
66
+ $woocommerce_wpml->settings['rewrite_rules_flashed'] = 1;
67
+ }
68
+
69
+ add_filter( 'wpml_tm_dashboard_translatable_types', array(
70
+ __CLASS__,
71
+ 'hide_variation_type_on_tm_dashboard'
72
+ ) );
73
+
74
+ new WCML_Setup( $woocommerce_wpml, $sitepress );
75
+ if ( ! empty( $woocommerce_wpml->settings['set_up_wizard_run'] ) ) {
76
+ add_action( 'admin_notices', array( __CLASS__, 'admin_notice_after_install' ) );
77
+ }
78
+
79
+ $translated_product_type_terms = WCML_Install::translated_product_type_terms();
80
+ if ( !empty( $translated_product_type_terms ) ) {
81
+ add_action( 'admin_notices', array( __CLASS__, 'admin_translated_product_type_terms_notice' ) );
82
+ }elseif( $sitepress->is_translated_taxonomy( 'product_type' ) ){
83
+ add_action( 'admin_notices', array( __CLASS__, 'admin_translated_product_type_notice' ) );
84
+ }
85
+
86
+ }
87
+
88
+ }
89
+
90
+ private static function set_language_information( &$sitepress ){
91
+ global $wpdb;
92
+
93
+ $def_lang = $sitepress->get_default_language();
94
+ //set language info for products
95
+ $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
96
+ foreach($products as $product){
97
+ $exist = $sitepress->get_language_for_element($product->ID,'post_product');
98
+ if(!$exist){
99
+ $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
100
+ }
101
+ }
102
+
103
+ //set language info for taxonomies
104
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
105
+ foreach($terms as $term){
106
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
107
+ if(!$exist){
108
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
109
+ }
110
+ }
111
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
112
+ foreach($terms as $term){
113
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
114
+ if(!$exist){
115
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
116
+ }
117
+ }
118
+
119
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
120
+ foreach($terms as $term){
121
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
122
+ if(!$exist){
123
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
124
+ }
125
+ }
126
+ }
127
+
128
+ //handle situation when product_type terms translated before activating WCML
129
+ public static function check_product_type_terms(){
130
+ global $wpdb;
131
+ //check if terms were translated
132
+ $translations = self::translated_product_type_terms();
133
+
134
+ if( $translations ){
135
+ foreach( $translations as $translation ){
136
+ if( !is_null( $translation->source_language_code ) ){
137
+ //check relationships
138
+ $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
139
+ if( $term_relationships ){
140
+ $orig_term = $wpdb->get_var( $wpdb->prepare( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type' AND trid = %d AND source_language_code IS NULL", $translation->trid ) );
141
+ if( $orig_term ){
142
+ foreach( $term_relationships as $term_relationship ){
143
+ $wpdb->update(
144
+ $wpdb->term_relationships,
145
+ array(
146
+ 'term_taxonomy_id' => $orig_term
147
+ ),
148
+ array(
149
+ 'object_id' => $term_relationship->object_id,
150
+ 'term_taxonomy_id' => $translation->element_id
151
+ )
152
+ );
153
+ }
154
+ }
155
+ }
156
+ $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
157
+
158
+ if( $term_id ){
159
+ $wpdb->delete(
160
+ $wpdb->terms,
161
+ array(
162
+ 'term_id' => $term_id
163
+ )
164
+ );
165
+
166
+ $wpdb->delete(
167
+ $wpdb->term_taxonomy,
168
+ array(
169
+ 'term_taxonomy_id' => $translation->element_id
170
+ )
171
+ );
172
+ }
173
+ }
174
+ }
175
+
176
+ foreach( $translations as $translation ){
177
+ $wpdb->delete(
178
+ $wpdb->prefix . 'icl_translations',
179
+ array(
180
+ 'translation_id' => $translation->translation_id
181
+ )
182
+ );
183
+ }
184
+ }
185
+ }
186
+
187
+ public static function translated_product_type_terms(){
188
+ global $wpdb;
189
+ //check if terms were translated
190
+ $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
191
+
192
+ return $translations;
193
+ }
194
+
195
+ private static function handle_admin_texts(){
196
+ if(class_exists('woocommerce')){
197
+ //emails texts
198
+ $emails = new WC_Emails();
199
+ foreach($emails->emails as $email){
200
+ $option_name = $email->plugin_id.$email->id.'_settings';
201
+ if(!get_option($option_name)){
202
+ add_option($option_name,$email->settings);
203
+ }
204
+ }
205
+ }
206
+ }
207
+
208
+ public static function admin_notice_after_install(){
209
+ global $woocommerce_wpml;
210
+
211
+ if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
212
+
213
+ $url = $_SERVER['REQUEST_URI'];
214
+ $pos = strpos($url, '?');
215
+
216
+ if($pos !== false){
217
+ $url .= '&wcml_action=dismiss';
218
+ } else {
219
+ $url .= '?wcml_action=dismiss';
220
+ }
221
+ ?>
222
+ <div id="message" class="updated message fade otgs-is-dismissible">
223
+ <p>
224
+ <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
225
+ </p>
226
+ <p>
227
+ <a class="button-primary align-right" href="<?php echo WCML_Links::generate_tracking_link('https://wpml.org/documentation/related-projects/woocommerce-multilingual/','woocommerce-multilingual','documentation'); ?>" target="_blank">
228
+ <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
229
+ </a>
230
+ </p>
231
+ <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
232
+ </div>
233
+ <?php
234
+ }
235
+ }
236
+
237
+ public static function admin_translated_product_type_notice(){ ?>
238
+
239
+ <div id="message" class="updated error">
240
+ <p>
241
+ <?php printf(__("We detected a problem in your WPML configuration: the %sproduct_type%s taxonomy is set as translatable and this would cause problems with translated products. You can fix this in the %sMultilingual Content Setup page%s.", 'woocommerce-multilingual'), '<i>', '</i>','<a href="' . admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/main.php&sm=mcsetup#ml-content-setup-sec-8' ) . '">','</a>'); ?>
242
+ </p>
243
+ </div>
244
+
245
+ <?php
246
+ }
247
+
248
+ public static function admin_translated_product_type_terms_notice(){ ?>
249
+
250
+ <div id="message" class="updated error">
251
+ <p>
252
+ <?php printf(__("We detected that the %sproduct_type%s field was set incorrectly for some product translations. This happened because the product_type taxonomy was translated. You can fix this in the WooCommerce Multilingual %stroubleshooting page%s.", 'woocommerce-multilingual'), '<i>', '</i>','<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=troubleshooting' ) . '">','</a>'); ?>
253
+ </p>
254
+ </div>
255
+
256
+ <?php
257
+ }
258
+
259
+ public static function hide_variation_type_on_tm_dashboard( $types ){
260
+ unset( $types['product_variation'] );
261
+ return $types;
262
+ }
263
+
264
  }
inc/class-wcml-languages-upgrader.php CHANGED
@@ -1,301 +1,301 @@
1
- <?php
2
-
3
- class WCML_Languages_Upgrader{
4
-
5
-
6
-
7
- function __construct(){
8
-
9
- add_action( 'icl_update_active_languages', array( $this, 'download_woocommerce_translations_for_active_languages' ) );
10
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_update' ), 11 );
11
- add_filter( 'upgrader_pre_download', array( $this, 'version_update' ), 10, 2 );
12
- add_action( 'admin_notices', array( $this, 'translation_upgrade_notice' ) );
13
- add_action( 'wp_ajax_hide_wcml_translations_message', array($this, 'hide_wcml_translations_message') );
14
-
15
- $this->load_js();
16
- }
17
-
18
- /**
19
- * Automatically download translations for WC ( when user install WCML ( from 3.3.3) / add new language in WPML )
20
- *
21
- * @param string $lang_code Language code
22
- *
23
- */
24
- function download_woocommerce_translations( $lang_code, $wc_version ){
25
- global $sitepress;
26
-
27
- $locale = $sitepress->get_locale( $lang_code );
28
-
29
- if( $locale != 'en_US' && $this->has_available_update( $locale, $wc_version ) ){
30
-
31
- $wc_version = $wc_version ? $wc_version : WC_VERSION;
32
-
33
- include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
34
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
35
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
36
- require_once( ABSPATH . 'wp-admin/includes/template.php' );
37
-
38
- $url = 'update-core.php?action=do-translation-upgrade';
39
- $nonce = 'upgrade-translations';
40
- $title = '';
41
- $context = WP_LANG_DIR;
42
-
43
- $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
44
-
45
- $upgr_object = array();
46
- $upgr_object[0] = new stdClass();
47
- $upgr_object[0]->type = 'plugin';
48
- $upgr_object[0]->slug = 'woocommerce';
49
- $upgr_object[0]->language = $locale;
50
- $upgr_object[0]->version = $wc_version;
51
- $upgr_object[0]->updated = date('Y-m-d H:i:s');
52
- $upgr_object[0]->package = $this->get_language_pack_uri( $locale, $wc_version );
53
- $upgr_object[0]->autoupdate = 1;
54
-
55
- $ob_level_before = ob_get_level();
56
-
57
- $upgrader->bulk_upgrade( $upgr_object );
58
-
59
- // Close a potential unclosed output buffer
60
- $ob_level_after = ob_get_level();
61
- if( $ob_level_after > $ob_level_before ){
62
- ob_end_clean();
63
- }
64
-
65
-
66
- $this->save_translation_version( $locale, false, $wc_version );
67
- }
68
-
69
- }
70
-
71
-
72
- /*
73
- * Automatically download translations for WC for active languages
74
- *
75
- */
76
- function download_woocommerce_translations_for_active_languages( $wc_version = false ){
77
- global $sitepress, $woocommerce_wpml;
78
-
79
- $active_languages = $sitepress->get_active_languages();
80
-
81
- $current_language = $sitepress->get_current_language();
82
-
83
- foreach( $active_languages as $language ){
84
-
85
- $this->download_woocommerce_translations( $language['code'], $wc_version );
86
-
87
- }
88
-
89
- $sitepress->switch_lang( $current_language );
90
-
91
- if( isset( $woocommerce_wpml->url_translation ) ){
92
- $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
93
- }
94
-
95
- }
96
-
97
-
98
- /*
99
- * Check for WC language updates
100
- *
101
- * @param object $data Transient update data
102
- *
103
- * @return object
104
- */
105
- function check_for_update( $data ){
106
- global $sitepress;
107
-
108
- $active_languages = $sitepress->get_active_languages();
109
- $current_language = $sitepress->get_current_language();
110
-
111
- foreach( $active_languages as $language ){
112
- if( $language['code'] == 'en' )
113
- continue;
114
-
115
- $locale = $sitepress->get_locale( $language['code'] );
116
-
117
- if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
118
-
119
- $data->translations[] = array(
120
- 'type' => 'plugin',
121
- 'slug' => 'woocommerce',
122
- 'language' => $locale,
123
- 'version' => WC_VERSION,
124
- 'updated' => date( 'Y-m-d H:i:s' ),
125
- 'package' => $this->get_language_pack_uri( $locale ),
126
- 'autoupdate' => 1
127
- );
128
-
129
- }
130
-
131
- }
132
-
133
- return $data;
134
- }
135
-
136
-
137
- function get_language_pack_uri( $locale, $version = false ){
138
-
139
- if( !$version ){
140
- $version = WC_VERSION;
141
- }
142
-
143
- if( version_compare( $version, '2.5.0', '<') ){
144
- $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
145
- return $repo . $version . '/packages/' . $locale . '.zip';
146
-
147
- }else{
148
- $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
149
- return $repo . $version . '/' . $locale . '.zip';
150
- }
151
-
152
- }
153
-
154
- /*
155
- * Update the WC language version in database
156
- *
157
- *
158
- * @param bool $reply Whether to bail without returning the package (default: false)
159
- * @param string $package Package URL
160
- *
161
- * @return bool
162
- */
163
- function version_update( $reply, $package ) {
164
-
165
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
166
-
167
- if( !is_array( $notices ) ){
168
- return $reply;
169
- }
170
-
171
- foreach( $notices as $key => $locale){
172
- if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
173
-
174
- $this->save_translation_version( $locale, $key );
175
-
176
- }
177
- }
178
-
179
- return $reply;
180
- }
181
-
182
-
183
- function save_translation_version( $locale, $key = false, $wc_version = false ){
184
-
185
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
186
-
187
- // Update the language pack version
188
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
189
-
190
- if( is_array( $notices ) ){
191
-
192
- if( !$key )
193
- $key = array_search( $locale, $notices );
194
-
195
- // Remove the translation upgrade notice
196
- unset( $notices[ $key ] );
197
-
198
- update_option( 'wcml_translations_upgrade_notice', $notices );
199
-
200
- }
201
-
202
- }
203
-
204
- /*
205
- * Check if has available translation update
206
- *
207
- * @param string $locale Locale code
208
- *
209
- * @return bool
210
- */
211
- function has_available_update( $locale, $wc_version = false ) {
212
- $wc_version = $wc_version ? $wc_version : WC_VERSION;
213
-
214
- $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
215
-
216
- $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
217
- $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
218
-
219
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
220
-
221
- if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
222
- if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
223
-
224
- if( !$notices || !in_array( $locale, $notices )){
225
- $notices[] = $locale;
226
-
227
- update_option( 'wcml_translations_upgrade_notice', $notices );
228
- update_option( 'hide_wcml_translations_message', 0 );
229
- }
230
-
231
- return true;
232
- } else {
233
- // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
234
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
235
- }
236
- }
237
-
238
- return false;
239
- }
240
-
241
-
242
- /**
243
- * Check if language pack exists
244
- *
245
- * @return bool
246
- */
247
- function check_if_language_pack_exists( $locale, $wc_version ) {
248
-
249
- $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
250
-
251
- if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
252
- return true;
253
- } else {
254
- return false;
255
- }
256
- }
257
-
258
-
259
- /*
260
- * Display Translations upgrade notice message
261
- */
262
- function translation_upgrade_notice(){
263
- global $woocommerce_wpml;
264
-
265
- $screen = get_current_screen();
266
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
267
-
268
- if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
269
-
270
- $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
271
- $lang_notices->show();
272
- }
273
- }
274
-
275
- /*
276
- * Hide Translations upgrade notice message ( update option in DB )
277
- */
278
- function hide_wcml_translations_message(){
279
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
280
- if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
281
- die('Invalid nonce');
282
- }
283
- update_option( 'hide_wcml_translations_message', true );
284
-
285
- die();
286
- }
287
-
288
- public function load_js(){
289
-
290
- wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
291
- wp_enqueue_script( 'wcml-lang-notice');
292
-
293
- wp_localize_script( 'wcml-lang-notice', 'wcml_settings',
294
- array(
295
- 'warn' => __( "Downloading translations... Please don't close this page.", 'woocommerce-multilingual' )
296
- )
297
- );
298
-
299
- }
300
-
301
  }
1
+ <?php
2
+
3
+ class WCML_Languages_Upgrader{
4
+
5
+
6
+
7
+ function __construct(){
8
+
9
+ add_action( 'icl_update_active_languages', array( $this, 'download_woocommerce_translations_for_active_languages' ) );
10
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_update' ), 11 );
11
+ add_filter( 'upgrader_pre_download', array( $this, 'version_update' ), 10, 2 );
12
+ add_action( 'admin_notices', array( $this, 'translation_upgrade_notice' ) );
13
+ add_action( 'wp_ajax_hide_wcml_translations_message', array($this, 'hide_wcml_translations_message') );
14
+
15
+ $this->load_js();
16
+ }
17
+
18
+ /**
19
+ * Automatically download translations for WC ( when user install WCML ( from 3.3.3) / add new language in WPML )
20
+ *
21
+ * @param string $lang_code Language code
22
+ *
23
+ */
24
+ function download_woocommerce_translations( $lang_code, $wc_version ){
25
+ global $sitepress;
26
+
27
+ $locale = $sitepress->get_locale( $lang_code );
28
+
29
+ if( $locale != 'en_US' && $this->has_available_update( $locale, $wc_version ) ){
30
+
31
+ $wc_version = $wc_version ? $wc_version : WC_VERSION;
32
+
33
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
34
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
35
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
36
+ require_once( ABSPATH . 'wp-admin/includes/template.php' );
37
+
38
+ $url = 'update-core.php?action=do-translation-upgrade';
39
+ $nonce = 'upgrade-translations';
40
+ $title = '';
41
+ $context = WP_LANG_DIR;
42
+
43
+ $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
44
+
45
+ $upgr_object = array();
46
+ $upgr_object[0] = new stdClass();
47
+ $upgr_object[0]->type = 'plugin';
48
+ $upgr_object[0]->slug = 'woocommerce';
49
+ $upgr_object[0]->language = $locale;
50
+ $upgr_object[0]->version = $wc_version;
51
+ $upgr_object[0]->updated = date('Y-m-d H:i:s');
52
+ $upgr_object[0]->package = $this->get_language_pack_uri( $locale, $wc_version );
53
+ $upgr_object[0]->autoupdate = 1;
54
+
55
+ $ob_level_before = ob_get_level();
56
+
57
+ $upgrader->bulk_upgrade( $upgr_object );
58
+
59
+ // Close a potential unclosed output buffer
60
+ $ob_level_after = ob_get_level();
61
+ if( $ob_level_after > $ob_level_before ){
62
+ ob_end_clean();
63
+ }
64
+
65
+
66
+ $this->save_translation_version( $locale, false, $wc_version );
67
+ }
68
+
69
+ }
70
+
71
+
72
+ /*
73
+ * Automatically download translations for WC for active languages
74
+ *
75
+ */
76
+ function download_woocommerce_translations_for_active_languages( $wc_version = false ){
77
+ global $sitepress, $woocommerce_wpml;
78
+
79
+ $active_languages = $sitepress->get_active_languages();
80
+
81
+ $current_language = $sitepress->get_current_language();
82
+
83
+ foreach( $active_languages as $language ){
84
+
85
+ $this->download_woocommerce_translations( $language['code'], $wc_version );
86
+
87
+ }
88
+
89
+ $sitepress->switch_lang( $current_language );
90
+
91
+ if( isset( $woocommerce_wpml->url_translation ) ){
92
+ $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
93
+ }
94
+
95
+ }
96
+
97
+
98
+ /*
99
+ * Check for WC language updates
100
+ *
101
+ * @param object $data Transient update data
102
+ *
103
+ * @return object
104
+ */
105
+ function check_for_update( $data ){
106
+ global $sitepress;
107
+
108
+ $active_languages = $sitepress->get_active_languages();
109
+ $current_language = $sitepress->get_current_language();
110
+
111
+ foreach( $active_languages as $language ){
112
+ if( $language['code'] == 'en' )
113
+ continue;
114
+
115
+ $locale = $sitepress->get_locale( $language['code'] );
116
+
117
+ if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
118
+
119
+ $data->translations[] = array(
120
+ 'type' => 'plugin',
121
+ 'slug' => 'woocommerce',
122
+ 'language' => $locale,
123
+ 'version' => WC_VERSION,
124
+ 'updated' => date( 'Y-m-d H:i:s' ),
125
+ 'package' => $this->get_language_pack_uri( $locale ),
126
+ 'autoupdate' => 1
127
+ );
128
+
129
+ }
130
+
131
+ }
132
+
133
+ return $data;
134
+ }
135
+
136
+
137
+ function get_language_pack_uri( $locale, $version = false ){
138
+
139
+ if( !$version ){
140
+ $version = WC_VERSION;
141
+ }
142
+
143
+ if( version_compare( $version, '2.5.0', '<') ){
144
+ $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
145
+ return $repo . $version . '/packages/' . $locale . '.zip';
146
+
147
+ }else{
148
+ $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
149
+ return $repo . $version . '/' . $locale . '.zip';
150
+ }
151
+
152
+ }
153
+
154
+ /*
155
+ * Update the WC language version in database
156
+ *
157
+ *
158
+ * @param bool $reply Whether to bail without returning the package (default: false)
159
+ * @param string $package Package URL
160
+ *
161
+ * @return bool
162
+ */
163
+ function version_update( $reply, $package ) {
164
+
165
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
166
+
167
+ if( !is_array( $notices ) ){
168
+ return $reply;
169
+ }
170
+
171
+ foreach( $notices as $key => $locale){
172
+ if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
173
+
174
+ $this->save_translation_version( $locale, $key );
175
+
176
+ }
177
+ }
178
+
179
+ return $reply;
180
+ }
181
+
182
+
183
+ function save_translation_version( $locale, $key = false, $wc_version = false ){
184
+
185
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
186
+
187
+ // Update the language pack version
188
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
189
+
190
+ if( is_array( $notices ) ){
191
+
192
+ if( !$key )
193
+ $key = array_search( $locale, $notices );
194
+
195
+ // Remove the translation upgrade notice
196
+ unset( $notices[ $key ] );
197
+
198
+ update_option( 'wcml_translations_upgrade_notice', $notices );
199
+
200
+ }
201
+
202
+ }
203
+
204
+ /*
205
+ * Check if has available translation update
206
+ *
207
+ * @param string $locale Locale code
208
+ *
209
+ * @return bool
210
+ */
211
+ function has_available_update( $locale, $wc_version = false ) {
212
+ $wc_version = $wc_version ? $wc_version : WC_VERSION;
213
+
214
+ $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
215
+
216
+ $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
217
+ $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
218
+
219
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
220
+
221
+ if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
222
+ if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
223
+
224
+ if( !$notices || !in_array( $locale, $notices )){
225
+ $notices[] = $locale;
226
+
227
+ update_option( 'wcml_translations_upgrade_notice', $notices );
228
+ update_option( 'hide_wcml_translations_message', 0 );
229
+ }
230
+
231
+ return true;
232
+ } else {
233
+ // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
234
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
235
+ }
236
+ }
237
+
238
+ return false;
239
+ }
240
+
241
+
242
+ /**
243
+ * Check if language pack exists
244
+ *
245
+ * @return bool
246
+ */
247
+ function check_if_language_pack_exists( $locale, $wc_version ) {
248
+
249
+ $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
250
+
251
+ if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
252
+ return true;
253
+ } else {
254
+ return false;
255
+ }
256
+ }
257
+
258
+
259
+ /*
260
+ * Display Translations upgrade notice message
261
+ */
262
+ function translation_upgrade_notice(){
263
+ global $woocommerce_wpml;
264
+
265
+ $screen = get_current_screen();
266
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
267
+
268
+ if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
269
+
270
+ $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
271
+ $lang_notices->show();
272
+ }
273
+ }
274
+
275
+ /*
276
+ * Hide Translations upgrade notice message ( update option in DB )
277
+ */
278
+ function hide_wcml_translations_message(){
279
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
280
+ if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
281
+ die('Invalid nonce');
282
+ }
283
+ update_option( 'hide_wcml_translations_message', true );
284
+
285
+ die();
286
+ }
287
+
288
+ public function load_js(){
289
+
290
+ wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
291
+ wp_enqueue_script( 'wcml-lang-notice');
292
+
293
+ wp_localize_script( 'wcml-lang-notice', 'wcml_settings',
294
+ array(
295
+ 'warn' => __( "Downloading translations... Please don't close this page.", 'woocommerce-multilingual' )
296
+ )
297
+ );
298
+
299
+ }
300
+
301
  }
inc/class-wcml-locale.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
-
3
- class WCML_Locale{
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
-
8
- public function __construct( &$woocommerce_wpml, &$sitepress ){
9
- $this->woocommerce_wpml = $woocommerce_wpml;
10
- $this->sitepress = $sitepress;
11
-
12
- $this->load_locale();
13
-
14
- add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
15
- add_action( 'woocommerce_email', array( $this, 'woocommerce_email_refresh_text_domain' ) );
16
- add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
17
- add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
18
-
19
- }
20
-
21
- function load_locale(){
22
- return load_plugin_textdomain( 'woocommerce-multilingual', false, WCML_PLUGIN_FOLDER.'/locale' );
23
- }
24
-
25
- public function switch_locale( $lang_code = false ) {
26
- global $l10n;
27
- static $original_l10n;
28
- if ( ! empty( $lang_code ) ) {
29
- $original_l10n = isset( $l10n[ 'woocommerce-multilingual' ] ) ? $l10n[ 'woocommerce-multilingual' ] : null;
30
- if ( $original_l10n !== null ) {
31
- unset( $l10n[ 'woocommerce-multilingual' ] );
32
- }
33
- return load_textdomain( 'woocommerce-multilingual',
34
- WCML_LOCALE_PATH . '/woocommerce-multilingual-' . $this->sitepress->get_locale( $lang_code ) . '.mo' );
35
-
36
- } else { // switch back
37
- $l10n[ 'woocommerce-multilingual' ] = $original_l10n;
38
- }
39
- }
40
-
41
- /* Change locale to saving language - needs for sanitize_title exception wcml-390 */
42
- public function update_product_action_locale_check( $locale ){
43
- if( isset($_POST['action']) && $_POST['action'] == 'wpml_translation_dialog_save_job' ){
44
- return $this->sitepress->get_locale( $_POST[ 'job_details' ][ 'target' ] );
45
- }
46
- return $locale;
47
- }
48
-
49
- public function woocommerce_email_refresh_text_domain(){
50
- if( !isset( $_GET[ 'page' ] ) || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] != 'wc-settings' ) ){
51
- $this->wcml_refresh_text_domain();
52
- }
53
- }
54
-
55
- public function wcml_refresh_text_domain(){
56
- global $woocommerce;
57
- $domain = 'woocommerce';
58
- unload_textdomain( $domain );
59
- $woocommerce->load_plugin_textdomain();
60
- }
61
-
62
  }
1
+ <?php
2
+
3
+ class WCML_Locale{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+
8
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
9
+ $this->woocommerce_wpml = $woocommerce_wpml;
10
+ $this->sitepress = $sitepress;
11
+
12
+ $this->load_locale();
13
+
14
+ add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
15
+ add_action( 'woocommerce_email', array( $this, 'woocommerce_email_refresh_text_domain' ) );
16
+ add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
17
+ add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
18
+
19
+ }
20
+
21
+ function load_locale(){
22
+ return load_plugin_textdomain( 'woocommerce-multilingual', false, WCML_PLUGIN_FOLDER.'/locale' );
23
+ }
24
+
25
+ public function switch_locale( $lang_code = false ) {
26
+ global $l10n;
27
+ static $original_l10n;
28
+ if ( ! empty( $lang_code ) ) {
29
+ $original_l10n = isset( $l10n[ 'woocommerce-multilingual' ] ) ? $l10n[ 'woocommerce-multilingual' ] : null;
30
+ if ( $original_l10n !== null ) {
31
+ unset( $l10n[ 'woocommerce-multilingual' ] );
32
+ }
33
+ return load_textdomain( 'woocommerce-multilingual',
34
+ WCML_LOCALE_PATH . '/woocommerce-multilingual-' . $this->sitepress->get_locale( $lang_code ) . '.mo' );
35
+
36
+ } else { // switch back
37
+ $l10n[ 'woocommerce-multilingual' ] = $original_l10n;
38
+ }
39
+ }
40
+
41
+ /* Change locale to saving language - needs for sanitize_title exception wcml-390 */
42
+ public function update_product_action_locale_check( $locale ){
43
+ if( isset($_POST['action']) && $_POST['action'] == 'wpml_translation_dialog_save_job' ){
44
+ return $this->sitepress->get_locale( $_POST[ 'job_details' ][ 'target' ] );
45
+ }
46
+ return $locale;
47
+ }
48
+
49
+ public function woocommerce_email_refresh_text_domain(){
50
+ if( !isset( $_GET[ 'page' ] ) || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] != 'wc-settings' ) ){
51
+ $this->wcml_refresh_text_domain();
52
+ }
53
+ }
54
+
55
+ public function wcml_refresh_text_domain(){
56
+ global $woocommerce;
57
+ $domain = 'woocommerce';
58
+ unload_textdomain( $domain );
59
+ $woocommerce->load_plugin_textdomain();
60
+ }
61
+
62
  }
inc/class-wcml-media.php CHANGED
@@ -1,184 +1,184 @@
1
- <?php
2
-
3
- class WCML_Media{
4
-
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var SitePress */
8
- private $sitepress;
9
- /** @var wpdb */
10
- private $wpdb;
11
-
12
- public $settings = array();
13
-
14
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
15
-
16
- $this->woocommerce_wpml =& $woocommerce_wpml;
17
- $this->sitepress =& $sitepress;
18
- $this->wpdb =& $wpdb;
19
-
20
- $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
21
- $this->settings['translate_media'] = $wpml_media_options['new_content_settings']['always_translate_media'];
22
- $this->settings['duplicate_media'] = $wpml_media_options['new_content_settings']['duplicate_media'];
23
- $this->settings['duplicate_featured'] = $wpml_media_options['new_content_settings']['duplicate_featured'];
24
-
25
- //remove media sync on product page
26
- add_action( 'admin_head', array( $this, 'remove_language_options' ), 11 );
27
-
28
- //when save new attachment duplicate product gallery
29
- add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'sync_product_gallery_duplicate_attachment' ), 11, 2 );
30
- add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
31
- }
32
-
33
- public function sync_feature_product_meta(){
34
-
35
- if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) ) {
36
- $product_id = absint( $_GET[ 'product_id' ] );
37
-
38
- if ( 'product' === get_post_type( $product_id ) && $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
39
- $value = get_post_meta( $product_id, '_featured', true ) === 'yes' ? 'no' : 'yes';
40
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
41
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
42
- foreach( $translations as $translation ){
43
- if ( !$translation->original ) {
44
- update_post_meta( $translation->element_id, '_featured', $value );
45
- }
46
- }
47
- }
48
- }
49
- }
50
-
51
- public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ){
52
- if( defined( 'WPML_MEDIA_VERSION' ) ){
53
- $thumbnail_id = get_post_meta( $orig_post_id, '_thumbnail_id', true );
54
- $trnsl_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
55
- if( is_null( $trnsl_thumbnail ) && $thumbnail_id ){
56
- $trnsl_thumbnail = WPML_Media::create_duplicate_attachment( $thumbnail_id, wp_get_post_parent_id( $thumbnail_id ), $lang );
57
- }
58
-
59
- update_post_meta( $trnsl_post_id, '_thumbnail_id', $trnsl_thumbnail );
60
- update_post_meta( $orig_post_id, '_wpml_media_duplicate', 1 );
61
- update_post_meta( $orig_post_id, '_wpml_media_featured', 1 );
62
- }
63
- }
64
-
65
- public function sync_product_gallery( $product_id ){
66
- if( !defined( 'WPML_MEDIA_VERSION' ) ){
67
- return;
68
- }
69
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
70
- $gallery_ids = explode( ',', $product_gallery );
71
-
72
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
73
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
74
- foreach( $translations as $translation ){
75
- $duplicated_ids = '';
76
- if ( !$translation->original ) {
77
- foreach( $gallery_ids as $image_id ){
78
- if( get_post( $image_id ) ) {
79
- $duplicated_id = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $translation->language_code );
80
- if ( is_null( $duplicated_id ) && $image_id ) {
81
- $duplicated_id = WPML_Media::create_duplicate_attachment( $image_id, wp_get_post_parent_id( $image_id ), $translation->language_code );
82
- }
83
- $duplicated_ids .= $duplicated_id . ',';
84
- }
85
- }
86
- $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
87
- update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
88
- }
89
- }
90
- }
91
-
92
- public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ){
93
- $product_id = wp_get_post_parent_id( $att_id );
94
- $post_type = get_post_type( $product_id );
95
- if( $post_type != 'product' ){
96
- return;
97
- }
98
- $this->sync_product_gallery( $product_id );
99
- }
100
-
101
- public function product_images_ids( $product_id ){
102
- $product_images_ids = array();
103
-
104
- //thumbnail image
105
- $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
106
- if( $tmb ) {
107
- $product_images_ids[] = $tmb;
108
- }
109
-
110
- //product gallery
111
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
112
- if( $product_gallery ) {
113
- $product_gallery = explode( ',', $product_gallery );
114
- foreach( $product_gallery as $img ){
115
- if( !in_array( $img, $product_images_ids ) ){
116
- $product_images_ids[] = $img;
117
- }
118
- }
119
- }
120
-
121
- foreach( wp_get_post_terms( $product_id, 'product_type', array( "fields" => "names" ) ) as $type ){
122
- $product_type = $type;
123
- }
124
-
125
- if( isset( $product_type ) && $product_type == 'variable' ){
126
- $get_post_variations_image = $this->wpdb->get_col(
127
- $this->wpdb->prepare(
128
- "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
129
- LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
130
- WHERE pm.meta_key='_thumbnail_id'
131
- AND p.post_status IN ('publish','private')
132
- AND p.post_type = 'product_variation'
133
- AND p.post_parent = %d
134
- ORDER BY ID", $product_id )
135
- );
136
- foreach( $get_post_variations_image as $variation_image ){
137
- if( $variation_image && !in_array( $variation_image, $product_images_ids ) ){
138
- $product_images_ids[] = $variation_image;
139
- }
140
- }
141
- }
142
-
143
- foreach( $product_images_ids as $key => $image ){
144
- if( ! get_post_status ( $image ) ){
145
- unset( $product_images_ids[ $key ] );
146
- }
147
- }
148
-
149
- return $product_images_ids;
150
- }
151
-
152
- public function exclude_not_duplicated_attachments( &$product_images, $product_id ){
153
-
154
- $thumbnail_id = get_post_meta( $product_id, '_thumbnail_id', true );
155
-
156
- if ( empty( $this->settings[ 'duplicate_media' ] ) ) {
157
- $product_images = $thumbnail_id ? array( $thumbnail_id ) : array();
158
- }
159
-
160
- $key = $thumbnail_id ? array_search( $thumbnail_id, $product_images ) : false;
161
- if( false !== $key && empty( $this->settings[ 'duplicate_featured' ] ) ){
162
- unset( $product_images[$key] );
163
- }
164
-
165
- return $product_images;
166
- }
167
-
168
- public function remove_language_options(){
169
- global $WPML_media, $typenow;
170
- if( defined( 'WPML_MEDIA_VERSION' ) && $typenow == 'product' ){
171
- remove_action( 'icl_post_languages_options_after', array( $WPML_media, 'language_options' ) );
172
- add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
173
- }
174
- }
175
-
176
- public function media_inputs(){
177
- $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
178
-
179
- echo '<input name="icl_duplicate_attachments" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_media' ].'" />';
180
- echo '<input name="icl_duplicate_featured_image" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_featured' ].'" />';
181
- }
182
-
183
-
184
  }
1
+ <?php
2
+
3
+ class WCML_Media{
4
+
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var SitePress */
8
+ private $sitepress;
9
+ /** @var wpdb */
10
+ private $wpdb;
11
+
12
+ public $settings = array();
13
+
14
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
15
+
16
+ $this->woocommerce_wpml =& $woocommerce_wpml;
17
+ $this->sitepress =& $sitepress;
18
+ $this->wpdb =& $wpdb;
19
+
20
+ $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
21
+ $this->settings['translate_media'] = $wpml_media_options['new_content_settings']['always_translate_media'];
22
+ $this->settings['duplicate_media'] = $wpml_media_options['new_content_settings']['duplicate_media'];
23
+ $this->settings['duplicate_featured'] = $wpml_media_options['new_content_settings']['duplicate_featured'];
24
+
25
+ //remove media sync on product page
26
+ add_action( 'admin_head', array( $this, 'remove_language_options' ), 11 );
27
+
28
+ //when save new attachment duplicate product gallery
29
+ add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'sync_product_gallery_duplicate_attachment' ), 11, 2 );
30
+ add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
31
+ }
32
+
33
+ public function sync_feature_product_meta(){
34
+
35
+ if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) ) {
36
+ $product_id = absint( $_GET[ 'product_id' ] );
37
+
38
+ if ( 'product' === get_post_type( $product_id ) && $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
39
+ $value = get_post_meta( $product_id, '_featured', true ) === 'yes' ? 'no' : 'yes';
40
+ $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
41
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
42
+ foreach( $translations as $translation ){
43
+ if ( !$translation->original ) {
44
+ update_post_meta( $translation->element_id, '_featured', $value );
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ){
52
+ if( defined( 'WPML_MEDIA_VERSION' ) ){
53
+ $thumbnail_id = get_post_meta( $orig_post_id, '_thumbnail_id', true );
54
+ $trnsl_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
55
+ if( is_null( $trnsl_thumbnail ) && $thumbnail_id ){
56
+ $trnsl_thumbnail = WPML_Media::create_duplicate_attachment( $thumbnail_id, wp_get_post_parent_id( $thumbnail_id ), $lang );
57
+ }
58
+
59
+ update_post_meta( $trnsl_post_id, '_thumbnail_id', $trnsl_thumbnail );
60
+ update_post_meta( $orig_post_id, '_wpml_media_duplicate', 1 );
61
+ update_post_meta( $orig_post_id, '_wpml_media_featured', 1 );
62
+ }
63
+ }
64
+
65
+ public function sync_product_gallery( $product_id ){
66
+ if( !defined( 'WPML_MEDIA_VERSION' ) ){
67
+ return;
68
+ }
69
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
70
+ $gallery_ids = explode( ',', $product_gallery );
71
+
72
+ $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
73
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
74
+ foreach( $translations as $translation ){
75
+ $duplicated_ids = '';
76
+ if ( !$translation->original ) {
77
+ foreach( $gallery_ids as $image_id ){
78
+ if( get_post( $image_id ) ) {
79
+ $duplicated_id = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $translation->language_code );
80
+ if ( is_null( $duplicated_id ) && $image_id ) {
81
+ $duplicated_id = WPML_Media::create_duplicate_attachment( $image_id, wp_get_post_parent_id( $image_id ), $translation->language_code );
82
+ }
83
+ $duplicated_ids .= $duplicated_id . ',';
84
+ }
85
+ }
86
+ $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
87
+ update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
88
+ }
89
+ }
90
+ }
91
+
92
+ public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ){
93
+ $product_id = wp_get_post_parent_id( $att_id );
94
+ $post_type = get_post_type( $product_id );
95
+ if( $post_type != 'product' ){
96
+ return;
97
+ }
98
+ $this->sync_product_gallery( $product_id );
99
+ }
100
+
101
+ public function product_images_ids( $product_id ){
102
+ $product_images_ids = array();
103
+
104
+ //thumbnail image
105
+ $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
106
+ if( $tmb ) {
107
+ $product_images_ids[] = $tmb;
108
+ }
109
+
110
+ //product gallery
111
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
112
+ if( $product_gallery ) {
113
+ $product_gallery = explode( ',', $product_gallery );
114
+ foreach( $product_gallery as $img ){
115
+ if( !in_array( $img, $product_images_ids ) ){
116
+ $product_images_ids[] = $img;
117
+ }
118
+ }
119
+ }
120
+
121
+ foreach( wp_get_post_terms( $product_id, 'product_type', array( "fields" => "names" ) ) as $type ){
122
+ $product_type = $type;
123
+ }
124
+
125
+ if( isset( $product_type ) && $product_type == 'variable' ){
126
+ $get_post_variations_image = $this->wpdb->get_col(
127
+ $this->wpdb->prepare(
128
+ "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
129
+ LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
130
+ WHERE pm.meta_key='_thumbnail_id'
131
+ AND p.post_status IN ('publish','private')
132
+ AND p.post_type = 'product_variation'
133
+ AND p.post_parent = %d
134
+ ORDER BY ID", $product_id )
135
+ );
136
+ foreach( $get_post_variations_image as $variation_image ){
137
+ if( $variation_image && !in_array( $variation_image, $product_images_ids ) ){
138
+ $product_images_ids[] = $variation_image;
139
+ }
140
+ }
141
+ }
142
+
143
+ foreach( $product_images_ids as $key => $image ){
144
+ if( ! get_post_status ( $image ) ){
145
+ unset( $product_images_ids[ $key ] );
146
+ }
147
+ }
148
+
149
+ return $product_images_ids;
150
+ }
151
+
152
+ public function exclude_not_duplicated_attachments( &$product_images, $product_id ){
153
+
154
+ $thumbnail_id = get_post_meta( $product_id, '_thumbnail_id', true );
155
+
156
+ if ( empty( $this->settings[ 'duplicate_media' ] ) ) {
157
+ $product_images = $thumbnail_id ? array( $thumbnail_id ) : array();
158
+ }
159
+
160
+ $key = $thumbnail_id ? array_search( $thumbnail_id, $product_images ) : false;
161
+ if( false !== $key && empty( $this->settings[ 'duplicate_featured' ] ) ){
162
+ unset( $product_images[$key] );
163
+ }
164
+
165
+ return $product_images;
166
+ }
167
+
168
+ public function remove_language_options(){
169
+ global $WPML_media, $typenow;
170
+ if( defined( 'WPML_MEDIA_VERSION' ) && $typenow == 'product' ){
171
+ remove_action( 'icl_post_languages_options_after', array( $WPML_media, 'language_options' ) );
172
+ add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
173
+ }
174
+ }
175
+
176
+ public function media_inputs(){
177
+ $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
178
+
179
+ echo '<input name="icl_duplicate_attachments" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_media' ].'" />';
180
+ echo '<input name="icl_duplicate_featured_image" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_featured' ].'" />';
181
+ }
182
+
183
+
184
  }
inc/class-wcml-orders.php CHANGED
@@ -1,381 +1,381 @@
1
- <?php
2
- class WCML_Orders{
3
-
4
- private $woocommerce_wpml;
5
- private $sitepress;
6
-
7
- private $standart_order_notes = array('Order status changed from %s to %s.',
8
- 'Order item stock reduced successfully.','Item #%s stock reduced from %s to %s.','Item #%s stock increased from %s to %s.','Awaiting BACS payment','Awaiting cheque payment','Payment to be made upon delivery.',
9
- 'Validation error: PayPal amounts do not match (gross %s).','Validation error: PayPal IPN response from a different email address (%s).','Payment pending: %s',
10
- 'Payment %s via IPN.','Validation error: PayPal amounts do not match (amt %s).','IPN payment completed','PDT payment completed'
11
- );
12
-
13
- public function __construct( &$woocommerce_wpml, &$sitepress ){
14
- $this->woocommerce_wpml = $woocommerce_wpml;
15
- $this->sitepress = $sitepress;
16
-
17
- add_action('init', array($this, 'init'));
18
-
19
- //checkout page
20
- add_action( 'wp_ajax_woocommerce_checkout',array($this,'switch_to_current'),9);
21
- add_action( 'wp_ajax_nopriv_woocommerce_checkout',array($this,'switch_to_current'),9);
22
-
23
- add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
24
- }
25
-
26
- function init(){
27
-
28
- add_action('woocommerce_shipping_update_ajax', array($this, 'fix_shipping_update'));
29
- add_action('woocommerce_checkout_update_order_meta', array($this, 'set_order_language'));
30
-
31
- add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
32
-
33
- add_filter('the_comments', array($this, 'get_filtered_comments'));
34
- add_filter('gettext',array($this, 'filtered_woocommerce_new_order_note_data'),10,3);
35
-
36
- add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
37
-
38
- add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_language_backend'), 10, 2 );
39
- add_action( 'woocommerce_order_actions_start', array( $this, 'order_language_dropdown' ), 11 ); //after order currency drop-down
40
-
41
- //special case for wcml-741
42
- add_action('updated_post_meta', array($this,'update_order_currency'), 100,4);
43
-
44
- add_action( 'woocommerce_before_order_itemmeta', array( $this, 'backend_before_order_itemmeta' ), 100, 3 );
45
- add_action( 'woocommerce_after_order_itemmeta', array( $this, 'backend_after_order_itemmeta' ), 100, 3 );
46
-
47
- }
48
-
49
- function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
50
- if(in_array($text,$this->standart_order_notes)){
51
-
52
- $language = $this->woocommerce_wpml->strings->get_string_language( $text, 'woocommerce' );
53
-
54
- if( $this->sitepress->get_user_admin_language( get_current_user_id(), true ) != $language ){
55
-
56
- $string_id = icl_get_string_id( $text, 'woocommerce');
57
- $strings = icl_get_string_translations_by_id( $string_id );
58
- if($strings){
59
- $translations = $strings[ $this->sitepress->get_user_admin_language( get_current_user_id(), true ) ]['value'];
60
- }
61
-
62
- }else{
63
- return $text;
64
- }
65
- }
66
-
67
- return $translations;
68
- }
69
-
70
- function get_filtered_comments($comments){
71
-
72
- $user_id = get_current_user_id();
73
-
74
- if( $user_id ){
75
-
76
- $user_language = get_user_meta( $user_id, 'icl_admin_language', true );
77
-
78
- foreach($comments as $key=>$comment){
79
-
80
- $comment_string_id = icl_get_string_id( $comment->comment_content, 'woocommerce');
81
-
82
- if($comment_string_id){
83
- $comment_strings = icl_get_string_translations_by_id( $comment_string_id );
84
- if($comment_strings){
85
- $comments[$key]->comment_content = $comment_strings[$user_language]['value'];
86
- }
87
- }
88
- }
89
-
90
- }
91
-
92
- return $comments;
93
-
94
- }
95
-
96
- function woocommerce_order_get_items( $items, $order ){
97
-
98
- if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ) {
99
- // on order edit page use admin default language
100
- $language_to_filter = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
101
- }elseif( isset( $_GET[ 'action' ] ) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status' || $_GET['action'] == 'mark_processing') ){
102
- //backward compatibility for WC < 2.7
103
- $order_id = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
104
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
105
- $language_to_filter = $order_language ? $order_language : $this->sitepress->get_default_language();
106
- }else{
107
- $language_to_filter = $this->sitepress->get_current_language();
108
- }
109
-
110
- foreach( $items as $index => $item ){
111
- if( is_array( $item ) ){
112
- // WC < 2.7
113
- foreach( $item as $key => $item_data ){
114
- if( $key == 'product_id' ){
115
- $tr_product_id = apply_filters( 'translate_object_id', $item_data, 'product', false, $language_to_filter );
116
- if( !is_null( $tr_product_id ) ){
117
- $items[ $index ][ $key ] = $tr_product_id;
118
- $items[ $index ][ 'name'] = get_post( $tr_product_id )->post_title;
119
- }
120
- }
121
- if( $key == 'variation_id' ){
122
- $tr_variation_id = apply_filters( 'translate_object_id', $item_data, 'product_variation', false, $language_to_filter );
123
- if( !is_null($tr_variation_id)){
124
- $items[$index][$key] = $tr_variation_id;
125
- }
126
- }
127
-
128
- if (substr($key, 0, 3) == 'pa_') {
129
- //attr is taxonomy
130
-
131
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $key, $item_data );
132
- $tr_id = apply_filters( 'translate_object_id', $term_id, $key, false, $language_to_filter );
133
-
134
- if(!is_null($tr_id)){
135
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $key);
136
- $items[$index][$key] = $translated_term->slug;
137
- }
138
- }
139
-
140
- if( $key == 'type' && $item_data == 'shipping' && isset( $item[ 'method_id' ] ) ){
141
-
142
- $items[ $index ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $language_to_filter );
143
-
144
- }
145
- }
146
- }else{
147
- // WC >= 2.7
148
- if( $item instanceof WC_Order_Item_Product ){
149
- if( $item->get_type() == 'line_item' ){
150
- $item_product_id = $item->get_product_id();
151
- if( get_post_type( $item_product_id ) == 'product_variation' ){
152
- $item_product_id = wp_get_post_parent_id( $item_product_id );
153
- }
154
-
155
- $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
156
- if( !is_null( $tr_product_id ) ){
157
- $item->set_product_id( $tr_product_id );
158
- $item->set_name( get_post( $tr_product_id )->post_title );
159
- }
160
- $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
161
- if( !is_null( $tr_variation_id ) ){
162
- $item->set_variation_id( $tr_variation_id );
163
- }
164
-
165
- $meta_data = array();
166
- foreach( $item->get_meta_data() as $data ){
167
-
168
- if( substr( $data->key, 0, 3) == 'pa_' ){
169
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $data->key, $data->value );
170
- $tr_id = apply_filters( 'translate_object_id', $term_id, $data->key, false, $language_to_filter );
171
-
172
- if(!is_null($tr_id)){
173
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $data->key);
174
- $data->value = $translated_term->slug;
175
- }
176
- }
177
-
178
- $meta_data[] = $data;
179
-
180
- }
181
- }
182
- }elseif( $item instanceof WC_Order_Item_Shipping ){
183
- if( $item->get_method_id() ){
184
- $item->set_method_title( $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item->get_method_title(), $item->get_method_id(), $language_to_filter ) );
185
- }
186
- }
187
- }
188
- }
189
-
190
- return $items;
191
-
192
- }
193
-
194
- public function backend_before_order_itemmeta( $item_id, $item, $product ){
195
- global $sitepress;
196
-
197
- if( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
198
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
199
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
200
- //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
201
- if( !is_array( $item_meta ) ){
202
- $item_meta = array( $item_meta );
203
- }
204
-
205
- foreach( $item_meta as $value ){
206
- $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
207
- }
208
- }
209
- }
210
- }
211
- }
212
-
213
- public function backend_after_order_itemmeta( $item_id, $item, $product ){
214
- global $sitepress;
215
-
216
- $order_languge = $this->get_order_language_by_item_id( $item_id );
217
- if( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
218
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
219
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
220
- //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
221
- if( !is_array( $item_meta ) ){
222
- $item_meta = array( $item_meta );
223
- }
224
-
225
- foreach( $item_meta as $value ){
226
- $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
227
- }
228
- }
229
- }
230
- }
231
- }
232
-
233
- public function get_order_language_by_item_id( $item_id ){
234
- global $wpdb;
235
-
236
- $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
237
-
238
- return get_post_meta( $order_id, 'wpml_language', true );
239
- }
240
-
241
- //force update to display attribute in correct language on edit order page
242
- public function force_update_itemmeta( $item_id, $key, $value, $languge ){
243
- global $wpdb, $woocommerce_wpml;
244
-
245
- $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
246
- $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
247
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
248
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
249
-
250
- if( $translated_term ){
251
- $value = $translated_term->slug;
252
- $wpdb->update( $wpdb->prefix.'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array( 'order_item_id' => $item_id, 'meta_key' => $key ) );
253
- }
254
- }
255
-
256
- // Fix for shipping update on the checkout page.
257
- function fix_shipping_update($amount){
258
- global $sitepress, $post;
259
-
260
- if($sitepress->get_current_language() !== $sitepress->get_default_language() && $post->ID == $this->checkout_page_id()){
261
-
262
- $_SESSION['icl_checkout_shipping_amount'] = $amount;
263
-
264
- $amount = $_SESSION['icl_checkout_shipping_amount'];
265
-
266
- }
267
-
268
- return $amount;
269
- }
270
-
271
-
272
- /**
273
- * Adds language to order post type.
274
- *
275
- * Language was stored in the session created on checkout page.
276
- * See params().
277
- *
278
- * @param type $order_id
279
- */
280
- function set_order_language($order_id) {
281
- if(!get_post_meta($order_id, 'wpml_language')){
282
- $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
283
- update_post_meta($order_id, 'wpml_language', $language);
284
- }
285
- }
286
-
287
- function append_query_parameters($parameters){
288
-
289
- if(is_order_received_page() || is_checkout()){
290
- if(!in_array('order', $parameters)) $parameters[] = 'order';
291
- if(!in_array('key', $parameters)) $parameters[] = 'key';
292
- }
293
-
294
- return $parameters;
295
- }
296
-
297
- function switch_to_current(){
298
- $this->woocommerce_wpml->emails->change_email_language($this->sitepress->get_current_language());
299
- }
300
-
301
- function order_language_dropdown( $order_id ){
302
- if( !get_post_meta( $order_id, '_order_currency') ) {
303
- $languages = apply_filters( 'wpml_active_languages', array(), array( 'skip_missing' => 0, 'orderby' => 'code' ) );
304
- $selected_lang = isset( $_COOKIE [ '_wcml_dashboard_order_language' ] ) ? $_COOKIE [ '_wcml_dashboard_order_language' ] : $this->sitepress->get_default_language();
305
- ?>
306
- <li class="wide">
307
- <label><?php _e('Order language:'); ?></label>
308
- <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
309
- <?php if (!empty($languages)): ?>
310
-
311
- <?php foreach ($languages as $l): ?>
312
-
313
- <option
314
- value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
315
-
316
- <?php endforeach; ?>
317
-
318
- <?php endif; ?>
319
- </select>
320
- </li>
321
- <?php
322
- $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
323
- wc_enqueue_js( "
324
- var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
325
-
326
- jQuery('#dropdown_shop_order_language').on('change', function(){
327
- if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual')). "')){
328
- var lang = jQuery(this).val();
329
-
330
- jQuery.ajax({
331
- url: ajaxurl,
332
- type: 'post',
333
- dataType: 'json',
334
- data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '".$wcml_set_dashboard_order_language_nonce."' },
335
- success: function( response ){
336
- if(typeof response.error !== 'undefined'){
337
- alert(response.error);
338
- }else{
339
- window.location = window.location.href;
340
- }
341
- }
342
- });
343
- }else{
344
- jQuery(this).val( order_lang_current_value );
345
- return false;
346
- }
347
- });
348
-
349
- ");
350
- }
351
- }
352
-
353
- function order_delete_items(){
354
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
355
- if(!$nonce || !wp_verify_nonce($nonce, 'set_dashboard_order_language')){
356
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
357
- die();
358
- }
359
-
360
- setcookie('_wcml_dashboard_order_language', filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
361
-
362
- }
363
-
364
- function set_order_language_backend( $post_id, $post ){
365
-
366
- if( isset( $_POST['wcml_shop_order_language'] ) ){
367
- update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
368
- }
369
-
370
- }
371
-
372
- function update_order_currency( $meta_id, $object_id, $meta_key, $meta_value ){
373
-
374
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT && get_post_type($object_id) == 'shop_order' && isset( $_GET['wc-ajax'] ) && $_GET['wc-ajax'] == 'checkout' ){
375
- update_post_meta( $object_id, '_order_currency', get_woocommerce_currency() );
376
- }
377
-
378
- }
379
-
380
-
381
- }
1
+ <?php
2
+ class WCML_Orders{
3
+
4
+ private $woocommerce_wpml;
5
+ private $sitepress;
6
+
7
+ private $standart_order_notes = array('Order status changed from %s to %s.',
8
+ 'Order item stock reduced successfully.','Item #%s stock reduced from %s to %s.','Item #%s stock increased from %s to %s.','Awaiting BACS payment','Awaiting cheque payment','Payment to be made upon delivery.',
9
+ 'Validation error: PayPal amounts do not match (gross %s).','Validation error: PayPal IPN response from a different email address (%s).','Payment pending: %s',
10
+ 'Payment %s via IPN.','Validation error: PayPal amounts do not match (amt %s).','IPN payment completed','PDT payment completed'
11
+ );
12
+
13
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
14
+ $this->woocommerce_wpml = $woocommerce_wpml;
15
+ $this->sitepress = $sitepress;
16
+
17
+ add_action('init', array($this, 'init'));
18
+
19
+ //checkout page
20
+ add_action( 'wp_ajax_woocommerce_checkout',array($this,'switch_to_current'),9);
21
+ add_action( 'wp_ajax_nopriv_woocommerce_checkout',array($this,'switch_to_current'),9);
22
+
23
+ add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
24
+ }
25
+
26
+ function init(){
27
+
28
+ add_action('woocommerce_shipping_update_ajax', array($this, 'fix_shipping_update'));
29
+ add_action('woocommerce_checkout_update_order_meta', array($this, 'set_order_language'));
30
+
31
+ add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
32
+
33
+ add_filter('the_comments', array($this, 'get_filtered_comments'));
34
+ add_filter('gettext',array($this, 'filtered_woocommerce_new_order_note_data'),10,3);
35
+
36
+ add_filter( 'woocommerce_order_get_items', array( $this, 'woocommerce_order_get_items' ), 10, 2 );
37
+
38
+ add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_language_backend'), 10, 2 );
39
+ add_action( 'woocommerce_order_actions_start', array( $this, 'order_language_dropdown' ), 11 ); //after order currency drop-down
40
+
41
+ //special case for wcml-741
42
+ add_action('updated_post_meta', array($this,'update_order_currency'), 100,4);
43
+
44
+ add_action( 'woocommerce_before_order_itemmeta', array( $this, 'backend_before_order_itemmeta' ), 100, 3 );
45
+ add_action( 'woocommerce_after_order_itemmeta', array( $this, 'backend_after_order_itemmeta' ), 100, 3 );
46
+
47
+ }
48
+
49
+ function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
50
+ if(in_array($text,$this->standart_order_notes)){
51
+
52
+ $language = $this->woocommerce_wpml->strings->get_string_language( $text, 'woocommerce' );
53
+
54
+ if( $this->sitepress->get_user_admin_language( get_current_user_id(), true ) != $language ){
55
+
56
+ $string_id = icl_get_string_id( $text, 'woocommerce');
57
+ $strings = icl_get_string_translations_by_id( $string_id );
58
+ if($strings){
59
+ $translations = $strings[ $this->sitepress->get_user_admin_language( get_current_user_id(), true ) ]['value'];
60
+ }
61
+
62
+ }else{
63
+ return $text;
64
+ }
65
+ }
66
+
67
+ return $translations;
68
+ }
69
+
70
+ function get_filtered_comments($comments){
71
+
72
+ $user_id = get_current_user_id();
73
+
74
+ if( $user_id ){
75
+
76
+ $user_language = get_user_meta( $user_id, 'icl_admin_language', true );
77
+
78
+ foreach($comments as $key=>$comment){
79
+
80
+ $comment_string_id = icl_get_string_id( $comment->comment_content, 'woocommerce');
81
+
82
+ if($comment_string_id){
83
+ $comment_strings = icl_get_string_translations_by_id( $comment_string_id );
84
+ if($comment_strings){
85
+ $comments[$key]->comment_content = $comment_strings[$user_language]['value'];
86
+ }
87
+ }
88
+ }
89
+
90
+ }
91
+
92
+ return $comments;
93
+
94
+ }
95
+
96
+ function woocommerce_order_get_items( $items, $order ){
97
+
98
+ if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ) {
99
+ // on order edit page use admin default language
100
+ $language_to_filter = $this->sitepress->get_user_admin_language( get_current_user_id(), true );
101
+ }elseif( isset( $_GET[ 'action' ] ) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status' || $_GET['action'] == 'mark_processing') ){
102
+ //backward compatibility for WC < 2.7
103
+ $order_id = method_exists( 'WC_Order', 'get_id' ) ? $order->get_id() : $order->id;
104
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
105
+ $language_to_filter = $order_language ? $order_language : $this->sitepress->get_default_language();
106
+ }else{
107
+ $language_to_filter = $this->sitepress->get_current_language();
108
+ }
109
+
110
+ foreach( $items as $index => $item ){
111
+ if( is_array( $item ) ){
112
+ // WC < 2.7
113
+ foreach( $item as $key => $item_data ){
114
+ if( $key == 'product_id' ){
115
+ $tr_product_id = apply_filters( 'translate_object_id', $item_data, 'product', false, $language_to_filter );
116
+ if( !is_null( $tr_product_id ) ){
117
+ $items[ $index ][ $key ] = $tr_product_id;
118
+ $items[ $index ][ 'name'] = get_post( $tr_product_id )->post_title;
119
+ }
120
+ }
121
+ if( $key == 'variation_id' ){
122
+ $tr_variation_id = apply_filters( 'translate_object_id', $item_data, 'product_variation', false, $language_to_filter );
123
+ if( !is_null($tr_variation_id)){
124
+ $items[$index][$key] = $tr_variation_id;
125
+ }
126
+ }
127
+
128
+ if (substr($key, 0, 3) == 'pa_') {
129
+ //attr is taxonomy
130
+
131
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $key, $item_data );
132
+ $tr_id = apply_filters( 'translate_object_id', $term_id, $key, false, $language_to_filter );
133
+
134
+ if(!is_null($tr_id)){
135
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $key);
136
+ $items[$index][$key] = $translated_term->slug;
137
+ }
138
+ }
139
+
140
+ if( $key == 'type' && $item_data == 'shipping' && isset( $item[ 'method_id' ] ) ){
141
+
142
+ $items[ $index ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $language_to_filter );
143
+
144
+ }
145
+ }
146
+ }else{
147
+ // WC >= 2.7
148
+ if( $item instanceof WC_Order_Item_Product ){
149
+ if( $item->get_type() == 'line_item' ){
150
+ $item_product_id = $item->get_product_id();
151
+ if( get_post_type( $item_product_id ) == 'product_variation' ){
152
+ $item_product_id = wp_get_post_parent_id( $item_product_id );
153
+ }
154
+
155
+ $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
156
+ if( !is_null( $tr_product_id ) ){
157
+ $item->set_product_id( $tr_product_id );
158
+ $item->set_name( get_post( $tr_product_id )->post_title );
159
+ }
160
+ $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
161
+ if( !is_null( $tr_variation_id ) ){
162
+ $item->set_variation_id( $tr_variation_id );
163
+ }
164
+
165
+ $meta_data = array();
166
+ foreach( $item->get_meta_data() as $data ){
167
+
168
+ if( substr( $data->key, 0, 3) == 'pa_' ){
169
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $data->key, $data->value );
170
+ $tr_id = apply_filters( 'translate_object_id', $term_id, $data->key, false, $language_to_filter );
171
+
172
+ if(!is_null($tr_id)){
173
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $data->key);
174
+ $data->value = $translated_term->slug;
175
+ }
176
+ }
177
+
178
+ $meta_data[] = $data;
179
+
180
+ }
181
+ }
182
+ }elseif( $item instanceof WC_Order_Item_Shipping ){
183
+ if( $item->get_method_id() ){
184
+ $item->set_method_title( $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item->get_method_title(), $item->get_method_id(), $language_to_filter ) );
185
+ }
186
+ }
187
+ }
188
+ }
189
+
190
+ return $items;
191
+
192
+ }
193
+
194
+ public function backend_before_order_itemmeta( $item_id, $item, $product ){
195
+ global $sitepress;
196
+
197
+ if( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
198
+ foreach( $item[ 'item_meta' ] as $key => $item_meta ){
199
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
200
+ //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
201
+ if( !is_array( $item_meta ) ){
202
+ $item_meta = array( $item_meta );
203
+ }
204
+
205
+ foreach( $item_meta as $value ){
206
+ $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ public function backend_after_order_itemmeta( $item_id, $item, $product ){
214
+ global $sitepress;
215
+
216
+ $order_languge = $this->get_order_language_by_item_id( $item_id );
217
+ if( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
218
+ foreach( $item[ 'item_meta' ] as $key => $item_meta ){
219
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
220
+ //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
221
+ if( !is_array( $item_meta ) ){
222
+ $item_meta = array( $item_meta );
223
+ }
224
+
225
+ foreach( $item_meta as $value ){
226
+ $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+
233
+ public function get_order_language_by_item_id( $item_id ){
234
+ global $wpdb;
235
+
236
+ $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
237
+
238
+ return get_post_meta( $order_id, 'wpml_language', true );
239
+ }
240
+
241
+ //force update to display attribute in correct language on edit order page
242
+ public function force_update_itemmeta( $item_id, $key, $value, $languge ){
243
+ global $wpdb, $woocommerce_wpml;
244
+
245
+ $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
246
+ $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
247
+ $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
248
+ $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
249
+
250
+ if( $translated_term ){
251
+ $value = $translated_term->slug;
252
+ $wpdb->update( $wpdb->prefix.'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array( 'order_item_id' => $item_id, 'meta_key' => $key ) );
253
+ }
254
+ }
255
+
256
+ // Fix for shipping update on the checkout page.
257
+ function fix_shipping_update($amount){
258
+ global $sitepress, $post;
259
+
260
+ if($sitepress->get_current_language() !== $sitepress->get_default_language() && $post->ID == $this->checkout_page_id()){
261
+
262
+ $_SESSION['icl_checkout_shipping_amount'] = $amount;
263
+
264
+ $amount = $_SESSION['icl_checkout_shipping_amount'];
265
+
266
+ }
267
+
268
+ return $amount;
269
+ }
270
+
271
+
272
+ /**
273
+ * Adds language to order post type.
274
+ *
275
+ * Language was stored in the session created on checkout page.
276
+ * See params().
277
+ *
278
+ * @param type $order_id
279
+ */
280
+ function set_order_language($order_id) {
281
+ if(!get_post_meta($order_id, 'wpml_language')){
282
+ $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
283
+ update_post_meta($order_id, 'wpml_language', $language);
284
+ }
285
+ }
286
+
287
+ function append_query_parameters($parameters){
288
+
289
+ if(is_order_received_page() || is_checkout()){
290
+ if(!in_array('order', $parameters)) $parameters[] = 'order';
291
+ if(!in_array('key', $parameters)) $parameters[] = 'key';
292
+ }
293
+
294
+ return $parameters;
295
+ }
296
+
297
+ function switch_to_current(){
298
+ $this->woocommerce_wpml->emails->change_email_language($this->sitepress->get_current_language());
299
+ }
300
+
301
+ function order_language_dropdown( $order_id ){
302
+ if( !get_post_meta( $order_id, '_order_currency') ) {
303
+ $languages = apply_filters( 'wpml_active_languages', array(), array( 'skip_missing' => 0, 'orderby' => 'code' ) );
304
+ $selected_lang = isset( $_COOKIE [ '_wcml_dashboard_order_language' ] ) ? $_COOKIE [ '_wcml_dashboard_order_language' ] : $this->sitepress->get_default_language();
305
+ ?>
306
+ <li class="wide">
307
+ <label><?php _e('Order language:'); ?></label>
308
+ <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
309
+ <?php if (!empty($languages)): ?>
310
+
311
+ <?php foreach ($languages as $l): ?>
312
+
313
+ <option
314
+ value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
315
+
316
+ <?php endforeach; ?>
317
+
318
+ <?php endif; ?>
319
+ </select>
320
+ </li>
321
+ <?php
322
+ $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
323
+ wc_enqueue_js( "
324
+ var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
325
+
326
+ jQuery('#dropdown_shop_order_language').on('change', function(){
327
+ if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual')). "')){
328
+ var lang = jQuery(this).val();
329
+
330
+ jQuery.ajax({
331
+ url: ajaxurl,
332
+ type: 'post',
333
+ dataType: 'json',
334
+ data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '".$wcml_set_dashboard_order_language_nonce."' },
335
+ success: function( response ){
336
+ if(typeof response.error !== 'undefined'){
337
+ alert(response.error);
338
+ }else{
339
+ window.location = window.location.href;
340
+ }
341
+ }
342
+ });
343
+ }else{
344
+ jQuery(this).val( order_lang_current_value );
345
+ return false;
346
+ }
347
+ });
348
+
349
+ ");
350
+ }
351
+ }
352
+
353
+ function order_delete_items(){
354
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
355
+ if(!$nonce || !wp_verify_nonce($nonce, 'set_dashboard_order_language')){
356
+ echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
357
+ die();
358
+ }
359
+
360
+ setcookie('_wcml_dashboard_order_language', filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
361
+
362
+ }
363
+
364
+ function set_order_language_backend( $post_id, $post ){
365
+
366
+ if( isset( $_POST['wcml_shop_order_language'] ) ){
367
+ update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
368
+ }
369
+
370
+ }
371
+
372
+ function update_order_currency( $meta_id, $object_id, $meta_key, $meta_value ){
373
+
374
+ if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT && get_post_type($object_id) == 'shop_order' && isset( $_GET['wc-ajax'] ) && $_GET['wc-ajax'] == 'checkout' ){
375
+ update_post_meta( $object_id, '_order_currency', get_woocommerce_currency() );
376
+ }
377
+
378
+ }
379
+
380
+
381
+ }
inc/class-wcml-products-screen-options.php CHANGED
@@ -1,46 +1,46 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Screen_Options
5
- */
6
- class WCML_Products_Screen_Options {
7
-
8
- /**
9
- * Setup hooks.
10
- */
11
- public function init() {
12
- add_filter( 'default_hidden_columns', array( $this, 'filter_screen_options' ), 10, 2 );
13
- add_filter( 'wpml_hide_management_column', array( $this, 'sitepress_screen_option_filter' ), 10, 2 );
14
- }
15
-
16
- /**
17
- * Hide management column by default for products.
18
- *
19
- * @param $is_visible
20
- * @param $post_type
21
- *
22
- * @return bool
23
- */
24
- public function sitepress_screen_option_filter( $is_visible, $post_type ) {
25
- if ( 'product' === $post_type ) {
26
- $is_visible = false;
27
- }
28
-
29
- return $is_visible;
30
- }
31
-
32
- /**
33
- * Set default option for translations management column.
34
- *
35
- * @param $hidden
36
- * @param $screen
37
- *
38
- * @return array
39
- */
40
- public function filter_screen_options( $hidden, $screen ) {
41
- if ( 'edit-product' === $screen->id ) {
42
- $hidden[] = 'icl_translations';
43
- }
44
- return $hidden;
45
- }
46
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Screen_Options
5
+ */
6
+ class WCML_Products_Screen_Options {
7
+
8
+ /**
9
+ * Setup hooks.
10
+ */
11
+ public function init() {
12
+ add_filter( 'default_hidden_columns', array( $this, 'filter_screen_options' ), 10, 2 );
13
+ add_filter( 'wpml_hide_management_column', array( $this, 'sitepress_screen_option_filter' ), 10, 2 );
14
+ }
15
+
16
+ /**
17
+ * Hide management column by default for products.
18
+ *
19
+ * @param $is_visible
20
+ * @param $post_type
21
+ *
22
+ * @return bool
23
+ */
24
+ public function sitepress_screen_option_filter( $is_visible, $post_type ) {
25
+ if ( 'product' === $post_type ) {
26
+ $is_visible = false;
27
+ }
28
+
29
+ return $is_visible;
30
+ }
31
+
32
+ /**
33
+ * Set default option for translations management column.
34
+ *
35
+ * @param $hidden
36
+ * @param $screen
37
+ *
38
+ * @return array
39
+ */
40
+ public function filter_screen_options( $hidden, $screen ) {
41
+ if ( 'edit-product' === $screen->id ) {
42
+ $hidden[] = 'icl_translations';
43
+ }
44
+ return $hidden;
45
+ }
46
+ }
inc/class-wcml-products.php CHANGED
@@ -1,506 +1,541 @@
1
- <?php
2
-
3
- class WCML_Products{
4
-
5
- /**
6
- * @var WCML_TP_Support
7
- */
8
- public $tp_support;
9
-
10
- /**
11
- * @var woocommerce_wpml
12
- */
13
- private $woocommerce_wpml;
14
- /**
15
- * @var SitePress
16
- */
17
- private $sitepress;
18
- /**
19
- * @var wpdb
20
- */
21
- private $wpdb;
22
-
23
-
24
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb )
25
- {
26
- $this->woocommerce_wpml = $woocommerce_wpml;
27
- $this->sitepress = $sitepress;
28
- $this->wpdb = $wpdb;
29
-
30
- if( is_admin() ){
31
-
32
- add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
-
34
- add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
35
-
36
- $this->tp_support = new WCML_TP_Support();
37
-
38
- }else{
39
- add_filter( 'woocommerce_json_search_found_products', array( $this, 'filter_found_products_by_language' ) );
40
- add_filter( 'woocommerce_related_products_args', array( $this, 'filter_related_products_args' ) );
41
- }
42
-
43
- add_filter( 'woocommerce_upsell_crosssell_search_products', array( $this, 'filter_woocommerce_upsell_crosssell_posts_by_language' ) );
44
- //update menu_order fro translations after ordering original products
45
- add_action( 'woocommerce_after_product_ordering', array( $this, 'update_all_products_translations_ordering' ) );
46
- //filter to copy excerpt value
47
- add_filter( 'wpml_copy_from_original_custom_fields', array( $this, 'filter_excerpt_field_content_copy' ) );
48
-
49
- add_filter( 'wpml_override_is_translator', array( $this, 'wcml_override_is_translator' ), 10, 3 );
50
- }
51
-
52
- // Check if original product
53
- public function is_original_product( $product_id ){
54
- $cache_key = $product_id;
55
- $cache_group = 'is_original_product';
56
- $temp_is_original = wp_cache_get($cache_key, $cache_group);
57
-
58
- if($temp_is_original) return $temp_is_original;
59
-
60
- $is_original = $this->wpdb->get_var(
61
- $this->wpdb->prepare(
62
- "SELECT source_language_code IS NULL
63
- FROM {$this->wpdb->prefix}icl_translations
64
- WHERE element_id=%d AND element_type='post_product'",
65
- $product_id )
66
- );
67
-
68
- wp_cache_set( $cache_key, $is_original, $cache_group );
69
-
70
- return $is_original;
71
- }
72
-
73
- // Get original product language
74
- public function get_original_product_language( $product_id ){
75
- $cache_key = $product_id;
76
- $cache_group = 'original_product_language';
77
- $temp_language = wp_cache_get( $cache_key, $cache_group );
78
- if($temp_language) return $temp_language;
79
-
80
- $language = $this->wpdb->get_var( $this->wpdb->prepare( "
81
- SELECT t2.language_code FROM {$this->wpdb->prefix}icl_translations as t1
82
- LEFT JOIN {$this->wpdb->prefix}icl_translations as t2 ON t1.trid = t2.trid
83
- WHERE t1.element_id=%d AND t1.element_type=%s AND t2.source_language_code IS NULL", $product_id, 'post_'.get_post_type($product_id) ) );
84
-
85
- wp_cache_set( $cache_key, $language, $cache_group );
86
- return $language;
87
- }
88
-
89
- public function is_variable_product( $product_id ){
90
- $cache_key = $product_id;
91
- $cache_group = 'is_variable_product';
92
- $temp_is_variable = wp_cache_get( $cache_key, $cache_group );
93
- if( $temp_is_variable ) return $temp_is_variable;
94
-
95
- $get_variation_term_taxonomy_ids = $this->wpdb->get_col( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.name = 'variable' AND tt.taxonomy = 'product_type'" );
96
- $get_variation_term_taxonomy_ids = apply_filters( 'wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids );
97
-
98
- $is_variable_product = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count(object_id) FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id IN (".join(',',$get_variation_term_taxonomy_ids).")",$product_id ) );
99
- $is_variable_product = apply_filters( 'wcml_is_variable_product', $is_variable_product, $product_id );
100
-
101
- wp_cache_set( $cache_key, $is_variable_product, $cache_group );
102
-
103
- return $is_variable_product;
104
- }
105
-
106
- public function is_grouped_product($product_id){
107
- $get_variation_term_taxonomy_id = $this->wpdb->get_var( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.name = 'grouped'" );
108
- $is_grouped_product = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count(object_id) FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id = %d ",$product_id,$get_variation_term_taxonomy_id ) );
109
-
110
- return $is_grouped_product;
111
- }
112
-
113
- public function get_translation_flags( $active_languages, $slang = false, $job_language = false ){
114
- $available_languages = array();
115
-
116
- foreach( $active_languages as $key => $language ){
117
- if( $job_language && $language[ 'code' ] != $job_language ) {
118
- continue;
119
- }elseif ( !$slang ||
120
- (
121
- ( $slang != $language[ 'code' ] ) &&
122
- ( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ||
123
- wpml_check_user_is_translator( $slang, $language[ 'code' ] ) ) &&
124
- ( !isset( $_POST[ 'translation_status_lang' ] ) ||
125
- ( isset( $_POST[ 'translation_status_lang' ] ) &&
126
- ( $_POST[ 'translation_status_lang' ] == $language[ 'code' ] ) ||
127
- $_POST[ 'translation_status_lang' ]=='' )
128
- )
129
- )
130
- ){
131
- $available_languages[ $key ][ 'name' ] = $language[ 'english_name' ];
132
- $available_languages[ $key ][ 'flag_url' ] = $this->sitepress->get_flag_url( $language[ 'code' ] );
133
- }
134
- }
135
-
136
- return $available_languages;
137
- }
138
-
139
- public function get_translation_statuses( $original_product_id, $product_translations, $active_languages, $slang = false, $trid = false, $job_language = false ){
140
- foreach ( $active_languages as $language ) {
141
- if( $job_language && $language['code'] != $job_language ) {
142
- continue;
143
- }elseif( isset( $product_translations[ $language[ 'code' ] ] ) && $product_translations[ $language[ 'code' ] ]->original ) { ?>
144
- <span title="<?php echo $language['english_name'] . ': ' . __('Original language', 'woocommerce-multilingual'); ?>">
145
- <i class="otgs-ico-original"></i>
146
- </span>
147
- <?php }elseif(
148
- $slang != $language[ 'code' ] &&
149
- ( !isset( $_POST[ 'translation_status_lang' ] ) ||
150
- ( isset( $_POST['translation_status_lang']) &&
151
- $_POST['translation_status_lang'] == $language['code'] ||
152
- $_POST['translation_status_lang'] == ''
153
- )
154
- )
155
- ) {
156
- if( isset( $product_translations[ $language[ 'code' ] ] ) ) {
157
- $job_id = $this->wpdb->get_var(
158
- $this->wpdb->prepare(
159
- "SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job AS tj
160
- LEFT JOIN {$this->wpdb->prefix}icl_translation_status AS ts
161
- ON tj.rid = ts.rid WHERE ts.translation_id=%d",
162
- $product_translations[ $language[ 'code' ] ]->translation_id )
163
- );
164
- }else{
165
- $job_id = false;
166
- }
167
-
168
- if( !current_user_can( 'wpml_manage_woocommerce_multilingual' ) && isset( $product_translations[ $language[ 'code' ] ] ) ) {
169
- $tr_status = $this->wpdb->get_row(
170
- $this->wpdb->prepare(
171
- "SELECT status,translator_id FROM {$this->wpdb->prefix}icl_translation_status
172
- WHERE translation_id = %d",
173
- $product_translations[ $language[ 'code' ] ]->translation_id )
174
- );
175
-
176
- if( !is_null( $tr_status ) && get_current_user_id() != $tr_status->translator_id ){
177
- if( $tr_status->status == ICL_TM_IN_PROGRESS ) { ?>
178
- <a title="<?php _e( 'Translation in progress', 'woocommerce-multilingual' ); ?>"><i
179
- class="otgs-ico-in-progress"></i></a>
180
- <?php continue;
181
- }elseif( $tr_status->status == ICL_TM_WAITING_FOR_TRANSLATOR && !$job_id ){
182
- $tr_job_id = $this->wpdb->get_var(
183
- $this->wpdb->prepare(
184
- "SELECT j.job_id FROM {$this->wpdb->prefix}icl_translate_job j
185
- JOIN {$this->wpdb->prefix}icl_translation_status s ON j.rid = s.rid
186
- WHERE s.translation_id = %d",
187
- $product_translations[ $language[ 'code' ] ]->translation_id )
188
- );
189
- $translation_queue_page = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $tr_job_id );
190
- $edit_url = apply_filters( 'icl_job_edit_url', $translation_queue_page, $tr_job_id );
191
- ?>
192
- <a href="<?php echo $edit_url ?>" title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Take this and edit', 'woocommerce-multilingual' ); ?>">
193
- <i class="otgs-ico-add"></i>
194
- </a>
195
- <?php continue;
196
- }
197
- }
198
- wpml_tm_load_status_display_filter();
199
- } ?>
200
- <a href="<?php echo apply_filters( 'wpml_link_to_translation', '', $original_product_id, $language[ 'code' ], $trid ) ?>"
201
- <?php if( isset( $product_translations[ $language[ 'code' ] ] ) ){
202
- $tr_status = $this->wpdb->get_row(
203
- $this->wpdb->prepare(
204
- "SELECT status,needs_update FROM {$this->wpdb->prefix}icl_translation_status
205
- WHERE translation_id = %d",
206
- $product_translations[ $language[ 'code' ] ]->translation_id )
207
- );
208
- if (!$tr_status ) { ?>
209
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
210
- <i class="otgs-ico-add"></i>
211
- <?php }elseif( $tr_status->needs_update ){ ?>
212
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Update translation', 'woocommerce-multilingual' ); ?>">
213
- <i class="otgs-ico-refresh"></i>
214
- <?php }elseif( $tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE ){ ?>
215
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Finish translating', 'woocommerce-multilingual' ); ?>">
216
- <i class="otgs-ico-refresh"></i>
217
- <?php }elseif( $tr_status->status == ICL_TM_COMPLETE ){ ?>
218
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
219
- <i class="otgs-ico-edit"></i>
220
- <?php }elseif( $tr_status->status == ICL_TM_DUPLICATE ){ ?>
221
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
222
- <i class="otgs-ico-duplicate"></i>
223
- <?php }
224
- } else { ?>
225
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
226
- <i class="otgs-ico-add"></i>
227
- <?php } ?>
228
- </a>
229
- <?php } ?>
230
- <?php }
231
- }
232
-
233
- public function wcml_override_is_translator( $is_translator, $user_id, $args ){
234
-
235
- if( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ){
236
- return true;
237
- }
238
-
239
- return $is_translator;
240
- }
241
-
242
- //product quickedit
243
- public function filter_product_actions( $actions, $post ){
244
- if(
245
- $post->post_type == 'product' &&
246
- !$this->is_original_product( $post->ID ) &&
247
- isset( $actions[ 'inline hide-if-no-js' ] ) )
248
- {
249
- $new_actions = array();
250
- foreach( $actions as $key => $action ) {
251
- if( $key == 'inline hide-if-no-js' ) {
252
- $new_actions[ 'quick_hide' ] = '<a href="#TB_inline?width=200&height=150&inlineId=quick_edit_notice" class="thickbox" title="' .
253
- __('Edit this item inline', 'woocommerce-multilingual') . '">' .
254
- __('Quick Edit', 'woocommerce-multilingual') . '</a>';
255
- } else {
256
- $new_actions[ $key ] = $action;
257
- }
258
- }
259
- return $new_actions;
260
- }
261
- return $actions;
262
- }
263
-
264
- /**
265
- * Filters upsell/crosell products in the correct language.
266
- */
267
- public function filter_found_products_by_language( $found_products ){
268
- $current_page_language = $this->sitepress->get_current_language();
269
-
270
- foreach( $found_products as $product_id => $output_v ){
271
- $post_data = $this->wpdb->get_row(
272
- $this->wpdb->prepare(
273
- "SELECT * FROM {$this->wpdb->prefix}icl_translations
274
- WHERE element_id = %d AND element_type LIKE 'post_%'", $product_id
275
- )
276
- );
277
-
278
- $product_language = $post_data->language_code;
279
-
280
- if( $product_language !== $current_page_language ){
281
- unset( $found_products[ $product_id ] );
282
- }
283
- }
284
-
285
- return $found_products;
286
- }
287
-
288
- /**
289
- * Takes off translated products from the Up-sells/Cross-sells tab.
290
- */
291
- public function filter_woocommerce_upsell_crosssell_posts_by_language( $posts ){
292
- foreach( $posts as $key => $post ){
293
- $post_id = $posts[ $key ]->ID;
294
- $post_data = $this->wpdb->get_row(
295
- $this->wpdb->prepare(
296
- "SELECT * FROM {$this->wpdb->prefix}icl_translations
297
- WHERE element_id = %d ", $post_id
298
- ),
299
- ARRAY_A );
300
-
301
- if( $post_data[ 'language_code' ] !== $this->sitepress->get_current_language() ){
302
- unset( $posts[ $key ] );
303
- }
304
- }
305
-
306
- return $posts;
307
- }
308
-
309
- public function woocommerce_json_search_found_products( $found_products ){
310
-
311
- foreach( $found_products as $post => $formatted_product_name ) {
312
- $parent = wp_get_post_parent_id( $post );
313
- if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
314
- && ( ( !$parent && $this->sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
315
- || ( $parent && $this->sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
316
- )
317
- ||
318
- ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
319
- && ( ( !$parent && $this->is_original_product($post) )
320
- || ( $parent && $this->is_original_product($parent) ) )
321
- )
322
- ) {
323
-
324
- $new_found_products[$post] = $formatted_product_name;
325
- }
326
- }
327
-
328
- return isset ( $new_found_products ) ? $new_found_products : $found_products ;
329
- }
330
-
331
- //update menu_order fro translations after ordering original products
332
- public function update_all_products_translations_ordering(){
333
- if( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) {
334
- $current_language = $this->sitepress->get_current_language();
335
- if( $current_language == $this->sitepress->get_default_language() ){
336
- $products = $this->wpdb->get_results(
337
- $this->wpdb->prepare(
338
- "SELECT p.ID FROM {$this->wpdb->posts} AS p
339
- LEFT JOIN {$this->wpdb->prefix}icl_translations AS icl
340
- ON icl.element_id = p.id
341
- WHERE p.post_type = 'product'
342
- AND p.post_status IN ( 'publish', 'future', 'draft', 'pending', 'private' )
343
- AND icl.element_type= 'post_product'
344
- AND icl.language_code = %s",
345
- $current_language )
346
- );
347
-
348
- foreach( $products as $product ){
349
- $this->update_order_for_product_translations( $product->ID );
350
- }
351
- }
352
- }
353
- }
354
-
355
- //update menu_order fro translations after ordering original products
356
- public function update_order_for_product_translations( $product_id ){
357
- if( isset( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) && $this->woocommerce_wpml->settings[ 'products_sync_order' ] ){
358
- $current_language = $this->sitepress->get_current_language();
359
-
360
- if ( $current_language == $this->sitepress->get_default_language() ) {
361
- $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
362
- $trid = $this->sitepress->get_element_trid($product_id, 'post_product');
363
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
364
-
365
- foreach( $translations as $translation ){
366
- if( $translation->element_id != $product_id ){
367
- $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation->element_id ) );
368
- }
369
- }
370
- }
371
- }
372
- }
373
-
374
- public function filter_excerpt_field_content_copy( $elements ) {
375
-
376
- if ( $elements[ 'post_type' ] == 'product' ) {
377
- $elements[ 'excerpt' ] ['editor_type'] = 'editor';
378
- }
379
- if ( function_exists( 'format_for_editor' ) ) {
380
- // WordPress 4.3 uses format_for_editor
381
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( format_for_editor( $elements[ 'excerpt' ][ 'value' ], $_POST[ 'excerpt_type' ] ) );
382
- } else {
383
- // Backwards compatible for WordPress < 4.3
384
- if($_POST[ 'excerpt_type'] == 'rich'){
385
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_richedit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
386
- }else{
387
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_htmledit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
388
- }
389
- }
390
- return $elements;
391
- }
392
-
393
- // Check if user can translate product
394
- public function user_can_translate_product( $trid, $language_code ){
395
- global $iclTranslationManagement;
396
-
397
- $current_translator = $iclTranslationManagement->get_current_translator();
398
- $job_id = $this->wpdb->get_var( $this->wpdb->prepare("
399
- SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job tj
400
- JOIN {$this->wpdb->prefix}icl_translation_status ts ON tj.rid = ts.rid
401
- JOIN {$this->wpdb->prefix}icl_translations t ON ts.translation_id = t.translation_id
402
- WHERE t.trid = %d AND t.language_code='%s'
403
- ORDER BY tj.job_id DESC LIMIT 1
404
- ", $trid, $language_code ) );
405
-
406
- if( $job_id && wpml_check_user_is_translator( $this->sitepress->get_source_language_by_trid( $trid ), $language_code ) ){
407
- return true;
408
- }
409
- return false;
410
- }
411
-
412
- public function filter_related_products_args( $args ){
413
- if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
414
- isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
415
- $this->woocommerce_wpml->settings[ 'display_custom_prices' ] )
416
- {
417
-
418
- $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
419
- $woocommerce_currency = get_option('woocommerce_currency');
420
-
421
- if( $client_currency != $woocommerce_currency ){
422
- $args['meta_query'][] = array(
423
- 'key' => '_wcml_custom_prices_status',
424
- 'value' => 1,
425
- 'compare' => '=',
426
- );
427
- }
428
-
429
- }
430
- return $args;
431
- }
432
-
433
- /*
434
- * get meta ids for multiple values post meta key
435
- */
436
- public function get_mid_ids_by_key( $post_id, $meta_key ) {
437
- $ids = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT meta_id FROM {$this->wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key ) );
438
- if( $ids )
439
- return $ids;
440
-
441
- return false;
442
- }
443
-
444
- // count "in progress" and "waiting on translation" as untranslated too
445
- public function get_untranslated_products_count( $language ){
446
-
447
- $count = 0;
448
-
449
- $products = $this->wpdb->get_results( "
450
- SELECT p.ID, t.trid, t.language_code
451
- FROM {$this->wpdb->posts} AS p
452
- LEFT JOIN {$this->wpdb->prefix}icl_translations AS t ON t.element_id = p.id
453
- WHERE p.post_type = 'product' AND t.element_type = 'post_product' AND t.source_language_code IS NULL
454
- " );
455
-
456
- foreach( $products as $product ){
457
- if( $product->language_code == $language ) continue;
458
-
459
- $element_key = array( 'trid' => $product->trid, 'language_code' => $language );
460
- $translation_status = apply_filters( 'wpml_tm_translation_status', null, $element_key );
461
-
462
- if( in_array( $translation_status, array( ICL_TM_NOT_TRANSLATED, ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ) ) ){
463
- $count++;
464
- }
465
- }
466
-
467
- return $count;
468
- }
469
-
470
- public function is_hide_resign_button(){
471
- global $iclTranslationManagement;
472
-
473
- $hide_resign = false;
474
-
475
- if( isset( $_GET[ 'source_language_code' ] ) && isset( $_GET[ 'language_code' ] ) ){
476
-
477
- $from_lang = $_GET[ 'source_language_code' ];
478
- $to_lang = $_GET[ 'language_code' ];
479
-
480
- }elseif( isset( $_GET[ 'job_id' ] ) ){
481
-
482
- $job = $iclTranslationManagement->get_translation_job( $_GET[ 'job_id' ] );
483
- $from_lang = $job->source_language_code;
484
- $to_lang = $job->language_code;
485
-
486
- }
487
-
488
- if( isset( $from_lang ) ){
489
-
490
- $translators = $iclTranslationManagement->get_blog_translators(
491
- array(
492
- 'from' => $from_lang,
493
- 'to' => $to_lang
494
- )
495
- );
496
-
497
- if( empty( $translators ) || ( sizeof( $translators ) == 1 && $translators[0]->ID == get_current_user_id() ) ){
498
- $hide_resign = true;
499
- }
500
-
501
- }
502
-
503
- return $hide_resign;
504
- }
505
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
506
  }
1
+ <?php
2
+
3
+ class WCML_Products{
4
+
5
+ /**
6
+ * @var WCML_TP_Support
7
+ */
8
+ public $tp_support;
9
+
10
+ /**
11
+ * @var woocommerce_wpml
12
+ */
13
+ private $woocommerce_wpml;
14
+ /**
15
+ * @var SitePress
16
+ */
17
+ private $sitepress;
18
+ /**
19
+ * @var wpdb
20
+ */
21
+ private $wpdb;
22
+
23
+
24
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb )
25
+ {
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ $this->sitepress = $sitepress;
28
+ $this->wpdb = $wpdb;
29
+
30
+ if( is_admin() ){
31
+
32
+ add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
+
34
+ add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
35
+
36
+ $this->tp_support = new WCML_TP_Support();
37
+
38
+ add_action( 'wp_ajax_wpml_switch_post_language', array( $this, 'switch_product_variations_language' ), 9 );
39
+
40
+ }else{
41
+ add_filter( 'woocommerce_json_search_found_products', array( $this, 'filter_found_products_by_language' ) );
42
+ add_filter( 'woocommerce_related_products_args', array( $this, 'filter_related_products_args' ) );
43
+ }
44
+
45
+ add_filter( 'woocommerce_upsell_crosssell_search_products', array( $this, 'filter_woocommerce_upsell_crosssell_posts_by_language' ) );
46
+ //update menu_order fro translations after ordering original products
47
+ add_action( 'woocommerce_after_product_ordering', array( $this, 'update_all_products_translations_ordering' ) );
48
+ //filter to copy excerpt value
49
+ add_filter( 'wpml_copy_from_original_custom_fields', array( $this, 'filter_excerpt_field_content_copy' ) );
50
+
51
+ add_filter( 'wpml_override_is_translator', array( $this, 'wcml_override_is_translator' ), 10, 3 );
52
+ }
53
+
54
+ // Check if original product
55
+ public function is_original_product( $product_id ){
56
+ $cache_key = $product_id;
57
+ $cache_group = 'is_original_product';
58
+ $temp_is_original = wp_cache_get($cache_key, $cache_group);
59
+
60
+ if($temp_is_original) return $temp_is_original;
61
+
62
+ $is_original = $this->wpdb->get_var(
63
+ $this->wpdb->prepare(
64
+ "SELECT source_language_code IS NULL
65
+ FROM {$this->wpdb->prefix}icl_translations
66
+ WHERE element_id=%d AND element_type='post_product'",
67
+ $product_id )
68
+ );
69
+
70
+ wp_cache_set( $cache_key, $is_original, $cache_group );
71
+
72
+ return $is_original;
73
+ }
74
+
75
+ // Get original product language
76
+ public function get_original_product_language( $product_id ){
77
+ $cache_key = $product_id;
78
+ $cache_group = 'original_product_language';
79
+ $temp_language = wp_cache_get( $cache_key, $cache_group );
80
+ if($temp_language) return $temp_language;
81
+
82
+ $language = $this->wpdb->get_var( $this->wpdb->prepare( "
83
+ SELECT t2.language_code FROM {$this->wpdb->prefix}icl_translations as t1
84
+ LEFT JOIN {$this->wpdb->prefix}icl_translations as t2 ON t1.trid = t2.trid
85
+ WHERE t1.element_id=%d AND t1.element_type=%s AND t2.source_language_code IS NULL", $product_id, 'post_'.get_post_type($product_id) ) );
86
+
87
+ wp_cache_set( $cache_key, $language, $cache_group );
88
+ return $language;
89
+ }
90
+
91
+ public function is_variable_product( $product_id ){
92
+ $cache_key = $product_id;
93
+ $cache_group = 'is_variable_product';
94
+ $temp_is_variable = wp_cache_get( $cache_key, $cache_group );
95
+ if( $temp_is_variable ) return $temp_is_variable;
96
+
97
+ $get_variation_term_taxonomy_ids = $this->wpdb->get_col( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.name = 'variable' AND tt.taxonomy = 'product_type'" );
98
+ $get_variation_term_taxonomy_ids = apply_filters( 'wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids );
99
+
100
+ $is_variable_product = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count(object_id) FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id IN (".join(',',$get_variation_term_taxonomy_ids).")",$product_id ) );
101
+ $is_variable_product = apply_filters( 'wcml_is_variable_product', $is_variable_product, $product_id );
102
+
103
+ wp_cache_set( $cache_key, $is_variable_product, $cache_group );
104
+
105
+ return $is_variable_product;
106
+ }
107
+
108
+ public function is_grouped_product($product_id){
109
+ $get_variation_term_taxonomy_id = $this->wpdb->get_var( "SELECT tt.term_taxonomy_id FROM {$this->wpdb->terms} AS t LEFT JOIN {$this->wpdb->term_taxonomy} AS tt ON t.term_id = tt.term_id WHERE t.name = 'grouped'" );
110
+ $is_grouped_product = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count(object_id) FROM {$this->wpdb->term_relationships} WHERE object_id = %d AND term_taxonomy_id = %d ",$product_id,$get_variation_term_taxonomy_id ) );
111
+
112
+ return $is_grouped_product;
113
+ }
114
+
115
+ public function get_translation_flags( $active_languages, $slang = false, $job_language = false ){
116
+ $available_languages = array();
117
+
118
+ foreach( $active_languages as $key => $language ){
119
+ if( $job_language && $language[ 'code' ] != $job_language ) {
120
+ continue;
121
+ }elseif ( !$slang ||
122
+ (
123
+ ( $slang != $language[ 'code' ] ) &&
124
+ ( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ||
125
+ wpml_check_user_is_translator( $slang, $language[ 'code' ] ) ) &&
126
+ ( !isset( $_POST[ 'translation_status_lang' ] ) ||
127
+ ( isset( $_POST[ 'translation_status_lang' ] ) &&
128
+ ( $_POST[ 'translation_status_lang' ] == $language[ 'code' ] ) ||
129
+ $_POST[ 'translation_status_lang' ]=='' )
130
+ )
131
+ )
132
+ ){
133
+ $available_languages[ $key ][ 'name' ] = $language[ 'english_name' ];
134
+ $available_languages[ $key ][ 'flag_url' ] = $this->sitepress->get_flag_url( $language[ 'code' ] );
135
+ }
136
+ }
137
+
138
+ return $available_languages;
139
+ }
140
+
141
+ public function get_translation_statuses( $original_product_id, $product_translations, $active_languages, $slang = false, $trid = false, $job_language = false ){
142
+ foreach ( $active_languages as $language ) {
143
+ if( $job_language && $language['code'] != $job_language ) {
144
+ continue;
145
+ }elseif( isset( $product_translations[ $language[ 'code' ] ] ) && $product_translations[ $language[ 'code' ] ]->original ) { ?>
146
+ <span title="<?php echo $language['english_name'] . ': ' . __('Original language', 'woocommerce-multilingual'); ?>">
147
+ <i class="otgs-ico-original"></i>
148
+ </span>
149
+ <?php }elseif(
150
+ $slang != $language[ 'code' ] &&
151
+ ( !isset( $_POST[ 'translation_status_lang' ] ) ||
152
+ ( isset( $_POST['translation_status_lang']) &&
153
+ $_POST['translation_status_lang'] == $language['code'] ||
154
+ $_POST['translation_status_lang'] == ''
155
+ )
156
+ )
157
+ ) {
158
+ if( isset( $product_translations[ $language[ 'code' ] ] ) ) {
159
+ $job_id = $this->wpdb->get_var(
160
+ $this->wpdb->prepare(
161
+ "SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job AS tj
162
+ LEFT JOIN {$this->wpdb->prefix}icl_translation_status AS ts
163
+ ON tj.rid = ts.rid WHERE ts.translation_id=%d",
164
+ $product_translations[ $language[ 'code' ] ]->translation_id )
165
+ );
166
+ }else{
167
+ $job_id = false;
168
+ }
169
+
170
+ if( !current_user_can( 'wpml_manage_woocommerce_multilingual' ) && isset( $product_translations[ $language[ 'code' ] ] ) ) {
171
+ $tr_status = $this->wpdb->get_row(
172
+ $this->wpdb->prepare(
173
+ "SELECT status,translator_id FROM {$this->wpdb->prefix}icl_translation_status
174
+ WHERE translation_id = %d",
175
+ $product_translations[ $language[ 'code' ] ]->translation_id )
176
+ );
177
+
178
+ if( !is_null( $tr_status ) && get_current_user_id() != $tr_status->translator_id ){
179
+ if( $tr_status->status == ICL_TM_IN_PROGRESS ) { ?>
180
+ <a title="<?php _e( 'Translation in progress', 'woocommerce-multilingual' ); ?>"><i
181
+ class="otgs-ico-in-progress"></i></a>
182
+ <?php continue;
183
+ }elseif( $tr_status->status == ICL_TM_WAITING_FOR_TRANSLATOR && !$job_id ){
184
+ $tr_job_id = $this->wpdb->get_var(
185
+ $this->wpdb->prepare(
186
+ "SELECT j.job_id FROM {$this->wpdb->prefix}icl_translate_job j
187
+ JOIN {$this->wpdb->prefix}icl_translation_status s ON j.rid = s.rid
188
+ WHERE s.translation_id = %d",
189
+ $product_translations[ $language[ 'code' ] ]->translation_id )
190
+ );
191
+ $translation_queue_page = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $tr_job_id );
192
+ $edit_url = apply_filters( 'icl_job_edit_url', $translation_queue_page, $tr_job_id );
193
+ ?>
194
+ <a href="<?php echo $edit_url ?>" title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Take this and edit', 'woocommerce-multilingual' ); ?>">
195
+ <i class="otgs-ico-add"></i>
196
+ </a>
197
+ <?php continue;
198
+ }
199
+ }
200
+ wpml_tm_load_status_display_filter();
201
+ } ?>
202
+ <a href="<?php echo apply_filters( 'wpml_link_to_translation', '', $original_product_id, $language[ 'code' ], $trid ) ?>"
203
+ <?php if( isset( $product_translations[ $language[ 'code' ] ] ) ){
204
+ $tr_status = $this->wpdb->get_row(
205
+ $this->wpdb->prepare(
206
+ "SELECT status,needs_update FROM {$this->wpdb->prefix}icl_translation_status
207
+ WHERE translation_id = %d",
208
+ $product_translations[ $language[ 'code' ] ]->translation_id )
209
+ );
210
+ if (!$tr_status ) { ?>
211
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
212
+ <i class="otgs-ico-add"></i>
213
+ <?php }elseif( $tr_status->needs_update ){ ?>
214
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Update translation', 'woocommerce-multilingual' ); ?>">
215
+ <i class="otgs-ico-refresh"></i>
216
+ <?php }elseif( $tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE ){ ?>
217
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Finish translating', 'woocommerce-multilingual' ); ?>">
218
+ <i class="otgs-ico-refresh"></i>
219
+ <?php }elseif( $tr_status->status == ICL_TM_COMPLETE ){ ?>
220
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
221
+ <i class="otgs-ico-edit"></i>
222
+ <?php }elseif( $tr_status->status == ICL_TM_DUPLICATE ){ ?>
223
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
224
+ <i class="otgs-ico-duplicate"></i>
225
+ <?php }
226
+ } else { ?>
227
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
228
+ <i class="otgs-ico-add"></i>
229
+ <?php } ?>
230
+ </a>
231
+ <?php } ?>
232
+ <?php }
233
+ }
234
+
235
+ public function wcml_override_is_translator( $is_translator, $user_id, $args ){
236
+
237
+ if( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ){
238
+ return true;
239
+ }
240
+
241
+ return $is_translator;
242
+ }
243
+
244
+ //product quickedit
245
+ public function filter_product_actions( $actions, $post ){
246
+ if(
247
+ $post->post_type == 'product' &&
248
+ !$this->is_original_product( $post->ID ) &&
249
+ isset( $actions[ 'inline hide-if-no-js' ] ) )
250
+ {
251
+ $new_actions = array();
252
+ foreach( $actions as $key => $action ) {
253
+ if( $key == 'inline hide-if-no-js' ) {
254
+ $new_actions[ 'quick_hide' ] = '<a href="#TB_inline?width=200&height=150&inlineId=quick_edit_notice" class="thickbox" title="' .
255
+ __('Edit this item inline', 'woocommerce-multilingual') . '">' .
256
+ __('Quick Edit', 'woocommerce-multilingual') . '</a>';
257
+ } else {
258
+ $new_actions[ $key ] = $action;
259
+ }
260
+ }
261
+ return $new_actions;
262
+ }
263
+ return $actions;
264
+ }
265
+
266
+ /**
267
+ * Filters upsell/crosell products in the correct language.
268
+ */
269
+ public function filter_found_products_by_language( $found_products ){
270
+ $current_page_language = $this->sitepress->get_current_language();
271
+
272
+ foreach( $found_products as $product_id => $output_v ){
273
+ $post_data = $this->wpdb->get_row(
274
+ $this->wpdb->prepare(
275
+ "SELECT * FROM {$this->wpdb->prefix}icl_translations
276
+ WHERE element_id = %d AND element_type LIKE 'post_%'", $product_id
277
+ )
278
+ );
279
+
280
+ $product_language = $post_data->language_code;
281
+
282
+ if( $product_language !== $current_page_language ){
283
+ unset( $found_products[ $product_id ] );
284
+ }
285
+ }
286
+
287
+ return $found_products;
288
+ }
289
+
290
+ /**
291
+ * Takes off translated products from the Up-sells/Cross-sells tab.
292
+ */
293
+ public function filter_woocommerce_upsell_crosssell_posts_by_language( $posts ){
294
+ foreach( $posts as $key => $post ){
295
+ $post_id = $posts[ $key ]->ID;
296
+ $post_data = $this->wpdb->get_row(
297
+ $this->wpdb->prepare(
298
+ "SELECT * FROM {$this->wpdb->prefix}icl_translations
299
+ WHERE element_id = %d ", $post_id
300
+ ),
301
+ ARRAY_A );
302
+
303
+ if( $post_data[ 'language_code' ] !== $this->sitepress->get_current_language() ){
304
+ unset( $posts[ $key ] );
305
+ }
306
+ }
307
+
308
+ return $posts;
309
+ }
310
+
311
+ public function woocommerce_json_search_found_products( $found_products ){
312
+
313
+ foreach( $found_products as $post => $formatted_product_name ) {
314
+ $parent = wp_get_post_parent_id( $post );
315
+ if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
316
+ && ( ( !$parent && $this->sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
317
+ || ( $parent && $this->sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
318
+ )
319
+ ||
320
+ ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
321
+ && ( ( !$parent && $this->is_original_product($post) )
322
+ || ( $parent && $this->is_original_product($parent) ) )
323
+ )
324
+ ) {
325
+
326
+ $new_found_products[$post] = $formatted_product_name;
327
+ }
328
+ }
329
+
330
+ return isset ( $new_found_products ) ? $new_found_products : $found_products ;
331
+ }
332
+
333
+ //update menu_order fro translations after ordering original products
334
+ public function update_all_products_translations_ordering(){
335
+ if( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) {
336
+ $current_language = $this->sitepress->get_current_language();
337
+ if( $current_language == $this->sitepress->get_default_language() ){
338
+ $products = $this->wpdb->get_results(
339
+ $this->wpdb->prepare(
340
+ "SELECT p.ID FROM {$this->wpdb->posts} AS p
341
+ LEFT JOIN {$this->wpdb->prefix}icl_translations AS icl
342
+ ON icl.element_id = p.id
343
+ WHERE p.post_type = 'product'
344
+ AND p.post_status IN ( 'publish', 'future', 'draft', 'pending', 'private' )
345
+ AND icl.element_type= 'post_product'
346
+ AND icl.language_code = %s",
347
+ $current_language )
348
+ );
349
+
350
+ foreach( $products as $product ){
351
+ $this->update_order_for_product_translations( $product->ID );
352
+ }
353
+ }
354
+ }
355
+ }
356
+
357
+ //update menu_order fro translations after ordering original products
358
+ public function update_order_for_product_translations( $product_id ){
359
+ if( isset( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) && $this->woocommerce_wpml->settings[ 'products_sync_order' ] ){
360
+ $current_language = $this->sitepress->get_current_language();
361
+
362
+ if ( $current_language == $this->sitepress->get_default_language() ) {
363
+ $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
364
+ $trid = $this->sitepress->get_element_trid($product_id, 'post_product');
365
+ $translations = $this->sitepress->get_element_translations($trid, 'post_product');
366
+
367
+ foreach( $translations as $translation ){
368
+ if( $translation->element_id != $product_id ){
369
+ $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation->element_id ) );
370
+ }
371
+ }
372
+ }
373
+ }
374
+ }
375
+
376
+ public function filter_excerpt_field_content_copy( $elements ) {
377
+
378
+ if ( $elements[ 'post_type' ] == 'product' ) {
379
+ $elements[ 'excerpt' ] ['editor_type'] = 'editor';
380
+ }
381
+ if ( function_exists( 'format_for_editor' ) ) {
382
+ // WordPress 4.3 uses format_for_editor
383
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( format_for_editor( $elements[ 'excerpt' ][ 'value' ], $_POST[ 'excerpt_type' ] ) );
384
+ } else {
385
+ // Backwards compatible for WordPress < 4.3
386
+ if($_POST[ 'excerpt_type'] == 'rich'){
387
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_richedit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
388
+ }else{
389
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_htmledit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
390
+ }
391
+ }
392
+ return $elements;
393
+ }
394
+
395
+ // Check if user can translate product
396
+ public function user_can_translate_product( $trid, $language_code ){
397
+ global $iclTranslationManagement;
398
+
399
+ $current_translator = $iclTranslationManagement->get_current_translator();
400
+ $job_id = $this->wpdb->get_var( $this->wpdb->prepare("
401
+ SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job tj
402
+ JOIN {$this->wpdb->prefix}icl_translation_status ts ON tj.rid = ts.rid
403
+ JOIN {$this->wpdb->prefix}icl_translations t ON ts.translation_id = t.translation_id
404
+ WHERE t.trid = %d AND t.language_code='%s'
405
+ ORDER BY tj.job_id DESC LIMIT 1
406
+ ", $trid, $language_code ) );
407
+
408
+ if( $job_id && wpml_check_user_is_translator( $this->sitepress->get_source_language_by_trid( $trid ), $language_code ) ){
409
+ return true;
410
+ }
411
+ return false;
412
+ }
413
+
414
+ public function filter_related_products_args( $args ){
415
+ if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
416
+ isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
417
+ $this->woocommerce_wpml->settings[ 'display_custom_prices' ] )
418
+ {
419
+
420
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
421
+ $woocommerce_currency = get_option('woocommerce_currency');
422
+
423
+ if( $client_currency != $woocommerce_currency ){
424
+ $args['meta_query'][] = array(
425
+ 'key' => '_wcml_custom_prices_status',
426
+ 'value' => 1,
427
+ 'compare' => '=',
428
+ );
429
+ }
430
+
431
+ }
432
+ return $args;
433
+ }
434
+
435
+ /*
436
+ * get meta ids for multiple values post meta key
437
+ */
438
+ public function get_mid_ids_by_key( $post_id, $meta_key ) {
439
+ $ids = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT meta_id FROM {$this->wpdb->postmeta} WHERE post_id = %d AND meta_key = %s", $post_id, $meta_key ) );
440
+ if( $ids )
441
+ return $ids;
442
+
443
+ return false;
444
+ }
445
+
446
+ // count "in progress" and "waiting on translation" as untranslated too
447
+ public function get_untranslated_products_count( $language ){
448
+
449
+ $count = 0;
450
+
451
+ $products = $this->wpdb->get_results( "
452
+ SELECT p.ID, t.trid, t.language_code
453
+ FROM {$this->wpdb->posts} AS p
454
+ LEFT JOIN {$this->wpdb->prefix}icl_translations AS t ON t.element_id = p.id
455
+ WHERE p.post_type = 'product' AND t.element_type = 'post_product' AND t.source_language_code IS NULL
456
+ " );
457
+
458
+ foreach( $products as $product ){
459
+ if( $product->language_code == $language ) continue;
460
+
461
+ $element_key = array( 'trid' => $product->trid, 'language_code' => $language );
462
+ $translation_status = apply_filters( 'wpml_tm_translation_status', null, $element_key );
463
+
464
+ if( in_array( $translation_status, array( ICL_TM_NOT_TRANSLATED, ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ) ) ){
465
+ $count++;
466
+ }
467
+ }
468
+
469
+ return $count;
470
+ }
471
+
472
+ public function is_hide_resign_button(){
473
+ global $iclTranslationManagement;
474
+
475
+ $hide_resign = false;
476
+
477
+ if( isset( $_GET[ 'source_language_code' ] ) && isset( $_GET[ 'language_code' ] ) ){
478
+
479
+ $from_lang = $_GET[ 'source_language_code' ];
480
+ $to_lang = $_GET[ 'language_code' ];
481
+
482
+ }elseif( isset( $_GET[ 'job_id' ] ) ){
483
+
484
+ $job = $iclTranslationManagement->get_translation_job( $_GET[ 'job_id' ] );
485
+ $from_lang = $job->source_language_code;
486
+ $to_lang = $job->language_code;
487
+
488
+ }
489
+
490
+ if( isset( $from_lang ) ){
491
+
492
+ $translators = $iclTranslationManagement->get_blog_translators(
493
+ array(
494
+ 'from' => $from_lang,
495
+ 'to' => $to_lang
496
+ )
497
+ );
498
+
499
+ if( empty( $translators ) || ( sizeof( $translators ) == 1 && $translators[0]->ID == get_current_user_id() ) ){
500
+ $hide_resign = true;
501
+ }
502
+
503
+ }
504
+
505
+ return $hide_resign;
506
+ }
507
+
508
+ public function switch_product_variations_language(){
509
+
510
+ $lang_to = false;
511
+ $post_id = false;
512
+
513
+ if ( isset( $_POST[ 'wpml_to' ] ) ) {
514
+ $lang_to = $_POST[ 'wpml_to' ];
515
+ }
516
+ if ( isset( $_POST[ 'wpml_post_id' ] ) ) {
517
+ $post_id = $_POST[ 'wpml_post_id' ];
518
+ }
519
+
520
+ if ( $post_id && $lang_to && get_post_type( $post_id ) == 'product' ) {
521
+ $product_variations = $this->woocommerce_wpml->sync_variations_data->get_product_variations( $post_id );
522
+ foreach( $product_variations as $product_variation ){
523
+ $trid = $this->sitepress->get_element_trid( $product_variation->ID, 'post_product_variation' );
524
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $product_variation->ID, 'product_variation', false, $lang_to );
525
+ if( is_null( $current_prod_variation_id ) ){
526
+ $this->sitepress->set_element_language_details( $product_variation->ID, 'post_product_variation', $trid, $lang_to );
527
+
528
+ foreach( get_post_custom( $product_variation->ID ) as $meta_key => $meta ) {
529
+ foreach ( $meta as $meta_value ) {
530
+ if ( substr( $meta_key, 0, 10 ) == 'attribute_' ) {
531
+ $trn_post_meta = $this->woocommerce_wpml->attributes->get_translated_variation_attribute_post_meta( $meta_value, $meta_key, $product_variation->ID, $product_variation->ID, $lang_to );
532
+ update_post_meta( $product_variation->ID, $trn_post_meta['meta_key'], $trn_post_meta['meta_value']);
533
+ }
534
+ }
535
+ }
536
+ }
537
+ }
538
+ }
539
+ }
540
+
541
  }
inc/class-wcml-reports.php CHANGED
@@ -1,267 +1,267 @@
1
- <?php
2
-
3
-
4
- class WCML_Reports{
5
-
6
- public $tab;
7
- public $report;
8
-
9
- public function __construct(){
10
-
11
- add_action('init', array($this, 'init'));
12
-
13
- }
14
-
15
- public function init(){
16
-
17
- if( isset($_GET['page']) && $_GET['page'] == 'wc-reports' ) {
18
-
19
- $this->tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'orders';
20
- $this->report = isset( $_GET['report'] ) ? $_GET['report'] : '';
21
-
22
- add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'filter_reports_query' ), 0 );
23
-
24
- if ( $this->tab == 'orders' && $this->report == 'sales_by_product' ) {
25
- add_filter( 'woocommerce_reports_get_order_report_data', array( $this, 'combine_report_by_languages' ) );
26
- }
27
-
28
- }
29
-
30
- add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
31
- add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
32
- add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
33
-
34
- }
35
-
36
- public function filter_reports_query($query){
37
- global $wpdb, $sitepress;
38
-
39
- $current_language = $sitepress->get_current_language();
40
- $active_languages = $sitepress->get_active_languages();
41
-
42
- if($this->tab == 'orders' && $this->report == 'sales_by_product'){
43
-
44
- $sparkline_query = strpos( $query[ 'select'], 'sparkline_value' ) !== false;
45
-
46
- if(
47
-
48
- $sparkline_query ||
49
- isset( $query[ 'order_by' ] ) && ( $query[ 'order_by' ] == 'ORDER BY order_item_qty DESC' || $query[ 'order_by' ] == 'ORDER BY order_item_total DESC' )
50
-
51
- ){
52
-
53
-
54
- $query[ 'select' ] .= " , order_language.meta_value AS order_language , translations.trid";
55
-
56
- $query[ 'join' ] .= " LEFT JOIN {$wpdb->postmeta} order_language ON posts.ID = order_language.post_id";
57
- $query[ 'where' ] .= " AND order_language.meta_key = 'wpml_language' ";
58
-
59
- $query[ 'join' ] .= " LEFT JOIN {$wpdb->prefix}icl_translations translations ON translations.element_id = order_item_meta__product_id.meta_value";
60
- $query[ 'where' ] .= " AND translations.element_type IN ('post_product','post_product_variation') ";
61
-
62
- if(!$sparkline_query){
63
- $limit = str_replace('LIMIT ', '', trim($query[ 'limit' ]));
64
- $query[ 'limit' ] = sprintf(" LIMIT %d ", $limit * count($active_languages));
65
- }
66
-
67
-
68
- if($sparkline_query){
69
- preg_match("#order_item_meta__product_id\.meta_value = '([0-9]+)'#", $query[ 'where' ], $matches);
70
- $product_id = $matches[1];
71
- $post_type = get_post_type($product_id);
72
- $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
73
- $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
74
- $product_ids = array();
75
- foreach($translations as $translation){
76
- $product_ids[] = $translation->element_id;
77
- }
78
-
79
- $query[ 'where' ] = str_replace("order_item_meta__product_id.meta_value = '{$product_id}'", "order_item_meta__product_id.meta_value IN(" . join(',', $product_ids) . ")", $query[ 'where' ]);
80
-
81
- }
82
-
83
- $query[ 'select' ] .= ', translations.language_code AS language_code_' . esc_sql( $current_language ); // user for per-language caching
84
-
85
- }elseif(
86
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount' || //sales for the selected items
87
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count' || //purchases for the selected items
88
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' || //Get orders and dates in range - main chart: order_item_counts
89
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' //Get orders and dates in range - main chart: order_item_amounts
90
-
91
- ){
92
-
93
- preg_match("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", $query[ 'where' ], $matches);
94
- $product_ids = array();
95
- $exp = array_map('trim', explode(',', $matches[1]));
96
- foreach($exp as $e){
97
- $product_ids[] = trim($e, "'");
98
- }
99
- $all_product_ids = array();
100
- foreach($product_ids as $product_id){
101
- $post_type = get_post_type($product_id);
102
- $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
103
- $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
104
- foreach($translations as $translation){
105
- $all_product_ids[] = $translation->element_id;
106
- }
107
- }
108
-
109
- $query[ 'where' ] = preg_replace("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", "order_item_meta__product_id_array.meta_value IN (" . join(',', $all_product_ids) . ")", $query[ 'where' ]);
110
-
111
-
112
- }
113
-
114
- }
115
-
116
- return $query;
117
- }
118
-
119
-
120
- public function combine_report_by_languages($results){
121
- global $sitepress, $wpdb;
122
-
123
- if(is_array($results) && isset($results['0']->order_item_qty)){
124
- $mode = 'top_sellers';
125
- }elseif(is_array($results) && isset($results['0']->order_item_total)){
126
- $mode = 'top_earners';
127
- }elseif(isset($results['0']->sparkline_value)){
128
- $mode = 'top_sellers_spark';
129
- }else{
130
- return $results;
131
- }
132
-
133
- if(!isset($results['0']->trid)) return $results;
134
-
135
- $current_language = $sitepress->get_current_language();
136
-
137
- $combined_results = array();
138
-
139
- foreach($results as $k => $row){
140
-
141
- switch($mode){
142
- case 'top_sellers':
143
- case 'top_earners':
144
- $key = $row->trid;
145
- break;
146
- case 'top_sellers_spark':
147
- $key = $row->trid . '#' . substr($row->post_date, 0, 10);
148
- break;
149
- }
150
-
151
- if($row->order_language == $current_language){
152
-
153
- $combined_results[$key] = $row;
154
-
155
- }
156
-
157
- }
158
-
159
- foreach($results as $k => $row){
160
-
161
- if($row->order_language != $current_language){
162
-
163
- switch($mode){
164
- case 'top_sellers':
165
- case 'top_earners':
166
- $key = $row->trid;
167
- break;
168
- case 'top_sellers_spark':
169
- $key = $row->trid . '#' . substr($row->post_date, 0, 10);
170
- break;
171
- }
172
-
173
- if(isset($combined_results[$key])){
174
-
175
- switch($mode){
176
- case 'top_sellers':
177
- $combined_results[$key]->order_item_qty += $row->order_item_qty;
178
- break;
179
- case 'top_earners':
180
- $combined_results[$key]->order_item_total += $row->order_item_total;
181
- break;
182
- case 'top_sellers_spark':
183
- $combined_results[$key]->sparkline_value += $row->sparkline_value;
184
- break;
185
-
186
- }
187
-
188
- }else{
189
-
190
- $default_product_id = apply_filters( 'translate_object_id',$row->product_id, 'product', false, $current_language);
191
-
192
- if($default_product_id){
193
- $combined_results[$key] = new stdClass();
194
- $combined_results[$key]->product_id = $default_product_id;
195
-
196
- switch($mode){
197
- case 'top_sellers':
198
- $combined_results[$key]->order_item_qty = $row->order_item_qty;
199
- break;
200
- case 'top_earners':
201
- $combined_results[$key]->order_item_total = $row->order_item_total;
202
- break;
203
- case 'top_sellers_spark':
204
- $combined_results[$key]->sparkline_value = $row->sparkline_value;
205
- $combined_results[$key]->post_date = $row->post_date;
206
- break;
207
- }
208
-
209
- }
210
-
211
- }
212
-
213
-
214
- }
215
-
216
- }
217
-
218
- switch($mode){
219
- case 'top_sellers':
220
- usort($combined_results, array(__CLASS__, '_order_by_quantity'));
221
- array_slice($combined_results, 0, 12);
222
- break;
223
- case 'top_earners':
224
- usort($combined_results, array(__CLASS__, '_order_by_total'));
225
- array_slice($combined_results, 0, 12);
226
- break;
227
- case 'top_sellers_spark':
228
- break;
229
-
230
-
231
- }
232
-
233
- foreach($combined_results as $k => $row){
234
- unset($combined_results[$k]->trid, $combined_results[$k]->order_language);
235
- }
236
-
237
-
238
- return $combined_results;
239
- }
240
-
241
- private static function _order_by_quantity($a, $b){
242
- return $a->order_item_qty < $b->order_item_qty;
243
- }
244
-
245
- private static function _order_by_total($a, $b){
246
- return $a->order_item_total < $b->order_item_total;
247
- }
248
-
249
- public function filter_reports_stock_query( $query_from ){
250
- global $wpdb, $sitepress;
251
-
252
- $current_language = $sitepress->get_current_language();
253
-
254
- if( $current_language !== 'all' ){
255
- $query_from = preg_replace("/WHERE/",
256
- "LEFT JOIN {$wpdb->prefix}icl_translations AS t
257
- ON posts.ID = t.element_id
258
- WHERE", $query_from);
259
-
260
- $query_from .= " AND t.element_type IN ( 'post_product', 'post_product_variation' ) AND t.language_code = '".$current_language."'";
261
- }
262
-
263
-
264
- return $query_from;
265
- }
266
-
267
- }
1
+ <?php
2
+
3
+
4
+ class WCML_Reports{
5
+
6
+ public $tab;
7
+ public $report;
8
+
9
+ public function __construct(){
10
+
11
+ add_action('init', array($this, 'init'));
12
+
13
+ }
14
+
15
+ public function init(){
16
+
17
+ if( isset($_GET['page']) && $_GET['page'] == 'wc-reports' ) {
18
+
19
+ $this->tab = isset( $_GET['tab'] ) ? $_GET['tab'] : 'orders';
20
+ $this->report = isset( $_GET['report'] ) ? $_GET['report'] : '';
21
+
22
+ add_filter( 'woocommerce_reports_get_order_report_query', array( $this, 'filter_reports_query' ), 0 );
23
+
24
+ if ( $this->tab == 'orders' && $this->report == 'sales_by_product' ) {
25
+ add_filter( 'woocommerce_reports_get_order_report_data', array( $this, 'combine_report_by_languages' ) );
26
+ }
27
+
28
+ }
29
+
30
+ add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
31
+ add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
32
+ add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
33
+
34
+ }
35
+
36
+ public function filter_reports_query($query){
37
+ global $wpdb, $sitepress;
38
+
39
+ $current_language = $sitepress->get_current_language();
40
+ $active_languages = $sitepress->get_active_languages();
41
+
42
+ if($this->tab == 'orders' && $this->report == 'sales_by_product'){
43
+
44
+ $sparkline_query = strpos( $query[ 'select'], 'sparkline_value' ) !== false;
45
+
46
+ if(
47
+
48
+ $sparkline_query ||
49
+ isset( $query[ 'order_by' ] ) && ( $query[ 'order_by' ] == 'ORDER BY order_item_qty DESC' || $query[ 'order_by' ] == 'ORDER BY order_item_total DESC' )
50
+
51
+ ){
52
+
53
+
54
+ $query[ 'select' ] .= " , order_language.meta_value AS order_language , translations.trid";
55
+
56
+ $query[ 'join' ] .= " LEFT JOIN {$wpdb->postmeta} order_language ON posts.ID = order_language.post_id";
57
+ $query[ 'where' ] .= " AND order_language.meta_key = 'wpml_language' ";
58
+
59
+ $query[ 'join' ] .= " LEFT JOIN {$wpdb->prefix}icl_translations translations ON translations.element_id = order_item_meta__product_id.meta_value";
60
+ $query[ 'where' ] .= " AND translations.element_type IN ('post_product','post_product_variation') ";
61
+
62
+ if(!$sparkline_query){
63
+ $limit = str_replace('LIMIT ', '', trim($query[ 'limit' ]));
64
+ $query[ 'limit' ] = sprintf(" LIMIT %d ", $limit * count($active_languages));
65
+ }
66
+
67
+
68
+ if($sparkline_query){
69
+ preg_match("#order_item_meta__product_id\.meta_value = '([0-9]+)'#", $query[ 'where' ], $matches);
70
+ $product_id = $matches[1];
71
+ $post_type = get_post_type($product_id);
72
+ $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
73
+ $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
74
+ $product_ids = array();
75
+ foreach($translations as $translation){
76
+ $product_ids[] = $translation->element_id;
77
+ }
78
+
79
+ $query[ 'where' ] = str_replace("order_item_meta__product_id.meta_value = '{$product_id}'", "order_item_meta__product_id.meta_value IN(" . join(',', $product_ids) . ")", $query[ 'where' ]);
80
+
81
+ }
82
+
83
+ $query[ 'select' ] .= ', translations.language_code AS language_code_' . esc_sql( str_replace('-', '_', $current_language) ); // user for per-language caching
84
+
85
+ }elseif(
86
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount' || //sales for the selected items
87
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count' || //purchases for the selected items
88
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' || //Get orders and dates in range - main chart: order_item_counts
89
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' //Get orders and dates in range - main chart: order_item_amounts
90
+
91
+ ){
92
+
93
+ preg_match("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", $query[ 'where' ], $matches);
94
+ $product_ids = array();
95
+ $exp = array_map('trim', explode(',', $matches[1]));
96
+ foreach($exp as $e){
97
+ $product_ids[] = trim($e, "'");
98
+ }
99
+ $all_product_ids = array();
100
+ foreach($product_ids as $product_id){
101
+ $post_type = get_post_type($product_id);
102
+ $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
103
+ $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
104
+ foreach($translations as $translation){
105
+ $all_product_ids[] = $translation->element_id;
106
+ }
107
+ }
108
+
109
+ $query[ 'where' ] = preg_replace("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", "order_item_meta__product_id_array.meta_value IN (" . join(',', $all_product_ids) . ")", $query[ 'where' ]);
110
+
111
+
112
+ }
113
+
114
+ }
115
+
116
+ return $query;
117
+ }
118
+
119
+
120
+ public function combine_report_by_languages($results){
121
+ global $sitepress, $wpdb;
122
+
123
+ if(is_array($results) && isset($results['0']->order_item_qty)){
124
+ $mode = 'top_sellers';
125
+ }elseif(is_array($results) && isset($results['0']->order_item_total)){
126
+ $mode = 'top_earners';
127
+ }elseif(isset($results['0']->sparkline_value)){
128
+ $mode = 'top_sellers_spark';
129
+ }else{
130
+ return $results;
131
+ }
132
+
133
+ if(!isset($results['0']->trid)) return $results;
134
+
135
+ $current_language = $sitepress->get_current_language();
136
+
137
+ $combined_results = array();
138
+
139
+ foreach($results as $k => $row){
140
+
141
+ switch($mode){
142
+ case 'top_sellers':
143
+ case 'top_earners':
144
+ $key = $row->trid;
145
+ break;
146
+ case 'top_sellers_spark':
147
+ $key = $row->trid . '#' . substr($row->post_date, 0, 10);
148
+ break;
149
+ }
150
+
151
+ if($row->order_language == $current_language){
152
+
153
+ $combined_results[$key] = $row;
154
+
155
+ }
156
+
157
+ }
158
+
159
+ foreach($results as $k => $row){
160
+
161
+ if($row->order_language != $current_language){
162
+
163
+ switch($mode){
164
+ case 'top_sellers':
165
+ case 'top_earners':
166
+ $key = $row->trid;
167
+ break;
168
+ case 'top_sellers_spark':
169
+ $key = $row->trid . '#' . substr($row->post_date, 0, 10);
170
+ break;
171
+ }
172
+
173
+ if(isset($combined_results[$key])){
174
+
175
+ switch($mode){
176
+ case 'top_sellers':
177
+ $combined_results[$key]->order_item_qty += $row->order_item_qty;
178
+ break;
179
+ case 'top_earners':
180
+ $combined_results[$key]->order_item_total += $row->order_item_total;
181
+ break;
182
+ case 'top_sellers_spark':
183
+ $combined_results[$key]->sparkline_value += $row->sparkline_value;
184
+ break;
185
+
186
+ }
187
+
188
+ }else{
189
+
190
+ $default_product_id = apply_filters( 'translate_object_id',$row->product_id, 'product', false, $current_language);
191
+
192
+ if($default_product_id){
193
+ $combined_results[$key] = new stdClass();
194
+ $combined_results[$key]->product_id = $default_product_id;
195
+
196
+ switch($mode){
197
+ case 'top_sellers':
198
+ $combined_results[$key]->order_item_qty = $row->order_item_qty;
199
+ break;
200
+ case 'top_earners':
201
+ $combined_results[$key]->order_item_total = $row->order_item_total;
202
+ break;
203
+ case 'top_sellers_spark':
204
+ $combined_results[$key]->sparkline_value = $row->sparkline_value;
205
+ $combined_results[$key]->post_date = $row->post_date;
206
+ break;
207
+ }
208
+
209
+ }
210
+
211
+ }
212
+
213
+
214
+ }
215
+
216
+ }
217
+
218
+ switch($mode){
219
+ case 'top_sellers':
220
+ usort($combined_results, array(__CLASS__, '_order_by_quantity'));
221
+ array_slice($combined_results, 0, 12);
222
+ break;
223
+ case 'top_earners':
224
+ usort($combined_results, array(__CLASS__, '_order_by_total'));
225
+ array_slice($combined_results, 0, 12);
226
+ break;
227
+ case 'top_sellers_spark':
228
+ break;
229
+
230
+
231
+ }
232
+
233
+ foreach($combined_results as $k => $row){
234
+ unset($combined_results[$k]->trid, $combined_results[$k]->order_language);
235
+ }
236
+
237
+
238
+ return $combined_results;
239
+ }
240
+
241
+ private static function _order_by_quantity($a, $b){
242
+ return $a->order_item_qty < $b->order_item_qty;
243
+ }
244
+
245
+ private static function _order_by_total($a, $b){
246
+ return $a->order_item_total < $b->order_item_total;
247
+ }
248
+
249
+ public function filter_reports_stock_query( $query_from ){
250
+ global $wpdb, $sitepress;
251
+
252
+ $current_language = $sitepress->get_current_language();
253
+
254
+ if( $current_language !== 'all' ){
255
+ $query_from = preg_replace("/WHERE/",
256
+ "LEFT JOIN {$wpdb->prefix}icl_translations AS t
257
+ ON posts.ID = t.element_id
258
+ WHERE", $query_from);
259
+
260
+ $query_from .= " AND t.element_type IN ( 'post_product', 'post_product_variation' ) AND t.language_code = '".$current_language."'";
261
+ }
262
+
263
+
264
+ return $query_from;
265
+ }
266
+
267
+ }
inc/class-wcml-requests.php CHANGED
@@ -1,87 +1,87 @@
1
- <?php
2
- class WCML_Requests{
3
-
4
- function __construct(){
5
-
6
- add_action('init', array($this, 'run') );
7
-
8
-
9
- }
10
-
11
- function run(){
12
- global $woocommerce_wpml;
13
-
14
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
15
-
16
- if(isset($_POST['wcml_save_settings']) && wp_verify_nonce($nonce, 'wcml_save_settings_nonce')){
17
- global $sitepress,$sitepress_settings;
18
-
19
- $woocommerce_wpml->settings['trnsl_interface'] = filter_input( INPUT_POST, 'trnsl_interface', FILTER_SANITIZE_NUMBER_INT );
20
-
21
- $woocommerce_wpml->settings['products_sync_date'] = empty($_POST['products_sync_date']) ? 0 : 1;
22
- $woocommerce_wpml->settings['products_sync_order'] = empty($_POST['products_sync_order']) ? 0 : 1;
23
-
24
- $wcml_file_path_sync = filter_input( INPUT_POST, 'wcml_file_path_sync', FILTER_SANITIZE_NUMBER_INT );
25
-
26
- $woocommerce_wpml->settings['file_path_sync'] = $wcml_file_path_sync;
27
-
28
- $woocommerce_wpml->settings['cart_sync']['lang_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT ) );
29
- $woocommerce_wpml->settings['cart_sync']['currency_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT ) );
30
-
31
- $woocommerce_wpml->update_settings();
32
-
33
- $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
34
- $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
35
- $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
36
-
37
- $sitepress->save_settings($sitepress_settings);
38
-
39
- $message = array(
40
- 'id' => 'wcml-settings-saved',
41
- 'text' => __('Your settings have been saved.', 'woocommerce-multilingual' ),
42
- 'group' => 'wcml-settings',
43
- 'admin_notice' => true,
44
- 'limit_to_page' => true,
45
- 'classes' => array('updated', 'notice', 'notice-success'),
46
- 'show_once' => true
47
- );
48
- ICL_AdminNotifier::add_message( $message );
49
- }
50
-
51
- if( isset( $_GET[ 'wcml_action' ] ) ){
52
- if( $_GET['wcml_action'] == 'dismiss' ){
53
- $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
54
- }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
55
- $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
56
- }
57
- $woocommerce_wpml->update_settings();
58
- }
59
-
60
- add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
61
-
62
- // Override cached widget id
63
- add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
64
- }
65
-
66
- function update_settings_from_warning(){
67
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
68
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
69
- die('Invalid nonce');
70
- }
71
- global $woocommerce_wpml;
72
-
73
- $woocommerce_wpml->settings[$_POST['setting']] = 1;
74
- $woocommerce_wpml->update_settings();
75
-
76
- }
77
-
78
- public function override_cached_widget_id( $widget_id ){
79
-
80
- if( defined( 'ICL_LANGUAGE_CODE' ) ){
81
- $widget_id .= ':' . ICL_LANGUAGE_CODE;
82
- }
83
-
84
- return $widget_id;
85
- }
86
-
87
  }
1
+ <?php
2
+ class WCML_Requests{
3
+
4
+ function __construct(){
5
+
6
+ add_action('init', array($this, 'run') );
7
+
8
+
9
+ }
10
+
11
+ function run(){
12
+ global $woocommerce_wpml;
13
+
14
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
15
+
16
+ if(isset($_POST['wcml_save_settings']) && wp_verify_nonce($nonce, 'wcml_save_settings_nonce')){
17
+ global $sitepress,$sitepress_settings;
18
+
19
+ $woocommerce_wpml->settings['trnsl_interface'] = filter_input( INPUT_POST, 'trnsl_interface', FILTER_SANITIZE_NUMBER_INT );
20
+
21
+ $woocommerce_wpml->settings['products_sync_date'] = empty($_POST['products_sync_date']) ? 0 : 1;
22
+ $woocommerce_wpml->settings['products_sync_order'] = empty($_POST['products_sync_order']) ? 0 : 1;
23
+
24
+ $wcml_file_path_sync = filter_input( INPUT_POST, 'wcml_file_path_sync', FILTER_SANITIZE_NUMBER_INT );
25
+
26
+ $woocommerce_wpml->settings['file_path_sync'] = $wcml_file_path_sync;
27
+
28
+ $woocommerce_wpml->settings['cart_sync']['lang_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT ) );
29
+ $woocommerce_wpml->settings['cart_sync']['currency_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT ) );
30
+
31
+ $woocommerce_wpml->update_settings();
32
+
33
+ $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
34
+ $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
35
+ $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
36
+
37
+ $sitepress->save_settings($sitepress_settings);
38
+
39
+ $message = array(
40
+ 'id' => 'wcml-settings-saved',
41
+ 'text' => __('Your settings have been saved.', 'woocommerce-multilingual' ),
42
+ 'group' => 'wcml-settings',
43
+ 'admin_notice' => true,
44
+ 'limit_to_page' => true,
45
+ 'classes' => array('updated', 'notice', 'notice-success'),
46
+ 'show_once' => true
47
+ );
48
+ ICL_AdminNotifier::add_message( $message );
49
+ }
50
+
51
+ if( isset( $_GET[ 'wcml_action' ] ) ){
52
+ if( $_GET['wcml_action'] == 'dismiss' ){
53
+ $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
54
+ }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
55
+ $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
56
+ }
57
+ $woocommerce_wpml->update_settings();
58
+ }
59
+
60
+ add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
61
+
62
+ // Override cached widget id
63
+ add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
64
+ }
65
+
66
+ function update_settings_from_warning(){
67
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
68
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
69
+ die('Invalid nonce');
70
+ }
71
+ global $woocommerce_wpml;
72
+
73
+ $woocommerce_wpml->settings[$_POST['setting']] = 1;
74
+ $woocommerce_wpml->update_settings();
75
+
76
+ }
77
+
78
+ public function override_cached_widget_id( $widget_id ){
79
+
80
+ if( defined( 'ICL_LANGUAGE_CODE' ) ){
81
+ $widget_id .= ':' . ICL_LANGUAGE_CODE;
82
+ }
83
+
84
+ return $widget_id;
85
+ }
86
+
87
  }
inc/class-wcml-resources.php CHANGED
@@ -1,244 +1,244 @@
1
- <?php
2
-
3
- class WCML_Resources {
4
-
5
- private static $page;
6
- private static $tab;
7
- private static $is_wpml_wcml_page;
8
- private static $pagenow;
9
-
10
- private static $woocommerce_wpml;
11
- private static $sitepress;
12
-
13
- public static function set_up_resources( &$woocommerce_wpml, &$sitepress ) {
14
- global $pagenow;
15
-
16
- self::$woocommerce_wpml =& $woocommerce_wpml;
17
- self::$sitepress =& $sitepress;
18
-
19
- self::$page = isset($_GET['page']) ? $_GET['page'] : null;
20
- self::$tab = isset($_GET['tab']) ? $_GET['tab'] : null;
21
- self::$is_wpml_wcml_page = self::$page == 'wpml-wcml';
22
- self::$pagenow = $pagenow;
23
-
24
- self::load_css();
25
- self::load_js();
26
-
27
- $is_edit_product = self::$pagenow == 'post.php' && isset($_GET['post']) && get_post_type( $_GET['post'] ) == 'product';
28
- $is_original_product = isset( $_GET['post'] ) && !is_array( $_GET['post'] ) && self::$woocommerce_wpml->products->is_original_product( $_GET['post'] );
29
- $is_new_product = self::$pagenow == 'post-new.php' && isset($_GET['source_lang']) && isset($_GET['post_type']) && $_GET['post_type'] == 'product';
30
-
31
- if ( ($is_edit_product && !$is_original_product) || $is_new_product && !self::$woocommerce_wpml->settings['trnsl_interface'] ) {
32
- add_action( 'init', array(__CLASS__, 'load_lock_fields_js') );
33
- add_action( 'admin_footer', array(__CLASS__, 'hidden_label') );
34
- }
35
- }
36
-
37
- private static function load_css() {
38
-
39
- if ( self::$is_wpml_wcml_page || self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
40
-
41
- self::load_management_css();
42
-
43
- if ( in_array( self::$tab, array('multi-currency', 'slugs') ) ) {
44
- wp_register_style( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/css/dialogs.css', array('wpml-dialog'), WCML_VERSION );
45
- wp_enqueue_style( 'wcml-dialogs' );
46
- }
47
- }
48
-
49
- if ( self::$pagenow == 'options-permalink.php' ) {
50
- wp_register_style( 'wcml_op', WCML_PLUGIN_URL . '/res/css/options-permalink.css', null, WCML_VERSION );
51
- wp_enqueue_style( 'wcml_op' );
52
- }
53
-
54
- wp_register_style( 'wcml_admin', WCML_PLUGIN_URL . '/res/css/admin.css', array( 'wp-pointer' ), WCML_VERSION );
55
- wp_enqueue_style( 'wcml_admin' );
56
- }
57
-
58
- public static function load_management_css() {
59
- wp_register_style( 'wpml-wcml', WCML_PLUGIN_URL . '/res/css/management.css', array(), WCML_VERSION );
60
- wp_enqueue_style( 'wpml-wcml' );
61
- }
62
-
63
- private static function load_js() {
64
-
65
- wp_register_script( 'wcml-scripts', WCML_PLUGIN_URL . '/res/js/scripts' . WCML_JS_MIN . '.js', array(
66
- 'jquery',
67
- 'jquery-ui-core',
68
- 'jquery-ui-resizable'
69
- ), WCML_VERSION );
70
-
71
- wp_enqueue_script(
72
- 'wcml-pointer',
73
- WCML_PLUGIN_URL . '/res/js/pointer' . WCML_JS_MIN . '.js',
74
- array( 'wp-pointer' ),
75
- WCML_VERSION,
76
- true
77
- );
78
-
79
- wp_register_script( 'wcml-front-scripts', WCML_PLUGIN_URL . '/res/js/front-scripts' . WCML_JS_MIN . '.js', array(
80
- 'jquery'
81
- ), WCML_VERSION );
82
- wp_enqueue_script( 'wcml-front-scripts' );
83
-
84
- if ( self::$is_wpml_wcml_page ) {
85
-
86
- wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
87
- wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core', 'jquery-ui-dialog'), WCML_VERSION );
88
- wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
89
-
90
- wp_enqueue_script( 'wcml-dialogs' );
91
- wp_enqueue_script( 'wcml-scripts' );
92
- wp_enqueue_script( 'jquery-cookie' );
93
- wp_enqueue_script( 'wcml-troubleshooting' );
94
-
95
- wp_localize_script( 'wcml-scripts', 'wcml_settings',
96
- array(
97
- 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
98
- )
99
- );
100
-
101
- self::load_tooltip_resources();
102
- }
103
-
104
- if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
105
- wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
106
- wp_enqueue_script( 'wpml_tm' );
107
- }
108
-
109
- if ( self::$page == 'wpml-wcml' && self::$tab == 'multi-currency' ) {
110
- wp_register_script( 'multi-currency', WCML_PLUGIN_URL . '/res/js/multi-currency' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-sortable'), WCML_VERSION, true );
111
- wp_enqueue_script( 'multi-currency' );
112
- wp_register_script( 'exchange-rates', WCML_PLUGIN_URL . '/res/js/exchange-rates' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
113
- wp_enqueue_script( 'exchange-rates' );
114
- }
115
-
116
- if ( self::$page == 'wpml-wcml' && self::$tab == 'product-attributes' ) {
117
- wp_register_script( 'product-attributes', WCML_PLUGIN_URL . '/res/js/product-attributes' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
118
- wp_enqueue_script( 'product-attributes' );
119
- }
120
-
121
- if ( self::$page == 'wpml-wcml' && self::$tab == 'custom-taxonomies' ) {
122
- wp_register_script( 'custom-taxonomies', WCML_PLUGIN_URL . '/res/js/product-custom-taxonomies' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
123
- wp_enqueue_script( 'custom-taxonomies' );
124
- }
125
-
126
- if ( !is_admin() ) {
127
- $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
128
-
129
- wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
130
- wp_enqueue_script( 'cart-widget' );
131
- wp_localize_script( 'cart-widget', 'actions', array(
132
- 'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
133
- 'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0
134
- ) );
135
- } else {
136
- wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
137
- wp_enqueue_script( 'wcml-messages' );
138
- }
139
-
140
- $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
141
-
142
- if( $is_attr_page ){
143
- wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
144
- wp_enqueue_script( 'wcml-attributes' );
145
- }
146
-
147
- if( self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
148
-
149
- self::load_tooltip_resources();
150
- wp_enqueue_media();
151
- wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core'), WCML_VERSION);
152
- wp_enqueue_script( 'wcml-editor' );
153
- wp_localize_script( 'wcml-editor', 'wcml_settings',
154
- array(
155
- 'strings' => array(
156
- 'choose' => __( 'Choose a file', 'woocommerce_multilingual' ),
157
- 'save_tooltip' => __( 'At least one of these fields is required: title, content or excerpt', 'woocommerce_multilingual' ),
158
- 'resign_tooltip'=> __( 'This translation job will no longer be assigned to you. Other translators will be able take it and continue the translation.', 'woocommerce-multilingual')
159
- ),
160
- 'hide_resign' => self::$woocommerce_wpml->products->is_hide_resign_button()
161
- )
162
- );
163
- }
164
-
165
- if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
166
- self::load_tooltip_resources();
167
- wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION );
168
- wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
169
- }
170
- }
171
-
172
- public static function load_tooltip_resources() {
173
-
174
- if ( class_exists( 'woocommerce' ) ) {
175
- wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
176
- wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
177
- wp_enqueue_script( 'jquery-tiptip' );
178
- wp_enqueue_script( 'wcml-tooltip-init' );
179
- wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
180
- }
181
-
182
- }
183
-
184
- public static function load_lock_fields_js() {
185
-
186
- wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
187
- wp_enqueue_script( 'wcml-lock-script' );
188
-
189
- $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
190
- if( isset( $_GET[ 'post' ] ) ){
191
- $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET[ 'post' ] );
192
- $original_id = apply_filters( 'translate_object_id', $_GET[ 'post' ], 'product', true, $original_language );
193
- $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
194
- if( $custom_product_sync && $custom_product_sync == 'self' ) {
195
- $file_path_sync = false;
196
- }elseif( $custom_product_sync && $custom_product_sync == 'auto' ){
197
- $file_path_sync = true;
198
- }
199
- }
200
-
201
- wp_localize_script( 'wcml-lock-script', 'unlock_fields', array(
202
- 'menu_order' => self::$woocommerce_wpml->settings['products_sync_order'],
203
- 'file_paths' => $file_path_sync
204
- )
205
- );
206
- wp_localize_script( 'wcml-lock-script', 'non_standard_fields', array(
207
- 'ids' => apply_filters( 'wcml_js_lock_fields_ids', array() ),
208
- 'classes' => apply_filters( 'wcml_js_lock_fields_classes', array() ),
209
- 'input_names' => apply_filters( 'wcml_js_lock_fields_input_names', array() )
210
- ) );
211
-
212
- do_action( 'wcml_after_load_lock_fields_js' );
213
-
214
- }
215
-
216
- public static function hidden_label() {
217
- global $sitepress;
218
-
219
- echo '<img src="' . WCML_PLUGIN_URL . '/res/images/locked.png" class="wcml_lock_img wcml_lock_icon" alt="' .
220
- __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
221
- '" title="' . __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
222
- '" style="display: none;position:relative;left:2px;top:2px;">';
223
-
224
- if ( isset($_GET['post']) ) {
225
- $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET['post'] );
226
- $original_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $original_language );
227
- } elseif ( isset($_GET['trid']) ) {
228
- $original_id = $sitepress->get_original_element_id_by_trid( $_GET['trid'] );
229
- }
230
-
231
- if ( isset($_GET['lang']) ) {
232
- $language = $_GET['lang'];
233
- } else {
234
- return;
235
- }
236
-
237
- echo '<h3 class="wcml_prod_hidden_notice">' .
238
- sprintf( __( "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products.",
239
- 'woocommerce-multilingual' ),
240
- '<a href="' . get_edit_post_link( $original_id ) . '" >' . get_the_title( $original_id ) . '</a>',
241
- '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
242
- __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
243
- }
244
  }
1
+ <?php
2
+
3
+ class WCML_Resources {
4
+
5
+ private static $page;
6
+ private static $tab;
7
+ private static $is_wpml_wcml_page;
8
+ private static $pagenow;
9
+
10
+ private static $woocommerce_wpml;
11
+ private static $sitepress;
12
+
13
+ public static function set_up_resources( &$woocommerce_wpml, &$sitepress ) {
14
+ global $pagenow;
15
+
16
+ self::$woocommerce_wpml =& $woocommerce_wpml;
17
+ self::$sitepress =& $sitepress;
18
+
19
+ self::$page = isset($_GET['page']) ? $_GET['page'] : null;
20
+ self::$tab = isset($_GET['tab']) ? $_GET['tab'] : null;
21
+ self::$is_wpml_wcml_page = self::$page == 'wpml-wcml';
22
+ self::$pagenow = $pagenow;
23
+
24
+ self::load_css();
25
+ self::load_js();
26
+
27
+ $is_edit_product = self::$pagenow == 'post.php' && isset($_GET['post']) && get_post_type( $_GET['post'] ) == 'product';
28
+ $is_original_product = isset( $_GET['post'] ) && !is_array( $_GET['post'] ) && self::$woocommerce_wpml->products->is_original_product( $_GET['post'] );
29
+ $is_new_product = self::$pagenow == 'post-new.php' && isset($_GET['source_lang']) && isset($_GET['post_type']) && $_GET['post_type'] == 'product';
30
+
31
+ if ( ($is_edit_product && !$is_original_product) || $is_new_product && !self::$woocommerce_wpml->settings['trnsl_interface'] ) {
32
+ add_action( 'init', array(__CLASS__, 'load_lock_fields_js') );
33
+ add_action( 'admin_footer', array(__CLASS__, 'hidden_label') );
34
+ }
35
+ }
36
+
37
+ private static function load_css() {
38
+
39
+ if ( self::$is_wpml_wcml_page || self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
40
+
41
+ self::load_management_css();
42
+
43
+ if ( in_array( self::$tab, array('multi-currency', 'slugs') ) ) {
44
+ wp_register_style( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/css/dialogs.css', array('wpml-dialog'), WCML_VERSION );
45
+ wp_enqueue_style( 'wcml-dialogs' );
46
+ }
47
+ }
48
+
49
+ if ( self::$pagenow == 'options-permalink.php' ) {
50
+ wp_register_style( 'wcml_op', WCML_PLUGIN_URL . '/res/css/options-permalink.css', null, WCML_VERSION );
51
+ wp_enqueue_style( 'wcml_op' );
52
+ }
53
+
54
+ wp_register_style( 'wcml_admin', WCML_PLUGIN_URL . '/res/css/admin.css', array( 'wp-pointer' ), WCML_VERSION );
55
+ wp_enqueue_style( 'wcml_admin' );
56
+ }
57
+
58
+ public static function load_management_css() {
59
+ wp_register_style( 'wpml-wcml', WCML_PLUGIN_URL . '/res/css/management.css', array(), WCML_VERSION );
60
+ wp_enqueue_style( 'wpml-wcml' );
61
+ }
62
+
63
+ private static function load_js() {
64
+
65
+ wp_register_script( 'wcml-scripts', WCML_PLUGIN_URL . '/res/js/scripts' . WCML_JS_MIN . '.js', array(
66
+ 'jquery',
67
+ 'jquery-ui-core',
68
+ 'jquery-ui-resizable'
69
+ ), WCML_VERSION );
70
+
71
+ wp_enqueue_script(
72
+ 'wcml-pointer',
73
+ WCML_PLUGIN_URL . '/res/js/pointer' . WCML_JS_MIN . '.js',
74
+ array( 'wp-pointer' ),
75
+ WCML_VERSION,
76
+ true
77
+ );
78
+
79
+ wp_register_script( 'wcml-front-scripts', WCML_PLUGIN_URL . '/res/js/front-scripts' . WCML_JS_MIN . '.js', array(
80
+ 'jquery'
81
+ ), WCML_VERSION );
82
+ wp_enqueue_script( 'wcml-front-scripts' );
83
+
84
+ if ( self::$is_wpml_wcml_page ) {
85
+
86
+ wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
87
+ wp_register_script( 'wcml-dialogs', WCML_PLUGIN_URL . '/res/js/dialogs' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core', 'jquery-ui-dialog'), WCML_VERSION );
88
+ wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
89
+
90
+ wp_enqueue_script( 'wcml-dialogs' );
91
+ wp_enqueue_script( 'wcml-scripts' );
92
+ wp_enqueue_script( 'jquery-cookie' );
93
+ wp_enqueue_script( 'wcml-troubleshooting' );
94
+
95
+ wp_localize_script( 'wcml-scripts', 'wcml_settings',
96
+ array(
97
+ 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
98
+ )
99
+ );
100
+
101
+ self::load_tooltip_resources();
102
+ }
103
+
104
+ if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
105
+ wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
106
+ wp_enqueue_script( 'wpml_tm' );
107
+ }
108
+
109
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'multi-currency' ) {
110
+ wp_register_script( 'multi-currency', WCML_PLUGIN_URL . '/res/js/multi-currency' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-sortable'), WCML_VERSION, true );
111
+ wp_enqueue_script( 'multi-currency' );
112
+ wp_register_script( 'exchange-rates', WCML_PLUGIN_URL . '/res/js/exchange-rates' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
113
+ wp_enqueue_script( 'exchange-rates' );
114
+ }
115
+
116
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'product-attributes' ) {
117
+ wp_register_script( 'product-attributes', WCML_PLUGIN_URL . '/res/js/product-attributes' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
118
+ wp_enqueue_script( 'product-attributes' );
119
+ }
120
+
121
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'custom-taxonomies' ) {
122
+ wp_register_script( 'custom-taxonomies', WCML_PLUGIN_URL . '/res/js/product-custom-taxonomies' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
123
+ wp_enqueue_script( 'custom-taxonomies' );
124
+ }
125
+
126
+ if ( !is_admin() ) {
127
+ $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
128
+
129
+ wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
130
+ wp_enqueue_script( 'cart-widget' );
131
+ wp_localize_script( 'cart-widget', 'actions', array(
132
+ 'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
133
+ 'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0
134
+ ) );
135
+ } else {
136
+ wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
137
+ wp_enqueue_script( 'wcml-messages' );
138
+ }
139
+
140
+ $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
141
+
142
+ if( $is_attr_page ){
143
+ wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
144
+ wp_enqueue_script( 'wcml-attributes' );
145
+ }
146
+
147
+ if( self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
148
+
149
+ self::load_tooltip_resources();
150
+ wp_enqueue_media();
151
+ wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core'), WCML_VERSION);
152
+ wp_enqueue_script( 'wcml-editor' );
153
+ wp_localize_script( 'wcml-editor', 'wcml_settings',
154
+ array(
155
+ 'strings' => array(
156
+ 'choose' => __( 'Choose a file', 'woocommerce_multilingual' ),
157
+ 'save_tooltip' => __( 'At least one of these fields is required: title, content or excerpt', 'woocommerce_multilingual' ),
158
+ 'resign_tooltip'=> __( 'This translation job will no longer be assigned to you. Other translators will be able take it and continue the translation.', 'woocommerce-multilingual')
159
+ ),
160
+ 'hide_resign' => self::$woocommerce_wpml->products->is_hide_resign_button()
161
+ )
162
+ );
163
+ }
164
+
165
+ if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
166
+ self::load_tooltip_resources();
167
+ wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION );
168
+ wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
169
+ }
170
+ }
171
+
172
+ public static function load_tooltip_resources() {
173
+
174
+ if ( class_exists( 'woocommerce' ) ) {
175
+ wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
176
+ wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
177
+ wp_enqueue_script( 'jquery-tiptip' );
178
+ wp_enqueue_script( 'wcml-tooltip-init' );
179
+ wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
180
+ }
181
+
182
+ }
183
+
184
+ public static function load_lock_fields_js() {
185
+
186
+ wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
187
+ wp_enqueue_script( 'wcml-lock-script' );
188
+
189
+ $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
190
+ if( isset( $_GET[ 'post' ] ) ){
191
+ $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET[ 'post' ] );
192
+ $original_id = apply_filters( 'translate_object_id', $_GET[ 'post' ], 'product', true, $original_language );
193
+ $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
194
+ if( $custom_product_sync && $custom_product_sync == 'self' ) {
195
+ $file_path_sync = false;
196
+ }elseif( $custom_product_sync && $custom_product_sync == 'auto' ){
197
+ $file_path_sync = true;
198
+ }
199
+ }
200
+
201
+ wp_localize_script( 'wcml-lock-script', 'unlock_fields', array(
202
+ 'menu_order' => self::$woocommerce_wpml->settings['products_sync_order'],
203
+ 'file_paths' => $file_path_sync
204
+ )
205
+ );
206
+ wp_localize_script( 'wcml-lock-script', 'non_standard_fields', array(
207
+ 'ids' => apply_filters( 'wcml_js_lock_fields_ids', array() ),
208
+ 'classes' => apply_filters( 'wcml_js_lock_fields_classes', array() ),
209
+ 'input_names' => apply_filters( 'wcml_js_lock_fields_input_names', array() )
210
+ ) );
211
+
212
+ do_action( 'wcml_after_load_lock_fields_js' );
213
+
214
+ }
215
+
216
+ public static function hidden_label() {
217
+ global $sitepress;
218
+
219
+ echo '<img src="' . WCML_PLUGIN_URL . '/res/images/locked.png" class="wcml_lock_img wcml_lock_icon" alt="' .
220
+ __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
221
+ '" title="' . __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
222
+ '" style="display: none;position:relative;left:2px;top:2px;">';
223
+
224
+ if ( isset($_GET['post']) ) {
225
+ $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET['post'] );
226
+ $original_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $original_language );
227
+ } elseif ( isset($_GET['trid']) ) {
228
+ $original_id = $sitepress->get_original_element_id_by_trid( $_GET['trid'] );
229
+ }
230
+
231
+ if ( isset($_GET['lang']) ) {
232
+ $language = $_GET['lang'];
233
+ } else {
234
+ return;
235
+ }
236
+
237
+ echo '<h3 class="wcml_prod_hidden_notice">' .
238
+ sprintf( __( "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products.",
239
+ 'woocommerce-multilingual' ),
240
+ '<a href="' . get_edit_post_link( $original_id ) . '" >' . get_the_title( $original_id ) . '</a>',
241
+ '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
242
+ __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
243
+ }
244
  }
inc/class-wcml-store-pages.php CHANGED
@@ -1,594 +1,614 @@
1
- <?php
2
-
3
- class WCML_Store_Pages{
4
-
5
- /**
6
- * @var woocommerce_wpml
7
- */
8
- private $woocommerce_wpml;
9
- /**
10
- * @var SitePress
11
- */
12
- private $sitepress;
13
-
14
- function __construct( $woocommerce_wpml, $sitepress ){
15
-
16
- $this->woocommerce_wpml =& $woocommerce_wpml;
17
- $this->sitepress =& $sitepress;
18
-
19
- add_action('init', array($this, 'init'));
20
- add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
21
- add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
22
- //update wc pages ids after change default language or create new if not exists
23
- add_action( 'icl_after_set_default_language', array( $this, 'after_set_default_language' ), 10, 2 );
24
- // Translate shop page ids
25
- $this->add_filter_to_get_shop_translated_page_id();
26
- add_filter( 'template_include', array( $this, 'template_loader' ), 100 );
27
-
28
- if( is_admin() ){
29
- add_action( 'icl_post_languages_options_before', array( $this, 'show_translate_shop_pages_notice') );
30
- }
31
- }
32
-
33
- function init(){
34
-
35
- if(!is_admin()){
36
- add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
37
- add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
38
- add_filter('parse_request', array($this, 'adjust_shop_page'));
39
- }
40
-
41
- add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
42
-
43
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
44
- if (isset($_POST['create_pages']) && wp_verify_nonce($nonce, 'create_pages')) {
45
- $this->create_missing_store_pages_with_redirect();
46
- }
47
-
48
- $this->front_page_id = get_option('page_on_front');
49
- $this->shop_page_id = wc_get_page_id('shop');
50
- $this->shop_page = get_post( $this->shop_page_id );
51
- }
52
-
53
- function switch_pages_language( $pages ){
54
-
55
- $default_language = $this->sitepress->get_default_language();
56
-
57
- if( $this->sitepress->get_current_language() != $default_language ){
58
- foreach( $pages as $key => $page ){
59
-
60
- switch( $key ){
61
- case 'shop':
62
- $page['name'] = 'shop';
63
- $page['title'] = 'Shop';
64
- break;
65
- case 'cart':
66
- $page['name'] = 'cart';
67
- $page['title'] = 'Cart';
68
- break;
69
- case 'checkout':
70
- $page['name'] = 'checkout';
71
- $page['title'] = 'Checkout';
72
- break;
73
- case 'myaccount':
74
- $page['name'] = 'my-account';
75
- $page['title'] = 'My account';
76
- break;
77
- }
78
-
79
- if( $this->sitepress->get_default_language() != 'en' ){
80
- $page['name'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page slug'.$page['name'], $default_language );
81
- $page['title'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page title'.$page['title'], $default_language );
82
- }
83
- }
84
- }
85
-
86
- return $pages;
87
- }
88
-
89
- function install_pages_action( $pages ){
90
- global $wpdb;
91
-
92
- foreach( $pages as $key => $page){
93
-
94
- if ( strlen( $page[ 'content' ] ) > 0 ) {
95
- // Search for an existing page with the specified page content (typically a shortcode)
96
- $page_found = $wpdb->get_var( $wpdb->prepare( "
97
- SELECT ID FROM " . $wpdb->posts . " as p
98
- LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
99
- WHERE post_type='page'
100
- AND post_content LIKE %s
101
- AND icl.element_type = 'post_page'
102
- AND icl.language_code = %s LIMIT 1;
103
- ",
104
- "%{$page[ 'content' ]}%", $this->sitepress->get_default_language() ) );
105
- } else {
106
- // Search for an existing page with the specified page slug
107
- $page_found = $wpdb->get_var( $wpdb->prepare( "
108
- SELECT ID FROM " . $wpdb->posts . " as p
109
- LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
110
- WHERE post_type='page'
111
- AND post_name = %s
112
- AND icl.element_type = 'post_page'
113
- AND icl.language_code = %s LIMIT 1;
114
- ",
115
- esc_sql( $page['name'] ), $this->sitepress->get_default_language() ) );
116
- }
117
-
118
- if( !$page_found ){
119
- $page_data = array(
120
- 'post_status' => 'publish',
121
- 'post_type' => 'page',
122
- 'post_author' => 1,
123
- 'post_name' => esc_sql( $page['name'] ),
124
- 'post_title' => $page['title'],
125
- 'post_content' => $page['content'],
126
- 'post_parent' => ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '',
127
- 'comment_status' => 'closed'
128
- );
129
- $page_id = wp_insert_post( $page_data );
130
-
131
- if ( 'woocommerce_' . $key . '_page_id' )
132
- update_option( 'woocommerce_' . $key . '_page_id', $page_id );
133
- }
134
-
135
- unset( $pages[ $key ] );
136
- }
137
-
138
- return $pages;
139
- }
140
-
141
- function add_filter_to_get_shop_translated_page_id(){
142
- $woo_pages = array(
143
- 'shop_page_id',
144
- 'cart_page_id',
145
- 'checkout_page_id',
146
- 'myaccount_page_id',
147
- 'lost_password_page_id',
148
- 'edit_address_page_id',
149
- 'view_order_page_id',
150
- 'change_password_page_id',
151
- 'logout_page_id',
152
- 'pay_page_id',
153
- 'thanks_page_id',
154
- 'terms_page_id',
155
- 'review_order_page_id'
156
- );
157
-
158
- foreach($woo_pages as $woo_page){
159
- add_filter('woocommerce_get_'.$woo_page, array($this, 'translate_pages_in_settings'));
160
- //I think following filter not needed because "option_woocommerce_..." not used in Woo, but I need ask David to confirm this
161
- add_filter('option_woocommerce_'.$woo_page, array($this, 'translate_pages_in_settings'));
162
- }
163
-
164
- add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_url'));
165
- }
166
-
167
- function translate_pages_in_settings($id) {
168
- global $pagenow;
169
- if( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ){
170
- return $id;
171
- }
172
-
173
- return apply_filters( 'translate_object_id',$id, 'page', true);
174
- }
175
-
176
- /**
177
- * Filters WooCommerce query for translated shop page
178
- *
179
- */
180
- function shop_page_query($q) {
181
- if ( ! $q->is_main_query() )
182
- return;
183
-
184
- //do not alter query_object and query_object_id (part 1 of 2)
185
- global $wp_query;
186
- $queried_object_original = isset($wp_query->queried_object) ? $wp_query->queried_object : null;
187
- $queried_object_id_original = isset($wp_query->queried_object_id) ? $wp_query->queried_object_id : null;
188
-
189
- if (
190
- !empty($this->shop_page) &&
191
- $this->shop_page->post_status == 'publish' &&
192
- !empty($this->front_page_id) &&
193
- $q->get('post_type') != 'product' &&
194
- $q->get('page_id') !== $this->front_page_id &&
195
- $this->shop_page_id == $q->get('page_id')
196
- ){
197
- $q->set( 'post_type', 'product' );
198
- $q->set( 'page_id', '' );
199
- if ( isset( $q->query['paged'] ) )
200
- $q->set( 'paged', $q->query['paged'] );
201
-
202
- // Get the actual WP page to avoid errors
203
- // This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
204
- global $wp_post_types;
205
-
206
- $q->is_page = true;
207
-
208
- $wp_post_types['product']->ID = $this->shop_page->ID;
209
- $wp_post_types['product']->post_title = $this->shop_page->post_title;
210
- $wp_post_types['product']->post_name = $this->shop_page->post_name;
211
-
212
- // Fix conditional functions
213
- $q->is_singular = false;
214
- $q->is_post_type_archive = true;
215
- $q->is_archive = true;
216
- }
217
-
218
- //do not alter query_object and query_object_id (part 2 of 2)
219
- if(is_null($queried_object_original)){
220
- unset($wp_query->queried_object);
221
- }else{
222
- $wp_query->queried_object = $queried_object_original;
223
- }
224
- if(is_null($queried_object_id_original)){
225
- unset($wp_query->queried_object_id);
226
- }else{
227
- $wp_query->queried_object_id = $queried_object_id_original;
228
- }
229
-
230
- }
231
-
232
-
233
- /**
234
- * Translate shop url
235
- */
236
- function translate_ls_shop_url($languages, $debug_mode = false) {
237
-
238
- $shop_id = $this->shop_page_id;
239
- $front_id = apply_filters( 'translate_object_id',$this->front_page_id, 'page');
240
-
241
- foreach ($languages as $language) {
242
- // shop page
243
- // obsolete?
244
- if (is_post_type_archive('product') || $debug_mode ) {
245
- if ($front_id == $shop_id) {
246
- $url = $this->sitepress->language_url($language['language_code']);
247
- } else {
248
- $this->sitepress->switch_lang($language['language_code']);
249
- $url = get_permalink( apply_filters( 'translate_object_id', $shop_id, 'page', true, $language['language_code']) );
250
- $this->sitepress->switch_lang();
251
- }
252
-
253
- $languages[$language['language_code']]['url'] = $url;
254
- }
255
- }
256
-
257
- return $languages;
258
- }
259
-
260
- function adjust_shop_page($q) {
261
-
262
- if ( $this->sitepress->get_default_language() != $this->sitepress->get_current_language() ) {
263
- if (!empty($q->query_vars['pagename'])) {
264
- $shop_page = get_post( wc_get_page_id('shop') );
265
- // we should explode by / for children page
266
- $query_var_page = explode('/',$q->query_vars['pagename']);
267
- if (isset($shop_page->post_name) && ( ( $shop_page->post_name == $query_var_page[count($query_var_page)-1]) || ( $shop_page->post_name == strtolower($query_var_page[count($query_var_page)-1]) ) ) ) {
268
- unset($q->query_vars['page']);
269
- unset($q->query_vars['pagename']);
270
- $q->query_vars['post_type'] = 'product';
271
- }
272
- }
273
- }
274
- }
275
-
276
- function create_missing_store_pages_with_redirect(){
277
- $this->create_missing_store_pages();
278
-
279
- wp_redirect(admin_url('admin.php?page=wpml-wcml&tab=status')); exit;
280
-
281
- }
282
-
283
- /**
284
- * create missing pages
285
- */
286
- function create_missing_store_pages() {
287
- global $wp_rewrite;
288
- $miss_lang = $this->get_missing_store_pages();
289
-
290
- //dummy array for names
291
- $names = array( __('Cart', 'woocommerce-multilingual'),
292
- __('Checkout', 'woocommerce-multilingual'),
293
- __('Checkout &rarr; Pay', 'woocommerce-multilingual'),
294
- __('Order Received', 'woocommerce-multilingual'),
295
- __('My Account', 'woocommerce-multilingual'),
296
- __('Change Password', 'woocommerce-multilingual'),
297
- __('Edit My Address', 'woocommerce-multilingual'),
298
- __('Logout', 'woocommerce-multilingual'),
299
- __('Lost Password', 'woocommerce-multilingual'),
300
- __('View Order', 'woocommerce-multilingual'),
301
- __('Shop', 'woocommerce-multilingual'));
302
-
303
- if (isset($miss_lang['codes'])) {
304
- $wp_rewrite = new WP_Rewrite();
305
-
306
- $check_pages = $this->get_wc_pages();
307
- $default_language = $this->sitepress->get_default_language();
308
- if(in_array($default_language, $miss_lang['codes'])){
309
- $miss_lang['codes'] = array_merge(array($default_language), array_diff($miss_lang['codes'], array($default_language)));
310
- }
311
-
312
- foreach ($miss_lang['codes'] as $mis_lang) {
313
- $args = array();
314
-
315
- $this->woocommerce_wpml->locale->switch_locale( $mis_lang );
316
-
317
- foreach ($check_pages as $page) {
318
- $orig_id = get_option($page);
319
- $trid = $this->sitepress->get_element_trid($orig_id,'post_page');
320
- $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
321
-
322
- if (!isset( $translations[ $mis_lang ] ) || ( !is_null( $translations[$mis_lang]->element_id ) && get_post_status( $translations[$mis_lang]->element_id )!='publish' ) ) {
323
- $orig_page = get_post($orig_id);
324
-
325
- switch( $page ){
326
- case 'woocommerce_shop_page_id':
327
- $page_title = $mis_lang !== 'en' ? __( 'Shop', 'woocommerce-multilingual') : 'Shop';
328
- break;
329
- case 'woocommerce_cart_page_id':
330
- $page_title = $mis_lang !== 'en' ? __( 'Cart', 'woocommerce-multilingual') : 'Cart';
331
- break;
332
- case 'woocommerce_checkout_page_id':
333
- $page_title = $mis_lang !== 'en' ? __( 'Checkout', 'woocommerce-multilingual') : 'Checkout';
334
- break;
335
- case 'woocommerce_myaccount_page_id':
336
- $page_title = $mis_lang !== 'en' ? __( 'My Account', 'woocommerce-multilingual') : 'My Account';
337
- break;
338
- default:
339
- $page_title = $mis_lang !== 'en' ? translate( $orig_page->post_title, 'woocommerce-multilingual') : $orig_page->post_title;
340
- break;
341
- }
342
-
343
- $args['post_title'] = $page_title;
344
- $args['post_type'] = $orig_page->post_type;
345
- $args['post_content'] = $orig_page->post_content;
346
- $args['post_excerpt'] = $orig_page->post_excerpt;
347
- $args['post_status'] = ( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) != 'publish' ) ? 'publish' : $orig_page->post_status;
348
- $args['menu_order'] = $orig_page->menu_order;
349
- $args['ping_status'] = $orig_page->ping_status;
350
- $args['comment_status'] = $orig_page->comment_status;
351
- $post_parent = apply_filters( 'translate_object_id',$orig_page->post_parent, 'page', false, $mis_lang);
352
- $args['post_parent'] = is_null($post_parent)?0:$post_parent;
353
- $new_page_id = wp_insert_post($args);
354
-
355
- if( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) == 'trash' && $mis_lang == $default_language){
356
- update_option($page, $new_page_id);
357
- }
358
-
359
- if( isset($translations[$mis_lang]->element_id) && !is_null($translations[$mis_lang]->element_id)){
360
- $this->sitepress->set_element_language_details($translations[$mis_lang]->element_id, 'post_page', false, $mis_lang);
361
- }
362
-
363
- $trid = $this->sitepress->get_element_trid($orig_id, 'post_page');
364
- $this->sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
365
- }
366
- }
367
- $this->woocommerce_wpml->locale->switch_locale();
368
- }
369
- }
370
- }
371
-
372
- /**
373
- * get missing pages
374
- * return array;
375
- */
376
- function get_missing_store_pages() {
377
-
378
- $check_pages = $this->get_wc_pages();
379
-
380
- $missing_lang = '';
381
- $pages_in_progress = array();
382
-
383
- foreach ($check_pages as $page) {
384
- $page_id = get_option($page);
385
- $page_obj = get_post($page_id);
386
- if(!$page_id || !$page_obj || $page_obj->post_status != 'publish' ){
387
- return 'non_exist';
388
- }
389
- }
390
-
391
- $languages = $this->sitepress->get_active_languages();
392
-
393
- $missing_lang_codes = array();
394
-
395
- foreach ($check_pages as $page) {
396
- $store_page_id = get_option($page);
397
- $trid = $this->sitepress->get_element_trid($store_page_id,'post_page');
398
- $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
399
- $pages_in_progress_miss_lang = '';
400
- foreach ($languages as $language) {
401
- if ( !in_array( $language['code'], $missing_lang_codes ) &&
402
- ( !isset( $translations[ $language['code'] ] ) || ( !is_null( $translations[$language['code']]->element_id ) && get_post_status( $translations[$language['code']]->element_id )!='publish' ) ) ) {
403
-
404
- $missing_lang_codes[] = $language['code'];
405
-
406
- $missing_lang[] = $language;
407
-
408
- continue;
409
- }
410
-
411
- if ( isset($translations[$language['code']] ) && is_null( $translations[$language['code']]->element_id ) ) {
412
-
413
- $pages_in_progress[$store_page_id][] = $language;
414
-
415
- }
416
- }
417
- }
418
-
419
-
420
- foreach( $pages_in_progress as $key => $page_in_progress ){
421
- $pages_in_progress_notice[$key]['page'] = get_the_title( $key ).' :';
422
- $pages_in_progress_notice[$key]['lang'] = $page_in_progress;
423
-
424
- }
425
-
426
- $status = array();
427
-
428
- if (!empty($missing_lang)) {
429
- $status['lang'] = $missing_lang;
430
- $status['codes'] = $missing_lang_codes;
431
- }
432
-
433
- if (!empty($pages_in_progress_notice)) {
434
- $status['in_progress'] = $pages_in_progress_notice;
435
- }
436
-
437
- if(!empty($status)){
438
- return $status;
439
- }else {
440
- return false;
441
- }
442
- }
443
-
444
- /**
445
- * Filters WooCommerce checkout link.
446
- */
447
- function get_checkout_page_url(){
448
- return get_permalink(apply_filters( 'translate_object_id',get_option('woocommerce_checkout_page_id'), 'page', true));
449
- }
450
-
451
- function get_wc_pages(){
452
- return apply_filters('wcml_wc_installed_pages', array(
453
- 'woocommerce_shop_page_id',
454
- 'woocommerce_cart_page_id',
455
- 'woocommerce_checkout_page_id',
456
- 'woocommerce_myaccount_page_id'
457
- ));
458
- }
459
-
460
- function after_set_default_language( $code, $previous_code ){
461
- global $wpdb;
462
-
463
- $this->create_missing_store_pages();
464
- $pages = $this->get_wc_pages();
465
-
466
- foreach( $pages as $page ){
467
-
468
- if( $page_id = get_option($page) ){
469
- $trnsl_id = apply_filters( 'translate_object_id', $page_id, 'page', false, $code );
470
- if( !is_null( $trnsl_id ) ){
471
- $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => $page ) );
472
- }
473
- }
474
-
475
- }
476
-
477
- // Clear any unwanted data
478
- wc_delete_product_transients();
479
- delete_transient( 'woocommerce_cache_excluded_uris' );
480
- }
481
-
482
- function template_loader( $template ){
483
-
484
- if ( is_product_taxonomy() ) {
485
- global $sitepress, $woocommerce_wpml;
486
-
487
- $current_language = $sitepress->get_current_language();
488
- $default_language = $sitepress->get_default_language();
489
-
490
- if( $current_language != $default_language ) {
491
-
492
- $templates = array( 'woocommerce.php' );
493
-
494
- $term = get_queried_object();
495
-
496
- if (is_tax('product_cat') || is_tax('product_tag')) {
497
- $file = 'taxonomy-' . $term->taxonomy . '.php';
498
- } else {
499
- $file = 'archive-product.php';
500
- }
501
-
502
- // check templates
503
- $term = get_queried_object();
504
- $taxonomy = $term->taxonomy;
505
- $prefix = 'taxonomy-'.$taxonomy;
506
- $original_term_id = icl_object_id($term->term_id, $taxonomy, true, $default_language);
507
- $original_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $original_term_id, $taxonomy );
508
-
509
-
510
- $terms_to_check = array( $term->term_id => $term->slug );
511
- if ($original_term) {
512
- $terms_to_check[ $original_term_id ] = $original_term->slug;
513
- }
514
-
515
- $paths = array( '', WC()->template_path() );
516
-
517
- foreach( $paths as $path ){
518
-
519
- foreach( $terms_to_check as $term_id => $term_slug ){
520
-
521
- $templates[] = $path."$prefix-{$current_language}-{$term_slug}.php";
522
- $templates[] = $path."$prefix-{$current_language}-{$term_id}.php";
523
- $templates[] = $path."$prefix-{$term_slug}.php";
524
- $templates[] = $path."$prefix-{$term_id}.php";
525
-
526
- }
527
-
528
- $templates[] = $path."$prefix-{$current_language}.php";
529
- $templates[] = $path."$prefix.php";
530
- $templates[] = $path.$file;
531
- }
532
-
533
- $loaded_template = locate_template( array_unique( $templates ) );
534
-
535
- if ( $loaded_template ) {
536
-
537
- $template = $loaded_template;
538
-
539
- }
540
-
541
- }
542
-
543
- }
544
-
545
- return $template;
546
-
547
- }
548
-
549
- public function show_translate_shop_pages_notice(){
550
- if( empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] ) ){
551
-
552
- $is_shop_page = false;
553
-
554
- $pages = $this->get_wc_pages();
555
- $current_page_id = get_the_ID();
556
- foreach( $pages as $page ){
557
- $page_id = get_option( $page );
558
- if( $page_id && $page_id === $current_page_id ){
559
- $is_shop_page = true;
560
- break;
561
- }
562
- }
563
-
564
- if ( $is_shop_page ) {
565
-
566
- $is_translated = true;
567
- $active_languages = array_keys( $this->sitepress->get_active_languages() );
568
-
569
- $trid = $this->sitepress->get_element_trid( $current_page_id, 'post_page' );
570
- $translations = $this->sitepress->get_element_translations($trid, $current_page_id, true, true, true );
571
-
572
- foreach( $active_languages as $language ){
573
- if( !isset( $translations[$language] ) ){
574
- $is_translated = false;
575
- break;
576
- }
577
- }
578
-
579
- if( !$is_translated ){
580
- $text = sprintf( __( 'To quickly translate this and other WooCommerce store pages, please run the %ssetup wizard%s.', 'woocommerce-multilingual' ),
581
- '<a href="' . admin_url( 'admin.php?page=wcml-setup' ) . '">', '</a>' );
582
-
583
- echo '<div class="notice notice-error inline">';
584
- echo '<p><i class="otgs-ico-warning"></i> ' . $text . '</p>';
585
- echo '</div>';
586
- }
587
- }
588
-
589
- }
590
-
591
-
592
- }
593
-
594
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Store_Pages{
4
+
5
+ /**
6
+ * @var woocommerce_wpml
7
+ */
8
+ private $woocommerce_wpml;
9
+ /**
10
+ * @var SitePress
11
+ */
12
+ private $sitepress;
13
+
14
+ function __construct( $woocommerce_wpml, $sitepress ){
15
+
16
+ $this->woocommerce_wpml =& $woocommerce_wpml;
17
+ $this->sitepress =& $sitepress;
18
+
19
+ add_action('init', array($this, 'init'));
20
+ add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
21
+ add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
22
+ //update wc pages ids after change default language or create new if not exists
23
+ add_action( 'icl_after_set_default_language', array( $this, 'after_set_default_language' ), 10, 2 );
24
+ // Translate shop page ids
25
+ $this->add_filter_to_get_shop_translated_page_id();
26
+ add_filter( 'template_include', array( $this, 'template_loader' ), 100 );
27
+
28
+ if( is_admin() ){
29
+ add_action( 'icl_post_languages_options_before', array( $this, 'show_translate_shop_pages_notice') );
30
+ }
31
+ }
32
+
33
+ function init(){
34
+
35
+ if(!is_admin()){
36
+ add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
37
+ add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
38
+ add_filter('parse_request', array($this, 'adjust_shop_page'));
39
+ }
40
+
41
+ add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
42
+
43
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
44
+ if (isset($_POST['create_pages']) && wp_verify_nonce($nonce, 'create_pages')) {
45
+ $this->create_missing_store_pages_with_redirect();
46
+ }
47
+
48
+ $this->front_page_id = get_option('page_on_front');
49
+ $this->shop_page_id = wc_get_page_id('shop');
50
+ $this->shop_page = get_post( $this->shop_page_id );
51
+ }
52
+
53
+ function switch_pages_language( $pages ){
54
+
55
+ $default_language = $this->sitepress->get_default_language();
56
+
57
+ if( $this->sitepress->get_current_language() != $default_language ){
58
+ foreach( $pages as $key => $page ){
59
+
60
+ switch( $key ){
61
+ case 'shop':
62
+ $page['name'] = 'shop';
63
+ $page['title'] = 'Shop';
64
+ break;
65
+ case 'cart':
66
+ $page['name'] = 'cart';
67
+ $page['title'] = 'Cart';
68
+ break;
69
+ case 'checkout':
70
+ $page['name'] = 'checkout';
71
+ $page['title'] = 'Checkout';
72
+ break;
73
+ case 'myaccount':
74
+ $page['name'] = 'my-account';
75
+ $page['title'] = 'My account';
76
+ break;
77
+ }
78
+
79
+ if( $this->sitepress->get_default_language() != 'en' ){
80
+ $page['name'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page slug'.$page['name'], $default_language );
81
+ $page['title'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page title'.$page['title'], $default_language );
82
+ }
83
+ }
84
+ }
85
+
86
+ return $pages;
87
+ }
88
+
89
+ function install_pages_action( $pages ){
90
+ global $wpdb;
91
+
92
+ foreach( $pages as $key => $page){
93
+
94
+ if ( strlen( $page[ 'content' ] ) > 0 ) {
95
+ // Search for an existing page with the specified page content (typically a shortcode)
96
+ $page_found = $wpdb->get_var( $wpdb->prepare( "
97
+ SELECT ID FROM " . $wpdb->posts . " as p
98
+ LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
99
+ WHERE post_type='page'
100
+ AND post_content LIKE %s
101
+ AND icl.element_type = 'post_page'
102
+ AND icl.language_code = %s LIMIT 1;
103
+ ",
104
+ "%{$page[ 'content' ]}%", $this->sitepress->get_default_language() ) );
105
+ } else {
106
+ // Search for an existing page with the specified page slug
107
+ $page_found = $wpdb->get_var( $wpdb->prepare( "
108
+ SELECT ID FROM " . $wpdb->posts . " as p
109
+ LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
110
+ WHERE post_type='page'
111
+ AND post_name = %s
112
+ AND icl.element_type = 'post_page'
113
+ AND icl.language_code = %s LIMIT 1;
114
+ ",
115
+ esc_sql( $page['name'] ), $this->sitepress->get_default_language() ) );
116
+ }
117
+
118
+ if( !$page_found ){
119
+ $page_data = array(
120
+ 'post_status' => 'publish',
121
+ 'post_type' => 'page',
122
+ 'post_author' => 1,
123
+ 'post_name' => esc_sql( $page['name'] ),
124
+ 'post_title' => $page['title'],
125
+ 'post_content' => $page['content'],
126
+ 'post_parent' => ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '',
127
+ 'comment_status' => 'closed'
128
+ );
129
+ $page_id = wp_insert_post( $page_data );
130
+
131
+ if ( 'woocommerce_' . $key . '_page_id' )
132
+ update_option( 'woocommerce_' . $key . '_page_id', $page_id );
133
+ }
134
+
135
+ unset( $pages[ $key ] );
136
+ }
137
+
138
+ return $pages;
139
+ }
140
+
141
+ function add_filter_to_get_shop_translated_page_id(){
142
+ $woo_pages = array(
143
+ 'shop_page_id',
144
+ 'cart_page_id',
145
+ 'checkout_page_id',
146
+ 'myaccount_page_id',
147
+ 'lost_password_page_id',
148
+ 'edit_address_page_id',
149
+ 'view_order_page_id',
150
+ 'change_password_page_id',
151
+ 'logout_page_id',
152
+ 'pay_page_id',
153
+ 'thanks_page_id',
154
+ 'terms_page_id',
155
+ 'review_order_page_id'
156
+ );
157
+
158
+ foreach($woo_pages as $woo_page){
159
+ add_filter('woocommerce_get_'.$woo_page, array($this, 'translate_pages_in_settings'));
160
+ //I think following filter not needed because "option_woocommerce_..." not used in Woo, but I need ask David to confirm this
161
+ add_filter('option_woocommerce_'.$woo_page, array($this, 'translate_pages_in_settings'));
162
+ }
163
+
164
+ add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_url'));
165
+ }
166
+
167
+ function translate_pages_in_settings($id) {
168
+ global $pagenow;
169
+ if( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ){
170
+ return $id;
171
+ }
172
+
173
+ return apply_filters( 'translate_object_id',$id, 'page', true);
174
+ }
175
+
176
+ /**
177
+ * Filters WooCommerce query for translated shop page
178
+ *
179
+ */
180
+ function shop_page_query($q) {
181
+ if ( ! $q->is_main_query() )
182
+ return;
183
+
184
+ //do not alter query_object and query_object_id (part 1 of 2)
185
+ global $wp_query;
186
+ $queried_object_original = isset($wp_query->queried_object) ? $wp_query->queried_object : null;
187
+ $queried_object_id_original = isset($wp_query->queried_object_id) ? $wp_query->queried_object_id : null;
188
+
189
+ if (
190
+ !empty($this->shop_page) &&
191
+ $this->shop_page->post_status == 'publish' &&
192
+ !empty($this->front_page_id) &&
193
+ $q->get('post_type') != 'product' &&
194
+ $q->get('page_id') !== $this->front_page_id &&
195
+ $this->shop_page_id == $q->get('page_id')
196
+ ){
197
+ $q->set( 'post_type', 'product' );
198
+ $q->set( 'page_id', '' );
199
+ if ( isset( $q->query['paged'] ) )
200
+ $q->set( 'paged', $q->query['paged'] );
201
+
202
+ // Get the actual WP page to avoid errors
203
+ // This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
204
+ global $wp_post_types;
205
+
206
+ $q->is_page = true;
207
+
208
+ $wp_post_types['product']->ID = $this->shop_page->ID;
209
+ $wp_post_types['product']->post_title = $this->shop_page->post_title;
210
+ $wp_post_types['product']->post_name = $this->shop_page->post_name;
211
+
212
+ // Fix conditional functions
213
+ $q->is_singular = false;
214
+ $q->is_post_type_archive = true;
215
+ $q->is_archive = true;
216
+ }
217
+
218
+ //do not alter query_object and query_object_id (part 2 of 2)
219
+ if(is_null($queried_object_original)){
220
+ unset($wp_query->queried_object);
221
+ }else{
222
+ $wp_query->queried_object = $queried_object_original;
223
+ }
224
+ if(is_null($queried_object_id_original)){
225
+ unset($wp_query->queried_object_id);
226
+ }else{
227
+ $wp_query->queried_object_id = $queried_object_id_original;
228
+ }
229
+
230
+ }
231
+
232
+
233
+ /**
234
+ * Translate shop url
235
+ */
236
+ function translate_ls_shop_url($languages, $debug_mode = false) {
237
+
238
+ $shop_id = $this->shop_page_id;
239
+ $front_id = apply_filters( 'translate_object_id',$this->front_page_id, 'page');
240
+
241
+ foreach ($languages as $language) {
242
+ // shop page
243
+ // obsolete?
244
+ if (is_post_type_archive('product') || $debug_mode ) {
245
+ if ($front_id == $shop_id) {
246
+ $url = $this->sitepress->language_url($language['language_code']);
247
+ } else {
248
+ $this->sitepress->switch_lang($language['language_code']);
249
+ $url = get_permalink( apply_filters( 'translate_object_id', $shop_id, 'page', true, $language['language_code']) );
250
+ $this->sitepress->switch_lang();
251
+ }
252
+
253
+ $languages[$language['language_code']]['url'] = $url;
254
+ }
255
+ }
256
+
257
+ // copy get parameters?
258
+ $gets_passed = array();
259
+ $parameters_copied = apply_filters( 'icl_lang_sel_copy_parameters',
260
+ array_map( 'trim',
261
+ explode( ',',
262
+ wpml_get_setting_filter('',
263
+ 'icl_lang_sel_copy_parameters') ) ) );
264
+ if ( $parameters_copied ) {
265
+ foreach ( $_GET as $k => $v ) {
266
+ if ( in_array( $k, $parameters_copied ) ) {
267
+ $gets_passed[ $k ] = $v;
268
+ }
269
+ }
270
+
271
+ foreach( $languages as $code => $language ){
272
+ $languages[$code]['url'] = add_query_arg( $gets_passed, $language['url'] );
273
+ }
274
+ }
275
+
276
+
277
+ return $languages;
278
+ }
279
+
280
+ function adjust_shop_page($q) {
281
+
282
+ if ( $this->sitepress->get_default_language() != $this->sitepress->get_current_language() ) {
283
+ if (!empty($q->query_vars['pagename'])) {
284
+ $shop_page = get_post( wc_get_page_id('shop') );
285
+ // we should explode by / for children page
286
+ $query_var_page = explode('/',$q->query_vars['pagename']);
287
+ if (isset($shop_page->post_name) && ( ( $shop_page->post_name == $query_var_page[count($query_var_page)-1]) || ( $shop_page->post_name == strtolower($query_var_page[count($query_var_page)-1]) ) ) ) {
288
+ unset($q->query_vars['page']);
289
+ unset($q->query_vars['pagename']);
290
+ $q->query_vars['post_type'] = 'product';
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ function create_missing_store_pages_with_redirect(){
297
+ $this->create_missing_store_pages();
298
+
299
+ wp_redirect(admin_url('admin.php?page=wpml-wcml&tab=status')); exit;
300
+
301
+ }
302
+
303
+ /**
304
+ * create missing pages
305
+ */
306
+ function create_missing_store_pages() {
307
+ global $wp_rewrite;
308
+ $miss_lang = $this->get_missing_store_pages();
309
+
310
+ //dummy array for names
311
+ $names = array( __('Cart', 'woocommerce-multilingual'),
312
+ __('Checkout', 'woocommerce-multilingual'),
313
+ __('Checkout &rarr; Pay', 'woocommerce-multilingual'),
314
+ __('Order Received', 'woocommerce-multilingual'),
315
+ __('My Account', 'woocommerce-multilingual'),
316
+ __('Change Password', 'woocommerce-multilingual'),
317
+ __('Edit My Address', 'woocommerce-multilingual'),
318
+ __('Logout', 'woocommerce-multilingual'),
319
+ __('Lost Password', 'woocommerce-multilingual'),
320
+ __('View Order', 'woocommerce-multilingual'),
321
+ __('Shop', 'woocommerce-multilingual'));
322
+
323
+ if (isset($miss_lang['codes'])) {
324
+ $wp_rewrite = new WP_Rewrite();
325
+
326
+ $check_pages = $this->get_wc_pages();
327
+ $default_language = $this->sitepress->get_default_language();
328
+ if(in_array($default_language, $miss_lang['codes'])){
329
+ $miss_lang['codes'] = array_merge(array($default_language), array_diff($miss_lang['codes'], array($default_language)));
330
+ }
331
+
332
+ foreach ($miss_lang['codes'] as $mis_lang) {
333
+ $args = array();
334
+
335
+ $this->woocommerce_wpml->locale->switch_locale( $mis_lang );
336
+
337
+ foreach ($check_pages as $page) {
338
+ $orig_id = get_option($page);
339
+ $trid = $this->sitepress->get_element_trid($orig_id,'post_page');
340
+ $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
341
+
342
+ if (!isset( $translations[ $mis_lang ] ) || ( !is_null( $translations[$mis_lang]->element_id ) && get_post_status( $translations[$mis_lang]->element_id )!='publish' ) ) {
343
+ $orig_page = get_post($orig_id);
344
+
345
+ switch( $page ){
346
+ case 'woocommerce_shop_page_id':
347
+ $page_title = $mis_lang !== 'en' ? __( 'Shop', 'woocommerce-multilingual') : 'Shop';
348
+ break;
349
+ case 'woocommerce_cart_page_id':
350
+ $page_title = $mis_lang !== 'en' ? __( 'Cart', 'woocommerce-multilingual') : 'Cart';
351
+ break;
352
+ case 'woocommerce_checkout_page_id':
353
+ $page_title = $mis_lang !== 'en' ? __( 'Checkout', 'woocommerce-multilingual') : 'Checkout';
354
+ break;
355
+ case 'woocommerce_myaccount_page_id':
356
+ $page_title = $mis_lang !== 'en' ? __( 'My Account', 'woocommerce-multilingual') : 'My Account';
357
+ break;
358
+ default:
359
+ $page_title = $mis_lang !== 'en' ? translate( $orig_page->post_title, 'woocommerce-multilingual') : $orig_page->post_title;
360
+ break;
361
+ }
362
+
363
+ $args['post_title'] = $page_title;
364
+ $args['post_type'] = $orig_page->post_type;
365
+ $args['post_content'] = $orig_page->post_content;
366
+ $args['post_excerpt'] = $orig_page->post_excerpt;
367
+ $args['post_status'] = ( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) != 'publish' ) ? 'publish' : $orig_page->post_status;
368
+ $args['menu_order'] = $orig_page->menu_order;
369
+ $args['ping_status'] = $orig_page->ping_status;
370
+ $args['comment_status'] = $orig_page->comment_status;
371
+ $post_parent = apply_filters( 'translate_object_id',$orig_page->post_parent, 'page', false, $mis_lang);
372
+ $args['post_parent'] = is_null($post_parent)?0:$post_parent;
373
+ $new_page_id = wp_insert_post($args);
374
+
375
+ if( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) == 'trash' && $mis_lang == $default_language){
376
+ update_option($page, $new_page_id);
377
+ }
378
+
379
+ if( isset($translations[$mis_lang]->element_id) && !is_null($translations[$mis_lang]->element_id)){
380
+ $this->sitepress->set_element_language_details($translations[$mis_lang]->element_id, 'post_page', false, $mis_lang);
381
+ }
382
+
383
+ $trid = $this->sitepress->get_element_trid($orig_id, 'post_page');
384
+ $this->sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
385
+ }
386
+ }
387
+ $this->woocommerce_wpml->locale->switch_locale();
388
+ }
389
+ }
390
+ }
391
+
392
+ /**
393
+ * get missing pages
394
+ * return array;
395
+ */
396
+ function get_missing_store_pages() {
397
+
398
+ $check_pages = $this->get_wc_pages();
399
+
400
+ $missing_lang = array();
401
+ $pages_in_progress = array();
402
+
403
+ foreach ($check_pages as $page) {
404
+ $page_id = get_option($page);
405
+ $page_obj = get_post($page_id);
406
+ if(!$page_id || !$page_obj || $page_obj->post_status != 'publish' ){
407
+ return 'non_exist';
408
+ }
409
+ }
410
+
411
+ $languages = $this->sitepress->get_active_languages();
412
+
413
+ $missing_lang_codes = array();
414
+
415
+ foreach ($check_pages as $page) {
416
+ $store_page_id = get_option($page);
417
+ $trid = $this->sitepress->get_element_trid($store_page_id,'post_page');
418
+ $translations = $this->sitepress->get_element_translations($trid,'post_page',true);
419
+ $pages_in_progress_miss_lang = '';
420
+ foreach ($languages as $language) {
421
+ if ( !in_array( $language['code'], $missing_lang_codes ) &&
422
+ ( !isset( $translations[ $language['code'] ] ) || ( !is_null( $translations[$language['code']]->element_id ) && get_post_status( $translations[$language['code']]->element_id )!='publish' ) ) ) {
423
+
424
+ $missing_lang_codes[] = $language['code'];
425
+
426
+ $missing_lang[] = $language;
427
+
428
+ continue;
429
+ }
430
+
431
+ if ( isset($translations[$language['code']] ) && is_null( $translations[$language['code']]->element_id ) ) {
432
+
433
+ $pages_in_progress[$store_page_id][] = $language;
434
+
435
+ }
436
+ }
437
+ }
438
+
439
+
440
+ foreach( $pages_in_progress as $key => $page_in_progress ){
441
+ $pages_in_progress_notice[$key]['page'] = get_the_title( $key ).' :';
442
+ $pages_in_progress_notice[$key]['lang'] = $page_in_progress;
443
+
444
+ }
445
+
446
+ $status = array();
447
+
448
+ if (!empty($missing_lang)) {
449
+ $status['lang'] = $missing_lang;
450
+ $status['codes'] = $missing_lang_codes;
451
+ }
452
+
453
+ if (!empty($pages_in_progress_notice)) {
454
+ $status['in_progress'] = $pages_in_progress_notice;
455
+ }
456
+
457
+ if(!empty($status)){
458
+ return $status;
459
+ }else {
460
+ return false;
461
+ }
462
+ }
463
+
464
+ /**
465
+ * Filters WooCommerce checkout link.
466
+ */
467
+ function get_checkout_page_url(){
468
+ return get_permalink(apply_filters( 'translate_object_id',get_option('woocommerce_checkout_page_id'), 'page', true));
469
+ }
470
+
471
+ function get_wc_pages(){
472
+ return apply_filters('wcml_wc_installed_pages', array(
473
+ 'woocommerce_shop_page_id',
474
+ 'woocommerce_cart_page_id',
475
+ 'woocommerce_checkout_page_id',
476
+ 'woocommerce_myaccount_page_id'
477
+ ));
478
+ }
479
+
480
+ function after_set_default_language( $code, $previous_code ){
481
+ global $wpdb;
482
+
483
+ $this->create_missing_store_pages();
484
+ $pages = $this->get_wc_pages();
485
+
486
+ foreach( $pages as $page ){
487
+
488
+ if( $page_id = get_option($page) ){
489
+ $trnsl_id = apply_filters( 'translate_object_id', $page_id, 'page', false, $code );
490
+ if( !is_null( $trnsl_id ) ){
491
+ $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => $page ) );
492
+ }
493
+ }
494
+
495
+ }
496
+
497
+ // Clear any unwanted data
498
+ wc_delete_product_transients();
499
+ delete_transient( 'woocommerce_cache_excluded_uris' );
500
+ }
501
+
502
+ function template_loader( $template ){
503
+
504
+ if ( is_product_taxonomy() ) {
505
+ global $sitepress, $woocommerce_wpml;
506
+
507
+ $current_language = $sitepress->get_current_language();
508
+ $default_language = $sitepress->get_default_language();
509
+
510
+ if( $current_language != $default_language ) {
511
+
512
+ $templates = array( 'woocommerce.php' );
513
+
514
+ $term = get_queried_object();
515
+
516
+ if (is_tax('product_cat') || is_tax('product_tag')) {
517
+ $file = 'taxonomy-' . $term->taxonomy . '.php';
518
+ } else {
519
+ $file = 'archive-product.php';
520
+ }
521
+
522
+ // check templates
523
+ $term = get_queried_object();
524
+ $taxonomy = $term->taxonomy;
525
+ $prefix = 'taxonomy-'.$taxonomy;
526
+ $original_term_id = icl_object_id($term->term_id, $taxonomy, true, $default_language);
527
+ $original_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $original_term_id, $taxonomy );
528
+
529
+
530
+ $terms_to_check = array( $term->term_id => $term->slug );
531
+ if ($original_term) {
532
+ $terms_to_check[ $original_term_id ] = $original_term->slug;
533
+ }
534
+
535
+ $paths = array( '', WC()->template_path() );
536
+
537
+ foreach( $paths as $path ){
538
+
539
+ foreach( $terms_to_check as $term_id => $term_slug ){
540
+
541
+ $templates[] = $path."$prefix-{$current_language}-{$term_slug}.php";
542
+ $templates[] = $path."$prefix-{$current_language}-{$term_id}.php";
543
+ $templates[] = $path."$prefix-{$term_slug}.php";
544
+ $templates[] = $path."$prefix-{$term_id}.php";
545
+
546
+ }
547
+
548
+ $templates[] = $path."$prefix-{$current_language}.php";
549
+ $templates[] = $path."$prefix.php";
550
+ $templates[] = $path.$file;
551
+ }
552
+
553
+ $loaded_template = locate_template( array_unique( $templates ) );
554
+
555
+ if ( $loaded_template ) {
556
+
557
+ $template = $loaded_template;
558
+
559
+ }
560
+
561
+ }
562
+
563
+ }
564
+
565
+ return $template;
566
+
567
+ }
568
+
569
+ public function show_translate_shop_pages_notice(){
570
+ if( empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] ) ){
571
+
572
+ $is_shop_page = false;
573
+
574
+ $pages = $this->get_wc_pages();
575
+ $current_page_id = get_the_ID();
576
+ foreach( $pages as $page ){
577
+ $page_id = get_option( $page );
578
+ if( $page_id && $page_id === $current_page_id ){
579
+ $is_shop_page = true;
580
+ break;
581
+ }
582
+ }
583
+
584
+ if ( $is_shop_page ) {
585
+
586
+ $is_translated = true;
587
+ $active_languages = array_keys( $this->sitepress->get_active_languages() );
588
+
589
+ $trid = $this->sitepress->get_element_trid( $current_page_id, 'post_page' );
590
+ $translations = $this->sitepress->get_element_translations($trid, $current_page_id, true, true, true );
591
+
592
+ foreach( $active_languages as $language ){
593
+ if( !isset( $translations[$language] ) ){
594
+ $is_translated = false;
595
+ break;
596
+ }
597
+ }
598
+
599
+ if( !$is_translated ){
600
+ $text = sprintf( __( 'To quickly translate this and other WooCommerce store pages, please run the %ssetup wizard%s.', 'woocommerce-multilingual' ),
601
+ '<a href="' . admin_url( 'admin.php?page=wcml-setup' ) . '">', '</a>' );
602
+
603
+ echo '<div class="notice notice-error inline">';
604
+ echo '<p><i class="otgs-ico-warning"></i> ' . $text . '</p>';
605
+ echo '</div>';
606
+ }
607
+ }
608
+
609
+ }
610
+
611
+
612
+ }
613
+
614
+ }
inc/class-wcml-terms.php CHANGED
@@ -1,968 +1,968 @@
1
- <?php
2
-
3
- class WCML_Terms{
4
-
5
- private $ALL_TAXONOMY_TERMS_TRANSLATED = 0;
6
- private $NEW_TAXONOMY_TERMS = 1;
7
- private $NEW_TAXONOMY_IGNORED = 2;
8
-
9
- private $woocommerce_wpml;
10
- private $sitepress;
11
- private $wpdb;
12
-
13
- function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
14
- $this->woocommerce_wpml = $woocommerce_wpml;
15
- $this->sitepress = $sitepress;
16
- $this->wpdb = $wpdb;
17
-
18
- add_action('updated_woocommerce_term_meta',array($this,'sync_term_order'), 100,4);
19
-
20
- add_filter('wp_get_object_terms', array($this->sitepress, 'get_terms_filter'));
21
-
22
- add_action('icl_save_term_translation', array($this,'save_wc_term_meta'), 100,4);
23
-
24
- add_action('created_term', array($this, 'translated_terms_status_update'), 10,3);
25
- add_action('edit_term', array($this, 'translated_terms_status_update'), 10,3);
26
- add_action('wp_ajax_wcml_update_term_translated_warnings', array( $this, 'wcml_update_term_translated_warnings'));
27
-
28
- add_action('created_term', array( $this, 'set_flag_for_variation_on_attribute_update'), 10, 3);
29
-
30
- add_filter('wpml_taxonomy_translation_bottom', array( $this, 'sync_taxonomy_translations'), 10, 3 );
31
-
32
- add_action('wp_ajax_wcml_sync_product_variations', array( $this, 'wcml_sync_product_variations'));
33
- add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content', array( $this, 'wcml_sync_taxonomies_in_content'));
34
- add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content_preview', array( $this, 'wcml_sync_taxonomies_in_content_preview'));
35
-
36
- if(is_admin()){
37
- add_action('admin_menu', array($this, 'admin_menu_setup'));
38
- }
39
-
40
- add_action('delete_term',array($this, 'wcml_delete_term'),10,4);
41
- add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
42
- //filter coupons terms in admin
43
- add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
44
- add_filter('get_terms',array($this,'filter_shipping_classes_terms'),10,3);
45
-
46
- add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
47
- add_action( 'created_term_translation', array( $this, 'set_flag_to_sync'), 10, 3 );
48
- }
49
-
50
- function admin_menu_setup(){
51
- global $pagenow;
52
- if($pagenow == 'edit-tags.php' && isset($_GET['action']) && $_GET['action'] == 'edit'){
53
- add_action('admin_notices', array($this, 'show_term_translation_screen_notices'));
54
- }
55
-
56
- $page = isset( $_GET['page'] )? $_GET['page'] : '';
57
- if ( $page === ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' ) {
58
- WCML_Resources::load_management_css();
59
- wp_enqueue_script( 'wcml-scripts' );
60
- }
61
-
62
- }
63
-
64
- function save_wc_term_meta($original_tax, $result){
65
-
66
-
67
- // WooCommerce before termmeta table migration
68
- $wc_before_term_meta = get_option( 'db_version' ) < 34370;
69
-
70
- // backwards compatibility - before the termmeta table was added
71
- if( $wc_before_term_meta ){
72
-
73
- $term_wc_meta = $this->wpdb->get_results($this->wpdb->prepare("SELECT * FROM {$this->wpdb->woocommerce_termmeta} WHERE woocommerce_term_id=%s", $original_tax->term_id));
74
- foreach ( $term_wc_meta as $wc_meta ){
75
- $wc_original_metakey = $wc_meta->meta_key;
76
- $wc_original_metavalue = $wc_meta->meta_value;
77
- update_woocommerce_term_meta($result['term_id'], $wc_original_metakey, $wc_original_metavalue);
78
- }
79
- // End of backwards compatibility - before the termmeta table was added
80
- }else{
81
-
82
- $term_wc_meta = get_term_meta($original_tax->term_id, false, 1);
83
- foreach ( $term_wc_meta as $key => $values ) {
84
- update_term_meta( $result['term_id'], $key, array_pop( $values ) );
85
- }
86
-
87
- }
88
- }
89
-
90
- function show_term_translation_screen_notices(){
91
-
92
- $taxonomies = array_keys(get_taxonomies(array('object_type'=>array('product')),'objects'));
93
- $taxonomies = $taxonomies + array_keys(get_taxonomies(array('object_type'=>array('product_variations')),'objects'));
94
- $taxonomies = array_unique($taxonomies);
95
- $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : false;
96
- if( $taxonomy && in_array( $taxonomy, $taxonomies ) ){
97
- $taxonomy_obj = get_taxonomy($taxonomy);
98
- $message = sprintf(__('To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s.', 'woocommerce-multilingual'),
99
- $taxonomy_obj->labels->name,
100
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . $taxonomy_obj->labels->singular_name, '</a></strong>',
101
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml">'), '</a></strong>');
102
-
103
- echo '<div class="updated"><p>' . $message . '</p></div>';
104
- }
105
-
106
- }
107
-
108
- function sync_term_order_globally() {
109
- //syncs the term order of any taxonomy in $this->wpdb->prefix.'woocommerce_attribute_taxonomies'
110
- //use it when term orderings have become unsynched, e.g. before WCML 3.3.
111
-
112
- if(!defined('WOOCOMMERCE_VERSION')){
113
- return;
114
- }
115
-
116
- $cur_lang = $this->sitepress->get_current_language();
117
- $lang = $this->sitepress->get_default_language();
118
- $this->sitepress->switch_lang($lang);
119
-
120
- $taxes = wc_get_attribute_taxonomies ();
121
-
122
- if ($taxes) foreach ($taxes as $woo_tax) {
123
- $tax = 'pa_'.$woo_tax->attribute_name;
124
- $meta_key = 'order_'.$tax;
125
- //if ($tax != 'pa_frame') continue;
126
- $terms = get_terms($tax);
127
- if ($terms)foreach ($terms as $term) {
128
- $term_order = get_woocommerce_term_meta($term->term_id,$meta_key);
129
- $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_'.$tax);
130
- $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
131
- if ($translations) foreach ($translations as $trans) {
132
- if ($trans->language_code != $lang) {
133
- update_woocommerce_term_meta( $trans->term_id, $meta_key, $term_order);
134
- }
135
- }
136
- }
137
- }
138
-
139
- //sync product categories ordering
140
- $terms = get_terms('product_cat');
141
- if ($terms) foreach($terms as $term) {
142
- $term_order = get_woocommerce_term_meta($term->term_id,'order');
143
- $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
144
- $translations = $this->sitepress->get_element_translations($trid,'tax_product_cat');
145
- if ($translations) foreach ($translations as $trans) {
146
- if ($trans->language_code != $lang) {
147
- update_woocommerce_term_meta( $trans->term_id, 'order', $term_order);
148
- }
149
- }
150
- }
151
-
152
- $this->sitepress->switch_lang($cur_lang);
153
-
154
- $this->woocommerce_wpml->settings['is_term_order_synced'] = 'yes';
155
- $this->woocommerce_wpml->update_settings();
156
-
157
- }
158
-
159
- function sync_term_order($meta_id, $object_id, $meta_key, $meta_value) {
160
-
161
- // WooCommerce before termmeta table migration
162
- $wc_before_term_meta = get_option( 'db_version' ) < 34370;
163
-
164
- if (!isset($_POST['thetaxonomy']) || !taxonomy_exists($_POST['thetaxonomy']) || substr($meta_key,0,5) != 'order')
165
- return;
166
-
167
- $tax = filter_input( INPUT_POST, 'thetaxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
168
-
169
- $term_taxonomy_id = $this->wpdb->get_var($this->wpdb->prepare("SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $object_id, $tax));
170
- $trid = $this->sitepress->get_element_trid($term_taxonomy_id, 'tax_' . $tax);
171
- $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
172
- if ($translations) foreach ($translations as $trans) {
173
- if ($trans->element_id != $term_taxonomy_id) {
174
-
175
- // Backwards compatibility - WooCommerce termmeta table
176
- if( $wc_before_term_meta ) {
177
- $this->wpdb->update( $this->wpdb->prefix . 'woocommerce_termmeta',
178
- array('meta_value' => $meta_value),
179
- array('woocommerce_term_id' => $trans->term_id, 'meta_key' => $meta_key) );
180
- // END Backwards compatibility - WooCommerce termmeta table
181
- } else{
182
- update_term_meta( $trans->term_id, $meta_key, $meta_value);
183
- }
184
-
185
- }
186
- }
187
-
188
- }
189
-
190
- function translated_terms_status_update($term_id, $tt_id, $taxonomy){
191
-
192
- if ( isset( $_POST['product_cat_thumbnail_id'] ) || isset( $_POST['display_type'] ) ){
193
- global $sitepress_settings;
194
-
195
- if( $this->is_original_category($tt_id,'tax_'.$taxonomy) ){
196
- $trid = $this->sitepress->get_element_trid($tt_id,'tax_'.$taxonomy);
197
- $translations = $this->sitepress->get_element_translations($trid,'tax_'.$taxonomy);
198
-
199
- foreach($translations as $translation){
200
- if(!$translation->original){
201
- if(isset($_POST['display_type'])){
202
- update_woocommerce_term_meta( $translation->term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
203
- }
204
- update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', apply_filters( 'translate_object_id',esc_attr( $_POST['product_cat_thumbnail_id'] ),'attachment',true,$translation->language_code));
205
- }
206
- }
207
- }
208
- }
209
-
210
- global $wp_taxonomies;
211
- if(in_array('product', $wp_taxonomies[$taxonomy]->object_type) || in_array('product_variation', $wp_taxonomies[$taxonomy]->object_type)){
212
- $this->update_terms_translated_status($taxonomy);
213
- }
214
-
215
- }
216
-
217
- function is_original_category( $tt_id, $taxonomy ){
218
- $is_original = $this->wpdb->get_var($this->wpdb->prepare("SELECT source_language_code IS NULL FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $tt_id, $taxonomy ));
219
- return $is_original ? true : false;
220
- }
221
-
222
- public function wcml_update_term_translated_warnings(){
223
- $ret = array();
224
-
225
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
226
-
227
- $wcml_settings = $this->woocommerce_wpml->get_settings();
228
-
229
- $attribute_taxonomies = $this->woocommerce_wpml->attributes->get_translatable_attributes();
230
-
231
- $attribute_taxonomies_arr = array();
232
- foreach($attribute_taxonomies as $a){
233
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
234
- }
235
-
236
- $ret['is_attribute'] = intval( in_array( $taxonomy, $attribute_taxonomies_arr ) );
237
-
238
- if( isset( $wcml_settings['untranstaled_terms'][$taxonomy] ) &&
239
- (
240
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->ALL_TAXONOMY_TERMS_TRANSLATED ||
241
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_IGNORED
242
- )
243
- ){
244
-
245
- $ret['hide'] = 1;
246
- }else{
247
-
248
- $ret['hide'] = 0;
249
-
250
- if( isset( $wcml_settings[ 'sync_'.$taxonomy ]) ){
251
- $ret[ 'show_button' ] = $wcml_settings[ 'sync_'.$taxonomy ];
252
- }elseif( in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
253
- $ret[ 'show_button' ] = $wcml_settings[ 'sync_variations' ];
254
- }
255
- }
256
-
257
- if( $ret[ 'is_attribute' ] ){
258
- $ret['hide'] = $this->woocommerce_wpml->attributes->is_attributes_fully_translated();
259
- }
260
-
261
- echo json_encode($ret);
262
- exit;
263
-
264
- }
265
-
266
- public function update_terms_translated_status($taxonomy){
267
-
268
- $wcml_settings = $this->woocommerce_wpml->get_settings();
269
- $is_translatable= 1;
270
- $not_translated_count = 0;
271
- $original_terms = array();
272
-
273
- if( isset( $wcml_settings[ 'attributes_settings' ][ $taxonomy ] ) && !$wcml_settings[ 'attributes_settings' ][ $taxonomy ] ){
274
- $is_translatable = 0;
275
- }
276
-
277
- if( $is_translatable ){
278
-
279
- $active_languages = $this->sitepress->get_active_languages();
280
-
281
- foreach($active_languages as $language){
282
- $terms = $this->wpdb->get_results($this->wpdb->prepare("
283
- SELECT t1.element_id AS e1, t2.element_id AS e2 FROM {$this->wpdb->term_taxonomy} x
284
- JOIN {$this->wpdb->prefix}icl_translations t1 ON x.term_taxonomy_id = t1.element_id AND t1.element_type = %s AND t1.source_language_code IS NULL
285
- LEFT JOIN {$this->wpdb->prefix}icl_translations t2 ON t2.trid = t1.trid AND t2.language_code = %s
286
- ", 'tax_' . $taxonomy, $language['code']));
287
- foreach($terms as $term){
288
- if( empty( $term->e2 ) && !in_array( $term->e1, $original_terms ) ){
289
- $original_terms[] = $term->e1;
290
- $not_translated_count ++;
291
- }
292
- }
293
- }
294
- }
295
-
296
- $status = $not_translated_count ? $this->NEW_TAXONOMY_TERMS : $this->ALL_TAXONOMY_TERMS_TRANSLATED;
297
-
298
- if( isset( $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] ) && $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] === $this->NEW_TAXONOMY_IGNORED ){
299
- $status = $this->NEW_TAXONOMY_IGNORED;
300
- }
301
-
302
- $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] = array( 'count' => $not_translated_count , 'status' => $status );
303
-
304
- $this->woocommerce_wpml->update_settings( $wcml_settings );
305
-
306
- return $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ];
307
-
308
- }
309
-
310
- public function is_fully_translated($taxonomy){
311
-
312
- $wcml_settings = $this->woocommerce_wpml->get_settings();
313
-
314
- $return = true;
315
-
316
- if( !isset($wcml_settings['untranstaled_terms'][$taxonomy]) ){
317
- $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
318
- }
319
-
320
- if($wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_TERMS){
321
- $return = false;
322
- }
323
-
324
-
325
- return $return;
326
- }
327
-
328
- public function get_untranslated_terms_number( $taxonomy, $force_update = false ){
329
-
330
- $wcml_settings = $this->woocommerce_wpml->get_settings();
331
-
332
- if( $force_update || !isset($wcml_settings['untranstaled_terms'][$taxonomy] ) ){
333
- $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
334
- }
335
-
336
- return $wcml_settings['untranstaled_terms'][$taxonomy]['count'];
337
-
338
- }
339
-
340
- public function set_flag_for_variation_on_attribute_update($term_id, $tt_id, $taxonomy){
341
-
342
- $attribute_taxonomies = wc_get_attribute_taxonomies();
343
- foreach($attribute_taxonomies as $a){
344
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
345
- }
346
-
347
- if(isset( $attribute_taxonomies_arr ) && in_array($taxonomy, $attribute_taxonomies_arr)){
348
-
349
- $wcml_settings = $this->woocommerce_wpml->get_settings();
350
-
351
- // get term language
352
- $term_language = $this->sitepress->get_element_language_details($tt_id, 'tax_' . $taxonomy);
353
-
354
- if( isset( $term_language->language_code ) && $term_language->language_code != $this->sitepress->get_default_language()){
355
- // get term in the default language
356
- $term_id = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $this->sitepress->get_default_language());
357
-
358
- //does it belong to any posts (variations)
359
- $objects = get_objects_in_term($term_id, $taxonomy);
360
-
361
- if(!isset($wcml_settings['variations_needed'][$taxonomy])){
362
- $wcml_settings['variations_needed'][$taxonomy] = 0;
363
- }
364
- $wcml_settings['variations_needed'][$taxonomy] += count($objects);
365
-
366
- $this->woocommerce_wpml->update_settings($wcml_settings);
367
-
368
- }
369
- }
370
-
371
- }
372
-
373
- public function sync_taxonomy_translations( $html, $taxonomy, $taxonomy_obj ){
374
-
375
- $is_wcml = is_admin() && $taxonomy && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']);
376
- $is_ajax = is_ajax() && $taxonomy && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_get_terms_and_labels_for_taxonomy_table';
377
- if( $is_wcml || $is_ajax ){
378
-
379
- $sync_tax = new WCML_Sync_Taxonomy( $this->woocommerce_wpml, $taxonomy, $taxonomy_obj );
380
- $html = $sync_tax->get_view();
381
- }
382
-
383
- return $html;
384
- }
385
-
386
- public function wcml_sync_product_variations($taxonomy){
387
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
388
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_product_variations')){
389
- die('Invalid nonce');
390
- }
391
-
392
- $VARIATIONS_THRESHOLD = 20;
393
-
394
- $wcml_settings = $this->woocommerce_wpml->get_settings();
395
- $response = array();
396
-
397
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
398
-
399
- $languages_processed = intval( $_POST['languages_processed']);
400
-
401
- $condition = $languages_processed?'>=':'>';
402
-
403
- $where = isset($_POST['last_post_id']) && $_POST['last_post_id'] ? ' ID '.$condition.' ' . intval($_POST['last_post_id']) . ' AND ' : '';
404
-
405
- $post_ids = $this->wpdb->get_col($this->wpdb->prepare("
406
- SELECT DISTINCT tr.object_id
407
- FROM {$this->wpdb->term_relationships} tr
408
- JOIN {$this->wpdb->term_taxonomy} tx on tr.term_taxonomy_id = tx.term_taxonomy_id
409
- JOIN {$this->wpdb->posts} p ON tr.object_id = p.ID
410
- JOIN {$this->wpdb->prefix}icl_translations t ON t.element_id = p.ID
411
- WHERE {$where} tx.taxonomy = %s AND p.post_type = 'product' AND t.element_type='post_product' AND t.language_code = %s
412
- ORDER BY ID ASC
413
-
414
- ", $taxonomy, $this->sitepress->get_default_language()));
415
-
416
- if($post_ids){
417
-
418
- $variations_processed = 0;
419
- $posts_processed = 0;
420
- foreach($post_ids as $post_id){
421
- $terms = wp_get_post_terms($post_id, $taxonomy);
422
- $terms_count = count($terms) . "\n\n";
423
-
424
- $trid = $this->sitepress->get_element_trid($post_id, 'post_product');
425
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
426
-
427
- $i = 1;
428
-
429
- foreach($translations as $translation){
430
-
431
- if($i > $languages_processed && $translation->element_id != $post_id){
432
- $this->woocommerce_wpml->sync_product_data->sync_product_taxonomies($post_id, $translation->element_id, $translation->language_code);
433
- $this->woocommerce_wpml->sync_variations_data->sync_product_variations($post_id, $translation->element_id, $translation->language_code, false, true);
434
- $this->woocommerce_wpml->translation_editor->create_product_translation_package($post_id,$trid, $translation->language_code,ICL_TM_COMPLETE);
435
- $variations_processed += $terms_count*2;
436
- $response['languages_processed'] = $i;
437
- $i++;
438
- //check if sum of 2 iterations doesn't exceed $VARIATIONS_THRESHOLD
439
- if($variations_processed >= $VARIATIONS_THRESHOLD){
440
- break;
441
- }
442
- }else{
443
- $i++;
444
- }
445
- }
446
- $response['last_post_id'] = $post_id;
447
- if(--$i == count($translations)){
448
- $response['languages_processed'] = 0;
449
- $languages_processed = 0;
450
- }else{
451
- break;
452
- }
453
-
454
- $posts_processed ++;
455
-
456
- }
457
-
458
- $response['go'] = 1;
459
-
460
- }else{
461
-
462
- $response['go'] = 0;
463
-
464
- }
465
-
466
- $response['progress'] = $response['go'] ? sprintf(__('%d products left', 'woocommerce-multilingual'), count($post_ids) - $posts_processed) : __('Synchronization complete!', 'woocommerce-multilingual');
467
-
468
- if($response['go'] && isset($wcml_settings['variations_needed'][$taxonomy]) && !empty($variations_processed)){
469
- $wcml_settings['variations_needed'][$taxonomy] = max($wcml_settings['variations_needed'][$taxonomy] - $variations_processed, 0);
470
- }else{
471
- if($response['go'] == 0){
472
- $wcml_settings['variations_needed'][$taxonomy] = 0;
473
- }
474
- }
475
- $wcml_settings['sync_variations'] = 0;
476
-
477
- $this->woocommerce_wpml->update_settings($wcml_settings);
478
-
479
- echo json_encode($response);
480
- exit;
481
- }
482
-
483
- public function wcml_sync_taxonomies_in_content_preview(){
484
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
485
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content_preview')){
486
- die('Invalid nonce');
487
- }
488
-
489
- global $wp_taxonomies;
490
-
491
- $html = $message = $errors = '';
492
-
493
-
494
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
495
- $object_types = $wp_taxonomies[$_POST['taxonomy']]->object_type;
496
-
497
- foreach($object_types as $object_type){
498
-
499
- $html .= $this->render_assignment_status($object_type, $_POST['taxonomy'], $preview = true);
500
-
501
- }
502
-
503
- }else{
504
- $errors = sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
505
- }
506
-
507
-
508
- echo json_encode(array('html' => $html, 'message'=> $message, 'errors' => $errors));
509
- exit;
510
- }
511
-
512
- public function wcml_sync_taxonomies_in_content(){
513
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
514
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content')){
515
- die('Invalid nonce');
516
- }
517
-
518
- global $wp_taxonomies;
519
-
520
- $html = $message = $errors = '';
521
-
522
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
523
- $html .= $this->render_assignment_status($_POST['post'], $_POST['taxonomy'], $preview = false);
524
-
525
- }else{
526
- $errors .= sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
527
- }
528
-
529
-
530
- echo json_encode(array('html' => $html, 'errors' => $errors));
531
- exit;
532
- }
533
-
534
- public function render_assignment_status($object_type, $taxonomy, $preview = true){
535
- global $wp_post_types, $wp_taxonomies;
536
-
537
- $default_language = $this->sitepress->get_default_language();
538
-
539
- $posts = $this->wpdb->get_results($this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} AS p LEFT JOIN {$this->wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = %s AND tr.source_language_code is NULL", $object_type ) );
540
-
541
- foreach($posts as $post){
542
-
543
- $terms = wp_get_post_terms($post->ID, $taxonomy);
544
-
545
- $term_ids = array();
546
- foreach($terms as $term){
547
- $term_ids[] = $term->term_id;
548
- }
549
-
550
- $trid = $this->sitepress->get_element_trid($post->ID, 'post_' . $post->post_type);
551
- $translations = $this->sitepress->get_element_translations($trid, 'post_' . $post->post_type, true, true);
552
-
553
- foreach($translations as $language => $translation){
554
-
555
- if($language != $default_language && $translation->element_id){
556
-
557
- $terms_of_translation = wp_get_post_terms($translation->element_id, $taxonomy);
558
-
559
- $translation_term_ids = array();
560
- foreach($terms_of_translation as $term){
561
-
562
- $term_id_original = apply_filters( 'translate_object_id',$term->term_id, $taxonomy, false, $default_language );
563
- if(!$term_id_original || !in_array($term_id_original, $term_ids)){
564
- // remove term
565
-
566
- if($preview){
567
- $needs_sync = true;
568
- break(3);
569
- }
570
-
571
- $current_terms = wp_get_post_terms($translation->element_id, $taxonomy);
572
- $updated_terms = array();
573
- foreach($current_terms as $cterm){
574
- if($cterm->term_id != $term->term_id){
575
- $updated_terms[] = $taxonomy != 'product_type' ? $term->term_id : $term->name;
576
- }
577
- if(!$preview){
578
-
579
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
580
- $updated_terms = array_unique( array_map( 'intval', $updated_terms ) );
581
- }
582
-
583
- wp_set_post_terms($translation->element_id, $updated_terms, $taxonomy);
584
- }
585
-
586
- }
587
-
588
- }else{
589
- $translation_term_ids[] = $term_id_original;
590
- }
591
-
592
- }
593
-
594
- foreach($term_ids as $term_id){
595
-
596
- if(!in_array($term_id, $translation_term_ids)){
597
- // add term
598
-
599
- if($preview){
600
- $needs_sync = true;
601
- break(3);
602
- }
603
- $terms_array = array();
604
- $term_id_translated = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $language);
605
-
606
- // not using get_term
607
- $translated_term = $this->wpdb->get_row($this->wpdb->prepare("
608
- SELECT * FROM {$this->wpdb->terms} t JOIN {$this->wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $term_id_translated, $taxonomy));
609
-
610
- if( $translated_term ){
611
- $terms_array[] = $translated_term->term_id;
612
- }
613
-
614
- if(!$preview){
615
-
616
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
617
- $terms_array = array_unique( array_map( 'intval', $terms_array ) );
618
- }
619
-
620
- wp_set_post_terms($translation->element_id, $terms_array, $taxonomy, true);
621
- }
622
-
623
- }
624
-
625
- }
626
-
627
- }
628
-
629
- }
630
-
631
- }
632
-
633
- $wcml_settings = $this->woocommerce_wpml->get_settings();
634
- $wcml_settings['sync_'.$taxonomy] = 0;
635
- $this->woocommerce_wpml->update_settings($wcml_settings);
636
-
637
- $out = '';
638
-
639
- if($preview){
640
-
641
- $out .= '<div class="wcml_tt_sync_row">';
642
- if(!empty($needs_sync)){
643
- $out .= '<form class="wcml_tt_do_sync">';
644
- $out .= '<input type="hidden" name="post" value="' . $object_type . '" />';
645
- $out .= wp_nonce_field('wcml_sync_taxonomies_in_content', 'wcml_sync_taxonomies_in_content_nonce',true,false);
646
- $out .= '<input type="hidden" name="taxonomy" value="' . $taxonomy . '" />';
647
- $out .= sprintf(__('Some translated %s have different %s assignments.', 'woocommerce-multilingual'),
648
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>',
649
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>');
650
- $out .= '&nbsp;<a class="submit button-secondary" href="#">' . sprintf(__('Update %s for all translated %s', 'woocommerce-multilingual'),
651
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
652
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>') . '</a>' .
653
- '&nbsp;<img src="'. ICL_PLUGIN_URL . '/res/img/ajax-loader.gif" alt="loading" height="16" width="16" class="wcml_tt_spinner" />';
654
- $out .= "</form>";
655
- }else{
656
- $out .= sprintf(__('All %s have the same %s assignments.', 'woocommerce-multilingual'),
657
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
658
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>');
659
- }
660
- $out .= "</div>";
661
-
662
- }else{
663
-
664
- $out .= sprintf(__('Successfully updated %s for all translated %s.', 'woocommerce-multilingual'), $wp_taxonomies[$taxonomy]->labels->name, $wp_post_types[$object_type]->labels->name);
665
-
666
- }
667
-
668
- return $out;
669
- }
670
-
671
- function shipping_terms($terms, $post_id, $taxonomy){
672
- global $pagenow;
673
-
674
- if( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_load_variations' ){
675
- return $terms;
676
- }
677
-
678
- if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
679
-
680
- remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
681
- $terms = get_the_terms( apply_filters( 'translate_object_id', $post_id, get_post_type($post_id), true, $this->sitepress->get_current_language() ),'product_shipping_class');
682
- add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
683
- return $terms;
684
- }
685
-
686
- return $terms;
687
- }
688
-
689
- function filter_coupons_terms($terms, $taxonomies, $args){
690
- global $pagenow;
691
-
692
- if(is_admin() && (($pagenow == 'post-new.php' && isset($_GET['post_type']) && $_GET['post_type'] == 'shop_coupon') || ($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'shop_coupon')) && in_array('product_cat',$taxonomies)){
693
- remove_filter('get_terms',array($this,'filter_coupons_terms'));
694
- $current_language = $this->sitepress->get_current_language();
695
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
696
- $terms = get_terms( 'product_cat', 'orderby=name&hide_empty=0');
697
- add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
698
- $this->sitepress->switch_lang($current_language);
699
- }
700
-
701
- return $terms;
702
- }
703
-
704
- function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
705
-
706
- $on_wc_settings_page = isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] === 'wc-settings';
707
- $on_shipping_tab = isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] === 'shipping';
708
- $on_classes_section = isset( $_GET[ 'section' ] ) && $_GET[ 'section' ] === 'classes';
709
-
710
- if( is_admin() && in_array( 'product_shipping_class', (array) $taxonomies ) && $on_wc_settings_page && $on_shipping_tab && !$on_classes_section ){
711
- remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
712
- $current_language = $this->sitepress->get_current_language();
713
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
714
- add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
715
- $terms = get_terms( $taxonomies, $args );
716
- remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
717
- add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
718
- $this->sitepress->switch_lang($current_language);
719
- }
720
-
721
- return $terms;
722
- }
723
-
724
- function wcml_delete_term($term, $tt_id, $taxonomy, $deleted_term){
725
- global $wp_taxonomies;
726
-
727
- foreach($wp_taxonomies as $key=>$taxonomy_obj){
728
- if((in_array('product',$taxonomy_obj->object_type) || in_array('product_variation',$taxonomy_obj->object_type) ) && $key==$taxonomy){
729
- $this->update_terms_translated_status($taxonomy);
730
- break;
731
- }
732
- }
733
-
734
- }
735
-
736
- function get_product_terms_filter( $terms, $product_id, $taxonomy, $args ){
737
-
738
- $language = $this->sitepress->get_language_for_element( $product_id, 'post_'.get_post_type( $product_id ) );
739
-
740
- $is_objects_array = is_object( current ( $terms ) );
741
-
742
- $filtered_terms = array();
743
-
744
- foreach( $terms as $term ){
745
-
746
- if( !$is_objects_array ){
747
- $term_obj = get_term_by( 'name', $term, $taxonomy );
748
- if( !$term_obj ){
749
- $term_obj = get_term_by( 'slug', $term, $taxonomy );
750
- $is_slug = true;
751
- }
752
- }
753
-
754
- if( empty($term_obj) ){
755
- $filtered_terms[] = $term;
756
- continue;
757
- }
758
-
759
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_obj->term_id, $taxonomy, true, $language );
760
-
761
- if( $is_objects_array ){
762
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy );
763
- }else{
764
- if( isset( $is_slug ) ){
765
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy )->slug;
766
- }else{
767
- $filtered_terms[] = ( is_ajax() && isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'woocommerce_add_variation', 'woocommerce_link_all_variations') ) ) ? strtolower ( get_term( $trnsl_term_id, $taxonomy )->name ) : get_term( $trnsl_term_id, $taxonomy )->name;
768
- }
769
- }
770
- }
771
-
772
- return $filtered_terms;
773
- }
774
-
775
-
776
-
777
-
778
- function set_flag_to_sync( $taxonomy, $el_id, $language_code ){
779
-
780
- $elem_details = $this->sitepress->get_element_language_details( $el_id, 'tax_'.$taxonomy );
781
- if( is_null( $elem_details->source_language_code ) )
782
- return;
783
-
784
- $this->check_if_sync_term_translation_needed( $el_id, $taxonomy );
785
-
786
- }
787
-
788
- function check_if_sync_terms_needed(){
789
-
790
- $wcml_settings = $this->woocommerce_wpml->get_settings();
791
- $wcml_settings['sync_variations'] = 0;
792
- $wcml_settings['sync_product_cat'] = 0;
793
- $wcml_settings['sync_product_tag'] = 0;
794
- $wcml_settings['sync_product_shipping_class'] = 0;
795
- $this->woocommerce_wpml->update_settings( $wcml_settings );
796
-
797
- $taxonomies_to_check = array( 'product_cat', 'product_tag', 'product_shipping_class' );
798
-
799
- foreach( $taxonomies_to_check as $check_taxonomy ){
800
- $terms = get_terms( $check_taxonomy, array( 'hide_empty' => false, 'fields' => 'ids' ) );
801
- if (is_array($terms)){
802
- foreach( $terms as $term ){
803
- if( $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], $check_taxonomy ) ){
804
- break;
805
- }
806
- }
807
- }
808
- }
809
-
810
- $attribute_taxonomies = wc_get_attribute_taxonomies();
811
- $flag_set = false;
812
- foreach( $attribute_taxonomies as $a ){
813
-
814
- $terms = get_terms( 'pa_' . $a->attribute_name, array( 'hide_empty' => false, 'fields' => 'ids' ) );
815
- if (is_array($terms)){
816
- foreach( $terms as $term ){
817
- $flag_set = $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], 'pa_' . $a->attribute_name );
818
- if( $flag_set ){
819
- break;
820
- }
821
- }
822
- }
823
-
824
- if( $flag_set ){
825
- break;
826
- }
827
- }
828
-
829
- }
830
-
831
- function check_if_sync_term_translation_needed( $t_id, $taxonomy ){
832
-
833
- $wcml_settings = $this->woocommerce_wpml->get_settings();
834
-
835
- $attribute_taxonomies = wc_get_attribute_taxonomies();
836
- $attribute_taxonomies_arr = array();
837
- foreach($attribute_taxonomies as $a){
838
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
839
- }
840
-
841
- if( ( isset( $wcml_settings[ 'sync_'.$taxonomy ]) && $wcml_settings[ 'sync_'.$taxonomy ] ) || ( in_array( $taxonomy, $attribute_taxonomies_arr ) && isset( $wcml_settings[ 'sync_variations' ]) && $wcml_settings['sync_variations'] ) ){
842
- return true;
843
- }
844
-
845
- $translations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT t2.element_id, t2.source_language_code FROM {$this->wpdb->prefix}icl_translations AS t1 LEFT JOIN {$this->wpdb->prefix}icl_translations AS t2 ON t1.trid = t2.trid WHERE t1.element_id = %d AND t1.element_type = %s ", $t_id, 'tax_'.$taxonomy ) );
846
-
847
- foreach( $translations as $key => $translation ){
848
- if ( is_null( $translation->source_language_code ) ) {
849
- $original_count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
850
- unset( $translations[ $key ] );
851
- }
852
- }
853
-
854
- foreach( $translations as $translation ){
855
-
856
- $count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
857
- if( $original_count != $count ){
858
-
859
- if( in_array( $taxonomy, array( 'product_cat', 'product_tag', 'product_shipping_class' ) ) ){
860
- $wcml_settings[ 'sync_'.$taxonomy ] = 1;
861
- $this->woocommerce_wpml->update_settings($wcml_settings);
862
- return true;
863
- }
864
-
865
- if( isset( $attribute_taxonomies_arr ) && in_array( $taxonomy, $attribute_taxonomies_arr ) ){
866
- $wcml_settings['sync_variations'] = 1;
867
- $this->woocommerce_wpml->update_settings($wcml_settings);
868
- return true;
869
- }
870
-
871
- }
872
-
873
- }
874
-
875
- }
876
-
877
- function get_table_taxonomies( $taxonomies ){
878
-
879
- foreach( $taxonomies as $key => $taxonomy ){
880
- if (substr($key, 0, 3) != 'pa_') {
881
- unset( $taxonomies[$key]);
882
- }
883
- }
884
-
885
- return $taxonomies;
886
- }
887
-
888
- function get_wc_taxonomies(){
889
-
890
- global $wp_taxonomies;
891
- $taxonomies = array();
892
-
893
- //don't use get_taxonomies for product, because when one more post type registered for product taxonomy functions returned taxonomies only for product type
894
- foreach ( $wp_taxonomies as $key => $taxonomy ) {
895
-
896
- if (
897
- ( in_array( 'product', $taxonomy->object_type ) || in_array( 'product_variation', $taxonomy->object_type ) ) &&
898
- ! in_array( $key, $taxonomies )
899
- ) {
900
-
901
- if( substr( $key, 0, 3 ) == 'pa_' && !$this->woocommerce_wpml->attributes->is_translatable_attribute( $key ) ){
902
- continue;
903
- }
904
-
905
- $taxonomies[] = $key;
906
- }
907
- }
908
-
909
- return $taxonomies;
910
-
911
- }
912
-
913
- function has_wc_taxonomies_to_translate(){
914
-
915
- $taxonomies = $this->get_wc_taxonomies();
916
-
917
- $no_tax_to_trnls = false;
918
- foreach ( $taxonomies as $taxonomy ){
919
- if ( $taxonomy == 'product_type' || $this->get_untranslated_terms_number( $taxonomy ) == 0 ) {
920
- continue;
921
- } else {
922
- $no_tax_to_trnls = true;
923
- }
924
- }
925
-
926
- return $no_tax_to_trnls;
927
-
928
- }
929
-
930
- /*
931
- * Use custom query, because get_term_by function return false for terms with "0" slug *
932
- */
933
- public function wcml_get_term_id_by_slug( $taxonomy, $slug ){
934
-
935
- return $this->wpdb->get_var(
936
- $this->wpdb->prepare(
937
- "SELECT tt.term_id FROM {$this->wpdb->terms} AS t
938
- INNER JOIN {$this->wpdb->term_taxonomy} AS tt
939
- ON t.term_id = tt.term_id
940
- WHERE tt.taxonomy = %s AND t.slug = %s LIMIT 1",
941
- $taxonomy, sanitize_title( $slug ) )
942
- );
943
- }
944
-
945
- public function wcml_get_term_by_id( $term_id, $taxonomy ){
946
-
947
- return $this->wpdb->get_row(
948
- $this->wpdb->prepare("
949
- SELECT * FROM {$this->wpdb->terms} t
950
- JOIN {$this->wpdb->term_taxonomy} x
951
- ON x.term_id = t.term_id
952
- WHERE t.term_id = %d AND x.taxonomy = %s",
953
- $term_id, $taxonomy )
954
- );
955
- }
956
-
957
- public function wcml_get_translated_term( $term_id, $taxonomy, $language ){
958
-
959
- $tr_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, false, $language );
960
-
961
- if( !is_null( $tr_id ) ) {
962
- $term_id = $tr_id;
963
- }
964
-
965
- return $this->wcml_get_term_by_id( $term_id, $taxonomy );
966
- }
967
-
968
- }
1
+ <?php
2
+
3
+ class WCML_Terms{
4
+
5
+ private $ALL_TAXONOMY_TERMS_TRANSLATED = 0;
6
+ private $NEW_TAXONOMY_TERMS = 1;
7
+ private $NEW_TAXONOMY_IGNORED = 2;
8
+
9
+ private $woocommerce_wpml;
10
+ private $sitepress;
11
+ private $wpdb;
12
+
13
+ function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
14
+ $this->woocommerce_wpml = $woocommerce_wpml;
15
+ $this->sitepress = $sitepress;
16
+ $this->wpdb = $wpdb;
17
+
18
+ add_action('updated_woocommerce_term_meta',array($this,'sync_term_order'), 100,4);
19
+
20
+ add_filter('wp_get_object_terms', array($this->sitepress, 'get_terms_filter'));
21
+
22
+ add_action('icl_save_term_translation', array($this,'save_wc_term_meta'), 100,4);
23
+
24
+ add_action('created_term', array($this, 'translated_terms_status_update'), 10,3);
25
+ add_action('edit_term', array($this, 'translated_terms_status_update'), 10,3);
26
+ add_action('wp_ajax_wcml_update_term_translated_warnings', array( $this, 'wcml_update_term_translated_warnings'));
27
+
28
+ add_action('created_term', array( $this, 'set_flag_for_variation_on_attribute_update'), 10, 3);
29
+
30
+ add_filter('wpml_taxonomy_translation_bottom', array( $this, 'sync_taxonomy_translations'), 10, 3 );
31
+
32
+ add_action('wp_ajax_wcml_sync_product_variations', array( $this, 'wcml_sync_product_variations'));
33
+ add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content', array( $this, 'wcml_sync_taxonomies_in_content'));
34
+ add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content_preview', array( $this, 'wcml_sync_taxonomies_in_content_preview'));
35
+
36
+ if(is_admin()){
37
+ add_action('admin_menu', array($this, 'admin_menu_setup'));
38
+ }
39
+
40
+ add_action('delete_term',array($this, 'wcml_delete_term'),10,4);
41
+ add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
42
+ //filter coupons terms in admin
43
+ add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
44
+ add_filter('get_terms',array($this,'filter_shipping_classes_terms'),10,3);
45
+
46
+ add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
47
+ add_action( 'created_term_translation', array( $this, 'set_flag_to_sync'), 10, 3 );
48
+ }
49
+
50
+ function admin_menu_setup(){
51
+ global $pagenow;
52
+ if($pagenow == 'edit-tags.php' && isset($_GET['action']) && $_GET['action'] == 'edit'){
53
+ add_action('admin_notices', array($this, 'show_term_translation_screen_notices'));
54
+ }
55
+
56
+ $page = isset( $_GET['page'] )? $_GET['page'] : '';
57
+ if ( $page === ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' ) {
58
+ WCML_Resources::load_management_css();
59
+ wp_enqueue_script( 'wcml-scripts' );
60
+ }
61
+
62
+ }
63
+
64
+ function save_wc_term_meta($original_tax, $result){
65
+
66
+
67
+ // WooCommerce before termmeta table migration
68
+ $wc_before_term_meta = get_option( 'db_version' ) < 34370;
69
+
70
+ // backwards compatibility - before the termmeta table was added
71
+ if( $wc_before_term_meta ){
72
+
73
+ $term_wc_meta = $this->wpdb->get_results($this->wpdb->prepare("SELECT * FROM {$this->wpdb->woocommerce_termmeta} WHERE woocommerce_term_id=%s", $original_tax->term_id));
74
+ foreach ( $term_wc_meta as $wc_meta ){
75
+ $wc_original_metakey = $wc_meta->meta_key;
76
+ $wc_original_metavalue = $wc_meta->meta_value;
77
+ update_woocommerce_term_meta($result['term_id'], $wc_original_metakey, $wc_original_metavalue);
78
+ }
79
+ // End of backwards compatibility - before the termmeta table was added
80
+ }else{
81
+
82
+ $term_wc_meta = get_term_meta($original_tax->term_id, false, 1);
83
+ foreach ( $term_wc_meta as $key => $values ) {
84
+ update_term_meta( $result['term_id'], $key, array_pop( $values ) );
85
+ }
86
+
87
+ }
88
+ }
89
+
90
+ function show_term_translation_screen_notices(){
91
+
92
+ $taxonomies = array_keys(get_taxonomies(array('object_type'=>array('product')),'objects'));
93
+ $taxonomies = $taxonomies + array_keys(get_taxonomies(array('object_type'=>array('product_variations')),'objects'));
94
+ $taxonomies = array_unique($taxonomies);
95
+ $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : false;
96
+ if( $taxonomy && in_array( $taxonomy, $taxonomies ) ){
97
+ $taxonomy_obj = get_taxonomy($taxonomy);
98
+ $message = sprintf(__('To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s.', 'woocommerce-multilingual'),
99
+ $taxonomy_obj->labels->name,
100
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . $taxonomy_obj->labels->singular_name, '</a></strong>',
101
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml">'), '</a></strong>');
102
+
103
+ echo '<div class="updated"><p>' . $message . '</p></div>';
104
+ }
105
+
106
+ }
107
+
108
+ function sync_term_order_globally() {
109
+ //syncs the term order of any taxonomy in $this->wpdb->prefix.'woocommerce_attribute_taxonomies'
110
+ //use it when term orderings have become unsynched, e.g. before WCML 3.3.
111
+
112
+ if(!defined('WOOCOMMERCE_VERSION')){
113
+ return;
114
+ }
115
+
116
+ $cur_lang = $this->sitepress->get_current_language();
117
+ $lang = $this->sitepress->get_default_language();
118
+ $this->sitepress->switch_lang($lang);
119
+
120
+ $taxes = wc_get_attribute_taxonomies ();
121
+
122
+ if ($taxes) foreach ($taxes as $woo_tax) {
123
+ $tax = 'pa_'.$woo_tax->attribute_name;
124
+ $meta_key = 'order_'.$tax;
125
+ //if ($tax != 'pa_frame') continue;
126
+ $terms = get_terms($tax);
127
+ if ($terms)foreach ($terms as $term) {
128
+ $term_order = get_woocommerce_term_meta($term->term_id,$meta_key);
129
+ $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_'.$tax);
130
+ $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
131
+ if ($translations) foreach ($translations as $trans) {
132
+ if ($trans->language_code != $lang) {
133
+ update_woocommerce_term_meta( $trans->term_id, $meta_key, $term_order);
134
+ }
135
+ }
136
+ }
137
+ }
138
+
139
+ //sync product categories ordering
140
+ $terms = get_terms('product_cat');
141
+ if ($terms) foreach($terms as $term) {
142
+ $term_order = get_woocommerce_term_meta($term->term_id,'order');
143
+ $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
144
+ $translations = $this->sitepress->get_element_translations($trid,'tax_product_cat');
145
+ if ($translations) foreach ($translations as $trans) {
146
+ if ($trans->language_code != $lang) {
147
+ update_woocommerce_term_meta( $trans->term_id, 'order', $term_order);
148
+ }
149
+ }
150
+ }
151
+
152
+ $this->sitepress->switch_lang($cur_lang);
153
+
154
+ $this->woocommerce_wpml->settings['is_term_order_synced'] = 'yes';
155
+ $this->woocommerce_wpml->update_settings();
156
+
157
+ }
158
+
159
+ function sync_term_order($meta_id, $object_id, $meta_key, $meta_value) {
160
+
161
+ // WooCommerce before termmeta table migration
162
+ $wc_before_term_meta = get_option( 'db_version' ) < 34370;
163
+
164
+ if (!isset($_POST['thetaxonomy']) || !taxonomy_exists($_POST['thetaxonomy']) || substr($meta_key,0,5) != 'order')
165
+ return;
166
+
167
+ $tax = filter_input( INPUT_POST, 'thetaxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
168
+
169
+ $term_taxonomy_id = $this->wpdb->get_var($this->wpdb->prepare("SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $object_id, $tax));
170
+ $trid = $this->sitepress->get_element_trid($term_taxonomy_id, 'tax_' . $tax);
171
+ $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
172
+ if ($translations) foreach ($translations as $trans) {
173
+ if ($trans->element_id != $term_taxonomy_id) {
174
+
175
+ // Backwards compatibility - WooCommerce termmeta table
176
+ if( $wc_before_term_meta ) {
177
+ $this->wpdb->update( $this->wpdb->prefix . 'woocommerce_termmeta',
178
+ array('meta_value' => $meta_value),
179
+ array('woocommerce_term_id' => $trans->term_id, 'meta_key' => $meta_key) );
180
+ // END Backwards compatibility - WooCommerce termmeta table
181
+ } else{
182
+ update_term_meta( $trans->term_id, $meta_key, $meta_value);
183
+ }
184
+
185
+ }
186
+ }
187
+
188
+ }
189
+
190
+ function translated_terms_status_update($term_id, $tt_id, $taxonomy){
191
+
192
+ if ( isset( $_POST['product_cat_thumbnail_id'] ) || isset( $_POST['display_type'] ) ){
193
+ global $sitepress_settings;
194
+
195
+ if( $this->is_original_category($tt_id,'tax_'.$taxonomy) ){
196
+ $trid = $this->sitepress->get_element_trid($tt_id,'tax_'.$taxonomy);
197
+ $translations = $this->sitepress->get_element_translations($trid,'tax_'.$taxonomy);
198
+
199
+ foreach($translations as $translation){
200
+ if(!$translation->original){
201
+ if(isset($_POST['display_type'])){
202
+ update_woocommerce_term_meta( $translation->term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
203
+ }
204
+ update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', apply_filters( 'translate_object_id',esc_attr( $_POST['product_cat_thumbnail_id'] ),'attachment',true,$translation->language_code));
205
+ }
206
+ }
207
+ }
208
+ }
209
+
210
+ global $wp_taxonomies;
211
+ if(in_array('product', $wp_taxonomies[$taxonomy]->object_type) || in_array('product_variation', $wp_taxonomies[$taxonomy]->object_type)){
212
+ $this->update_terms_translated_status($taxonomy);
213
+ }
214
+
215
+ }
216
+
217
+ function is_original_category( $tt_id, $taxonomy ){
218
+ $is_original = $this->wpdb->get_var($this->wpdb->prepare("SELECT source_language_code IS NULL FROM {$this->wpdb->prefix}icl_translations WHERE element_id=%d AND element_type=%s", $tt_id, $taxonomy ));
219
+ return $is_original ? true : false;
220
+ }
221
+
222
+ public function wcml_update_term_translated_warnings(){
223
+ $ret = array();
224
+
225
+ $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
226
+
227
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
228
+
229
+ $attribute_taxonomies = $this->woocommerce_wpml->attributes->get_translatable_attributes();
230
+
231
+ $attribute_taxonomies_arr = array();
232
+ foreach($attribute_taxonomies as $a){
233
+ $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
234
+ }
235
+
236
+ $ret['is_attribute'] = intval( in_array( $taxonomy, $attribute_taxonomies_arr ) );
237
+
238
+ if( isset( $wcml_settings['untranstaled_terms'][$taxonomy] ) &&
239
+ (
240
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->ALL_TAXONOMY_TERMS_TRANSLATED ||
241
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_IGNORED
242
+ )
243
+ ){
244
+
245
+ $ret['hide'] = 1;
246
+ }else{
247
+
248
+ $ret['hide'] = 0;
249
+
250
+ if( isset( $wcml_settings[ 'sync_'.$taxonomy ]) ){
251
+ $ret[ 'show_button' ] = $wcml_settings[ 'sync_'.$taxonomy ];
252
+ }elseif( in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
253
+ $ret[ 'show_button' ] = $wcml_settings[ 'sync_variations' ];
254
+ }
255
+ }
256
+
257
+ if( $ret[ 'is_attribute' ] ){
258
+ $ret['hide'] = $this->woocommerce_wpml->attributes->is_attributes_fully_translated();
259
+ }
260
+
261
+ echo json_encode($ret);
262
+ exit;
263
+
264
+ }
265
+
266
+ public function update_terms_translated_status($taxonomy){
267
+
268
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
269
+ $is_translatable= 1;
270
+ $not_translated_count = 0;
271
+ $original_terms = array();
272
+
273
+ if( isset( $wcml_settings[ 'attributes_settings' ][ $taxonomy ] ) && !$wcml_settings[ 'attributes_settings' ][ $taxonomy ] ){
274
+ $is_translatable = 0;
275
+ }
276
+
277
+ if( $is_translatable ){
278
+
279
+ $active_languages = $this->sitepress->get_active_languages();
280
+
281
+ foreach($active_languages as $language){
282
+ $terms = $this->wpdb->get_results($this->wpdb->prepare("
283
+ SELECT t1.element_id AS e1, t2.element_id AS e2 FROM {$this->wpdb->term_taxonomy} x
284
+ JOIN {$this->wpdb->prefix}icl_translations t1 ON x.term_taxonomy_id = t1.element_id AND t1.element_type = %s AND t1.source_language_code IS NULL
285
+ LEFT JOIN {$this->wpdb->prefix}icl_translations t2 ON t2.trid = t1.trid AND t2.language_code = %s
286
+ ", 'tax_' . $taxonomy, $language['code']));
287
+ foreach($terms as $term){
288
+ if( empty( $term->e2 ) && !in_array( $term->e1, $original_terms ) ){
289
+ $original_terms[] = $term->e1;
290
+ $not_translated_count ++;
291
+ }
292
+ }
293
+ }
294
+ }
295
+
296
+ $status = $not_translated_count ? $this->NEW_TAXONOMY_TERMS : $this->ALL_TAXONOMY_TERMS_TRANSLATED;
297
+
298
+ if( isset( $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] ) && $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] === $this->NEW_TAXONOMY_IGNORED ){
299
+ $status = $this->NEW_TAXONOMY_IGNORED;
300
+ }
301
+
302
+ $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] = array( 'count' => $not_translated_count , 'status' => $status );
303
+
304
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
305
+
306
+ return $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ];
307
+
308
+ }
309
+
310
+ public function is_fully_translated($taxonomy){
311
+
312
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
313
+
314
+ $return = true;
315
+
316
+ if( !isset($wcml_settings['untranstaled_terms'][$taxonomy]) ){
317
+ $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
318
+ }
319
+
320
+ if($wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_TERMS){
321
+ $return = false;
322
+ }
323
+
324
+
325
+ return $return;
326
+ }
327
+
328
+ public function get_untranslated_terms_number( $taxonomy, $force_update = false ){
329
+
330
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
331
+
332
+ if( $force_update || !isset($wcml_settings['untranstaled_terms'][$taxonomy] ) ){
333
+ $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
334
+ }
335
+
336
+ return $wcml_settings['untranstaled_terms'][$taxonomy]['count'];
337
+
338
+ }
339
+
340
+ public function set_flag_for_variation_on_attribute_update($term_id, $tt_id, $taxonomy){
341
+
342
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
343
+ foreach($attribute_taxonomies as $a){
344
+ $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
345
+ }
346
+
347
+ if(isset( $attribute_taxonomies_arr ) && in_array($taxonomy, $attribute_taxonomies_arr)){
348
+
349
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
350
+
351
+ // get term language
352
+ $term_language = $this->sitepress->get_element_language_details($tt_id, 'tax_' . $taxonomy);
353
+
354
+ if( isset( $term_language->language_code ) && $term_language->language_code != $this->sitepress->get_default_language()){
355
+ // get term in the default language
356
+ $term_id = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $this->sitepress->get_default_language());
357
+
358
+ //does it belong to any posts (variations)
359
+ $objects = get_objects_in_term($term_id, $taxonomy);
360
+
361
+ if(!isset($wcml_settings['variations_needed'][$taxonomy])){
362
+ $wcml_settings['variations_needed'][$taxonomy] = 0;
363
+ }
364
+ $wcml_settings['variations_needed'][$taxonomy] += count($objects);
365
+
366
+ $this->woocommerce_wpml->update_settings($wcml_settings);
367
+
368
+ }
369
+ }
370
+
371
+ }
372
+
373
+ public function sync_taxonomy_translations( $html, $taxonomy, $taxonomy_obj ){
374
+
375
+ $is_wcml = is_admin() && $taxonomy && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']);
376
+ $is_ajax = is_ajax() && $taxonomy && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_get_terms_and_labels_for_taxonomy_table';
377
+ if( $is_wcml || $is_ajax ){
378
+
379
+ $sync_tax = new WCML_Sync_Taxonomy( $this->woocommerce_wpml, $taxonomy, $taxonomy_obj );
380
+ $html = $sync_tax->get_view();
381
+ }
382
+
383
+ return $html;
384
+ }
385
+
386
+ public function wcml_sync_product_variations($taxonomy){
387
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
388
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_product_variations')){
389
+ die('Invalid nonce');
390
+ }
391
+
392
+ $VARIATIONS_THRESHOLD = 20;
393
+
394
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
395
+ $response = array();
396
+
397
+ $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
398
+
399
+ $languages_processed = intval( $_POST['languages_processed']);
400
+
401
+ $condition = $languages_processed?'>=':'>';
402
+
403
+ $where = isset($_POST['last_post_id']) && $_POST['last_post_id'] ? ' ID '.$condition.' ' . intval($_POST['last_post_id']) . ' AND ' : '';
404
+
405
+ $post_ids = $this->wpdb->get_col($this->wpdb->prepare("
406
+ SELECT DISTINCT tr.object_id
407
+ FROM {$this->wpdb->term_relationships} tr
408
+ JOIN {$this->wpdb->term_taxonomy} tx on tr.term_taxonomy_id = tx.term_taxonomy_id
409
+ JOIN {$this->wpdb->posts} p ON tr.object_id = p.ID
410
+ JOIN {$this->wpdb->prefix}icl_translations t ON t.element_id = p.ID
411
+ WHERE {$where} tx.taxonomy = %s AND p.post_type = 'product' AND t.element_type='post_product' AND t.language_code = %s
412
+ ORDER BY ID ASC
413
+
414
+ ", $taxonomy, $this->sitepress->get_default_language()));
415
+
416
+ if($post_ids){
417
+
418
+ $variations_processed = 0;
419
+ $posts_processed = 0;
420
+ foreach($post_ids as $post_id){
421
+ $terms = wp_get_post_terms($post_id, $taxonomy);
422
+ $terms_count = count($terms) . "\n\n";
423
+
424
+ $trid = $this->sitepress->get_element_trid($post_id, 'post_product');
425
+ $translations = $this->sitepress->get_element_translations($trid, 'post_product');
426
+
427
+ $i = 1;
428
+
429
+ foreach($translations as $translation){
430
+
431
+ if($i > $languages_processed && $translation->element_id != $post_id){
432
+ $this->woocommerce_wpml->sync_product_data->sync_product_taxonomies($post_id, $translation->element_id, $translation->language_code);
433
+ $this->woocommerce_wpml->sync_variations_data->sync_product_variations($post_id, $translation->element_id, $translation->language_code, false, true);
434
+ $this->woocommerce_wpml->translation_editor->create_product_translation_package($post_id,$trid, $translation->language_code,ICL_TM_COMPLETE);
435
+ $variations_processed += $terms_count*2;
436
+ $response['languages_processed'] = $i;
437
+ $i++;
438
+ //check if sum of 2 iterations doesn't exceed $VARIATIONS_THRESHOLD
439
+ if($variations_processed >= $VARIATIONS_THRESHOLD){
440
+ break;
441
+ }
442
+ }else{
443
+ $i++;
444
+ }
445
+ }
446
+ $response['last_post_id'] = $post_id;
447
+ if(--$i == count($translations)){
448
+ $response['languages_processed'] = 0;
449
+ $languages_processed = 0;
450
+ }else{
451
+ break;
452
+ }
453
+
454
+ $posts_processed ++;
455
+
456
+ }
457
+
458
+ $response['go'] = 1;
459
+
460
+ }else{
461
+
462
+ $response['go'] = 0;
463
+
464
+ }
465
+
466
+ $response['progress'] = $response['go'] ? sprintf(__('%d products left', 'woocommerce-multilingual'), count($post_ids) - $posts_processed) : __('Synchronization complete!', 'woocommerce-multilingual');
467
+
468
+ if($response['go'] && isset($wcml_settings['variations_needed'][$taxonomy]) && !empty($variations_processed)){
469
+ $wcml_settings['variations_needed'][$taxonomy] = max($wcml_settings['variations_needed'][$taxonomy] - $variations_processed, 0);
470
+ }else{
471
+ if($response['go'] == 0){
472
+ $wcml_settings['variations_needed'][$taxonomy] = 0;
473
+ }
474
+ }
475
+ $wcml_settings['sync_variations'] = 0;
476
+
477
+ $this->woocommerce_wpml->update_settings($wcml_settings);
478
+
479
+ echo json_encode($response);
480
+ exit;
481
+ }
482
+
483
+ public function wcml_sync_taxonomies_in_content_preview(){
484
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
485
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content_preview')){
486
+ die('Invalid nonce');
487
+ }
488
+
489
+ global $wp_taxonomies;
490
+
491
+ $html = $message = $errors = '';
492
+
493
+
494
+ if(isset($wp_taxonomies[$_POST['taxonomy']])){
495
+ $object_types = $wp_taxonomies[$_POST['taxonomy']]->object_type;
496
+
497
+ foreach($object_types as $object_type){
498
+
499
+ $html .= $this->render_assignment_status($object_type, $_POST['taxonomy'], $preview = true);
500
+
501
+ }
502
+
503
+ }else{
504
+ $errors = sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
505
+ }
506
+
507
+
508
+ echo json_encode(array('html' => $html, 'message'=> $message, 'errors' => $errors));
509
+ exit;
510
+ }
511
+
512
+ public function wcml_sync_taxonomies_in_content(){
513
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
514
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content')){
515
+ die('Invalid nonce');
516
+ }
517
+
518
+ global $wp_taxonomies;
519
+
520
+ $html = $message = $errors = '';
521
+
522
+ if(isset($wp_taxonomies[$_POST['taxonomy']])){
523
+ $html .= $this->render_assignment_status($_POST['post'], $_POST['taxonomy'], $preview = false);
524
+
525
+ }else{
526
+ $errors .= sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
527
+ }
528
+
529
+
530
+ echo json_encode(array('html' => $html, 'errors' => $errors));
531
+ exit;
532
+ }
533
+
534
+ public function render_assignment_status($object_type, $taxonomy, $preview = true){
535
+ global $wp_post_types, $wp_taxonomies;
536
+
537
+ $default_language = $this->sitepress->get_default_language();
538
+
539
+ $posts = $this->wpdb->get_results($this->wpdb->prepare( "SELECT * FROM {$this->wpdb->posts} AS p LEFT JOIN {$this->wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = %s AND tr.source_language_code is NULL", $object_type ) );
540
+
541
+ foreach($posts as $post){
542
+
543
+ $terms = wp_get_post_terms($post->ID, $taxonomy);
544
+
545
+ $term_ids = array();
546
+ foreach($terms as $term){
547
+ $term_ids[] = $term->term_id;
548
+ }
549
+
550
+ $trid = $this->sitepress->get_element_trid($post->ID, 'post_' . $post->post_type);
551
+ $translations = $this->sitepress->get_element_translations($trid, 'post_' . $post->post_type, true, true);
552
+
553
+ foreach($translations as $language => $translation){
554
+
555
+ if($language != $default_language && $translation->element_id){
556
+
557
+ $terms_of_translation = wp_get_post_terms($translation->element_id, $taxonomy);
558
+
559
+ $translation_term_ids = array();
560
+ foreach($terms_of_translation as $term){
561
+
562
+ $term_id_original = apply_filters( 'translate_object_id',$term->term_id, $taxonomy, false, $default_language );
563
+ if(!$term_id_original || !in_array($term_id_original, $term_ids)){
564
+ // remove term
565
+
566
+ if($preview){
567
+ $needs_sync = true;
568
+ break(3);
569
+ }
570
+
571
+ $current_terms = wp_get_post_terms($translation->element_id, $taxonomy);
572
+ $updated_terms = array();
573
+ foreach($current_terms as $cterm){
574
+ if($cterm->term_id != $term->term_id){
575
+ $updated_terms[] = $taxonomy != 'product_type' ? $term->term_id : $term->name;
576
+ }
577
+ if(!$preview){
578
+
579
+ if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
580
+ $updated_terms = array_unique( array_map( 'intval', $updated_terms ) );
581
+ }
582
+
583
+ wp_set_post_terms($translation->element_id, $updated_terms, $taxonomy);
584
+ }
585
+
586
+ }
587
+
588
+ }else{
589
+ $translation_term_ids[] = $term_id_original;
590
+ }
591
+
592
+ }
593
+
594
+ foreach($term_ids as $term_id){
595
+
596
+ if(!in_array($term_id, $translation_term_ids)){
597
+ // add term
598
+
599
+ if($preview){
600
+ $needs_sync = true;
601
+ break(3);
602
+ }
603
+ $terms_array = array();
604
+ $term_id_translated = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $language);
605
+
606
+ // not using get_term
607
+ $translated_term = $this->wpdb->get_row($this->wpdb->prepare("
608
+ SELECT * FROM {$this->wpdb->terms} t JOIN {$this->wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $term_id_translated, $taxonomy));
609
+
610
+ if( $translated_term ){
611
+ $terms_array[] = $translated_term->term_id;
612
+ }
613
+
614
+ if(!$preview){
615
+
616
+ if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
617
+ $terms_array = array_unique( array_map( 'intval', $terms_array ) );
618
+ }
619
+
620
+ wp_set_post_terms($translation->element_id, $terms_array, $taxonomy, true);
621
+ }
622
+
623
+ }
624
+
625
+ }
626
+
627
+ }
628
+
629
+ }
630
+
631
+ }
632
+
633
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
634
+ $wcml_settings['sync_'.$taxonomy] = 0;
635
+ $this->woocommerce_wpml->update_settings($wcml_settings);
636
+
637
+ $out = '';
638
+
639
+ if($preview){
640
+
641
+ $out .= '<div class="wcml_tt_sync_row">';
642
+ if(!empty($needs_sync)){
643
+ $out .= '<form class="wcml_tt_do_sync">';
644
+ $out .= '<input type="hidden" name="post" value="' . $object_type . '" />';
645
+ $out .= wp_nonce_field('wcml_sync_taxonomies_in_content', 'wcml_sync_taxonomies_in_content_nonce',true,false);
646
+ $out .= '<input type="hidden" name="taxonomy" value="' . $taxonomy . '" />';
647
+ $out .= sprintf(__('Some translated %s have different %s assignments.', 'woocommerce-multilingual'),
648
+ '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>',
649
+ '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>');
650
+ $out .= '&nbsp;<a class="submit button-secondary" href="#">' . sprintf(__('Update %s for all translated %s', 'woocommerce-multilingual'),
651
+ '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
652
+ '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>') . '</a>' .
653
+ '&nbsp;<img src="'. ICL_PLUGIN_URL . '/res/img/ajax-loader.gif" alt="loading" height="16" width="16" class="wcml_tt_spinner" />';
654
+ $out .= "</form>";
655
+ }else{
656
+ $out .= sprintf(__('All %s have the same %s assignments.', 'woocommerce-multilingual'),
657
+ '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
658
+ '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>');
659
+ }
660
+ $out .= "</div>";
661
+
662
+ }else{
663
+
664
+ $out .= sprintf(__('Successfully updated %s for all translated %s.', 'woocommerce-multilingual'), $wp_taxonomies[$taxonomy]->labels->name, $wp_post_types[$object_type]->labels->name);
665
+
666
+ }
667
+
668
+ return $out;
669
+ }
670
+
671
+ function shipping_terms($terms, $post_id, $taxonomy){
672
+ global $pagenow;
673
+
674
+ if( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_load_variations' ){
675
+ return $terms;
676
+ }
677
+
678
+ if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
679
+
680
+ remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
681
+ $terms = get_the_terms( apply_filters( 'translate_object_id', $post_id, get_post_type($post_id), true, $this->sitepress->get_current_language() ),'product_shipping_class');
682
+ add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
683
+ return $terms;
684
+ }
685
+
686
+ return $terms;
687
+ }
688
+
689
+ function filter_coupons_terms($terms, $taxonomies, $args){
690
+ global $pagenow;
691
+
692
+ if(is_admin() && (($pagenow == 'post-new.php' && isset($_GET['post_type']) && $_GET['post_type'] == 'shop_coupon') || ($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'shop_coupon')) && in_array('product_cat',$taxonomies)){
693
+ remove_filter('get_terms',array($this,'filter_coupons_terms'));
694
+ $current_language = $this->sitepress->get_current_language();
695
+ $this->sitepress->switch_lang($this->sitepress->get_default_language());
696
+ $terms = get_terms( 'product_cat', 'orderby=name&hide_empty=0');
697
+ add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
698
+ $this->sitepress->switch_lang($current_language);
699
+ }
700
+
701
+ return $terms;
702
+ }
703
+
704
+ function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
705
+
706
+ $on_wc_settings_page = isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] === 'wc-settings';
707
+ $on_shipping_tab = isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] === 'shipping';
708
+ $on_classes_section = isset( $_GET[ 'section' ] ) && $_GET[ 'section' ] === 'classes';
709
+
710
+ if( is_admin() && in_array( 'product_shipping_class', (array) $taxonomies ) && $on_wc_settings_page && $on_shipping_tab && !$on_classes_section ){
711
+ remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
712
+ $current_language = $this->sitepress->get_current_language();
713
+ $this->sitepress->switch_lang($this->sitepress->get_default_language());
714
+ add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
715
+ $terms = get_terms( $taxonomies, $args );
716
+ remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
717
+ add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
718
+ $this->sitepress->switch_lang($current_language);
719
+ }
720
+
721
+ return $terms;
722
+ }
723
+
724
+ function wcml_delete_term($term, $tt_id, $taxonomy, $deleted_term){
725
+ global $wp_taxonomies;
726
+
727
+ foreach($wp_taxonomies as $key=>$taxonomy_obj){
728
+ if((in_array('product',$taxonomy_obj->object_type) || in_array('product_variation',$taxonomy_obj->object_type) ) && $key==$taxonomy){
729
+ $this->update_terms_translated_status($taxonomy);
730
+ break;
731
+ }
732
+ }
733
+
734
+ }
735
+
736
+ function get_product_terms_filter( $terms, $product_id, $taxonomy, $args ){
737
+
738
+ $language = $this->sitepress->get_language_for_element( $product_id, 'post_'.get_post_type( $product_id ) );
739
+
740
+ $is_objects_array = is_object( current ( $terms ) );
741
+
742
+ $filtered_terms = array();
743
+
744
+ foreach( $terms as $term ){
745
+
746
+ if( !$is_objects_array ){
747
+ $term_obj = get_term_by( 'name', $term, $taxonomy );
748
+ if( !$term_obj ){
749
+ $term_obj = get_term_by( 'slug', $term, $taxonomy );
750
+ $is_slug = true;
751
+ }
752
+ }
753
+
754
+ if( empty($term_obj) ){
755
+ $filtered_terms[] = $term;
756
+ continue;
757
+ }
758
+
759
+ $trnsl_term_id = apply_filters( 'translate_object_id', $term_obj->term_id, $taxonomy, true, $language );
760
+
761
+ if( $is_objects_array ){
762
+ $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy );
763
+ }else{
764
+ if( isset( $is_slug ) ){
765
+ $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy )->slug;
766
+ }else{
767
+ $filtered_terms[] = ( is_ajax() && isset( $_POST['action'] ) && in_array( $_POST['action'], array( 'woocommerce_add_variation', 'woocommerce_link_all_variations') ) ) ? strtolower ( get_term( $trnsl_term_id, $taxonomy )->name ) : get_term( $trnsl_term_id, $taxonomy )->name;
768
+ }
769
+ }
770
+ }
771
+
772
+ return $filtered_terms;
773
+ }
774
+
775
+
776
+
777
+
778
+ function set_flag_to_sync( $taxonomy, $el_id, $language_code ){
779
+
780
+ $elem_details = $this->sitepress->get_element_language_details( $el_id, 'tax_'.$taxonomy );
781
+ if( is_null( $elem_details->source_language_code ) )
782
+ return;
783
+
784
+ $this->check_if_sync_term_translation_needed( $el_id, $taxonomy );
785
+
786
+ }
787
+
788
+ function check_if_sync_terms_needed(){
789
+
790
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
791
+ $wcml_settings['sync_variations'] = 0;
792
+ $wcml_settings['sync_product_cat'] = 0;
793
+ $wcml_settings['sync_product_tag'] = 0;
794
+ $wcml_settings['sync_product_shipping_class'] = 0;
795
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
796
+
797
+ $taxonomies_to_check = array( 'product_cat', 'product_tag', 'product_shipping_class' );
798
+
799
+ foreach( $taxonomies_to_check as $check_taxonomy ){
800
+ $terms = get_terms( $check_taxonomy, array( 'hide_empty' => false, 'fields' => 'ids' ) );
801
+ if (is_array($terms)){
802
+ foreach( $terms as $term ){
803
+ if( $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], $check_taxonomy ) ){
804
+ break;
805
+ }
806
+ }
807
+ }
808
+ }
809
+
810
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
811
+ $flag_set = false;
812
+ foreach( $attribute_taxonomies as $a ){
813
+
814
+ $terms = get_terms( 'pa_' . $a->attribute_name, array( 'hide_empty' => false, 'fields' => 'ids' ) );
815
+ if (is_array($terms)){
816
+ foreach( $terms as $term ){
817
+ $flag_set = $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], 'pa_' . $a->attribute_name );
818
+ if( $flag_set ){
819
+ break;
820
+ }
821
+ }
822
+ }
823
+
824
+ if( $flag_set ){
825
+ break;
826
+ }
827
+ }
828
+
829
+ }
830
+
831
+ function check_if_sync_term_translation_needed( $t_id, $taxonomy ){
832
+
833
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
834
+
835
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
836
+ $attribute_taxonomies_arr = array();
837
+ foreach($attribute_taxonomies as $a){
838
+ $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
839
+ }
840
+
841
+ if( ( isset( $wcml_settings[ 'sync_'.$taxonomy ]) && $wcml_settings[ 'sync_'.$taxonomy ] ) || ( in_array( $taxonomy, $attribute_taxonomies_arr ) && isset( $wcml_settings[ 'sync_variations' ]) && $wcml_settings['sync_variations'] ) ){
842
+ return true;
843
+ }
844
+
845
+ $translations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT t2.element_id, t2.source_language_code FROM {$this->wpdb->prefix}icl_translations AS t1 LEFT JOIN {$this->wpdb->prefix}icl_translations AS t2 ON t1.trid = t2.trid WHERE t1.element_id = %d AND t1.element_type = %s ", $t_id, 'tax_'.$taxonomy ) );
846
+
847
+ foreach( $translations as $key => $translation ){
848
+ if ( is_null( $translation->source_language_code ) ) {
849
+ $original_count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
850
+ unset( $translations[ $key ] );
851
+ }
852
+ }
853
+
854
+ foreach( $translations as $translation ){
855
+
856
+ $count = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT count( object_id ) FROM {$this->wpdb->term_relationships} WHERE term_taxonomy_id = %d ", $translation->element_id ) );
857
+ if( $original_count != $count ){
858
+
859
+ if( in_array( $taxonomy, array( 'product_cat', 'product_tag', 'product_shipping_class' ) ) ){
860
+ $wcml_settings[ 'sync_'.$taxonomy ] = 1;
861
+ $this->woocommerce_wpml->update_settings($wcml_settings);
862
+ return true;
863
+ }
864
+
865
+ if( isset( $attribute_taxonomies_arr ) && in_array( $taxonomy, $attribute_taxonomies_arr ) ){
866
+ $wcml_settings['sync_variations'] = 1;
867
+ $this->woocommerce_wpml->update_settings($wcml_settings);
868
+ return true;
869
+ }
870
+
871
+ }
872
+
873
+ }
874
+
875
+ }
876
+
877
+ function get_table_taxonomies( $taxonomies ){
878
+
879
+ foreach( $taxonomies as $key => $taxonomy ){
880
+ if (substr($key, 0, 3) != 'pa_') {
881
+ unset( $taxonomies[$key]);
882
+ }
883
+ }
884
+
885
+ return $taxonomies;
886
+ }
887
+
888
+ function get_wc_taxonomies(){
889
+
890
+ global $wp_taxonomies;
891
+ $taxonomies = array();
892
+
893
+ //don't use get_taxonomies for product, because when one more post type registered for product taxonomy functions returned taxonomies only for product type
894
+ foreach ( $wp_taxonomies as $key => $taxonomy ) {
895
+
896
+ if (
897
+ ( in_array( 'product', $taxonomy->object_type ) || in_array( 'product_variation', $taxonomy->object_type ) ) &&
898
+ ! in_array( $key, $taxonomies )
899
+ ) {
900
+
901
+ if( substr( $key, 0, 3 ) == 'pa_' && !$this->woocommerce_wpml->attributes->is_translatable_attribute( $key ) ){
902
+ continue;
903
+ }
904
+
905
+ $taxonomies[] = $key;
906
+ }
907
+ }
908
+
909
+ return $taxonomies;
910
+
911
+ }
912
+
913
+ function has_wc_taxonomies_to_translate(){
914
+
915
+ $taxonomies = $this->get_wc_taxonomies();
916
+
917
+ $no_tax_to_trnls = false;
918
+ foreach ( $taxonomies as $taxonomy ){
919
+ if ( $taxonomy == 'product_type' || $this->get_untranslated_terms_number( $taxonomy ) == 0 ) {
920
+ continue;
921
+ } else {
922
+ $no_tax_to_trnls = true;
923
+ }
924
+ }
925
+
926
+ return $no_tax_to_trnls;
927
+
928
+ }
929
+
930
+ /*
931
+ * Use custom query, because get_term_by function return false for terms with "0" slug *
932
+ */
933
+ public function wcml_get_term_id_by_slug( $taxonomy, $slug ){
934
+
935
+ return $this->wpdb->get_var(
936
+ $this->wpdb->prepare(
937
+ "SELECT tt.term_id FROM {$this->wpdb->terms} AS t
938
+ INNER JOIN {$this->wpdb->term_taxonomy} AS tt
939
+ ON t.term_id = tt.term_id
940
+ WHERE tt.taxonomy = %s AND t.slug = %s LIMIT 1",
941
+ $taxonomy, sanitize_title( $slug ) )
942
+ );
943
+ }
944
+
945
+ public function wcml_get_term_by_id( $term_id, $taxonomy ){
946
+
947
+ return $this->wpdb->get_row(
948
+ $this->wpdb->prepare("
949
+ SELECT * FROM {$this->wpdb->terms} t
950
+ JOIN {$this->wpdb->term_taxonomy} x
951
+ ON x.term_id = t.term_id
952
+ WHERE t.term_id = %d AND x.taxonomy = %s",
953
+ $term_id, $taxonomy )
954
+ );
955
+ }
956
+
957
+ public function wcml_get_translated_term( $term_id, $taxonomy, $language ){
958
+
959
+ $tr_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, false, $language );
960
+
961
+ if( !is_null( $tr_id ) ) {
962
+ $term_id = $tr_id;
963
+ }
964
+
965
+ return $this->wcml_get_term_by_id( $term_id, $taxonomy );
966
+ }
967
+
968
+ }
inc/class-wcml-tp-support.php CHANGED
@@ -1,316 +1,316 @@
1
- <?php
2
-
3
- class WCML_TP_Support {
4
-
5
- /** @var WPML_Element_Translation_Package */
6
- private $tp;
7
-
8
- public function __construct() {
9
-
10
- $this->tp = new WPML_Element_Translation_Package;
11
-
12
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_attributes_to_translation_package' ), 10, 2 );
13
- add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 2 );
14
-
15
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_variation_descriptions_translation_package' ), 10, 2 );
16
- add_action( 'wpml_pro_translation_completed', array( $this, 'save_variation_descriptions_translations' ), 20, 3 ); //after WCML_Products
17
-
18
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_slug_to_translation_package' ), 10, 2 );
19
- add_action( 'wpml_translation_job_saved', array( $this, 'save_slug_translations' ), 10, 2 );
20
-
21
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_images_to_translation_package' ), 10, 2 );
22
- add_action( 'wpml_translation_job_saved', array( $this, 'save_images_translations' ), 10, 3 );
23
-
24
- }
25
-
26
- public function append_custom_attributes_to_translation_package( $package, $post ) {
27
-
28
- if ( $post->post_type == 'product' ) {
29
-
30
- $product = wc_get_product( $post->ID );
31
-
32
- $product_type = Deprecated_WC_Functions::get_product_type( $post->ID );
33
-
34
- if ( ! empty( $product ) && $product_type === 'variable' ) {
35
-
36
- $attributes = $product->get_attributes();
37
-
38
- foreach ( $attributes as $attribute_key => $attribute ) {
39
- if ( ! $attribute['is_taxonomy'] ) {
40
-
41
- $package['contents'][ 'wc_attribute_name:' . $attribute_key ] = array(
42
- 'translate' => 1,
43
- 'data' => $this->tp->encode_field_data( $attribute['name'], 'base64' ),
44
- 'format' => 'base64'
45
- );
46
-
47
- $values = explode( '|', $attribute['value'] );
48
- $values = array_map( 'trim', $values );
49
-
50
- foreach ( $values as $value_key => $value ) {
51
-
52
- $package['contents'][ 'wc_attribute_value:' . $value_key . ':' . $attribute_key ] = array(
53
- 'translate' => 1,
54
- 'data' => $this->tp->encode_field_data( $value, 'base64' ),
55
- 'format' => 'base64'
56
- );
57
-
58
- }
59
-
60
- }
61
- }
62
-
63
- }
64
-
65
- }
66
-
67
- return $package;
68
- }
69
-
70
- public function save_custom_attribute_translations( $post_id, $data ) {
71
- global $woocommerce_wpml;
72
-
73
- $translated_attributes = array();
74
-
75
- foreach ( $data as $data_key => $value ) {
76
-
77
- if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_attribute_' ) === 0 ) {
78
-
79
- if ( strpos( $value['field_type'], 'wc_attribute_name:' ) === 0 ) {
80
-
81
- $exp = explode( ':', $value['field_type'], 2 );
82
- $attribute_key = $exp[1];
83
-
84
- $translated_attributes[ $attribute_key ]['name'] = $value['data'];
85
-
86
- } else if ( strpos( $value['field_type'], 'wc_attribute_value:' ) === 0 ) {
87
-
88
- $exp = explode( ':', $value['field_type'], 3 );
89
- $value_key = $exp[1];
90
- $attribute_key = $exp[2];
91
-
92
- $translated_attributes[ $attribute_key ]['values'][ $value_key ] = $value['data'];
93
-
94
- }
95
-
96
- }
97
-
98
- }
99
-
100
- if ( $translated_attributes ) {
101
-
102
- $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
103
-
104
- $original_post_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
105
- $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
106
-
107
- $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
108
-
109
- foreach ( $translated_attributes as $attribute_key => $attribute ) {
110
-
111
- $product_attributes[ $attribute_key ] = array(
112
- 'name' => $attribute['name'],
113
- 'value' => join( ' | ', $attribute['values'] ),
114
- 'is_taxonomy' => 0,
115
- 'is_visible' => $original_attributes[ $attribute_key ]['is_visible'],
116
- 'position' => $original_attributes[ $attribute_key ]['position']
117
- );
118
-
119
-
120
- }
121
-
122
- update_post_meta( $post_id, '_product_attributes', $product_attributes );
123
-
124
- }
125
-
126
- }
127
-
128
- public function append_variation_descriptions_translation_package( $package, $post ) {
129
-
130
- if ( $post->post_type == 'product' ) {
131
-
132
- /** @var WC_Product_Variable $product */
133
- $product = wc_get_product( $post->ID );
134
-
135
- $product_type = Deprecated_WC_Functions::get_product_type( $post->ID );
136
-
137
- if ( ! empty( $product ) && $product_type === 'variable' ) {
138
-
139
- $variations = $product->get_available_variations();
140
-
141
- foreach ( $variations as $variation ) {
142
-
143
- if ( ! empty( $variation['variation_description'] ) ) {
144
-
145
- $package['contents'][ 'wc_variation_description:' . $variation['variation_id'] ] = array(
146
- 'translate' => 1,
147
- 'data' => $this->tp->encode_field_data( $variation['variation_description'], 'base64' ),
148
- 'format' => 'base64'
149
- );
150
-
151
- }
152
-
153
- }
154
-
155
- }
156
-
157
- }
158
-
159
- return $package;
160
-
161
- }
162
-
163
- public function save_variation_descriptions_translations( $post_id, $data, $job ) {
164
-
165
- $language = $job->language_code;
166
-
167
- foreach ( $data as $data_key => $value ) {
168
-
169
- if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_variation_description:' ) === 0 ) {
170
-
171
- $variation_id = substr( $value['field_type'], strpos( $value['field_type'], ':' ) + 1 );
172
-
173
- if ( is_post_type_translated( 'product_variation' ) ) {
174
-
175
- $translated_variation_id = apply_filters( 'translate_object_id', $variation_id, 'product_variation', false, $language );
176
-
177
- } else {
178
- global $sitepress;
179
- $trid = $sitepress->get_element_trid( $variation_id, 'post_product_variation' );
180
- $translations = $sitepress->get_element_translations( $trid, 'post_product_variation', true, true, true );
181
-
182
- $translated_variation_id = isset( $translations[ $language ] ) ? $translations[ $language ]->element_id : false;
183
-
184
- }
185
-
186
- if ( $translated_variation_id ) {
187
- update_post_meta( $translated_variation_id, '_variation_description', $value['data'] );
188
- }
189
-
190
-
191
- }
192
-
193
- }
194
-
195
- }
196
-
197
- public function append_slug_to_translation_package( $package, $post ) {
198
- if ( $post->post_type == 'product' ) {
199
-
200
- $this->add_to_package( $package, 'slug', urldecode( $post->post_name ) );
201
- }
202
-
203
- return $package;
204
- }
205
-
206
- public function save_slug_translations( $post_id, $data ) {
207
- global $wpdb;
208
-
209
- foreach ( $data as $data_key => $value ) {
210
- if ( $value['finished'] && isset( $value['field_type'] ) && 'slug' === $value['field_type'] ) {
211
- $product = get_post( $post_id );
212
- if ( $product->post_type == 'product' ) {
213
- $new_slug = wp_unique_post_slug( sanitize_title( $value['data'] ), $post_id, $product->post_status, $product->post_type, $product->post_parent );
214
- $wpdb->update( $wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $post_id ) );
215
- break;
216
- }
217
- }
218
- }
219
- }
220
-
221
- public function append_images_to_translation_package( $package, $post ) {
222
- global $wpdb;
223
-
224
- if ( $post->post_type == 'product' ) {
225
-
226
- $woocommerce_wpml = woocommerce_wpml::instance();
227
- $product_images = $woocommerce_wpml->media->product_images_ids( $post->ID );
228
- $product_images = $woocommerce_wpml->media->exclude_not_duplicated_attachments( $product_images, $post->ID );
229
- foreach ( $product_images as $image_id ) {
230
- $attachment_data = $wpdb->get_row( $wpdb->prepare( "SELECT post_title,post_excerpt,post_content FROM {$wpdb->posts} WHERE ID = %d", $image_id ) );
231
- if ( ! $attachment_data ) {
232
- continue;
233
- }
234
- $alt_text = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
235
- $alt_text = $alt_text ? $alt_text : '';
236
- $this->add_to_package( $package, 'image-id-' . $image_id . '-title', $attachment_data->post_title );
237
- $this->add_to_package( $package, 'image-id-' . $image_id . '-caption', $attachment_data->post_excerpt );
238
- $this->add_to_package( $package, 'image-id-' . $image_id . '-description', $attachment_data->post_content );
239
- $this->add_to_package( $package, 'image-id-' . $image_id . '-alt-text', $alt_text );
240
-
241
- }
242
- }
243
- return $package;
244
- }
245
-
246
- public function save_images_translations( $post_id, $data, $job ) {
247
- global $wpdb;
248
-
249
- $language = $job->language_code;
250
-
251
- $woocommerce_wpml = woocommerce_wpml::instance();
252
-
253
- $product_images = $woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
254
- foreach ( $product_images as $image_id ) {
255
- $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
256
- $image_data = $this->get_image_data( $image_id, $data );
257
- if ( ! empty( $image_data ) ) {
258
-
259
- $translation = array();
260
- if( isset( $image_data['title'] ) ){
261
- $translation['post_title'] = $image_data['title'];
262
- }
263
- if( isset( $image_data['description'] ) ){
264
- $translation['post_content'] = $image_data['description'];
265
- }
266
- if( isset( $image_data['caption'] ) ){
267
- $translation['post_excerpt'] = $image_data['caption'];
268
- }
269
-
270
- if( $translation ){
271
- $wpdb->update( $wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
272
- }
273
-
274
- if ( isset( $image_data['alt-text'] ) ) {
275
- update_post_meta( $translated_prod_image, '_wp_attachment_image_alt', $image_data['alt-text'] );
276
- }
277
- }
278
- }
279
- }
280
-
281
- private function get_image_data( $image_id, $data ) {
282
- $image_data = array();
283
-
284
- foreach ( $data as $data_key => $value ) {
285
- if ( $value['finished'] ) {
286
- if ( strpos( $value['field_type'], 'image-id-' . $image_id ) === 0 ) {
287
- if ( $value['field_type'] === 'image-id-' . $image_id . '-title' ) {
288
- $image_data['title'] = $value['data'];
289
- }
290
- if ( $value['field_type'] === 'image-id-' . $image_id . '-caption' ) {
291
- $image_data['caption'] = $value['data'];
292
- }
293
- if ( $value['field_type'] === 'image-id-' . $image_id . '-description' ) {
294
- $image_data['description'] = $value['data'];
295
- }
296
- if ( $value['field_type'] === 'image-id-' . $image_id . '-alt-text' ) {
297
- $image_data['alt-text'] = $value['data'];
298
- }
299
- }
300
- }
301
- }
302
-
303
- return $image_data;
304
- }
305
-
306
- private function add_to_package( &$package, $key, $data ) {
307
- $package['contents'][ $key ] = array(
308
- 'translate' => 1,
309
- 'data' => $this->tp->encode_field_data( $data, 'base64' ),
310
- 'format' => 'base64'
311
- );
312
-
313
- }
314
- }
315
-
316
-
1
+ <?php
2
+
3
+ class WCML_TP_Support {
4
+
5
+ /** @var WPML_Element_Translation_Package */
6
+ private $tp;
7
+
8
+ public function __construct() {
9
+
10
+ $this->tp = new WPML_Element_Translation_Package;
11
+
12
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_attributes_to_translation_package' ), 10, 2 );
13
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 2 );
14
+
15
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_variation_descriptions_translation_package' ), 10, 2 );
16
+ add_action( 'wpml_pro_translation_completed', array( $this, 'save_variation_descriptions_translations' ), 20, 3 ); //after WCML_Products
17
+
18
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_slug_to_translation_package' ), 10, 2 );
19
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_slug_translations' ), 10, 2 );
20
+
21
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_images_to_translation_package' ), 10, 2 );
22
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_images_translations' ), 10, 3 );
23
+
24
+ }
25
+
26
+ public function append_custom_attributes_to_translation_package( $package, $post ) {
27
+
28
+ if ( $post->post_type == 'product' ) {
29
+
30
+ $product = wc_get_product( $post->ID );
31
+
32
+ $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
33
+
34
+ if ( ! empty( $product ) && $product_type === 'variable' ) {
35
+
36
+ $attributes = $product->get_attributes();
37
+
38
+ foreach ( $attributes as $attribute_key => $attribute ) {
39
+ if ( ! $attribute['is_taxonomy'] ) {
40
+
41
+ $package['contents'][ 'wc_attribute_name:' . $attribute_key ] = array(
42
+ 'translate' => 1,
43
+ 'data' => $this->tp->encode_field_data( $attribute['name'], 'base64' ),
44
+ 'format' => 'base64'
45
+ );
46
+
47
+ $values = explode( '|', $attribute['value'] );
48
+ $values = array_map( 'trim', $values );
49
+
50
+ foreach ( $values as $value_key => $value ) {
51
+
52
+ $package['contents'][ 'wc_attribute_value:' . $value_key . ':' . $attribute_key ] = array(
53
+ 'translate' => 1,
54
+ 'data' => $this->tp->encode_field_data( $value, 'base64' ),
55
+ 'format' => 'base64'
56
+ );
57
+
58
+ }
59
+
60
+ }
61
+ }
62
+
63
+ }
64
+
65
+ }
66
+
67
+ return $package;
68
+ }
69
+
70
+ public function save_custom_attribute_translations( $post_id, $data ) {
71
+ global $woocommerce_wpml;
72
+
73
+ $translated_attributes = array();
74
+
75
+ foreach ( $data as $data_key => $value ) {
76
+
77
+ if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_attribute_' ) === 0 ) {
78
+
79
+ if ( strpos( $value['field_type'], 'wc_attribute_name:' ) === 0 ) {
80
+
81
+ $exp = explode( ':', $value['field_type'], 2 );
82
+ $attribute_key = $exp[1];
83
+
84
+ $translated_attributes[ $attribute_key ]['name'] = $value['data'];
85
+
86
+ } else if ( strpos( $value['field_type'], 'wc_attribute_value:' ) === 0 ) {
87
+
88
+ $exp = explode( ':', $value['field_type'], 3 );
89
+ $value_key = $exp[1];
90
+ $attribute_key = $exp[2];
91
+
92
+ $translated_attributes[ $attribute_key ]['values'][ $value_key ] = $value['data'];
93
+
94
+ }
95
+
96
+ }
97
+
98
+ }
99
+
100
+ if ( $translated_attributes ) {
101
+
102
+ $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
103
+
104
+ $original_post_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
105
+ $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
106
+
107
+ $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
108
+
109
+ foreach ( $translated_attributes as $attribute_key => $attribute ) {
110
+
111
+ $product_attributes[ $attribute_key ] = array(
112
+ 'name' => $attribute['name'],
113
+ 'value' => join( ' | ', $attribute['values'] ),
114
+ 'is_taxonomy' => 0,
115
+ 'is_visible' => $original_attributes[ $attribute_key ]['is_visible'],
116
+ 'position' => $original_attributes[ $attribute_key ]['position']
117
+ );
118
+
119
+
120
+ }
121
+
122
+ update_post_meta( $post_id, '_product_attributes', $product_attributes );
123
+
124
+ }
125
+
126
+ }
127
+
128
+ public function append_variation_descriptions_translation_package( $package, $post ) {
129
+
130
+ if ( $post->post_type == 'product' ) {
131
+
132
+ /** @var WC_Product_Variable $product */
133
+ $product = wc_get_product( $post->ID );
134
+
135
+ $product_type = WooCommerce_Functions_Wrapper::get_product_type( $post->ID );
136
+
137
+ if ( ! empty( $product ) && $product_type === 'variable' ) {
138
+
139
+ $variations = $product->get_available_variations();
140
+
141
+ foreach ( $variations as $variation ) {
142
+
143
+ if ( ! empty( $variation['variation_description'] ) ) {
144
+
145
+ $package['contents'][ 'wc_variation_description:' . $variation['variation_id'] ] = array(
146
+ 'translate' => 1,
147
+ 'data' => $this->tp->encode_field_data( $variation['variation_description'], 'base64' ),
148
+ 'format' => 'base64'
149
+ );
150
+
151
+ }
152
+
153
+ }
154
+
155
+ }
156
+
157
+ }
158
+
159
+ return $package;
160
+
161
+ }
162
+
163
+ public function save_variation_descriptions_translations( $post_id, $data, $job ) {
164
+
165
+ $language = $job->language_code;
166
+
167
+ foreach ( $data as $data_key => $value ) {
168
+
169
+ if ( $value['finished'] && isset( $value['field_type'] ) && strpos( $value['field_type'], 'wc_variation_description:' ) === 0 ) {
170
+
171
+ $variation_id = substr( $value['field_type'], strpos( $value['field_type'], ':' ) + 1 );
172
+
173
+ if ( is_post_type_translated( 'product_variation' ) ) {
174
+
175
+ $translated_variation_id = apply_filters( 'translate_object_id', $variation_id, 'product_variation', false, $language );
176
+
177
+ } else {
178
+ global $sitepress;
179
+ $trid = $sitepress->get_element_trid( $variation_id, 'post_product_variation' );
180
+ $translations = $sitepress->get_element_translations( $trid, 'post_product_variation', true, true, true );
181
+
182
+ $translated_variation_id = isset( $translations[ $language ] ) ? $translations[ $language ]->element_id : false;
183
+
184
+ }
185
+
186
+ if ( $translated_variation_id ) {
187
+ update_post_meta( $translated_variation_id, '_variation_description', $value['data'] );
188
+ }
189
+
190
+
191
+ }
192
+
193
+ }
194
+
195
+ }
196
+
197
+ public function append_slug_to_translation_package( $package, $post ) {
198
+ if ( $post->post_type == 'product' ) {
199
+
200
+ $this->add_to_package( $package, 'slug', urldecode( $post->post_name ) );
201
+ }
202
+
203
+ return $package;
204
+ }
205
+
206
+ public function save_slug_translations( $post_id, $data ) {
207
+ global $wpdb;
208
+
209
+ foreach ( $data as $data_key => $value ) {
210
+ if ( $value['finished'] && isset( $value['field_type'] ) && 'slug' === $value['field_type'] ) {
211
+ $product = get_post( $post_id );
212
+ if ( $product->post_type == 'product' ) {
213
+ $new_slug = wp_unique_post_slug( sanitize_title( $value['data'] ), $post_id, $product->post_status, $product->post_type, $product->post_parent );
214
+ $wpdb->update( $wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $post_id ) );
215
+ break;
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ public function append_images_to_translation_package( $package, $post ) {
222
+ global $wpdb;
223
+
224
+ if ( $post->post_type == 'product' ) {
225
+
226
+ $woocommerce_wpml = woocommerce_wpml::instance();
227
+ $product_images = $woocommerce_wpml->media->product_images_ids( $post->ID );
228
+ $product_images = $woocommerce_wpml->media->exclude_not_duplicated_attachments( $product_images, $post->ID );
229
+ foreach ( $product_images as $image_id ) {
230
+ $attachment_data = $wpdb->get_row( $wpdb->prepare( "SELECT post_title,post_excerpt,post_content FROM {$wpdb->posts} WHERE ID = %d", $image_id ) );
231
+ if ( ! $attachment_data ) {
232
+ continue;
233
+ }
234
+ $alt_text = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
235
+ $alt_text = $alt_text ? $alt_text : '';
236
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-title', $attachment_data->post_title );
237
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-caption', $attachment_data->post_excerpt );
238
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-description', $attachment_data->post_content );
239
+ $this->add_to_package( $package, 'image-id-' . $image_id . '-alt-text', $alt_text );
240
+
241
+ }
242
+ }
243
+ return $package;
244
+ }
245
+
246
+ public function save_images_translations( $post_id, $data, $job ) {
247
+ global $wpdb;
248
+
249
+ $language = $job->language_code;
250
+
251
+ $woocommerce_wpml = woocommerce_wpml::instance();
252
+
253
+ $product_images = $woocommerce_wpml->media->product_images_ids( $job->original_doc_id );
254
+ foreach ( $product_images as $image_id ) {
255
+ $translated_prod_image = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $language );
256
+ $image_data = $this->get_image_data( $image_id, $data );
257
+ if ( ! empty( $image_data ) ) {
258
+
259
+ $translation = array();
260
+ if( isset( $image_data['title'] ) ){
261
+ $translation['post_title'] = $image_data['title'];
262
+ }
263
+ if( isset( $image_data['description'] ) ){
264
+ $translation['post_content'] = $image_data['description'];
265
+ }
266
+ if( isset( $image_data['caption'] ) ){
267
+ $translation['post_excerpt'] = $image_data['caption'];
268
+ }
269
+
270
+ if( $translation ){
271
+ $wpdb->update( $wpdb->posts, $translation, array( 'id' => $translated_prod_image ) );
272
+ }
273
+
274
+ if ( isset( $image_data['alt-text'] ) ) {
275
+ update_post_meta( $translated_prod_image, '_wp_attachment_image_alt', $image_data['alt-text'] );
276
+ }
277
+ }
278
+ }
279
+ }
280
+
281
+ private function get_image_data( $image_id, $data ) {
282
+ $image_data = array();
283
+
284
+ foreach ( $data as $data_key => $value ) {
285
+ if ( $value['finished'] ) {
286
+ if ( strpos( $value['field_type'], 'image-id-' . $image_id ) === 0 ) {
287
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-title' ) {
288
+ $image_data['title'] = $value['data'];
289
+ }
290
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-caption' ) {
291
+ $image_data['caption'] = $value['data'];
292
+ }
293
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-description' ) {
294
+ $image_data['description'] = $value['data'];
295
+ }
296
+ if ( $value['field_type'] === 'image-id-' . $image_id . '-alt-text' ) {
297
+ $image_data['alt-text'] = $value['data'];
298
+ }
299
+ }
300
+ }
301
+ }
302
+
303
+ return $image_data;
304
+ }
305
+
306
+ private function add_to_package( &$package, $key, $data ) {
307
+ $package['contents'][ $key ] = array(
308
+ 'translate' => 1,
309
+ 'data' => $this->tp->encode_field_data( $data, 'base64' ),
310
+ 'format' => 'base64'
311
+ );
312
+
313
+ }
314
+ }
315
+
316
+
inc/class-wcml-troubleshooting.php CHANGED
@@ -1,249 +1,249 @@
1
- <?php
2
-
3
- class WCML_Troubleshooting{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'));
8
-
9
- }
10
-
11
- function init(){
12
- add_action('wp_ajax_trbl_sync_variations', array($this,'trbl_sync_variations'));
13
- add_action('wp_ajax_trbl_gallery_images', array($this,'trbl_gallery_images'));
14
- add_action('wp_ajax_trbl_update_count', array($this,'trbl_update_count'));
15
- add_action('wp_ajax_trbl_sync_categories', array($this,'trbl_sync_categories'));
16
- add_action('wp_ajax_trbl_duplicate_terms', array($this,'trbl_duplicate_terms'));
17
- add_action('wp_ajax_trbl_fix_product_type_terms', array($this,'trbl_fix_product_type_terms'));
18
-
19
- }
20
-
21
- function wcml_count_products_with_variations(){
22
- return count(get_option('wcml_products_to_sync'));
23
- }
24
-
25
- function trbl_update_count(){
26
-
27
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
28
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_update_count')){
29
- die('Invalid nonce');
30
- }
31
-
32
- $this->wcml_sync_variations_update_option();
33
- echo $this->wcml_count_products_with_variations();
34
-
35
- die();
36
- }
37
-
38
- function wcml_sync_variations_update_option(){
39
- global $wpdb;
40
- $get_variation_term_taxonomy_ids = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.name = 'variable'");
41
- $get_variation_term_taxonomy_ids = apply_filters('wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids);
42
-
43
- $get_variables_products = $wpdb->get_results($wpdb->prepare("SELECT tr.element_id as id,tr.language_code as lang FROM {$wpdb->prefix}icl_translations AS tr LEFT JOIN $wpdb->term_relationships as t ON tr.element_id = t.object_id LEFT JOIN $wpdb->posts AS p ON tr.element_id = p.ID
44
- WHERE p.post_status = 'publish' AND tr.source_language_code is NULL AND tr.element_type = 'post_product' AND t.term_taxonomy_id IN (%s) ORDER BY tr.element_id",join(',',$get_variation_term_taxonomy_ids)),ARRAY_A);
45
-
46
- update_option('wcml_products_to_sync',$get_variables_products);
47
- }
48
-
49
- function wcml_count_products(){
50
- global $wpdb;
51
- $get_products_count = $wpdb->get_var("SELECT count(ID) FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL");
52
- return $get_products_count;
53
- }
54
-
55
- function wcml_count_products_for_gallery_sync(){
56
- global $wpdb;
57
- $all_products = $wpdb->get_results("SELECT p.ID FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL");
58
- foreach($all_products as $key=>$product){
59
- if(get_post_meta($product->ID,'gallery_sync',true)){
60
- unset($all_products[$key]);
61
- }
62
- }
63
- return count($all_products);
64
- }
65
-
66
- function wcml_count_product_categories(){
67
- global $wpdb;
68
- $get_product_categories = $wpdb->get_results("SELECT t.term_taxonomy_id FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL");
69
- foreach($get_product_categories as $key=>$get_product_category){
70
- if(get_option('wcml_sync_category_'.$get_product_category->term_taxonomy_id)){
71
- unset($get_product_categories[$key]);
72
- }
73
- }
74
- return count($get_product_categories);
75
- }
76
-
77
-
78
- function trbl_sync_variations(){
79
-
80
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
81
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_sync_variations')){
82
- die('Invalid nonce');
83
- }
84
-
85
- global $woocommerce_wpml,$wpdb,$sitepress;
86
-
87
- $get_variables_products = get_option('wcml_products_to_sync');
88
- $all_active_lang = $sitepress->get_active_languages();
89
- $unset_keys = array();
90
- $products_for_one_ajax = array_slice($get_variables_products,0,3,true);
91
-
92
-
93
- foreach ($products_for_one_ajax as $key => $product){
94
- foreach($all_active_lang as $language){
95
- if($language['code'] != $product['lang']){
96
- $tr_product_id = apply_filters( 'translate_object_id',$product['id'],'product',false,$language['code']);
97
-
98
- if(!is_null($tr_product_id)){
99
- $woocommerce_wpml->sync_variations_data->sync_product_variations($product['id'],$tr_product_id,$language['code'],false,true);
100
- }
101
- if(!in_array($key,$unset_keys)){
102
- $unset_keys[] = $key;
103
- }
104
- }
105
- }
106
- }
107
-
108
-
109
- foreach($unset_keys as $unset_key){
110
- unset($get_variables_products[$unset_key]);
111
- }
112
-
113
- update_option('wcml_products_to_sync',$get_variables_products);
114
-
115
- $wcml_settings = get_option('_wcml_settings');
116
- if(isset($wcml_settings['notifications']) && isset($wcml_settings['notifications']['varimages'])){
117
- $wcml_settings['notifications']['varimages']['show'] = 0;
118
- update_option('_wcml_settings', $wcml_settings);
119
- }
120
-
121
- echo 1;
122
-
123
- die();
124
- }
125
-
126
- function trbl_gallery_images(){
127
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
128
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_gallery_images')){
129
- die('Invalid nonce');
130
- }
131
-
132
- $page = isset($_POST['page'])? intval( $_POST['page'] ) :0;
133
-
134
- global $woocommerce_wpml,$wpdb;
135
-
136
- $all_products = $wpdb->get_results($wpdb->prepare("SELECT p.* FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL ORDER BY p.ID LIMIT %d,5",$page*5));
137
-
138
- foreach($all_products as $product){
139
- if(!get_post_meta($product->ID,'gallery_sync',true)){
140
- $woocommerce_wpml->media->sync_product_gallery($product->ID);
141
- add_post_meta($product->ID,'gallery_sync',true);
142
- }
143
- }
144
-
145
- echo 1;
146
-
147
- die();
148
-
149
- }
150
-
151
- function trbl_sync_categories(){
152
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
153
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_sync_categories')){
154
- die('Invalid nonce');
155
- }
156
-
157
- $page = isset($_POST['page'])? intval( $_POST['page'] ):0;
158
-
159
- global $wpdb,$sitepress;
160
-
161
- $all_categories = $wpdb->get_results($wpdb->prepare("SELECT t.term_taxonomy_id,t.term_id,tr.language_code FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL ORDER BY t.term_taxonomy_id LIMIT %d,5",$page*5));
162
-
163
- foreach($all_categories as $category){
164
- if(!get_option('wcml_sync_category_'.$category->term_taxonomy_id)){
165
- add_option('wcml_sync_category_'.$category->term_taxonomy_id,true);
166
- $trid = $sitepress->get_element_trid($category->term_taxonomy_id,'tax_product_cat');
167
- $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
168
- $type = get_woocommerce_term_meta( $category->term_id, 'display_type',true);
169
- $thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id',true);
170
- foreach($translations as $translation){
171
- if($translation->language_code != $category->language_code ){
172
- update_woocommerce_term_meta( $translation->term_id, 'display_type', $type );
173
- update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', apply_filters( 'translate_object_id',$thumbnail_id,'attachment',true,$translation->language_code) );
174
- }
175
- }
176
- }
177
-
178
- }
179
-
180
- echo 1;
181
-
182
- die();
183
-
184
- }
185
-
186
-
187
- function trbl_duplicate_terms(){
188
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
189
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_duplicate_terms')){
190
- die('Invalid nonce');
191
- }
192
- global $sitepress;
193
-
194
- $attr = isset($_POST['attr'])?$_POST['attr']:false;
195
-
196
- $terms = get_terms($attr,'hide_empty=0');
197
- $i = 0;
198
- $languages = $sitepress->get_active_languages();
199
- foreach($terms as $term){
200
- foreach($languages as $language){
201
- $tr_id = apply_filters( 'translate_object_id',$term->term_id, $attr, false, $language['code']);
202
-
203
- if(is_null($tr_id)){
204
- $term_args = array();
205
- // hierarchy - parents
206
- if ( is_taxonomy_hierarchical( $attr ) ) {
207
- // fix hierarchy
208
- if ( $term->parent ) {
209
- $original_parent_translated = apply_filters( 'translate_object_id', $term->parent, $attr, false, $language['code'] );
210
- if ( $original_parent_translated ) {
211
- $term_args[ 'parent' ] = $original_parent_translated;
212
- }
213
- }
214
- }
215
-
216
- $term_name = $term->name;
217
- $slug = $term->name.'-'.$language['code'];
218
- $slug = WPML_Terms_Translations::term_unique_slug( $slug, $attr, $language['code'] );
219
- $term_args[ 'slug' ] = $slug;
220
-
221
- $new_term = wp_insert_term( $term_name , $attr, $term_args );
222
- if ( $new_term && !is_wp_error( $new_term ) ) {
223
- $tt_id = $sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $attr );
224
- $sitepress->set_element_language_details( $new_term[ 'term_taxonomy_id' ], 'tax_' . $attr, $tt_id, $language['code'] );
225
- }
226
- }
227
- }
228
-
229
- }
230
-
231
- echo 1;
232
-
233
- die();
234
- }
235
-
236
- function trbl_fix_product_type_terms(){
237
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
238
- if(!$nonce || !wp_verify_nonce($nonce, 'trbl_product_type_terms')){
239
- die('Invalid nonce');
240
- }
241
-
242
- WCML_Install::check_product_type_terms();
243
-
244
- echo 1;
245
-
246
- die();
247
- }
248
-
249
  }
1
+ <?php
2
+
3
+ class WCML_Troubleshooting{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'));
8
+
9
+ }
10
+
11
+ function init(){
12
+ add_action('wp_ajax_trbl_sync_variations', array($this,'trbl_sync_variations'));
13
+ add_action('wp_ajax_trbl_gallery_images', array($this,'trbl_gallery_images'));
14
+ add_action('wp_ajax_trbl_update_count', array($this,'trbl_update_count'));
15
+ add_action('wp_ajax_trbl_sync_categories', array($this,'trbl_sync_categories'));
16
+ add_action('wp_ajax_trbl_duplicate_terms', array($this,'trbl_duplicate_terms'));
17
+ add_action('wp_ajax_trbl_fix_product_type_terms', array($this,'trbl_fix_product_type_terms'));
18
+
19
+ }
20
+
21
+ function wcml_count_products_with_variations(){
22
+ return count(get_option('wcml_products_to_sync'));
23
+ }
24
+
25
+ function trbl_update_count(){
26
+
27
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
28
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_update_count')){
29
+ die('Invalid nonce');
30
+ }
31
+
32
+ $this->wcml_sync_variations_update_option();
33
+ echo $this->wcml_count_products_with_variations();
34
+
35
+ die();
36
+ }
37
+
38
+ function wcml_sync_variations_update_option(){
39
+ global $wpdb;
40
+ $get_variation_term_taxonomy_ids = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.name = 'variable'");
41
+ $get_variation_term_taxonomy_ids = apply_filters('wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids);
42
+
43
+ $get_variables_products = $wpdb->get_results($wpdb->prepare("SELECT tr.element_id as id,tr.language_code as lang FROM {$wpdb->prefix}icl_translations AS tr LEFT JOIN $wpdb->term_relationships as t ON tr.element_id = t.object_id LEFT JOIN $wpdb->posts AS p ON tr.element_id = p.ID
44
+ WHERE p.post_status = 'publish' AND tr.source_language_code is NULL AND tr.element_type = 'post_product' AND t.term_taxonomy_id IN (%s) ORDER BY tr.element_id",join(',',$get_variation_term_taxonomy_ids)),ARRAY_A);
45
+
46
+ update_option('wcml_products_to_sync',$get_variables_products);
47
+ }
48
+
49
+ function wcml_count_products(){
50
+ global $wpdb;
51
+ $get_products_count = $wpdb->get_var("SELECT count(ID) FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL");
52
+ return $get_products_count;
53
+ }
54
+
55
+ function wcml_count_products_for_gallery_sync(){
56
+ global $wpdb;
57
+ $all_products = $wpdb->get_results("SELECT p.ID FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL");
58
+ foreach($all_products as $key=>$product){
59
+ if(get_post_meta($product->ID,'gallery_sync',true)){
60
+ unset($all_products[$key]);
61
+ }
62
+ }
63
+ return count($all_products);
64
+ }
65
+
66
+ function wcml_count_product_categories(){
67
+ global $wpdb;
68
+ $get_product_categories = $wpdb->get_results("SELECT t.term_taxonomy_id FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL");
69
+ foreach($get_product_categories as $key=>$get_product_category){
70
+ if(get_option('wcml_sync_category_'.$get_product_category->term_taxonomy_id)){
71
+ unset($get_product_categories[$key]);
72
+ }
73
+ }
74
+ return count($get_product_categories);
75
+ }
76
+
77
+
78
+ function trbl_sync_variations(){
79
+
80
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
81
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_sync_variations')){
82
+ die('Invalid nonce');
83
+ }
84
+
85
+ global $woocommerce_wpml,$wpdb,$sitepress;
86
+
87
+ $get_variables_products = get_option('wcml_products_to_sync');
88
+ $all_active_lang = $sitepress->get_active_languages();
89
+ $unset_keys = array();
90
+ $products_for_one_ajax = array_slice($get_variables_products,0,3,true);
91
+
92
+
93
+ foreach ($products_for_one_ajax as $key => $product){
94
+ foreach($all_active_lang as $language){
95
+ if($language['code'] != $product['lang']){
96
+ $tr_product_id = apply_filters( 'translate_object_id',$product['id'],'product',false,$language['code']);
97
+
98
+ if(!is_null($tr_product_id)){
99
+ $woocommerce_wpml->sync_variations_data->sync_product_variations($product['id'],$tr_product_id,$language['code'],false,true);
100
+ }
101
+ if(!in_array($key,$unset_keys)){
102
+ $unset_keys[] = $key;
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+
109
+ foreach($unset_keys as $unset_key){
110
+ unset($get_variables_products[$unset_key]);
111
+ }
112
+
113
+ update_option('wcml_products_to_sync',$get_variables_products);
114
+
115
+ $wcml_settings = get_option('_wcml_settings');
116
+ if(isset($wcml_settings['notifications']) && isset($wcml_settings['notifications']['varimages'])){
117
+ $wcml_settings['notifications']['varimages']['show'] = 0;
118
+ update_option('_wcml_settings', $wcml_settings);
119
+ }
120
+
121
+ echo 1;
122
+
123
+ die();
124
+ }
125
+
126
+ function trbl_gallery_images(){
127
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
128
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_gallery_images')){
129
+ die('Invalid nonce');
130
+ }
131
+
132
+ $page = isset($_POST['page'])? intval( $_POST['page'] ) :0;
133
+
134
+ global $woocommerce_wpml,$wpdb;
135
+
136
+ $all_products = $wpdb->get_results($wpdb->prepare("SELECT p.* FROM $wpdb->posts AS p LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = p.ID WHERE p.post_status = 'publish' AND p.post_type = 'product' AND tr.source_language_code is NULL ORDER BY p.ID LIMIT %d,5",$page*5));
137
+
138
+ foreach($all_products as $product){
139
+ if(!get_post_meta($product->ID,'gallery_sync',true)){
140
+ $woocommerce_wpml->media->sync_product_gallery($product->ID);
141
+ add_post_meta($product->ID,'gallery_sync',true);
142
+ }
143
+ }
144
+
145
+ echo 1;
146
+
147
+ die();
148
+
149
+ }
150
+
151
+ function trbl_sync_categories(){
152
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
153
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_sync_categories')){
154
+ die('Invalid nonce');
155
+ }
156
+
157
+ $page = isset($_POST['page'])? intval( $_POST['page'] ):0;
158
+
159
+ global $wpdb,$sitepress;
160
+
161
+ $all_categories = $wpdb->get_results($wpdb->prepare("SELECT t.term_taxonomy_id,t.term_id,tr.language_code FROM $wpdb->term_taxonomy AS t LEFT JOIN {$wpdb->prefix}icl_translations AS tr ON tr.element_id = t.term_taxonomy_id WHERE t.taxonomy = 'product_cat' AND tr.element_type = 'tax_product_cat' AND tr.source_language_code is NULL ORDER BY t.term_taxonomy_id LIMIT %d,5",$page*5));
162
+
163
+ foreach($all_categories as $category){
164
+ if(!get_option('wcml_sync_category_'.$category->term_taxonomy_id)){
165
+ add_option('wcml_sync_category_'.$category->term_taxonomy_id,true);
166
+ $trid = $sitepress->get_element_trid($category->term_taxonomy_id,'tax_product_cat');
167
+ $translations = $sitepress->get_element_translations($trid,'tax_product_cat');
168
+ $type = get_woocommerce_term_meta( $category->term_id, 'display_type',true);
169
+ $thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id',true);
170
+ foreach($translations as $translation){
171
+ if($translation->language_code != $category->language_code ){
172
+ update_woocommerce_term_meta( $translation->term_id, 'display_type', $type );
173
+ update_woocommerce_term_meta( $translation->term_id, 'thumbnail_id', apply_filters( 'translate_object_id',$thumbnail_id,'attachment',true,$translation->language_code) );
174
+ }
175
+ }
176
+ }
177
+
178
+ }
179
+
180
+ echo 1;
181
+
182
+ die();
183
+
184
+ }
185
+
186
+
187
+ function trbl_duplicate_terms(){
188
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
189
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_duplicate_terms')){
190
+ die('Invalid nonce');
191
+ }
192
+ global $sitepress;
193
+
194
+ $attr = isset($_POST['attr'])?$_POST['attr']:false;
195
+
196
+ $terms = get_terms($attr,'hide_empty=0');
197
+ $i = 0;
198
+ $languages = $sitepress->get_active_languages();
199
+ foreach($terms as $term){
200
+ foreach($languages as $language){
201
+ $tr_id = apply_filters( 'translate_object_id',$term->term_id, $attr, false, $language['code']);
202
+
203
+ if(is_null($tr_id)){
204
+ $term_args = array();
205
+ // hierarchy - parents
206
+ if ( is_taxonomy_hierarchical( $attr ) ) {
207
+ // fix hierarchy
208
+ if ( $term->parent ) {
209
+ $original_parent_translated = apply_filters( 'translate_object_id', $term->parent, $attr, false, $language['code'] );
210
+ if ( $original_parent_translated ) {
211
+ $term_args[ 'parent' ] = $original_parent_translated;
212
+ }
213
+ }
214
+ }
215
+
216
+ $term_name = $term->name;
217
+ $slug = $term->name.'-'.$language['code'];
218
+ $slug = WPML_Terms_Translations::term_unique_slug( $slug, $attr, $language['code'] );
219
+ $term_args[ 'slug' ] = $slug;
220
+
221
+ $new_term = wp_insert_term( $term_name , $attr, $term_args );
222
+ if ( $new_term && !is_wp_error( $new_term ) ) {
223
+ $tt_id = $sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_' . $attr );
224
+ $sitepress->set_element_language_details( $new_term[ 'term_taxonomy_id' ], 'tax_' . $attr, $tt_id, $language['code'] );
225
+ }
226
+ }
227
+ }
228
+
229
+ }
230
+
231
+ echo 1;
232
+
233
+ die();
234
+ }
235
+
236
+ function trbl_fix_product_type_terms(){
237
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
238
+ if(!$nonce || !wp_verify_nonce($nonce, 'trbl_product_type_terms')){
239
+ die('Invalid nonce');
240
+ }
241
+
242
+ WCML_Install::check_product_type_terms();
243
+
244
+ echo 1;
245
+
246
+ die();
247
+ }
248
+
249
  }
inc/class-wcml-upgrade.php CHANGED
@@ -1,532 +1,532 @@
1
- <?php
2
-
3
- class WCML_Upgrade{
4
-
5
- private $versions = array(
6
-
7
- '2.9.9.1',
8
- '3.1',
9
- '3.2',
10
- '3.3',
11
- '3.5',
12
- '3.5.4',
13
- '3.6',
14
- '3.7',
15
- '3.7.3',
16
- '3.7.11',
17
- '3.8',
18
- '3.9',
19
- '3.9.1',
20
- '4.0'
21
- );
22
-
23
- function __construct(){
24
-
25
- add_action('init', array($this, 'run'));
26
- add_action('init', array($this, 'setup_upgrade_notices'));
27
- add_action('admin_notices', array($this, 'show_upgrade_notices'));
28
-
29
- add_action('wp_ajax_wcml_hide_notice', array($this, 'hide_upgrade_notice'));
30
-
31
- }
32
-
33
- function setup_upgrade_notices(){
34
-
35
- $wcml_settings = get_option('_wcml_settings');
36
- $version_in_db = get_option('_wcml_version');
37
-
38
- if(!empty($version_in_db) && version_compare($version_in_db, '2.9.9.1', '<')){
39
- $n = 'varimages';
40
- $wcml_settings['notifications'][$n] =
41
- array(
42
- 'show' => 1,
43
- 'text' => __('Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?', 'wcml').
44
- '<br /><strong>' .
45
- ' <a href="' . admin_url('admin.php?page=wpml-wcml&tab=troubleshooting') . '">' . __('Yes, go to the troubleshooting page', 'wcml') . '</a> |' .
46
- ' <a href="#" onclick="jQuery.ajax({type:\'POST\',url: ajaxurl,data:\'action=wcml_hide_notice&notice='.$n.'\',success:function(){jQuery(\'#' . $n . '\').fadeOut()}});return false;">' . __('No - dismiss', 'wcml') . '</a>' .
47
- '</strong>'
48
- );
49
- update_option('_wcml_settings', $wcml_settings);
50
- }
51
-
52
- }
53
-
54
- function show_upgrade_notices(){
55
- $wcml_settings = get_option('_wcml_settings');
56
- if(!empty($wcml_settings['notifications'])){
57
- foreach($wcml_settings['notifications'] as $k => $notification){
58
-
59
- // exceptions
60
- if(isset($_GET['tab']) && $_GET['tab'] == 'troubleshooting' && $k == 'varimages') continue;
61
-
62
- if($notification['show']){
63
- ?>
64
- <div id="<?php echo $k ?>" class="updated">
65
- <p><?php echo $notification['text'] ?></p>
66
- </div>
67
- <?php
68
- }
69
- }
70
- }
71
- }
72
-
73
- function hide_upgrade_notice($k){
74
-
75
- if(empty($k)){
76
- $k = $_POST['notice'];
77
- }
78
-
79
- $wcml_settings = get_option('_wcml_settings');
80
- if(isset($wcml_settings['notifications'][$k])){
81
- $wcml_settings['notifications'][$k]['show'] = 0;
82
- update_option('_wcml_settings', $wcml_settings);
83
- }
84
- }
85
-
86
- function run(){
87
-
88
- $version_in_db = get_option('_wcml_version');
89
-
90
- // exception - starting in 2.3.2
91
- if(empty($version_in_db) && get_option('icl_is_wcml_installed')){
92
- $version_in_db = '2.3.2';
93
- }
94
-
95
- $migration_ran = false;
96
-
97
- if($version_in_db && version_compare($version_in_db, WCML_VERSION, '<')){
98
-
99
- foreach($this->versions as $version){
100
-
101
- if(version_compare($version, WCML_VERSION, '<=') && version_compare($version, $version_in_db, '>')){
102
-
103
- $upgrade_method = 'upgrade_' . str_replace('.', '_', $version);
104
-
105
- if(method_exists($this, $upgrade_method)){
106
- $this->$upgrade_method();
107
- $migration_ran = true;
108
- }
109
-
110
- }
111
-
112
- }
113
-
114
- }
115
-
116
- if($migration_ran || empty($version_in_db)){
117
- update_option('_wcml_version', WCML_VERSION);
118
- }
119
- }
120
-
121
- function upgrade_2_9_9_1(){
122
- global $wpdb;
123
-
124
- //migrate exists currencies
125
- $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
126
- foreach($currencies as $currency){
127
- if(isset($currency->language_code)){
128
- $wpdb->insert($wpdb->prefix .'icl_languages_currencies', array(
129
- 'language_code' => $currency->language_code,
130
- 'currency_id' => $currency->id
131
- )
132
- );
133
- }
134
- }
135
-
136
- $cols = $wpdb->get_col("SHOW COLUMNS FROM {$wpdb->prefix}icl_currencies");
137
- if(in_array('language_code', $cols)){
138
- $wpdb->query("ALTER TABLE {$wpdb->prefix}icl_currencies DROP COLUMN language_code");
139
- }
140
-
141
- // migrate settings
142
- $new_settings = array(
143
- 'is_term_order_synced' => get_option('icl_is_wcml_term_order_synched'),
144
- 'file_path_sync' => get_option('wcml_file_path_sync'),
145
- 'is_installed' => get_option('icl_is_wpcml_installed'),
146
- 'dismiss_doc_main' => get_option('wpml_dismiss_doc_main'),
147
- 'enable_multi_currency' => get_option('icl_enable_multi_currency'),
148
- 'currency_converting_option' => get_option('currency_converting_option')
149
- );
150
-
151
- if(!get_option('_wcml_settings')){
152
- add_option('_wcml_settings', $new_settings, false, true);
153
- }
154
-
155
- delete_option('icl_is_wcml_term_order_synced');
156
- delete_option('wcml_file_path_sync');
157
- delete_option('icl_is_wpcml_installed');
158
- delete_option('wpml_dismiss_doc_main');
159
- delete_option('icl_enable_multi_currency');
160
- delete_option('currency_converting_option');
161
-
162
-
163
- }
164
-
165
- function upgrade_3_1(){
166
- global $wpdb,$sitepress;
167
- $wcml_settings = get_option('_wcml_settings');
168
-
169
- if(isset($wcml_settings['enable_multi_currency']) && $wcml_settings['enable_multi_currency'] == 'yes'){
170
- $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_INDEPENDENT;
171
- }else{
172
- $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_DISABLED;
173
- }
174
-
175
- $wcml_settings['products_sync_date'] = 1;
176
-
177
-
178
- update_option('_wcml_settings', $wcml_settings);
179
-
180
- // multi-currency migration
181
- if($wcml_settings['enable_multi_currency'] == 'yes' && $wcml_settings['currency_converting_option'] == 2){
182
-
183
- // get currencies exchange rates
184
- $results = $wpdb->get_results("SELECT code, value FROM {$wpdb->prefix}icl_currencies");
185
- foreach($results as $row){
186
- $exchange_rates[$row->code] = $row->value;
187
- }
188
-
189
- // get languages currencies map
190
- $results = $wpdb->get_results("SELECT l.language_code, c.code FROM {$wpdb->prefix}icl_languages_currencies l JOIN {$wpdb->prefix}icl_currencies c ON l.currency_id = c.id");
191
- foreach($results as $row){
192
- $language_currencies[$row->language_code] = $row->code;
193
- }
194
-
195
-
196
- $results = $wpdb->get_results($wpdb->prepare("
197
- SELECT p.ID, t.trid, t.element_type
198
- FROM {$wpdb->posts} p JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
199
- WHERE
200
- p.post_type in ('product', 'product_variation') AND t.language_code = %s
201
-
202
- ", $sitepress->get_default_language()));
203
-
204
- // set custom conversion rates
205
- foreach($results as $row){
206
- $translations = $sitepress->get_element_translations($row->trid, $row->element_type);
207
- $meta = get_post_meta($row->ID);
208
- $original_prices['_price'] = !empty($meta['_price']) ? $meta['_price'][0] : 0;
209
- $original_prices['_regular_price'] = !empty($meta['_regular_price']) ? $meta['_regular_price'][0] : 0;
210
- $original_prices['_sale_price'] = !empty($meta['_sale_price']) ? $meta['_sale_price'][0] : 0;
211
-
212
-
213
- $ccr = array();
214
-
215
- foreach($translations as $translation){
216
- if($translation->element_id != $row->ID){
217
-
218
- $meta = get_post_meta($translation->element_id);
219
- $translated_prices['_price'] = $meta['_price'][0];
220
- $translated_prices['_regular_price'] = $meta['_regular_price'][0];
221
- $translated_prices['_sale_price'] = $meta['_sale_price'][0];
222
-
223
- if(!empty($translated_prices['_price']) && !empty($original_prices['_price']) && $translated_prices['_price'] != $original_prices['_price']){
224
-
225
- $ccr['_price'][$language_currencies[$translation->language_code]] = $translated_prices['_price'] / $original_prices['_price'];
226
-
227
- }
228
- if(!empty($translated_prices['_regular_price']) && !empty($original_prices['_regular_price']) && $translated_prices['_regular_price'] != $original_prices['_regular_price']){
229
-
230
- $ccr['_regular_price'][$language_currencies[$translation->language_code]] = $translated_prices['_regular_price'] / $original_prices['_regular_price'];
231
-
232
- }
233
- if(!empty($translated_prices['_sale_price']) && !empty($original_prices['_sale_price']) && $translated_prices['_sale_price'] != $original_prices['_sale_price']){
234
-
235
- $ccr['_sale_price'][$language_currencies[$translation->language_code]] = $translated_prices['_sale_price'] / $original_prices['_sale_price'] ;
236
-
237
- }
238
-
239
-
240
- }
241
- }
242
-
243
- if($ccr){
244
- update_post_meta($row->ID, '_custom_conversion_rate', $ccr);
245
- }
246
-
247
-
248
- }
249
-
250
-
251
- }
252
-
253
- }
254
-
255
- function upgrade_3_2(){
256
-
257
- WCML_Capabilities::set_up_capabilities();
258
-
259
- //delete not existing currencies in WC
260
- global $wpdb;
261
- $currencies = $wpdb->get_results("SELECT id,code FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
262
- $wc_currencies = get_woocommerce_currencies();
263
- foreach ($currencies as $currency){
264
- if(!array_key_exists($currency->code,$wc_currencies)){
265
- $wpdb->delete( $wpdb->prefix . 'icl_currencies', array( 'ID' => $currency->id ) );
266
- }
267
- }
268
-
269
- }
270
-
271
- function upgrade_3_3(){
272
- global $wpdb, $woocommerce_wpml;
273
-
274
- WCML_Capabilities::set_up_capabilities();
275
-
276
- $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` ASC", OBJECT);
277
- if($currencies)
278
- foreach($this->currencies as $currency){
279
-
280
- $woocommerce_wpml->settings['currency_options'][$currency->code]['rate'] = $currency->value;
281
- $woocommerce_wpml->settings['currency_options'][$currency->code]['updated'] = $currency->changed;
282
- $woocommerce_wpml->settings['currency_options'][$currency->code]['position'] = 'left';
283
- $woocommerce_wpml->settings['currency_options'][$currency->code]['languages'] = $woocommerce_wpml->settings['currencies_languages'];
284
- unset($woocommerce_wpml->settings['currencies_languages']);
285
-
286
- $woocommerce_wpml->update_settings();
287
-
288
- }
289
-
290
- $wpdb->query("DROP TABLE `{$wpdb->prefix}icl_currencies`");
291
-
292
- }
293
-
294
- function upgrade_3_5()
295
- {
296
- global $wpdb;
297
- $wcml_settings = get_option('_wcml_settings');
298
-
299
- $wcml_settings['products_sync_order'] = 1;
300
-
301
- update_option('_wcml_settings', $wcml_settings);
302
- }
303
-
304
- function upgrade_3_5_4()
305
- {
306
- flush_rewrite_rules( );
307
- }
308
-
309
- function upgrade_3_6()
310
- {
311
- $wcml_settings = get_option('_wcml_settings');
312
-
313
- $wcml_settings['display_custom_prices'] = 0;
314
- $wcml_settings['currency_switcher_product_visibility'] = 1;
315
-
316
- update_option('_wcml_settings', $wcml_settings);
317
- }
318
-
319
- function upgrade_3_7(){
320
- global $woocommerce_wpml,$wpdb;
321
-
322
- $woocommerce_permalinks = maybe_unserialize( get_option('woocommerce_permalinks') );
323
-
324
- if( is_array( $woocommerce_permalinks ) ) {
325
- foreach ( $woocommerce_permalinks as $base_key => $base ) {
326
-
327
- $base_key = trim( $base_key, '/' );
328
-
329
- if ( $base ) {
330
- $taxonomy = false;
331
-
332
- switch ( $base_key ) {
333
- case 'category_base':
334
- $taxonomy = 'product_cat';
335
- break;
336
- case 'tag_base':
337
- $taxonomy = 'product_tag';
338
- break;
339
- case 'attribute_base':
340
- $taxonomy = 'attribute';
341
- break;
342
- }
343
-
344
- if ( $taxonomy ) {
345
- $wpdb->update(
346
- $wpdb->prefix . 'icl_strings',
347
- array(
348
- 'context' => 'WordPress',
349
- 'name' => sprintf( 'URL %s tax slug', $taxonomy )
350
- ),
351
- array(
352
- 'context' => sprintf( 'URL %s slugs - %s', $taxonomy, $base ),
353
- 'name' => sprintf( 'Url %s slug: %s', $taxonomy, $base )
354
- )
355
- );
356
-
357
- }
358
- }
359
-
360
- }
361
- }
362
-
363
- $endpoint_keys = array( 'order-pay', 'order-received', 'view-order', 'edit-account', 'edit-address', 'lost-password', 'customer-logout', 'add-payment-method' );
364
-
365
- foreach( $endpoint_keys as $endpoint_key ){
366
-
367
- $wpdb->query(
368
- $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
369
- SET context = 'WooCommerce Endpoints', name = %s
370
- WHERE context = 'WordPress' AND name = %s",
371
- $endpoint_key, 'Endpoint slug: '. $endpoint_key )
372
- );
373
-
374
- // update domain_name_context_md5 value
375
- $string_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = 'WooCommerce Endpoints' AND name = %s", $endpoint_key ) );
376
-
377
- if( $string_id ){
378
- $wpdb->query(
379
- $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
380
- SET domain_name_context_md5 = %s
381
- WHERE id = %d",
382
- md5( $endpoint_key,'WooCommerce Endpoints' ), $string_id )
383
- );
384
- }
385
-
386
- }
387
-
388
- if( !isset($woocommerce_wpml->terms) ){
389
- global $sitepress;
390
- $woocommerce_wpml->terms = new WCML_Terms( $woocommerce_wpml, $sitepress, $wpdb );
391
- }
392
- $woocommerce_wpml->terms->check_if_sync_terms_needed();
393
-
394
- $wcml_settings = get_option('_wcml_settings');
395
-
396
- $wcml_settings['sync_taxonomies_checked'] = 1;
397
-
398
- update_option('_wcml_settings', $wcml_settings);
399
-
400
-
401
- //update custom fields for bookings
402
- $bookable_resources = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_resource' AND source_language_code IS NOT NULL");
403
-
404
- foreach( $bookable_resources AS $bookable_resource ){
405
- update_post_meta( $bookable_resource->element_id, 'wcml_is_translated', true );
406
- }
407
-
408
- $bookable_persons = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_person' AND source_language_code IS NOT NULL");
409
-
410
- foreach( $bookable_persons AS $bookable_person ){
411
- update_post_meta( $bookable_person->element_id, 'wcml_is_translated', true );
412
- }
413
-
414
- }
415
-
416
- function upgrade_3_7_3()
417
- {
418
- global $sitepress;
419
-
420
- $active_languages = $sitepress->get_active_languages();
421
- $current_language = $sitepress->get_current_language();
422
-
423
- foreach( $active_languages as $lang ){
424
-
425
- $sitepress->switch_lang( $lang['code'] );
426
-
427
- $product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
428
-
429
- _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
430
-
431
- $product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
432
-
433
- _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
434
-
435
- }
436
-
437
- $sitepress->switch_lang( $current_language );
438
-
439
- }
440
-
441
- function upgrade_3_7_11(){
442
-
443
- $wcml_settings = get_option('_wcml_settings');
444
- $wcml_settings['dismiss_doc_main'] = 1;
445
- update_option('_wcml_settings', $wcml_settings);
446
- }
447
-
448
- function upgrade_3_8(){
449
-
450
- $wcml_settings = get_option('_wcml_settings');
451
- $wcml_settings['set_up_wizard_run'] = 1;
452
-
453
- if( isset($wcml_settings[ 'attributes_settings' ]) ) {
454
- $attributes_settings = $wcml_settings['attributes_settings'];
455
- foreach ( $attributes_settings as $name => $value ) {
456
- if ( substr( $name, 0, 3 ) != 'pa_' ) {
457
- unset( $wcml_settings['attributes_settings'] [$name] );
458
- $wcml_settings['attributes_settings'] ['pa_' . $name] = $value;
459
- }
460
- }
461
- }
462
-
463
- update_option('_wcml_settings', $wcml_settings);
464
-
465
- }
466
-
467
- function upgrade_3_9(){
468
- global $wpdb;
469
-
470
- $meta_keys_to_fix = array(
471
- '_price',
472
- '_regular_price',
473
- '_sale_price',
474
- '_sku'
475
- );
476
-
477
- $sql = "
478
- UPDATE {$wpdb->postmeta}
479
- SET meta_value = ''
480
- WHERE meta_key IN('" . join("','", $meta_keys_to_fix) . "')
481
- AND meta_value IS NULL";
482
-
483
- $wpdb->query( $sql );
484
-
485
- }
486
-
487
- function upgrade_3_9_1(){
488
- global $wpdb, $sitepress;
489
-
490
- $results = $wpdb->get_results("
491
- SELECT p.ID, t.trid, t.element_type
492
- FROM {$wpdb->posts} p
493
- JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
494
- WHERE p.post_type in ('product', 'product_variation') AND t.source_language_code IS NULL
495
- ");
496
-
497
- foreach( $results as $product ){
498
-
499
- if( get_post_meta( $product->ID, '_manage_stock', true ) === 'yes' ){
500
-
501
- $translations = $sitepress->get_element_translations( $product->trid, $product->element_type );
502
-
503
- $min_stock = false;
504
-
505
- //collect min stock
506
- foreach( $translations as $translation ){
507
- $stock = get_post_meta( $translation->element_id, '_stock', true );
508
- if( !$min_stock || $stock < $min_stock ){
509
- $min_stock = $stock;
510
- }
511
- }
512
-
513
- //update stock value
514
- foreach( $translations as $translation ){
515
- update_post_meta( $translation->element_id, '_stock', $min_stock );
516
- }
517
- }
518
- }
519
- }
520
-
521
- function upgrade_4_0(){
522
- $wcml_settings = get_option( '_wcml_settings' );
523
- $wcml_settings[ 'dismiss_tm_warning' ] = 0;
524
- $wcml_settings['cart_sync']['lang_switch'] = WCML_CART_SYNC;
525
- $wcml_settings['cart_sync']['currency_switch'] = WCML_CART_SYNC;
526
-
527
- update_option('_wcml_settings', $wcml_settings);
528
-
529
- }
530
-
531
-
532
  }
1
+ <?php
2
+
3
+ class WCML_Upgrade{
4
+
5
+ private $versions = array(
6
+
7
+ '2.9.9.1',
8
+ '3.1',
9
+ '3.2',
10
+ '3.3',
11
+ '3.5',
12
+ '3.5.4',
13
+ '3.6',
14
+ '3.7',
15
+ '3.7.3',
16
+ '3.7.11',
17
+ '3.8',
18
+ '3.9',
19
+ '3.9.1',
20
+ '4.0'
21
+ );
22
+
23
+ function __construct(){
24
+
25
+ add_action('init', array($this, 'run'));
26
+ add_action('init', array($this, 'setup_upgrade_notices'));
27
+ add_action('admin_notices', array($this, 'show_upgrade_notices'));
28
+
29
+ add_action('wp_ajax_wcml_hide_notice', array($this, 'hide_upgrade_notice'));
30
+
31
+ }
32
+
33
+ function setup_upgrade_notices(){
34
+
35
+ $wcml_settings = get_option('_wcml_settings');
36
+ $version_in_db = get_option('_wcml_version');
37
+
38
+ if(!empty($version_in_db) && version_compare($version_in_db, '2.9.9.1', '<')){
39
+ $n = 'varimages';
40
+ $wcml_settings['notifications'][$n] =
41
+ array(
42
+ 'show' => 1,
43
+ 'text' => __('Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?', 'wcml').
44
+ '<br /><strong>' .
45
+ ' <a href="' . admin_url('admin.php?page=wpml-wcml&tab=troubleshooting') . '">' . __('Yes, go to the troubleshooting page', 'wcml') . '</a> |' .
46
+ ' <a href="#" onclick="jQuery.ajax({type:\'POST\',url: ajaxurl,data:\'action=wcml_hide_notice&notice='.$n.'\',success:function(){jQuery(\'#' . $n . '\').fadeOut()}});return false;">' . __('No - dismiss', 'wcml') . '</a>' .
47
+ '</strong>'
48
+ );
49
+ update_option('_wcml_settings', $wcml_settings);
50
+ }
51
+
52
+ }
53
+
54
+ function show_upgrade_notices(){
55
+ $wcml_settings = get_option('_wcml_settings');
56
+ if(!empty($wcml_settings['notifications'])){
57
+ foreach($wcml_settings['notifications'] as $k => $notification){
58
+
59
+ // exceptions
60
+ if(isset($_GET['tab']) && $_GET['tab'] == 'troubleshooting' && $k == 'varimages') continue;
61
+
62
+ if($notification['show']){
63
+ ?>
64
+ <div id="<?php echo $k ?>" class="updated">
65
+ <p><?php echo $notification['text'] ?></p>
66
+ </div>
67
+ <?php
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ function hide_upgrade_notice($k){
74
+
75
+ if(empty($k)){
76
+ $k = $_POST['notice'];
77
+ }
78
+
79
+ $wcml_settings = get_option('_wcml_settings');
80
+ if(isset($wcml_settings['notifications'][$k])){
81
+ $wcml_settings['notifications'][$k]['show'] = 0;
82
+ update_option('_wcml_settings', $wcml_settings);
83
+ }
84
+ }
85
+
86
+ function run(){
87
+
88
+ $version_in_db = get_option('_wcml_version');
89
+
90
+ // exception - starting in 2.3.2
91
+ if(empty($version_in_db) && get_option('icl_is_wcml_installed')){
92
+ $version_in_db = '2.3.2';
93
+ }
94
+
95
+ $migration_ran = false;
96
+
97
+ if($version_in_db && version_compare($version_in_db, WCML_VERSION, '<')){
98
+
99
+ foreach($this->versions as $version){
100
+
101
+ if(version_compare($version, WCML_VERSION, '<=') && version_compare($version, $version_in_db, '>')){
102
+
103
+ $upgrade_method = 'upgrade_' . str_replace('.', '_', $version);
104
+
105
+ if(method_exists($this, $upgrade_method)){
106
+ $this->$upgrade_method();
107
+ $migration_ran = true;
108
+ }
109
+
110
+ }
111
+
112
+ }
113
+
114
+ }
115
+
116
+ if($migration_ran || empty($version_in_db)){
117
+ update_option('_wcml_version', WCML_VERSION);
118
+ }
119
+ }
120
+
121
+ function upgrade_2_9_9_1(){
122
+ global $wpdb;
123
+
124
+ //migrate exists currencies
125
+ $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
126
+ foreach($currencies as $currency){
127
+ if(isset($currency->language_code)){
128
+ $wpdb->insert($wpdb->prefix .'icl_languages_currencies', array(
129
+ 'language_code' => $currency->language_code,
130
+ 'currency_id' => $currency->id
131
+ )
132
+ );
133
+ }
134
+ }
135
+
136
+ $cols = $wpdb->get_col("SHOW COLUMNS FROM {$wpdb->prefix}icl_currencies");
137
+ if(in_array('language_code', $cols)){
138
+ $wpdb->query("ALTER TABLE {$wpdb->prefix}icl_currencies DROP COLUMN language_code");
139
+ }
140
+
141
+ // migrate settings
142
+ $new_settings = array(
143
+ 'is_term_order_synced' => get_option('icl_is_wcml_term_order_synched'),
144
+ 'file_path_sync' => get_option('wcml_file_path_sync'),
145
+ 'is_installed' => get_option('icl_is_wpcml_installed'),
146
+ 'dismiss_doc_main' => get_option('wpml_dismiss_doc_main'),
147
+ 'enable_multi_currency' => get_option('icl_enable_multi_currency'),
148
+ 'currency_converting_option' => get_option('currency_converting_option')
149
+ );
150
+
151
+ if(!get_option('_wcml_settings')){
152
+ add_option('_wcml_settings', $new_settings, false, true);
153
+ }
154
+
155
+ delete_option('icl_is_wcml_term_order_synced');
156
+ delete_option('wcml_file_path_sync');
157
+ delete_option('icl_is_wpcml_installed');
158
+ delete_option('wpml_dismiss_doc_main');
159
+ delete_option('icl_enable_multi_currency');
160
+ delete_option('currency_converting_option');
161
+
162
+
163
+ }
164
+
165
+ function upgrade_3_1(){
166
+ global $wpdb,$sitepress;
167
+ $wcml_settings = get_option('_wcml_settings');
168
+
169
+ if(isset($wcml_settings['enable_multi_currency']) && $wcml_settings['enable_multi_currency'] == 'yes'){
170
+ $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_INDEPENDENT;
171
+ }else{
172
+ $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_DISABLED;
173
+ }
174
+
175
+ $wcml_settings['products_sync_date'] = 1;
176
+
177
+
178
+ update_option('_wcml_settings', $wcml_settings);
179
+
180
+ // multi-currency migration
181
+ if($wcml_settings['enable_multi_currency'] == 'yes' && $wcml_settings['currency_converting_option'] == 2){
182
+
183
+ // get currencies exchange rates
184
+ $results = $wpdb->get_results("SELECT code, value FROM {$wpdb->prefix}icl_currencies");
185
+ foreach($results as $row){
186
+ $exchange_rates[$row->code] = $row->value;
187
+ }
188
+
189
+ // get languages currencies map
190
+ $results = $wpdb->get_results("SELECT l.language_code, c.code FROM {$wpdb->prefix}icl_languages_currencies l JOIN {$wpdb->prefix}icl_currencies c ON l.currency_id = c.id");
191
+ foreach($results as $row){
192
+ $language_currencies[$row->language_code] = $row->code;
193
+ }
194
+
195
+
196
+ $results = $wpdb->get_results($wpdb->prepare("
197
+ SELECT p.ID, t.trid, t.element_type
198
+ FROM {$wpdb->posts} p JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
199
+ WHERE
200
+ p.post_type in ('product', 'product_variation') AND t.language_code = %s
201
+
202
+ ", $sitepress->get_default_language()));
203
+
204
+ // set custom conversion rates
205
+ foreach($results as $row){
206
+ $translations = $sitepress->get_element_translations($row->trid, $row->element_type);
207
+ $meta = get_post_meta($row->ID);
208
+ $original_prices['_price'] = !empty($meta['_price']) ? $meta['_price'][0] : 0;
209
+ $original_prices['_regular_price'] = !empty($meta['_regular_price']) ? $meta['_regular_price'][0] : 0;
210
+ $original_prices['_sale_price'] = !empty($meta['_sale_price']) ? $meta['_sale_price'][0] : 0;
211
+
212
+
213
+ $ccr = array();
214
+
215
+ foreach($translations as $translation){
216
+ if($translation->element_id != $row->ID){
217
+
218
+ $meta = get_post_meta($translation->element_id);
219
+ $translated_prices['_price'] = $meta['_price'][0];
220
+ $translated_prices['_regular_price'] = $meta['_regular_price'][0];
221
+ $translated_prices['_sale_price'] = $meta['_sale_price'][0];
222
+
223
+ if(!empty($translated_prices['_price']) && !empty($original_prices['_price']) && $translated_prices['_price'] != $original_prices['_price']){
224
+
225
+ $ccr['_price'][$language_currencies[$translation->language_code]] = $translated_prices['_price'] / $original_prices['_price'];
226
+
227
+ }
228
+ if(!empty($translated_prices['_regular_price']) && !empty($original_prices['_regular_price']) && $translated_prices['_regular_price'] != $original_prices['_regular_price']){
229
+
230
+ $ccr['_regular_price'][$language_currencies[$translation->language_code]] = $translated_prices['_regular_price'] / $original_prices['_regular_price'];
231
+
232
+ }
233
+ if(!empty($translated_prices['_sale_price']) && !empty($original_prices['_sale_price']) && $translated_prices['_sale_price'] != $original_prices['_sale_price']){
234
+
235
+ $ccr['_sale_price'][$language_currencies[$translation->language_code]] = $translated_prices['_sale_price'] / $original_prices['_sale_price'] ;
236
+
237
+ }
238
+
239
+
240
+ }
241
+ }
242
+
243
+ if($ccr){
244
+ update_post_meta($row->ID, '_custom_conversion_rate', $ccr);
245
+ }
246
+
247
+
248
+ }
249
+
250
+
251
+ }
252
+
253
+ }
254
+
255
+ function upgrade_3_2(){
256
+
257
+ WCML_Capabilities::set_up_capabilities();
258
+
259
+ //delete not existing currencies in WC
260
+ global $wpdb;
261
+ $currencies = $wpdb->get_results("SELECT id,code FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
262
+ $wc_currencies = get_woocommerce_currencies();
263
+ foreach ($currencies as $currency){
264
+ if(!array_key_exists($currency->code,$wc_currencies)){
265
+ $wpdb->delete( $wpdb->prefix . 'icl_currencies', array( 'ID' => $currency->id ) );
266
+ }
267
+ }
268
+
269
+ }
270
+
271
+ function upgrade_3_3(){
272
+ global $wpdb, $woocommerce_wpml;
273
+
274
+ WCML_Capabilities::set_up_capabilities();
275
+
276
+ $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` ASC", OBJECT);
277
+ if($currencies)
278
+ foreach($this->currencies as $currency){
279
+
280
+ $woocommerce_wpml->settings['currency_options'][$currency->code]['rate'] = $currency->value;
281
+ $woocommerce_wpml->settings['currency_options'][$currency->code]['updated'] = $currency->changed;
282
+ $woocommerce_wpml->settings['currency_options'][$currency->code]['position'] = 'left';
283
+ $woocommerce_wpml->settings['currency_options'][$currency->code]['languages'] = $woocommerce_wpml->settings['currencies_languages'];
284
+ unset($woocommerce_wpml->settings['currencies_languages']);
285
+
286
+ $woocommerce_wpml->update_settings();
287
+
288
+ }
289
+
290
+ $wpdb->query("DROP TABLE `{$wpdb->prefix}icl_currencies`");
291
+
292
+ }
293
+
294
+ function upgrade_3_5()
295
+ {
296
+ global $wpdb;
297
+ $wcml_settings = get_option('_wcml_settings');
298
+
299
+ $wcml_settings['products_sync_order'] = 1;
300
+
301
+ update_option('_wcml_settings', $wcml_settings);
302
+ }
303
+
304
+ function upgrade_3_5_4()
305
+ {
306
+ flush_rewrite_rules( );
307
+ }
308
+
309
+ function upgrade_3_6()
310
+ {
311
+ $wcml_settings = get_option('_wcml_settings');
312
+
313
+ $wcml_settings['display_custom_prices'] = 0;
314
+ $wcml_settings['currency_switcher_product_visibility'] = 1;
315
+
316
+ update_option('_wcml_settings', $wcml_settings);
317
+ }
318
+
319
+ function upgrade_3_7(){
320
+ global $woocommerce_wpml,$wpdb;
321
+
322
+ $woocommerce_permalinks = maybe_unserialize( get_option('woocommerce_permalinks') );
323
+
324
+ if( is_array( $woocommerce_permalinks ) ) {
325
+ foreach ( $woocommerce_permalinks as $base_key => $base ) {
326
+
327
+ $base_key = trim( $base_key, '/' );
328
+
329
+ if ( $base ) {
330
+ $taxonomy = false;
331
+
332
+ switch ( $base_key ) {
333
+ case 'category_base':
334
+ $taxonomy = 'product_cat';
335
+ break;
336
+ case 'tag_base':
337
+ $taxonomy = 'product_tag';
338
+ break;
339
+ case 'attribute_base':
340
+ $taxonomy = 'attribute';
341
+ break;
342
+ }
343
+
344
+ if ( $taxonomy ) {
345
+ $wpdb->update(
346
+ $wpdb->prefix . 'icl_strings',
347
+ array(
348
+ 'context' => 'WordPress',
349
+ 'name' => sprintf( 'URL %s tax slug', $taxonomy )
350
+ ),
351
+ array(
352
+ 'context' => sprintf( 'URL %s slugs - %s', $taxonomy, $base ),
353
+ 'name' => sprintf( 'Url %s slug: %s', $taxonomy, $base )
354
+ )
355
+ );
356
+
357
+ }
358
+ }
359
+
360
+ }
361
+ }
362
+
363
+ $endpoint_keys = array( 'order-pay', 'order-received', 'view-order', 'edit-account', 'edit-address', 'lost-password', 'customer-logout', 'add-payment-method' );
364
+
365
+ foreach( $endpoint_keys as $endpoint_key ){
366
+
367
+ $wpdb->query(
368
+ $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
369
+ SET context = 'WooCommerce Endpoints', name = %s
370
+ WHERE context = 'WordPress' AND name = %s",
371
+ $endpoint_key, 'Endpoint slug: '. $endpoint_key )
372
+ );
373
+
374
+ // update domain_name_context_md5 value
375
+ $string_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = 'WooCommerce Endpoints' AND name = %s", $endpoint_key ) );
376
+
377
+ if( $string_id ){
378
+ $wpdb->query(
379
+ $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
380
+ SET domain_name_context_md5 = %s
381
+ WHERE id = %d",
382
+ md5( $endpoint_key,'WooCommerce Endpoints' ), $string_id )
383
+ );
384
+ }
385
+
386
+ }
387
+
388
+ if( !isset($woocommerce_wpml->terms) ){
389
+ global $sitepress;
390
+ $woocommerce_wpml->terms = new WCML_Terms( $woocommerce_wpml, $sitepress, $wpdb );
391
+ }
392
+ $woocommerce_wpml->terms->check_if_sync_terms_needed();
393
+
394
+ $wcml_settings = get_option('_wcml_settings');
395
+
396
+ $wcml_settings['sync_taxonomies_checked'] = 1;
397
+
398
+ update_option('_wcml_settings', $wcml_settings);
399
+
400
+
401
+ //update custom fields for bookings
402
+ $bookable_resources = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_resource' AND source_language_code IS NOT NULL");
403
+
404
+ foreach( $bookable_resources AS $bookable_resource ){
405
+ update_post_meta( $bookable_resource->element_id, 'wcml_is_translated', true );
406
+ }
407
+
408
+ $bookable_persons = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_person' AND source_language_code IS NOT NULL");
409
+
410
+ foreach( $bookable_persons AS $bookable_person ){
411
+ update_post_meta( $bookable_person->element_id, 'wcml_is_translated', true );
412
+ }
413
+
414
+ }
415
+
416
+ function upgrade_3_7_3()
417
+ {
418
+ global $sitepress;
419
+
420
+ $active_languages = $sitepress->get_active_languages();
421
+ $current_language = $sitepress->get_current_language();
422
+
423
+ foreach( $active_languages as $lang ){
424
+
425
+ $sitepress->switch_lang( $lang['code'] );
426
+
427
+ $product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
428
+
429
+ _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
430
+
431
+ $product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
432
+
433
+ _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
434
+
435
+ }
436
+
437
+ $sitepress->switch_lang( $current_language );
438
+
439
+ }
440
+
441
+ function upgrade_3_7_11(){
442
+
443
+ $wcml_settings = get_option('_wcml_settings');
444
+ $wcml_settings['dismiss_doc_main'] = 1;
445
+ update_option('_wcml_settings', $wcml_settings);
446
+ }
447
+
448
+ function upgrade_3_8(){
449
+
450
+ $wcml_settings = get_option('_wcml_settings');
451
+ $wcml_settings['set_up_wizard_run'] = 1;
452
+
453
+ if( isset($wcml_settings[ 'attributes_settings' ]) ) {
454
+ $attributes_settings = $wcml_settings['attributes_settings'];
455
+ foreach ( $attributes_settings as $name => $value ) {
456
+ if ( substr( $name, 0, 3 ) != 'pa_' ) {
457
+ unset( $wcml_settings['attributes_settings'] [$name] );
458
+ $wcml_settings['attributes_settings'] ['pa_' . $name] = $value;
459
+ }
460
+ }
461
+ }
462
+
463
+ update_option('_wcml_settings', $wcml_settings);
464
+
465
+ }
466
+
467
+ function upgrade_3_9(){
468
+ global $wpdb;
469
+
470
+ $meta_keys_to_fix = array(
471
+ '_price',
472
+ '_regular_price',
473
+ '_sale_price',
474
+ '_sku'
475
+ );
476
+
477
+ $sql = "
478
+ UPDATE {$wpdb->postmeta}
479
+ SET meta_value = ''
480
+ WHERE meta_key IN('" . join("','", $meta_keys_to_fix) . "')
481
+ AND meta_value IS NULL";
482
+
483
+ $wpdb->query( $sql );
484
+
485
+ }
486
+
487
+ function upgrade_3_9_1(){
488
+ global $wpdb, $sitepress;
489
+
490
+ $results = $wpdb->get_results("
491
+ SELECT p.ID, t.trid, t.element_type
492
+ FROM {$wpdb->posts} p
493
+ JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
494
+ WHERE p.post_type in ('product', 'product_variation') AND t.source_language_code IS NULL
495
+ ");
496
+
497
+ foreach( $results as $product ){
498
+
499
+ if( get_post_meta( $product->ID, '_manage_stock', true ) === 'yes' ){
500
+
501
+ $translations = $sitepress->get_element_translations( $product->trid, $product->element_type );
502
+
503
+ $min_stock = false;
504
+
505
+ //collect min stock
506
+ foreach( $translations as $translation ){
507
+ $stock = get_post_meta( $translation->element_id, '_stock', true );
508
+ if( !$min_stock || $stock < $min_stock ){
509
+ $min_stock = $stock;
510
+ }
511
+ }
512
+
513
+ //update stock value
514
+ foreach( $translations as $translation ){
515
+ update_post_meta( $translation->element_id, '_stock', $min_stock );
516
+ }
517
+ }
518
+ }
519
+ }
520
+
521
+ function upgrade_4_0(){
522
+ $wcml_settings = get_option( '_wcml_settings' );
523
+ $wcml_settings[ 'dismiss_tm_warning' ] = 0;
524
+ $wcml_settings['cart_sync']['lang_switch'] = WCML_CART_SYNC;
525
+ $wcml_settings['cart_sync']['currency_switch'] = WCML_CART_SYNC;
526
+
527
+ update_option('_wcml_settings', $wcml_settings);
528
+
529
+ }
530
+
531
+
532
  }
inc/class-wcml-url-translation.php CHANGED
@@ -1,822 +1,822 @@
1
- <?php
2
-
3
- class WCML_Url_Translation {
4
-
5
- public $default_product_base;
6
- public $default_product_category_base;
7
- public $default_product_category_gettext_base;
8
- public $default_product_tag_base;
9
- public $default_product_tag_gettext_base;
10
-
11
- function __construct() {
12
-
13
- $this->default_product_base = 'product';
14
- $this->default_product_category_base = 'product-category';
15
- $this->default_product_tag_base = 'product-tag';
16
- $this->default_product_category_gettext_base = _x( 'product-category', 'slug', 'woocommerce' );
17
- $this->default_product_tag_gettext_base = _x( 'product-tag', 'slug', 'woocommerce' );
18
-
19
- $this->wc_permalinks = get_option( 'woocommerce_permalinks' );
20
-
21
- $this->set_up(); //initialization
22
-
23
- add_filter( 'pre_update_option_woocommerce_permalinks', array( $this, 'register_product_and_taxonomy_bases' ), 10, 2 );
24
-
25
- add_filter( 'pre_update_option_rewrite_rules', array( $this, 'force_bases_in_strings_languages' ), 1, 1 ); // high priority
26
-
27
- add_filter( 'option_rewrite_rules', array( $this, 'translate_bases_in_rewrite_rules' ), 0, 1 ); // high priority
28
-
29
- add_filter( 'term_link', array( $this, 'translate_taxonomy_base' ), 0, 3 ); // high priority
30
-
31
- add_action( 'init', array( $this, 'fix_post_object_rewrite_slug' ), 6 ); // handle the particular case of the default product base: wpmlst-540
32
-
33
- add_action( 'wp_ajax_wcml_update_base_translation', array( $this, 'wcml_update_base_translation' ) );
34
-
35
- add_filter( 'redirect_canonical', array( $this, 'check_wc_tax_url_on_redirect' ), 10, 2 );
36
-
37
- add_filter( 'query_vars', array( $this, 'translate_query_var_for_product' ) );
38
-
39
- add_filter( 'wp_redirect', array( $this, 'encode_shop_slug' ), 10, 2 );
40
-
41
- }
42
-
43
- function set_up() {
44
- global $woocommerce_wpml;
45
-
46
- if ( empty( $woocommerce_wpml->settings['url_translation_set_up'] ) ) {
47
-
48
- $this->clean_up_product_and_taxonomy_bases();
49
-
50
- //set translate product by default
51
- $this->translate_product_base();
52
-
53
- $this->register_product_and_taxonomy_bases();
54
-
55
- $woocommerce_wpml->settings['url_translation_set_up'] = 1;
56
- $woocommerce_wpml->update_settings();
57
- }
58
-
59
- }
60
-
61
- function clean_up_product_and_taxonomy_bases(){
62
- global $wpdb;
63
-
64
- $base = $this->get_woocommerce_product_base();
65
-
66
- //delete other old product bases
67
- $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_strings WHERE context = 'WordPress' AND value != '".trim( $base,'/' )."' AND name LIKE 'URL slug:%' " );
68
-
69
- //update name for current base
70
-
71
- $wpdb->update(
72
- $wpdb->prefix . 'icl_strings',
73
- array(
74
- 'context' => 'WordPress',
75
- 'name' => 'URL slug: product'
76
- ),
77
- array(
78
- 'context' => 'WordPress',
79
- 'name' => sprintf('Url slug: %s', trim( $base,'/' ))
80
- )
81
- );
82
-
83
- $woocommerce_permalinks = maybe_unserialize( get_option('woocommerce_permalinks') );
84
-
85
- foreach ( (array) $woocommerce_permalinks as $base_key => $base ) {
86
-
87
- $base_key = trim($base_key, '/');
88
-
89
- $taxonomy = false;
90
-
91
- switch( $base_key ){
92
- case 'category_base': $taxonomy = 'product_cat'; break;
93
- case 'tag_base': $taxonomy = 'product_tag'; break;
94
- case 'attribute_base':$taxonomy = 'attribute'; break;
95
- }
96
-
97
- if( $taxonomy ) {
98
- $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_strings WHERE context LIKE '".sprintf('URL %s slugs - ', $taxonomy)."%'" );
99
- }
100
-
101
- }
102
-
103
- }
104
-
105
- function fix_post_object_rewrite_slug(){
106
- global $wp_post_types, $wp_rewrite;
107
-
108
- if( empty( $this->wc_permalinks['product_base'] ) ){
109
-
110
- $wp_post_types['product']->rewrite['slug'] = 'product';
111
- $wp_rewrite->extra_permastructs['product']['struct'] = '/product/%product%';
112
-
113
- }
114
-
115
- }
116
-
117
- function url_strings_context() {
118
- return 'WordPress';
119
- }
120
-
121
- public function url_string_name( $type, $value = '' ) {
122
-
123
- $name = '';
124
-
125
- switch ( $type ) {
126
- case 'product':
127
- $name = sprintf( 'URL slug: %s', $type );
128
- break;
129
- case 'product_cat':
130
- case 'product_tag':
131
- case 'attribute':
132
- $name = sprintf( 'URL %s tax slug', $type );
133
- break;
134
- case 'attribute_slug':
135
- $name = sprintf( 'URL attribute slug: %s', $value );
136
- break;
137
- }
138
-
139
- return $name;
140
- }
141
-
142
- function translate_product_base() {
143
-
144
- if ( !defined( 'WOOCOMMERCE_VERSION' ) || ( !isset( $GLOBALS['ICL_Pro_Translation'] ) || is_null( $GLOBALS['ICL_Pro_Translation'] ) ) ) {
145
- return;
146
- }
147
-
148
- $slug = $this->get_woocommerce_product_base();
149
-
150
- if ( version_compare( WPML_ST_VERSION, '2.2.6', '>' ) ) {
151
-
152
- // Use new API for WPML ST > 2.2.6
153
- do_action( 'wpml_activate_slug_translation', 'product', $slug );
154
-
155
- } else {
156
-
157
- // force_product_slug_translation_on
158
- global $sitepress;
159
- $iclsettings = $sitepress->get_settings();
160
- if ( empty( $iclsettings['posts_slug_translation']['on'] ) || empty( $iclsettings['posts_slug_translation']['types']['product'] ) ) {
161
- $iclsettings['posts_slug_translation']['on'] = 1;
162
- $iclsettings['posts_slug_translation']['types']['product'] = 1;
163
- $sitepress->save_settings( $iclsettings );
164
- }
165
-
166
- $string = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
167
- if ( !$string ) {
168
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'product' ), $slug );
169
- }
170
-
171
- }
172
-
173
- }
174
-
175
- function get_woocommerce_product_base() {
176
-
177
- if ( isset( $this->wc_permalinks['product_base'] ) && !empty( $this->wc_permalinks['product_base'] ) ) {
178
- return trim( $this->wc_permalinks['product_base'], '/' );
179
- } elseif ( get_option( 'woocommerce_product_slug' ) != false ) {
180
- return trim( get_option( 'woocommerce_product_slug' ), '/' );
181
- } else {
182
- return $this->default_product_base; // the default WooCommerce value. Before permalinks options are saved
183
- }
184
-
185
- }
186
-
187
- function register_product_and_taxonomy_bases( $value = false, $old_value = false ) {
188
- global $woocommerce_wpml;
189
-
190
- if( empty( $value ) ){
191
- $permalink_options = $this->wc_permalinks;
192
- }else{
193
- $permalink_options = $value;
194
- }
195
-
196
- // products
197
- $product_base = !empty( $permalink_options['product_base'] ) ? trim( $permalink_options['product_base'], '/' ) : $this->default_product_base;
198
- $name = $this->url_string_name( 'product' );
199
-
200
- $string_language = $woocommerce_wpml->strings->get_string_language( $product_base, $this->url_strings_context(), $name );
201
- if( is_null($string_language) ){
202
- $string_language = '';
203
- }
204
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $product_base, false, $string_language );
205
-
206
- if( isset($_POST['product_base_language'])){
207
- $woocommerce_wpml->strings->set_string_language( $product_base, $this->url_strings_context(), $name, $_POST['product_base_language']);
208
- }
209
-
210
- if ( $product_base == $this->default_product_base ) {
211
- $this->add_default_slug_translations( $product_base, $name );
212
- }
213
-
214
- // categories
215
- $category_base = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $this->default_product_category_base;
216
- $name = $this->url_string_name( 'product_cat' );
217
-
218
- $string_language = $woocommerce_wpml->strings->get_string_language( $category_base, $this->url_strings_context(), $name );
219
- if( is_null($string_language) ){
220
- $string_language = '';
221
- }
222
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $category_base, false, $string_language );
223
-
224
- if( isset($_POST['category_base_language'])){
225
- $woocommerce_wpml->strings->set_string_language( $category_base, $this->url_strings_context(), $name, $_POST['category_base_language']);
226
- }
227
-
228
- if ( $category_base == $this->default_product_category_base ) {
229
- $this->add_default_slug_translations( $category_base, $name );
230
- }
231
-
232
- // tags
233
- $tag_base = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $this->default_product_tag_base;
234
- $name = $this->url_string_name( 'product_tag' );
235
-
236
- $string_language = $woocommerce_wpml->strings->get_string_language( $tag_base, $this->url_strings_context(), $name );
237
- if( is_null($string_language) ){
238
- $string_language = '';
239
- }
240
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $tag_base, false, $string_language );
241
-
242
- if( isset($_POST['tag_base_language'])){
243
- $woocommerce_wpml->strings->set_string_language( $tag_base, $this->url_strings_context(), $name, $_POST['tag_base_language']);
244
- }
245
-
246
- if ( $tag_base == $this->default_product_tag_base ) {
247
- $this->add_default_slug_translations( $tag_base, $name );
248
- }
249
-
250
-
251
- if ( isset( $permalink_options['attribute_base'] ) && $permalink_options['attribute_base'] ) {
252
- $attr_base = trim( $permalink_options['attribute_base'], '/' );
253
-
254
- $string_language = $woocommerce_wpml->strings->get_string_language( $attr_base, $this->url_strings_context(), $name );
255
- if( is_null($string_language) ){
256
- $string_language = '';
257
- }
258
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute' ), $attr_base, false, $string_language );
259
-
260
- if( isset($_POST['attribute_base_language'])){
261
- $woocommerce_wpml->strings->set_string_language( $attr_base, $this->url_strings_context(), $this->url_string_name( 'attribute' ), $_POST['attribute_base_language']);
262
- }
263
- }
264
-
265
- return $value;
266
- }
267
-
268
- function add_default_slug_translations( $slug, $name ) {
269
- global $woocommerce_wpml, $sitepress, $wpdb;
270
-
271
- $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $name );
272
- $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $name );
273
-
274
- // will use a filter in the future wpmlst-529
275
- $string_object = new WPML_ST_String( $string_id, $wpdb );
276
- $string_translation_statuses = $string_object->get_translation_statuses();
277
-
278
- foreach ( $string_translation_statuses as $s ) {
279
- $string_translations[$s->language] = $s->status;
280
- }
281
-
282
- $languages = $sitepress->get_active_languages();
283
-
284
- foreach ( $languages as $language => $language_info ) {
285
-
286
- if ( $language != $string_language ) {
287
-
288
- // check if there's an existing translation
289
- if ( !isset( $string_translations[$language] ) ) {
290
-
291
- $slug_translation = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( $slug, $language, false );
292
-
293
- if ( $slug_translation ) {
294
- // add string translation
295
- icl_add_string_translation( $string_id, $language, $slug_translation, ICL_STRING_TRANSLATION_COMPLETE );
296
- }
297
-
298
- }
299
-
300
- }
301
- }
302
-
303
- }
304
-
305
- function force_bases_in_strings_languages( $value ) {
306
- global $sitepress, $woocommerce_wpml;
307
-
308
- if( $value && $sitepress->get_current_language() != 'en' ) {
309
-
310
- remove_filter( 'gettext_with_context', array( $woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
311
- $taxonomies = array(
312
- 'product_cat' => array(
313
- 'base' => 'category_base',
314
- 'base_translated' => apply_filters(
315
- 'wpml_translate_single_string',
316
- 'product-category',
317
- $this->url_strings_context(),
318
- $this->url_string_name( 'product_cat' )
319
- ),
320
- 'default' => $this->default_product_category_base
321
- ),
322
- 'product_tag' => array(
323
- 'base' => 'tag_base',
324
- 'base_translated' => apply_filters(
325
- 'wpml_translate_single_string',
326
- 'product-tag',
327
- $this->url_strings_context(),
328
- $this->url_string_name( 'product_tag' )
329
- ),
330
- 'default' => $this->default_product_tag_base
331
- ),
332
- );
333
- add_filter( 'gettext_with_context', array( $woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
334
- foreach ( $taxonomies as $taxonomy => $taxonomy_details ) {
335
-
336
- if ( empty( $this->wc_permalinks[$taxonomy_details['base']] ) && $value ) {
337
-
338
- $new_value = array();
339
- foreach ( $value as $k => $v ) {
340
- $k = preg_replace( "#" . $taxonomy_details['base_translated'] . "/#", $taxonomy_details['default'] . '/', $k );
341
- $new_value[$k] = $v;
342
- }
343
- $value = $new_value;
344
- unset( $new_value );
345
-
346
- }
347
-
348
- }
349
-
350
- }
351
-
352
- return $value;
353
-
354
- }
355
-
356
- function translate_bases_in_rewrite_rules( $value ) {
357
- global $sitepress, $sitepress_settings, $woocommerce_wpml;
358
-
359
- if ( ! empty( $value ) ) {
360
-
361
- $taxonomies = array( 'product_cat', 'product_tag' );
362
-
363
- foreach ( $taxonomies as $taxonomy ) {
364
- $slug_details = $this->get_translated_tax_slug( $taxonomy );
365
-
366
- $string_language = $woocommerce_wpml->strings->get_string_language( $slug_details['slug'], $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
367
- if ( $sitepress->get_current_language() == $string_language ) {
368
- continue;
369
- }
370
-
371
- if ( $slug_details ) {
372
-
373
- $slug_match = addslashes( ltrim($slug_details['slug'], '/') );
374
- $slug_translation_match = ltrim($slug_details['translated_slug'], '/');
375
-
376
- $buff_value = array();
377
- foreach ( (array)$value as $k => $v ) {
378
-
379
- if ( $slug_details['slug'] != $slug_details['translated_slug'] && preg_match( '#^[^/]*/?' . $slug_match . '/#', $k ) ) {
380
- $k = preg_replace( '#^([^/]*)(/?)' . $slug_match . '/#', '$1$2' . $slug_translation_match . '/', $k );
381
- }
382
-
383
- $buff_value[$k] = $v;
384
- }
385
- $value = $buff_value;
386
- unset( $buff_value );
387
- }
388
-
389
- }
390
-
391
- // handle attributes
392
- $wc_taxonomies = wc_get_attribute_taxonomies();
393
- $wc_taxonomies_wc_format = array();
394
- foreach ( $wc_taxonomies as $k => $v ) {
395
- $wc_taxonomies_wc_format[] = 'pa_' . $v->attribute_name;
396
- }
397
-
398
- foreach ( $wc_taxonomies_wc_format as $taxonomy ) {
399
- $taxonomy_obj = get_taxonomy( $taxonomy );
400
-
401
- if ( isset( $taxonomy_obj->rewrite['slug'] ) ) {
402
- $exp = explode( '/', trim( $taxonomy_obj->rewrite['slug'], '/' ) );
403
- $slug = join( '/', array_slice( $exp, 0, count( $exp ) - 1 ) );
404
-
405
- $attribute_slug = preg_replace( "#^$slug/#", '', $taxonomy_obj->rewrite['slug'] );
406
- }
407
-
408
- if ( isset( $slug ) ) {
409
- $string_language = $woocommerce_wpml->strings->get_string_language($slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
410
-
411
- if ($sitepress->get_current_language() != $string_language) {
412
-
413
- $slug_translation = apply_filters('wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
414
- if ($slug_translation) {
415
-
416
- $attribute_slug_translation = apply_filters('wpml_translate_single_string', $attribute_slug, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $attribute_slug) );
417
-
418
- $slug_match = addslashes( ltrim($slug, '/') );
419
- $slug_translation_match = ltrim($slug_translation, '/');
420
-
421
- $buff_value = array();
422
- foreach ((array)$value as $k => $v) {
423
- if ($slug != $slug_translation && preg_match('#^' . $slug_match . '/(.*)#', $k)) {
424
- $k = preg_replace('#^' . $slug_match . '/(' . $attribute_slug .')/(.*)#', $slug_translation_match . '/' . $attribute_slug_translation . '/$2', $k);
425
- }
426
- $buff_value[$k] = $v;
427
- }
428
-
429
- $value = $buff_value;
430
- unset($buff_value);
431
-
432
- }
433
-
434
- }
435
- }
436
-
437
- }
438
-
439
-
440
-
441
- //filter shop page rewrite slug
442
- $current_shop_id = wc_get_page_id( 'shop' );
443
- $default_shop_id = apply_filters( 'translate_object_id', $current_shop_id, 'page', true, $sitepress->get_default_language() );
444
-
445
- if ( is_null( get_post( $current_shop_id ) ) || is_null( get_post( $default_shop_id ) ) )
446
- return $value;
447
-
448
- $current_slug = get_post( $current_shop_id )->post_name;
449
- $default_slug = get_post( $default_shop_id )->post_name;
450
-
451
- if ( $current_slug != $default_slug ) {
452
- $buff_value = array();
453
- foreach ( (array)$value as $k => $v ) {
454
-
455
- if( preg_match( '#^' . $default_slug . '/\?\$$#', $k ) ||
456
- preg_match( '#^' . $default_slug . '/\(?feed#', $k ) ||
457
- preg_match( '#^' . $default_slug . '/page#', $k )){
458
-
459
- $k = preg_replace( '#^' . $default_slug . '/#', $current_slug . '/', $k );
460
- }
461
-
462
- $buff_value[$k] = $v;
463
- }
464
-
465
- $value = $buff_value;
466
- unset( $buff_value );
467
- }
468
- }
469
-
470
- return $value;
471
- }
472
-
473
- function translate_taxonomy_base( $termlink, $term, $taxonomy ) {
474
- global $wp_rewrite, $wpml_term_translations, $sitepress;
475
- static $no_recursion_flag;
476
-
477
- // handles product categories, product tags and attributes
478
-
479
- $wc_taxonomies = wc_get_attribute_taxonomies();
480
- foreach ( $wc_taxonomies as $k => $v ) {
481
- $wc_taxonomies_wc_format[] = 'pa_' . $v->attribute_name;
482
- }
483
-
484
- if ( ( $taxonomy == 'product_cat' || $taxonomy == 'product_tag' || ( !empty( $wc_taxonomies_wc_format ) && in_array( $taxonomy, $wc_taxonomies_wc_format ) ) ) && !$no_recursion_flag ) {
485
-
486
- $cache_key = 'termlink#' . $taxonomy . '#' . $term->term_id;
487
- if ( false && $link = wp_cache_get( $cache_key, 'terms' ) ) {
488
- $termlink = $link;
489
-
490
- } else {
491
-
492
- $no_recursion_flag = false;
493
-
494
- if ( !is_null( $wpml_term_translations ) ) {
495
- $term_language = $term->term_id ? $wpml_term_translations->get_element_lang_code( $term->term_taxonomy_id ) : false;
496
- } else {
497
- $term_language = $term->term_id ? $sitepress->get_language_for_element( $term->term_taxonomy_id, 'tax_' . $taxonomy ) : false;
498
- }
499
-
500
- if ( $term_language ) {
501
-
502
- $slug_details = $this->get_translated_tax_slug( $taxonomy, $term_language, true );
503
-
504
- $base = $slug_details['slug'];
505
- $base_translated = $slug_details['translated_slug'];
506
-
507
- if ( !empty( $base_translated ) && $base_translated != $base && isset( $wp_rewrite->extra_permastructs[$taxonomy] ) ) {
508
-
509
- $buff = $wp_rewrite->extra_permastructs[$taxonomy]['struct'];
510
-
511
- // translate the attribute base
512
- $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = preg_replace( '#^' . $base . '/(.*)#', $base_translated . '/$1', $wp_rewrite->extra_permastructs[$taxonomy]['struct'] );
513
-
514
- // translate the attribute slug
515
- if( isset($this->wc_permalinks['attribute_base']) && $this->wc_permalinks['attribute_base'] === $base ){
516
-
517
- $attribute_slug = preg_replace('#^' . $base . '/([^/]+)/.+$#', '$1', $wp_rewrite->extra_permastructs[$taxonomy]['struct']);
518
- $attribute_slug_default = preg_replace('#^pa_#', '', $taxonomy );
519
- $attribute_slug_translation = apply_filters(
520
- 'wpml_translate_single_string',
521
- $attribute_slug,
522
- $this->url_strings_context(),
523
- $this->url_string_name( 'attribute_slug', $attribute_slug_default ),
524
- $term_language
525
- );
526
-
527
- if( $attribute_slug_translation != $attribute_slug ){
528
- $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = preg_replace(
529
- '#^' . $base_translated . '/([^/]+)/(.+)$#',
530
- $base_translated . '/' . $attribute_slug_translation . '/$2',
531
- $wp_rewrite->extra_permastructs[$taxonomy]['struct']
532
- );
533
- }
534
-
535
- }
536
-
537
-
538
- $no_recursion_flag = true;
539
- $termlink = get_term_link( $term, $taxonomy );
540
-
541
- $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = $buff;
542
-
543
- }
544
-
545
- }
546
-
547
- $no_recursion_flag = false;
548
-
549
- wp_cache_add( $cache_key, $termlink, 'terms', 0 );
550
- }
551
-
552
- }
553
-
554
- return $termlink;
555
- }
556
-
557
- function get_translated_tax_slug( $taxonomy, $language = false, $return_gettext_slug = false ) {
558
- global $sitepress, $woocommerce_wpml;
559
-
560
- switch ( $taxonomy ) {
561
- case 'product_tag':
562
-
563
- if( !empty( $this->wc_permalinks['tag_base'] ) ) {
564
- $slug = $gettext_slug = trim($this->wc_permalinks['tag_base'], '/');
565
- }else{
566
- $slug = 'product-tag';
567
- if( $return_gettext_slug ){
568
- $gettext_slug = $this->default_product_tag_gettext_base;
569
- }
570
- }
571
-
572
- $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
573
-
574
- break;
575
-
576
- case 'product_cat':
577
-
578
- if( !empty( $this->wc_permalinks['category_base'] ) ) {
579
- $slug = $gettext_slug = trim( $this->wc_permalinks['category_base'], '/' );
580
- }else{
581
- $slug = 'product-category';
582
- if( $return_gettext_slug ){
583
- $gettext_slug = $this->default_product_category_gettext_base;
584
- }
585
- }
586
-
587
- $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
588
-
589
- break;
590
-
591
- default:
592
- $slug = $gettext_slug = trim( $this->wc_permalinks['attribute_base'], '/' );
593
-
594
- $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
595
-
596
- $taxonomy = 'attribute';
597
-
598
- break;
599
- }
600
-
601
- if ( !$language ) {
602
- $language = $sitepress->get_current_language();
603
- }
604
-
605
- if ( $slug && $language != 'all' && $language != $string_language ) {
606
-
607
- $slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ), $language, false );
608
-
609
- return array( 'slug' => $return_gettext_slug ? $gettext_slug : $slug, 'translated_slug' => $slug_translation );
610
- }
611
-
612
- return array( 'slug' => $return_gettext_slug ? $gettext_slug : $slug, 'translated_slug' => $return_gettext_slug && $language != $string_language ? $gettext_slug : $slug );
613
-
614
- }
615
-
616
- function get_base_translation ( $base, $language ){
617
- global $woocommerce_wpml;
618
-
619
- // case of attribute slugs
620
- if( strpos( $base, 'attribute_slug-' ) === 0 ){
621
- $slug = preg_replace( '#^attribute_slug-#', '', $base );
622
- $base = 'attribute_slug';
623
- }
624
-
625
- switch ( $base ) {
626
- case 'product':
627
- $slug = $this->get_woocommerce_product_base();
628
- $return['name'] = __('Product Base', 'woocommerce-multilingual');
629
- break;
630
-
631
- case 'product_tag':
632
- $slug = !empty( $this->wc_permalinks['tag_base'] ) ? trim( $this->wc_permalinks['tag_base'], '/' ) : 'product-tag';
633
- $return['name'] = __('Product Tag Base', 'woocommerce-multilingual');
634
- break;
635
-
636
- case 'product_cat':
637
- $slug = !empty( $this->wc_permalinks['category_base'] ) ? trim( $this->wc_permalinks['category_base'], '/' ) : 'product-category';
638
- $return['name'] = __('Product Category Base', 'woocommerce-multilingual');
639
- break;
640
-
641
- case 'attribute':
642
- $slug = trim( $this->wc_permalinks['attribute_base'], '/' );
643
- $return['name'] = __('Product Attribute Base', 'woocommerce-multilingual');
644
- break;
645
-
646
- case 'attribute_slug':
647
- $return['name'] = __('Attribute Slug', 'woocommerce-multilingual');
648
- $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( $base, $slug ) );
649
- break;
650
-
651
- default:
652
- $endpoints = WC()->query->query_vars;
653
- $slug = isset( $endpoints[ $base ] ) ? $endpoints[ $base ] : false ;
654
- $return['name'] = sprintf( __('Endpoint: %s', 'woocommerce-multilingual'), $base);
655
- $string_id = icl_get_string_id( $slug, 'WooCommerce Endpoints', $base );
656
- break;
657
- }
658
-
659
- $return['original_value'] = $slug;
660
- if( !isset( $string_id ) ){
661
- $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( $base ) );
662
- }
663
- $base_translations = icl_get_string_translations_by_id( $string_id );
664
-
665
- $return['translated_base'] = '';
666
- if( isset($base_translations[$language])){
667
- if( $base_translations[$language]['status'] == ICL_TM_COMPLETE ){
668
- $return['translated_base'] = $base_translations[$language]['value'];
669
- }elseif($base_translations[$language]['status'] == ICL_TM_NEEDS_UPDATE){
670
- $return['translated_base'] = $base_translations[$language]['value'];
671
- $return['needs_update '] = true;
672
- }
673
- }
674
-
675
- return $return;
676
-
677
- }
678
-
679
- function get_source_slug_language( $base ){
680
- global $sitepress, $woocommerce_wpml;
681
-
682
- if( $base == 'shop' ){
683
- $source_language = $sitepress->get_language_for_element( get_option('woocommerce_shop_page_id' ) , 'post_page' );
684
- }elseif( in_array( $base, array( 'product','product_cat','product_tag','attribute') ) ){
685
- $source_language = $woocommerce_wpml->strings->get_string_language( $base, $this->url_strings_context(), $this->url_string_name( $base ) );
686
- }else{
687
- $source_language = $woocommerce_wpml->strings->get_string_language( $base, 'WooCommerce Endpoints', $base );
688
- }
689
-
690
- return $source_language;
691
- }
692
-
693
-
694
- function wcml_update_base_translation(){
695
-
696
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
697
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_update_base_translation')){
698
- die('Invalid nonce');
699
- }
700
-
701
- global $wpdb, $woocommerce_wpml, $sitepress;
702
-
703
- $original_base = $_POST['base'];
704
- $original_base_value = $_POST['base_value'];
705
- $base_translation = $_POST['base_translation'];
706
- $language = $_POST['language'];
707
-
708
- if( $original_base == 'shop' ){
709
- $original_shop_id = get_option('woocommerce_shop_page_id' );
710
- $translated_shop_id = apply_filters( 'translate_object_id', $original_shop_id , 'page', false, $language );
711
-
712
- if( !is_null( $translated_shop_id ) ){
713
-
714
- $trnsl_shop_obj = get_post( $translated_shop_id );
715
- $new_slug = wp_unique_post_slug( sanitize_title( $_POST['base_translation'] ), $translated_shop_id, $trnsl_shop_obj->post_status, $trnsl_shop_obj->post_type, $trnsl_shop_obj->post_parent );
716
- $wpdb->update( $wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $translated_shop_id ) );
717
-
718
- }
719
-
720
- }else{
721
- if( in_array( $original_base, array( 'product','product_cat','product_tag','attribute') ) ) {
722
- $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( $original_base ) );
723
- }elseif( strpos( $original_base, 'attribute_slug-' ) === 0 ){
724
- $slug = preg_replace( '#^attribute_slug-#', '', $original_base );
725
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ), $slug );
726
- $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ) );
727
- }else{
728
- $string_id = icl_get_string_id( $original_base_value, 'WooCommerce Endpoints', $original_base );
729
- if( !$string_id && function_exists( 'icl_register_string' ) ){
730
- $string_id = icl_register_string( 'WooCommerce Endpoints', $original_base, $original_base_value );
731
- }
732
- $woocommerce_wpml->endpoints->add_endpoints();
733
- $woocommerce_wpml->endpoints->flush_rules_for_endpoints_translations();
734
- }
735
-
736
- icl_add_string_translation( $string_id, $language, $base_translation, ICL_STRING_TRANSLATION_COMPLETE );
737
-
738
- }
739
-
740
- $edit_base = new WCML_Store_URLs_Edit_Base_UI( $original_base, $language, $woocommerce_wpml, $sitepress );
741
- $html = $edit_base->get_view();
742
-
743
- echo json_encode($html);
744
- die();
745
-
746
-
747
- }
748
-
749
- // return correct redirect URL for WC standard taxonomies when pretty permalink uses with lang as parameter in WPML
750
- function check_wc_tax_url_on_redirect( $redirect_url, $requested_url ){
751
- global $wp_query;
752
-
753
- if( is_tax() ){
754
- $original = @parse_url( $requested_url );
755
- parse_str( $original['query'], $query_args ) ;
756
- if( ( isset( $query_args[ 'product_cat' ] ) || isset( $query_args[ 'product_tag' ] ) ) && isset ( $query_args[ 'lang' ] ) ){
757
- $obj = $wp_query->get_queried_object();
758
- $tax_url = get_term_link( (int)$obj->term_id, $obj->taxonomy ) ;
759
-
760
- return $tax_url;
761
- }
762
- }
763
-
764
- return $redirect_url;
765
- }
766
-
767
- public function translate_query_var_for_product($public_query_vars){
768
- global $woocommerce_wpml, $sitepress;
769
-
770
- $product_permalink = $woocommerce_wpml->strings->product_permalink_slug();
771
- $string_language = $woocommerce_wpml->strings->get_string_language( $product_permalink, $this->url_strings_context(), $this->url_string_name('product') );
772
-
773
- if( $sitepress->get_current_language() != $string_language ){
774
- $translated_slug = $this->get_translated_product_base_by_lang( false,$product_permalink );
775
-
776
- if(isset($_GET[$translated_slug])){
777
- $buff = $_GET[$translated_slug];
778
- unset($_GET[$translated_slug]);
779
- $_GET[$product_permalink] = $buff;
780
- }
781
-
782
- }
783
-
784
- return $public_query_vars;
785
- }
786
-
787
- public function get_translated_product_base_by_lang($language = false, $product_slug = false){
788
- global $woocommerce_wpml;
789
-
790
- if(!$language){
791
- global $sitepress;
792
- $language = $sitepress->get_current_language();
793
-
794
- }
795
-
796
- if(!$product_slug){
797
- $product_slug = $woocommerce_wpml->strings->product_permalink_slug();
798
- }
799
-
800
- if ( version_compare( WPML_ST_VERSION, '2.3', '>=' ) ) {
801
- $translated_slug = apply_filters( 'wpml_get_translated_slug', $product_slug, 'product' , $language );
802
- }elseif ( apply_filters( 'wpml_slug_translation_available', false) ) {
803
- $translated_slug = apply_filters( 'wpml_get_translated_slug', 'product' , $language );
804
- } else {
805
- $translated_slug = apply_filters( 'wpml_translate_single_string', $product_slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
806
- }
807
-
808
- return $translated_slug;
809
- }
810
-
811
- public function encode_shop_slug($location, $status){
812
- if(get_post_type(get_query_var('p')) == 'product'){
813
- global $sitepress;
814
- $language = $sitepress->get_language_for_element(get_query_var('p'), 'post_product');
815
- $base_slug = $this->get_translated_product_base_by_lang($language);
816
-
817
- $location = str_replace($base_slug , urlencode($base_slug),$location);
818
- }
819
-
820
- return $location;
821
- }
822
  }
1
+ <?php
2
+
3
+ class WCML_Url_Translation {
4
+
5
+ public $default_product_base;
6
+ public $default_product_category_base;
7
+ public $default_product_category_gettext_base;
8
+ public $default_product_tag_base;
9
+ public $default_product_tag_gettext_base;
10
+
11
+ function __construct() {
12
+
13
+ $this->default_product_base = 'product';
14
+ $this->default_product_category_base = 'product-category';
15
+ $this->default_product_tag_base = 'product-tag';
16
+ $this->default_product_category_gettext_base = _x( 'product-category', 'slug', 'woocommerce' );
17
+ $this->default_product_tag_gettext_base = _x( 'product-tag', 'slug', 'woocommerce' );
18
+
19
+ $this->wc_permalinks = get_option( 'woocommerce_permalinks' );
20
+
21
+ $this->set_up(); //initialization
22
+
23
+ add_filter( 'pre_update_option_woocommerce_permalinks', array( $this, 'register_product_and_taxonomy_bases' ), 10, 2 );
24
+
25
+ add_filter( 'pre_update_option_rewrite_rules', array( $this, 'force_bases_in_strings_languages' ), 1, 1 ); // high priority
26
+
27
+ add_filter( 'option_rewrite_rules', array( $this, 'translate_bases_in_rewrite_rules' ), 0, 1 ); // high priority
28
+
29
+ add_filter( 'term_link', array( $this, 'translate_taxonomy_base' ), 0, 3 ); // high priority
30
+
31
+ add_action( 'init', array( $this, 'fix_post_object_rewrite_slug' ), 6 ); // handle the particular case of the default product base: wpmlst-540
32
+
33
+ add_action( 'wp_ajax_wcml_update_base_translation', array( $this, 'wcml_update_base_translation' ) );
34
+
35
+ add_filter( 'redirect_canonical', array( $this, 'check_wc_tax_url_on_redirect' ), 10, 2 );
36
+
37
+ add_filter( 'query_vars', array( $this, 'translate_query_var_for_product' ) );
38
+
39
+ add_filter( 'wp_redirect', array( $this, 'encode_shop_slug' ), 10, 2 );
40
+
41
+ }
42
+
43
+ function set_up() {
44
+ global $woocommerce_wpml;
45
+
46
+ if ( empty( $woocommerce_wpml->settings['url_translation_set_up'] ) ) {
47
+
48
+ $this->clean_up_product_and_taxonomy_bases();
49
+
50
+ //set translate product by default
51
+ $this->translate_product_base();
52
+
53
+ $this->register_product_and_taxonomy_bases();
54
+
55
+ $woocommerce_wpml->settings['url_translation_set_up'] = 1;
56
+ $woocommerce_wpml->update_settings();
57
+ }
58
+
59
+ }
60
+
61
+ function clean_up_product_and_taxonomy_bases(){
62
+ global $wpdb;
63
+
64
+ $base = $this->get_woocommerce_product_base();
65
+
66
+ //delete other old product bases
67
+ $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_strings WHERE context = 'WordPress' AND value != '".trim( $base,'/' )."' AND name LIKE 'URL slug:%' " );
68
+
69
+ //update name for current base
70
+
71
+ $wpdb->update(
72
+ $wpdb->prefix . 'icl_strings',
73
+ array(
74
+ 'context' => 'WordPress',
75
+ 'name' => 'URL slug: product'
76
+ ),
77
+ array(
78
+ 'context' => 'WordPress',
79
+ 'name' => sprintf('Url slug: %s', trim( $base,'/' ))
80
+ )
81
+ );
82
+
83
+ $woocommerce_permalinks = maybe_unserialize( get_option('woocommerce_permalinks') );
84
+
85
+ foreach ( (array) $woocommerce_permalinks as $base_key => $base ) {
86
+
87
+ $base_key = trim($base_key, '/');
88
+
89
+ $taxonomy = false;
90
+
91
+ switch( $base_key ){
92
+ case 'category_base': $taxonomy = 'product_cat'; break;
93
+ case 'tag_base': $taxonomy = 'product_tag'; break;
94
+ case 'attribute_base':$taxonomy = 'attribute'; break;
95
+ }
96
+
97
+ if( $taxonomy ) {
98
+ $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_strings WHERE context LIKE '".sprintf('URL %s slugs - ', $taxonomy)."%'" );
99
+ }
100
+
101
+ }
102
+
103
+ }
104
+
105
+ function fix_post_object_rewrite_slug(){
106
+ global $wp_post_types, $wp_rewrite;
107
+
108
+ if( empty( $this->wc_permalinks['product_base'] ) ){
109
+
110
+ $wp_post_types['product']->rewrite['slug'] = 'product';
111
+ $wp_rewrite->extra_permastructs['product']['struct'] = '/product/%product%';
112
+
113
+ }
114
+
115
+ }
116
+
117
+ function url_strings_context() {
118
+ return 'WordPress';
119
+ }
120
+
121
+ public function url_string_name( $type, $value = '' ) {
122
+
123
+ $name = '';
124
+
125
+ switch ( $type ) {
126
+ case 'product':
127
+ $name = sprintf( 'URL slug: %s', $type );
128
+ break;
129
+ case 'product_cat':
130
+ case 'product_tag':
131
+ case 'attribute':
132
+ $name = sprintf( 'URL %s tax slug', $type );
133
+ break;
134
+ case 'attribute_slug':
135
+ $name = sprintf( 'URL attribute slug: %s', $value );
136
+ break;
137
+ }
138
+
139
+ return $name;
140
+ }
141
+
142
+ function translate_product_base() {
143
+
144
+ if ( !defined( 'WOOCOMMERCE_VERSION' ) || ( !isset( $GLOBALS['ICL_Pro_Translation'] ) || is_null( $GLOBALS['ICL_Pro_Translation'] ) ) ) {
145
+ return;
146
+ }
147
+
148
+ $slug = $this->get_woocommerce_product_base();
149
+
150
+ if ( version_compare( WPML_ST_VERSION, '2.2.6', '>' ) ) {
151
+
152
+ // Use new API for WPML ST > 2.2.6
153
+ do_action( 'wpml_activate_slug_translation', 'product', $slug );
154
+
155
+ } else {
156
+
157
+ // force_product_slug_translation_on
158
+ global $sitepress;
159
+ $iclsettings = $sitepress->get_settings();
160
+ if ( empty( $iclsettings['posts_slug_translation']['on'] ) || empty( $iclsettings['posts_slug_translation']['types']['product'] ) ) {
161
+ $iclsettings['posts_slug_translation']['on'] = 1;
162
+ $iclsettings['posts_slug_translation']['types']['product'] = 1;
163
+ $sitepress->save_settings( $iclsettings );
164
+ }
165
+
166
+ $string = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
167
+ if ( !$string ) {
168
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'product' ), $slug );
169
+ }
170
+
171
+ }
172
+
173
+ }
174
+
175
+ function get_woocommerce_product_base() {
176
+
177
+ if ( isset( $this->wc_permalinks['product_base'] ) && !empty( $this->wc_permalinks['product_base'] ) ) {
178
+ return trim( $this->wc_permalinks['product_base'], '/' );
179
+ } elseif ( get_option( 'woocommerce_product_slug' ) != false ) {
180
+ return trim( get_option( 'woocommerce_product_slug' ), '/' );
181
+ } else {
182
+ return $this->default_product_base; // the default WooCommerce value. Before permalinks options are saved
183
+ }
184
+
185
+ }
186
+
187
+ function register_product_and_taxonomy_bases( $value = false, $old_value = false ) {
188
+ global $woocommerce_wpml;
189
+
190
+ if( empty( $value ) ){
191
+ $permalink_options = $this->wc_permalinks;
192
+ }else{
193
+ $permalink_options = $value;
194
+ }
195
+
196
+ // products
197
+ $product_base = !empty( $permalink_options['product_base'] ) ? trim( $permalink_options['product_base'], '/' ) : $this->default_product_base;
198
+ $name = $this->url_string_name( 'product' );
199
+
200
+ $string_language = $woocommerce_wpml->strings->get_string_language( $product_base, $this->url_strings_context(), $name );
201
+ if( is_null($string_language) ){
202
+ $string_language = '';
203
+ }
204
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $product_base, false, $string_language );
205
+
206
+ if( isset($_POST['product_base_language'])){
207
+ $woocommerce_wpml->strings->set_string_language( $product_base, $this->url_strings_context(), $name, $_POST['product_base_language']);
208
+ }
209
+
210
+ if ( $product_base == $this->default_product_base ) {
211
+ $this->add_default_slug_translations( $product_base, $name );
212
+ }
213
+
214
+ // categories
215
+ $category_base = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $this->default_product_category_base;
216
+ $name = $this->url_string_name( 'product_cat' );
217
+
218
+ $string_language = $woocommerce_wpml->strings->get_string_language( $category_base, $this->url_strings_context(), $name );
219
+ if( is_null($string_language) ){
220
+ $string_language = '';
221
+ }
222
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $category_base, false, $string_language );
223
+
224
+ if( isset($_POST['category_base_language'])){
225
+ $woocommerce_wpml->strings->set_string_language( $category_base, $this->url_strings_context(), $name, $_POST['category_base_language']);
226
+ }
227
+
228
+ if ( $category_base == $this->default_product_category_base ) {
229
+ $this->add_default_slug_translations( $category_base, $name );
230
+ }
231
+
232
+ // tags
233
+ $tag_base = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $this->default_product_tag_base;
234
+ $name = $this->url_string_name( 'product_tag' );
235
+
236
+ $string_language = $woocommerce_wpml->strings->get_string_language( $tag_base, $this->url_strings_context(), $name );
237
+ if( is_null($string_language) ){
238
+ $string_language = '';
239
+ }
240
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $name, $tag_base, false, $string_language );
241
+
242
+ if( isset($_POST['tag_base_language'])){
243
+ $woocommerce_wpml->strings->set_string_language( $tag_base, $this->url_strings_context(), $name, $_POST['tag_base_language']);
244
+ }
245
+
246
+ if ( $tag_base == $this->default_product_tag_base ) {
247
+ $this->add_default_slug_translations( $tag_base, $name );
248
+ }
249
+
250
+
251
+ if ( isset( $permalink_options['attribute_base'] ) && $permalink_options['attribute_base'] ) {
252
+ $attr_base = trim( $permalink_options['attribute_base'], '/' );
253
+
254
+ $string_language = $woocommerce_wpml->strings->get_string_language( $attr_base, $this->url_strings_context(), $name );
255
+ if( is_null($string_language) ){
256
+ $string_language = '';
257
+ }
258
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute' ), $attr_base, false, $string_language );
259
+
260
+ if( isset($_POST['attribute_base_language'])){
261
+ $woocommerce_wpml->strings->set_string_language( $attr_base, $this->url_strings_context(), $this->url_string_name( 'attribute' ), $_POST['attribute_base_language']);
262
+ }
263
+ }
264
+
265
+ return $value;
266
+ }
267
+
268
+ function add_default_slug_translations( $slug, $name ) {
269
+ global $woocommerce_wpml, $sitepress, $wpdb;
270
+
271
+ $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $name );
272
+ $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $name );
273
+
274
+ // will use a filter in the future wpmlst-529
275
+ $string_object = new WPML_ST_String( $string_id, $wpdb );
276
+ $string_translation_statuses = $string_object->get_translation_statuses();
277
+
278
+ foreach ( $string_translation_statuses as $s ) {
279
+ $string_translations[$s->language] = $s->status;
280
+ }
281
+
282
+ $languages = $sitepress->get_active_languages();
283
+
284
+ foreach ( $languages as $language => $language_info ) {
285
+
286
+ if ( $language != $string_language ) {
287
+
288
+ // check if there's an existing translation
289
+ if ( !isset( $string_translations[$language] ) ) {
290
+
291
+ $slug_translation = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( $slug, $language, false );
292
+
293
+ if ( $slug_translation ) {
294
+ // add string translation
295
+ icl_add_string_translation( $string_id, $language, $slug_translation, ICL_STRING_TRANSLATION_COMPLETE );
296
+ }
297
+
298
+ }
299
+
300
+ }
301
+ }
302
+
303
+ }
304
+
305
+ function force_bases_in_strings_languages( $value ) {
306
+ global $sitepress, $woocommerce_wpml;
307
+
308
+ if( $value && $sitepress->get_current_language() != 'en' ) {
309
+
310
+ remove_filter( 'gettext_with_context', array( $woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
311
+ $taxonomies = array(
312
+ 'product_cat' => array(
313
+ 'base' => 'category_base',
314
+ 'base_translated' => apply_filters(
315
+ 'wpml_translate_single_string',
316
+ 'product-category',
317
+ $this->url_strings_context(),
318
+ $this->url_string_name( 'product_cat' )
319
+ ),
320
+ 'default' => $this->default_product_category_base
321
+ ),
322
+ 'product_tag' => array(
323
+ 'base' => 'tag_base',
324
+ 'base_translated' => apply_filters(
325
+ 'wpml_translate_single_string',
326
+ 'product-tag',
327
+ $this->url_strings_context(),
328
+ $this->url_string_name( 'product_tag' )
329
+ ),
330
+ 'default' => $this->default_product_tag_base
331
+ ),
332
+ );
333
+ add_filter( 'gettext_with_context', array( $woocommerce_wpml->strings, 'category_base_in_strings_language' ), 99, 3 );
334
+ foreach ( $taxonomies as $taxonomy => $taxonomy_details ) {
335
+
336
+ if ( empty( $this->wc_permalinks[$taxonomy_details['base']] ) && $value ) {
337
+
338
+ $new_value = array();
339
+ foreach ( $value as $k => $v ) {
340
+ $k = preg_replace( "#" . $taxonomy_details['base_translated'] . "/#", $taxonomy_details['default'] . '/', $k );
341
+ $new_value[$k] = $v;
342
+ }
343
+ $value = $new_value;
344
+ unset( $new_value );
345
+
346
+ }
347
+
348
+ }
349
+
350
+ }
351
+
352
+ return $value;
353
+
354
+ }
355
+
356
+ function translate_bases_in_rewrite_rules( $value ) {
357
+ global $sitepress, $sitepress_settings, $woocommerce_wpml;
358
+
359
+ if ( ! empty( $value ) ) {
360
+
361
+ $taxonomies = array( 'product_cat', 'product_tag' );
362
+
363
+ foreach ( $taxonomies as $taxonomy ) {
364
+ $slug_details = $this->get_translated_tax_slug( $taxonomy );
365
+
366
+ $string_language = $woocommerce_wpml->strings->get_string_language( $slug_details['slug'], $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
367
+ if ( $sitepress->get_current_language() == $string_language ) {
368
+ continue;
369
+ }
370
+
371
+ if ( $slug_details ) {
372
+
373
+ $slug_match = addslashes( ltrim($slug_details['slug'], '/') );
374
+ $slug_translation_match = ltrim($slug_details['translated_slug'], '/');
375
+
376
+ $buff_value = array();
377
+ foreach ( (array)$value as $k => $v ) {
378
+
379
+ if ( $slug_details['slug'] != $slug_details['translated_slug'] && preg_match( '#^[^/]*/?' . $slug_match . '/#', $k ) ) {
380
+ $k = preg_replace( '#^([^/]*)(/?)' . $slug_match . '/#', '$1$2' . $slug_translation_match . '/', $k );
381
+ }
382
+
383
+ $buff_value[$k] = $v;
384
+ }
385
+ $value = $buff_value;
386
+ unset( $buff_value );
387
+ }
388
+
389
+ }
390
+
391
+ // handle attributes
392
+ $wc_taxonomies = wc_get_attribute_taxonomies();
393
+ $wc_taxonomies_wc_format = array();
394
+ foreach ( $wc_taxonomies as $k => $v ) {
395
+ $wc_taxonomies_wc_format[] = 'pa_' . $v->attribute_name;
396
+ }
397
+
398
+ foreach ( $wc_taxonomies_wc_format as $taxonomy ) {
399
+ $taxonomy_obj = get_taxonomy( $taxonomy );
400
+
401
+ if ( isset( $taxonomy_obj->rewrite['slug'] ) ) {
402
+ $exp = explode( '/', trim( $taxonomy_obj->rewrite['slug'], '/' ) );
403
+ $slug = join( '/', array_slice( $exp, 0, count( $exp ) - 1 ) );
404
+
405
+ $attribute_slug = preg_replace( "#^$slug/#", '', $taxonomy_obj->rewrite['slug'] );
406
+ }
407
+
408
+ if ( isset( $slug ) ) {
409
+ $string_language = $woocommerce_wpml->strings->get_string_language($slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
410
+
411
+ if ($sitepress->get_current_language() != $string_language) {
412
+
413
+ $slug_translation = apply_filters('wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
414
+ if ($slug_translation) {
415
+
416
+ $attribute_slug_translation = apply_filters('wpml_translate_single_string', $attribute_slug, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $attribute_slug) );
417
+
418
+ $slug_match = addslashes( ltrim($slug, '/') );
419
+ $slug_translation_match = ltrim($slug_translation, '/');
420
+
421
+ $buff_value = array();
422
+ foreach ((array)$value as $k => $v) {
423
+ if ($slug != $slug_translation && preg_match('#^' . $slug_match . '/(.*)#', $k)) {
424
+ $k = preg_replace('#^' . $slug_match . '/(' . $attribute_slug .')/(.*)#', $slug_translation_match . '/' . $attribute_slug_translation . '/$2', $k);
425
+ }
426
+ $buff_value[$k] = $v;
427
+ }
428
+
429
+ $value = $buff_value;
430
+ unset($buff_value);
431
+
432
+ }
433
+
434
+ }
435
+ }
436
+
437
+ }
438
+
439
+
440
+
441
+ //filter shop page rewrite slug
442
+ $current_shop_id = wc_get_page_id( 'shop' );
443
+ $default_shop_id = apply_filters( 'translate_object_id', $current_shop_id, 'page', true, $sitepress->get_default_language() );
444
+
445
+ if ( is_null( get_post( $current_shop_id ) ) || is_null( get_post( $default_shop_id ) ) )
446
+ return $value;
447
+
448
+ $current_slug = get_post( $current_shop_id )->post_name;
449
+ $default_slug = get_post( $default_shop_id )->post_name;
450
+
451
+ if ( $current_slug != $default_slug ) {
452
+ $buff_value = array();
453
+ foreach ( (array)$value as $k => $v ) {
454
+
455
+ if( preg_match( '#^' . $default_slug . '/\?\$$#', $k ) ||
456
+ preg_match( '#^' . $default_slug . '/\(?feed#', $k ) ||
457
+ preg_match( '#^' . $default_slug . '/page#', $k )){
458
+
459
+ $k = preg_replace( '#^' . $default_slug . '/#', $current_slug . '/', $k );
460
+ }
461
+
462
+ $buff_value[$k] = $v;
463
+ }
464
+
465
+ $value = $buff_value;
466
+ unset( $buff_value );
467
+ }
468
+ }
469
+
470
+ return $value;
471
+ }
472
+
473
+ function translate_taxonomy_base( $termlink, $term, $taxonomy ) {
474
+ global $wp_rewrite, $wpml_term_translations, $sitepress;
475
+ static $no_recursion_flag;
476
+
477
+ // handles product categories, product tags and attributes
478
+
479
+ $wc_taxonomies = wc_get_attribute_taxonomies();
480
+ foreach ( $wc_taxonomies as $k => $v ) {
481
+ $wc_taxonomies_wc_format[] = 'pa_' . $v->attribute_name;
482
+ }
483
+
484
+ if ( ( $taxonomy == 'product_cat' || $taxonomy == 'product_tag' || ( !empty( $wc_taxonomies_wc_format ) && in_array( $taxonomy, $wc_taxonomies_wc_format ) ) ) && !$no_recursion_flag ) {
485
+
486
+ $cache_key = 'termlink#' . $taxonomy . '#' . $term->term_id;
487
+ if ( false && $link = wp_cache_get( $cache_key, 'terms' ) ) {
488
+ $termlink = $link;
489
+
490
+ } else {
491
+
492
+ $no_recursion_flag = false;
493
+
494
+ if ( !is_null( $wpml_term_translations ) ) {
495
+ $term_language = $term->term_id ? $wpml_term_translations->get_element_lang_code( $term->term_taxonomy_id ) : false;
496
+ } else {
497
+ $term_language = $term->term_id ? $sitepress->get_language_for_element( $term->term_taxonomy_id, 'tax_' . $taxonomy ) : false;
498
+ }
499
+
500
+ if ( $term_language ) {
501
+
502
+ $slug_details = $this->get_translated_tax_slug( $taxonomy, $term_language, true );
503
+
504
+ $base = $slug_details['slug'];
505
+ $base_translated = $slug_details['translated_slug'];
506
+
507
+ if ( !empty( $base_translated ) && $base_translated != $base && isset( $wp_rewrite->extra_permastructs[$taxonomy] ) ) {
508
+
509
+ $buff = $wp_rewrite->extra_permastructs[$taxonomy]['struct'];
510
+
511
+ // translate the attribute base
512
+ $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = preg_replace( '#^' . $base . '/(.*)#', $base_translated . '/$1', $wp_rewrite->extra_permastructs[$taxonomy]['struct'] );
513
+
514
+ // translate the attribute slug
515
+ if( isset($this->wc_permalinks['attribute_base']) && $this->wc_permalinks['attribute_base'] === $base ){
516
+
517
+ $attribute_slug = preg_replace('#^' . $base . '/([^/]+)/.+$#', '$1', $wp_rewrite->extra_permastructs[$taxonomy]['struct']);
518
+ $attribute_slug_default = preg_replace('#^pa_#', '', $taxonomy );
519
+ $attribute_slug_translation = apply_filters(
520
+ 'wpml_translate_single_string',
521
+ $attribute_slug,
522
+ $this->url_strings_context(),
523
+ $this->url_string_name( 'attribute_slug', $attribute_slug_default ),
524
+ $term_language
525
+ );
526
+
527
+ if( $attribute_slug_translation != $attribute_slug ){
528
+ $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = preg_replace(
529
+ '#^' . $base_translated . '/([^/]+)/(.+)$#',
530
+ $base_translated . '/' . $attribute_slug_translation . '/$2',
531
+ $wp_rewrite->extra_permastructs[$taxonomy]['struct']
532
+ );
533
+ }
534
+
535
+ }
536
+
537
+
538
+ $no_recursion_flag = true;
539
+ $termlink = get_term_link( $term, $taxonomy );
540
+
541
+ $wp_rewrite->extra_permastructs[$taxonomy]['struct'] = $buff;
542
+
543
+ }
544
+
545
+ }
546
+
547
+ $no_recursion_flag = false;
548
+
549
+ wp_cache_add( $cache_key, $termlink, 'terms', 0 );
550
+ }
551
+
552
+ }
553
+
554
+ return $termlink;
555
+ }
556
+
557
+ function get_translated_tax_slug( $taxonomy, $language = false, $return_gettext_slug = false ) {
558
+ global $sitepress, $woocommerce_wpml;
559
+
560
+ switch ( $taxonomy ) {
561
+ case 'product_tag':
562
+
563
+ if( !empty( $this->wc_permalinks['tag_base'] ) ) {
564
+ $slug = $gettext_slug = trim($this->wc_permalinks['tag_base'], '/');
565
+ }else{
566
+ $slug = 'product-tag';
567
+ if( $return_gettext_slug ){
568
+ $gettext_slug = $this->default_product_tag_gettext_base;
569
+ }
570
+ }
571
+
572
+ $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
573
+
574
+ break;
575
+
576
+ case 'product_cat':
577
+
578
+ if( !empty( $this->wc_permalinks['category_base'] ) ) {
579
+ $slug = $gettext_slug = trim( $this->wc_permalinks['category_base'], '/' );
580
+ }else{
581
+ $slug = 'product-category';
582
+ if( $return_gettext_slug ){
583
+ $gettext_slug = $this->default_product_category_gettext_base;
584
+ }
585
+ }
586
+
587
+ $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ) );
588
+
589
+ break;
590
+
591
+ default:
592
+ $slug = $gettext_slug = trim( $this->wc_permalinks['attribute_base'], '/' );
593
+
594
+ $string_language = $woocommerce_wpml->strings->get_string_language( $slug, $this->url_strings_context(), $this->url_string_name( 'attribute' ) );
595
+
596
+ $taxonomy = 'attribute';
597
+
598
+ break;
599
+ }
600
+
601
+ if ( !$language ) {
602
+ $language = $sitepress->get_current_language();
603
+ }
604
+
605
+ if ( $slug && $language != 'all' && $language != $string_language ) {
606
+
607
+ $slug_translation = apply_filters( 'wpml_translate_single_string', $slug, $this->url_strings_context(), $this->url_string_name( $taxonomy ), $language, false );
608
+
609
+ return array( 'slug' => $return_gettext_slug ? $gettext_slug : $slug, 'translated_slug' => $slug_translation );
610
+ }
611
+
612
+ return array( 'slug' => $return_gettext_slug ? $gettext_slug : $slug, 'translated_slug' => $return_gettext_slug && $language != $string_language ? $gettext_slug : $slug );
613
+
614
+ }
615
+
616
+ function get_base_translation ( $base, $language ){
617
+ global $woocommerce_wpml;
618
+
619
+ // case of attribute slugs
620
+ if( strpos( $base, 'attribute_slug-' ) === 0 ){
621
+ $slug = preg_replace( '#^attribute_slug-#', '', $base );
622
+ $base = 'attribute_slug';
623
+ }
624
+
625
+ switch ( $base ) {
626
+ case 'product':
627
+ $slug = $this->get_woocommerce_product_base();
628
+ $return['name'] = __('Product Base', 'woocommerce-multilingual');
629
+ break;
630
+
631
+ case 'product_tag':
632
+ $slug = !empty( $this->wc_permalinks['tag_base'] ) ? trim( $this->wc_permalinks['tag_base'], '/' ) : 'product-tag';
633
+ $return['name'] = __('Product Tag Base', 'woocommerce-multilingual');
634
+ break;
635
+
636
+ case 'product_cat':
637
+ $slug = !empty( $this->wc_permalinks['category_base'] ) ? trim( $this->wc_permalinks['category_base'], '/' ) : 'product-category';
638
+ $return['name'] = __('Product Category Base', 'woocommerce-multilingual');
639
+ break;
640
+
641
+ case 'attribute':
642
+ $slug = trim( $this->wc_permalinks['attribute_base'], '/' );
643
+ $return['name'] = __('Product Attribute Base', 'woocommerce-multilingual');
644
+ break;
645
+
646
+ case 'attribute_slug':
647
+ $return['name'] = __('Attribute Slug', 'woocommerce-multilingual');
648
+ $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( $base, $slug ) );
649
+ break;
650
+
651
+ default:
652
+ $endpoints = WC()->query->query_vars;
653
+ $slug = isset( $endpoints[ $base ] ) ? $endpoints[ $base ] : false ;
654
+ $return['name'] = sprintf( __('Endpoint: %s', 'woocommerce-multilingual'), $base);
655
+ $string_id = icl_get_string_id( $slug, 'WooCommerce Endpoints', $base );
656
+ break;
657
+ }
658
+
659
+ $return['original_value'] = $slug;
660
+ if( !isset( $string_id ) ){
661
+ $string_id = icl_get_string_id( $slug, $this->url_strings_context(), $this->url_string_name( $base ) );
662
+ }
663
+ $base_translations = icl_get_string_translations_by_id( $string_id );
664
+
665
+ $return['translated_base'] = '';
666
+ if( isset($base_translations[$language])){
667
+ if( $base_translations[$language]['status'] == ICL_TM_COMPLETE ){
668
+ $return['translated_base'] = $base_translations[$language]['value'];
669
+ }elseif($base_translations[$language]['status'] == ICL_TM_NEEDS_UPDATE){
670
+ $return['translated_base'] = $base_translations[$language]['value'];
671
+ $return['needs_update '] = true;
672
+ }
673
+ }
674
+
675
+ return $return;
676
+
677
+ }
678
+
679
+ function get_source_slug_language( $base ){
680
+ global $sitepress, $woocommerce_wpml;
681
+
682
+ if( $base == 'shop' ){
683
+ $source_language = $sitepress->get_language_for_element( get_option('woocommerce_shop_page_id' ) , 'post_page' );
684
+ }elseif( in_array( $base, array( 'product','product_cat','product_tag','attribute') ) ){
685
+ $source_language = $woocommerce_wpml->strings->get_string_language( $base, $this->url_strings_context(), $this->url_string_name( $base ) );
686
+ }else{
687
+ $source_language = $woocommerce_wpml->strings->get_string_language( $base, 'WooCommerce Endpoints', $base );
688
+ }
689
+
690
+ return $source_language;
691
+ }
692
+
693
+
694
+ function wcml_update_base_translation(){
695
+
696
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
697
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_update_base_translation')){
698
+ die('Invalid nonce');
699
+ }
700
+
701
+ global $wpdb, $woocommerce_wpml, $sitepress;
702
+
703
+ $original_base = $_POST['base'];
704
+ $original_base_value = $_POST['base_value'];
705
+ $base_translation = $_POST['base_translation'];
706
+ $language = $_POST['language'];
707
+
708
+ if( $original_base == 'shop' ){
709
+ $original_shop_id = get_option('woocommerce_shop_page_id' );
710
+ $translated_shop_id = apply_filters( 'translate_object_id', $original_shop_id , 'page', false, $language );
711
+
712
+ if( !is_null( $translated_shop_id ) ){
713
+
714
+ $trnsl_shop_obj = get_post( $translated_shop_id );
715
+ $new_slug = wp_unique_post_slug( sanitize_title( $_POST['base_translation'] ), $translated_shop_id, $trnsl_shop_obj->post_status, $trnsl_shop_obj->post_type, $trnsl_shop_obj->post_parent );
716
+ $wpdb->update( $wpdb->posts, array( 'post_name' => $new_slug ), array( 'ID' => $translated_shop_id ) );
717
+
718
+ }
719
+
720
+ }else{
721
+ if( in_array( $original_base, array( 'product','product_cat','product_tag','attribute') ) ) {
722
+ $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( $original_base ) );
723
+ }elseif( strpos( $original_base, 'attribute_slug-' ) === 0 ){
724
+ $slug = preg_replace( '#^attribute_slug-#', '', $original_base );
725
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ), $slug );
726
+ $string_id = icl_get_string_id( $original_base_value, $this->url_strings_context(), $this->url_string_name( 'attribute_slug', $slug ) );
727
+ }else{
728
+ $string_id = icl_get_string_id( $original_base_value, 'WooCommerce Endpoints', $original_base );
729
+ if( !$string_id && function_exists( 'icl_register_string' ) ){
730
+ $string_id = icl_register_string( 'WooCommerce Endpoints', $original_base, $original_base_value );
731
+ }
732
+ $woocommerce_wpml->endpoints->add_endpoints();
733
+ $woocommerce_wpml->endpoints->flush_rules_for_endpoints_translations();
734
+ }
735
+
736
+ icl_add_string_translation( $string_id, $language, $base_translation, ICL_STRING_TRANSLATION_COMPLETE );
737
+
738
+ }
739
+
740
+ $edit_base = new WCML_Store_URLs_Edit_Base_UI( $original_base, $language, $woocommerce_wpml, $sitepress );
741
+ $html = $edit_base->get_view();
742
+
743
+ echo json_encode($html);
744
+ die();
745
+
746
+
747
+ }
748
+
749
+ // return correct redirect URL for WC standard taxonomies when pretty permalink uses with lang as parameter in WPML
750
+ function check_wc_tax_url_on_redirect( $redirect_url, $requested_url ){
751
+ global $wp_query;
752
+
753
+ if( is_tax() ){
754
+ $original = @parse_url( $requested_url );
755
+ parse_str( $original['query'], $query_args ) ;
756
+ if( ( isset( $query_args[ 'product_cat' ] ) || isset( $query_args[ 'product_tag' ] ) ) && isset ( $query_args[ 'lang' ] ) ){
757
+ $obj = $wp_query->get_queried_object();
758
+ $tax_url = get_term_link( (int)$obj->term_id, $obj->taxonomy ) ;
759
+
760
+ return $tax_url;
761
+ }
762
+ }
763
+
764
+ return $redirect_url;
765
+ }
766
+
767
+ public function translate_query_var_for_product($public_query_vars){
768
+ global $woocommerce_wpml, $sitepress;
769
+
770
+ $product_permalink = $woocommerce_wpml->strings->product_permalink_slug();
771
+ $string_language = $woocommerce_wpml->strings->get_string_language( $product_permalink, $this->url_strings_context(), $this->url_string_name('product') );
772
+
773
+ if( $sitepress->get_current_language() != $string_language ){
774
+ $translated_slug = $this->get_translated_product_base_by_lang( false,$product_permalink );
775
+
776
+ if(isset($_GET[$translated_slug])){
777
+ $buff = $_GET[$translated_slug];
778
+ unset($_GET[$translated_slug]);
779
+ $_GET[$product_permalink] = $buff;
780
+ }
781
+
782
+ }
783
+
784
+ return $public_query_vars;
785
+ }
786
+
787
+ public function get_translated_product_base_by_lang($language = false, $product_slug = false){
788
+ global $woocommerce_wpml;
789
+
790
+ if(!$language){
791
+ global $sitepress;
792
+ $language = $sitepress->get_current_language();
793
+
794
+ }
795
+
796
+ if(!$product_slug){
797
+ $product_slug = $woocommerce_wpml->strings->product_permalink_slug();
798
+ }
799
+
800
+ if ( version_compare( WPML_ST_VERSION, '2.3', '>=' ) ) {
801
+ $translated_slug = apply_filters( 'wpml_get_translated_slug', $product_slug, 'product' , $language );
802
+ }elseif ( apply_filters( 'wpml_slug_translation_available', false) ) {
803
+ $translated_slug = apply_filters( 'wpml_get_translated_slug', 'product' , $language );
804
+ } else {
805
+ $translated_slug = apply_filters( 'wpml_translate_single_string', $product_slug, $this->url_strings_context(), $this->url_string_name( 'product' ) );
806
+ }
807
+
808
+ return $translated_slug;
809
+ }
810
+
811
+ public function encode_shop_slug($location, $status){
812
+ if(get_post_type(get_query_var('p')) == 'product'){
813
+ global $sitepress;
814
+ $language = $sitepress->get_language_for_element(get_query_var('p'), 'post_product');
815
+ $base_slug = $this->get_translated_product_base_by_lang($language);
816
+
817
+ $location = str_replace($base_slug , urlencode($base_slug),$location);
818
+ }
819
+
820
+ return $location;
821
+ }
822
  }
inc/class-wcml-wc-gateways.php CHANGED
@@ -1,187 +1,187 @@
1
- <?php
2
-
3
- class WCML_WC_Gateways{
4
-
5
- private $current_language;
6
- private $sitepress;
7
-
8
- function __construct( &$woocommerce_wpml, &$sitepress ){
9
-
10
- $this->sitepress = $sitepress;
11
- $this->woocommerce_wpml = $woocommerce_wpml;
12
-
13
- add_action( 'init', array( $this, 'init' ), 11 );
14
-
15
- $this->current_language = $sitepress->get_current_language();
16
- if( $this->current_language == 'all' ){
17
- $this->current_language = $sitepress->get_default_language();
18
- }
19
-
20
- add_filter( 'woocommerce_payment_gateways', array( $this, 'loaded_woocommerce_payment_gateways' ) );
21
-
22
- }
23
-
24
- function init(){
25
- global $pagenow;
26
-
27
- add_filter('woocommerce_gateway_title', array($this, 'translate_gateway_title'), 10, 2);
28
- add_filter('woocommerce_gateway_description', array($this, 'translate_gateway_description'), 10, 2);
29
-
30
- if( is_admin() && $pagenow == 'admin.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'checkout' ){
31
- add_action( 'admin_footer', array($this, 'show_language_links_for_gateways' ) );
32
- $this->register_and_set_gateway_strings_language();
33
- }
34
-
35
- }
36
-
37
-
38
- function loaded_woocommerce_payment_gateways( $load_gateways ){
39
-
40
- foreach( $load_gateways as $key => $gateway ){
41
-
42
- $load_gateway = is_string( $gateway ) ? new $gateway() : $gateway;
43
- $this->payment_gateways_filters( $load_gateway );
44
- $load_gateways[ $key ] = $load_gateway;
45
-
46
- }
47
-
48
- return $load_gateways;
49
- }
50
-
51
- function payment_gateways_filters( $gateway ){
52
-
53
- if( isset( $gateway->id ) ){
54
- $gateway_id = $gateway->id;
55
- $this->translate_gateway_strings( $gateway );
56
- }
57
-
58
- }
59
-
60
- function translate_gateway_strings( $gateway ){
61
-
62
- if( isset( $gateway->enabled ) && $gateway->enabled != 'no' ){
63
-
64
- if( isset( $gateway->instructions ) ){
65
- $gateway->instructions = $this->translate_gateway_instructions( $gateway->instructions, $gateway->id );
66
- }
67
-
68
- if( isset( $gateway->description ) ){
69
- $gateway->description = $this->translate_gateway_description( $gateway->description, $gateway->id );
70
- }
71
-
72
- if( isset( $gateway->title ) ){
73
- $gateway->title = $this->translate_gateway_title( $gateway->title, $gateway->id );
74
- }
75
- }
76
-
77
- return $gateway;
78
-
79
- }
80
-
81
- function translate_gateway_title( $title, $gateway_id, $language = false ) {
82
- $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $gateway_id .'_gateway_title', $language ? $language : $this->current_language );
83
- return $title;
84
- }
85
-
86
- function translate_gateway_description( $description, $gateway_id) {
87
- $description = apply_filters( 'wpml_translate_single_string', $description, 'woocommerce', $gateway_id . '_gateway_description', $this->current_language );
88
- return $description;
89
- }
90
-
91
- function translate_gateway_instructions( $instructions, $gateway_id ){
92
- $instructions = apply_filters( 'wpml_translate_single_string', $instructions, 'woocommerce', $gateway_id . '_gateway_instructions', $this->current_language );
93
- return $instructions;
94
- }
95
-
96
- function show_language_links_for_gateways(){
97
-
98
- $text_keys = array(
99
- 'title',
100
- 'description',
101
- 'instructions'
102
- );
103
- $wc_payment_gateways = WC_Payment_Gateways::instance();
104
-
105
- foreach( $wc_payment_gateways->payment_gateways() as $payment_gateway ) {
106
-
107
- if( isset( $_GET['section'] ) && $_GET['section'] == $payment_gateway->id ){
108
-
109
- foreach( $text_keys as $text_key ) {
110
-
111
- if ( isset( $payment_gateway->settings[ $text_key ] ) ) {
112
- $setting_value = $payment_gateway->settings[ $text_key ];
113
- }elseif( $text_key === 'instructions' ){
114
- $setting_value = $payment_gateway->description;
115
- }else{
116
- $setting_value = $payment_gateway->$text_key;
117
- }
118
-
119
- $input_name = $payment_gateway->plugin_id.$payment_gateway->id.'_'.$text_key;
120
- $gateway_option = $payment_gateway->plugin_id.$payment_gateway->id.'_settings';
121
-
122
- $lang_selector = new WPML_Simple_Language_Selector( $this->sitepress );
123
- $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'woocommerce', $payment_gateway->id .'_gateway_'. $text_key );
124
- if( is_null( $language ) ) {
125
- $language = $this->sitepress->get_default_language();
126
- }
127
-
128
- $lang_selector->render( array(
129
- 'id' => $gateway_option.'_'.$text_key.'_language_selector',
130
- 'name' => 'wcml_lang-'.$gateway_option.'-'.$text_key,
131
- 'selected' => $language,
132
- 'show_please_select' => false,
133
- 'echo' => true,
134
- 'style' => 'width: 18%;float: left;margin-top: 3px;'
135
- )
136
- );
137
-
138
- $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=woocommerce&search='. esc_attr( $setting_value ) );
139
- if( $text_key === 'title' || $payment_gateway->id === 'paypal' ){
140
- $input_type = 'input';
141
- }else{
142
- $input_type = 'textarea';
143
- }
144
- ?>
145
- <script>
146
- var input = jQuery('<?php echo $input_type ?>[name="<?php echo $input_name ?>"]');
147
- if ( input.length ) {
148
- input.parent().append('<div class="translation_controls"></div>');
149
- input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
150
- jQuery('#<?php echo $gateway_option.'_'.$text_key.'_language_selector' ?>').prependTo( input.parent().find('.translation_controls') );
151
- }
152
- </script>
153
- <?php }
154
- }
155
- }
156
- }
157
-
158
- function register_and_set_gateway_strings_language(){
159
-
160
- foreach( $_POST as $key => $language ){
161
-
162
- if( substr( $key, 0, 9 ) == 'wcml_lang' ){
163
-
164
- $gateway_string = explode( '-', $key );
165
-
166
- if( isset( $gateway_string[2] ) ){
167
-
168
- $gateway_key = str_replace( '_settings', '', $gateway_string[1] );
169
- $gateway_string_name = str_replace( 'woocommerce_', '', $gateway_key ) .'_gateway_'. $gateway_string[2];
170
- $gateway_key .= '_'.$gateway_string[2];
171
-
172
- $gateway_settings = get_option( $gateway_string[1], true );
173
-
174
- $string_value = isset( $_POST[ $gateway_key ] ) ? $_POST[ $gateway_key ] : '';
175
- $opt_string_value = isset( $gateway_settings[ $gateway_string[2] ] ) ? $gateway_settings[ $gateway_string[2] ] : $string_value;
176
-
177
- $context = 'woocommerce';
178
-
179
- do_action( 'wpml_register_single_string', $context, $gateway_string_name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
180
-
181
- $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $gateway_string_name, $language );
182
- }
183
- }
184
- }
185
- }
186
-
187
  }
1
+ <?php
2
+
3
+ class WCML_WC_Gateways{
4
+
5
+ private $current_language;
6
+ private $sitepress;
7
+
8
+ function __construct( &$woocommerce_wpml, &$sitepress ){
9
+
10
+ $this->sitepress = $sitepress;
11
+ $this->woocommerce_wpml = $woocommerce_wpml;
12
+
13
+ add_action( 'init', array( $this, 'init' ), 11 );
14
+
15
+ $this->current_language = $sitepress->get_current_language();
16
+ if( $this->current_language == 'all' ){
17
+ $this->current_language = $sitepress->get_default_language();
18
+ }
19
+
20
+ add_filter( 'woocommerce_payment_gateways', array( $this, 'loaded_woocommerce_payment_gateways' ) );
21
+
22
+ }
23
+
24
+ function init(){
25
+ global $pagenow;
26
+
27
+ add_filter('woocommerce_gateway_title', array($this, 'translate_gateway_title'), 10, 2);
28
+ add_filter('woocommerce_gateway_description', array($this, 'translate_gateway_description'), 10, 2);
29
+
30
+ if( is_admin() && $pagenow == 'admin.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'checkout' ){
31
+ add_action( 'admin_footer', array($this, 'show_language_links_for_gateways' ) );
32
+ $this->register_and_set_gateway_strings_language();
33
+ }
34
+
35
+ }
36
+
37
+
38
+ function loaded_woocommerce_payment_gateways( $load_gateways ){
39
+
40
+ foreach( $load_gateways as $key => $gateway ){
41
+
42
+ $load_gateway = is_string( $gateway ) ? new $gateway() : $gateway;
43
+ $this->payment_gateways_filters( $load_gateway );
44
+ $load_gateways[ $key ] = $load_gateway;
45
+
46
+ }
47
+
48
+ return $load_gateways;
49
+ }
50
+
51
+ function payment_gateways_filters( $gateway ){
52
+
53
+ if( isset( $gateway->id ) ){
54
+ $gateway_id = $gateway->id;
55
+ $this->translate_gateway_strings( $gateway );
56
+ }
57
+
58
+ }
59
+
60
+ function translate_gateway_strings( $gateway ){
61
+
62
+ if( isset( $gateway->enabled ) && $gateway->enabled != 'no' ){
63
+
64
+ if( isset( $gateway->instructions ) ){
65
+ $gateway->instructions = $this->translate_gateway_instructions( $gateway->instructions, $gateway->id );
66
+ }
67
+
68
+ if( isset( $gateway->description ) ){
69
+ $gateway->description = $this->translate_gateway_description( $gateway->description, $gateway->id );
70
+ }
71
+
72
+ if( isset( $gateway->title ) ){
73
+ $gateway->title = $this->translate_gateway_title( $gateway->title, $gateway->id );
74
+ }
75
+ }
76
+
77
+ return $gateway;
78
+
79
+ }
80
+
81
+ function translate_gateway_title( $title, $gateway_id, $language = false ) {
82
+ $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $gateway_id .'_gateway_title', $language ? $language : $this->current_language );
83
+ return $title;
84
+ }
85
+
86
+ function translate_gateway_description( $description, $gateway_id) {
87
+ $description = apply_filters( 'wpml_translate_single_string', $description, 'woocommerce', $gateway_id . '_gateway_description', $this->current_language );
88
+ return $description;
89
+ }
90
+
91
+ function translate_gateway_instructions( $instructions, $gateway_id ){
92
+ $instructions = apply_filters( 'wpml_translate_single_string', $instructions, 'woocommerce', $gateway_id . '_gateway_instructions', $this->current_language );
93
+ return $instructions;
94
+ }
95
+
96
+ function show_language_links_for_gateways(){
97
+
98
+ $text_keys = array(
99
+ 'title',
100
+ 'description',
101
+ 'instructions'
102
+ );
103
+ $wc_payment_gateways = WC_Payment_Gateways::instance();
104
+
105
+ foreach( $wc_payment_gateways->payment_gateways() as $payment_gateway ) {
106
+
107
+ if( isset( $_GET['section'] ) && $_GET['section'] == $payment_gateway->id ){
108
+
109
+ foreach( $text_keys as $text_key ) {
110
+
111
+ if ( isset( $payment_gateway->settings[ $text_key ] ) ) {
112
+ $setting_value = $payment_gateway->settings[ $text_key ];
113
+ }elseif( $text_key === 'instructions' ){
114
+ $setting_value = $payment_gateway->description;
115
+ }else{
116
+ $setting_value = $payment_gateway->$text_key;
117
+ }
118
+
119
+ $input_name = $payment_gateway->plugin_id.$payment_gateway->id.'_'.$text_key;
120
+ $gateway_option = $payment_gateway->plugin_id.$payment_gateway->id.'_settings';
121
+
122
+ $lang_selector = new WPML_Simple_Language_Selector( $this->sitepress );
123
+ $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'woocommerce', $payment_gateway->id .'_gateway_'. $text_key );
124
+ if( is_null( $language ) ) {
125
+ $language = $this->sitepress->get_default_language();
126
+ }
127
+
128
+ $lang_selector->render( array(
129
+ 'id' => $gateway_option.'_'.$text_key.'_language_selector',
130
+ 'name' => 'wcml_lang-'.$gateway_option.'-'.$text_key,
131
+ 'selected' => $language,
132
+ 'show_please_select' => false,
133
+ 'echo' => true,
134
+ 'style' => 'width: 18%;float: left;margin-top: 3px;'
135
+ )
136
+ );
137
+
138
+ $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=woocommerce&search='. esc_attr( $setting_value ) );
139
+ if( $text_key === 'title' || $payment_gateway->id === 'paypal' ){
140
+ $input_type = 'input';
141
+ }else{
142
+ $input_type = 'textarea';
143
+ }
144
+ ?>
145
+ <script>
146
+ var input = jQuery('<?php echo $input_type ?>[name="<?php echo $input_name ?>"]');
147
+ if ( input.length ) {
148
+ input.parent().append('<div class="translation_controls"></div>');
149
+ input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
150
+ jQuery('#<?php echo $gateway_option.'_'.$text_key.'_language_selector' ?>').prependTo( input.parent().find('.translation_controls') );
151
+ }
152
+ </script>
153
+ <?php }
154
+ }
155
+ }
156
+ }
157
+
158
+ function register_and_set_gateway_strings_language(){
159
+
160
+ foreach( $_POST as $key => $language ){
161
+
162
+ if( substr( $key, 0, 9 ) == 'wcml_lang' ){
163
+
164
+ $gateway_string = explode( '-', $key );
165
+
166
+ if( isset( $gateway_string[2] ) ){
167
+
168
+ $gateway_key = str_replace( '_settings', '', $gateway_string[1] );
169
+ $gateway_string_name = str_replace( 'woocommerce_', '', $gateway_key ) .'_gateway_'. $gateway_string[2];
170
+ $gateway_key .= '_'.$gateway_string[2];
171
+
172
+ $gateway_settings = get_option( $gateway_string[1], true );
173
+
174
+ $string_value = isset( $_POST[ $gateway_key ] ) ? $_POST[ $gateway_key ] : '';
175
+ $opt_string_value = isset( $gateway_settings[ $gateway_string[2] ] ) ? $gateway_settings[ $gateway_string[2] ] : $string_value;
176
+
177
+ $context = 'woocommerce';
178
+
179
+ do_action( 'wpml_register_single_string', $context, $gateway_string_name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
180
+
181
+ $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $gateway_string_name, $language );
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
  }
inc/class-wcml-wc-shipping.php CHANGED
@@ -1,228 +1,228 @@
1
- <?php
2
-
3
- class WCML_WC_Shipping{
4
-
5
- private $current_language;
6
- private $sitepress;
7
-
8
- function __construct( &$sitepress ){
9
-
10
- $this->sitepress = $sitepress;
11
-
12
- add_filter('woocommerce_package_rates', array($this, 'translate_shipping_methods_in_package'));
13
- add_action('woocommerce_tax_rate_added', array($this, 'register_tax_rate_label_string'), 10, 2 );
14
- add_filter('woocommerce_rate_label',array($this,'translate_woocommerce_rate_label'));
15
-
16
- $this->shipping_methods_filters();
17
- add_action('wp_ajax_woocommerce_shipping_zone_methods_save_settings', array( $this, 'save_shipping_zone_method_from_ajax'), 9 );
18
-
19
- $this->current_language = $this->sitepress->get_current_language();
20
- if( $this->current_language == 'all' ){
21
- $this->current_language = $this->sitepress->get_default_language();
22
- }
23
-
24
- add_action( 'icl_save_term_translation', array( $this, 'sync_class_costs_for_new_shipping_classes' ), 100, 2 );
25
-
26
-
27
- add_filter( 'pre_update_option_woocommerce_flat_rate_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
28
- add_filter( 'pre_update_option_woocommerce_international_delivery_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
29
- add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs_from_ajax'), 9);
30
- }
31
-
32
- function shipping_methods_filters(){
33
-
34
- $shipping_methods = WC()->shipping->get_shipping_methods();
35
-
36
- foreach ( $shipping_methods as $shipping_method ) {
37
-
38
- if( isset( $shipping_method->id ) ){
39
- $shipping_method_id = $shipping_method->id;
40
- }else{
41
- continue;
42
- }
43
-
44
- if( ( defined('WC_VERSION') && version_compare( WC_VERSION , '2.6', '<' ) ) ){
45
- add_filter( 'woocommerce_settings_api_sanitized_fields_'.$shipping_method_id, array( $this, 'register_shipping_strings' ) );
46
- }else{
47
- add_filter( 'woocommerce_shipping_' . $shipping_method_id . '_instance_settings_values', array( $this, 'register_zone_shipping_strings' ),9,2 );
48
- }
49
-
50
- add_filter( 'option_woocommerce_'.$shipping_method_id.'_settings', array( $this, 'translate_shipping_strings' ), 9, 2 );
51
- }
52
- }
53
-
54
- function save_shipping_zone_method_from_ajax(){
55
- foreach( $_POST['data'] as $key => $value ){
56
- if( strstr( $key, '_title' ) ){
57
- $shipping_id = str_replace( 'woocommerce_', '', $key );
58
- $shipping_id = str_replace( '_title', '', $shipping_id );
59
- $this->register_shipping_title( $shipping_id.$_POST['instance_id'], $value );
60
- break;
61
- }
62
- }
63
- }
64
-
65
- function register_zone_shipping_strings( $instance_settings, $object ){
66
- if( !empty( $instance_settings['title'] ) ){
67
- $this->register_shipping_title( $object->id.$object->instance_id, $instance_settings['title'] );
68
-
69
- $instance_settings = $this->sync_flat_rate_class_cost( $object->get_post_data(), $instance_settings );
70
- }
71
-
72
- return $instance_settings;
73
- }
74
-
75
- function register_shipping_strings( $fields ){
76
- $shipping = WC_Shipping::instance();
77
-
78
- foreach( $shipping->get_shipping_methods() as $shipping_method ){
79
- if( isset( $_POST['woocommerce_'.$shipping_method->id.'_enabled'] ) ){
80
- $shipping_method_id = $shipping_method->id;
81
- break;
82
- }
83
- }
84
-
85
- if( isset( $shipping_method_id ) ){
86
- $this->register_shipping_title( $shipping_method_id, $fields['title'] );
87
- }
88
-
89
- return $fields;
90
- }
91
-
92
- function register_shipping_title( $shipping_method_id, $title ){
93
- do_action( 'wpml_register_single_string', 'woocommerce', $shipping_method_id .'_shipping_method_title', $title );
94
- }
95
-
96
- function translate_shipping_strings( $value, $option = false ){
97
-
98
- if( $option && isset( $value['enabled']) && $value['enabled'] == 'no' ){
99
- return $value;
100
- }
101
-
102
- $shipping_id = str_replace( 'woocommerce_', '', $option );
103
- $shipping_id = str_replace( '_settings', '', $shipping_id );
104
-
105
- if( isset( $value['title'] ) ){
106
- $value['title'] = $this->translate_shipping_method_title( $value['title'], $shipping_id );
107
- }
108
-
109
- return $value;
110
- }
111
-
112
- function translate_shipping_methods_in_package( $available_methods ){
113
-
114
- foreach($available_methods as $key => $method){
115
- $available_methods[$key]->label = $this->translate_shipping_method_title( $method->label, $key );
116
- }
117
-
118
- return $available_methods;
119
- }
120
-
121
- function translate_shipping_method_title( $title, $shipping_id, $language = false ) {
122
- $shipping_id = str_replace( ':', '', $shipping_id );
123
- $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $shipping_id .'_shipping_method_title', $language ? $language : $this->current_language );
124
-
125
- return $title;
126
- }
127
-
128
- function translate_woocommerce_rate_label( $label ){
129
-
130
- $label = apply_filters( 'wpml_translate_single_string', $label, 'woocommerce taxes', $label );
131
-
132
- return $label;
133
- }
134
-
135
- function register_tax_rate_label_string( $id, $tax_rate ){
136
-
137
- if( !empty( $tax_rate['tax_rate_name'] ) ){
138
- do_action('wpml_register_single_string', 'woocommerce taxes', $tax_rate['tax_rate_name'] , $tax_rate['tax_rate_name'] );
139
- }
140
-
141
- }
142
-
143
- function sync_class_costs_for_new_shipping_classes( $original_tax, $result ){
144
- //update flat rate options for shipping classes
145
- if( $original_tax->taxonomy == 'product_shipping_class' ){
146
-
147
- $settings = get_option( 'woocommerce_flat_rate_settings' );
148
- if( is_array( $settings ) ){
149
- update_option( 'woocommerce_flat_rate_settings', $this->update_woocommerce_shipping_settings_for_class_costs( $settings ) );
150
- }
151
-
152
- $settings = get_option( 'woocommerce_international_delivery_settings' );
153
- if( is_array( $settings ) ){
154
- update_option( 'woocommerce_international_delivery_settings', $this->update_woocommerce_shipping_settings_for_class_costs( $settings ) );
155
- }
156
-
157
- }
158
- }
159
-
160
- function update_woocommerce_shipping_settings_for_class_costs( $settings ){
161
-
162
- remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
163
- foreach( $settings as $setting_key => $value ){
164
-
165
- if( substr($setting_key, 0, 11) == 'class_cost_' ){
166
-
167
- $shipp_class_key = substr($setting_key, 11 );
168
-
169
- if( is_numeric( $shipp_class_key ) ){
170
- $shipp_class = get_term( $shipp_class_key, 'product_shipping_class' );
171
- }else{
172
- $shipp_class = get_term_by( 'slug', $shipp_class_key, 'product_shipping_class' );
173
- }
174
-
175
- $trid = $this->sitepress->get_element_trid( $shipp_class->term_taxonomy_id, 'tax_product_shipping_class' );
176
-
177
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_shipping_class' );
178
-
179
- foreach( $translations as $translation ){
180
-
181
- $tr_shipp_class = get_term_by( 'term_taxonomy_id', $translation->element_id, 'product_shipping_class' );
182
-
183
- if( is_numeric( $shipp_class_key ) ){
184
- $settings[ 'class_cost_'.$tr_shipp_class->term_id ] = $value;
185
- }else{
186
- $settings[ 'class_cost_'.$tr_shipp_class->slug ] = $value;
187
- }
188
-
189
- }
190
-
191
- }
192
-
193
- }
194
- add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
195
-
196
- return $settings;
197
- }
198
-
199
- function update_woocommerce_shipping_settings_for_class_costs_from_ajax(){
200
-
201
- if (isset($_POST['data']['woocommerce_flat_rate_type']) && $_POST['data']['woocommerce_flat_rate_type'] == 'class') {
202
-
203
- $flat_rate_setting_id = 'woocommerce_flat_rate_' . $_POST['data']['instance_id'] . '_settings';
204
- $settings = get_option( $flat_rate_setting_id, true );
205
-
206
- $settings = $this->sync_flat_rate_class_cost( $_POST['data'], $settings );
207
-
208
- update_option($flat_rate_setting_id, $settings);
209
- }
210
- }
211
-
212
- function sync_flat_rate_class_cost( $data, $inst_settings ){
213
-
214
- $settings = array();
215
- foreach ( $data as $key => $value ) {
216
- if ( substr( $key, 0, 33) == 'woocommerce_flat_rate_class_cost_' ) {
217
- $settings[ substr( $key, 22 ) ] = $value;
218
- }
219
- }
220
-
221
- $updated_costs_settings = $this->update_woocommerce_shipping_settings_for_class_costs( $settings );
222
-
223
- $inst_settings = is_array( $inst_settings ) ? array_replace( $inst_settings, $updated_costs_settings ) : $updated_costs_settings;
224
-
225
- return $inst_settings;
226
- }
227
-
228
  }
1
+ <?php
2
+
3
+ class WCML_WC_Shipping{
4
+
5
+ private $current_language;
6
+ private $sitepress;
7
+
8
+ function __construct( &$sitepress ){
9
+
10
+ $this->sitepress = $sitepress;
11
+
12
+ add_filter('woocommerce_package_rates', array($this, 'translate_shipping_methods_in_package'));
13
+ add_action('woocommerce_tax_rate_added', array($this, 'register_tax_rate_label_string'), 10, 2 );
14
+ add_filter('woocommerce_rate_label',array($this,'translate_woocommerce_rate_label'));
15
+
16
+ $this->shipping_methods_filters();
17
+ add_action('wp_ajax_woocommerce_shipping_zone_methods_save_settings', array( $this, 'save_shipping_zone_method_from_ajax'), 9 );
18
+
19
+ $this->current_language = $this->sitepress->get_current_language();
20
+ if( $this->current_language == 'all' ){
21
+ $this->current_language = $this->sitepress->get_default_language();
22
+ }
23
+
24
+ add_action( 'icl_save_term_translation', array( $this, 'sync_class_costs_for_new_shipping_classes' ), 100, 2 );
25
+
26
+
27
+ add_filter( 'pre_update_option_woocommerce_flat_rate_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
28
+ add_filter( 'pre_update_option_woocommerce_international_delivery_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs' ) );
29
+ add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', array( $this, 'update_woocommerce_shipping_settings_for_class_costs_from_ajax'), 9);
30
+ }
31
+
32
+ function shipping_methods_filters(){
33
+
34
+ $shipping_methods = WC()->shipping->get_shipping_methods();
35
+
36
+ foreach ( $shipping_methods as $shipping_method ) {
37
+
38
+ if( isset( $shipping_method->id ) ){
39
+ $shipping_method_id = $shipping_method->id;
40
+ }else{
41
+ continue;
42
+ }
43
+
44
+ if( ( defined('WC_VERSION') && version_compare( WC_VERSION , '2.6', '<' ) ) ){
45
+ add_filter( 'woocommerce_settings_api_sanitized_fields_'.$shipping_method_id, array( $this, 'register_shipping_strings' ) );
46
+ }else{
47
+ add_filter( 'woocommerce_shipping_' . $shipping_method_id . '_instance_settings_values', array( $this, 'register_zone_shipping_strings' ),9,2 );
48
+ }
49
+
50
+ add_filter( 'option_woocommerce_'.$shipping_method_id.'_settings', array( $this, 'translate_shipping_strings' ), 9, 2 );
51
+ }
52
+ }
53
+
54
+ function save_shipping_zone_method_from_ajax(){
55
+ foreach( $_POST['data'] as $key => $value ){
56
+ if( strstr( $key, '_title' ) ){
57
+ $shipping_id = str_replace( 'woocommerce_', '', $key );
58
+ $shipping_id = str_replace( '_title', '', $shipping_id );
59
+ $this->register_shipping_title( $shipping_id.$_POST['instance_id'], $value );
60
+ break;
61
+ }
62
+ }
63
+ }
64
+
65
+ function register_zone_shipping_strings( $instance_settings, $object ){
66
+ if( !empty( $instance_settings['title'] ) ){
67
+ $this->register_shipping_title( $object->id.$object->instance_id, $instance_settings['title'] );
68
+
69
+ $instance_settings = $this->sync_flat_rate_class_cost( $object->get_post_data(), $instance_settings );
70
+ }
71
+
72
+ return $instance_settings;
73
+ }
74
+
75
+ function register_shipping_strings( $fields ){
76
+ $shipping = WC_Shipping::instance();
77
+
78
+ foreach( $shipping->get_shipping_methods() as $shipping_method ){
79
+ if( isset( $_POST['woocommerce_'.$shipping_method->id.'_enabled'] ) ){
80
+ $shipping_method_id = $shipping_method->id;
81
+ break;
82
+ }
83
+ }
84
+
85
+ if( isset( $shipping_method_id ) ){
86
+ $this->register_shipping_title( $shipping_method_id, $fields['title'] );
87
+ }
88
+
89
+ return $fields;
90
+ }
91
+
92
+ function register_shipping_title( $shipping_method_id, $title ){
93
+ do_action( 'wpml_register_single_string', 'woocommerce', $shipping_method_id .'_shipping_method_title', $title );
94
+ }
95
+
96
+ function translate_shipping_strings( $value, $option = false ){
97
+
98
+ if( $option && isset( $value['enabled']) && $value['enabled'] == 'no' ){
99
+ return $value;
100
+ }
101
+
102
+ $shipping_id = str_replace( 'woocommerce_', '', $option );
103
+ $shipping_id = str_replace( '_settings', '', $shipping_id );
104
+
105
+ if( isset( $value['title'] ) ){
106
+ $value['title'] = $this->translate_shipping_method_title( $value['title'], $shipping_id );
107
+ }
108
+
109
+ return $value;
110
+ }
111
+
112
+ function translate_shipping_methods_in_package( $available_methods ){
113
+
114
+ foreach($available_methods as $key => $method){
115
+ $available_methods[$key]->label = $this->translate_shipping_method_title( $method->label, $key );
116
+ }
117
+
118
+ return $available_methods;
119
+ }
120
+
121
+ function translate_shipping_method_title( $title, $shipping_id, $language = false ) {
122
+ $shipping_id = str_replace( ':', '', $shipping_id );
123
+ $title = apply_filters( 'wpml_translate_single_string', $title, 'woocommerce', $shipping_id .'_shipping_method_title', $language ? $language : $this->current_language );
124
+
125
+ return $title;
126
+ }
127
+
128
+ function translate_woocommerce_rate_label( $label ){
129
+
130
+ $label = apply_filters( 'wpml_translate_single_string', $label, 'woocommerce taxes', $label );
131
+
132
+ return $label;
133
+ }
134
+
135
+ function register_tax_rate_label_string( $id, $tax_rate ){
136
+
137
+ if( !empty( $tax_rate['tax_rate_name'] ) ){
138
+ do_action('wpml_register_single_string', 'woocommerce taxes', $tax_rate['tax_rate_name'] , $tax_rate['tax_rate_name'] );
139
+ }
140
+
141
+ }
142
+
143
+ function sync_class_costs_for_new_shipping_classes( $original_tax, $result ){
144
+ //update flat rate options for shipping classes
145
+ if( $original_tax->taxonomy == 'product_shipping_class' ){
146
+
147
+ $settings = get_option( 'woocommerce_flat_rate_settings' );
148
+ if( is_array( $settings ) ){
149
+ update_option( 'woocommerce_flat_rate_settings', $this->update_woocommerce_shipping_settings_for_class_costs( $settings ) );
150
+ }
151
+
152
+ $settings = get_option( 'woocommerce_international_delivery_settings' );
153
+ if( is_array( $settings ) ){
154
+ update_option( 'woocommerce_international_delivery_settings', $this->update_woocommerce_shipping_settings_for_class_costs( $settings ) );
155
+ }
156
+
157
+ }
158
+ }
159
+
160
+ function update_woocommerce_shipping_settings_for_class_costs( $settings ){
161
+
162
+ remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
163
+ foreach( $settings as $setting_key => $value ){
164
+
165
+ if( substr($setting_key, 0, 11) == 'class_cost_' ){
166
+
167
+ $shipp_class_key = substr($setting_key, 11 );
168
+
169
+ if( is_numeric( $shipp_class_key ) ){
170
+ $shipp_class = get_term( $shipp_class_key, 'product_shipping_class' );
171
+ }else{
172
+ $shipp_class = get_term_by( 'slug', $shipp_class_key, 'product_shipping_class' );
173
+ }
174
+
175
+ $trid = $this->sitepress->get_element_trid( $shipp_class->term_taxonomy_id, 'tax_product_shipping_class' );
176
+
177
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_shipping_class' );
178
+
179
+ foreach( $translations as $translation ){
180
+
181
+ $tr_shipp_class = get_term_by( 'term_taxonomy_id', $translation->element_id, 'product_shipping_class' );
182
+
183
+ if( is_numeric( $shipp_class_key ) ){
184
+ $settings[ 'class_cost_'.$tr_shipp_class->term_id ] = $value;
185
+ }else{
186
+ $settings[ 'class_cost_'.$tr_shipp_class->slug ] = $value;
187
+ }
188
+
189
+ }
190
+
191
+ }
192
+
193
+ }
194
+ add_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
195
+
196
+ return $settings;
197
+ }
198
+
199
+ function update_woocommerce_shipping_settings_for_class_costs_from_ajax(){
200
+
201
+ if (isset($_POST['data']['woocommerce_flat_rate_type']) && $_POST['data']['woocommerce_flat_rate_type'] == 'class') {
202
+
203
+ $flat_rate_setting_id = 'woocommerce_flat_rate_' . $_POST['data']['instance_id'] . '_settings';
204
+ $settings = get_option( $flat_rate_setting_id, true );
205
+
206
+ $settings = $this->sync_flat_rate_class_cost( $_POST['data'], $settings );
207
+
208
+ update_option($flat_rate_setting_id, $settings);
209
+ }
210
+ }
211
+
212
+ function sync_flat_rate_class_cost( $data, $inst_settings ){
213
+
214
+ $settings = array();
215
+ foreach ( $data as $key => $value ) {
216
+ if ( substr( $key, 0, 33) == 'woocommerce_flat_rate_class_cost_' ) {
217
+ $settings[ substr( $key, 22 ) ] = $value;
218
+ }
219
+ }
220
+
221
+ $updated_costs_settings = $this->update_woocommerce_shipping_settings_for_class_costs( $settings );
222
+
223
+ $inst_settings = is_array( $inst_settings ) ? array_replace( $inst_settings, $updated_costs_settings ) : $updated_costs_settings;
224
+
225
+ return $inst_settings;
226
+ }
227
+
228
  }
inc/class-wcml-wc-strings.php CHANGED
@@ -1,471 +1,471 @@
1
- <?php
2
-
3
- class WCML_WC_Strings{
4
-
5
- private $translations_from_mo_file = array();
6
- private $mo_files = array();
7
- private $current_language;
8
-
9
- function __construct(){
10
-
11
- add_action( 'init', array( $this, 'init' ) );
12
- add_action( 'registered_taxonomy', array ( $this, 'translate_attributes_label_in_wp_taxonomies' ), 100, 3 );
13
- }
14
-
15
- function init(){
16
- global $pagenow, $sitepress;
17
-
18
- $this->current_language = $sitepress->get_current_language();
19
- if( $this->current_language == 'all' ){
20
- $this->current_language = $sitepress->get_default_language();
21
- }
22
-
23
- //translate attribute label
24
- add_filter('woocommerce_attribute_label',array($this,'translated_attribute_label'),10,3);
25
- add_filter('woocommerce_cart_item_name',array($this,'translated_cart_item_name'),10,3);
26
- add_filter('woocommerce_checkout_product_title',array($this,'translated_checkout_product_title'),10,2);
27
-
28
- if( is_admin() && $pagenow == 'options-permalink.php' ){
29
- add_filter( 'gettext_with_context', array( $this, 'category_base_in_strings_language' ), 99, 3 );
30
- add_action( 'admin_footer', array( $this, 'show_custom_url_base_translation_links' ) );
31
- add_action('admin_footer', array($this, 'show_custom_url_base_language_requirement'));
32
- }
33
- add_action( 'woocommerce_product_options_attributes', array ( $this, 'notice_after_woocommerce_product_options_attributes' ) );
34
-
35
- if( !is_admin() ){
36
- add_filter( 'woocommerce_attribute_taxonomies', array( $this, 'translate_attribute_taxonomies_labels') );
37
- }
38
-
39
- add_filter('woocommerce_get_breadcrumb', array($this, 'filter_woocommerce_breadcrumbs' ), 10, 2 );
40
- }
41
-
42
- function translated_attribute_label($label, $name, $product_obj = false){
43
- global $sitepress, $product, $sitepress_settings;
44
-
45
- $product_id = false;
46
- $lang = $sitepress->get_current_language();
47
- $name = sanitize_title($name);
48
-
49
- if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ){
50
- $lang = $sitepress->get_user_admin_language( get_current_user_id(), true );
51
- }
52
-
53
- if( isset($product->id) ){
54
- $product_id = $product->id;
55
- }elseif( is_numeric( $product_obj ) ){
56
- $product_id = $product_obj;
57
- }elseif( isset($product_obj->id) ){
58
- $product_id = $product_obj->id;
59
- }
60
-
61
- if( $product_id ){
62
-
63
- $custom_attr_translation = get_post_meta( $product_id, 'attr_label_translations', true ) ;
64
-
65
- if( $custom_attr_translation ){
66
- if( isset( $custom_attr_translation[$lang][$name] ) ){
67
- return $custom_attr_translation[$lang][$name];
68
- }
69
- }
70
-
71
- }
72
-
73
- if(is_admin() && !wpml_is_ajax()){
74
-
75
- $string_language = $this->get_string_language( 'taxonomy singular name: '.$label, 'WordPress' );
76
-
77
- if($sitepress->get_user_admin_language( get_current_user_id(), true ) != $string_language){
78
- $string_id = icl_get_string_id( 'taxonomy singular name: '.$label, 'WordPress' );
79
- $strings = icl_get_string_translations_by_id($string_id);
80
- if($strings){
81
- return $strings[$sitepress->get_user_admin_language( get_current_user_id(), true )]['value'];
82
- }
83
- }else{
84
- return $label;
85
- }
86
-
87
- }
88
-
89
- $trnsl_label = apply_filters( 'wpml_translate_single_string', $label, 'WordPress', 'taxonomy singular name: '.$label, $lang );
90
-
91
- if( $label != $trnsl_label ){
92
- return $trnsl_label;
93
- }
94
-
95
- // backward compatibility for WCML < 3.6.1
96
- $trnsl_labels = get_option('wcml_custom_attr_translations');
97
-
98
- if( isset( $trnsl_labels[$lang][$name] ) && !empty( $trnsl_labels[$lang][$name] ) ){
99
- return $trnsl_labels[$lang][$name];
100
- }
101
-
102
- return $label;
103
- }
104
-
105
- function translated_cart_item_name($title, $values, $cart_item_key){
106
-
107
- if($values){
108
-
109
- $parent = wp_get_post_parent_id( $values['product_id'] );
110
- $tr_product_id = apply_filters( 'translate_object_id', $values['product_id'], 'product', true );
111
- $trnsl_title = get_the_title($tr_product_id);
112
-
113
- if($parent){
114
- $tr_parent = apply_filters( 'translate_object_id', $parent, 'product', true );
115
- $trnsl_title = get_the_title( $tr_parent ) . ' &rarr; ' . $trnsl_title;
116
- }
117
-
118
- if( strstr( $title,'</a>' ) ){
119
- $trnsl_title = sprintf( '<a href="%s">%s</a>', $values['data']->get_permalink(), $trnsl_title );
120
- }else{
121
- $trnsl_title = $trnsl_title. '&nbsp;';
122
- }
123
-
124
- $title = $trnsl_title;
125
- }
126
-
127
- return $title;
128
- }
129
-
130
- function translated_checkout_product_title($title,$product){
131
-
132
- if(isset($product->id)){
133
- $tr_product_id = apply_filters( 'translate_object_id', $product->id, 'product', true, $this->current_language );
134
- $title = get_the_title($tr_product_id);
135
- }
136
-
137
- return $title;
138
- }
139
-
140
- // Catch the default slugs for translation
141
- function translate_default_slug($translation, $text, $context, $domain) {
142
- global $sitepress, $woocommerce_wpml;
143
-
144
- if ($context == 'slug' || $context == 'default-slug') {
145
- $wc_slug = $woocommerce_wpml->url_translation->get_woocommerce_product_base();
146
- if(is_admin()){
147
- $admin_language = $sitepress->get_admin_language();
148
- }
149
- $current_language = $sitepress->get_current_language();
150
-
151
- $strings_language = $this->get_domain_language('woocommerce');
152
-
153
- if ($text == $wc_slug && $domain == 'woocommerce' && $strings_language) {
154
- $sitepress->switch_lang($strings_language);
155
- $translation = _x($text, 'URL slug', $domain);
156
- $sitepress->switch_lang($current_language);
157
- if(is_admin()){
158
- $sitepress->set_admin_language($admin_language);
159
- }
160
- }else{
161
- $translation = $text;
162
- }
163
-
164
- if(!is_admin()){
165
- $sitepress->switch_lang($current_language);
166
- }
167
- }
168
-
169
- return $translation;
170
-
171
- }
172
-
173
-
174
-
175
- function show_custom_url_base_language_requirement(){
176
- $category_base = ($c = get_option('category_base') ) ? $c : 'category';
177
- ?>
178
- <script>
179
- if(jQuery('#woocommerce_permalink_structure').length){
180
- jQuery('#woocommerce_permalink_structure').parent().append(jQuery('#wpml_wcml_custom_base_req').html());
181
- }
182
- if(jQuery('input[name="woocommerce_product_category_slug"]').length && jQuery('input[name="woocommerce_product_category_slug"]').val() == '<?php echo $category_base ?>'){
183
- jQuery('input[name="woocommerce_product_category_slug"]').parent().append('<br><i class="icon-warning-sign"><?php
184
- _e('You are using the same value as for the regular category base. This is known to create conflicts resulting in urls not working properly.', 'woocommerce-multilingual') ?></i>');
185
- }
186
- </script>
187
- <?php
188
-
189
- }
190
-
191
- function show_custom_url_base_translation_links(){
192
- global $woocommerce_wpml,$sitepress;
193
- $permalink_options = get_option( 'woocommerce_permalinks' );
194
-
195
- $lang_selector = new WPML_Simple_Language_Selector( $sitepress );
196
-
197
- $bases = array( 'tag_base' => 'product_tag', 'category_base' => 'product_cat', 'attribute_base' => 'attribute', 'product_base' => 'product' );
198
-
199
- foreach( $bases as $key => $base ){
200
-
201
- switch($base){
202
- case 'product_tag':
203
- $input_name = 'woocommerce_product_tag_slug';
204
- $value = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $woocommerce_wpml->url_translation->default_product_tag_base;
205
- break;
206
- case 'product_cat':
207
- $input_name = 'woocommerce_product_category_slug';
208
- $value = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $woocommerce_wpml->url_translation->default_product_category_base;
209
- break;
210
- case 'attribute':
211
- $input_name = 'woocommerce_product_attribute_slug';
212
- $value = !empty( $permalink_options['attribute_base'] ) ? $permalink_options['attribute_base'] : '';
213
- break;
214
- case 'product':
215
- $input_name = 'product_permalink_structure';
216
- if( empty( $permalink_options['product_base'] ) ){
217
- $value = _x( 'product', 'default-slug', 'woocommerce' );
218
- }else{
219
- $value = trim( $permalink_options['product_base'], '/' );
220
- }
221
-
222
- break;
223
- }
224
-
225
- $language = $this->get_string_language( trim( $value, '/' ), $woocommerce_wpml->url_translation->url_strings_context(), $woocommerce_wpml->url_translation->url_string_name( $base ) );
226
-
227
- if( is_null($language) ){
228
- $language = $sitepress->get_default_language();
229
- }
230
-
231
- echo $lang_selector->render( array( 'id' => $key.'_language_selector', 'name' => $key.'_language', 'selected' => $language, 'show_please_select' => false ) ); ?>
232
-
233
- <script>
234
- var input = jQuery('input[name="<?php echo $input_name ?>"]');
235
-
236
- if(input.length){
237
-
238
- if( '<?php echo $input_name ?>' == 'product_permalink_structure' && jQuery('input[name="product_permalink"]:checked').val() == '' ){
239
- input = jQuery('input[name="product_permalink"]:checked').closest('.form-table').find('code').eq(0);
240
- }
241
-
242
- input.parent().append('<div class="translation_controls"></div>');
243
-
244
- if( '<?php echo $input_name ?>' == 'woocommerce_product_attribute_slug' && input.val() == '' ){
245
-
246
- input.parent().find('.translation_controls').append('&nbsp;');
247
-
248
- }else{
249
- input.parent().find('.translation_controls').append('<a href="<?php
250
- echo admin_url( 'admin.php?page=wpml-wcml&tab=slugs' )
251
- ?>"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
252
- }
253
-
254
- jQuery('#<?php echo $key ?>_language_selector').prependTo( input.parent().find('.translation_controls') );
255
- }
256
- </script>
257
- <?php }
258
-
259
- }
260
-
261
- function category_base_in_strings_language($text, $original_value, $context){
262
- if($context == 'slug' && ($original_value == 'product-category' || $original_value == 'product-tag')){
263
- $text = $original_value;
264
- }
265
- return $text;
266
- }
267
-
268
- function product_permalink_slug(){
269
- $permalinks = get_option( 'woocommerce_permalinks' );
270
- $slug = empty( $permalinks['product_base'] ) ? 'product' : trim($permalinks['product_base'],'/');
271
-
272
- return $slug;
273
- }
274
-
275
- function get_domain_language( $domain ){
276
- global $sitepress;
277
-
278
- $lang_of_domain = new WPML_Language_Of_Domain( $sitepress );
279
- $domain_lang = $lang_of_domain->get_language( $domain );
280
-
281
- if ( $domain_lang ) {
282
- $source_lang = $domain_lang;
283
- }else{
284
- $source_lang = 'en';
285
- }
286
-
287
- return $source_lang;
288
- }
289
-
290
- function get_string_language( $value, $context, $name = false ){
291
- global $wpdb;
292
-
293
- if( $name !== false ){
294
-
295
- $string_language = apply_filters( 'wpml_get_string_language', null, $context, $name );
296
-
297
- }else{
298
-
299
- $string_id = icl_get_string_id( $value, $context, $name );
300
-
301
- if( !$string_id ){
302
- return 'en';
303
- }
304
-
305
- $string_object = new WPML_ST_String($string_id, $wpdb);
306
- $string_language = $string_object->get_language();
307
-
308
- }
309
-
310
- if( !$string_language ){
311
- return 'en';
312
- }
313
-
314
- return $string_language;
315
-
316
- }
317
-
318
- function set_string_language( $value, $context, $name , $language ){
319
- global $wpdb;
320
-
321
- $string_id = icl_get_string_id( $value, $context, $name );
322
-
323
- $string_object = new WPML_ST_String( $string_id, $wpdb );
324
- $string_language = $string_object->set_language( $language );
325
-
326
- return $string_language;
327
- }
328
-
329
-
330
- /*
331
- * Filter breadcrumbs
332
- *
333
- */
334
- function filter_woocommerce_breadcrumbs( $breadcrumbs, $object ){
335
- global $sitepress,$woocommerce_wpml;
336
-
337
- $current_language = $sitepress->get_current_language();
338
- $default_language = $sitepress->get_default_language();
339
-
340
- if( $current_language != $default_language || $default_language != 'en' ){
341
-
342
- $shop_page = get_post( wc_get_page_id( 'shop' ) );
343
-
344
- // If permalinks contain the shop page in the URI prepend the breadcrumb with shop
345
- // Similar to WC_Breadcrumb::prepend_shop_page
346
- $trnsl_base = $woocommerce_wpml->url_translation->get_base_translation( 'product', $current_language );
347
- if( $trnsl_base['translated_base'] === '' ){
348
- $trnsl_base['translated_base'] = $trnsl_base['original_value'];
349
- }
350
-
351
- if ( $shop_page->ID && strstr( $trnsl_base['translated_base'], urldecode( $shop_page->post_name ) ) && get_option( 'page_on_front' ) != $shop_page->ID ) {
352
- $breadcrumbs_buff = array();
353
- $i = 0;
354
- foreach( $breadcrumbs as $key => $breadcrumb ){
355
-
356
- if( !in_array( $breadcrumb, $breadcrumbs_buff ) ){
357
- $breadcrumbs_buff[ $i ] = $breadcrumb;
358
- }
359
-
360
- if( $key === 0 && $breadcrumbs[ 1 ][ 1 ] != get_post_type_archive_link( 'product' ) ){
361
- $i++;
362
- $breadcrumbs_buff[ $i ] = array( $shop_page->post_title, get_post_type_archive_link( 'product' ) );
363
- }
364
- $i++;
365
- }
366
- $breadcrumbs = $breadcrumbs_buff;
367
-
368
- $breadcrumbs = array_values($breadcrumbs);
369
- }
370
-
371
- }
372
-
373
- return $breadcrumbs;
374
- }
375
-
376
- /*
377
- * Add notice message to users
378
- */
379
- function notice_after_woocommerce_product_options_attributes(){
380
- global $sitepress;
381
-
382
- if( isset( $_GET['post'] ) && $sitepress->get_default_language() != $sitepress->get_current_language() ){
383
- $original_product_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $sitepress->get_default_language() );
384
-
385
- printf( '<p>'.__('In order to edit custom attributes you need to use the <a href="%s">custom product translation editor</a>', 'woocommerce-multilingual').'</p>', admin_url('admin.php?page=wpml-wcml&tab=products&prid='.$original_product_id ) );
386
- }
387
- }
388
-
389
- function translate_attribute_taxonomies_labels( $attribute_taxonomies ){
390
- global $sitepress;
391
-
392
- if( is_admin() && !wpml_is_ajax() ){
393
-
394
- foreach( $attribute_taxonomies as $key => $attribute_taxonomy ){
395
- $string_language = $this->get_string_language( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
396
-
397
- if( $sitepress->get_current_language() == $string_language ) continue;
398
-
399
- $string_id = icl_get_string_id( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
400
- $strings = icl_get_string_translations_by_id( $string_id );
401
-
402
- if($strings && isset($strings[$sitepress->get_current_language()])) {
403
- $attribute_taxonomies[$key]->attribute_label = $strings[$sitepress->get_current_language()]['value'];
404
- }
405
- }
406
-
407
- }
408
-
409
-
410
- return $attribute_taxonomies;
411
- }
412
-
413
- function get_translation_from_woocommerce_mo_file( $string, $language, $return_original = true ){
414
- global $sitepress;
415
-
416
- $original_string = $string;
417
-
418
- if ( ! isset( $this->translations_from_mo_file[ $original_string ][ $language ] ) ) {
419
-
420
- if ( ! isset( $this->translations_from_mo_file[ $original_string ] ) ) {
421
- $this->translations_from_mo_file[ $original_string ] = array();
422
- }
423
-
424
- if ( ! isset( $this->mo_files[ $language ] ) ) {
425
- $mo = new MO();
426
- $mo_file = WP_LANG_DIR . '/plugins/woocommerce-' . $sitepress->get_locale( $language ) . '.mo';
427
- if( !file_exists( $mo_file ) ){
428
- return $return_original ? $string : null;
429
- }
430
-
431
- $mo->import_from_file( $mo_file );
432
- $this->mo_files[ $language ] = &$mo->entries;
433
- }
434
-
435
- if( in_array( $string, array( 'product','product-category','product-tag' ) ) ){
436
- $string = 'slug'. chr(4) .$string;
437
- }
438
-
439
- if( isset( $this->mo_files[ $language ][$string] ) ){
440
- $this->translations_from_mo_file[ $original_string ][ $language ] = $this->mo_files[ $language ][$string]->translations[0];
441
- } else {
442
- $this->translations_from_mo_file[ $original_string ][ $language ] = $return_original ? $original_string : null;
443
- }
444
- }
445
-
446
- return $this->translations_from_mo_file[ $original_string ][ $language ];
447
-
448
- }
449
-
450
- function translate_attributes_label_in_wp_taxonomies( $taxonomy, $obj_type, $args ){
451
- global $wp_taxonomies, $sitepress;
452
- $obj_type = array_unique( (array) $obj_type );
453
-
454
- $current_language = $sitepress->get_current_language();
455
-
456
- if( $current_language != 'all' && in_array( 'product', $obj_type ) && substr( $taxonomy, 0, 3) == 'pa_' && isset( $wp_taxonomies[ $taxonomy ] )){
457
-
458
- if( is_array( $args['labels'] ) ){
459
- $name = $args['labels']['singular_name'];
460
- }else{
461
- $name = $args['labels']->name;
462
- }
463
-
464
- $wp_taxonomies[$taxonomy]->labels->name = apply_filters( 'wpml_translate_single_string', $name, 'WordPress', 'taxonomy singular name: '.$name, $current_language );
465
-
466
-
467
- }
468
-
469
- }
470
-
471
  }
1
+ <?php
2
+
3
+ class WCML_WC_Strings{
4
+
5
+ private $translations_from_mo_file = array();
6
+ private $mo_files = array();
7
+ private $current_language;
8
+
9
+ function __construct(){
10
+
11
+ add_action( 'init', array( $this, 'init' ) );
12
+ add_action( 'registered_taxonomy', array ( $this, 'translate_attributes_label_in_wp_taxonomies' ), 100, 3 );
13
+ }
14
+
15
+ function init(){
16
+ global $pagenow, $sitepress;
17
+
18
+ $this->current_language = $sitepress->get_current_language();
19
+ if( $this->current_language == 'all' ){
20
+ $this->current_language = $sitepress->get_default_language();
21
+ }
22
+
23
+ //translate attribute label
24
+ add_filter('woocommerce_attribute_label',array($this,'translated_attribute_label'),10,3);
25
+ add_filter('woocommerce_cart_item_name',array($this,'translated_cart_item_name'),10,3);
26
+ add_filter('woocommerce_checkout_product_title',array($this,'translated_checkout_product_title'),10,2);
27
+
28
+ if( is_admin() && $pagenow == 'options-permalink.php' ){
29
+ add_filter( 'gettext_with_context', array( $this, 'category_base_in_strings_language' ), 99, 3 );
30
+ add_action( 'admin_footer', array( $this, 'show_custom_url_base_translation_links' ) );
31
+ add_action('admin_footer', array($this, 'show_custom_url_base_language_requirement'));
32
+ }
33
+ add_action( 'woocommerce_product_options_attributes', array ( $this, 'notice_after_woocommerce_product_options_attributes' ) );
34
+
35
+ if( !is_admin() ){
36
+ add_filter( 'woocommerce_attribute_taxonomies', array( $this, 'translate_attribute_taxonomies_labels') );
37
+ }
38
+
39
+ add_filter('woocommerce_get_breadcrumb', array($this, 'filter_woocommerce_breadcrumbs' ), 10, 2 );
40
+ }
41
+
42
+ function translated_attribute_label($label, $name, $product_obj = false){
43
+ global $sitepress, $product, $sitepress_settings;
44
+
45
+ $product_id = false;
46
+ $lang = $sitepress->get_current_language();
47
+ $name = sanitize_title($name);
48
+
49
+ if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ){
50
+ $lang = $sitepress->get_user_admin_language( get_current_user_id(), true );
51
+ }
52
+
53
+ if( isset($product->id) ){
54
+ $product_id = $product->id;
55
+ }elseif( is_numeric( $product_obj ) ){
56
+ $product_id = $product_obj;
57
+ }elseif( isset($product_obj->id) ){
58
+ $product_id = $product_obj->id;
59
+ }
60
+
61
+ if( $product_id ){
62
+
63
+ $custom_attr_translation = get_post_meta( $product_id, 'attr_label_translations', true ) ;
64
+
65
+ if( $custom_attr_translation ){
66
+ if( isset( $custom_attr_translation[$lang][$name] ) ){
67
+ return $custom_attr_translation[$lang][$name];
68
+ }
69
+ }
70
+
71
+ }
72
+
73
+ if(is_admin() && !wpml_is_ajax()){
74
+
75
+ $string_language = $this->get_string_language( 'taxonomy singular name: '.$label, 'WordPress' );
76
+
77
+ if($sitepress->get_user_admin_language( get_current_user_id(), true ) != $string_language){
78
+ $string_id = icl_get_string_id( 'taxonomy singular name: '.$label, 'WordPress' );
79
+ $strings = icl_get_string_translations_by_id($string_id);
80
+ if($strings){
81
+ return $strings[$sitepress->get_user_admin_language( get_current_user_id(), true )]['value'];
82
+ }
83
+ }else{
84
+ return $label;
85
+ }
86
+
87
+ }
88
+
89
+ $trnsl_label = apply_filters( 'wpml_translate_single_string', $label, 'WordPress', 'taxonomy singular name: '.$label, $lang );
90
+
91
+ if( $label != $trnsl_label ){
92
+ return $trnsl_label;
93
+ }
94
+
95
+ // backward compatibility for WCML < 3.6.1
96
+ $trnsl_labels = get_option('wcml_custom_attr_translations');
97
+
98
+ if( isset( $trnsl_labels[$lang][$name] ) && !empty( $trnsl_labels[$lang][$name] ) ){
99
+ return $trnsl_labels[$lang][$name];
100
+ }
101
+
102
+ return $label;
103
+ }
104
+
105
+ function translated_cart_item_name($title, $values, $cart_item_key){
106
+
107
+ if($values){
108
+
109
+ $parent = wp_get_post_parent_id( $values['product_id'] );
110
+ $tr_product_id = apply_filters( 'translate_object_id', $values['product_id'], 'product', true );
111
+ $trnsl_title = get_the_title($tr_product_id);
112
+
113
+ if($parent){
114
+ $tr_parent = apply_filters( 'translate_object_id', $parent, 'product', true );
115
+ $trnsl_title = get_the_title( $tr_parent ) . ' &rarr; ' . $trnsl_title;
116
+ }
117
+
118
+ if( strstr( $title,'</a>' ) ){
119
+ $trnsl_title = sprintf( '<a href="%s">%s</a>', $values['data']->get_permalink(), $trnsl_title );
120
+ }else{
121
+ $trnsl_title = $trnsl_title. '&nbsp;';
122
+ }
123
+
124
+ $title = $trnsl_title;
125
+ }
126
+
127
+ return $title;
128
+ }
129
+
130
+ function translated_checkout_product_title($title,$product){
131
+
132
+ if(isset($product->id)){
133
+ $tr_product_id = apply_filters( 'translate_object_id', $product->id, 'product', true, $this->current_language );
134
+ $title = get_the_title($tr_product_id);
135
+ }
136
+
137
+ return $title;
138
+ }
139
+
140
+ // Catch the default slugs for translation
141
+ function translate_default_slug($translation, $text, $context, $domain) {
142
+ global $sitepress, $woocommerce_wpml;
143
+
144
+ if ($context == 'slug' || $context == 'default-slug') {
145
+ $wc_slug = $woocommerce_wpml->url_translation->get_woocommerce_product_base();
146
+ if(is_admin()){
147
+ $admin_language = $sitepress->get_admin_language();
148
+ }
149
+ $current_language = $sitepress->get_current_language();
150
+
151
+ $strings_language = $this->get_domain_language('woocommerce');
152
+
153
+ if ($text == $wc_slug && $domain == 'woocommerce' && $strings_language) {
154
+ $sitepress->switch_lang($strings_language);
155
+ $translation = _x($text, 'URL slug', $domain);
156
+ $sitepress->switch_lang($current_language);
157
+ if(is_admin()){
158
+ $sitepress->set_admin_language($admin_language);
159
+ }
160
+ }else{
161
+ $translation = $text;
162
+ }
163
+
164
+ if(!is_admin()){
165
+ $sitepress->switch_lang($current_language);
166
+ }
167
+ }
168
+
169
+ return $translation;
170
+
171
+ }
172
+
173
+
174
+
175
+ function show_custom_url_base_language_requirement(){
176
+ $category_base = ($c = get_option('category_base') ) ? $c : 'category';
177
+ ?>
178
+ <script>
179
+ if(jQuery('#woocommerce_permalink_structure').length){
180
+ jQuery('#woocommerce_permalink_structure').parent().append(jQuery('#wpml_wcml_custom_base_req').html());
181
+ }
182
+ if(jQuery('input[name="woocommerce_product_category_slug"]').length && jQuery('input[name="woocommerce_product_category_slug"]').val() == '<?php echo $category_base ?>'){
183
+ jQuery('input[name="woocommerce_product_category_slug"]').parent().append('<br><i class="icon-warning-sign"><?php
184
+ _e('You are using the same value as for the regular category base. This is known to create conflicts resulting in urls not working properly.', 'woocommerce-multilingual') ?></i>');
185
+ }
186
+ </script>
187
+ <?php
188
+
189
+ }
190
+
191
+ function show_custom_url_base_translation_links(){
192
+ global $woocommerce_wpml,$sitepress;
193
+ $permalink_options = get_option( 'woocommerce_permalinks' );
194
+
195
+ $lang_selector = new WPML_Simple_Language_Selector( $sitepress );
196
+
197
+ $bases = array( 'tag_base' => 'product_tag', 'category_base' => 'product_cat', 'attribute_base' => 'attribute', 'product_base' => 'product' );
198
+
199
+ foreach( $bases as $key => $base ){
200
+
201
+ switch($base){
202
+ case 'product_tag':
203
+ $input_name = 'woocommerce_product_tag_slug';
204
+ $value = !empty( $permalink_options['tag_base'] ) ? $permalink_options['tag_base'] : $woocommerce_wpml->url_translation->default_product_tag_base;
205
+ break;
206
+ case 'product_cat':
207
+ $input_name = 'woocommerce_product_category_slug';
208
+ $value = !empty( $permalink_options['category_base'] ) ? $permalink_options['category_base'] : $woocommerce_wpml->url_translation->default_product_category_base;
209
+ break;
210
+ case 'attribute':
211
+ $input_name = 'woocommerce_product_attribute_slug';
212
+ $value = !empty( $permalink_options['attribute_base'] ) ? $permalink_options['attribute_base'] : '';
213
+ break;
214
+ case 'product':
215
+ $input_name = 'product_permalink_structure';
216
+ if( empty( $permalink_options['product_base'] ) ){
217
+ $value = _x( 'product', 'default-slug', 'woocommerce' );
218
+ }else{
219
+ $value = trim( $permalink_options['product_base'], '/' );
220
+ }
221
+
222
+ break;
223
+ }
224
+
225
+ $language = $this->get_string_language( trim( $value, '/' ), $woocommerce_wpml->url_translation->url_strings_context(), $woocommerce_wpml->url_translation->url_string_name( $base ) );
226
+
227
+ if( is_null($language) ){
228
+ $language = $sitepress->get_default_language();
229
+ }
230
+
231
+ echo $lang_selector->render( array( 'id' => $key.'_language_selector', 'name' => $key.'_language', 'selected' => $language, 'show_please_select' => false ) ); ?>
232
+
233
+ <script>
234
+ var input = jQuery('input[name="<?php echo $input_name ?>"]');
235
+
236
+ if(input.length){
237
+
238
+ if( '<?php echo $input_name ?>' == 'product_permalink_structure' && jQuery('input[name="product_permalink"]:checked').val() == '' ){
239
+ input = jQuery('input[name="product_permalink"]:checked').closest('.form-table').find('code').eq(0);
240
+ }
241
+
242
+ input.parent().append('<div class="translation_controls"></div>');
243
+
244
+ if( '<?php echo $input_name ?>' == 'woocommerce_product_attribute_slug' && input.val() == '' ){
245
+
246
+ input.parent().find('.translation_controls').append('&nbsp;');
247
+
248
+ }else{
249
+ input.parent().find('.translation_controls').append('<a href="<?php
250
+ echo admin_url( 'admin.php?page=wpml-wcml&tab=slugs' )
251
+ ?>"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
252
+ }
253
+
254
+ jQuery('#<?php echo $key ?>_language_selector').prependTo( input.parent().find('.translation_controls') );
255
+ }
256
+ </script>
257
+ <?php }
258
+
259
+ }
260
+
261
+ function category_base_in_strings_language($text, $original_value, $context){
262
+ if($context == 'slug' && ($original_value == 'product-category' || $original_value == 'product-tag')){
263
+ $text = $original_value;
264
+ }
265
+ return $text;
266
+ }
267
+
268
+ function product_permalink_slug(){
269
+ $permalinks = get_option( 'woocommerce_permalinks' );
270
+ $slug = empty( $permalinks['product_base'] ) ? 'product' : trim($permalinks['product_base'],'/');
271
+
272
+ return $slug;
273
+ }
274
+
275
+ function get_domain_language( $domain ){
276
+ global $sitepress;
277
+
278
+ $lang_of_domain = new WPML_Language_Of_Domain( $sitepress );
279
+ $domain_lang = $lang_of_domain->get_language( $domain );
280
+
281
+ if ( $domain_lang ) {
282
+ $source_lang = $domain_lang;
283
+ }else{
284
+ $source_lang = 'en';
285
+ }
286
+
287
+ return $source_lang;
288
+ }
289
+
290
+ function get_string_language( $value, $context, $name = false ){
291
+ global $wpdb;
292
+
293
+ if( $name !== false ){
294
+
295
+ $string_language = apply_filters( 'wpml_get_string_language', null, $context, $name );
296
+
297
+ }else{
298
+
299
+ $string_id = icl_get_string_id( $value, $context, $name );
300
+
301
+ if( !$string_id ){
302
+ return 'en';
303
+ }
304
+
305
+ $string_object = new WPML_ST_String($string_id, $wpdb);
306
+ $string_language = $string_object->get_language();
307
+
308
+ }
309
+
310
+ if( !$string_language ){
311
+ return 'en';
312
+ }
313
+
314
+ return $string_language;
315
+
316
+ }
317
+
318
+ function set_string_language( $value, $context, $name , $language ){
319
+ global $wpdb;
320
+
321
+ $string_id = icl_get_string_id( $value, $context, $name );
322
+
323
+ $string_object = new WPML_ST_String( $string_id, $wpdb );
324
+ $string_language = $string_object->set_language( $language );
325
+
326
+ return $string_language;
327
+ }
328
+
329
+
330
+ /*
331
+ * Filter breadcrumbs
332
+ *
333
+ */
334
+ function filter_woocommerce_breadcrumbs( $breadcrumbs, $object ){
335
+ global $sitepress,$woocommerce_wpml;
336
+
337
+ $current_language = $sitepress->get_current_language();
338
+ $default_language = $sitepress->get_default_language();
339
+
340
+ if( $current_language != $default_language || $default_language != 'en' ){
341
+
342
+ $shop_page = get_post( wc_get_page_id( 'shop' ) );
343
+
344
+ // If permalinks contain the shop page in the URI prepend the breadcrumb with shop
345
+ // Similar to WC_Breadcrumb::prepend_shop_page
346
+ $trnsl_base = $woocommerce_wpml->url_translation->get_base_translation( 'product', $current_language );
347
+ if( $trnsl_base['translated_base'] === '' ){
348
+ $trnsl_base['translated_base'] = $trnsl_base['original_value'];
349
+ }
350
+
351
+ if ( $shop_page->ID && strstr( $trnsl_base['translated_base'], urldecode( $shop_page->post_name ) ) && get_option( 'page_on_front' ) != $shop_page->ID ) {
352
+ $breadcrumbs_buff = array();
353
+ $i = 0;
354
+ foreach( $breadcrumbs as $key => $breadcrumb ){
355
+
356
+ if( !in_array( $breadcrumb, $breadcrumbs_buff ) ){
357
+ $breadcrumbs_buff[ $i ] = $breadcrumb;
358
+ }
359
+
360
+ if( $key === 0 && $breadcrumbs[ 1 ][ 1 ] != get_post_type_archive_link( 'product' ) ){
361
+ $i++;
362
+ $breadcrumbs_buff[ $i ] = array( $shop_page->post_title, get_post_type_archive_link( 'product' ) );
363
+ }
364
+ $i++;
365
+ }
366
+ $breadcrumbs = $breadcrumbs_buff;
367
+
368
+ $breadcrumbs = array_values($breadcrumbs);
369
+ }
370
+
371
+ }
372
+
373
+ return $breadcrumbs;
374
+ }
375
+
376
+ /*
377
+ * Add notice message to users
378
+ */
379
+ function notice_after_woocommerce_product_options_attributes(){
380
+ global $sitepress;
381
+
382
+ if( isset( $_GET['post'] ) && $sitepress->get_default_language() != $sitepress->get_current_language() ){
383
+ $original_product_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $sitepress->get_default_language() );
384
+
385
+ printf( '<p>'.__('In order to edit custom attributes you need to use the <a href="%s">custom product translation editor</a>', 'woocommerce-multilingual').'</p>', admin_url('admin.php?page=wpml-wcml&tab=products&prid='.$original_product_id ) );
386
+ }
387
+ }
388
+
389
+ function translate_attribute_taxonomies_labels( $attribute_taxonomies ){
390
+ global $sitepress;
391
+
392
+ if( is_admin() && !wpml_is_ajax() ){
393
+
394
+ foreach( $attribute_taxonomies as $key => $attribute_taxonomy ){
395
+ $string_language = $this->get_string_language( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
396
+
397
+ if( $sitepress->get_current_language() == $string_language ) continue;
398
+
399
+ $string_id = icl_get_string_id( $attribute_taxonomy->attribute_name, 'WordPress', 'taxonomy singular name: '.$attribute_taxonomy->attribute_name );
400
+ $strings = icl_get_string_translations_by_id( $string_id );
401
+
402
+ if($strings && isset($strings[$sitepress->get_current_language()])) {
403
+ $attribute_taxonomies[$key]->attribute_label = $strings[$sitepress->get_current_language()]['value'];
404
+ }
405
+ }
406
+
407
+ }
408
+
409
+
410
+ return $attribute_taxonomies;
411
+ }
412
+
413
+ function get_translation_from_woocommerce_mo_file( $string, $language, $return_original = true ){
414
+ global $sitepress;
415
+
416
+ $original_string = $string;
417
+
418
+ if ( ! isset( $this->translations_from_mo_file[ $original_string ][ $language ] ) ) {
419
+
420
+ if ( ! isset( $this->translations_from_mo_file[ $original_string ] ) ) {
421
+ $this->translations_from_mo_file[ $original_string ] = array();
422
+ }
423
+
424
+ if ( ! isset( $this->mo_files[ $language ] ) ) {
425
+ $mo = new MO();
426
+ $mo_file = WP_LANG_DIR . '/plugins/woocommerce-' . $sitepress->get_locale( $language ) . '.mo';
427
+ if( !file_exists( $mo_file ) ){
428
+ return $return_original ? $string : null;
429
+ }
430
+
431
+ $mo->import_from_file( $mo_file );
432
+ $this->mo_files[ $language ] = &$mo->entries;
433
+ }
434
+
435
+ if( in_array( $string, array( 'product','product-category','product-tag' ) ) ){
436
+ $string = 'slug'. chr(4) .$string;
437
+ }
438
+
439
+ if( isset( $this->mo_files[ $language ][$string] ) ){
440
+ $this->translations_from_mo_file[ $original_string ][ $language ] = $this->mo_files[ $language ][$string]->translations[0];
441
+ } else {
442
+ $this->translations_from_mo_file[ $original_string ][ $language ] = $return_original ? $original_string : null;
443
+ }
444
+ }
445
+
446
+ return $this->translations_from_mo_file[ $original_string ][ $language ];
447
+
448
+ }
449
+
450
+ function translate_attributes_label_in_wp_taxonomies( $taxonomy, $obj_type, $args ){
451
+ global $wp_taxonomies, $sitepress;
452
+ $obj_type = array_unique( (array) $obj_type );
453
+
454
+ $current_language = $sitepress->get_current_language();
455
+
456
+ if( $current_language != 'all' && in_array( 'product', $obj_type ) && substr( $taxonomy, 0, 3) == 'pa_' && isset( $wp_taxonomies[ $taxonomy ] )){
457
+
458
+ if( is_array( $args['labels'] ) ){
459
+ $name = $args['labels']['singular_name'];
460
+ }else{
461
+ $name = $args['labels']->name;
462
+ }
463
+
464
+ $wp_taxonomies[$taxonomy]->labels->name = apply_filters( 'wpml_translate_single_string', $name, 'WordPress', 'taxonomy singular name: '.$name, $current_language );
465
+
466
+
467
+ }
468
+
469
+ }
470
+
471
  }
inc/class-wcml-widgets.php CHANGED
@@ -1,26 +1,26 @@
1
- <?php
2
-
3
- class WCML_Widgets{
4
-
5
- private $woocommerce_wpml;
6
-
7
- public function __construct( &$woocommerce_wpml ) {
8
- $this->woocommerce_wpml =& $woocommerce_wpml;
9
-
10
- add_action( 'widgets_init', array($this, 'register_widgets' ) );
11
-
12
- }
13
-
14
- public function register_widgets(){
15
-
16
- if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
17
- register_widget( 'WCML_Currency_Switcher_Widget' );
18
- }
19
-
20
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR || $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'lang_switch' ] == WCML_CART_CLEAR ){
21
- register_widget( 'WCML_Cart_Removed_Items_Widget' );
22
- }
23
-
24
- }
25
-
26
  }
1
+ <?php
2
+
3
+ class WCML_Widgets{
4
+
5
+ private $woocommerce_wpml;
6
+
7
+ public function __construct( &$woocommerce_wpml ) {
8
+ $this->woocommerce_wpml =& $woocommerce_wpml;
9
+
10
+ add_action( 'widgets_init', array($this, 'register_widgets' ) );
11
+
12
+ }
13
+
14
+ public function register_widgets(){
15
+
16
+ if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
17
+ register_widget( 'WCML_Currency_Switcher_Widget' );
18
+ }
19
+
20
+ if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR || $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'lang_switch' ] == WCML_CART_CLEAR ){
21
+ register_widget( 'WCML_Cart_Removed_Items_Widget' );
22
+ }
23
+
24
+ }
25
+
26
  }
inc/class-wcml-woocommerce-rest-api-support.php CHANGED
@@ -1,413 +1,413 @@
1
- <?php
2
-
3
- class WCML_WooCommerce_Rest_API_Support{
4
-
5
- private $woocommerce_wpml;
6
- /**
7
- * @var SitePress
8
- */
9
- private $sitepress;
10
- private $sitepress_settings;
11
-
12
- function __construct( &$woocommerce_wpml, &$sitepress ){
13
-
14
- $this->woocommerce_wpml =& $woocommerce_wpml;
15
- $this->sitepress =& $sitepress;
16
- $this->sitepress_settings = $this->sitepress->get_settings();
17
-
18
- add_action( 'parse_request', array( $this, 'use_canonical_home_url' ), -10 );
19
- add_action( 'init', array( $this, 'init' ) );
20
-
21
- add_filter( 'woocommerce_api_query_args', array($this, 'add_lang_parameter'), 10, 2 );
22
- add_filter( 'woocommerce_api_dispatch_args', array($this, 'dispatch_args_filter'), 10, 2 );
23
-
24
- add_filter( 'woocommerce_api_order_response' , array( $this, 'filter_order_items_by_language' ), 10, 4 );
25
- add_action( 'woocommerce_api_create_order' , array( $this, 'set_order_language' ), 10, 2 );
26
-
27
-
28
- add_action( 'woocommerce_api_create_product', array( $this, 'set_product_language' ), 10 , 2 );
29
- add_action( 'woocommerce_api_create_product', array( $this, 'set_product_custom_prices' ), 10 , 2 );
30
- add_action( 'woocommerce_api_product_response', array( $this, 'append_product_language_and_translations' ) );
31
- add_action( 'woocommerce_api_product_response', array( $this, 'append_product_secondary_prices' ) );
32
-
33
- add_action( 'woocommerce_api_edit_product', array( $this, 'sync_product_with_translations' ), 10, 2 );
34
- }
35
-
36
- public function init(){
37
-
38
- //remove rewrite rules filtering for PayPal IPN url
39
- if( strstr($_SERVER['REQUEST_URI'],'WC_Gateway_Paypal') && $this->sitepress_settings[ 'urls' ][ 'directory_for_default_language' ] ) {
40
- remove_filter('option_rewrite_rules', array($this->sitepress, 'rewrite_rules_filter'));
41
- }
42
-
43
- }
44
-
45
- // Use url without the language parameter. Needed for the signature match.
46
- public function use_canonical_home_url(){
47
- global $wp;
48
-
49
- if(!empty($wp->query_vars['wc-api-version'])) {
50
- global $wpml_url_filters;
51
- remove_filter('home_url', array($wpml_url_filters, 'home_url_filter'), -10, 2);
52
-
53
- }
54
-
55
- }
56
-
57
- public function add_lang_parameter( $args, $request_args ){
58
-
59
- if( isset( $request_args['lang'] ) ) {
60
- $args['lang'] = $request_args['lang'];
61
- }
62
-
63
- return $args;
64
- }
65
-
66
- public function dispatch_args_filter( $args, $callback ){
67
- global $wp;
68
-
69
- $route = $wp->query_vars['wc-api-route'];
70
-
71
-
72
- if( isset( $args['filter']['lang'] ) ){
73
-
74
- $lang = $args['filter']['lang'];
75
-
76
- $active_languages = $this->sitepress->get_active_languages();
77
-
78
- if ( !isset($active_languages[$lang]) && $lang != 'all' ) {
79
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $lang ), '404' );
80
- }
81
-
82
- if ( $lang != $this->sitepress->get_default_language() ) {
83
- if ( $lang != 'all' ) {
84
-
85
- $this->sitepress->switch_lang( $lang );
86
-
87
- }else{
88
-
89
- switch($route){
90
- case '/products':
91
- // Remove filters for the post query
92
- remove_action( 'query_vars', array( $this->sitepress, 'query_vars' ) );
93
- global $wpml_query_filter;
94
- remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10 );
95
- remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10 );
96
- break;
97
-
98
- case '/products/categories':
99
- // Remove WPML language filters for the terms query
100
- remove_filter('terms_clauses', array($this->sitepress,'terms_clauses'));
101
- remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
102
- break;
103
-
104
- }
105
-
106
- }
107
- }
108
-
109
- if( $route == '/orders'){
110
- add_filter( 'woocommerce_order_get_items', array( $this, 'get_order_items_in_the_current_language' ) );
111
- }
112
-
113
-
114
- }
115
-
116
-
117
- return $args;
118
-
119
- }
120
-
121
- /**
122
- * Filter orders content in the current language
123
- */
124
- public function get_order_items_in_the_current_language( $items ){
125
-
126
- $lang = get_query_var('lang');
127
- $wc_taxonomies = wc_get_attribute_taxonomies();
128
- $attributes = array();
129
- foreach( $wc_taxonomies as $taxonomy ){
130
- $attributes[] = 'pa_' . $taxonomy->attribute_name;
131
- }
132
-
133
- foreach( $items as $key => $item ){
134
-
135
- if( isset( $item['product_id'] ) ) {
136
- $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
137
- $items[$key]['product_id'] = $translated_product_id;
138
- $items[$key]['item_meta']['_product_id'] = $translated_product_id;
139
- $items[$key]['name'] = get_post_field( 'post_title', $translated_product_id );
140
- foreach ( $item['item_meta_array'] as $k => $m ) {
141
- if ( $m->key == '_product_id' ) {
142
- $items[$key]['item_meta_array'][$k]->value = $translated_product_id;
143
- }
144
- }
145
- }
146
-
147
- // Variations included
148
- if( !empty( $item['variation_id'] ) ){
149
- $translated_variation_id = apply_filters('translate_object_id', $item['variation_id'], 'product_variation', true, $lang);
150
- $items[$key]['variation_id'] = $translated_variation_id;
151
- $items[$key]['item_meta']['_variation_id'] = $translated_variation_id;
152
- foreach( $attributes as $attribute_name ){
153
- if( isset( $item['item_meta'][$attribute_name] ) ){
154
-
155
- foreach( $item['item_meta'][$attribute_name] as $idx => $attr ){
156
- $term = get_term_by('slug', $attr, $attribute_name);
157
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
158
- $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
159
- $items[$key]['item_meta'][$attribute_name][$idx] = $translated_term->slug;
160
- }
161
-
162
- }
163
-
164
- if( isset( $item[$attribute_name] ) ){
165
- $term = get_term_by('slug', $item[$attribute_name], $attribute_name);
166
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
167
- $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
168
- $items[$key][$attribute_name] = $translated_term->slug;
169
- }
170
- }
171
-
172
- foreach( $item['item_meta_array'] as $k => $m){
173
- if($m->key == '_variation_id'){
174
-
175
- $items[$key]['item_meta_array'][$k]->value = $translated_variation_id;
176
-
177
- } elseif( in_array( $m->key, $attributes ) ){
178
-
179
- $term = get_term_by('slug', $m->value, $m->key);
180
- $translated_term_id = apply_filters('translate_object_id', $term->term_id, $m->key, true, $lang);
181
- $translated_term = get_term_by('id', $translated_term_id, $m->key);
182
- $items[$key]['item_meta_array'][$k]->value = $translated_term->slug;
183
-
184
- }
185
- }
186
-
187
-
188
- }
189
-
190
- }
191
-
192
- return $items;
193
-
194
- }
195
-
196
- /**
197
- * Filters the items of an order according to a given languages
198
- *
199
- * @param $order_data
200
- * @param $order
201
- * @param $fields
202
- * @param $server
203
- * @return mixed
204
- */
205
- public function filter_order_items_by_language( $order_data, $order, $fields, $server ){
206
-
207
- $lang = get_query_var('lang');
208
-
209
- $order_lang = get_post_meta($order->ID, 'wpml_language');
210
-
211
- if( $order_lang != $lang ){
212
-
213
- foreach( $order_data['line_items'] as $k => $item ){
214
-
215
- if( isset( $item['product_id'] ) ){
216
-
217
- $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
218
- if( $translated_product_id ){
219
- $translated_product = get_post( $translated_product_id );
220
- $order_data['line_items'][$k]['product_id'] = $translated_product_id;
221
- if( $translated_product->post_type == 'product_variation' ){
222
- $post_parent = get_post( $translated_product->post_parent );
223
- $post_name = $post_parent->post_title;
224
- } else {
225
- $post_name = $translated_product->post_title;
226
- }
227
- $order_data['line_items'][$k]['name'] = $post_name;
228
- }
229
-
230
- }
231
-
232
- }
233
-
234
- }
235
-
236
- return $order_data;
237
- }
238
-
239
-
240
- /**
241
- * Sets the language for a new order
242
- *
243
- * @param $order_id
244
- * @param $data
245
- *
246
- * @throws WC_API_Exception
247
- */
248
- public function set_order_language( $order_id, $data ){
249
-
250
- if( isset( $data['lang'] ) ){
251
-
252
- $active_languages = $this->sitepress->get_active_languages();
253
- if( !isset( $active_languages[$data['lang']] ) ){
254
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
255
- }
256
-
257
- update_post_meta( $order_id, 'wpml_language', $data['lang']);
258
-
259
- }
260
-
261
- }
262
-
263
- /**
264
- * Sets the product information according to the provided language
265
- *
266
- * @param $id
267
- * @param $data
268
- *
269
- * @throws WC_API_Exception
270
- *
271
- */
272
- public function set_product_language( $id, $data ){
273
-
274
- if( isset( $data['lang'] )){
275
- $active_languages = $this->sitepress->get_active_languages();
276
- if( !isset( $active_languages[$data['lang']] ) ){
277
- throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
278
- }
279
- if( isset( $data['translation_of'] ) ){
280
- $trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' );
281
- if( empty($trid) ){
282
- throw new WC_API_Exception( '404', sprintf( __( 'Source product id not found: %s' ), $data['translation_of'] ), '404' );
283
- }
284
- }else{
285
- $trid = null;
286
- }
287
- $this->sitepress->set_element_language_details( $id, 'post_product', $trid, $data['lang'] );
288
- }
289
-
290
- }
291
-
292
- /**
293
- * Sets custom prices in secondary currencies for products
294
- *
295
- * @param $id
296
- * @param @data
297
- *
298
- */
299
- public function set_product_custom_prices( $id, $data ){
300
-
301
- if( !empty($this->woocommerce_wpml->multi_currency) ){
302
-
303
- if( (!empty($data['custom_prices'])) && (empty($data['translation_of']))){
304
- update_post_meta( $id, '_wcml_custom_prices_status', 1);
305
-
306
- foreach( $data['custom_prices'] as $currency => $prices ){
307
-
308
- $prices_uscore = array();
309
- foreach( $prices as $k => $p){
310
- $prices_uscore['_' . $k] = $p;
311
- }
312
-
313
- $this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $id, $prices_uscore, $currency );
314
-
315
- }
316
-
317
- }
318
- }
319
-
320
- }
321
-
322
- /**
323
- * Synchronizes product fields with its translations
324
- *
325
- * @param $id
326
- * @param $data
327
- */
328
- public function sync_product_with_translations( $id, $data ){
329
-
330
- // Force the WPML sync on post update for the changes
331
- // that don't trigger wp_save_post. e.g. stock
332
- if(
333
- !isset( $data['title']) ||
334
- !isset( $data['name']) ||
335
- !isset( $data['status']) ||
336
- !isset( $data['short_description']) ||
337
- !isset( $data['description'])
338
- ){
339
- $post = get_post( $id );
340
- wp_update_post( array( 'ID' => $id, 'post_title' => wc_clean( $post->post_title ) ) ); // triggers WPML sync
341
- }
342
- }
343
-
344
- /**
345
- * Appends the language and translation information to the get_product response
346
- *
347
- * @param $product_data
348
- */
349
- public function append_product_language_and_translations( $product_data ){
350
-
351
- $product_data['translations'] = array();
352
-
353
- $trid = $this->sitepress->get_element_trid( $product_data['id'], 'post_product' );
354
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product');
355
- foreach( $translations as $translation ){
356
- if( $translation->element_id == $product_data['id'] ){
357
- $product_language = $translation->language_code;
358
- }else{
359
- $product_data['translations'][$translation->language_code] = $translation->element_id;
360
- }
361
- }
362
-
363
- $product_data['lang'] = $product_language;
364
-
365
- return $product_data;
366
- }
367
-
368
- /**
369
- * Appends the secondary prices information to the get_product response
370
- *
371
- * @param $product_data
372
- */
373
- public function append_product_secondary_prices( $product_data ){
374
-
375
- if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ){
376
-
377
- $product_data['multi-currency-prices'] = array();
378
-
379
- $custom_prices_on = get_post_meta( $product_data['id'], '_wcml_custom_prices_status', true);
380
-
381
- foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ){
382
-
383
- if( $currency != get_option('woocommerce_currency') ){
384
-
385
- if( $custom_prices_on ){
386
-
387
- $custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data['id'], $currency );
388
- foreach( $custom_prices as $key => $price){
389
- $product_data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price;
390
-
391
- }
392
-
393
- } else {
394
- $product_data['multi-currency-prices'][$currency]['regular_price'] =
395
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['regular_price'], $currency );
396
- if( !empty($product_data['sale_price']) ){
397
- $product_data['multi-currency-prices'][$currency]['sale_price'] =
398
- $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['sale_price'], $currency );
399
- }
400
- }
401
-
402
- }
403
-
404
- }
405
-
406
- }
407
-
408
- return $product_data;
409
- }
410
-
411
- }
412
-
413
  ?>
1
+ <?php
2
+
3
+ class WCML_WooCommerce_Rest_API_Support{
4
+
5
+ private $woocommerce_wpml;
6
+ /**
7
+ * @var SitePress
8
+ */
9
+ private $sitepress;
10
+ private $sitepress_settings;
11
+
12
+ function __construct( &$woocommerce_wpml, &$sitepress ){
13
+
14
+ $this->woocommerce_wpml =& $woocommerce_wpml;
15
+ $this->sitepress =& $sitepress;
16
+ $this->sitepress_settings = $this->sitepress->get_settings();
17
+
18
+ add_action( 'parse_request', array( $this, 'use_canonical_home_url' ), -10 );
19
+ add_action( 'init', array( $this, 'init' ) );
20
+
21
+ add_filter( 'woocommerce_api_query_args', array($this, 'add_lang_parameter'), 10, 2 );
22
+ add_filter( 'woocommerce_api_dispatch_args', array($this, 'dispatch_args_filter'), 10, 2 );
23
+
24
+ add_filter( 'woocommerce_api_order_response' , array( $this, 'filter_order_items_by_language' ), 10, 4 );
25
+ add_action( 'woocommerce_api_create_order' , array( $this, 'set_order_language' ), 10, 2 );
26
+
27
+
28
+ add_action( 'woocommerce_api_create_product', array( $this, 'set_product_language' ), 10 , 2 );
29
+ add_action( 'woocommerce_api_create_product', array( $this, 'set_product_custom_prices' ), 10 , 2 );
30
+ add_action( 'woocommerce_api_product_response', array( $this, 'append_product_language_and_translations' ) );
31
+ add_action( 'woocommerce_api_product_response', array( $this, 'append_product_secondary_prices' ) );
32
+
33
+ add_action( 'woocommerce_api_edit_product', array( $this, 'sync_product_with_translations' ), 10, 2 );
34
+ }
35
+
36
+ public function init(){
37
+
38
+ //remove rewrite rules filtering for PayPal IPN url
39
+ if( strstr($_SERVER['REQUEST_URI'],'WC_Gateway_Paypal') && $this->sitepress_settings[ 'urls' ][ 'directory_for_default_language' ] ) {
40
+ remove_filter('option_rewrite_rules', array($this->sitepress, 'rewrite_rules_filter'));
41
+ }
42
+
43
+ }
44
+
45
+ // Use url without the language parameter. Needed for the signature match.
46
+ public function use_canonical_home_url(){
47
+ global $wp;
48
+
49
+ if(!empty($wp->query_vars['wc-api-version'])) {
50
+ global $wpml_url_filters;
51
+ remove_filter('home_url', array($wpml_url_filters, 'home_url_filter'), -10, 2);
52
+
53
+ }
54
+
55
+ }
56
+
57
+ public function add_lang_parameter( $args, $request_args ){
58
+
59
+ if( isset( $request_args['lang'] ) ) {
60
+ $args['lang'] = $request_args['lang'];
61
+ }
62
+
63
+ return $args;
64
+ }
65
+
66
+ public function dispatch_args_filter( $args, $callback ){
67
+ global $wp;
68
+
69
+ $route = $wp->query_vars['wc-api-route'];
70
+
71
+
72
+ if( isset( $args['filter']['lang'] ) ){
73
+
74
+ $lang = $args['filter']['lang'];
75
+
76
+ $active_languages = $this->sitepress->get_active_languages();
77
+
78
+ if ( !isset($active_languages[$lang]) && $lang != 'all' ) {
79
+ throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $lang ), '404' );
80
+ }
81
+
82
+ if ( $lang != $this->sitepress->get_default_language() ) {
83
+ if ( $lang != 'all' ) {
84
+
85
+ $this->sitepress->switch_lang( $lang );
86
+
87
+ }else{
88
+
89
+ switch($route){
90
+ case '/products':
91
+ // Remove filters for the post query
92
+ remove_action( 'query_vars', array( $this->sitepress, 'query_vars' ) );
93
+ global $wpml_query_filter;
94
+ remove_filter( 'posts_join', array( $wpml_query_filter, 'posts_join_filter' ), 10 );
95
+ remove_filter( 'posts_where', array( $wpml_query_filter, 'posts_where_filter' ), 10 );
96
+ break;
97
+
98
+ case '/products/categories':
99
+ // Remove WPML language filters for the terms query
100
+ remove_filter('terms_clauses', array($this->sitepress,'terms_clauses'));
101
+ remove_filter( 'get_term', array( $this->sitepress, 'get_term_adjust_id' ), 1 );
102
+ break;
103
+
104
+ }
105
+
106
+ }
107
+ }
108
+
109
+ if( $route == '/orders'){
110
+ add_filter( 'woocommerce_order_get_items', array( $this, 'get_order_items_in_the_current_language' ) );
111
+ }
112
+
113
+
114
+ }
115
+
116
+
117
+ return $args;
118
+
119
+ }
120
+
121
+ /**
122
+ * Filter orders content in the current language
123
+ */
124
+ public function get_order_items_in_the_current_language( $items ){
125
+
126
+ $lang = get_query_var('lang');
127
+ $wc_taxonomies = wc_get_attribute_taxonomies();
128
+ $attributes = array();
129
+ foreach( $wc_taxonomies as $taxonomy ){
130
+ $attributes[] = 'pa_' . $taxonomy->attribute_name;
131
+ }
132
+
133
+ foreach( $items as $key => $item ){
134
+
135
+ if( isset( $item['product_id'] ) ) {
136
+ $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
137
+ $items[$key]['product_id'] = $translated_product_id;
138
+ $items[$key]['item_meta']['_product_id'] = $translated_product_id;
139
+ $items[$key]['name'] = get_post_field( 'post_title', $translated_product_id );
140
+ foreach ( $item['item_meta_array'] as $k => $m ) {
141
+ if ( $m->key == '_product_id' ) {
142
+ $items[$key]['item_meta_array'][$k]->value = $translated_product_id;
143
+ }
144
+ }
145
+ }
146
+
147
+ // Variations included
148
+ if( !empty( $item['variation_id'] ) ){
149
+ $translated_variation_id = apply_filters('translate_object_id', $item['variation_id'], 'product_variation', true, $lang);
150
+ $items[$key]['variation_id'] = $translated_variation_id;
151
+ $items[$key]['item_meta']['_variation_id'] = $translated_variation_id;
152
+ foreach( $attributes as $attribute_name ){
153
+ if( isset( $item['item_meta'][$attribute_name] ) ){
154
+
155
+ foreach( $item['item_meta'][$attribute_name] as $idx => $attr ){
156
+ $term = get_term_by('slug', $attr, $attribute_name);
157
+ $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
158
+ $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
159
+ $items[$key]['item_meta'][$attribute_name][$idx] = $translated_term->slug;
160
+ }
161
+
162
+ }
163
+
164
+ if( isset( $item[$attribute_name] ) ){
165
+ $term = get_term_by('slug', $item[$attribute_name], $attribute_name);
166
+ $translated_term_id = apply_filters('translate_object_id', $term->term_id, $attribute_name, true, $lang);
167
+ $translated_term = get_term_by('id', $translated_term_id, $attribute_name);
168
+ $items[$key][$attribute_name] = $translated_term->slug;
169
+ }
170
+ }
171
+
172
+ foreach( $item['item_meta_array'] as $k => $m){
173
+ if($m->key == '_variation_id'){
174
+
175
+ $items[$key]['item_meta_array'][$k]->value = $translated_variation_id;
176
+
177
+ } elseif( in_array( $m->key, $attributes ) ){
178
+
179
+ $term = get_term_by('slug', $m->value, $m->key);
180
+ $translated_term_id = apply_filters('translate_object_id', $term->term_id, $m->key, true, $lang);
181
+ $translated_term = get_term_by('id', $translated_term_id, $m->key);
182
+ $items[$key]['item_meta_array'][$k]->value = $translated_term->slug;
183
+
184
+ }
185
+ }
186
+
187
+
188
+ }
189
+
190
+ }
191
+
192
+ return $items;
193
+
194
+ }
195
+
196
+ /**
197
+ * Filters the items of an order according to a given languages
198
+ *
199
+ * @param $order_data
200
+ * @param $order
201
+ * @param $fields
202
+ * @param $server
203
+ * @return mixed
204
+ */
205
+ public function filter_order_items_by_language( $order_data, $order, $fields, $server ){
206
+
207
+ $lang = get_query_var('lang');
208
+
209
+ $order_lang = get_post_meta($order->ID, 'wpml_language');
210
+
211
+ if( $order_lang != $lang ){
212
+
213
+ foreach( $order_data['line_items'] as $k => $item ){
214
+
215
+ if( isset( $item['product_id'] ) ){
216
+
217
+ $translated_product_id = apply_filters( 'translate_object_id', $item['product_id'], 'product', true, $lang );
218
+ if( $translated_product_id ){
219
+ $translated_product = get_post( $translated_product_id );
220
+ $order_data['line_items'][$k]['product_id'] = $translated_product_id;
221
+ if( $translated_product->post_type == 'product_variation' ){
222
+ $post_parent = get_post( $translated_product->post_parent );
223
+ $post_name = $post_parent->post_title;
224
+ } else {
225
+ $post_name = $translated_product->post_title;
226
+ }
227
+ $order_data['line_items'][$k]['name'] = $post_name;
228
+ }
229
+
230
+ }
231
+
232
+ }
233
+
234
+ }
235
+
236
+ return $order_data;
237
+ }
238
+
239
+
240
+ /**
241
+ * Sets the language for a new order
242
+ *
243
+ * @param $order_id
244
+ * @param $data
245
+ *
246
+ * @throws WC_API_Exception
247
+ */
248
+ public function set_order_language( $order_id, $data ){
249
+
250
+ if( isset( $data['lang'] ) ){
251
+
252
+ $active_languages = $this->sitepress->get_active_languages();
253
+ if( !isset( $active_languages[$data['lang']] ) ){
254
+ throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
255
+ }
256
+
257
+ update_post_meta( $order_id, 'wpml_language', $data['lang']);
258
+
259
+ }
260
+
261
+ }
262
+
263
+ /**
264
+ * Sets the product information according to the provided language
265
+ *
266
+ * @param $id
267
+ * @param $data
268
+ *
269
+ * @throws WC_API_Exception
270
+ *
271
+ */
272
+ public function set_product_language( $id, $data ){
273
+
274
+ if( isset( $data['lang'] )){
275
+ $active_languages = $this->sitepress->get_active_languages();
276
+ if( !isset( $active_languages[$data['lang']] ) ){
277
+ throw new WC_API_Exception( '404', sprintf( __( 'Invalid language parameter: %s' ), $data['lang'] ), '404' );
278
+ }
279
+ if( isset( $data['translation_of'] ) ){
280
+ $trid = $this->sitepress->get_element_trid( $data['translation_of'], 'post_product' );
281
+ if( empty($trid) ){
282
+ throw new WC_API_Exception( '404', sprintf( __( 'Source product id not found: %s' ), $data['translation_of'] ), '404' );
283
+ }
284
+ }else{
285
+ $trid = null;
286
+ }
287
+ $this->sitepress->set_element_language_details( $id, 'post_product', $trid, $data['lang'] );
288
+ }
289
+
290
+ }
291
+
292
+ /**
293
+ * Sets custom prices in secondary currencies for products
294
+ *
295
+ * @param $id
296
+ * @param @data
297
+ *
298
+ */
299
+ public function set_product_custom_prices( $id, $data ){
300
+
301
+ if( !empty($this->woocommerce_wpml->multi_currency) ){
302
+
303
+ if( (!empty($data['custom_prices'])) && (empty($data['translation_of']))){
304
+ update_post_meta( $id, '_wcml_custom_prices_status', 1);
305
+
306
+ foreach( $data['custom_prices'] as $currency => $prices ){
307
+
308
+ $prices_uscore = array();
309
+ foreach( $prices as $k => $p){
310
+ $prices_uscore['_' . $k] = $p;
311
+ }
312
+
313
+ $this->woocommerce_wpml->multi_currency->custom_prices->update_custom_prices( $id, $prices_uscore, $currency );
314
+
315
+ }
316
+
317
+ }
318
+ }
319
+
320
+ }
321
+
322
+ /**
323
+ * Synchronizes product fields with its translations
324
+ *
325
+ * @param $id
326
+ * @param $data
327
+ */
328
+ public function sync_product_with_translations( $id, $data ){
329
+
330
+ // Force the WPML sync on post update for the changes
331
+ // that don't trigger wp_save_post. e.g. stock
332
+ if(
333
+ !isset( $data['title']) ||
334
+ !isset( $data['name']) ||
335
+ !isset( $data['status']) ||
336
+ !isset( $data['short_description']) ||
337
+ !isset( $data['description'])
338
+ ){
339
+ $post = get_post( $id );
340
+ wp_update_post( array( 'ID' => $id, 'post_title' => wc_clean( $post->post_title ) ) ); // triggers WPML sync
341
+ }
342
+ }
343
+
344
+ /**
345
+ * Appends the language and translation information to the get_product response
346
+ *
347
+ * @param $product_data
348
+ */
349
+ public function append_product_language_and_translations( $product_data ){
350
+
351
+ $product_data['translations'] = array();
352
+
353
+ $trid = $this->sitepress->get_element_trid( $product_data['id'], 'post_product' );
354
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product');
355
+ foreach( $translations as $translation ){
356
+ if( $translation->element_id == $product_data['id'] ){
357
+ $product_language = $translation->language_code;
358
+ }else{
359
+ $product_data['translations'][$translation->language_code] = $translation->element_id;
360
+ }
361
+ }
362
+
363
+ $product_data['lang'] = $product_language;
364
+
365
+ return $product_data;
366
+ }
367
+
368
+ /**
369
+ * Appends the secondary prices information to the get_product response
370
+ *
371
+ * @param $product_data
372
+ */
373
+ public function append_product_secondary_prices( $product_data ){
374
+
375
+ if( !empty($this->woocommerce_wpml->multi_currency) && !empty($this->woocommerce_wpml->settings['currencies_order']) ){
376
+
377
+ $product_data['multi-currency-prices'] = array();
378
+
379
+ $custom_prices_on = get_post_meta( $product_data['id'], '_wcml_custom_prices_status', true);
380
+
381
+ foreach( $this->woocommerce_wpml->settings['currencies_order'] as $currency ){
382
+
383
+ if( $currency != get_option('woocommerce_currency') ){
384
+
385
+ if( $custom_prices_on ){
386
+
387
+ $custom_prices = (array) $this->woocommerce_wpml->multi_currency->custom_prices->get_product_custom_prices( $product_data['id'], $currency );
388
+ foreach( $custom_prices as $key => $price){
389
+ $product_data['multi-currency-prices'][$currency][ preg_replace('#^_#', '', $key) ] = $price;
390
+
391
+ }
392
+
393
+ } else {
394
+ $product_data['multi-currency-prices'][$currency]['regular_price'] =
395
+ $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['regular_price'], $currency );
396
+ if( !empty($product_data['sale_price']) ){
397
+ $product_data['multi-currency-prices'][$currency]['sale_price'] =
398
+ $this->woocommerce_wpml->multi_currency->prices->raw_price_filter( $product_data['sale_price'], $currency );
399
+ }
400
+ }
401
+
402
+ }
403
+
404
+ }
405
+
406
+ }
407
+
408
+ return $product_data;
409
+ }
410
+
411
+ }
412
+
413
  ?>
inc/class-wcml-xdomain-data.php CHANGED
@@ -1,93 +1,93 @@
1
- <?php
2
-
3
- /**
4
- * Handles data being passed between different domains using WPML xDomain logic
5
- * https://wpml.org/?page_id=693147
6
- *
7
- */
8
- class WCML_xDomain_Data {
9
-
10
- /**
11
- * xDomain_Data constructor.
12
- */
13
- function __construct() {
14
- add_filter( 'wpml_cross_domain_language_data', array($this, 'pass_data_to_domain') );
15
- add_action( 'before_woocommerce_init', array($this, 'check_request') );
16
- }
17
-
18
- /**
19
- * @param $data
20
- * @return mixed
21
- */
22
- function pass_data_to_domain( $data ) {
23
-
24
- $wcml_session_id = md5( microtime() . uniqid( rand(), TRUE ) );
25
- $data['wcsid'] = $wcml_session_id;
26
- $session_data = array();
27
-
28
- if ( isset($_COOKIE['wp_woocommerce_session_' . COOKIEHASH]) ) {
29
- $session_data['session'] = $_COOKIE['wp_woocommerce_session_' . COOKIEHASH];
30
- }
31
-
32
- if ( isset($_COOKIE['woocommerce_cart_hash']) ) {
33
- $session_data['hash'] = $_COOKIE['woocommerce_cart_hash'];
34
- $session_data['items'] = $_COOKIE['woocommerce_items_in_cart'];
35
- }
36
-
37
- if ( !empty($session_data) ) {
38
- update_option( 'wcml_session_data_' . $wcml_session_id, $session_data );
39
- }
40
-
41
- return $data;
42
- }
43
-
44
- /**
45
- *
46
- */
47
- function check_request() {
48
-
49
- if ( has_filter( 'wpml_get_cross_domain_language_data' ) ) { // After WPML 3.2.7
50
- $xdomain_data = apply_filters( 'wpml_get_cross_domain_language_data', array() );
51
- } else {
52
- if ( isset($_GET['xdomain_data']) ) {
53
- $xdomain_data = json_decode( base64_decode( $_GET['xdomain_data'] ), JSON_OBJECT_AS_ARRAY );
54
- }
55
- }
56
-
57
- if ( isset($xdomain_data['wcsid']) ) {
58
- $this->set_session_data( $xdomain_data['wcsid'] );
59
- }
60
-
61
- }
62
-
63
- /**
64
- * @param $wcml_session_id
65
- */
66
- function set_session_data( $wcml_session_id ) {
67
-
68
- $data = maybe_unserialize( get_option( 'wcml_session_data_' . $wcml_session_id ) );
69
-
70
- if ( !empty($data) ) {
71
-
72
- $session_expiration = time() + intval( apply_filters( 'wc_session_expiration', 60 * 60 * 48 ) ); // 48 Hours
73
- $secure = apply_filters( 'wc_session_use_secure_cookie', false );
74
-
75
- if ( isset($data['session']) ) {
76
- setcookie( 'wp_woocommerce_session_' . COOKIEHASH, $data['session'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
77
- $_COOKIE[ 'wp_woocommerce_session_' . COOKIEHASH ] = $data['session'];
78
- }
79
-
80
- if ( isset($data['hash ']) ) {
81
- setcookie( 'woocommerce_cart_hash', $data['hash'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
82
- setcookie( 'woocommerce_items_in_cart', $data['items'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
83
- $_COOKIE[ 'woocommerce_cart_hash' ] = $data['hash'];
84
- $_COOKIE[ 'woocommerce_items_in_cart' ] = $data['items'];
85
- }
86
-
87
- }
88
-
89
- delete_option( 'wcml_session_data_' . $wcml_session_id );
90
-
91
- }
92
-
93
  }
1
+ <?php
2
+
3
+ /**
4
+ * Handles data being passed between different domains using WPML xDomain logic
5
+ * https://wpml.org/?page_id=693147
6
+ *
7
+ */
8
+ class WCML_xDomain_Data {
9
+
10
+ /**
11
+ * xDomain_Data constructor.
12
+ */
13
+ function __construct() {
14
+ add_filter( 'wpml_cross_domain_language_data', array($this, 'pass_data_to_domain') );
15
+ add_action( 'before_woocommerce_init', array($this, 'check_request') );
16
+ }
17
+
18
+ /**
19
+ * @param $data
20
+ * @return mixed
21
+ */
22
+ function pass_data_to_domain( $data ) {
23
+
24
+ $wcml_session_id = md5( microtime() . uniqid( rand(), TRUE ) );
25
+ $data['wcsid'] = $wcml_session_id;
26
+ $session_data = array();
27
+
28
+ if ( isset($_COOKIE['wp_woocommerce_session_' . COOKIEHASH]) ) {
29
+ $session_data['session'] = $_COOKIE['wp_woocommerce_session_' . COOKIEHASH];
30
+ }
31
+
32
+ if ( isset($_COOKIE['woocommerce_cart_hash']) ) {
33
+ $session_data['hash'] = $_COOKIE['woocommerce_cart_hash'];
34
+ $session_data['items'] = $_COOKIE['woocommerce_items_in_cart'];
35
+ }
36
+
37
+ if ( !empty($session_data) ) {
38
+ update_option( 'wcml_session_data_' . $wcml_session_id, $session_data );
39
+ }
40
+
41
+ return $data;
42
+ }
43
+
44
+ /**
45
+ *
46
+ */
47
+ function check_request() {
48
+
49
+ if ( has_filter( 'wpml_get_cross_domain_language_data' ) ) { // After WPML 3.2.7
50
+ $xdomain_data = apply_filters( 'wpml_get_cross_domain_language_data', array() );
51
+ } else {
52
+ if ( isset($_GET['xdomain_data']) ) {
53
+ $xdomain_data = json_decode( base64_decode( $_GET['xdomain_data'] ), JSON_OBJECT_AS_ARRAY );
54
+ }
55
+ }
56
+
57
+ if ( isset($xdomain_data['wcsid']) ) {
58
+ $this->set_session_data( $xdomain_data['wcsid'] );
59
+ }
60
+
61
+ }
62
+
63
+ /**
64
+ * @param $wcml_session_id
65
+ */
66
+ function set_session_data( $wcml_session_id ) {
67
+
68
+ $data = maybe_unserialize( get_option( 'wcml_session_data_' . $wcml_session_id ) );
69
+
70
+ if ( !empty($data) ) {
71
+
72
+ $session_expiration = time() + intval( apply_filters( 'wc_session_expiration', 60 * 60 * 48 ) ); // 48 Hours
73
+ $secure = apply_filters( 'wc_session_use_secure_cookie', false );
74
+
75
+ if ( isset($data['session']) ) {
76
+ setcookie( 'wp_woocommerce_session_' . COOKIEHASH, $data['session'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
77
+ $_COOKIE[ 'wp_woocommerce_session_' . COOKIEHASH ] = $data['session'];
78
+ }
79
+
80
+ if ( isset($data['hash ']) ) {
81
+ setcookie( 'woocommerce_cart_hash', $data['hash'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
82
+ setcookie( 'woocommerce_items_in_cart', $data['items'], $session_expiration, COOKIEPATH, COOKIE_DOMAIN, $secure );
83
+ $_COOKIE[ 'woocommerce_cart_hash' ] = $data['hash'];
84
+ $_COOKIE[ 'woocommerce_items_in_cart' ] = $data['items'];
85
+ }
86
+
87
+ }
88
+
89
+ delete_option( 'wcml_session_data_' . $wcml_session_id );
90
+
91
+ }
92
+
93
  }
inc/class-woocommerce-wpml.php CHANGED
@@ -1,291 +1,291 @@
1
- <?php
2
- class woocommerce_wpml {
3
-
4
- /** @var woocommerce_wpml */
5
- protected static $_instance = null;
6
-
7
- public $settings;
8
- /** @var WCML_Troubleshooting */
9
- public $troubleshooting;
10
- /** @var WCML_Endpoints */
11
- public $endpoints;
12
- /** @var WCML_Products */
13
- public $products;
14
- /** @var WCML_Synchronize_Product_Data */
15
- public $sync_product_data;
16
- /** @var WCML_Synchronize_Variations_Data */
17
- public $sync_variations_data;
18
- /** @var WCML_Store_Pages */
19
- public $store;
20
- /** @var WCML_Emails */
21
- public $emails;
22
- /** @var WCML_Terms */
23
- public $terms;
24
- /** @var WCML_Attributes */
25
- public $attributes;
26
- /** @var WCML_Orders */
27
- public $orders;
28
- /** @var WCML_Currencies */
29
- public $currencies;
30
- /** @var WCML_Multi_Currency */
31
- public $multi_currency;
32
- /** @var WCML_Languages_Upgrader */
33
- public $languages_upgrader;
34
- /** @var WCML_Url_Translation */
35
- public $url_translation;
36
- /** @var WCML_Coupons */
37
- public $coupons;
38
- /** @var WCML_Locale */
39
- public $locale;
40
- /** @var WCML_Media */
41
- public $media;
42
- /** @var WCML_Downloadable_Products */
43
- public $downloadable;
44
- /** @var WCML_WC_Strings */
45
- public $strings;
46
- /** @var WCML_WC_Shipping */
47
- public $shipping;
48
- /** @var WCML_WC_Gateways */
49
- public $gateways;
50
-
51
- /** @var WCML_Reports */
52
- private $reports;
53
- /** @var WCML_Requests */
54
- public $requests;
55
- /** @var WCML_Compatibility */
56
- // NOTE: revert back to private after wcml-1218
57
- public $compatibility;
58
- /** @var WCML_xDomain_Data */
59
- private $xdomain_data;
60
-
61
- /** @var WCML_WooCommerce_Rest_API_Support */
62
- private $wc_rest_api;
63
-
64
- /**
65
- * @var WCML_Screen_Options
66
- */
67
- private $wcml_products_screen;
68
-
69
-
70
- public function __construct(){
71
-
72
- $this->settings = $this->get_settings();
73
-
74
- $this->currencies = new WCML_Currencies( $this );
75
-
76
- $this->xdomain_data = new WCML_xDomain_Data;
77
-
78
- new WCML_Widgets( $this );
79
-
80
- add_action('init', array($this, 'init'),2);
81
-
82
- }
83
-
84
- /**
85
- * Main instance.
86
- *
87
- * @since 3.8
88
- * @static
89
- * @return woocommerce_wpml
90
- */
91
- public static function instance() {
92
- global $woocommerce_wpml;
93
-
94
- if ( is_null( self::$_instance ) ) {
95
- self::$_instance = new self();
96
- $woocommerce_wpml = self::$_instance;
97
- }
98
-
99
- return self::$_instance;
100
- }
101
- public function init(){
102
- global $sitepress, $wpdb, $woocommerce;
103
-
104
- new WCML_Upgrade;
105
-
106
- $this->dependencies = new WCML_Dependencies;
107
- $this->check_dependencies = $this->dependencies->check();
108
-
109
- WCML_Admin_Menus::set_up_menus( $this, $sitepress, $wpdb, $this->check_dependencies );
110
-
111
- if( !$this->check_dependencies ){
112
- WCML_Capabilities::set_up_capabilities();
113
-
114
- wp_register_style( 'otgs-ico', WCML_PLUGIN_URL . '/res/css/otgs-ico.css', null, WCML_VERSION );
115
- wp_enqueue_style( 'otgs-ico');
116
-
117
- WCML_Resources::load_management_css();
118
- WCML_Resources::load_tooltip_resources();
119
- return false;
120
- }
121
-
122
- $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb );
123
-
124
- $actions_that_need_mc = array(
125
- 'save-mc-options',
126
- 'wcml_new_currency',
127
- 'wcml_save_currency',
128
- 'wcml_delete_currency',
129
- 'wcml_update_currency_lang',
130
- 'wcml_update_default_currency',
131
- 'wcml_price_preview',
132
- 'wcml_currencies_switcher_preview'
133
- );
134
- if($this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
135
- || ( isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'multi-currency' )
136
- || ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
137
- ){
138
- $this->multi_currency = new WCML_Multi_Currency;
139
- }else{
140
- add_shortcode('currency_switcher', '__return_empty_string');
141
- }
142
-
143
- if( is_admin() ) {
144
- $this->troubleshooting = new WCML_Troubleshooting();
145
- $this->links = new WCML_Links($this, $sitepress);
146
- $this->translation_editor = new WCML_Translation_Editor($this, $sitepress, $wpdb);
147
- $this->languages_upgrader = new WCML_Languages_Upgrader;
148
- $this->sync_variations_data = new WCML_Synchronize_Variations_Data($this, $sitepress, $wpdb);
149
- $this->wcml_products_screen = new WCML_Products_Screen_Options($sitepress);
150
- $this->wcml_products_screen->init();
151
- new WCML_Pointers();
152
- }
153
-
154
- $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
155
- $this->endpoints = new WCML_Endpoints;
156
- $this->products = new WCML_Products( $this, $sitepress, $wpdb );
157
- $this->store = new WCML_Store_Pages ($this, $sitepress ) ;
158
- $this->emails = new WCML_Emails( $this, $sitepress );
159
- $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
160
- $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
161
- $this->orders = new WCML_Orders( $this, $sitepress );
162
- $this->strings = new WCML_WC_Strings;
163
- $this->shipping = new WCML_WC_Shipping( $sitepress );
164
- $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
165
- $this->currencies = new WCML_Currencies( $this );
166
- $this->url_translation = new WCML_Url_Translation ( $this, $sitepress );
167
- $this->requests = new WCML_Requests;
168
- $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
169
- $this->coupons = new WCML_Coupons( $this, $sitepress );
170
- $this->locale = new WCML_Locale( $this, $sitepress );
171
- $this->media = new WCML_Media( $this, $sitepress, $wpdb );
172
- $this->downloadable = new WCML_Downloadable_Products( $this, $sitepress );
173
- $this->reports = new WCML_Reports;
174
- $this->wcml_products_screen = new WCML_Products_Screen_Options();
175
- $this->wcml_products_screen->init();
176
-
177
- new WCML_Ajax_Setup( $sitepress );
178
- new WCML_Fix_Copied_Custom_Fields_WPML353();
179
-
180
- if ( 'yes' == get_option( 'woocommerce_api_enabled' ) ){
181
- $this->wc_rest_api = new WCML_WooCommerce_Rest_API_Support( $this, $sitepress );
182
- }
183
-
184
- WCML_Install::initialize( $this, $sitepress );
185
-
186
- WCML_Resources::set_up_resources( $this, $sitepress );
187
-
188
- add_filter('woocommerce_get_checkout_payment_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
189
- add_filter('woocommerce_get_cancel_order_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
190
- add_filter('woocommerce_get_return_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
191
-
192
- add_action('wp_ajax_wcml_update_setting_ajx', array($this, 'update_setting_ajx'));
193
- }
194
-
195
- public function get_settings(){
196
-
197
- $defaults = array(
198
- 'file_path_sync' => 1,
199
- 'is_term_order_synced' => 0,
200
- 'enable_multi_currency' => WCML_MULTI_CURRENCIES_DISABLED,
201
- 'dismiss_doc_main' => 0,
202
- 'trnsl_interface' => 1,
203
- 'currency_options' => array(),
204
- 'currency_switcher_product_visibility' => 1,
205
- 'dismiss_tm_warning' => 0,
206
- 'cart_sync' => array(
207
- 'lang_switch' => WCML_CART_SYNC,
208
- 'currency_switch' => WCML_CART_SYNC
209
- )
210
- );
211
-
212
- if(empty($this->settings)){
213
- $this->settings = get_option('_wcml_settings');
214
- }
215
-
216
- foreach($defaults as $key => $value){
217
- if(!isset($this->settings[$key])){
218
- $this->settings[$key] = $value;
219
- }
220
- }
221
-
222
- return $this->settings;
223
- }
224
-
225
- public function update_settings($settings = null){
226
- if(!is_null($settings)){
227
- $this->settings = $settings;
228
- }
229
- update_option('_wcml_settings', $this->settings);
230
- }
231
-
232
- public function update_setting_ajx(){
233
- $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
234
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_settings')){
235
- die('Invalid nonce');
236
- }
237
-
238
- $data = $_POST;
239
- $error = '';
240
- $html = '';
241
-
242
- $this->settings[$data['setting']] = $data['value'];
243
- $this->update_settings();
244
-
245
- echo json_encode(array('html' => $html, 'error'=> $error));
246
- exit;
247
- }
248
-
249
- //get latest stable version from WC readme.txt
250
- public function get_stable_wc_version(){
251
- global $woocommerce;
252
-
253
- $file = $woocommerce->plugin_path(). '/readme.txt';
254
- $values = file($file);
255
- $wc_info = explode( ':', $values[5] );
256
- if( $wc_info[0] == 'Stable tag' ){
257
- $version = trim( $wc_info[1] );
258
- }else{
259
- foreach( $values as $value ){
260
- $wc_info = explode( ':', $value );
261
-
262
- if( $wc_info[0] == 'Stable tag' ){
263
- $version = trim( $wc_info[1] );
264
- }
265
- }
266
- }
267
-
268
- return $version;
269
- }
270
-
271
- public function get_supported_wp_version(){
272
- $file = WCML_PLUGIN_PATH. '/readme.txt';
273
-
274
- $values = file($file);
275
-
276
- $version = explode( ':', $values[6] );
277
-
278
- if( $version[0] == 'Tested up to' ){
279
- return $version[1];
280
- }
281
-
282
- foreach( $values as $value ){
283
- $version = explode( ':', $value );
284
-
285
- if( $version[0] == 'Tested up to' ){
286
- return $version[1];
287
- }
288
- }
289
-
290
- }
291
- }
1
+ <?php
2
+ class woocommerce_wpml {
3
+
4
+ /** @var woocommerce_wpml */
5
+ protected static $_instance = null;
6
+
7
+ public $settings;
8
+ /** @var WCML_Troubleshooting */
9
+ public $troubleshooting;
10
+ /** @var WCML_Endpoints */
11
+ public $endpoints;
12
+ /** @var WCML_Products */
13
+ public $products;
14
+ /** @var WCML_Synchronize_Product_Data */
15
+ public $sync_product_data;
16
+ /** @var WCML_Synchronize_Variations_Data */
17
+ public $sync_variations_data;
18
+ /** @var WCML_Store_Pages */
19
+ public $store;
20
+ /** @var WCML_Emails */
21
+ public $emails;
22
+ /** @var WCML_Terms */
23
+ public $terms;
24
+ /** @var WCML_Attributes */
25
+ public $attributes;
26
+ /** @var WCML_Orders */
27
+ public $orders;
28
+ /** @var WCML_Currencies */
29
+ public $currencies;
30
+ /** @var WCML_Multi_Currency */
31
+ public $multi_currency;
32
+ /** @var WCML_Languages_Upgrader */
33
+ public $languages_upgrader;
34
+ /** @var WCML_Url_Translation */
35
+ public $url_translation;
36
+ /** @var WCML_Coupons */
37
+ public $coupons;
38
+ /** @var WCML_Locale */
39
+ public $locale;
40
+ /** @var WCML_Media */
41
+ public $media;
42
+ /** @var WCML_Downloadable_Products */
43
+ public $downloadable;
44
+ /** @var WCML_WC_Strings */
45
+ public $strings;
46
+ /** @var WCML_WC_Shipping */
47
+ public $shipping;
48
+ /** @var WCML_WC_Gateways */
49
+ public $gateways;
50
+
51
+ /** @var WCML_Reports */
52
+ private $reports;
53
+ /** @var WCML_Requests */
54
+ public $requests;
55
+ /** @var WCML_Compatibility */
56
+ // NOTE: revert back to private after wcml-1218
57
+ public $compatibility;
58
+ /** @var WCML_xDomain_Data */
59
+ private $xdomain_data;
60
+
61
+ /** @var WCML_WooCommerce_Rest_API_Support */
62
+ private $wc_rest_api;
63
+
64
+ /**
65
+ * @var WCML_Screen_Options
66
+ */
67
+ private $wcml_products_screen;
68
+
69
+
70
+ public function __construct(){
71
+
72
+ $this->settings = $this->get_settings();
73
+
74
+ $this->currencies = new WCML_Currencies( $this );
75
+
76
+ $this->xdomain_data = new WCML_xDomain_Data;
77
+
78
+ new WCML_Widgets( $this );
79
+
80
+ add_action('init', array($this, 'init'),2);
81
+
82
+ }
83
+
84
+ /**
85
+ * Main instance.
86
+ *
87
+ * @since 3.8
88
+ * @static
89
+ * @return woocommerce_wpml
90
+ */
91
+ public static function instance() {
92
+ global $woocommerce_wpml;
93
+
94
+ if ( is_null( self::$_instance ) ) {
95
+ self::$_instance = new self();
96
+ $woocommerce_wpml = self::$_instance;
97
+ }
98
+
99
+ return self::$_instance;
100
+ }
101
+ public function init(){
102
+ global $sitepress, $wpdb, $woocommerce;
103
+
104
+ new WCML_Upgrade;
105
+
106
+ $this->dependencies = new WCML_Dependencies;
107
+ $this->check_dependencies = $this->dependencies->check();
108
+
109
+ WCML_Admin_Menus::set_up_menus( $this, $sitepress, $wpdb, $this->check_dependencies );
110
+
111
+ if( !$this->check_dependencies ){
112
+ WCML_Capabilities::set_up_capabilities();
113
+
114
+ wp_register_style( 'otgs-ico', WCML_PLUGIN_URL . '/res/css/otgs-ico.css', null, WCML_VERSION );
115
+ wp_enqueue_style( 'otgs-ico');
116
+
117
+ WCML_Resources::load_management_css();
118
+ WCML_Resources::load_tooltip_resources();
119
+ return false;
120
+ }
121
+
122
+ $this->compatibility = new WCML_Compatibility( $sitepress, $this, $wpdb );
123
+
124
+ $actions_that_need_mc = array(
125
+ 'save-mc-options',
126
+ 'wcml_new_currency',
127
+ 'wcml_save_currency',
128
+ 'wcml_delete_currency',
129
+ 'wcml_update_currency_lang',
130
+ 'wcml_update_default_currency',
131
+ 'wcml_price_preview',
132
+ 'wcml_currencies_switcher_preview'
133
+ );
134
+ if($this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
135
+ || ( isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'multi-currency' )
136
+ || ( isset( $_POST[ 'action' ] ) && in_array( $_POST[ 'action' ], $actions_that_need_mc ) )
137
+ ){
138
+ $this->multi_currency = new WCML_Multi_Currency;
139
+ }else{
140
+ add_shortcode('currency_switcher', '__return_empty_string');
141
+ }
142
+
143
+ if( is_admin() ) {
144
+ $this->troubleshooting = new WCML_Troubleshooting();
145
+ $this->links = new WCML_Links($this, $sitepress);
146
+ $this->translation_editor = new WCML_Translation_Editor($this, $sitepress, $wpdb);
147
+ $this->languages_upgrader = new WCML_Languages_Upgrader;
148
+ $this->sync_variations_data = new WCML_Synchronize_Variations_Data($this, $sitepress, $wpdb);
149
+ $this->wcml_products_screen = new WCML_Products_Screen_Options($sitepress);
150
+ $this->wcml_products_screen->init();
151
+ new WCML_Pointers();
152
+ }
153
+
154
+ $this->sync_product_data = new WCML_Synchronize_Product_Data( $this, $sitepress, $wpdb );
155
+ $this->endpoints = new WCML_Endpoints;
156
+ $this->products = new WCML_Products( $this, $sitepress, $wpdb );
157
+ $this->store = new WCML_Store_Pages ($this, $sitepress ) ;
158
+ $this->emails = new WCML_Emails( $this, $sitepress );
159
+ $this->terms = new WCML_Terms( $this, $sitepress, $wpdb );
160
+ $this->attributes = new WCML_Attributes( $this, $sitepress, $wpdb );
161
+ $this->orders = new WCML_Orders( $this, $sitepress );
162
+ $this->strings = new WCML_WC_Strings;
163
+ $this->shipping = new WCML_WC_Shipping( $sitepress );
164
+ $this->gateways = new WCML_WC_Gateways( $this, $sitepress );
165
+ $this->currencies = new WCML_Currencies( $this );
166
+ $this->url_translation = new WCML_Url_Translation ( $this, $sitepress );
167
+ $this->requests = new WCML_Requests;
168
+ $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
169
+ $this->coupons = new WCML_Coupons( $this, $sitepress );
170
+ $this->locale = new WCML_Locale( $this, $sitepress );
171
+ $this->media = new WCML_Media( $this, $sitepress, $wpdb );
172
+ $this->downloadable = new WCML_Downloadable_Products( $this, $sitepress );
173
+ $this->reports = new WCML_Reports;
174
+ $this->wcml_products_screen = new WCML_Products_Screen_Options();
175
+ $this->wcml_products_screen->init();
176
+
177
+ new WCML_Ajax_Setup( $sitepress );
178
+ new WCML_Fix_Copied_Custom_Fields_WPML353();
179
+
180
+ if ( 'yes' == get_option( 'woocommerce_api_enabled' ) ){
181
+ $this->wc_rest_api = new WCML_WooCommerce_Rest_API_Support( $this, $sitepress );
182
+ }
183
+
184
+ WCML_Install::initialize( $this, $sitepress );
185
+
186
+ WCML_Resources::set_up_resources( $this, $sitepress );
187
+
188
+ add_filter('woocommerce_get_checkout_payment_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
189
+ add_filter('woocommerce_get_cancel_order_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
190
+ add_filter('woocommerce_get_return_url', array('WCML_Links', 'filter_woocommerce_redirect_location'));
191
+
192
+ add_action('wp_ajax_wcml_update_setting_ajx', array($this, 'update_setting_ajx'));
193
+ }
194
+
195
+ public function get_settings(){
196
+
197
+ $defaults = array(
198
+ 'file_path_sync' => 1,
199
+ 'is_term_order_synced' => 0,
200
+ 'enable_multi_currency' => WCML_MULTI_CURRENCIES_DISABLED,
201
+ 'dismiss_doc_main' => 0,
202
+ 'trnsl_interface' => 1,
203
+ 'currency_options' => array(),
204
+ 'currency_switcher_product_visibility' => 1,
205
+ 'dismiss_tm_warning' => 0,
206
+ 'cart_sync' => array(
207
+ 'lang_switch' => WCML_CART_SYNC,
208
+ 'currency_switch' => WCML_CART_SYNC
209
+ )
210
+ );
211
+
212
+ if(empty($this->settings)){
213
+ $this->settings = get_option('_wcml_settings');
214
+ }
215
+
216
+ foreach($defaults as $key => $value){
217
+ if(!isset($this->settings[$key])){
218
+ $this->settings[$key] = $value;
219
+ }
220
+ }
221
+
222
+ return $this->settings;
223
+ }
224
+
225
+ public function update_settings($settings = null){
226
+ if(!is_null($settings)){
227
+ $this->settings = $settings;
228
+ }
229
+ update_option('_wcml_settings', $this->settings);
230
+ }
231
+
232
+ public function update_setting_ajx(){
233
+ $nonce = filter_input( INPUT_POST, 'nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
234
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_settings')){
235
+ die('Invalid nonce');
236
+ }
237
+
238
+ $data = $_POST;
239
+ $error = '';
240
+ $html = '';
241
+
242
+ $this->settings[$data['setting']] = $data['value'];
243
+ $this->update_settings();
244
+
245
+ echo json_encode(array('html' => $html, 'error'=> $error));
246
+ exit;
247
+ }
248
+
249
+ //get latest stable version from WC readme.txt
250
+ public function get_stable_wc_version(){
251
+ global $woocommerce;
252
+
253
+ $file = $woocommerce->plugin_path(). '/readme.txt';
254
+ $values = file($file);
255
+ $wc_info = explode( ':', $values[5] );
256
+ if( $wc_info[0] == 'Stable tag' ){
257
+ $version = trim( $wc_info[1] );
258
+ }else{
259
+ foreach( $values as $value ){
260
+ $wc_info = explode( ':', $value );
261
+
262
+ if( $wc_info[0] == 'Stable tag' ){
263
+ $version = trim( $wc_info[1] );
264
+ }
265
+ }
266
+ }
267
+
268
+ return $version;
269
+ }
270
+
271
+ public function get_supported_wp_version(){
272
+ $file = WCML_PLUGIN_PATH. '/readme.txt';
273
+
274
+ $values = file($file);
275
+
276
+ $version = explode( ':', $values[6] );
277
+
278
+ if( $version[0] == 'Tested up to' ){
279
+ return $version[1];
280
+ }
281
+
282
+ foreach( $values as $value ){
283
+ $version = explode( ':', $value );
284
+
285
+ if( $version[0] == 'Tested up to' ){
286
+ return $version[1];
287
+ }
288
+ }
289
+
290
+ }
291
+ }
inc/constants.php CHANGED
@@ -1,13 +1,13 @@
1
- <?php
2
-
3
- define('WCML_MULTI_CURRENCIES_DISABLED', 0);
4
- define('WCML_MULTI_CURRENCIES_PER_LANGUAGE', 1); //obsolete - migrate to 2
5
- define('WCML_MULTI_CURRENCIES_INDEPENDENT', 2);
6
-
7
- define( 'WCML_TRANSLATION_METHOD_MANUAL', 0);
8
- define( 'WCML_TRANSLATION_METHOD_EDITOR', 1);
9
-
10
- define( 'WCML_CART_CLEAR', 0);
11
- define( 'WCML_CART_SYNC', 1);
12
-
13
- define( 'WCML_JS_MIN', defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min');
1
+ <?php
2
+
3
+ define('WCML_MULTI_CURRENCIES_DISABLED', 0);
4
+ define('WCML_MULTI_CURRENCIES_PER_LANGUAGE', 1); //obsolete - migrate to 2
5
+ define('WCML_MULTI_CURRENCIES_INDEPENDENT', 2);
6
+
7
+ define( 'WCML_TRANSLATION_METHOD_MANUAL', 0);
8
+ define( 'WCML_TRANSLATION_METHOD_EDITOR', 1);
9
+
10
+ define( 'WCML_CART_CLEAR', 0);
11
+ define( 'WCML_CART_SYNC', 1);
12
+
13
+ define( 'WCML_JS_MIN', defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min');
inc/currencies/class-wcml-admin-currency-selector.php CHANGED
@@ -1,167 +1,167 @@
1
- <?php
2
-
3
- class WCML_Admin_Currency_Selector{
4
- private $woocommerce_wpml;
5
-
6
- public function __construct(){
7
-
8
- if( is_admin() ){
9
- add_filter('init', array($this, 'admin_currency_selector_init') );
10
- }
11
-
12
-
13
- }
14
-
15
- public function admin_currency_selector_init(){
16
- global $pagenow, $woocommerce_wpml;
17
-
18
- $this->woocommerce_wpml =& $woocommerce_wpml;
19
-
20
- //dashboard status screen
21
- if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
22
- $this->set_dashboard_currency();
23
-
24
- if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) && $pagenow == 'index.php' ) {
25
- add_action( 'admin_footer', array($this, 'show_dashboard_currency_selector') );
26
- } else {
27
- add_action( 'woocommerce_after_dashboard_status_widget', array($this, 'show_dashboard_currency_selector') );
28
- }
29
-
30
- add_action( 'wp_ajax_wcml_dashboard_set_currency', array($this, 'set_dashboard_currency_ajax') );
31
-
32
- add_filter( 'woocommerce_currency_symbol', array($this, 'filter_dashboard_currency_symbol') );
33
- }
34
-
35
- }
36
-
37
- /*
38
- * Add currency drop-down on dashboard page ( WooCommerce status block )
39
- */
40
- public function show_dashboard_currency_selector(){
41
-
42
- $current_dashboard_currency = $this->get_cookie_dashboard_currency();
43
-
44
- $wc_currencies = get_woocommerce_currencies();
45
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
46
- ?>
47
- <select id="dropdown_dashboard_currency" style="display: none; margin : 10px; ">
48
- <?php if(empty($orders_currencies)): ?>
49
- <option value=""><?php _e('Currency - no orders found', 'woocommerce-multilingual') ?></option>
50
- <?php else: ?>
51
- <?php foreach($order_currencies as $currency => $count ): ?>
52
-
53
- <option value="<?php echo $currency ?>" <?php echo $current_dashboard_currency == $currency ? 'selected="selected"':''; ?>>
54
- <?php echo $wc_currencies[$currency]; ?>
55
- </option>
56
-
57
- <?php endforeach; ?>
58
- <?php endif; ?>
59
- </select>
60
- <?php
61
-
62
- $wcml_dashboard_set_currency_nonce = wp_create_nonce( 'dashboard_set_currency' );
63
-
64
- wc_enqueue_js( "
65
-
66
- jQuery(document).ready(function(){
67
-
68
- var dashboard_dropdown = jQuery('#dropdown_dashboard_currency').clone();
69
- jQuery('#dropdown_dashboard_currency').remove();
70
- dashboard_dropdown.insertBefore('.sales-this-month a').show();
71
- jQuery('#woocommerce_dashboard_status .wc_status_list li').css('display','table');
72
-
73
- });
74
-
75
- jQuery(document).on('change', '#dropdown_dashboard_currency', function(){
76
- jQuery.ajax({
77
- url: ajaxurl,
78
- type: 'post',
79
- data: {
80
- action: 'wcml_dashboard_set_currency',
81
- currency: jQuery('#dropdown_dashboard_currency').val(),
82
- wcml_nonce: '".$wcml_dashboard_set_currency_nonce."'
83
- },
84
- success: function( response ){
85
- if(typeof response.error !== 'undefined'){
86
- alert(response.error);
87
- }else{
88
- window.location = window.location.href;
89
- }
90
- }
91
- })
92
- });
93
- ");
94
- }
95
-
96
- public function set_dashboard_currency_ajax(){
97
-
98
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
99
- if(!$nonce || !wp_verify_nonce($nonce, 'dashboard_set_currency')){
100
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
101
- die();
102
- }
103
-
104
- $this->set_dashboard_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
105
-
106
- die();
107
- }
108
-
109
- /*
110
- * Set dashboard currency cookie
111
- */
112
- public function set_dashboard_currency( $currency_code = false ){
113
-
114
- if( !$currency_code && !headers_sent()){
115
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
116
- $currency_code = get_woocommerce_currency();
117
- if(!isset($order_currencies[$currency_code])){
118
- foreach( $order_currencies as $currency_code => $count ){
119
- $currency_code = $currency_code;
120
- break;
121
- }
122
- }
123
- }
124
-
125
- setcookie('_wcml_dashboard_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
126
-
127
- }
128
-
129
- /*
130
- * Get dashboard currency cookie
131
- *
132
- * @return string
133
- *
134
- */
135
- public function get_cookie_dashboard_currency(){
136
-
137
- if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) ){
138
- $currency = $_COOKIE[ '_wcml_dashboard_currency' ];
139
- }else{
140
- $currency = get_woocommerce_currency();
141
- }
142
-
143
- return $currency;
144
- }
145
-
146
- /*
147
- * Filter currency symbol on dashboard page
148
- *
149
- * @param string $currency Currency code
150
- *
151
- * @return string
152
- *
153
- */
154
- public function filter_dashboard_currency_symbol( $currency ){
155
- global $pagenow;
156
-
157
- remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
158
- if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) && $pagenow == 'index.php' ){
159
- $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_dashboard_currency' ] );
160
- }
161
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
162
-
163
- return $currency;
164
- }
165
-
166
-
167
  }
1
+ <?php
2
+
3
+ class WCML_Admin_Currency_Selector{
4
+ private $woocommerce_wpml;
5
+
6
+ public function __construct(){
7
+
8
+ if( is_admin() ){
9
+ add_filter('init', array($this, 'admin_currency_selector_init') );
10
+ }
11
+
12
+
13
+ }
14
+
15
+ public function admin_currency_selector_init(){
16
+ global $pagenow, $woocommerce_wpml;
17
+
18
+ $this->woocommerce_wpml =& $woocommerce_wpml;
19
+
20
+ //dashboard status screen
21
+ if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) ) {
22
+ $this->set_dashboard_currency();
23
+
24
+ if ( version_compare( WOOCOMMERCE_VERSION, '2.4', '<' ) && $pagenow == 'index.php' ) {
25
+ add_action( 'admin_footer', array($this, 'show_dashboard_currency_selector') );
26
+ } else {
27
+ add_action( 'woocommerce_after_dashboard_status_widget', array($this, 'show_dashboard_currency_selector') );
28
+ }
29
+
30
+ add_action( 'wp_ajax_wcml_dashboard_set_currency', array($this, 'set_dashboard_currency_ajax') );
31
+
32
+ add_filter( 'woocommerce_currency_symbol', array($this, 'filter_dashboard_currency_symbol') );
33
+ }
34
+
35
+ }
36
+
37
+ /*
38
+ * Add currency drop-down on dashboard page ( WooCommerce status block )
39
+ */
40
+ public function show_dashboard_currency_selector(){
41
+
42
+ $current_dashboard_currency = $this->get_cookie_dashboard_currency();
43
+
44
+ $wc_currencies = get_woocommerce_currencies();
45
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
46
+ ?>
47
+ <select id="dropdown_dashboard_currency" style="display: none; margin : 10px; ">
48
+ <?php if(empty($orders_currencies)): ?>
49
+ <option value=""><?php _e('Currency - no orders found', 'woocommerce-multilingual') ?></option>
50
+ <?php else: ?>
51
+ <?php foreach($order_currencies as $currency => $count ): ?>
52
+
53
+ <option value="<?php echo $currency ?>" <?php echo $current_dashboard_currency == $currency ? 'selected="selected"':''; ?>>
54
+ <?php echo $wc_currencies[$currency]; ?>
55
+ </option>
56
+
57
+ <?php endforeach; ?>
58
+ <?php endif; ?>
59
+ </select>
60
+ <?php
61
+
62
+ $wcml_dashboard_set_currency_nonce = wp_create_nonce( 'dashboard_set_currency' );
63
+
64
+ wc_enqueue_js( "
65
+
66
+ jQuery(document).ready(function(){
67
+
68
+ var dashboard_dropdown = jQuery('#dropdown_dashboard_currency').clone();
69
+ jQuery('#dropdown_dashboard_currency').remove();
70
+ dashboard_dropdown.insertBefore('.sales-this-month a').show();
71
+ jQuery('#woocommerce_dashboard_status .wc_status_list li').css('display','table');
72
+
73
+ });
74
+
75
+ jQuery(document).on('change', '#dropdown_dashboard_currency', function(){
76
+ jQuery.ajax({
77
+ url: ajaxurl,
78
+ type: 'post',
79
+ data: {
80
+ action: 'wcml_dashboard_set_currency',
81
+ currency: jQuery('#dropdown_dashboard_currency').val(),
82
+ wcml_nonce: '".$wcml_dashboard_set_currency_nonce."'
83
+ },
84
+ success: function( response ){
85
+ if(typeof response.error !== 'undefined'){
86
+ alert(response.error);
87
+ }else{
88
+ window.location = window.location.href;
89
+ }
90
+ }
91
+ })
92
+ });
93
+ ");
94
+ }
95
+
96
+ public function set_dashboard_currency_ajax(){
97
+
98
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
99
+ if(!$nonce || !wp_verify_nonce($nonce, 'dashboard_set_currency')){
100
+ echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
101
+ die();
102
+ }
103
+
104
+ $this->set_dashboard_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
105
+
106
+ die();
107
+ }
108
+
109
+ /*
110
+ * Set dashboard currency cookie
111
+ */
112
+ public function set_dashboard_currency( $currency_code = false ){
113
+
114
+ if( !$currency_code && !headers_sent()){
115
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
116
+ $currency_code = get_woocommerce_currency();
117
+ if(!isset($order_currencies[$currency_code])){
118
+ foreach( $order_currencies as $currency_code => $count ){
119
+ $currency_code = $currency_code;
120
+ break;
121
+ }
122
+ }
123
+ }
124
+
125
+ setcookie('_wcml_dashboard_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
126
+
127
+ }
128
+
129
+ /*
130
+ * Get dashboard currency cookie
131
+ *
132
+ * @return string
133
+ *
134
+ */
135
+ public function get_cookie_dashboard_currency(){
136
+
137
+ if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) ){
138
+ $currency = $_COOKIE[ '_wcml_dashboard_currency' ];
139
+ }else{
140
+ $currency = get_woocommerce_currency();
141
+ }
142
+
143
+ return $currency;
144
+ }
145
+
146
+ /*
147
+ * Filter currency symbol on dashboard page
148
+ *
149
+ * @param string $currency Currency code
150
+ *
151
+ * @return string
152
+ *
153
+ */
154
+ public function filter_dashboard_currency_symbol( $currency ){
155
+ global $pagenow;
156
+
157
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
158
+ if( isset( $_COOKIE [ '_wcml_dashboard_currency' ] ) && $pagenow == 'index.php' ){
159
+ $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_dashboard_currency' ] );
160
+ }
161
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_dashboard_currency_symbol' ) );
162
+
163
+ return $currency;
164
+ }
165
+
166
+
167
  }
inc/currencies/class-wcml-currencies.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- class WCML_Currencies{
4
-
5
- private $woocommerce_wpml;
6
-
7
- public function __construct( &$woocommerce_wpml ) {
8
- $this->woocommerce_wpml =& $woocommerce_wpml;
9
-
10
- if( is_admin() ){
11
- add_action( 'update_option_woocommerce_currency', array( $this, 'update_default_currency' ), 10, 2 );
12
- }
13
-
14
- }
15
-
16
- public function update_default_currency( $old_value, $new_value ){
17
-
18
- $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
19
- $WCML_Multi_Currency_Install = new WCML_Multi_Currency_Install( $this->woocommerce_wpml->multi_currency, $this->woocommerce_wpml );
20
- $WCML_Multi_Currency_Install->set_default_currencies_languages( $old_value, $new_value );
21
-
22
- }
23
-
24
  }
1
+ <?php
2
+
3
+ class WCML_Currencies{
4
+
5
+ private $woocommerce_wpml;
6
+
7
+ public function __construct( &$woocommerce_wpml ) {
8
+ $this->woocommerce_wpml =& $woocommerce_wpml;
9
+
10
+ if( is_admin() ){
11
+ add_action( 'update_option_woocommerce_currency', array( $this, 'update_default_currency' ), 10, 2 );
12
+ }
13
+
14
+ }
15
+
16
+ public function update_default_currency( $old_value, $new_value ){
17
+
18
+ $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
19
+ $WCML_Multi_Currency_Install = new WCML_Multi_Currency_Install( $this->woocommerce_wpml->multi_currency, $this->woocommerce_wpml );
20
+ $WCML_Multi_Currency_Install->set_default_currencies_languages( $old_value, $new_value );
21
+
22
+ }
23
+
24
  }
inc/currencies/class-wcml-currency-switcher-widget.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
-
3
- class WCML_Currency_Switcher_Widget extends WP_Widget {
4
-
5
- function __construct() {
6
-
7
- parent::__construct( 'currency_sel_widget', __('Currency switcher', 'woocommerce-multilingual'), __('Currency switcher', 'woocommerce-multilingual'));
8
- }
9
-
10
- function widget($args, $instance) {
11
-
12
- echo $args['before_widget'];
13
-
14
- do_action('wcml_currency_switcher');
15
-
16
- echo $args['after_widget'];
17
- }
18
-
19
- function form( $instance ) {
20
-
21
- printf('<p><a href="%s">%s</a></p>',admin_url('admin.php?page=wpml-wcml&tab=multi-currency#currency-switcher'),__('Configure options', 'woocommerce-multilingual'));
22
- return;
23
-
24
- }
25
  }
1
+ <?php
2
+
3
+ class WCML_Currency_Switcher_Widget extends WP_Widget {
4
+
5
+ function __construct() {
6
+
7
+ parent::__construct( 'currency_sel_widget', __('Currency switcher', 'woocommerce-multilingual'), __('Currency switcher', 'woocommerce-multilingual'));
8
+ }
9
+
10
+ function widget($args, $instance) {
11
+
12
+ echo $args['before_widget'];
13
+
14
+ do_action('wcml_currency_switcher');
15
+
16
+ echo $args['after_widget'];
17
+ }
18
+
19
+ function form( $instance ) {
20
+
21
+ printf('<p><a href="%s">%s</a></p>',admin_url('admin.php?page=wpml-wcml&tab=multi-currency#currency-switcher'),__('Configure options', 'woocommerce-multilingual'));
22
+ return;
23
+
24
+ }
25
  }
inc/currencies/class-wcml-currency-switcher.php CHANGED
@@ -1,181 +1,185 @@
1
- <?php
2
-
3
- class WCML_Currency_Switcher {
4
-
5
- private $woocommerce_wpml;
6
-
7
- public function __construct() {
8
- global $woocommerce_wpml;
9
-
10
- $this->woocommerce_wpml =& $woocommerce_wpml;
11
-
12
- add_action( 'init', array($this, 'init'), 5 );
13
-
14
- }
15
-
16
- public function init() {
17
-
18
- add_action( 'wp_ajax_wcml_currencies_order', array($this, 'wcml_currencies_order') );
19
- add_action( 'wp_ajax_wcml_currencies_switcher_preview', array($this, 'wcml_currencies_switcher_preview') );
20
-
21
- add_action( 'wcml_currency_switcher', array($this, 'wcml_currency_switcher') );
22
- //@deprecated 3.9
23
- add_action( 'currency_switcher', array($this, 'currency_switcher') );
24
-
25
- add_shortcode( 'currency_switcher', array($this, 'currency_switcher_shortcode') );
26
-
27
- // Built in currency switcher
28
- add_action( 'woocommerce_product_meta_start', array($this, 'show_currency_switcher') );
29
-
30
- }
31
-
32
- public function wcml_currencies_order() {
33
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
34
- if ( !$nonce || !wp_verify_nonce( $nonce, 'set_currencies_order_nonce' ) ) {
35
- die('Invalid nonce');
36
- }
37
- global $woocommerce_wpml;
38
-
39
- $woocommerce_wpml->settings['currencies_order'] = explode( ';', $_POST['order'] );
40
- $woocommerce_wpml->update_settings();
41
- echo json_encode( array('message' => __( 'Currencies order updated', 'woocommerce-multilingual' )) );
42
- die;
43
- }
44
-
45
- public function wcml_currencies_switcher_preview() {
46
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
47
- if ( !$nonce || !wp_verify_nonce( $nonce, 'wcml_currencies_switcher_preview' ) ) {
48
- die('Invalid nonce');
49
- }
50
-
51
- echo $this->wcml_currency_switcher(
52
- array(
53
- 'format' => $_POST['template'] ? stripslashes_deep( $_POST['template'] ) : '%name% (%symbol%) - %code%',
54
- 'switcher_style' => $_POST['switcher_type'],
55
- 'orientation' => $_POST['orientation']
56
- )
57
- );
58
-
59
- die();
60
- }
61
-
62
- public function currency_switcher_shortcode( $atts ) {
63
- extract( shortcode_atts( array(), $atts ) );
64
-
65
- ob_start();
66
- $this->wcml_currency_switcher( $atts );
67
- $html = ob_get_contents();
68
- ob_end_clean();
69
-
70
- return $html;
71
- }
72
-
73
- public function wcml_currency_switcher( $args = array() ) {
74
- global $sitepress;
75
-
76
- if ( is_page( wc_get_page_id( 'myaccount' ) ) ) {
77
- return '';
78
- }
79
-
80
- $wcml_settings = $this->woocommerce_wpml->get_settings();
81
- $multi_currency_object =& $this->woocommerce_wpml->multi_currency;
82
-
83
- if ( !isset($args['switcher_style']) ) {
84
- $args['switcher_style'] = isset($wcml_settings['currency_switcher_style']) ? $wcml_settings['currency_switcher_style'] : 'dropdown';
85
- }
86
-
87
- if ( !isset($args['orientation']) ) {
88
- $args['orientation'] = isset($wcml_settings['wcml_curr_sel_orientation']) ? $wcml_settings['wcml_curr_sel_orientation'] : 'vertical';
89
- }
90
-
91
- if ( !isset($args['format']) ) {
92
- $args['format'] = isset($wcml_settings['wcml_curr_template']) && $wcml_settings['wcml_curr_template'] != '' ?
93
- $wcml_settings['wcml_curr_template'] : '%name% (%symbol%) - %code%';
94
- }
95
-
96
- $preview = '';
97
- $show_currency_switcher = true;
98
-
99
- $display_custom_prices = isset( $wcml_settings[ 'display_custom_prices' ] ) && $wcml_settings[ 'display_custom_prices' ];
100
-
101
- $is_cart_or_checkout = is_page( wc_get_page_id( 'cart' ) ) || is_page( wc_get_page_id( 'checkout' ) );
102
-
103
- if ( $display_custom_prices ) {
104
- if( $is_cart_or_checkout ){
105
- $show_currency_switcher = false;
106
- }elseif( is_product() ){
107
- $current_product_id = get_post()->ID;
108
- $original_product_language = $this->woocommerce_wpml->products->get_original_product_language( $current_product_id );
109
-
110
- $use_custom_prices = get_post_meta(
111
- apply_filters( 'translate_object_id', $current_product_id, get_post_type( $current_product_id ), true, $original_product_language ),
112
- '_wcml_custom_prices_status',
113
- true
114
- );
115
-
116
- if ( !$use_custom_prices ) $show_currency_switcher = false;
117
- }
118
- }
119
-
120
- if ( $show_currency_switcher ) {
121
-
122
- $currencies = isset($wcml_settings['currencies_order']) ?
123
- $wcml_settings['currencies_order'] :
124
- $multi_currency_object->get_currency_codes();
125
-
126
- if ( count($currencies) > 1) {
127
-
128
- if ( !is_admin() ) {
129
- foreach ( $currencies as $k => $currency ) {
130
- if ( $wcml_settings['currency_options'][$currency]['languages'][$sitepress->get_current_language()] != 1 ) {
131
- unset( $currencies[$k] );
132
- }
133
- }
134
- }
135
-
136
- $currency_switcher = new WCML_Currency_Switcher_UI( $args, $this->woocommerce_wpml, $currencies );
137
- $preview = $currency_switcher->get_view();
138
-
139
- } else{
140
-
141
- if( is_admin() ){
142
-
143
- $preview = '<i>' . __("You haven't added any secondary currencies.", 'woocommerce-multilingual') . '</i>';
144
-
145
- }else{
146
-
147
- $preview = '';
148
-
149
- }
150
-
151
- }
152
-
153
- }
154
-
155
- if ( !isset($args['echo']) || $args['echo'] ) {
156
- echo $preview;
157
- } else {
158
- return $preview;
159
- }
160
-
161
- }
162
-
163
- public function show_currency_switcher() {
164
- $settings = $this->woocommerce_wpml->get_settings();
165
-
166
- if ( is_product() && isset($settings['currency_switcher_product_visibility']) && $settings['currency_switcher_product_visibility'] === 1 ) {
167
- echo(do_shortcode( '[currency_switcher]' ));
168
- echo '<br />';
169
- }
170
-
171
- }
172
-
173
- /**
174
- * @deprecated 3.9
175
- */
176
- public function currency_switcher( $args = array() ){
177
- $this->wcml_currency_switcher( $args );
178
- }
179
-
180
-
 
 
 
 
181
  }
1
+ <?php
2
+
3
+ class WCML_Currency_Switcher {
4
+
5
+ private $woocommerce_wpml;
6
+
7
+ public function __construct() {
8
+ global $woocommerce_wpml;
9
+
10
+ $this->woocommerce_wpml =& $woocommerce_wpml;
11
+
12
+ add_action( 'init', array($this, 'init'), 5 );
13
+
14
+ }
15
+
16
+ public function init() {
17
+
18
+ add_action( 'wp_ajax_wcml_currencies_order', array($this, 'wcml_currencies_order') );
19
+ add_action( 'wp_ajax_wcml_currencies_switcher_preview', array($this, 'wcml_currencies_switcher_preview') );
20
+
21
+ add_action( 'wcml_currency_switcher', array($this, 'wcml_currency_switcher') );
22
+ //@deprecated 3.9
23
+ add_action( 'currency_switcher', array($this, 'currency_switcher') );
24
+
25
+ add_shortcode( 'currency_switcher', array($this, 'currency_switcher_shortcode') );
26
+
27
+ // Built in currency switcher
28
+ add_action( 'woocommerce_product_meta_start', array($this, 'show_currency_switcher') );
29
+
30
+ }
31
+
32
+ public function wcml_currencies_order() {
33
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
34
+ if ( !$nonce || !wp_verify_nonce( $nonce, 'set_currencies_order_nonce' ) ) {
35
+ die('Invalid nonce');
36
+ }
37
+ global $woocommerce_wpml;
38
+
39
+ $woocommerce_wpml->settings['currencies_order'] = explode( ';', $_POST['order'] );
40
+ $woocommerce_wpml->update_settings();
41
+ echo json_encode( array('message' => __( 'Currencies order updated', 'woocommerce-multilingual' )) );
42
+ die;
43
+ }
44
+
45
+ public function wcml_currencies_switcher_preview() {
46
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
47
+ if ( !$nonce || !wp_verify_nonce( $nonce, 'wcml_currencies_switcher_preview' ) ) {
48
+ die('Invalid nonce');
49
+ }
50
+
51
+ echo $this->wcml_currency_switcher(
52
+ array(
53
+ 'format' => $_POST['template'] ? stripslashes_deep( $_POST['template'] ) : '%name% (%symbol%) - %code%',
54
+ 'switcher_style' => $_POST['switcher_type'],
55
+ 'orientation' => $_POST['orientation']
56
+ )
57
+ );
58
+
59
+ die();
60
+ }
61
+
62
+ public function currency_switcher_shortcode( $atts ) {
63
+ extract( shortcode_atts( array(), $atts ) );
64
+
65
+ ob_start();
66
+ $this->wcml_currency_switcher( $atts );
67
+ $html = ob_get_contents();
68
+ ob_end_clean();
69
+
70
+ return $html;
71
+ }
72
+
73
+ public function wcml_currency_switcher( $args = array() ) {
74
+ global $sitepress;
75
+
76
+ if ( is_page( wc_get_page_id( 'myaccount' ) ) ) {
77
+ return '';
78
+ }
79
+
80
+ if( $args === '' ){
81
+ $args = array();
82
+ }
83
+
84
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
85
+ $multi_currency_object =& $this->woocommerce_wpml->multi_currency;
86
+
87
+ if ( !isset($args['switcher_style']) ) {
88
+ $args['switcher_style'] = isset($wcml_settings['currency_switcher_style']) ? $wcml_settings['currency_switcher_style'] : 'dropdown';
89
+ }
90
+
91
+ if ( !isset($args['orientation']) ) {
92
+ $args['orientation'] = isset($wcml_settings['wcml_curr_sel_orientation']) ? $wcml_settings['wcml_curr_sel_orientation'] : 'vertical';
93
+ }
94
+
95
+ if ( !isset($args['format']) ) {
96
+ $args['format'] = isset($wcml_settings['wcml_curr_template']) && $wcml_settings['wcml_curr_template'] != '' ?
97
+ $wcml_settings['wcml_curr_template'] : '%name% (%symbol%) - %code%';
98
+ }
99
+
100
+ $preview = '';
101
+ $show_currency_switcher = true;
102
+
103
+ $display_custom_prices = isset( $wcml_settings[ 'display_custom_prices' ] ) && $wcml_settings[ 'display_custom_prices' ];
104
+
105
+ $is_cart_or_checkout = is_page( wc_get_page_id( 'cart' ) ) || is_page( wc_get_page_id( 'checkout' ) );
106
+
107
+ if ( $display_custom_prices ) {
108
+ if( $is_cart_or_checkout ){
109
+ $show_currency_switcher = false;
110
+ }elseif( is_product() ){
111
+ $current_product_id = get_post()->ID;
112
+ $original_product_language = $this->woocommerce_wpml->products->get_original_product_language( $current_product_id );
113
+
114
+ $use_custom_prices = get_post_meta(
115
+ apply_filters( 'translate_object_id', $current_product_id, get_post_type( $current_product_id ), true, $original_product_language ),
116
+ '_wcml_custom_prices_status',
117
+ true
118
+ );
119
+
120
+ if ( !$use_custom_prices ) $show_currency_switcher = false;
121
+ }
122
+ }
123
+
124
+ if ( $show_currency_switcher ) {
125
+
126
+ $currencies = isset($wcml_settings['currencies_order']) ?
127
+ $wcml_settings['currencies_order'] :
128
+ $multi_currency_object->get_currency_codes();
129
+
130
+ if ( count($currencies) > 1) {
131
+
132
+ if ( !is_admin() ) {
133
+ foreach ( $currencies as $k => $currency ) {
134
+ if ( $wcml_settings['currency_options'][$currency]['languages'][$sitepress->get_current_language()] != 1 ) {
135
+ unset( $currencies[$k] );
136
+ }
137
+ }
138
+ }
139
+
140
+ $currency_switcher = new WCML_Currency_Switcher_UI( $args, $this->woocommerce_wpml, $currencies );
141
+ $preview = $currency_switcher->get_view();
142
+
143
+ } else{
144
+
145
+ if( is_admin() ){
146
+
147
+ $preview = '<i>' . __("You haven't added any secondary currencies.", 'woocommerce-multilingual') . '</i>';
148
+
149
+ }else{
150
+
151
+ $preview = '';
152
+
153
+ }
154
+
155
+ }
156
+
157
+ }
158
+
159
+ if ( !isset($args['echo']) || $args['echo'] ) {
160
+ echo $preview;
161
+ } else {
162
+ return $preview;
163
+ }
164
+
165
+ }
166
+
167
+ public function show_currency_switcher() {
168
+ $settings = $this->woocommerce_wpml->get_settings();
169
+
170
+ if ( is_product() && isset($settings['currency_switcher_product_visibility']) && $settings['currency_switcher_product_visibility'] === 1 ) {
171
+ echo(do_shortcode( '[currency_switcher]' ));
172
+ echo '<br />';
173
+ }
174
+
175
+ }
176
+
177
+ /**
178
+ * @deprecated 3.9
179
+ */
180
+ public function currency_switcher( $args = array() ){
181
+ $this->wcml_currency_switcher( $args );
182
+ }
183
+
184
+
185
  }
inc/currencies/class-wcml-custom-prices.php CHANGED
@@ -1,521 +1,473 @@
1
- <?php
2
-
3
- class WCML_Custom_Prices{
4
-
5
- private $woocommerce_wpml;
6
-
7
- public function __construct( &$woocommerce_wpml ){
8
- add_filter( 'init', array( $this, 'custom_prices_init' ) );
9
- $this->woocommerce_wpml = $woocommerce_wpml;
10
- }
11
-
12
- public function custom_prices_init(){
13
- if ( is_admin() ) {
14
- add_action( 'woocommerce_variation_options', array($this, 'add_individual_variation_nonce'), 10, 3 );
15
-
16
- //custom prices for different currencies for products/variations [BACKEND]
17
- add_action( 'woocommerce_product_options_pricing', array($this, 'woocommerce_product_options_custom_pricing') );
18
- add_action( 'woocommerce_product_after_variable_attributes', array($this, 'woocommerce_product_after_variable_attributes_custom_pricing'), 10, 3 );
19
-
20
- }
21
-
22
- if( version_compare( WC_VERSION , '2.7', '<' ) ){
23
- add_action( 'woocommerce_get_children', array( $this, 'filter_product_variations_with_custom_prices' ), 10 );
24
- }else{
25
- add_action( 'woocommerce_product_get_children', array( $this, 'filter_product_variations_with_custom_prices' ), 10 );
26
- }
27
-
28
- add_filter( 'loop_shop_post_in', array( $this, 'filter_products_with_custom_prices' ), 100 );
29
-
30
- }
31
-
32
- public function add_individual_variation_nonce($loop, $variation_data, $variation){
33
-
34
- wp_nonce_field('wcml_save_custom_prices_variation_' . $variation->ID, '_wcml_custom_prices_variation_' . $variation->ID . '_nonce');
35
-
36
- }
37
-
38
- public function get_product_custom_prices($product_id, $currency = false){
39
- global $wpdb, $sitepress;
40
-
41
- if( empty( $currency ) ){
42
- $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
43
- }
44
-
45
- if( get_option('woocommerce_currency') == $currency ){
46
- return false;
47
- }
48
-
49
- $original_product_id = $product_id;
50
- $post_type = get_post_type($product_id);
51
- $product_translations = $sitepress->get_element_translations($sitepress->get_element_trid($product_id, 'post_'.$post_type), 'post_'.$post_type);
52
- foreach($product_translations as $translation){
53
- if( $translation->original ){
54
- $original_product_id = $translation->element_id;
55
- break;
56
- }
57
- }
58
-
59
- $product_meta = get_post_custom($original_product_id);
60
-
61
- $custom_prices = false;
62
-
63
- if(!empty($product_meta['_wcml_custom_prices_status'][0])){
64
-
65
- $prices_keys = array(
66
- '_price', '_regular_price', '_sale_price',
67
- '_min_variation_price', '_max_variation_price',
68
- '_min_variation_regular_price', '_max_variation_regular_price',
69
- '_min_variation_sale_price', '_max_variation_sale_price');
70
-
71
- foreach($prices_keys as $key){
72
-
73
- if(!empty($product_meta[$key . '_' . $currency][0])){
74
- $custom_prices[$key] = $product_meta[$key . '_' . $currency][0];
75
- }
76
-
77
- }
78
-
79
- }
80
-
81
- if(!isset($custom_prices['_price'])) return false;
82
-
83
- $current__price_value = $custom_prices['_price'];
84
-
85
- // update sale price
86
- if(!empty($custom_prices['_sale_price'])){
87
-
88
- if(!empty($product_meta['_wcml_schedule_' . $currency][0])){
89
- // custom dates
90
- if(!empty($product_meta['_sale_price_dates_from_' . $currency][0]) && !empty($product_meta['_sale_price_dates_to_' . $currency][0])){
91
- if(current_time('timestamp') > $product_meta['_sale_price_dates_from_' . $currency][0] && current_time('timestamp') < $product_meta['_sale_price_dates_to_' . $currency][0]){
92
- $custom_prices['_price'] = $custom_prices['_sale_price'];
93
- }else{
94
- $custom_prices['_price'] = $custom_prices['_regular_price'];
95
- }
96
- }else{
97
- $custom_prices['_price'] = $custom_prices['_sale_price'];
98
- }
99
-
100
- }else{
101
- // inherit
102
- if(!empty($product_meta['_sale_price_dates_from'][0]) && !empty($product_meta['_sale_price_dates_to'][0])){
103
- if(current_time('timestamp') > $product_meta['_sale_price_dates_from'][0] && current_time('timestamp') < $product_meta['_sale_price_dates_to'][0]){
104
- $custom_prices['_price'] = $custom_prices['_sale_price'];
105
- }else{
106
- $custom_prices['_price'] = $custom_prices['_regular_price'];
107
- }
108
- }else{
109
- $custom_prices['_price'] = $custom_prices['_sale_price'];
110
- }
111
- }
112
-
113
- }
114
-
115
- if($custom_prices['_price'] != $current__price_value){
116
- update_post_meta($product_id, '_price_' . $currency, $custom_prices['_price']);
117
- }
118
-
119
- // detemine min/max variation prices
120
- if(!empty($product_meta['_min_variation_price'])){
121
-
122
- static $product_min_max_prices = array();
123
-
124
- if(empty($product_min_max_prices[$product_id])){
125
-
126
- // get variation ids
127
- $variation_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent = %d", $product_id));
128
-
129
- // variations with custom prices
130
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_wcml_custom_prices_status'",join(',', $variation_ids)));
131
- foreach($res as $row){
132
- $custom_prices_enabled[$row->post_id] = $row->meta_value;
133
- }
134
-
135
- // REGULAR PRICES
136
- // get custom prices
137
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_regular_price_" . $currency . "'",join(',', $variation_ids)));
138
- foreach($res as $row){
139
- $regular_prices[$row->post_id] = $row->meta_value;
140
- }
141
-
142
- // get default prices (default currency)
143
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_regular_price'",join(',', $variation_ids)));
144
- foreach($res as $row){
145
- $default_regular_prices[$row->post_id] = $row->meta_value;
146
- }
147
-
148
- // include the dynamic prices
149
- foreach($variation_ids as $vid){
150
- if(empty($regular_prices[$vid]) && isset($default_regular_prices[$vid])){
151
- $regular_prices[$vid] = apply_filters('wcml_raw_price_amount', $default_regular_prices[$vid] );
152
- }
153
- }
154
-
155
- // SALE PRICES
156
- // get custom prices
157
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key=%s",join(',', $variation_ids),'_sale_price_'.$currency));
158
- foreach($res as $row){
159
- $custom_sale_prices[$row->post_id] = $row->meta_value;
160
- }
161
-
162
- // get default prices (default currency)
163
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_sale_price' AND meta_value <> ''",join(',', $variation_ids)));
164
- foreach($res as $row){
165
- $default_sale_prices[$row->post_id] = $row->meta_value;
166
- }
167
-
168
- // include the dynamic prices
169
- foreach($variation_ids as $vid){
170
- if(empty($sale_prices[$vid]) && isset($default_sale_prices[$vid])){
171
- $sale_prices[$vid] = apply_filters('wcml_raw_price_amount', $default_sale_prices[$vid]);
172
- }
173
- }
174
-
175
-
176
- // PRICES
177
- // get custom prices
178
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key=%s",join(',', $variation_ids),'_price_'.$currency));
179
- foreach($res as $row){
180
- $custom_prices_prices[$row->post_id] = $row->meta_value;
181
- }
182
-
183
- // get default prices (default currency)
184
- $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_price'",join(',', $variation_ids)));
185
- foreach($res as $row){
186
- $default_prices[$row->post_id] = $row->meta_value;
187
- }
188
-
189
- // include the dynamic prices
190
- foreach($variation_ids as $vid){
191
- if(empty($custom_prices_prices[$vid]) && isset($default_prices[$vid])){
192
- $prices[$vid] = apply_filters('wcml_raw_price_amount', $default_prices[$vid]);
193
- }
194
- }
195
-
196
- if(!empty($regular_prices)){
197
- $product_min_max_prices[$product_id]['_min_variation_regular_price'] = min($regular_prices);
198
- $product_min_max_prices[$product_id]['_max_variation_regular_price'] = max($regular_prices);
199
- }
200
-
201
- if(!empty($sale_prices)){
202
- $product_min_max_prices[$product_id]['_min_variation_sale_price'] = min($sale_prices);
203
- $product_min_max_prices[$product_id]['_max_variation_sale_price'] = max($sale_prices);
204
- }
205
-
206
- if(!empty($prices)){
207
- $product_min_max_prices[$product_id]['_min_variation_price'] = min($prices);
208
- $product_min_max_prices[$product_id]['_max_variation_price'] = max($prices);
209
- }
210
-
211
-
212
- }
213
-
214
- if(isset($product_min_max_prices[$product_id]['_min_variation_regular_price'])){
215
- $custom_prices['_min_variation_regular_price'] = $product_min_max_prices[$product_id]['_min_variation_regular_price'];
216
- }
217
- if(isset($product_min_max_prices[$product_id]['_max_variation_regular_price'])){
218
- $custom_prices['_max_variation_regular_price'] = $product_min_max_prices[$product_id]['_max_variation_regular_price'];
219
- }
220
-
221
- if(isset($product_min_max_prices[$product_id]['_min_variation_sale_price'])){
222
- $custom_prices['_min_variation_sale_price'] = $product_min_max_prices[$product_id]['_min_variation_sale_price'];
223
- }
224
- if(isset($product_min_max_prices[$product_id]['_max_variation_sale_price'])){
225
- $custom_prices['_max_variation_sale_price'] = $product_min_max_prices[$product_id]['_max_variation_sale_price'];
226
- }
227
-
228
- if(isset($product_min_max_prices[$product_id]['_min_variation_price'])){
229
- $custom_prices['_min_variation_price'] = $product_min_max_prices[$product_id]['_min_variation_price'];
230
- }
231
- if(isset($product_min_max_prices[$product_id]['_max_variation_price'])){
232
- $custom_prices['_max_variation_price'] = $product_min_max_prices[$product_id]['_max_variation_price'];
233
- }
234
-
235
- }
236
-
237
- $custom_prices = apply_filters( 'wcml_product_custom_prices', $custom_prices, $product_id, $currency );
238
-
239
- return $custom_prices;
240
- }
241
-
242
- public function woocommerce_product_options_custom_pricing(){
243
- global $pagenow;
244
-
245
- $this->load_custom_prices_js_css();
246
-
247
- if( ( isset($_GET['post'] ) && ( get_post_type($_GET['post']) != 'product' || !$this->woocommerce_wpml->products->is_original_product( $_GET['post'] ) ) ) ||
248
- ( isset($_GET['post_type'] ) && $_GET['post_type'] == 'product' && isset( $_GET['source_lang'] ) ) ){
249
- return;
250
- }
251
-
252
- $product_id = 'new';
253
-
254
- if($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'product'){
255
- $product_id = $_GET['post'];
256
- }
257
-
258
- $this->custom_pricing_output($product_id);
259
-
260
- do_action( 'wcml_after_custom_prices_block', $product_id );
261
-
262
- wp_nonce_field('wcml_save_custom_prices','_wcml_custom_prices_nonce');
263
-
264
- }
265
-
266
- public function woocommerce_product_after_variable_attributes_custom_pricing($loop, $variation_data, $variation){
267
-
268
- if( $this->woocommerce_wpml->products->is_original_product( $variation->post_parent ) ) {
269
-
270
- echo '<tr><td>';
271
- $this->custom_pricing_output( $variation->ID );
272
- echo '</td></tr>';
273
-
274
- }
275
-
276
- }
277
-
278
- private function load_custom_prices_js_css(){
279
- wp_register_style( 'wpml-wcml-prices', WCML_PLUGIN_URL . '/res/css/wcml-prices.css', null, WCML_VERSION );
280
- wp_register_script( 'wcml-tm-scripts-prices', WCML_PLUGIN_URL . '/res/js/prices' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
281
-
282
- wp_enqueue_style('wpml-wcml-prices');
283
- wp_enqueue_script('wcml-tm-scripts-prices');
284
- }
285
-
286
- private function custom_pricing_output( $post_id = false){
287
-
288
- $custom_prices_ui = new WCML_Custom_Prices_UI( $this->woocommerce_wpml, $post_id );
289
- $custom_prices_ui->show();
290
-
291
- }
292
-
293
- //display variations with custom prices when "Show only products with custom prices in secondary currencies" enabled
294
- public function filter_product_variations_with_custom_prices( $children ){
295
-
296
- if( is_product() && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
297
- isset($this->woocommerce_wpml->settings['display_custom_prices']) &&
298
- $this->woocommerce_wpml->settings['display_custom_prices'] ){
299
-
300
- foreach( $children as $key => $child ){
301
- $orig_lang = $this->woocommerce_wpml->products->get_original_product_language( $child );
302
- $orig_child_id = apply_filters( 'translate_object_id', $child, get_post_type( $child ), true, $orig_lang );
303
-
304
- if( !get_post_meta( $orig_child_id, '_wcml_custom_prices_status', true ) ){
305
- unset( $children[ $key ] );
306
- }
307
- }
308
- }
309
-
310
- return $children;
311
-
312
- }
313
-
314
- // display products with custom prices only if enabled "Show only products with custom prices in secondary currencies" option on settings page
315
- public function filter_products_with_custom_prices( $filtered_posts ) {
316
- global $wpdb;
317
-
318
- if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
319
- isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
320
- $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ){
321
-
322
- $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
323
- $woocommerce_currency = get_option( 'woocommerce_currency' );
324
-
325
- if( $client_currency == $woocommerce_currency ){
326
- return $filtered_posts;
327
- }
328
- $matched_products = array();
329
- $matched_products_query = $wpdb->get_results( "
330
- SELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}
331
- INNER JOIN {$wpdb->postmeta} ON ID = post_id
332
- WHERE post_type IN ( 'product', 'product_variation' ) AND post_status = 'publish' AND meta_key = '_wcml_custom_prices_status' AND meta_value = 1
333
- ", OBJECT_K );
334
-
335
- if ( $matched_products_query ) {
336
- remove_filter( 'get_post_metadata', array( $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ), 10, 4);
337
- foreach ( $matched_products_query as $product ) {
338
- if( !get_post_meta( $product->ID,'_price_'.$client_currency, true ) ) continue;
339
- if ( $product->post_type == 'product' )
340
- $matched_products[] = apply_filters( 'translate_object_id', $product->ID, 'product', true );
341
- if ( $product->post_parent > 0 && ! in_array( $product->post_parent, $matched_products ) )
342
- $matched_products[] = apply_filters( 'translate_object_id', $product->post_parent, get_post_type( $product->post_parent ), true );
343
- }
344
- add_filter('get_post_metadata', array( $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ), 10, 4);
345
- }
346
-
347
- // Filter the id's
348
- if ( sizeof( $filtered_posts ) == 0) {
349
- $filtered_posts = $matched_products;
350
- $filtered_posts[] = 0;
351
- } else {
352
- $filtered_posts = array_intersect( $filtered_posts, $matched_products );
353
- $filtered_posts[] = 0;
354
- }
355
- }
356
-
357
- return $filtered_posts;
358
- }
359
-
360
- public function save_custom_prices( $post_id ){
361
- $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
362
-
363
- if( isset( $_POST[ '_wcml_custom_prices' ] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices' ) && !$this->woocommerce_wpml->products->is_variable_product( $post_id ) ){
364
- if( isset( $_POST[ '_wcml_custom_prices' ][ $post_id ] ) || isset( $_POST[ '_wcml_custom_prices' ][ 'new' ] ) ) {
365
- $wcml_custom_prices_option = isset( $_POST[ '_wcml_custom_prices' ][ $post_id ] ) ? $_POST[ '_wcml_custom_prices' ][ $post_id ] : $_POST[ '_wcml_custom_prices' ][ 'new' ];
366
- }else{
367
- $current_option = get_post_meta( $post_id, '_wcml_custom_prices_status', true );
368
- $wcml_custom_prices_option = $current_option ? $current_option : 0;
369
- }
370
- update_post_meta( $post_id, '_wcml_custom_prices_status', $wcml_custom_prices_option );
371
-
372
- if( $wcml_custom_prices_option == 1){
373
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
374
- foreach( $currencies as $code => $currency ){
375
- $sale_price = wc_format_decimal( $_POST[ '_custom_sale_price' ][ $code ] );
376
- $regular_price = wc_format_decimal( $_POST[ '_custom_regular_price' ][ $code ] );
377
- $date_from = isset( $_POST[ '_custom_sale_price_dates_from' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_from' ][ $code ] ) : '';
378
- $date_to = isset( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) : '';
379
- $schedule = $_POST[ '_wcml_schedule' ][ $code ];
380
-
381
- $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
382
- array( '_regular_price' => $regular_price,
383
- '_sale_price' => $sale_price,
384
- '_wcml_schedule' => $schedule,
385
- '_sale_price_dates_from' => $date_from,
386
- '_sale_price_dates_to' => $date_to ),
387
- $code
388
- );
389
- $this->update_custom_prices( $post_id, $custom_prices , $code );
390
-
391
- do_action( 'wcml_after_save_custom_prices', $post_id );
392
- }
393
- }
394
- }
395
- }
396
-
397
- public function update_custom_prices( $post_id, $custom_prices, $code ){
398
- $price = '';
399
-
400
- // initialization
401
- $keys = array(
402
- '_sale_price_dates_to', '_sale_price_dates_from',
403
- '_sale_price', '_sale_price_dates_to', '_sale_price_dates_from',
404
-
405
- );
406
- foreach( $keys as $key ){
407
- if( !isset( $custom_prices[$key] ) ){ $custom_prices[$key] = ''; }
408
- }
409
-
410
- foreach( $custom_prices as $custom_price_key => $custom_price_value ){
411
- update_post_meta( $post_id, $custom_price_key.'_'.$code, $custom_price_value );
412
- }
413
- if ( $custom_prices[ '_sale_price_dates_to' ] && ! $custom_prices[ '_sale_price_dates_from' ] ) {
414
- update_post_meta($post_id, '_sale_price_dates_from_' . $code, strtotime( 'NOW', current_time( 'timestamp' ) ) );
415
- }
416
- // Update price if on sale
417
- if ( $custom_prices[ '_sale_price' ] != '' && $custom_prices[ '_sale_price_dates_to' ] == '' && $custom_prices[ '_sale_price_dates_from' ] == '' ){
418
- $price = stripslashes( $custom_prices[ '_sale_price' ] );
419
- update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_sale_price' ] ) );
420
- }else{
421
- $price = stripslashes( $custom_prices[ '_regular_price' ] );
422
- update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_regular_price' ] ) );
423
- }
424
-
425
- if ( $custom_prices[ '_sale_price' ] != '' && $custom_prices[ '_sale_price_dates_from' ] < strtotime( 'NOW', current_time( 'timestamp' ) ) ){
426
- update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_sale_price' ] ) );
427
- $price = stripslashes( $custom_prices[ '_sale_price' ] );
428
- }
429
-
430
- if ( $custom_prices[ '_sale_price_dates_to' ] && $custom_prices[ '_sale_price_dates_to' ] < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
431
- update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_regular_price' ] ) );
432
- $price = stripslashes( $custom_prices[ '_regular_price' ] );
433
- update_post_meta( $post_id, '_sale_price_dates_from_'.$code, '' );
434
- update_post_meta( $post_id, '_sale_price_dates_to_'.$code, '' );
435
- }
436
-
437
- return $price;
438
- }
439
-
440
- public function sync_product_variations_custom_prices( $product_id ){
441
- global $wpdb;
442
-
443
- $is_variable_product = $this->woocommerce_wpml->products->is_variable_product( $product_id );
444
- if( $is_variable_product ){
445
- $get_all_post_variations = $wpdb->get_results(
446
- $wpdb->prepare(
447
- "SELECT * FROM {$wpdb->posts}
448
- WHERE post_status IN ('publish','private')
449
- AND post_type = 'product_variation'
450
- AND post_parent = %d
451
- ORDER BY ID"
452
- ,$product_id )
453
- );
454
- $duplicated_post_variation_ids = array();
455
- $min_max_prices = array();
456
-
457
- foreach( $get_all_post_variations as $k => $post_data ){
458
- $duplicated_post_variation_ids[] = $post_data->ID;
459
- //save files option
460
- $this->woocommerce_wpml->downloadable->save_files_option( $post_data->ID );
461
-
462
- if( !isset( $_POST[ '_wcml_custom_prices' ][ $post_data->ID ] ) ){
463
- continue; // save changes for individual variation
464
- }
465
- //save custom prices for variation
466
- $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_variation_' . $post_data->ID . '_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
467
- if( isset( $_POST['_wcml_custom_prices'][$post_data->ID]) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices_variation_' . $post_data->ID ) ){
468
- update_post_meta( $post_data->ID, '_wcml_custom_prices_status', $_POST[ '_wcml_custom_prices' ][ $post_data->ID ] );
469
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
470
-
471
- if( $_POST[ '_wcml_custom_prices' ][ $post_data->ID ] == 1 ){
472
- foreach( $currencies as $code => $currency ){
473
- $sale_price = $_POST[ '_custom_variation_sale_price' ][ $code ][ $post_data->ID ];
474
- $regular_price = $_POST[ '_custom_variation_regular_price' ][ $code ][ $post_data->ID ];
475
- $date_from = strtotime( $_POST[ '_custom_variation_sale_price_dates_from' ][ $code ][ $post_data->ID ] );
476
- $date_to = strtotime( $_POST[ '_custom_variation_sale_price_dates_to' ][ $code ][ $post_data->ID ] );
477
- $schedule = $_POST[ '_wcml_schedule' ][ $code ][ $post_data->ID ];
478
- $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
479
- array( '_regular_price' => $regular_price,
480
- '_sale_price' => $sale_price,
481
- '_wcml_schedule_' => $schedule,
482
- '_sale_price_dates_from' => $date_from,
483
- '_sale_price_dates_to' => $date_to ),
484
- $code,
485
- $post_data->ID
486
- );
487
- $price = $this->update_custom_prices( $post_data->ID, $custom_prices, $code );
488
-
489
- if( !isset( $min_max_prices[ '_min_variation_price_'.$code ] ) || ( $price && $price < $min_max_prices[ '_min_variation_price_'.$code ] ) ){
490
- $min_max_prices[ '_min_variation_price_'.$code ] = $price;
491
- $min_max_prices[ '_min_price_variation_id_'.$code ] = $post_data->ID;
492
- }
493
-
494
- if( !isset( $min_max_prices[ '_max_variation_price_'.$code ] ) || ( $price && $price > $min_max_prices[ '_max_variation_price_'.$code ] ) ){
495
- $min_max_prices[ '_max_variation_price_'.$code ] = $price;
496
- $min_max_prices[ '_max_price_variation_id_'.$code ] = $post_data->ID;
497
- }
498
-
499
- if( !isset( $min_max_prices[ '_min_variation_regular_price_'.$code ] ) || ( $regular_price && $regular_price < $min_max_prices[ '_min_variation_regular_price_'.$code ] ) ){
500
- $min_max_prices[ '_min_variation_regular_price_'.$code ] = $regular_price;
501
- }
502
-
503
- if( !isset( $min_max_prices[ '_max_variation_regular_price_'.$code ] ) || ( $regular_price && $regular_price > $min_max_prices[ '_max_variation_regular_price_'.$code ] ) ){
504
- $min_max_prices[ '_max_variation_regular_price_'.$code ] = $regular_price;
505
- }
506
-
507
- if( !isset( $min_max_prices[ '_min_variation_sale_price_'.$code ] ) || ( $sale_price && $sale_price < $min_max_prices[ '_min_variation_sale_price_'.$code ] ) ){
508
- $min_max_prices[ '_min_variation_sale_price_'.$code ] = $sale_price;
509
- }
510
-
511
- if( !isset( $min_max_prices[ '_max_variation_sale_price_'.$code ] ) || ( $sale_price && $sale_price > $min_max_prices[ '_max_variation_sale_price_'.$code ] ) ){
512
- $min_max_prices[ '_max_variation_sale_price_'.$code ] = $sale_price;
513
- }
514
- }
515
- }
516
- }
517
- }
518
- }
519
- }
520
-
521
  }
1
+ <?php
2
+
3
+ class WCML_Custom_Prices{
4
+
5
+ private $woocommerce_wpml;
6
+
7
+ public function __construct( &$woocommerce_wpml ){
8
+ add_filter( 'init', array( $this, 'custom_prices_init' ) );
9
+ $this->woocommerce_wpml = $woocommerce_wpml;
10
+ }
11
+
12
+ public function custom_prices_init(){
13
+ if ( is_admin() ) {
14
+ add_action( 'woocommerce_variation_options', array($this, 'add_individual_variation_nonce'), 10, 3 );
15
+
16
+ //custom prices for different currencies for products/variations [BACKEND]
17
+ add_action( 'woocommerce_product_options_pricing', array($this, 'woocommerce_product_options_custom_pricing') );
18
+ add_action( 'woocommerce_product_after_variable_attributes', array($this, 'woocommerce_product_after_variable_attributes_custom_pricing'), 10, 3 );
19
+
20
+ }
21
+
22
+ if( version_compare( WC_VERSION , '2.7', '<' ) ){
23
+ add_action( 'woocommerce_get_children', array( $this, 'filter_product_variations_with_custom_prices' ), 10 );
24
+ }else{
25
+ add_action( 'woocommerce_product_get_children', array( $this, 'filter_product_variations_with_custom_prices' ), 10 );
26
+ }
27
+
28
+ add_filter( 'loop_shop_post_in', array( $this, 'filter_products_with_custom_prices' ), 100 );
29
+
30
+ }
31
+
32
+ public function add_individual_variation_nonce($loop, $variation_data, $variation){
33
+
34
+ wp_nonce_field('wcml_save_custom_prices_variation_' . $variation->ID, '_wcml_custom_prices_variation_' . $variation->ID . '_nonce');
35
+
36
+ }
37
+
38
+ public function get_product_custom_prices($product_id, $currency = false){
39
+ global $wpdb, $sitepress;
40
+
41
+ if( empty( $currency ) ){
42
+ $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
43
+ }
44
+
45
+ if( get_option('woocommerce_currency') == $currency ){
46
+ return false;
47
+ }
48
+
49
+ $original_product_id = $product_id;
50
+ $post_type = get_post_type($product_id);
51
+ $product_translations = $sitepress->get_element_translations($sitepress->get_element_trid($product_id, 'post_'.$post_type), 'post_'.$post_type);
52
+ foreach($product_translations as $translation){
53
+ if( $translation->original ){
54
+ $original_product_id = $translation->element_id;
55
+ break;
56
+ }
57
+ }
58
+
59
+ $product_meta = get_post_custom($original_product_id);
60
+
61
+ $custom_prices = false;
62
+
63
+ if(!empty($product_meta['_wcml_custom_prices_status'][0])){
64
+
65
+ $prices_keys = array(
66
+ '_price', '_regular_price', '_sale_price',
67
+ '_min_variation_price', '_max_variation_price',
68
+ '_min_variation_regular_price', '_max_variation_regular_price',
69
+ '_min_variation_sale_price', '_max_variation_sale_price');
70
+
71
+ foreach($prices_keys as $key){
72
+
73
+ if(!empty($product_meta[$key . '_' . $currency][0])){
74
+ $custom_prices[$key] = $product_meta[$key . '_' . $currency][0];
75
+ }
76
+
77
+ }
78
+
79
+ }
80
+
81
+ if(!isset($custom_prices['_price'])) return false;
82
+
83
+ $current__price_value = $custom_prices['_price'];
84
+
85
+ // update sale price
86
+ if(!empty($custom_prices['_sale_price'])){
87
+
88
+ if(!empty($product_meta['_wcml_schedule_' . $currency][0])){
89
+ // custom dates
90
+ if(!empty($product_meta['_sale_price_dates_from_' . $currency][0]) && !empty($product_meta['_sale_price_dates_to_' . $currency][0])){
91
+ if(current_time('timestamp') > $product_meta['_sale_price_dates_from_' . $currency][0] && current_time('timestamp') < $product_meta['_sale_price_dates_to_' . $currency][0]){
92
+ $custom_prices['_price'] = $custom_prices['_sale_price'];
93
+ }else{
94
+ $custom_prices['_price'] = $custom_prices['_regular_price'];
95
+ }
96
+ }else{
97
+ $custom_prices['_price'] = $custom_prices['_sale_price'];
98
+ }
99
+
100
+ }else{
101
+ // inherit
102
+ if(!empty($product_meta['_sale_price_dates_from'][0]) && !empty($product_meta['_sale_price_dates_to'][0])){
103
+ if(current_time('timestamp') > $product_meta['_sale_price_dates_from'][0] && current_time('timestamp') < $product_meta['_sale_price_dates_to'][0]){
104
+ $custom_prices['_price'] = $custom_prices['_sale_price'];
105
+ }else{
106
+ $custom_prices['_price'] = $custom_prices['_regular_price'];
107
+ }
108
+ }else{
109
+ $custom_prices['_price'] = $custom_prices['_sale_price'];
110
+ }
111
+ }
112
+
113
+ }
114
+
115
+ if($custom_prices['_price'] != $current__price_value){
116
+ update_post_meta($product_id, '_price_' . $currency, $custom_prices['_price']);
117
+ }
118
+
119
+ // detemine min/max variation prices
120
+ if(!empty($product_meta['_min_variation_price'])){
121
+
122
+ static $product_min_max_prices = array();
123
+
124
+ if(empty($product_min_max_prices[$product_id])){
125
+
126
+ // get variation ids
127
+ $variation_ids = $wpdb->get_col($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE post_parent = %d", $product_id));
128
+
129
+ // variations with custom prices
130
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_wcml_custom_prices_status'",join(',', $variation_ids)));
131
+ foreach($res as $row){
132
+ $custom_prices_enabled[$row->post_id] = $row->meta_value;
133
+ }
134
+
135
+ // REGULAR PRICES
136
+ // get custom prices
137
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_regular_price_" . $currency . "'",join(',', $variation_ids)));
138
+ foreach($res as $row){
139
+ $regular_prices[$row->post_id] = $row->meta_value;
140
+ }
141
+
142
+ // get default prices (default currency)
143
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_regular_price'",join(',', $variation_ids)));
144
+ foreach($res as $row){
145
+ $default_regular_prices[$row->post_id] = $row->meta_value;
146
+ }
147
+
148
+ // include the dynamic prices
149
+ foreach($variation_ids as $vid){
150
+ if(empty($regular_prices[$vid]) && isset($default_regular_prices[$vid])){
151
+ $regular_prices[$vid] = apply_filters('wcml_raw_price_amount', $default_regular_prices[$vid] );
152
+ }
153
+ }
154
+
155
+ // SALE PRICES
156
+ // get custom prices
157
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key=%s",join(',', $variation_ids),'_sale_price_'.$currency));
158
+ foreach($res as $row){
159
+ $custom_sale_prices[$row->post_id] = $row->meta_value;
160
+ }
161
+
162
+ // get default prices (default currency)
163
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_sale_price' AND meta_value <> ''",join(',', $variation_ids)));
164
+ foreach($res as $row){
165
+ $default_sale_prices[$row->post_id] = $row->meta_value;
166
+ }
167
+
168
+ // include the dynamic prices
169
+ foreach($variation_ids as $vid){
170
+ if(empty($sale_prices[$vid]) && isset($default_sale_prices[$vid])){
171
+ $sale_prices[$vid] = apply_filters('wcml_raw_price_amount', $default_sale_prices[$vid]);
172
+ }
173
+ }
174
+
175
+
176
+ // PRICES
177
+ // get custom prices
178
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key=%s",join(',', $variation_ids),'_price_'.$currency));
179
+ foreach($res as $row){
180
+ $custom_prices_prices[$row->post_id] = $row->meta_value;
181
+ }
182
+
183
+ // get default prices (default currency)
184
+ $res = $wpdb->get_results($wpdb->prepare("SELECT post_id, meta_value FROM {$wpdb->postmeta} WHERE post_id IN(%s) AND meta_key='_price'",join(',', $variation_ids)));
185
+ foreach($res as $row){
186
+ $default_prices[$row->post_id] = $row->meta_value;
187
+ }
188
+
189
+ // include the dynamic prices
190
+ foreach($variation_ids as $vid){
191
+ if(empty($custom_prices_prices[$vid]) && isset($default_prices[$vid])){
192
+ $prices[$vid] = apply_filters('wcml_raw_price_amount', $default_prices[$vid]);
193
+ }
194
+ }
195
+
196
+ if(!empty($regular_prices)){
197
+ $product_min_max_prices[$product_id]['_min_variation_regular_price'] = min($regular_prices);
198
+ $product_min_max_prices[$product_id]['_max_variation_regular_price'] = max($regular_prices);
199
+ }
200
+
201
+ if(!empty($sale_prices)){
202
+ $product_min_max_prices[$product_id]['_min_variation_sale_price'] = min($sale_prices);
203
+ $product_min_max_prices[$product_id]['_max_variation_sale_price'] = max($sale_prices);
204
+ }
205
+
206
+ if(!empty($prices)){
207
+ $product_min_max_prices[$product_id]['_min_variation_price'] = min($prices);
208
+ $product_min_max_prices[$product_id]['_max_variation_price'] = max($prices);
209
+ }
210
+
211
+
212
+ }
213
+
214
+ if(isset($product_min_max_prices[$product_id]['_min_variation_regular_price'])){
215
+ $custom_prices['_min_variation_regular_price'] = $product_min_max_prices[$product_id]['_min_variation_regular_price'];
216
+ }
217
+ if(isset($product_min_max_prices[$product_id]['_max_variation_regular_price'])){
218
+ $custom_prices['_max_variation_regular_price'] = $product_min_max_prices[$product_id]['_max_variation_regular_price'];
219
+ }
220
+
221
+ if(isset($product_min_max_prices[$product_id]['_min_variation_sale_price'])){
222
+ $custom_prices['_min_variation_sale_price'] = $product_min_max_prices[$product_id]['_min_variation_sale_price'];
223
+ }
224
+ if(isset($product_min_max_prices[$product_id]['_max_variation_sale_price'])){
225
+ $custom_prices['_max_variation_sale_price'] = $product_min_max_prices[$product_id]['_max_variation_sale_price'];
226
+ }
227
+
228
+ if(isset($product_min_max_prices[$product_id]['_min_variation_price'])){
229
+ $custom_prices['_min_variation_price'] = $product_min_max_prices[$product_id]['_min_variation_price'];
230
+ }
231
+ if(isset($product_min_max_prices[$product_id]['_max_variation_price'])){
232
+ $custom_prices['_max_variation_price'] = $product_min_max_prices[$product_id]['_max_variation_price'];
233
+ }
234
+
235
+ }
236
+
237
+ $custom_prices = apply_filters( 'wcml_product_custom_prices', $custom_prices, $product_id, $currency );
238
+
239
+ return $custom_prices;
240
+ }
241
+
242
+ public function woocommerce_product_options_custom_pricing(){
243
+ global $pagenow;
244
+
245
+ $this->load_custom_prices_js_css();
246
+
247
+ if( ( isset($_GET['post'] ) && ( get_post_type($_GET['post']) != 'product' || !$this->woocommerce_wpml->products->is_original_product( $_GET['post'] ) ) ) ||
248
+ ( isset($_GET['post_type'] ) && $_GET['post_type'] == 'product' && isset( $_GET['source_lang'] ) ) ){
249
+ return;
250
+ }
251
+
252
+ $product_id = 'new';
253
+
254
+ if($pagenow == 'post.php' && isset($_GET['post']) && get_post_type($_GET['post']) == 'product'){
255
+ $product_id = $_GET['post'];
256
+ }
257
+
258
+ $this->custom_pricing_output($product_id);
259
+
260
+ do_action( 'wcml_after_custom_prices_block', $product_id );
261
+
262
+ wp_nonce_field('wcml_save_custom_prices','_wcml_custom_prices_nonce');
263
+
264
+ }
265
+
266
+ public function woocommerce_product_after_variable_attributes_custom_pricing($loop, $variation_data, $variation){
267
+
268
+ if( $this->woocommerce_wpml->products->is_original_product( $variation->post_parent ) ) {
269
+
270
+ echo '<tr><td>';
271
+ $this->custom_pricing_output( $variation->ID );
272
+ echo '</td></tr>';
273
+
274
+ }
275
+
276
+ }
277
+
278
+ private function load_custom_prices_js_css(){
279
+ wp_register_style( 'wpml-wcml-prices', WCML_PLUGIN_URL . '/res/css/wcml-prices.css', null, WCML_VERSION );
280
+ wp_register_script( 'wcml-tm-scripts-prices', WCML_PLUGIN_URL . '/res/js/prices' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
281
+
282
+ wp_enqueue_style('wpml-wcml-prices');
283
+ wp_enqueue_script('wcml-tm-scripts-prices');
284
+ }
285
+
286
+ private function custom_pricing_output( $post_id = false){
287
+
288
+ $custom_prices_ui = new WCML_Custom_Prices_UI( $this->woocommerce_wpml, $post_id );
289
+ $custom_prices_ui->show();
290
+
291
+ }
292
+
293
+ //display variations with custom prices when "Show only products with custom prices in secondary currencies" enabled
294
+ public function filter_product_variations_with_custom_prices( $children ){
295
+
296
+ if( is_product() && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
297
+ isset($this->woocommerce_wpml->settings['display_custom_prices']) &&
298
+ $this->woocommerce_wpml->settings['display_custom_prices'] ){
299
+
300
+ foreach( $children as $key => $child ){
301
+ $orig_lang = $this->woocommerce_wpml->products->get_original_product_language( $child );
302
+ $orig_child_id = apply_filters( 'translate_object_id', $child, get_post_type( $child ), true, $orig_lang );
303
+
304
+ if( !get_post_meta( $orig_child_id, '_wcml_custom_prices_status', true ) ){
305
+ unset( $children[ $key ] );
306
+ }
307
+ }
308
+ }
309
+
310
+ return $children;
311
+
312
+ }
313
+
314
+ // display products with custom prices only if enabled "Show only products with custom prices in secondary currencies" option on settings page
315
+ public function filter_products_with_custom_prices( $filtered_posts ) {
316
+ global $wpdb;
317
+
318
+ if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
319
+ isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
320
+ $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ){
321
+
322
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
323
+ $woocommerce_currency = get_option( 'woocommerce_currency' );
324
+
325
+ if( $client_currency == $woocommerce_currency ){
326
+ return $filtered_posts;
327
+ }
328
+ $matched_products = array();
329
+ $matched_products_query = $wpdb->get_results( "
330
+ SELECT DISTINCT ID, post_parent, post_type FROM {$wpdb->posts}
331
+ INNER JOIN {$wpdb->postmeta} ON ID = post_id
332
+ WHERE post_type IN ( 'product', 'product_variation' ) AND post_status = 'publish' AND meta_key = '_wcml_custom_prices_status' AND meta_value = 1
333
+ ", OBJECT_K );
334
+
335
+ if ( $matched_products_query ) {
336
+ remove_filter( 'get_post_metadata', array( $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ), 10, 4);
337
+ foreach ( $matched_products_query as $product ) {
338
+ if( !get_post_meta( $product->ID,'_price_'.$client_currency, true ) ) continue;
339
+ if ( $product->post_type == 'product' )
340
+ $matched_products[] = apply_filters( 'translate_object_id', $product->ID, 'product', true );
341
+ if ( $product->post_parent > 0 && ! in_array( $product->post_parent, $matched_products ) )
342
+ $matched_products[] = apply_filters( 'translate_object_id', $product->post_parent, get_post_type( $product->post_parent ), true );
343
+ }
344
+ add_filter('get_post_metadata', array( $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ), 10, 4);
345
+ }
346
+
347
+ // Filter the id's
348
+ if ( sizeof( $filtered_posts ) == 0) {
349
+ $filtered_posts = $matched_products;
350
+ $filtered_posts[] = 0;
351
+ } else {
352
+ $filtered_posts = array_intersect( $filtered_posts, $matched_products );
353
+ $filtered_posts[] = 0;
354
+ }
355
+ }
356
+
357
+ return $filtered_posts;
358
+ }
359
+
360
+ public function save_custom_prices( $post_id ){
361
+ $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
362
+
363
+ if( isset( $_POST[ '_wcml_custom_prices' ] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices' ) && !$this->woocommerce_wpml->products->is_variable_product( $post_id ) ){
364
+ if( isset( $_POST[ '_wcml_custom_prices' ][ $post_id ] ) || isset( $_POST[ '_wcml_custom_prices' ][ 'new' ] ) ) {
365
+ $wcml_custom_prices_option = isset( $_POST[ '_wcml_custom_prices' ][ $post_id ] ) ? $_POST[ '_wcml_custom_prices' ][ $post_id ] : $_POST[ '_wcml_custom_prices' ][ 'new' ];
366
+ }else{
367
+ $current_option = get_post_meta( $post_id, '_wcml_custom_prices_status', true );
368
+ $wcml_custom_prices_option = $current_option ? $current_option : 0;
369
+ }
370
+ update_post_meta( $post_id, '_wcml_custom_prices_status', $wcml_custom_prices_option );
371
+
372
+ if( $wcml_custom_prices_option == 1){
373
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
374
+ foreach( $currencies as $code => $currency ){
375
+ $sale_price = wc_format_decimal( $_POST[ '_custom_sale_price' ][ $code ] );
376
+ $regular_price = wc_format_decimal( $_POST[ '_custom_regular_price' ][ $code ] );
377
+ $date_from = isset( $_POST[ '_custom_sale_price_dates_from' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_from' ][ $code ] ) : '';
378
+ $date_to = isset( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) ? strtotime( $_POST[ '_custom_sale_price_dates_to' ][ $code ] ) : '';
379
+ $schedule = $_POST[ '_wcml_schedule' ][ $code ];
380
+
381
+ $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
382
+ array( '_regular_price' => $regular_price,
383
+ '_sale_price' => $sale_price,
384
+ '_wcml_schedule' => $schedule,
385
+ '_sale_price_dates_from' => $date_from,
386
+ '_sale_price_dates_to' => $date_to ),
387
+ $code
388
+ );
389
+ $this->update_custom_prices( $post_id, $custom_prices , $code );
390
+
391
+ do_action( 'wcml_after_save_custom_prices', $post_id );
392
+ }
393
+ }
394
+ }
395
+ }
396
+
397
+ public function update_custom_prices( $post_id, $custom_prices, $code ){
398
+ $price = '';
399
+
400
+ // initialization
401
+ $keys = array(
402
+ '_sale_price_dates_to', '_sale_price_dates_from',
403
+ '_sale_price', '_sale_price_dates_to', '_sale_price_dates_from',
404
+
405
+ );
406
+ foreach( $keys as $key ){
407
+ if( !isset( $custom_prices[$key] ) ){ $custom_prices[$key] = ''; }
408
+ }
409
+
410
+ foreach( $custom_prices as $custom_price_key => $custom_price_value ){
411
+ update_post_meta( $post_id, $custom_price_key.'_'.$code, $custom_price_value );
412
+ }
413
+ if ( $custom_prices[ '_sale_price_dates_to' ] && ! $custom_prices[ '_sale_price_dates_from' ] ) {
414
+ update_post_meta($post_id, '_sale_price_dates_from_' . $code, strtotime( 'NOW', current_time( 'timestamp' ) ) );
415
+ }
416
+ // Update price if on sale
417
+ if ( $custom_prices[ '_sale_price' ] != '' && $custom_prices[ '_sale_price_dates_to' ] == '' && $custom_prices[ '_sale_price_dates_from' ] == '' ){
418
+ $price = stripslashes( $custom_prices[ '_sale_price' ] );
419
+ update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_sale_price' ] ) );
420
+ }else{
421
+ $price = stripslashes( $custom_prices[ '_regular_price' ] );
422
+ update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_regular_price' ] ) );
423
+ }
424
+
425
+ if ( $custom_prices[ '_sale_price' ] != '' && $custom_prices[ '_sale_price_dates_from' ] < strtotime( 'NOW', current_time( 'timestamp' ) ) ){
426
+ update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_sale_price' ] ) );
427
+ $price = stripslashes( $custom_prices[ '_sale_price' ] );
428
+ }
429
+
430
+ if ( $custom_prices[ '_sale_price_dates_to' ] && $custom_prices[ '_sale_price_dates_to' ] < strtotime( 'NOW', current_time( 'timestamp' ) ) ) {
431
+ update_post_meta( $post_id, '_price_'.$code, stripslashes( $custom_prices[ '_regular_price' ] ) );
432
+ $price = stripslashes( $custom_prices[ '_regular_price' ] );
433
+ update_post_meta( $post_id, '_sale_price_dates_from_'.$code, '' );
434
+ update_post_meta( $post_id, '_sale_price_dates_to_'.$code, '' );
435
+ }
436
+
437
+ return $price;
438
+ }
439
+
440
+ public function sync_product_variations_custom_prices( $product_id ){
441
+
442
+ if( isset( $_POST[ '_wcml_custom_prices' ][ $product_id ] ) ){
443
+
444
+ //save custom prices for variation
445
+ $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_variation_' . $product_id . '_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
446
+ if( isset( $_POST[ '_wcml_custom_prices' ][ $product_id ] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_prices_variation_' . $product_id ) ){
447
+ update_post_meta( $product_id, '_wcml_custom_prices_status', $_POST[ '_wcml_custom_prices' ][ $product_id ] );
448
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
449
+
450
+ if( $_POST[ '_wcml_custom_prices' ][ $product_id ] == 1 ){
451
+ foreach( $currencies as $code => $currency ){
452
+ $sale_price = $_POST[ '_custom_variation_sale_price' ][ $code ][ $product_id ];
453
+ $regular_price = $_POST[ '_custom_variation_regular_price' ][ $code ][ $product_id ];
454
+ $date_from = strtotime( $_POST[ '_custom_variation_sale_price_dates_from' ][ $code ][ $product_id ] );
455
+ $date_to = strtotime( $_POST[ '_custom_variation_sale_price_dates_to' ][ $code ][ $product_id ] );
456
+ $schedule = $_POST[ '_wcml_schedule' ][ $code ][ $product_id ];
457
+ $custom_prices = apply_filters( 'wcml_update_custom_prices_values',
458
+ array( '_regular_price' => $regular_price,
459
+ '_sale_price' => $sale_price,
460
+ '_wcml_schedule_' => $schedule,
461
+ '_sale_price_dates_from' => $date_from,
462
+ '_sale_price_dates_to' => $date_to ),
463
+ $code,
464
+ $product_id
465
+ );
466
+ $price = $this->update_custom_prices( $product_id, $custom_prices, $code );
467
+ }
468
+ }
469
+ }
470
+ }
471
+ }
472
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
473
  }
inc/currencies/class-wcml-exchange-rates.php CHANGED
@@ -1,345 +1,345 @@
1
- <?php
2
-
3
- class WCML_Exchange_Rates{
4
-
5
- /**
6
- * @var woocommerce_wpml
7
- */
8
- private $woocommerce_wpml;
9
-
10
- /**
11
- * @var array
12
- */
13
- private $services = array();
14
-
15
- /**
16
- * @var array
17
- */
18
- private $settings;
19
-
20
- const cronjob_event = 'wcml_exchange_rates_update';
21
-
22
- function __construct( $woocommerce_wpml ) {
23
-
24
- $this->woocommerce_wpml =& $woocommerce_wpml;
25
-
26
- $this->initialize_settings();
27
-
28
- // Load built in services
29
- $this->services['yahoo'] = new WCML_Exchange_Rates_YahooFinance();
30
- $this->services['fixierio'] = new WCML_Exchange_Rates_Fixierio();
31
- $this->services['currencylayer'] = new WCML_Exchange_Rates_Currencylayer();
32
-
33
- if( is_admin() ){
34
- add_action( 'wcml_saved_mc_options', array($this, 'update_exchange_rate_options' ) ); //before init
35
- }
36
-
37
- add_action( 'init', array( $this, 'init' ) );
38
-
39
- }
40
-
41
- public function init(){
42
-
43
- if( $this->woocommerce_wpml->multi_currency->get_currencies() ){
44
-
45
- if( is_admin() ){
46
- add_action( 'wp_ajax_wcml_update_exchange_rates', array( $this, 'update_exchange_rates_ajax') );
47
- }
48
-
49
- add_filter( 'cron_schedules', array( $this, 'cron_schedules' ) );
50
- add_action( self::cronjob_event, array( $this, 'update_exchange_rates' ) );
51
-
52
- }
53
-
54
- }
55
-
56
- private function initialize_settings(){
57
-
58
- if( !isset( $this->woocommerce_wpml->settings['multi_currency']['exchange_rates'] ) ){
59
-
60
- $this->settings = array(
61
- 'automatic' => 0,
62
- 'service' => 'yahoo',
63
- 'lifting_charge' => 0,
64
- 'schedule' => 'manual',
65
- 'week_day' => 1,
66
- 'month_day' => 1
67
- );
68
-
69
- $this->save_settings();
70
-
71
- } else {
72
- $this->settings =& $this->woocommerce_wpml->settings['multi_currency']['exchange_rates'];
73
- }
74
-
75
- }
76
-
77
- public function get_services(){
78
- return $this->services;
79
- }
80
-
81
- /**
82
- * @param $service_id string
83
- * @param $service WCML_Exchange_Rate_Service
84
- */
85
- public function add_service( $service_id, $service ){
86
- $this->services[ $service_id ] = $service;
87
- }
88
-
89
- public function get_settings(){
90
- return $this->settings;
91
- }
92
-
93
- public function get_setting( $key ){
94
- return isset( $this->settings[$key] ) ? $this->settings[$key] : null;
95
- }
96
-
97
- public function save_settings(){
98
-
99
- $this->woocommerce_wpml->settings['multi_currency']['exchange_rates'] = $this->settings;
100
- $this->woocommerce_wpml->update_settings();
101
- }
102
-
103
- public function save_setting( $key, $value ){
104
- $this->settings[$key] = $value;
105
- $this->save_settings();
106
- }
107
-
108
- public function update_exchange_rates_ajax(){
109
-
110
- $response = array();
111
-
112
- if( wp_create_nonce( 'update-exchange-rates' ) == $_POST['wcml_nonce'] ) {
113
-
114
- try {
115
-
116
- $rates = $this->update_exchange_rates();
117
- $response['success'] = 1;
118
- $response['last_updated'] = date_i18n( 'F j, Y g:i a', $this->settings['last_updated'] );
119
- $response['rates'] = $rates;
120
-
121
- } catch ( Exception $e ) {
122
-
123
- $response['success'] = 0;
124
- $response['error'] = $e->getMessage();
125
- $response['service'] = $this->settings['service'];
126
-
127
- }
128
-
129
- } else {
130
-
131
- $response['success'] = 0;
132
- $response['error'] = 'Invalid nonce';
133
-
134
- }
135
-
136
- wp_send_json( $response );
137
- }
138
-
139
- public function update_exchange_rates(){
140
-
141
- if( isset( $this->services[ $this->settings['service'] ]) ){
142
- $service =& $this->services[ $this->settings['service'] ];
143
-
144
- $currencies = $this->woocommerce_wpml->multi_currency->get_currency_codes();
145
- $default_currency = get_option( 'woocommerce_currency' );
146
- $secondary_currencies = array_diff( $currencies, array( $default_currency ) );
147
-
148
- try{
149
- $rates = $service->get_rates( $default_currency, $secondary_currencies );
150
- } catch (Exception $e){
151
- if( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ){
152
- error_log( "Exchange rates update error (" . $this->settings['service'] . "): " . $e->getMessage() );
153
- }
154
- throw new Exception( $e->getMessage() );
155
- return;
156
- }
157
-
158
- $this->apply_lifting_charge( $rates );
159
-
160
- foreach( $rates as $to => $rate ){
161
- if( $rate && is_numeric( $rate ) ){
162
- $this->save_exchage_rate( $to, $rate );
163
- }
164
- }
165
- }
166
-
167
- $this->settings['last_updated'] = current_time( 'timestamp' );
168
- $this->save_settings();
169
-
170
- return $rates;
171
- }
172
-
173
- public function apply_lifting_charge( &$rates ){
174
- foreach( $rates as $k => $rate ){
175
- $rates[$k] = round( $rate * ( 1 + $this->settings['lifting_charge'] / 100 ), 4 );
176
- }
177
- }
178
-
179
- private function save_exchage_rate( $currency, $rate ){
180
-
181
- $this->woocommerce_wpml->settings['currency_options'][$currency]['previous_rate'] =
182
- $this->woocommerce_wpml->settings['currency_options'][$currency]['rate'];
183
- $this->woocommerce_wpml->settings['currency_options'][$currency]['rate'] = $rate;
184
- $this->woocommerce_wpml->update_settings();
185
-
186
- }
187
-
188
- public function get_currency_rate( $currency ){
189
- return $this->woocommerce_wpml->settings['currency_options'][$currency]['rate'];
190
- }
191
-
192
- public function update_exchange_rate_options( $post_data ){
193
-
194
- if( isset( $post_data['exchange-rates-automatic'] ) && $post_data['exchange-rates-automatic'] ) {
195
-
196
- $this->settings['automatic'] = intval($post_data['exchange-rates-automatic']);
197
-
198
- if ( isset($post_data['exchange-rates-service']) ) {
199
-
200
- // clear errors for replaced service
201
- if( $post_data['exchange-rates-service'] != $this->settings['service'] ){
202
- $this->services[$this->settings['service']]->clear_last_error();
203
- }
204
-
205
- $this->settings['service'] = sanitize_text_field( $post_data['exchange-rates-service'] );
206
-
207
- }
208
-
209
- if ( isset($post_data['services']) ) {
210
-
211
- foreach ( $post_data['services'] as $service_id => $service_data ) {
212
- foreach( $service_data as $key => $value ){
213
- $this->services[$service_id]->save_setting( 'api-key', $value );
214
- }
215
- }
216
-
217
- }
218
-
219
- $this->settings['lifting_charge'] = is_numeric( $post_data['lifting_charge'] ) ? $post_data['lifting_charge'] : 0;
220
-
221
- if ( isset($post_data['update-schedule']) ) {
222
- $this->settings['schedule'] = sanitize_text_field( $post_data['update-schedule'] );
223
- }
224
-
225
- if ( isset($post_data['update-time']) ) {
226
- $this->settings['time'] = sanitize_text_field( $post_data['update-time'] );
227
- }
228
-
229
- if ( isset($post_data['update-weekly-day']) ) {
230
- $this->settings['week_day'] = sanitize_text_field( $post_data['update-weekly-day'] );
231
- }
232
-
233
- if ( isset($post_data['update-monthly-day']) ) {
234
- $this->settings['month_day'] = sanitize_text_field( $post_data['update-monthly-day'] );
235
- }
236
-
237
- if ( $this->settings['schedule'] === 'manual' ) {
238
- $this->delete_update_cronjob();
239
- } else {
240
- $this->enable_update_cronjob();
241
- }
242
-
243
- } else {
244
- $this->settings['automatic'] = 0;
245
- $this->delete_update_cronjob();
246
- }
247
-
248
- $this->save_settings();
249
-
250
-
251
- }
252
-
253
- public function enable_update_cronjob(){
254
-
255
- $schedule = wp_get_schedule( self::cronjob_event );
256
-
257
- if( $schedule != $this->settings['schedule'] ){
258
- $this->delete_update_cronjob();
259
- }
260
-
261
-
262
- if( $this->settings['schedule'] == 'monthly' ){
263
- $current_day = date('j');
264
- $days_in_current_month = cal_days_in_month( CAL_GREGORIAN, date('n'), date('Y') );
265
-
266
- if( $this->settings['month_day'] >= $current_day && $this->settings['month_day'] <= $days_in_current_month ){
267
- $days = $this->settings['month_day'] - $current_day;
268
- }else{
269
- $days = $days_in_current_month - $current_day + $this->settings['month_day'];
270
- }
271
-
272
- $time_offset = time() + $days * 86400;
273
- $schedule = 'wcml_' . $this->settings['schedule'] . '_on_'