WooCommerce Multilingual – run WooCommerce with WPML - Version 3.9.0

Version Description

Download this release

Release Info

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

Code changes from version 3.8.6 to 3.9.0

Files changed (61) hide show
  1. compatibility/class-wcml-accommodation-bookings.php +180 -180
  2. compatibility/class-wcml-adventure-tours.php +370 -370
  3. compatibility/class-wcml-ajax-layered-nav-widget.php +38 -38
  4. compatibility/class-wcml-aurum.php +17 -17
  5. compatibility/class-wcml-bookings.php +2217 -2055
  6. compatibility/class-wcml-bulk-stock-management.php +45 -45
  7. compatibility/class-wcml-checkout-addons.php +20 -20
  8. compatibility/class-wcml-checkout-field-editor.php +125 -125
  9. compatibility/class-wcml-compatibility-helper.php +18 -18
  10. compatibility/class-wcml-composite-products.php +479 -479
  11. compatibility/class-wcml-dynamic-pricing.php +116 -116
  12. compatibility/class-wcml-extra-product-options.php +107 -107
  13. compatibility/class-wcml-flatsome.php +16 -16
  14. compatibility/class-wcml-gravityforms.php +47 -47
  15. compatibility/class-wcml-jck-wssv.php +23 -23
  16. compatibility/class-wcml-mix-and-match-products.php +67 -67
  17. compatibility/class-wcml-per-product-shipping.php +30 -30
  18. compatibility/class-wcml-product-addons.php +247 -247
  19. compatibility/class-wcml-product-bundles.php +408 -408
  20. compatibility/class-wcml-sensei.php +231 -231
  21. compatibility/class-wcml-tab-manager.php +707 -628
  22. compatibility/class-wcml-table-rate-shipping.php +103 -89
  23. compatibility/class-wcml-variation-swatches-and-photos.php +62 -62
  24. compatibility/class-wcml-vpc.php +20 -20
  25. compatibility/class-wcml-wc-ajax-cart.php +16 -16
  26. compatibility/class-wcml-wc-name-your-price.php +24 -24
  27. compatibility/class-wcml-wc-subscriptions.php +185 -185
  28. compatibility/class-wcml-wcexporter.php +70 -70
  29. compatibility/class-wcml-wpseo.php +41 -41
  30. compatibility/res/css/wcml-bookings.css +61 -61
  31. compatibility/res/js/wcml-adventure-tours.js +31 -31
  32. compatibility/res/js/wcml-bookings.js +91 -91
  33. compatibility/res/js/wcml-composite.js +32 -32
  34. embedded/composer/installers/.gitignore +0 -3
  35. embedded/composer/installers/composer.json +0 -92
  36. inc/admin-menus/class-wcml-admin-menus.php +291 -271
  37. inc/admin-menus/class-wcml-links.php +24 -24
  38. inc/admin-menus/class-wcml-pointers.php +82 -0
  39. inc/admin-menus/class-wcml-setup.php +342 -334
  40. inc/class-wcml-ajax-setup.php +131 -119
  41. inc/class-wcml-attributes.php +403 -384
  42. inc/class-wcml-capabilities.php +32 -32
  43. inc/class-wcml-cart.php +261 -246
  44. inc/class-wcml-compatibility.php +170 -170
  45. inc/class-wcml-coupons.php +87 -72
  46. inc/class-wcml-dependencies.php +346 -369
  47. inc/class-wcml-emails.php +458 -483
  48. inc/class-wcml-endpoints.php +283 -266
  49. inc/class-wcml-fix-copied-custom-fields-wpml353.php +40 -0
  50. inc/class-wcml-install.php +221 -209
  51. inc/class-wcml-languages-upgrader.php +291 -283
  52. inc/class-wcml-locale.php +61 -61
  53. inc/class-wcml-media.php +183 -183
  54. inc/class-wcml-orders.php +377 -309
  55. inc/class-wcml-products-screen-options.php +46 -215
  56. inc/class-wcml-products.php +496 -436
  57. inc/class-wcml-reports.php +258 -258
  58. inc/class-wcml-requests.php +67 -67
  59. inc/class-wcml-resources.php +228 -218
  60. inc/class-wcml-store-pages.php +594 -519
  61. inc/class-wcml-terms.php +439 -1032
compatibility/class-wcml-accommodation-bookings.php CHANGED
@@ -1,181 +1,181 @@
1
- <?php
2
-
3
- class WCML_Accommodation_Bookings{
4
-
5
- /**
6
- * @var woocommerce_wpml
7
- */
8
- private $woocommerce_wpml;
9
-
10
- function __construct( &$woocommerce_wpml ){
11
-
12
- $this->woocommerce_wpml = $woocommerce_wpml;
13
-
14
- add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
15
- add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
16
- add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing' , array( $this , 'after_bookings_pricing' ) );
17
-
18
- add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
19
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
20
-
21
- add_action( 'init', array( $this, 'load_assets' ), 100 );
22
- }
23
-
24
- function wcml_price_field_after_booking_base_cost( $post_id ){
25
-
26
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
27
-
28
- }
29
-
30
- function wcml_price_field_after_booking_pricing_override_block_cost( $pricing, $post_id ){
31
-
32
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_override_block_cost', $pricing );
33
-
34
- }
35
-
36
- function after_bookings_pricing( $post_id ){
37
-
38
- if( $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
39
-
40
- $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
41
-
42
- $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
43
-
44
- echo '<div class="wcml_custom_costs">';
45
-
46
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
47
- echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
48
-
49
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
50
-
51
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
52
- echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
53
-
54
- wp_nonce_field( 'wcml_save_accommodation_bookings_custom_costs', '_wcml_custom_costs_nonce' );
55
-
56
- echo '</div>';
57
- }
58
-
59
- }
60
-
61
- function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
62
-
63
- if( ( !$check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
64
-
65
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
66
-
67
- $wc_currencies = get_woocommerce_currencies();
68
-
69
- echo '<div class="wcml_custom_cost_field" >';
70
-
71
- foreach($currencies as $currency_code => $currency){
72
-
73
- switch( $field ){
74
- case 'wcml_wc_booking_base_cost':
75
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_accommodation_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
76
- 'min' => '',
77
- 'step' => '0.01'
78
- ) ) );
79
- break;
80
-
81
-
82
- case 'wcml_wc_booking_pricing_override_block_cost':
83
-
84
- if( isset( $pricing[ 'override_block_'.$currency_code ] ) ){
85
- $value = $pricing[ 'override_block_'.$currency_code ];
86
- }else{
87
- $value = '';
88
- }
89
-
90
- echo '<div class="wcml_bookings_range_block" >';
91
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
92
- echo '<input type="number" step="0.01" name="wcml_wc_accommodation_booking_pricing_override_block_cost['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
93
- echo '</div>';
94
- break;
95
-
96
- default:
97
- break;
98
-
99
- }
100
-
101
- }
102
-
103
- echo '</div>';
104
-
105
- }
106
- }
107
-
108
- function save_custom_costs( $post_id, $post ){
109
-
110
- $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
111
-
112
- if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_accommodation_bookings_custom_costs' ) ){
113
-
114
- update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
115
-
116
- if( $_POST['_wcml_custom_costs'] == 1 ){
117
-
118
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
119
-
120
- foreach( $currencies as $code => $currency ){
121
-
122
- $wc_booking_base_cost = $_POST[ 'wcml_wc_accommodation_booking_base_cost' ][ $code ];
123
- update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
124
- update_post_meta( $post_id, '_price_'.$code, $wc_booking_base_cost );
125
-
126
- }
127
-
128
- $updated_meta = array();
129
- $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
130
-
131
- foreach ( maybe_unserialize( $booking_pricing ) as $key => $prices ) {
132
-
133
- $updated_meta[ $key ] = $prices;
134
-
135
- foreach ( $currencies as $code => $currency ) {
136
-
137
- $updated_meta[ $key ][ 'override_block_'.$code ] = $_POST[ 'wcml_wc_accommodation_booking_pricing_override_block_cost' ][ $code ];
138
-
139
- }
140
-
141
- }
142
-
143
- update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
144
-
145
- }
146
- }
147
-
148
- }
149
-
150
- function product_price_filter( $value, $object_id, $meta_key, $single ){
151
-
152
- if(
153
- get_post_type( $object_id ) == 'product' &&
154
- $meta_key == '_price' &&
155
- $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
156
- !is_admin() &&
157
- ( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
158
- ) {
159
-
160
- remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
161
-
162
- $original_language = $this->woocommerce_wpml->products->get_original_product_language( $object_id );
163
- $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
164
-
165
- if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
166
-
167
- $price = get_post_meta( $object_id, '_price_' . $currency , true );
168
- }
169
-
170
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
171
- }
172
-
173
- return isset( $price) ? $price : $value;
174
- }
175
-
176
- public function load_assets(){
177
-
178
- $this->woocommerce_wpml->compatibility->bookings->load_assets( 'accommodation-booking' );
179
- }
180
-
181
  }
1
+ <?php
2
+
3
+ class WCML_Accommodation_Bookings{
4
+
5
+ /**
6
+ * @var woocommerce_wpml
7
+ */
8
+ private $woocommerce_wpml;
9
+
10
+ function __construct( &$woocommerce_wpml ){
11
+
12
+ $this->woocommerce_wpml = $woocommerce_wpml;
13
+
14
+ add_action( 'woocommerce_accommodation_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
15
+ add_action( 'woocommerce_accommodation_bookings_after_booking_pricing_override_block_cost' , array( $this, 'wcml_price_field_after_booking_pricing_override_block_cost' ), 10, 2 );
16
+ add_action( 'woocommerce_accommodation_bookings_after_bookings_pricing' , array( $this , 'after_bookings_pricing' ) );
17
+
18
+ add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 2 );
19
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
20
+
21
+ add_action( 'init', array( $this, 'load_assets' ), 100 );
22
+ }
23
+
24
+ function wcml_price_field_after_booking_base_cost( $post_id ){
25
+
26
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
27
+
28
+ }
29
+
30
+ function wcml_price_field_after_booking_pricing_override_block_cost( $pricing, $post_id ){
31
+
32
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_override_block_cost', $pricing );
33
+
34
+ }
35
+
36
+ function after_bookings_pricing( $post_id ){
37
+
38
+ if( $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
39
+
40
+ $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
41
+
42
+ $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
43
+
44
+ echo '<div class="wcml_custom_costs">';
45
+
46
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
47
+ echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
48
+
49
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
50
+
51
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
52
+ echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
53
+
54
+ wp_nonce_field( 'wcml_save_accommodation_bookings_custom_costs', '_wcml_custom_costs_nonce' );
55
+
56
+ echo '</div>';
57
+ }
58
+
59
+ }
60
+
61
+ function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
62
+
63
+ if( ( !$check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
64
+
65
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
66
+
67
+ $wc_currencies = get_woocommerce_currencies();
68
+
69
+ echo '<div class="wcml_custom_cost_field" >';
70
+
71
+ foreach($currencies as $currency_code => $currency){
72
+
73
+ switch( $field ){
74
+ case 'wcml_wc_booking_base_cost':
75
+ woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_accommodation_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
76
+ 'min' => '',
77
+ 'step' => '0.01'
78
+ ) ) );
79
+ break;
80
+
81
+
82
+ case 'wcml_wc_booking_pricing_override_block_cost':
83
+
84
+ if( isset( $pricing[ 'override_block_'.$currency_code ] ) ){
85
+ $value = $pricing[ 'override_block_'.$currency_code ];
86
+ }else{
87
+ $value = '';
88
+ }
89
+
90
+ echo '<div class="wcml_bookings_range_block" >';
91
+ echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
92
+ echo '<input type="number" step="0.01" name="wcml_wc_accommodation_booking_pricing_override_block_cost['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
93
+ echo '</div>';
94
+ break;
95
+
96
+ default:
97
+ break;
98
+
99
+ }
100
+
101
+ }
102
+
103
+ echo '</div>';
104
+
105
+ }
106
+ }
107
+
108
+ function save_custom_costs( $post_id, $post ){
109
+
110
+ $nonce = filter_input( INPUT_POST, '_wcml_custom_costs_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
111
+
112
+ if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_accommodation_bookings_custom_costs' ) ){
113
+
114
+ update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
115
+
116
+ if( $_POST['_wcml_custom_costs'] == 1 ){
117
+
118
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
119
+
120
+ foreach( $currencies as $code => $currency ){
121
+
122
+ $wc_booking_base_cost = $_POST[ 'wcml_wc_accommodation_booking_base_cost' ][ $code ];
123
+ update_post_meta( $post_id, '_wc_booking_base_cost_'.$code, $wc_booking_base_cost );
124
+ update_post_meta( $post_id, '_price_'.$code, $wc_booking_base_cost );
125
+
126
+ }
127
+
128
+ $updated_meta = array();
129
+ $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
130
+
131
+ foreach ( maybe_unserialize( $booking_pricing ) as $key => $prices ) {
132
+
133
+ $updated_meta[ $key ] = $prices;
134
+
135
+ foreach ( $currencies as $code => $currency ) {
136
+
137
+ $updated_meta[ $key ][ 'override_block_'.$code ] = $_POST[ 'wcml_wc_accommodation_booking_pricing_override_block_cost' ][ $code ];
138
+
139
+ }
140
+
141
+ }
142
+
143
+ update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
144
+
145
+ }
146
+ }
147
+
148
+ }
149
+
150
+ function product_price_filter( $value, $object_id, $meta_key, $single ){
151
+
152
+ if(
153
+ get_post_type( $object_id ) == 'product' &&
154
+ $meta_key == '_price' &&
155
+ $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
156
+ !is_admin() &&
157
+ ( $currency = $this->woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
158
+ ) {
159
+
160
+ remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
161
+
162
+ $original_language = $this->woocommerce_wpml->products->get_original_product_language( $object_id );
163
+ $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
164
+
165
+ if ( get_post_meta( $original_product, '_wcml_custom_costs_status' ) ) {
166
+
167
+ $price = get_post_meta( $object_id, '_price_' . $currency , true );
168
+ }
169
+
170
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
171
+ }
172
+
173
+ return isset( $price) ? $price : $value;
174
+ }
175
+
176
+ public function load_assets(){
177
+
178
+ $this->woocommerce_wpml->compatibility->bookings->load_assets( 'accommodation-booking' );
179
+ }
180
+
181
  }
compatibility/class-wcml-adventure-tours.php CHANGED
@@ -1,371 +1,371 @@
1
- <?php
2
-
3
- class WCML_Adventure_tours{
4
-
5
- private $tp;
6
-
7
- function __construct(){
8
- add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
9
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
10
-
11
- if (is_admin()) {
12
-
13
- add_action('wcml_gui_additional_box_html', array($this, 'custom_box_html'), 10, 3);
14
- add_filter('wcml_gui_additional_box_data', array($this, 'custom_box_html_data'), 10, 4);
15
- add_action('wcml_update_extra_fields', array($this, 'tour_data_update'), 10, 3);
16
-
17
- $this->tp = new WPML_Element_Translation_Package();
18
-
19
- add_filter('wpml_tm_translation_job_data', array($this, 'append_tour_data_translation_package'), 10, 2);
20
- add_action('wpml_translation_job_saved', array($this, 'save_tour_data_translation'), 10, 3);
21
-
22
- add_action( 'admin_footer', array( $this, 'load_assets' ) );
23
- add_action( 'wcml_after_custom_prices_block', array( $this, 'add_custom_prices_block' ) );
24
- add_action( 'wcml_after_save_custom_prices', array( $this, 'save_custom_costs' ) );
25
-
26
- add_filter( 'wcml_is_variable_product', array( $this, 'is_variable_tour' ), 10, 2 );
27
- add_filter( 'wcml_variation_term_taxonomy_ids', array( $this, 'add_tour_tax_id' ) );
28
- add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
29
- }
30
- }
31
-
32
-
33
- function sync_tour_data_across_translations($meta_id, $post_id, $meta_key, $tour_tabs_meta)
34
- {
35
- if ($meta_key != 'tour_tabs_meta')
36
- return false;
37
-
38
-
39
- global $sitepress, $woocommerce_wpml;
40
-
41
- $post = get_post($post_id);
42
-
43
- // skip auto-drafts // skip autosave
44
- if ( $post->post_status == 'auto-draft' || isset( $_POST['autosave'] ) ) {
45
- return false;
46
- }
47
-
48
- if ($post->post_type == 'product') {
49
-
50
- remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
51
-
52
- if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
53
-
54
- $original_product_id = $post_id;
55
-
56
- } else {
57
-
58
- $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
59
- $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language);
60
-
61
- }
62
-
63
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
64
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
65
-
66
- foreach ($product_translations as $product_translation) {
67
-
68
- if ( empty( $product_translation->original ) ) {
69
-
70
- $trnsl_tour_tabs_meta = get_post_meta( $product_translation->element_id, 'tour_tabs_meta', true );
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
-
78
- }
79
-
80
- add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
81
-
82
- }
83
-
84
- }
85
-
86
- function custom_box_html($obj, $product_id, $data)
87
- {
88
-
89
- if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
90
-
91
- $tour_section = new WPML_Editor_UI_Field_Section( __('Tour Data', 'woocommerce-multilingual'));
92
-
93
- $divider = true;
94
-
95
- foreach( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
96
-
97
- $group = new WPML_Editor_UI_Field_Group('', $divider);
98
- $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_title', __('Title', 'woocommerce-multilingual'), $data, false);
99
- $group->add_field($composite_field);
100
- $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_content', __('Content', 'woocommerce-multilingual'), $data, false);
101
- $group->add_field($composite_field);
102
- $tour_section->add_field($group);
103
-
104
- }
105
-
106
- if ( !empty( $tour_tabs_meta['tabs'] ) ) {
107
- $obj->add_field( $tour_section );
108
- }
109
-
110
- }
111
-
112
- }
113
-
114
- function custom_box_html_data($data, $product_id, $translation, $lang){
115
-
116
- if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
117
-
118
- foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
119
- $data['adventure_tour_' . $tour_tab_id . '_title'] = array('original' => $tour_tab_meta['title'] );
120
- $data['adventure_tour_' . $tour_tab_id . '_content'] = array('original' => $tour_tab_meta['content'] );
121
- }
122
-
123
- if ($translation) {
124
- $translated_tour_tabs_meta = get_post_meta( $translation->ID, 'tour_tabs_meta', true );
125
-
126
- if( $translated_tour_tabs_meta ){
127
- foreach ( $translated_tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
128
- $data['adventure_tour_' . $tour_tab_id . '_title']['translation'] = $tour_tab_meta['title'];
129
- $data['adventure_tour_' . $tour_tab_id . '_content']['translation'] = $tour_tab_meta['content'];
130
- }
131
- }
132
- }
133
-
134
- }
135
-
136
- return $data;
137
- }
138
-
139
- function tour_data_update( $original_product_id, $product_id, $data)
140
- {
141
-
142
- $tour_tabs_meta = get_post_meta( $original_product_id, 'tour_tabs_meta', true );
143
-
144
- if( isset( $tour_tabs_meta['tabs'] ) && is_array( $tour_tabs_meta['tabs'] ) ){
145
- foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
146
-
147
- if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_title')])) {
148
- $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $data[md5('adventure_tour_' . $tour_tab_id . '_title')];
149
- }
150
-
151
- if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_content')])) {
152
- $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $data[md5('adventure_tour_' . $tour_tab_id . '_content')];
153
- }
154
- }
155
- remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
156
-
157
- update_post_meta($product_id, 'tour_tabs_meta', $tour_tabs_meta);
158
-
159
- add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
160
- }
161
-
162
- }
163
-
164
- function append_tour_data_translation_package($package, $post)
165
- {
166
-
167
- if ($post->post_type == 'product') {
168
-
169
- $tour_tabs_meta = get_post_meta( $post->ID, 'tour_tabs_meta', true );
170
-
171
- if ($tour_tabs_meta) {
172
-
173
- $fields = array('title', 'content');
174
-
175
- foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
176
-
177
- foreach ($fields as $field) {
178
- if (!empty($tour_tab_meta[$field])) {
179
-
180
- $package['contents']['wc_adventure_tour:' . $tour_tab_id . ':' . $field] = array(
181
- 'translate' => 1,
182
- 'data' => $this->tp->encode_field_data($tour_tab_meta[$field], 'base64'),
183
- 'format' => 'base64'
184
- );
185
-
186
- }
187
- }
188
-
189
- }
190
-
191
- }
192
-
193
- }
194
-
195
- return $package;
196
-
197
- }
198
-
199
- function save_tour_data_translation($post_id, $data, $job)
200
- {
201
-
202
-
203
- $translated_tour_data = array();
204
- foreach ($data as $value) {
205
-
206
- if (preg_match('/wc_adventure_tour:([0-9]+):(.+)/', $value['field_type'], $matches)) {
207
-
208
- $tour_tab_id = $matches[1];
209
- $field = $matches[2];
210
-
211
- $translated_tour_data[$tour_tab_id][$field] = $value['data'];
212
-
213
- }
214
-
215
- }
216
-
217
- if ($translated_tour_data) {
218
-
219
- $tour_tabs_meta = get_post_meta( $job->original_doc_id, 'tour_tabs_meta', true );
220
-
221
-
222
- foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
223
-
224
- if (isset($translated_tour_data[$tour_tab_id]['title'])) {
225
- $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $translated_tour_data[$tour_tab_id]['title'];
226
- }
227
-
228
- if (isset($translated_tour_data[$tour_tab_id]['content'])) {
229
- $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $translated_tour_data[$tour_tab_id]['content'];
230
- }
231
- }
232
-
233
- }
234
- remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
235
- update_post_meta($post_id, 'tour_tabs_meta', $tour_tabs_meta);
236
- add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
237
-
238
- }
239
-
240
- function load_assets(){
241
- global $pagenow, $woocommerce_wpml;
242
-
243
- if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
244
- wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION );
245
- wp_enqueue_script( 'wcml-adventure-tours' );
246
- }
247
- }
248
-
249
- function add_custom_prices_block( $product_id ){
250
- global $woocommerce_wpml;
251
-
252
- if( $product_id != 'new' ){
253
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
254
- $tour_booking_periods = get_post_meta( $product_id, 'tour_booking_periods', true );
255
- $custom_periods_prices = get_post_meta( $product_id, 'custom_booking_periods_prices', true );
256
- if( $tour_booking_periods ){
257
- foreach( $tour_booking_periods as $per_key => $tour_booking_period ){
258
- foreach( $currencies as $key => $currency ){
259
-
260
- $value = isset($custom_periods_prices[ $per_key ][ $key ]) ? $custom_periods_prices[ $per_key ][ $key ]: '';
261
-
262
- echo '<div class="wcml_custom_cost_field" data-tour="'.$per_key.'" style="display: none;">';
263
- echo '<div>'.get_woocommerce_currency_symbol($key).'</div>';
264
- echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price['.$per_key.']['.$key.']" value="'.$value.'" />';
265
- echo '</div>';
266
- }
267
- }
268
- }
269
-
270
- echo '<div class="wcml_custom_cost_field_empty" style="display: none;">';
271
- echo '<div></div>';
272
- echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price" value="" />';
273
- echo '</div>';
274
- }
275
- }
276
-
277
- function save_custom_costs( $post_id ){
278
- global $woocommerce_wpml;
279
-
280
- $tour_spec_price = array();
281
- $currencies = $woocommerce_wpml->multi_currency->get_currencies();
282
-
283
- if( isset( $_POST[ 'tour_spec_price' ] ) && is_array( $_POST[ 'tour_spec_price' ] ) ) {
284
-
285
- foreach( $_POST[ 'tour_spec_price' ] as $per_key => $costs ) {
286
-
287
- foreach( $currencies as $code => $currency ) {
288
-
289
- $tour_spec_price[ $per_key ][ $code ] = $costs[ $code ];
290
-
291
- }
292
- }
293
-
294
- update_post_meta( $post_id, 'custom_booking_periods_prices', $tour_spec_price );
295
- }
296
- }
297
-
298
- function product_price_filter( $value, $object_id, $meta_key, $single ){
299
- global $woocommerce_wpml;
300
-
301
- if(
302
- get_post_type( $object_id ) == 'product' &&
303
- $meta_key == 'tour_booking_periods' &&
304
- $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
305
- !is_admin() &&
306
- ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
307
- ) {
308
-
309
- remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
310
-
311
- $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
312
- $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
313
-
314
- if ( get_post_meta( $original_product, '_wcml_custom_prices_status' ) ) {
315
- $custom_periods_prices = get_post_meta( $object_id, 'custom_booking_periods_prices', true );
316
- $tours_data = get_post_meta( $object_id, 'tour_booking_periods', true );
317
- if( $tours_data ){
318
- foreach( $tours_data as $key => $periods ){
319
- if( isset( $custom_periods_prices[ $key ][ $currency ] ) ){
320
- $tours_data[ $key ][ 'spec_price' ] = $custom_periods_prices[ $key ][ $currency ];
321
- }
322
- }
323
-
324
- if( $single ){
325
- $value[0] = $tours_data;
326
- }else{
327
- $value = $tours_data;
328
- }
329
-
330
- }
331
- }
332
- add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
333
- }
334
-
335
- return $value;
336
- }
337
-
338
- function add_tour_tax_id( $variation_term_taxonomy_ids ){
339
- global $wpdb;
340
- $tour_taxonomy_id = $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 = 'tour' AND tt.taxonomy = 'product_type'" );
341
-
342
- if( $tour_taxonomy_id ){
343
- $variation_term_taxonomy_ids[] = $tour_taxonomy_id;
344
- }
345
-
346
- return $variation_term_taxonomy_ids;
347
-
348
- }
349
-
350
- function is_variable_tour( $is_variable, $product_id ){
351
- $var_tour_meta = get_post_meta( $product_id, '_variable_tour', true );
352
-
353
- if( $is_variable && $var_tour_meta == 'yes' ){
354
- $is_variable = true;
355
- }elseif( $var_tour_meta == 'no' ){
356
- $is_variable = false;
357
- }
358
-
359
- return $is_variable;
360
- }
361
-
362
- function is_attributes_page( $is_attributes_page ){
363
-
364
- if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes_extended' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' ){
365
- $is_attributes_page = true;
366
- }
367
-
368
- return $is_attributes_page;
369
- }
370
-
371
  }
1
+ <?php
2
+
3
+ class WCML_Adventure_tours{
4
+
5
+ private $tp;
6
+
7
+ function __construct(){
8
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
9
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter'), 9, 4 );
10
+
11
+ if (is_admin()) {
12
+
13
+ add_action('wcml_gui_additional_box_html', array($this, 'custom_box_html'), 10, 3);
14
+ add_filter('wcml_gui_additional_box_data', array($this, 'custom_box_html_data'), 10, 4);
15
+ add_action('wcml_update_extra_fields', array($this, 'tour_data_update'), 10, 3);
16
+
17
+ $this->tp = new WPML_Element_Translation_Package();
18
+
19
+ add_filter('wpml_tm_translation_job_data', array($this, 'append_tour_data_translation_package'), 10, 2);
20
+ add_action('wpml_translation_job_saved', array($this, 'save_tour_data_translation'), 10, 3);
21
+
22
+ add_action( 'admin_footer', array( $this, 'load_assets' ) );
23
+ add_action( 'wcml_after_custom_prices_block', array( $this, 'add_custom_prices_block' ) );
24
+ add_action( 'wcml_after_save_custom_prices', array( $this, 'save_custom_costs' ) );
25
+
26
+ add_filter( 'wcml_is_variable_product', array( $this, 'is_variable_tour' ), 10, 2 );
27
+ add_filter( 'wcml_variation_term_taxonomy_ids', array( $this, 'add_tour_tax_id' ) );
28
+ add_filter( 'wcml_is_attributes_page', array( $this, 'is_attributes_page' ) );
29
+ }
30
+ }
31
+
32
+
33
+ function sync_tour_data_across_translations($meta_id, $post_id, $meta_key, $tour_tabs_meta)
34
+ {
35
+ if ($meta_key != 'tour_tabs_meta')
36
+ return false;
37
+
38
+
39
+ global $sitepress, $woocommerce_wpml;
40
+
41
+ $post = get_post($post_id);
42
+
43
+ // skip auto-drafts // skip autosave
44
+ if ( $post->post_status == 'auto-draft' || isset( $_POST['autosave'] ) ) {
45
+ return false;
46
+ }
47
+
48
+ if ($post->post_type == 'product') {
49
+
50
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
51
+
52
+ if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
53
+
54
+ $original_product_id = $post_id;
55
+
56
+ } else {
57
+
58
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
59
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language);
60
+
61
+ }
62
+
63
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
64
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
65
+
66
+ foreach ($product_translations as $product_translation) {
67
+
68
+ if ( empty( $product_translation->original ) ) {
69
+
70
+ $trnsl_tour_tabs_meta = get_post_meta( $product_translation->element_id, 'tour_tabs_meta', true );
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
+
78
+ }
79
+
80
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
81
+
82
+ }
83
+
84
+ }
85
+
86
+ function custom_box_html($obj, $product_id, $data)
87
+ {
88
+
89
+ if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
90
+
91
+ $tour_section = new WPML_Editor_UI_Field_Section( __('Tour Data', 'woocommerce-multilingual'));
92
+
93
+ $divider = true;
94
+
95
+ foreach( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
96
+
97
+ $group = new WPML_Editor_UI_Field_Group('', $divider);
98
+ $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_title', __('Title', 'woocommerce-multilingual'), $data, false);
99
+ $group->add_field($composite_field);
100
+ $composite_field = new WPML_Editor_UI_Single_Line_Field('adventure_tour_' . $tour_tab_id . '_content', __('Content', 'woocommerce-multilingual'), $data, false);
101
+ $group->add_field($composite_field);
102
+ $tour_section->add_field($group);
103
+
104
+ }
105
+
106
+ if ( !empty( $tour_tabs_meta['tabs'] ) ) {
107
+ $obj->add_field( $tour_section );
108
+ }
109
+
110
+ }
111
+
112
+ }
113
+
114
+ function custom_box_html_data($data, $product_id, $translation, $lang){
115
+
116
+ if ( $tour_tabs_meta = get_post_meta( $product_id, 'tour_tabs_meta', true ) ) {
117
+
118
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
119
+ $data['adventure_tour_' . $tour_tab_id . '_title'] = array('original' => $tour_tab_meta['title'] );
120
+ $data['adventure_tour_' . $tour_tab_id . '_content'] = array('original' => $tour_tab_meta['content'] );
121
+ }
122
+
123
+ if ($translation) {
124
+ $translated_tour_tabs_meta = get_post_meta( $translation->ID, 'tour_tabs_meta', true );
125
+
126
+ if( $translated_tour_tabs_meta ){
127
+ foreach ( $translated_tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
128
+ $data['adventure_tour_' . $tour_tab_id . '_title']['translation'] = $tour_tab_meta['title'];
129
+ $data['adventure_tour_' . $tour_tab_id . '_content']['translation'] = $tour_tab_meta['content'];
130
+ }
131
+ }
132
+ }
133
+
134
+ }
135
+
136
+ return $data;
137
+ }
138
+
139
+ function tour_data_update( $original_product_id, $product_id, $data)
140
+ {
141
+
142
+ $tour_tabs_meta = get_post_meta( $original_product_id, 'tour_tabs_meta', true );
143
+
144
+ if( isset( $tour_tabs_meta['tabs'] ) && is_array( $tour_tabs_meta['tabs'] ) ){
145
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta ) {
146
+
147
+ if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_title')])) {
148
+ $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $data[md5('adventure_tour_' . $tour_tab_id . '_title')];
149
+ }
150
+
151
+ if (!empty($data[md5('adventure_tour_' . $tour_tab_id . '_content')])) {
152
+ $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $data[md5('adventure_tour_' . $tour_tab_id . '_content')];
153
+ }
154
+ }
155
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
156
+
157
+ update_post_meta($product_id, 'tour_tabs_meta', $tour_tabs_meta);
158
+
159
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
160
+ }
161
+
162
+ }
163
+
164
+ function append_tour_data_translation_package($package, $post)
165
+ {
166
+
167
+ if ($post->post_type == 'product') {
168
+
169
+ $tour_tabs_meta = get_post_meta( $post->ID, 'tour_tabs_meta', true );
170
+
171
+ if ($tour_tabs_meta) {
172
+
173
+ $fields = array('title', 'content');
174
+
175
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
176
+
177
+ foreach ($fields as $field) {
178
+ if (!empty($tour_tab_meta[$field])) {
179
+
180
+ $package['contents']['wc_adventure_tour:' . $tour_tab_id . ':' . $field] = array(
181
+ 'translate' => 1,
182
+ 'data' => $this->tp->encode_field_data($tour_tab_meta[$field], 'base64'),
183
+ 'format' => 'base64'
184
+ );
185
+
186
+ }
187
+ }
188
+
189
+ }
190
+
191
+ }
192
+
193
+ }
194
+
195
+ return $package;
196
+
197
+ }
198
+
199
+ function save_tour_data_translation($post_id, $data, $job)
200
+ {
201
+
202
+
203
+ $translated_tour_data = array();
204
+ foreach ($data as $value) {
205
+
206
+ if (preg_match('/wc_adventure_tour:([0-9]+):(.+)/', $value['field_type'], $matches)) {
207
+
208
+ $tour_tab_id = $matches[1];
209
+ $field = $matches[2];
210
+
211
+ $translated_tour_data[$tour_tab_id][$field] = $value['data'];
212
+
213
+ }
214
+
215
+ }
216
+
217
+ if ($translated_tour_data) {
218
+
219
+ $tour_tabs_meta = get_post_meta( $job->original_doc_id, 'tour_tabs_meta', true );
220
+
221
+
222
+ foreach ( $tour_tabs_meta['tabs'] as $tour_tab_id => $tour_tab_meta) {
223
+
224
+ if (isset($translated_tour_data[$tour_tab_id]['title'])) {
225
+ $tour_tabs_meta['tabs'][$tour_tab_id]['title'] = $translated_tour_data[$tour_tab_id]['title'];
226
+ }
227
+
228
+ if (isset($translated_tour_data[$tour_tab_id]['content'])) {
229
+ $tour_tabs_meta['tabs'][$tour_tab_id]['content'] = $translated_tour_data[$tour_tab_id]['content'];
230
+ }
231
+ }
232
+
233
+ }
234
+ remove_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
235
+ update_post_meta($post_id, 'tour_tabs_meta', $tour_tabs_meta);
236
+ add_action('updated_post_meta', array($this, 'sync_tour_data_across_translations'), 10, 4);
237
+
238
+ }
239
+
240
+ function load_assets(){
241
+ global $pagenow, $woocommerce_wpml;
242
+
243
+ if( $pagenow == 'post.php' || $pagenow == 'post-new.php' ){
244
+ wp_register_script( 'wcml-adventure-tours', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-adventure-tours.js', array( 'jquery' ), WCML_VERSION );
245
+ wp_enqueue_script( 'wcml-adventure-tours' );
246
+ }
247
+ }
248
+
249
+ function add_custom_prices_block( $product_id ){
250
+ global $woocommerce_wpml;
251
+
252
+ if( $product_id != 'new' ){
253
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
254
+ $tour_booking_periods = get_post_meta( $product_id, 'tour_booking_periods', true );
255
+ $custom_periods_prices = get_post_meta( $product_id, 'custom_booking_periods_prices', true );
256
+ if( $tour_booking_periods ){
257
+ foreach( $tour_booking_periods as $per_key => $tour_booking_period ){
258
+ foreach( $currencies as $key => $currency ){
259
+
260
+ $value = isset($custom_periods_prices[ $per_key ][ $key ]) ? $custom_periods_prices[ $per_key ][ $key ]: '';
261
+
262
+ echo '<div class="wcml_custom_cost_field" data-tour="'.$per_key.'" style="display: none;">';
263
+ echo '<div>'.get_woocommerce_currency_symbol($key).'</div>';
264
+ echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price['.$per_key.']['.$key.']" value="'.$value.'" />';
265
+ echo '</div>';
266
+ }
267
+ }
268
+ }
269
+
270
+ echo '<div class="wcml_custom_cost_field_empty" style="display: none;">';
271
+ echo '<div></div>';
272
+ echo '<input type="text" class="wc_input_price" style="width: 60px;" name="tour_spec_price" value="" />';
273
+ echo '</div>';
274
+ }
275
+ }
276
+
277
+ function save_custom_costs( $post_id ){
278
+ global $woocommerce_wpml;
279
+
280
+ $tour_spec_price = array();
281
+ $currencies = $woocommerce_wpml->multi_currency->get_currencies();
282
+
283
+ if( isset( $_POST[ 'tour_spec_price' ] ) && is_array( $_POST[ 'tour_spec_price' ] ) ) {
284
+
285
+ foreach( $_POST[ 'tour_spec_price' ] as $per_key => $costs ) {
286
+
287
+ foreach( $currencies as $code => $currency ) {
288
+
289
+ $tour_spec_price[ $per_key ][ $code ] = $costs[ $code ];
290
+
291
+ }
292
+ }
293
+
294
+ update_post_meta( $post_id, 'custom_booking_periods_prices', $tour_spec_price );
295
+ }
296
+ }
297
+
298
+ function product_price_filter( $value, $object_id, $meta_key, $single ){
299
+ global $woocommerce_wpml;
300
+
301
+ if(
302
+ get_post_type( $object_id ) == 'product' &&
303
+ $meta_key == 'tour_booking_periods' &&
304
+ $woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
305
+ !is_admin() &&
306
+ ( $currency = $woocommerce_wpml->multi_currency->get_client_currency() ) != get_option( 'woocommerce_currency' )
307
+ ) {
308
+
309
+ remove_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
310
+
311
+ $original_language = $woocommerce_wpml->products->get_original_product_language( $object_id );
312
+ $original_product = apply_filters( 'translate_object_id', $object_id, 'product', true, $original_language );
313
+
314
+ if ( get_post_meta( $original_product, '_wcml_custom_prices_status' ) ) {
315
+ $custom_periods_prices = get_post_meta( $object_id, 'custom_booking_periods_prices', true );
316
+ $tours_data = get_post_meta( $object_id, 'tour_booking_periods', true );
317
+ if( $tours_data ){
318
+ foreach( $tours_data as $key => $periods ){
319
+ if( isset( $custom_periods_prices[ $key ][ $currency ] ) ){
320
+ $tours_data[ $key ][ 'spec_price' ] = $custom_periods_prices[ $key ][ $currency ];
321
+ }
322
+ }
323
+
324
+ if( $single ){
325
+ $value[0] = $tours_data;
326
+ }else{
327
+ $value = $tours_data;
328
+ }
329
+
330
+ }
331
+ }
332
+ add_filter( 'get_post_metadata', array( $this, 'product_price_filter' ), 9, 4 );
333
+ }
334
+
335
+ return $value;
336
+ }
337
+
338
+ function add_tour_tax_id( $variation_term_taxonomy_ids ){
339
+ global $wpdb;
340
+ $tour_taxonomy_id = $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 = 'tour' AND tt.taxonomy = 'product_type'" );
341
+
342
+ if( $tour_taxonomy_id ){
343
+ $variation_term_taxonomy_ids[] = $tour_taxonomy_id;
344
+ }
345
+
346
+ return $variation_term_taxonomy_ids;
347
+
348
+ }
349
+
350
+ function is_variable_tour( $is_variable, $product_id ){
351
+ $var_tour_meta = get_post_meta( $product_id, '_variable_tour', true );
352
+
353
+ if( $is_variable && $var_tour_meta == 'yes' ){
354
+ $is_variable = true;
355
+ }elseif( $var_tour_meta == 'no' ){
356
+ $is_variable = false;
357
+ }
358
+
359
+ return $is_variable;
360
+ }
361
+
362
+ function is_attributes_page( $is_attributes_page ){
363
+
364
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes_extended' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' ){
365
+ $is_attributes_page = true;
366
+ }
367
+
368
+ return $is_attributes_page;
369
+ }
370
+
371
  }
compatibility/class-wcml-ajax-layered-nav-widget.php CHANGED
@@ -1,38 +1,38 @@
1
- <?php
2
-
3
- /**
4
- Class for WooCommerce Advanced Ajax Layered Navigation
5
- */
6
-
7
- class WCML_Ajax_Layered_Nav_Widget {
8
- function __construct() {
9
- add_filter('wc_ajax_layered_nav_sizeselector_term_id', array($this, 'wc_ajax_layered_nav_sizeselector_term_id'));
10
- add_filter('wc_ajax_layered_nav_query_editor', array($this, 'wc_ajax_layered_nav_query_editor'),10,3);
11
- }
12
-
13
- function wc_ajax_layered_nav_sizeselector_term_id($term_id) {
14
- $ulanguage_code = apply_filters( 'wpml_default_language', null );
15
- $term_id = apply_filters( 'wpml_object_id', $term_id, 'category', true, $ulanguage_code );
16
- return $term_id;
17
- }
18
-
19
- function wc_ajax_layered_nav_query_editor($posts, $attribute, $value){
20
- $posts = get_posts(
21
- array(
22
- 'post_type' => 'product',
23
- 'numberposts' => -1,
24
- 'post_status' => 'publish',
25
- 'fields' => 'ids',
26
- 'no_found_rows' => true,
27
- 'tax_query' => array(
28
- array(
29
- 'taxonomy' => $attribute,
30
- 'terms' => $value,
31
- 'field' => 'term_id'
32
- )
33
- )
34
- )
35
- );
36
- return $posts;
37
- }
38
- }
1
+ <?php
2
+
3
+ /**
4
+ Class for WooCommerce Advanced Ajax Layered Navigation
5
+ */
6
+
7
+ class WCML_Ajax_Layered_Nav_Widget {
8
+ function __construct() {
9
+ add_filter('wc_ajax_layered_nav_sizeselector_term_id', array($this, 'wc_ajax_layered_nav_sizeselector_term_id'));
10
+ add_filter('wc_ajax_layered_nav_query_editor', array($this, 'wc_ajax_layered_nav_query_editor'),10,3);
11
+ }
12
+
13
+ function wc_ajax_layered_nav_sizeselector_term_id($term_id) {
14
+ $ulanguage_code = apply_filters( 'wpml_default_language', null );
15
+ $term_id = apply_filters( 'wpml_object_id', $term_id, 'category', true, $ulanguage_code );
16
+ return $term_id;
17
+ }
18
+
19
+ function wc_ajax_layered_nav_query_editor($posts, $attribute, $value){
20
+ $posts = get_posts(
21
+ array(
22
+ 'post_type' => 'product',
23
+ 'numberposts' => -1,
24
+ 'post_status' => 'publish',
25
+ 'fields' => 'ids',
26
+ 'no_found_rows' => true,
27
+ 'tax_query' => array(
28
+ array(
29
+ 'taxonomy' => $attribute,
30
+ 'terms' => $value,
31
+ 'field' => 'term_id'
32
+ )
33
+ )
34
+ )
35
+ );
36
+ return $posts;
37
+ }
38
+ }
compatibility/class-wcml-aurum.php CHANGED
@@ -1,17 +1,17 @@
1
- <?php
2
-
3
- class WCML_Aurum{
4
-
5
- function __construct(){
6
-
7
- add_filter( 'wcml_multi_currency_is_ajax', array( $this,'add_ajax_action' ) );
8
- }
9
-
10
- function add_ajax_action( $actions ){
11
-
12
- $actions[] = 'lab_wc_add_to_cart';
13
-
14
- return $actions;
15
- }
16
-
17
- }
1
+ <?php
2
+
3
+ class WCML_Aurum{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'wcml_multi_currency_is_ajax', array( $this,'add_ajax_action' ) );
8
+ }
9
+
10
+ function add_ajax_action( $actions ){
11
+
12
+ $actions[] = 'lab_wc_add_to_cart';
13
+
14
+ return $actions;
15
+ }
16
+
17
+ }
compatibility/class-wcml-bookings.php CHANGED
@@ -1,2056 +1,2218 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Bookings.
5
- */
6
- class WCML_Bookings {
7
-
8
- /**
9
- * @var WPML_Element_Translation_Package
10
- */
11
- public $tp;
12
-
13
- /**
14
- * @var SitePress
15
- */
16
- public $sitepress;
17
-
18
- /**
19
- * @var woocommerce_wpml
20
- */
21
- public $woocommerce_wpml;
22
-
23
- /**
24
- * @var wpdb
25
- */
26
- public $wpdb;
27
-
28
- /**
29
- * WCML_Bookings constructor.
30
- */
31
- function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
32
- $this->sitepress = $sitepress;
33
- $this->woocommerce_wpml = $woocommerce_wpml;
34
- $this->wpdb = $wpdb;
35
- add_action( 'woocommerce_bookings_after_booking_base_cost', array( $this, 'wcml_price_field_after_booking_base_cost' ) );
36
- add_action( 'woocommerce_bookings_after_booking_block_cost' , array( $this, 'wcml_price_field_after_booking_block_cost' ) );
37
- add_action( 'woocommerce_bookings_after_display_cost' , array( $this, 'wcml_price_field_after_display_cost' ) );
38
- add_action( 'woocommerce_bookings_after_booking_pricing_base_cost' , array( $this, 'wcml_price_field_after_booking_pricing_base_cost' ), 10, 2 );
39
- add_action( 'woocommerce_bookings_after_booking_pricing_cost' , array( $this, 'wcml_price_field_after_booking_pricing_cost' ), 10, 2 );
40
- add_action( 'woocommerce_bookings_after_person_cost' , array( $this, 'wcml_price_field_after_person_cost' ) );
41
- add_action( 'woocommerce_bookings_after_person_block_cost' , array( $this, 'wcml_price_field_after_person_block_cost' ) );
42
- add_action( 'woocommerce_bookings_after_resource_cost' , array( $this, 'wcml_price_field_after_resource_cost' ), 10, 2 );
43
- add_action( 'woocommerce_bookings_after_resource_block_cost' , array( $this, 'wcml_price_field_after_resource_block_cost' ), 10, 2 );
44
- add_action( 'woocommerce_bookings_after_bookings_pricing' , array( $this, 'after_bookings_pricing' ) );
45
-
46
- add_action( 'init', array( $this, 'load_assets' ) );
47
-
48
- add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 1 );
49
- add_action( 'wcml_before_sync_product_data', array( $this, 'sync_bookings' ), 10, 3 );
50
- add_action( 'wcml_before_sync_product', array( $this, 'sync_booking_data' ), 10, 2 );
51
-
52
- add_filter( 'woocommerce_bookings_process_cost_rules_cost', array( $this, 'wc_bookings_process_cost_rules_cost' ), 10, 3 );
53
- add_filter( 'woocommerce_bookings_process_cost_rules_base_cost', array( $this, 'wc_bookings_process_cost_rules_base_cost' ), 10, 3 );
54
- add_filter( 'woocommerce_bookings_process_cost_rules_override_block', array( $this, 'wc_bookings_process_cost_rules_override_block_cost' ), 10, 3 );
55
-
56
- add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'wcml_multi_currency_is_ajax' ) );
57
-
58
- add_filter( 'wcml_cart_contents_not_changed', array( $this, 'filter_bundled_product_in_cart_contents' ), 10, 3 );
59
-
60
- add_action( 'woocommerce_bookings_after_create_booking_page', array( $this, 'booking_currency_dropdown' ) );
61
- add_action( 'init', array( $this, 'set_booking_currency') );
62
-
63
- add_action( 'wp_ajax_wcml_booking_set_currency', array( $this, 'set_booking_currency_ajax' ) );
64
- add_action( 'woocommerce_bookings_create_booking_page_add_order_item', array( $this, 'set_order_currency_on_create_booking_page' ) );
65
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
66
- add_filter( 'get_booking_products_args', array( $this, 'filter_get_booking_products_args' ) );
67
- add_filter( 'wcml_filter_currency_position', array( $this, 'create_booking_page_client_currency' ) );
68
-
69
- add_filter( 'wcml_client_currency', array( $this, 'create_booking_page_client_currency' ) );
70
-
71
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html'), 10, 3 );
72
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data'), 10, 4 );
73
- add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons'), 10, 3 );
74
- add_filter( 'wcml_product_content_exception', array( $this, 'remove_custom_fields_to_translate' ), 10, 3 );
75
- add_filter( 'wcml_not_display_single_fields_to_translate', array( $this, 'remove_single_custom_fields_to_translate' ) );
76
- add_filter( 'wcml_product_content_label', array( $this, 'product_content_resource_label' ), 10, 2 );
77
- add_action( 'wcml_update_extra_fields', array( $this, 'wcml_products_tab_sync_resources_and_persons'), 10, 4 );
78
-
79
- add_action( 'woocommerce_new_booking', array( $this, 'duplicate_booking_for_translations') );
80
-
81
- $bookings_statuses = array( 'unpaid', 'pending-confirmation', 'confirmed', 'paid', 'cancelled', 'complete', 'in-cart', 'was-in-cart' );
82
- foreach( $bookings_statuses as $status ){
83
- add_action('woocommerce_booking_' . $status, array( $this, 'update_status_for_translations' ) );
84
- }
85
-
86
- add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
87
- add_filter( 'woocommerce_bookings_in_date_range_query', array( $this, 'bookings_in_date_range_query') );
88
- add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
89
- add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
90
-
91
- if( is_admin() ){
92
-
93
- $this->tp = new WPML_Element_Translation_Package;
94
-
95
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_persons_to_translation_package' ), 10, 2 );
96
- add_action( 'wpml_translation_job_saved', array( $this, 'save_person_translation' ), 10, 3 );
97
-
98
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_resources_to_translation_package' ), 10, 2 );
99
- add_action( 'wpml_translation_job_saved', array( $this, 'save_resource_translation' ), 10, 3 );
100
-
101
- //lock fields on translations pages
102
- add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
103
- add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
104
-
105
- //allow filtering resources by language
106
- add_filter( 'get_booking_resources_args', array( $this, 'filter_get_booking_resources_args' ) );
107
- }
108
-
109
- if( !is_admin() || isset( $_POST['action'] ) && $_POST['action'] == 'wc_bookings_calculate_costs' ){
110
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
111
- }
112
-
113
-
114
- $this->clear_transient_fields();
115
-
116
- }
117
-
118
- function wcml_price_field_after_booking_base_cost( $post_id ){
119
-
120
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
121
-
122
- }
123
-
124
- function wcml_price_field_after_booking_block_cost( $post_id ){
125
-
126
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
127
-
128
- }
129
-
130
- function wcml_price_field_after_display_cost( $post_id ){
131
-
132
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
133
-
134
- }
135
-
136
- function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ){
137
-
138
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
139
-
140
- }
141
-
142
- function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ){
143
-
144
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
145
-
146
- }
147
-
148
- function wcml_price_field_after_person_cost( $person_type_id ){
149
-
150
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
151
-
152
- }
153
-
154
- function wcml_price_field_after_person_block_cost( $person_type_id ){
155
-
156
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
157
-
158
- }
159
-
160
- function wcml_price_field_after_resource_cost( $resource_id, $post_id ){
161
-
162
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
163
-
164
- }
165
-
166
- function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ){
167
-
168
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
169
-
170
- }
171
-
172
- function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
173
-
174
-
175
- if( ( !$check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
176
-
177
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
178
-
179
- $wc_currencies = get_woocommerce_currencies();
180
-
181
- echo '<div class="wcml_custom_cost_field" >';
182
-
183
- foreach($currencies as $currency_code => $currency){
184
-
185
- switch( $field ){
186
- case 'wcml_wc_booking_cost':
187
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
188
- 'min' => '',
189
- 'step' => '0.01'
190
- ) ) );
191
- break;
192
- case 'wcml_wc_booking_base_cost':
193
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_booking_base_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_booking_base_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
194
- 'min' => '',
195
- 'step' => '0.01'
196
- ) ) );
197
- break;
198
- case 'wcml_wc_display_cost':
199
- woocommerce_wp_text_input( array( 'id' => 'wcml_wc_display_cost', 'class'=>'wcml_bookings_custom_price', 'name' => 'wcml_wc_display_cost['.$currency_code.']', 'label' => get_woocommerce_currency_symbol($currency_code), 'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ), 'value' => get_post_meta( $post_id, '_wc_display_cost_'.$currency_code, true ), 'type' => 'number', 'desc_tip' => true, 'custom_attributes' => array(
200
- 'min' => '',
201
- 'step' => '0.01'
202
- ) ) );
203
- break;
204
-
205
- case 'wcml_wc_booking_pricing_base_cost':
206
-
207
- if( isset( $pricing[ 'base_cost_'.$currency_code ] ) ){
208
- $value = $pricing[ 'base_cost_'.$currency_code ];
209
- }else{
210
- $value = '';
211
- }
212
-
213
- echo '<div class="wcml_bookings_range_block" >';
214
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
215
- echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
216
- echo '</div>';
217
- break;
218
-
219
- case 'wcml_wc_booking_pricing_cost':
220
-
221
- if( isset( $pricing[ 'cost_'.$currency_code ] ) ){
222
- $value = $pricing[ 'cost_'.$currency_code ];
223
- }else{
224
- $value = '';
225
- }
226
-
227
- echo '<div class="wcml_bookings_range_block" >';
228
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
229
- echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost['.$currency_code.'][]" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
230
- echo '</div>';
231
- break;
232
-
233
- case 'wcml_wc_booking_person_cost':
234
-
235
- $value = get_post_meta( $post_id, 'cost_'.$currency_code, true );
236
-
237
- echo '<div class="wcml_bookings_person_block" >';
238
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
239
- echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
240
- echo '</div>';
241
- break;
242
-
243
- case 'wcml_wc_booking_person_block_cost':
244
-
245
- $value = get_post_meta( $post_id, 'block_cost_'.$currency_code, true );
246
-
247
- echo '<div class="wcml_bookings_person_block" >';
248
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
249
- echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost['.$post_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
250
- echo '</div>';
251
- break;
252
-
253
- case 'wcml_wc_booking_resource_cost':
254
-
255
- $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
256
-
257
- if( isset( $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
258
- $value = $resource_base_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
259
- }else{
260
- $value = '';
261
- }
262
-
263
- echo '<div class="wcml_bookings_resource_block" >';
264
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
265
- echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
266
- echo '</div>';
267
- break;
268
-
269
- case 'wcml_wc_booking_resource_block_cost':
270
-
271
- $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
272
-
273
- if( isset( $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ] ) ){
274
- $value = $resource_block_costs[ 'custom_costs' ][ $currency_code ][ $resource_id ];
275
- }else{
276
- $value = '';
277
- }
278
-
279
- echo '<div class="wcml_bookings_resource_block" >';
280
- echo '<label>'. get_woocommerce_currency_symbol($currency_code) .'</label>';
281
- echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost['.$resource_id.']['.$currency_code.']" class="wcml_bookings_custom_price" value="'. $value .'" placeholder="0" />';
282
- echo '</div>';
283
- break;
284
-
285
- default:
286
- break;
287
-
288
- }
289
-
290
- }
291
-
292
- echo '</div>';
293
-
294
- }
295
- }
296
-
297
- function after_bookings_pricing( $post_id ){
298
-
299
-
300
- if( in_array( 'booking', wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) ) ) && $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
301
-
302
- $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
303
-
304
- $checked = !$custom_costs_status ? 'checked="checked"' : ' ';
305
-
306
- echo '<div class="wcml_custom_costs">';
307
-
308
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
309
- echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
310
-
311
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
312
-
313
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
314
- echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
315
-
316
- wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
317
-
318
- echo '</div>';
319
- }
320
-
321
- }
322
-
323
- function save_custom_costs( $post_id ) {
324
- $nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
325
-
326
- if( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
327
-
328
- update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
329
-
330
- if( 1 === (int) $_POST['_wcml_custom_costs'] ) {
331
-
332
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
333
- if( empty( $currencies ) || 0 === $post_id ) {
334
- return false;
335
- }
336
-
337
- $this->update_booking_costs( $currencies, $post_id );
338
- $this->update_booking_pricing( $currencies, $post_id );
339
-
340
-
341
- if( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
342
- $this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
343
- }
344
-
345
- if( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
346
- $this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
347
- }
348
-
349
- if( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
350
- $this->update_booking_resource_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_cost'] );
351
- }
352
-
353
- if( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
354
- $this->update_booking_resource_block_cost( $currencies, $post_id, $_POST[ 'wcml_wc_booking_resource_block_cost' ] );
355
- }
356
- } else {
357
- return false;
358
- }
359
- }
360
-
361
- }
362
-
363
- // sync existing product bookings for translations
364
- function sync_bookings( $original_product_id, $product_id, $lang ){
365
- $all_bookings_for_product = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id as id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
366
-
367
- foreach($all_bookings_for_product as $booking ){
368
- $check_if_exists = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT pm3.* FROM {$this->wpdb->postmeta} AS pm1
369
- LEFT JOIN {$this->wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
370
- LEFT JOIN {$this->wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
371
- WHERE pm1.meta_key = '_booking_duplicate_of' AND pm1.meta_value = %s AND pm2.meta_key = '_language_code' AND pm2.meta_value = %s AND pm3.meta_key = '_booking_product_id'"
372
- , $booking->id, $lang ) );
373
-
374
- if( is_null( $check_if_exists ) ) {
375
- $this->duplicate_booking_for_translations( $booking->id, $lang );
376
- } elseif ( '' === $check_if_exists->meta_value ) {
377
- update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
378
- update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
379
- update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
380
- }
381
- }
382
- }
383
-
384
- function sync_booking_data( $original_product_id, $current_product_id ){
385
-
386
- if( has_term( 'booking', 'product_type', $original_product_id ) ){
387
- global $pagenow, $iclTranslationManagement;
388
-
389
- // get language code
390
- $language_details = $this->sitepress->get_element_language_details( $original_product_id, 'post_product' );
391
- if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
392
- //translation editor support: sidestep icl_translations_cache
393
- $language_details = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT element_id, trid, language_code, source_language_code FROM {$this->wpdb->prefix}icl_translations WHERE element_id = %d AND element_type = 'post_product'", $original_product_id ) );
394
- }
395
- if ( empty( $language_details ) ) {
396
- return;
397
- }
398
-
399
- // pick posts to sync
400
- $posts = array();
401
- $translations = $this->sitepress->get_element_translations( $language_details->trid, 'post_product' );
402
- foreach ( $translations as $translation ) {
403
-
404
- if ( !$translation->original ) {
405
- $posts[ $translation->element_id ] = $translation;
406
- }
407
- }
408
-
409
- foreach ( $posts as $post_id => $translation ) {
410
-
411
- $trn_lang = $this->sitepress->get_language_for_element( $post_id, 'post_product' );
412
-
413
- //sync_resources
414
- $this->sync_resources( $original_product_id, $post_id, $trn_lang );
415
-
416
- //sync_persons
417
- $this->sync_persons( $original_product_id, $post_id, $trn_lang );
418
- }
419
-
420
- }
421
-
422
- }
423
-
424
- function sync_resources( $original_product_id, $translated_product_id, $lang_code, $duplicate = true ){
425
-
426
- $original_resources = $this->wpdb->get_results( $this->wpdb->prepare(
427
- "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
428
- $original_product_id ) );
429
-
430
- $translated_resources = $this->wpdb->get_col( $this->wpdb->prepare(
431
- "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
432
- $translated_product_id ) );
433
-
434
- $used_translated_resources = array();
435
-
436
- foreach ($original_resources as $resource) {
437
-
438
- $translated_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
439
- if( !is_null( $translated_resource_id ) ){
440
-
441
- if( in_array( $translated_resource_id, $translated_resources ) ){
442
- $this->update_product_resource( $translated_product_id, $translated_resource_id, $resource );
443
- }else{
444
- $this->add_product_resource( $translated_product_id, $translated_resource_id, $resource );
445
- }
446
- $used_translated_resources[] = $translated_resource_id;
447
- } else {
448
- if( $duplicate ){
449
- $this->duplicate_resource( $translated_product_id, $resource, $lang_code );
450
- }
451
- }
452
-
453
- }
454
-
455
- $removed_translated_resources_id = array_diff( $translated_resources, $used_translated_resources);
456
- foreach ( $removed_translated_resources_id as $resource_id ){
457
- $this->remove_resource_from_product( $translated_product_id, $resource_id );
458
- }
459
-
460
- $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_base_costs', $lang_code );
461
- $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_block_costs', $lang_code );
462
-
463
- }
464
-
465
- function duplicate_resource( $tr_product_id, $resource, $lang_code){
466
- global $iclTranslationManagement;
467
-
468
- if( method_exists( $this->sitepress, 'make_duplicate' ) ){
469
-
470
- $trns_resource_id = $this->sitepress->make_duplicate( $resource->resource_id, $lang_code );
471
-
472
- }else{
473
-
474
- if ( !isset( $iclTranslationManagement ) ) {
475
- $iclTranslationManagement = new TranslationManagement;
476
- }
477
-
478
- $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
479
-
480
- }
481
-
482
- $this->wpdb->insert(
483
- $this->wpdb->prefix . 'wc_booking_relationships',
484
- array(
485
- 'product_id' => $tr_product_id,
486
- 'resource_id' => $trns_resource_id,
487
- 'sort_order' => $resource->sort_order
488
- )
489
- );
490
-
491
- delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
492
-
493
- return $trns_resource_id;
494
- }
495
-
496
- public function add_product_resource( $product_id, $resource_id, $resource_data ){
497
-
498
- $this->wpdb->insert(
499
- $this->wpdb->prefix . 'wc_booking_relationships',
500
- array(
501
- 'sort_order' => $resource_data->sort_order,
502
- 'product_id' => $product_id,
503
- 'resource_id' => $resource_id
504
- )
505
- );
506
-
507
- update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
508
- update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
509
-
510
- }
511
-
512
- public function remove_resource_from_product( $product_id, $resource_id ){
513
-
514
- $this->wpdb->delete(
515
- $this->wpdb->prefix . 'wc_booking_relationships',
516
- array(
517
- 'product_id' => $product_id,
518
- 'resource_id' => $resource_id
519
- )
520
- );
521
-
522
- }
523
-
524
- public function update_product_resource( $product_id, $resource_id, $resource_data ){
525
-
526
- $this->wpdb->update(
527
- $this->wpdb->prefix . 'wc_booking_relationships',
528
- array(
529
- 'sort_order' => $resource_data->sort_order
530
- ),
531
- array(
532
- 'product_id' => $product_id,
533
- 'resource_id' => $resource_id
534
- )
535
- );
536
-
537
- update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
538
- update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
539
-
540
-
541
- }
542
-
543
- function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ){
544
- $orig_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
545
-
546
- $trnsl_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $tr_product_id ) );
547
-
548
-
549
- foreach ($orig_persons as $person) {
550
-
551
- $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
552
-
553
- if ( !is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
554
-
555
- if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
556
-
557
- unset($trnsl_persons[$key]);
558
-
559
- update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
560
- update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
561
- update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
562
- update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
563
-
564
-
565
- if( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT){
566
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
567
-
568
- foreach( $currencies as $code => $currency ){
569
-
570
- update_post_meta( $trnsl_person_id, 'block_cost_'.$code, get_post_meta( $person, 'block_cost_'.$code, true ) );
571
- update_post_meta( $trnsl_person_id, 'cost_'.$code, get_post_meta( $person, 'cost_'.$code, true ) );
572
-
573
- }
574
- }
575
-
576
- }
577
-
578
- }else{
579
-
580
- if( $duplicate ) {
581
-
582
- $this->duplicate_person($tr_product_id, $person, $lang_code);
583
-
584
- }else{
585
-
586
- continue;
587
-
588
- }
589
-
590
- }
591
-
592
- }
593
-
594
- foreach ($trnsl_persons as $trnsl_person) {
595
-
596
- wp_delete_post( $trnsl_person );
597
-
598
- }
599
-
600
- }
601
-
602
- function duplicate_person( $tr_product_id, $person_id, $lang_code ){
603
- global $iclTranslationManagement;
604
-
605
- if( method_exists( $this->sitepress, 'make_duplicate' ) ){
606
-
607
- $new_person_id = $this->sitepress->make_duplicate( $person_id, $lang_code );
608
-
609
- }else{
610
-
611
- if ( !isset( $iclTranslationManagement ) ) {
612
- $iclTranslationManagement = new TranslationManagement;
613
- }
614
-
615
- $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
616
-
617
- }
618
-
619
- $this->wpdb->update(
620
- $this->wpdb->posts,
621
- array(
622
- 'post_parent' => $tr_product_id
623
- ),
624
- array(
625
- 'ID' => $new_person_id
626
- )
627
- );
628
-
629
- delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
630
-
631
- return $new_person_id;
632
- }
633
-
634
- function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ){
635
-
636
- if( in_array( $meta_key, array( '_wc_booking_cost', '_wc_booking_base_cost', '_wc_display_cost', '_wc_booking_pricing', 'cost', 'block_cost', '_resource_base_costs', '_resource_block_costs' ) ) ){
637
-
638
-
639
-
640
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
641
-
642
- $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
643
-
644
- $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
645
-
646
- $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
647
-
648
- if ( $currency == get_option('woocommerce_currency') ){
649
- return $check;
650
- }
651
-
652
- if( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
653
-
654
- if ( get_post_type($object_id) == 'bookable_person' ) {
655
-
656
- $value = get_post_meta($object_id, $meta_key . '_' . $currency, true);
657
-
658
- if ( $cost_status && $value ) {
659
-
660
- return $value;
661
-
662
- } else {
663
-
664
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
665
-
666
- $cost = get_post_meta( $object_id, $meta_key, true);
667
-
668
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
669
-
670
- return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
671
- }
672
-
673
- } else {
674
-
675
- return $check;
676
-
677
- }
678
-
679
- }
680
-
681
- if( in_array ( $meta_key, array( '_wc_booking_pricing', '_resource_base_costs', '_resource_block_costs' ) ) ){
682
-
683
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
684
-
685
- if( $meta_key == '_wc_booking_pricing' ){
686
-
687
- if( $original_id != $object_id ){
688
- $value = get_post_meta( $original_id, $meta_key );
689
- }else{
690
- $value = $check;
691
- }
692
-
693
- }else{
694
-
695
- $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
696
-
697
- if( !$costs ){
698
- $value = $check;
699
- }elseif( $cost_status && isset( $costs[ 'custom_costs' ][ $currency ] ) ){
700
- $value = array( 0 => $costs[ 'custom_costs' ][ $currency ] );
701
- }elseif( $cost_status && isset( $costs[ 0 ][ 'custom_costs' ][ $currency ] )){
702
- $value = array( 0 => $costs[ 0 ][ 'custom_costs' ][ $currency ] );
703
- }else{
704
-
705
- $converted_values = array();
706
-
707
- foreach( $costs as $resource_id => $cost ){
708
- $converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
709
- }
710
-
711
- $value = $converted_values;
712
- }
713
-
714
- }
715
-
716
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
717
-
718
- return $value;
719
-
720
- }
721
-
722
- $value = get_post_meta( $original_id, $meta_key.'_'.$currency, true );
723
-
724
- if( $cost_status && ( !empty($value) || ( empty($value) && $meta_key == '_wc_display_cost' ) ) ){
725
-
726
- return $value;
727
-
728
- }else{
729
-
730
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
731
-
732
- $value = get_post_meta( $original_id, $meta_key, true );
733
-
734
- $value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
735
-
736
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
737
-
738
- return $value;
739
-
740
- }
741
-
742
- }
743
-
744
- }
745
-
746
- return $check;
747
- }
748
-
749
- function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ){
750
-
751
-
752
- $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
753
-
754
- if( $object_id == $original_product_id ){
755
-
756
- $trid = $this->sitepress->get_element_trid( $object_id, 'post_product' );
757
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
758
-
759
- foreach ( $translations as $translation ) {
760
-
761
- if ( !$translation->original ) {
762
-
763
- $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
764
-
765
- }
766
- }
767
-
768
- return $check;
769
-
770
- }else{
771
-
772
- $language_code = $this->sitepress->get_language_for_element( $object_id, 'post_product' );
773
-
774
- $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
775
-
776
- return true;
777
-
778
- }
779
-
780
- }
781
-
782
- function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ){
783
-
784
- $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
785
-
786
- $wc_booking_resource_costs = array();
787
- if( !empty( $original_costs ) ) {
788
- foreach ($original_costs as $resource_id => $costs) {
789
-
790
- if ($resource_id == 'custom_costs' && isset($costs['custom_costs'])) {
791
-
792
- foreach ($costs['custom_costs'] as $code => $currencies) {
793
-
794
- foreach ($currencies as $custom_costs_resource_id => $custom_cost) {
795
-
796
- $trns_resource_id = apply_filters('translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code);
797
-
798
- $wc_booking_resource_costs['custom_costs'][$code][$trns_resource_id] = $custom_cost;
799
-
800
- }
801
-
802
- }
803
-
804
- } else {
805
-
806
- $trns_resource_id = apply_filters('translate_object_id', $resource_id, 'bookable_resource', true, $language_code);
807
-
808
- $wc_booking_resource_costs[$trns_resource_id] = $costs;
809
-
810
- }
811
-
812
- }
813
- }
814
-
815
- update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
816
-
817
- }
818
-
819
- function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ){
820
- return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
821
- }
822
-
823
- function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ){
824
- return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
825
- }
826
-
827
- function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ){
828
- return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
829
- }
830
-
831
- function filter_pricing_cost( $cost, $fields, $name, $key ){
832
- global $product;
833
-
834
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
835
-
836
- $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
837
-
838
- if ( $currency == get_option('woocommerce_currency') ) {
839
- return $cost;
840
- }
841
-
842
- if( isset( $_POST[ 'form' ] ) ){
843
- parse_str( $_POST[ 'form' ], $posted );
844
-
845
- $booking_id = $posted[ 'add-to-cart' ];
846
-
847
- }elseif( isset( $_POST[ 'add-to-cart' ] ) ){
848
-
849
- $booking_id = $_POST[ 'add-to-cart' ];
850
-
851
- }
852
-
853
- if( isset( $booking_id ) ){
854
- $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $booking_id ) );
855
-
856
- if( $booking_id != $original_id ){
857
- $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
858
- $fields = $fields[$key];
859
- }
860
- }
861
-
862
- if( isset( $fields[ $name.$currency ] ) ){
863
- return $fields[ $name.$currency ];
864
- }else{
865
- return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
866
- }
867
-
868
- }
869
-
870
- return $cost;
871
-
872
- }
873
-
874
- function load_assets( $external_product_type = false ){
875
- global $pagenow;
876
-
877
- $product = $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ? wc_get_product( $_GET[ 'post' ] ) : false;
878
-
879
- if( ( $product && ( $product->product_type == 'booking' || $product->product_type == $external_product_type ) ) || $pagenow == 'post-new.php' ){
880
-
881
- wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
882
- wp_enqueue_style( 'wcml-bookings-css' );
883
-
884
- wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
885
- wp_enqueue_script( 'wcml-bookings-js' );
886
-
887
- }
888
-
889
- }
890
-
891
- function localize_lock_fields_js(){
892
- wp_localize_script( 'wcml-bookings-js', 'lock_settings' , array( 'lock_fields' => 1 ) );
893
- }
894
-
895
- function wcml_multi_currency_is_ajax( $actions ){
896
-
897
- $actions[] = 'wc_bookings_calculate_costs';
898
-
899
- return $actions;
900
- }
901
-
902
- function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ){
903
-
904
- if( $cart_item[ 'data' ] instanceof WC_Product_Booking && isset( $cart_item[ 'booking' ] ) ){
905
-
906
-
907
- $current_id = apply_filters( 'translate_object_id', $cart_item[ 'data' ]->id, 'product', true, $current_language );
908
- $cart_product_id = $cart_item['data']->id;
909
-
910
- if( $current_id != $cart_product_id ) {
911
-
912
- $cart_item['data'] = new WC_Product_Booking( $current_id );
913
-
914
- }
915
-
916
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ){
917
-
918
- $booking_info = array(
919
- 'wc_bookings_field_start_date_year' => $cart_item[ 'booking' ][ '_year' ],
920
- 'wc_bookings_field_start_date_month' => $cart_item[ 'booking' ][ '_month' ],
921
- 'wc_bookings_field_start_date_day' => $cart_item[ 'booking' ][ '_day' ],
922
- 'add-to-cart' => $current_id
923
- );
924
-
925
- if( isset( $cart_item[ 'booking' ][ '_persons' ] ) ){
926
- foreach( $cart_item[ 'booking' ][ '_persons' ] as $person_id => $value ){
927
- $booking_info[ 'wc_bookings_field_persons_' . apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $current_language ) ] = $value;
928
- }
929
- }
930
-
931
- if( isset( $cart_item[ 'booking' ][ '_resource_id' ] ) ){
932
- $booking_info[ 'wc_bookings_field_resource' ] = apply_filters( 'translate_object_id', $cart_item[ 'booking' ][ '_resource_id' ], 'bookable_resource', false, $current_language);
933
- }
934
-
935
- if( isset( $cart_item[ 'booking' ][ '_duration' ] ) ){
936
- $booking_info[ 'wc_bookings_field_duration' ] = $cart_item[ 'booking' ][ '_duration' ];
937
- }
938
-
939
- if( isset( $cart_item[ 'booking' ][ '_time' ] ) ){
940
- $booking_info[ 'wc_bookings_field_start_date_time' ] = $cart_item[ 'booking' ][ '_time' ];
941
- }
942
-
943
- $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
944
-
945
- $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
946
- update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item[ 'booking' ][ '_qty' ] ) );
947
- $cost = $booking_form->calculate_booking_cost( $booking_info );
948
- update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
949
-
950
- if( !is_wp_error( $cost ) ){
951
- $cart_item[ 'data' ]->set_price( $cost );
952
- }
953
- }
954
-
955
- }
956
-
957
- return $cart_item;
958
-
959
- }
960
-
961
- function booking_currency_dropdown(){
962
-
963
-
964
- if( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
965
- $current_booking_currency = $this->get_cookie_booking_currency();
966
-
967
- $wc_currencies = get_woocommerce_currencies();
968
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
969
- ?>
970
- <tr valign="top">
971
- <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
972
- <td>
973
- <select id="dropdown_booking_currency">
974
-
975
- <?php foreach($currencies as $currency => $count ): ?>
976
-
977
- <option value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"':''; ?>><?php echo $wc_currencies[$currency]; ?></option>
978
-
979
- <?php endforeach; ?>
980
-
981
- </select>
982
- </td>
983
- </tr>
984
-
985
- <?php
986
-
987
- $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
988
-
989
- wc_enqueue_js( "
990
-
991
- jQuery(document).on('change', '#dropdown_booking_currency', function(){
992
- jQuery.ajax({
993
- url: ajaxurl,
994
- type: 'post',
995
- data: {
996
- action: 'wcml_booking_set_currency',
997
- currency: jQuery('#dropdown_booking_currency').val(),
998
- wcml_nonce: '".$wcml_booking_set_currency_nonce."'
999
- },
1000
- success: function( response ){
1001
- if(typeof response.error !== 'undefined'){
1002
- alert(response.error);
1003
- }else{
1004
- window.location = window.location.href;
1005
- }
1006
- }
1007
- })
1008
- });
1009
- ");
1010
-
1011
- }
1012
-
1013
- }
1014
-
1015
- function set_booking_currency_ajax(){
1016
-
1017
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1018
- if(!$nonce || !wp_verify_nonce($nonce, 'booking_set_currency')){
1019
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
1020
- die();
1021
- }
1022
-
1023
- $this->set_booking_currency(filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ));
1024
-
1025
- die();
1026
- }
1027
-
1028
- function set_booking_currency( $currency_code = false ){
1029
-
1030
- if( !isset( $_COOKIE [ '_wcml_booking_currency' ]) && !headers_sent()) {
1031
-
1032
-
1033
- $currency_code = get_woocommerce_currency();
1034
-
1035
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
1036
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
1037
-
1038
- if (!isset($order_currencies[$currency_code])) {
1039
- foreach ($order_currencies as $currency_code => $count) {
1040
- $currency_code = $currency_code;
1041
- break;
1042
- }
1043
- }
1044
- }
1045
- }
1046
-
1047
- if( $currency_code ){
1048
- setcookie('_wcml_booking_currency', $currency_code , time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
1049
- }
1050
-
1051
- }
1052
-
1053
- function get_cookie_booking_currency(){
1054
-
1055
- if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) ){
1056
- $currency = $_COOKIE[ '_wcml_booking_currency' ];
1057
- }else{
1058
- $currency = get_woocommerce_currency();
1059
- }
1060
-
1061
- return $currency;
1062
- }
1063
-
1064
- function filter_booking_currency_symbol( $currency ){
1065
- global $pagenow;
1066
-
1067
- remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1068
- if( isset( $_COOKIE [ '_wcml_booking_currency' ] ) && $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ){
1069
- $currency = get_woocommerce_currency_symbol( $_COOKIE [ '_wcml_booking_currency' ] );
1070
- }
1071
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1072
-
1073
- return $currency;
1074
- }
1075
-
1076
- function create_booking_page_client_currency( $currency ){
1077
- global $pagenow;
1078
-
1079
- if( wpml_is_ajax() && isset( $_POST[ 'form' ] ) ){
1080
- parse_str( $_POST[ 'form' ], $posted );
1081
- }
1082
-
1083
- if( ( $pagenow == 'edit.php' && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'create_booking' ) || ( isset( $posted[ '_wp_http_referer' ] ) && strpos( $posted[ '_wp_http_referer' ], 'page=create_booking' ) !== false ) ){
1084
- $currency = $this->get_cookie_booking_currency();
1085
- }
1086
-
1087
- return $currency;
1088
- }
1089
-
1090
- function set_order_currency_on_create_booking_page( $order_id ){
1091
- update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1092
-
1093
- update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
1094
-
1095
- }
1096
-
1097
- function filter_get_booking_products_args( $args ){
1098
- if( isset( $args['suppress_filters'] ) ){
1099
- $args['suppress_filters'] = false;
1100
- }
1101
- return $args;
1102
- }
1103
-
1104
- function custom_box_html( $obj, $product_id, $data ){
1105
- if( wc_get_product($product_id)->product_type != 'booking' ){
1106
- return;
1107
- }
1108
-
1109
- $bookings_section = new WPML_Editor_UI_Field_Section( __( 'Bookings', 'woocommerce-multilingual' ) );
1110
-
1111
- if( get_post_meta( $product_id,'_wc_booking_has_resources',true) == 'yes' ){
1112
- $group = new WPML_Editor_UI_Field_Group( '', true );
1113
- $booking_field = new WPML_Editor_UI_Single_Line_Field( '_wc_booking_resouce_label', __( 'Resources Label', 'woocommerce-multilingual' ), $data, true );
1114
- $group->add_field( $booking_field );
1115
- $bookings_section->add_field( $group );
1116
- }
1117
-
1118
- $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1119
-
1120
- if( $orig_resources ){
1121
- $group = new WPML_Editor_UI_Field_Group( __( 'Resources', 'woocommerce-multilingual' ) );
1122
- $group_title = __( 'Resources', 'woocommerce-multilingual' );
1123
- foreach ( $orig_resources as $resource_id => $cost) {
1124
-
1125
- if ($resource_id == 'custom_costs') continue;
1126
-
1127
- $group = new WPML_Editor_UI_Field_Group( $group_title );
1128
- $group_title = '';
1129
-
1130
- $resource_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-resource_'.$resource_id.'_title', __( 'Title', 'woocommerce-multilingual' ), $data, true );
1131
- $group->add_field( $resource_field );
1132
- $bookings_section->add_field( $group );
1133
- }
1134
-
1135
- }
1136
-
1137
- $original_persons = $this->get_original_persons( $product_id );
1138
- end( $original_persons );
1139
- $last_key = key( $original_persons );
1140
- $divider = true;
1141
- $group_title = __( 'Person Types', 'woocommerce-multilingual' );
1142
- foreach( $original_persons as $person_id ){
1143
- if( $person_id == $last_key ){
1144
- $divider = false;
1145
- }
1146
- $group = new WPML_Editor_UI_Field_Group( $group_title , $divider );
1147
- $group_title = '';
1148
-
1149
- $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_'.$person_id.'_title', __( 'Person Type Name', 'woocommerce-multilingual' ), $data, false );
1150
- $group->add_field( $person_field );
1151
- $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_'.$person_id.'_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
1152
- $group->add_field( $person_field );
1153
- $bookings_section->add_field( $group );
1154
-
1155
- }
1156
-
1157
- if( $orig_resources || $original_persons ){
1158
- $obj->add_field( $bookings_section );
1159
- }
1160
-
1161
- }
1162
-
1163
-
1164
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
1165
-
1166
- if( wc_get_product($product_id)->product_type != 'booking' ){
1167
- return $data;
1168
- }
1169
-
1170
- if( get_post_meta( $product_id,'_wc_booking_has_resources',true) == 'yes' ){
1171
-
1172
- $data[ '_wc_booking_resouce_label' ] = array( 'original' => get_post_meta( $product_id,'_wc_booking_resouce_label',true) );
1173
- $data[ '_wc_booking_resouce_label' ][ 'translation' ] = $translation ? get_post_meta( $translation->ID,'_wc_booking_resouce_label',true) : '';
1174
- }
1175
-
1176
- $orig_resources = $this->get_original_resources( $product_id );
1177
-
1178
- if( $orig_resources && is_array( $orig_resources ) ){
1179
-
1180
- foreach ( $orig_resources as $resource_id => $cost) {
1181
-
1182
- if ( 'custom_costs' === $resource_id ){
1183
- continue;
1184
- }
1185
- $data[ 'bookings-resource_'.$resource_id.'_title' ] = array( 'original' => get_the_title( $resource_id ) );
1186
- global $sitepress;
1187
- $trns_resource_id = apply_filters('translate_object_id', $resource_id, 'bookable_resource', false, $lang);
1188
- $data[ 'bookings-resource_'.$resource_id.'_title' ][ 'translation' ] = $trns_resource_id ? get_the_title( $trns_resource_id ) : '';
1189
- }
1190
- }
1191
-
1192
- $original_persons = $this->get_original_persons( $product_id );
1193
-
1194
- foreach( $original_persons as $person_id ){
1195
-
1196
- $data[ 'bookings-person_'.$person_id.'_title' ] = array( 'original' => get_the_title( $person_id ) );
1197
- $data[ 'bookings-person_'.$person_id.'_description' ] = array( 'original' => get_post( $person_id )->post_excerpt );
1198
-
1199
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $lang );
1200
- $data[ 'bookings-person_'.$person_id.'_title' ][ 'translation' ] = $trnsl_person_id ? get_the_title( $trnsl_person_id ) : '';
1201
- $data[ 'bookings-person_'.$person_id.'_description' ][ 'translation' ] = $trnsl_person_id ? get_post( $trnsl_person_id )->post_excerpt : '';
1202
-
1203
- }
1204
-
1205
- return $data;
1206
- }
1207
-
1208
-
1209
- function get_original_resources( $product_id ){
1210
- $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1211
- return $orig_resources;
1212
- }
1213
-
1214
- function get_original_persons( $product_id ){
1215
- $original_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person' AND post_status = 'publish'", $product_id ) );
1216
- return $original_persons;
1217
- }
1218
-
1219
- function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ){
1220
- if( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ){
1221
- return false;
1222
- }
1223
- return $check;
1224
- }
1225
-
1226
- function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ){
1227
- if( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ){
1228
- $exception = true;
1229
- }
1230
- return $exception;
1231
- }
1232
-
1233
- function remove_single_custom_fields_to_translate( $fields ){
1234
- $fields[] = '_wc_booking_resouce_label';
1235
-
1236
- return $fields;
1237
- }
1238
-
1239
- function product_content_resource_label( $meta_key, $product_id ){
1240
- if ($meta_key == '_wc_booking_resouce_label'){
1241
- return __( 'Resources label', 'woocommerce-multilingual' );
1242
- }
1243
- return $meta_key;
1244
- }
1245
-
1246
- function wcml_products_tab_sync_resources_and_persons( $original_product_id, $tr_product_id, $data, $language ){
1247
- global $wpml_post_translations;
1248
-
1249
- remove_action ( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1250
-
1251
- $orig_resources = $orig_resources = $this->get_original_resources( $original_product_id );;
1252
-
1253
- if( $orig_resources ){
1254
-
1255
- foreach( $orig_resources as $orig_resource_id => $cost ){
1256
-
1257
- $resource_id = apply_filters( 'translate_object_id', $orig_resource_id, 'bookable_resource', false, $language );
1258
- $orig_resource = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $orig_resource_id, $original_product_id ), OBJECT );
1259
-
1260
- if( is_null( $resource_id ) ){
1261
-
1262
- if( $orig_resource ) {
1263
- $resource_id = $this->duplicate_resource( $tr_product_id, $orig_resource, $language);
1264
- }else{
1265
- continue;
1266
- }
1267
-
1268
- }else{
1269
- //update_relationship
1270
-
1271
- $exist = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $resource_id, $tr_product_id ) );
1272
-
1273
- if( !$exist ){
1274
-
1275
- $this->wpdb->insert(
1276
- $this->wpdb->prefix . 'wc_booking_relationships',
1277
- array(
1278
- 'product_id' => $tr_product_id,
1279
- 'resource_id' => $resource_id,
1280
- 'sort_order' => $orig_resource->sort_order
1281
- )
1282
- );
1283
-
1284
- }
1285
-
1286
- }
1287
-
1288
-
1289
-
1290
- $this->wpdb->update(
1291
- $this->wpdb->posts,
1292
- array(
1293
- 'post_title' => $data[ md5( 'bookings-resource_'.$orig_resource_id.'_title') ]
1294
- ),
1295
- array(
1296
- 'ID' => $resource_id
1297
- )
1298
- );
1299
-
1300
- update_post_meta( $resource_id, 'wcml_is_translated', true );
1301
-
1302
- }
1303
-
1304
- //sync resources data
1305
- $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1306
-
1307
- }
1308
-
1309
- $original_persons = $this->get_original_persons( $original_product_id );
1310
-
1311
- //sync persons
1312
- if( $original_persons ){
1313
-
1314
- foreach( $original_persons as $original_person_id ){
1315
-
1316
- $person_id = apply_filters( 'translate_object_id', $original_person_id, 'bookable_person', false, $language );
1317
-
1318
- if( is_null( $person_id ) ){
1319
-
1320
- $person_id = $this->duplicate_person( $tr_product_id, $original_person_id, $language);
1321
-
1322
- }else{
1323
-
1324
- $this->wpdb->update(
1325
- $this->wpdb->posts,
1326
- array(
1327
- 'post_parent' => $tr_product_id
1328
- ),
1329
- array(
1330
- 'ID' => $person_id
1331
- )
1332
- );
1333
-
1334
- }
1335
-
1336
- $this->wpdb->update(
1337
- $this->wpdb->posts,
1338
- array(
1339
- 'post_title' => $data[ md5 ( 'bookings-person_'.$original_person_id.'_title' ) ],
1340
- 'post_excerpt' => $data[ md5( 'bookings-person_'.$original_person_id.'_description' ) ],
1341
- ),
1342
- array(
1343
- 'ID' => $person_id
1344
- )
1345
- );
1346
-
1347
- update_post_meta( $person_id, 'wcml_is_translated', true );
1348
-
1349
- }
1350
-
1351
- //sync persons data
1352
- $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1353
-
1354
- }
1355
-
1356
- add_action ( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1357
-
1358
- }
1359
-
1360
- function duplicate_booking_for_translations( $booking_id, $lang = false ){
1361
- $booking_object = get_post( $booking_id );
1362
-
1363
- $booking_data = array(
1364
- 'post_type' => 'wc_booking',
1365
- 'post_title' => $booking_object->post_title,
1366
- 'post_status' => $booking_object->post_status,
1367
- 'ping_status' => 'closed',
1368
- 'post_parent' => $booking_object->post_parent,
1369
- );
1370
-
1371
- $active_languages = $this->sitepress->get_active_languages();
1372
-
1373
- foreach( $active_languages as $language ){
1374
-
1375
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1376
-
1377
- if( !$lang ){
1378
- $booking_language = $this->sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1379
- if ( $booking_language->language_code == $language['code'] ) {
1380
- continue;
1381
- }
1382
- }elseif( $lang != $language['code'] ){
1383
- continue;
1384
- }
1385
-
1386
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1387
- $trnsl_booking_persons = array();
1388
-
1389
- if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1390
- foreach( $booking_persons as $person_id => $person_count ){
1391
-
1392
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1393
-
1394
- if( is_null( $trnsl_person_id ) ){
1395
- $trnsl_booking_persons[] = $person_count;
1396
- }else{
1397
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1398
- }
1399
-
1400
- }
1401
- }
1402
-
1403
- $trnsl_booking_id = wp_insert_post( $booking_data );
1404
- $trid = $this->sitepress->get_element_trid( $booking_id );
1405
- $this->sitepress->set_element_language_details( $trnsl_booking_id, 'post_wc_booking', $trid, $language['code'] );
1406
-
1407
- $meta_args = array(
1408
- '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1409
- '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1410
- '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1411
- '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1412
- '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1413
- '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1414
- '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1415
- '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1416
- '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1417
- '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1418
- '_booking_duplicate_of' => $booking_id,
1419
- '_language_code' => $language['code'],
1420
- );
1421
-
1422
- foreach ( $meta_args as $key => $value ) {
1423
- update_post_meta( $trnsl_booking_id, $key, $value );
1424
- }
1425
-
1426
- WC_Cache_Helper::get_transient_version( 'bookings', true );
1427
-
1428
- }
1429
-
1430
-
1431
- }
1432
-
1433
- function get_translated_booking_product_id( $booking_id, $language ){
1434
-
1435
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1436
- $trnsl_booking_product_id = '';
1437
-
1438
- if( $booking_product_id ){
1439
- $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1440
- if( is_null( $trnsl_booking_product_id ) ){
1441
- $trnsl_booking_product_id = '';
1442
- }
1443
- }
1444
-
1445
- return $trnsl_booking_product_id;
1446
-
1447
- }
1448
-
1449
- function get_translated_booking_resource_id( $booking_id, $language ){
1450
-
1451
- $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1452
- $trnsl_booking_resource_id = '';
1453
-
1454
- if( $booking_resource_id ){
1455
- $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1456
-
1457
- if( is_null( $trnsl_booking_resource_id ) ){
1458
- $trnsl_booking_resource_id = '';
1459
- }
1460
- }
1461
-
1462
- return $trnsl_booking_resource_id;
1463
- }
1464
-
1465
- function get_translated_booking_persons_ids( $booking_id, $language ){
1466
-
1467
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1468
- $trnsl_booking_persons = array();
1469
-
1470
- if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1471
- foreach( $booking_persons as $person_id => $person_count ){
1472
-
1473
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1474
-
1475
- if( is_null( $trnsl_person_id ) ){
1476
- $trnsl_booking_persons[] = $person_count;
1477
- }else{
1478
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1479
- }
1480
-
1481
- }
1482
- }
1483
- return $trnsl_booking_persons;
1484
-
1485
- }
1486
-
1487
- function update_status_for_translations( $booking_id ){
1488
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1489
-
1490
- foreach( $translated_bookings as $booking ){
1491
-
1492
- $status = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT post_status FROM {$this->wpdb->posts} WHERE ID = %d", $booking_id ) ); //get_post_status( $booking_id );
1493
- $language = get_post_meta( $booking->post_id, '_language_code', true );
1494
-
1495
- $this->wpdb->update(
1496
- $this->wpdb->posts,
1497
- array(
1498
- 'post_status' => $status,
1499
- 'post_parent' => wp_get_post_parent_id( $booking_id ),
1500
- ),
1501
- array(
1502
- 'ID' => $booking->post_id
1503
- )
1504
- );
1505
-
1506
- update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1507
- update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1508
- update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1509
-
1510
- }
1511
-
1512
- }
1513
-
1514
- function get_translated_bookings($booking_id){
1515
- $translated_bookings = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_duplicate_of' AND meta_value = %d", $booking_id ) );
1516
-
1517
- return $translated_bookings;
1518
- }
1519
-
1520
- public function booking_filters_query( $query ) {
1521
- global $typenow;
1522
-
1523
- if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1524
-
1525
- $current_lang = $this->sitepress->get_current_language();
1526
-
1527
- $product_ids = $this->wpdb->get_col( $this->wpdb->prepare(
1528
- "SELECT element_id
1529
- FROM {$this->wpdb->prefix}icl_translations
1530
- WHERE language_code = %s AND element_type = 'post_product'", $current_lang ) );
1531
-
1532
- $product_ids = array_diff( $product_ids, array( NULL ) );
1533
-
1534
- if( ( !isset( $_GET['lang'] ) || ( isset( $_GET['lang'] ) && $_GET['lang'] != 'all' ) ) ){
1535
- $query->query_vars[ 'meta_query' ][] = array(
1536
- 'relation' => 'OR',
1537
- array(
1538
- 'key' => '_language_code',
1539
- 'value' => $current_lang,
1540
- 'compare ' => '='
1541
- ),
1542
- array(
1543
- 'key' => '_booking_product_id',
1544
- 'value' => $product_ids,
1545
- 'compare ' => 'IN'
1546
- )
1547
- );
1548
- }
1549
- }
1550
-
1551
- return $query;
1552
- }
1553
-
1554
- function bookings_in_date_range_query($booking_ids){
1555
- foreach ( $booking_ids as $key => $booking_id ) {
1556
-
1557
- $language_code = $this->sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ) , 'post_product' );
1558
- $current_language = $this->sitepress->get_current_language();
1559
-
1560
- if( $language_code != $current_language ){
1561
- unset( $booking_ids[$key] );
1562
- }
1563
-
1564
- }
1565
-
1566
- return $booking_ids;
1567
-
1568
- }
1569
-
1570
- function clear_transient_fields(){
1571
-
1572
- if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1573
-
1574
- //delete transient fields
1575
- $this->wpdb->query("
1576
- DELETE FROM {$this->wpdb->options}
1577
- WHERE option_name LIKE '%book_dr_%'
1578
- ");
1579
-
1580
- }
1581
-
1582
- }
1583
-
1584
- function delete_bookings( $booking_id ){
1585
-
1586
- if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1587
-
1588
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1589
-
1590
- remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1591
-
1592
- foreach( $translated_bookings as $booking ){
1593
- $this->wpdb->update(
1594
- $this->wpdb->posts,
1595
- array(
1596
- 'post_parent' => 0
1597
- ),
1598
- array(
1599
- 'ID' => $booking->post_id
1600
- )
1601
- );
1602
-
1603
- wp_delete_post( $booking->post_id );
1604
-
1605
- }
1606
-
1607
- add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1608
- }
1609
-
1610
- }
1611
-
1612
- function trash_bookings( $booking_id ){
1613
-
1614
- if( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ){
1615
-
1616
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1617
-
1618
- foreach( $translated_bookings as $booking ){
1619
-
1620
- $this->wpdb->update(
1621
- $this->wpdb->posts,
1622
- array(
1623
- 'post_status' => 'trash'
1624
- ),
1625
- array(
1626
- 'ID' => $booking->post_id
1627
- )
1628
- );
1629
-
1630
- }
1631
-
1632
- }
1633
-
1634
- }
1635
-
1636
- function append_persons_to_translation_package( $package, $post ){
1637
-
1638
- if( $post->post_type == 'product' ){
1639
- $product = wc_get_product( $post->ID );
1640
-
1641
- //WC_Product::get_type() available from WooCommerce 2.4.0
1642
- $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1643
-
1644
- if( $product_type == 'booking' ){
1645
-
1646
- $bookable_product = new WC_Product_Booking( $post->ID );
1647
-
1648
- $person_types = $bookable_product->get_person_types();
1649
-
1650
- foreach( $person_types as $person_type ) {
1651
-
1652
- $package['contents']['wc_bookings:person:' . $person_type->ID . ':name'] = array(
1653
- 'translate' => 1,
1654
- 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1655
- 'format' => 'base64'
1656
- );
1657
-
1658
- $package['contents']['wc_bookings:person:' . $person_type->ID . ':description'] = array(
1659
- 'translate' => 1,
1660
- 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1661
- 'format' => 'base64'
1662
- );
1663
-
1664
- }
1665
-
1666
- }
1667
-
1668
- }
1669
-
1670
- return $package;
1671
-
1672
- }
1673
-
1674
- function save_person_translation($post_id, $data, $job ){
1675
- $person_translations = array();
1676
-
1677
- foreach($data as $value){
1678
-
1679
- if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1680
-
1681
- $exp = explode( ':', $value['field_type'] );
1682
-
1683
- $person_id = $exp[2];
1684
- $field = $exp[3];
1685
-
1686
- $person_translations[$person_id][$field] = $value['data'];
1687
-
1688
- }
1689
-
1690
- }
1691
-
1692
- if( $person_translations ){
1693
-
1694
- foreach( $person_translations as $person_id => $pt ){
1695
-
1696
- $person_trid = $this->sitepress->get_element_trid( $person_id, 'post_bookable_person');
1697
-
1698
-
1699
- $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1700
-
1701
- if( empty($person_id_translated) ) {
1702
-
1703
- $person_post = array(
1704
-
1705
- 'post_type' => 'bookable_person',
1706
- 'post_status' => 'publish',
1707
- 'post_title' => $pt['name'],
1708
- 'post_parent' => $post_id,
1709
- 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1710
-
1711
- );
1712
-
1713
- $person_id_translated = wp_insert_post( $person_post );
1714
-
1715
- $this->sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1716
-
1717
- } else {
1718
-
1719
- $person_post = array(
1720
- 'ID' => $person_id_translated,
1721
- 'post_title' => $pt['name'],
1722
- 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1723
- );
1724
-
1725
- wp_update_post( $person_post );
1726
-
1727
- }
1728
-
1729
- }
1730
-
1731
- }
1732
-
1733
- }
1734
-
1735
- function append_resources_to_translation_package( $package, $post ){
1736
-
1737
- if( $post->post_type == 'product' ){
1738
- $product = wc_get_product( $post->ID );
1739
-
1740
- //WC_Product::get_type() available from WooCommerce 2.4.0
1741
- $product_type = method_exists($product, 'get_type') ? $product->get_type() : $product->product_type;
1742
-
1743
- if( $product_type == 'booking' && $product->has_resources() ){
1744
-
1745
- $resources = $product->get_resources();
1746
-
1747
- foreach( $resources as $resource ) {
1748
-
1749
- $package['contents']['wc_bookings:resource:' . $resource->ID . ':name'] = array(
1750
- 'translate' => 1,
1751
- 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1752
- 'format' => 'base64'
1753
- );
1754
-
1755
- }
1756
-
1757
- }
1758
-
1759
- }
1760
-
1761
- return $package;
1762
-
1763
- }
1764
-
1765
- function save_resource_translation( $post_id, $data, $job ){
1766
- $resource_translations = array();
1767
-
1768
- foreach($data as $value){
1769
-
1770
- if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1771
-
1772
- $exp = explode( ':', $value['field_type'] );
1773
-
1774
- $resource_id = $exp[2];
1775
- $field = $exp[3];
1776
-
1777
- $resource_translations[$resource_id][$field] = $value['data'];
1778
-
1779
- }
1780
-
1781
- }
1782
-
1783
- if( $resource_translations ){
1784
-
1785
- foreach( $resource_translations as $resource_id => $rt ){
1786
-
1787
- $resource_trid = $this->sitepress->get_element_trid( $resource_id, 'post_bookable_resource');
1788
-
1789
- $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1790
-
1791
- if( empty($resource_id_translated) ) {
1792
-
1793
- $resource_post = array(
1794
-
1795
- 'post_type' => 'bookable_resource',
1796
- 'post_status' => 'publish',
1797
- 'post_title' => $rt['name'],
1798
- 'post_parent' => $post_id
1799
- );
1800
-
1801
- $resource_id_translated = wp_insert_post( $resource_post );
1802
-
1803
- $this->sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
1804
-
1805
- $sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1806
- $relationship = array(
1807
- 'product_id' => $post_id,
1808
- 'resource_id' => $resource_id_translated,
1809
- 'sort_order' => $sort_order
1810
- );
1811
- $this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship);
1812
-
1813
- } else {
1814
-
1815
- $resource_post = array(
1816
- 'ID' => $resource_id_translated,
1817
- 'post_title' => $rt['name']
1818
- );
1819
-
1820
- wp_update_post( $resource_post );
1821
-
1822
- $sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1823
- $this->wpdb->update( $this->wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1824
- array ( 'product_id' => $post_id, 'resource_id' => $resource_id_translated) );
1825
-
1826
-
1827
- }
1828
-
1829
-
1830
- }
1831
-
1832
- }
1833
-
1834
- }
1835
-
1836
- function wcml_js_lock_fields_ids( $ids ){
1837
-
1838
- $ids = array_merge( $ids, array(
1839
- '_wc_booking_has_resources',
1840
- '_wc_booking_has_persons',
1841
- '_wc_booking_duration_type',
1842
- '_wc_booking_duration',
1843
- '_wc_booking_duration_unit',
1844
- '_wc_booking_calendar_display_mode',
1845
- '_wc_booking_requires_confirmation',
1846
- '_wc_booking_user_can_cancel',
1847
- '_wc_accommodation_booking_min_duration',
1848
- '_wc_accommodation_booking_max_duration',
1849
- '_wc_accommodation_booking_max_duration',
1850
- '_wc_accommodation_booking_calendar_display_mode',
1851
- '_wc_accommodation_booking_requires_confirmation',
1852
- '_wc_accommodation_booking_user_can_cancel',
1853
- '_wc_accommodation_booking_cancel_limit',
1854
- '_wc_accommodation_booking_cancel_limit_unit',
1855
- '_wc_accommodation_booking_qty',
1856
- '_wc_accommodation_booking_min_date',
1857
- '_wc_accommodation_booking_min_date_unit',
1858
- '_wc_accommodation_booking_max_date',
1859
- '_wc_accommodation_booking_max_date_unit',
1860
- 'bookings_pricing select',
1861
- 'bookings_resources select',
1862
- 'bookings_availability select',
1863
- 'bookings_persons input[type="checkbox"]'
1864
- ) );
1865
-
1866
- return $ids;
1867
- }
1868
-
1869
- /**
1870
- * @param array $args
1871
- *
1872
- * @return array
1873
- */
1874
- public function filter_get_booking_resources_args( $args ){
1875
-
1876
- $screen = get_current_screen();
1877
- if( $screen->id == 'product' ){
1878
- $args['suppress_filters'] = false;
1879
- }
1880
-
1881
- return $args;
1882
-
1883
- }
1884
-
1885
- /**
1886
- * @param array $currencies
1887
- * @param int $post_id
1888
- *
1889
- * @return bool
1890
- */
1891
- private function update_booking_costs( $currencies = array(), $post_id = 0 ) {
1892
- $booking_options = array(
1893
- 'wcml_wc_booking_cost' => '_wc_booking_cost_',
1894
- 'wcml_wc_booking_base_cost' => '_wc_booking_base_cost_',
1895
- 'wcml_wc_display_cost' => '_wc_display_cost_',
1896
- );
1897
-
1898
- foreach( $currencies as $code => $currency ) {
1899
- foreach( $booking_options as $booking_options_post_key => $booking_options_meta_key_prefix ) {
1900
- if ( isset( $_POST[ $booking_options_post_key ][ $code ] ) && '' !== $_POST[ $booking_options_post_key ][ $code ] ) {
1901
- update_post_meta( $post_id, $booking_options_meta_key_prefix . $code, sanitize_text_field( $_POST[ $booking_options_post_key ][ $code ] ) );
1902
- }
1903
- }
1904
- }
1905
-
1906
- return true;
1907
- }
1908
-
1909
- /**
1910
- * @param array $currencies
1911
- * @param int $post_id
1912
- *
1913
- * @return bool
1914
- */
1915
- private function update_booking_pricing( $currencies = array(), $post_id = 0 ) {
1916
- $updated_meta = array();
1917
- $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
1918
- if ( empty( $booking_pricing ) ) {
1919
- return false;
1920
- }
1921
-
1922
- foreach ( $booking_pricing as $key => $prices) {
1923
- $updated_meta[ $key ] = $prices;
1924
- foreach ( $currencies as $code => $currency ) {
1925
- if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
1926
- $updated_meta[ $key ]['base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
1927
- }
1928
- if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
1929
- $updated_meta[ $key ]['cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
1930
- }
1931
- }
1932
-
1933
- }
1934
-
1935
- update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
1936
- return true;
1937
- }
1938
-
1939
- /**
1940
- * @param array $currencies
1941
- * @param array $person_costs
1942
- *
1943
- * @return bool
1944
- */
1945
- private function update_booking_person_cost( $currencies = array(), $person_costs = array() ) {
1946
- if( empty( $person_costs ) ) {
1947
- return false;
1948
- }
1949
-
1950
- foreach( $person_costs as $person_id => $costs ) {
1951
- foreach ( $currencies as $code => $currency ) {
1952
- if ( isset( $costs[ $code ] ) ) {
1953
- update_post_meta( $person_id, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
1954
- }
1955
- }
1956
- }
1957
- return true;
1958
- }
1959
-
1960
- /**
1961
- * @param array $currencies
1962
- * @param array $block_costs
1963
- *
1964
- * @return bool
1965
- */
1966
- private function update_booking_person_block_cost( $currencies = array(), $block_costs = array() ) {
1967
- if( empty( $block_costs ) ) {
1968
- return false;
1969
- }
1970
-
1971
- foreach( $block_costs as $person_id => $costs ){
1972
- foreach( $currencies as $code => $currency ){
1973
- if ( isset( $costs[ $code ] ) ) {
1974
- update_post_meta( $person_id, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
1975
- }
1976
- }
1977
- }
1978
- return true;
1979
- }
1980
-
1981
- /**
1982
- * @param array $currencies
1983
- * @param int $post_id
1984
- * @param array $resource_cost
1985
- *
1986
- * @return bool
1987
- */
1988
- private function update_booking_resource_cost( $currencies = array(), $post_id = 0, $resource_cost = array() ) {
1989
- if ( empty( $resource_cost ) ) {
1990
- return false;
1991
- }
1992
-
1993
- $updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
1994
- if ( ! is_array( $updated_meta ) ) {
1995
- $updated_meta = array();
1996
- }
1997
-
1998
- $wc_booking_resource_costs = array();
1999
-
2000
- foreach ( $resource_cost as $resource_id => $costs) {
2001
-
2002
- foreach ($currencies as $code => $currency) {
2003
-
2004
- if ( isset( $costs[ $code ] ) ) {
2005
- $wc_booking_resource_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2006
- }
2007
-
2008
- }
2009
-
2010
- }
2011
-
2012
- $updated_meta[ 'custom_costs' ] = $wc_booking_resource_costs;
2013
-
2014
- update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
2015
-
2016
- $this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
2017
-
2018
- return true;
2019
- }
2020
-
2021
- /**
2022
- * @param array $currencies
2023
- * @param int $post_id
2024
- *
2025
- * @return bool
2026
- */
2027
- private function update_booking_resource_block_cost( $currencies = array(), $post_id = 0, $resource_block_cost = array() ) {
2028
- if( empty( $resource_block_cost ) ) {
2029
- return false;
2030
- }
2031
-
2032
- $updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
2033
-
2034
- $wc_booking_resource_block_costs = array();
2035
-
2036
- foreach( $resource_block_cost as $resource_id => $costs ){
2037
-
2038
- foreach( $currencies as $code => $currency ){
2039
-
2040
- if ( isset( $costs[ $code ] ) ) {
2041
- $wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2042
- }
2043
-
2044
- }
2045
-
2046
- }
2047
-
2048
- $updated_meta[ 'custom_costs' ] = $wc_booking_resource_block_costs;
2049
-
2050
- update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
2051
-
2052
- $this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
2053
-
2054
- return true;
2055
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2056
  }
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Bookings.
5
+ */
6
+ class WCML_Bookings {
7
+
8
+ /**
9
+ * @var WPML_Element_Translation_Package
10
+ */
11
+ public $tp;
12
+
13
+ /**
14
+ * @var SitePress
15
+ */
16
+ public $sitepress;
17
+
18
+ /**
19
+ * @var woocommerce_wpml
20
+ */
21
+ public $woocommerce_wpml;
22
+
23
+ /**
24
+ * @var wpdb
25
+ */
26
+ public $wpdb;
27
+
28
+ /**
29
+ * WCML_Bookings constructor.
30
+ */
31
+ function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
32
+ $this->sitepress = $sitepress;
33
+ $this->woocommerce_wpml = $woocommerce_wpml;
34
+ $this->wpdb = $wpdb;
35
+ add_action( 'woocommerce_bookings_after_booking_base_cost', array(
36
+ $this,
37
+ 'wcml_price_field_after_booking_base_cost'
38
+ ) );
39
+ add_action( 'woocommerce_bookings_after_booking_block_cost', array(
40
+ $this,
41
+ 'wcml_price_field_after_booking_block_cost'
42
+ ) );
43
+ add_action( 'woocommerce_bookings_after_display_cost', array( $this, 'wcml_price_field_after_display_cost' ) );
44
+ add_action( 'woocommerce_bookings_after_booking_pricing_base_cost', array(
45
+ $this,
46
+ 'wcml_price_field_after_booking_pricing_base_cost'
47
+ ), 10, 2 );
48
+ add_action( 'woocommerce_bookings_after_booking_pricing_cost', array(
49
+ $this,
50
+ 'wcml_price_field_after_booking_pricing_cost'
51
+ ), 10, 2 );
52
+ add_action( 'woocommerce_bookings_after_person_cost', array( $this, 'wcml_price_field_after_person_cost' ) );
53
+ add_action( 'woocommerce_bookings_after_person_block_cost', array(
54
+ $this,
55
+ 'wcml_price_field_after_person_block_cost'
56
+ ) );
57
+ add_action( 'woocommerce_bookings_after_resource_cost', array(
58
+ $this,
59
+ 'wcml_price_field_after_resource_cost'
60
+ ), 10, 2 );
61
+ add_action( 'woocommerce_bookings_after_resource_block_cost', array(
62
+ $this,
63
+ 'wcml_price_field_after_resource_block_cost'
64
+ ), 10, 2 );
65
+ add_action( 'woocommerce_bookings_after_bookings_pricing', array( $this, 'after_bookings_pricing' ) );
66
+
67
+ add_action( 'init', array( $this, 'load_assets' ) );
68
+
69
+ add_action( 'save_post', array( $this, 'save_custom_costs' ), 110, 1 );
70
+ add_action( 'wcml_before_sync_product_data', array( $this, 'sync_bookings' ), 10, 3 );
71
+ add_action( 'wcml_before_sync_product', array( $this, 'sync_booking_data' ), 10, 2 );
72
+
73
+ add_filter( 'woocommerce_bookings_process_cost_rules_cost', array(
74
+ $this,
75
+ 'wc_bookings_process_cost_rules_cost'
76
+ ), 10, 3 );
77
+ add_filter( 'woocommerce_bookings_process_cost_rules_base_cost', array(
78
+ $this,
79
+ 'wc_bookings_process_cost_rules_base_cost'
80
+ ), 10, 3 );
81
+ add_filter( 'woocommerce_bookings_process_cost_rules_override_block', array(
82
+ $this,
83
+ 'wc_bookings_process_cost_rules_override_block_cost'
84
+ ), 10, 3 );
85
+
86
+ add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'wcml_multi_currency_is_ajax' ) );
87
+
88
+ add_filter( 'wcml_cart_contents_not_changed', array(
89
+ $this,
90
+ 'filter_bundled_product_in_cart_contents'
91
+ ), 10, 3 );
92
+
93
+ add_action( 'woocommerce_bookings_after_create_booking_page', array( $this, 'booking_currency_dropdown' ) );
94
+ add_action( 'init', array( $this, 'set_booking_currency' ) );
95
+
96
+ add_action( 'wp_ajax_wcml_booking_set_currency', array( $this, 'set_booking_currency_ajax' ) );
97
+ add_action( 'woocommerce_bookings_create_booking_page_add_order_item', array(
98
+ $this,
99
+ 'set_order_currency_on_create_booking_page'
100
+ ) );
101
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
102
+ add_filter( 'get_booking_products_args', array( $this, 'filter_get_booking_products_args' ) );
103
+ add_filter( 'wcml_filter_currency_position', array( $this, 'create_booking_page_client_currency' ) );
104
+
105
+ add_filter( 'wcml_client_currency', array( $this, 'create_booking_page_client_currency' ) );
106
+
107
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
108
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
109
+ add_filter( 'wcml_check_is_single', array( $this, 'show_custom_blocks_for_resources_and_persons' ), 10, 3 );
110
+ add_filter( 'wcml_product_content_exception', array( $this, 'remove_custom_fields_to_translate' ), 10, 3 );
111
+ add_filter( 'wcml_not_display_single_fields_to_translate', array(
112
+ $this,
113
+ 'remove_single_custom_fields_to_translate'
114
+ ) );
115
+ add_filter( 'wcml_product_content_label', array( $this, 'product_content_resource_label' ), 10, 2 );
116
+ add_action( 'wcml_update_extra_fields', array( $this, 'wcml_products_tab_sync_resources_and_persons' ), 10, 4 );
117
+
118
+ add_action( 'woocommerce_new_booking', array( $this, 'duplicate_booking_for_translations' ) );
119
+
120
+ $bookings_statuses = array(
121
+ 'unpaid',
122
+ 'pending-confirmation',
123
+ 'confirmed',
124
+ 'paid',
125
+ 'cancelled',
126
+ 'complete',
127
+ 'in-cart',
128
+ 'was-in-cart'
129
+ );
130
+ foreach ( $bookings_statuses as $status ) {
131
+ add_action( 'woocommerce_booking_' . $status, array( $this, 'update_status_for_translations' ) );
132
+ }
133
+
134
+ add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
135
+ add_filter( 'woocommerce_bookings_in_date_range_query', array( $this, 'bookings_in_date_range_query' ) );
136
+ add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
137
+ add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
138
+
139
+ if ( is_admin() ) {
140
+
141
+ $this->tp = new WPML_Element_Translation_Package;
142
+
143
+ add_filter( 'wpml_tm_translation_job_data', array(
144
+ $this,
145
+ 'append_persons_to_translation_package'
146
+ ), 10, 2 );
147
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_person_translation' ), 10, 3 );
148
+
149
+ add_filter( 'wpml_tm_translation_job_data', array(
150
+ $this,
151
+ 'append_resources_to_translation_package'
152
+ ), 10, 2 );
153
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_resource_translation' ), 10, 3 );
154
+
155
+ //lock fields on translations pages
156
+ add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
157
+ add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
158
+
159
+ //allow filtering resources by language
160
+ add_filter( 'get_booking_resources_args', array( $this, 'filter_get_booking_resources_args' ) );
161
+ }
162
+
163
+ if ( ! is_admin() || isset( $_POST['action'] ) && $_POST['action'] == 'wc_bookings_calculate_costs' ) {
164
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
165
+ }
166
+
167
+ //@TODO review after WPML 3.6
168
+ if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
169
+ add_action( 'added_post_meta', array(
170
+ $this,
171
+ 'maybe_fix_double_serialized_wc_booking_availability'
172
+ ), 10, 4 );
173
+ }
174
+
175
+
176
+ $this->clear_transient_fields();
177
+
178
+ }
179
+
180
+ function wcml_price_field_after_booking_base_cost( $post_id ) {
181
+
182
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
183
+
184
+ }
185
+
186
+ function wcml_price_field_after_booking_block_cost( $post_id ) {
187
+
188
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
189
+
190
+ }
191
+
192
+ function wcml_price_field_after_display_cost( $post_id ) {
193
+
194
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
195
+
196
+ }
197
+
198
+ function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ) {
199
+
200
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
201
+
202
+ }
203
+
204
+ function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ) {
205
+
206
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
207
+
208
+ }
209
+
210
+ function wcml_price_field_after_person_cost( $person_type_id ) {
211
+
212
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
213
+
214
+ }
215
+
216
+ function wcml_price_field_after_person_block_cost( $person_type_id ) {
217
+
218
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
219
+
220
+ }
221
+
222
+ function wcml_price_field_after_resource_cost( $resource_id, $post_id ) {
223
+
224
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
225
+
226
+ }
227
+
228
+ function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ) {
229
+
230
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
231
+
232
+ }
233
+
234
+ function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ) {
235
+
236
+
237
+ if ( ( ! $check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
238
+
239
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
240
+
241
+ $wc_currencies = get_woocommerce_currencies();
242
+
243
+ echo '<div class="wcml_custom_cost_field" >';
244
+
245
+ foreach ( $currencies as $currency_code => $currency ) {
246
+
247
+ switch ( $field ) {
248
+ case 'wcml_wc_booking_cost':
249
+ woocommerce_wp_text_input( array(
250
+ 'id' => 'wcml_wc_booking_cost',
251
+ 'class' => 'wcml_bookings_custom_price',
252
+ 'name' => 'wcml_wc_booking_cost[' . $currency_code . ']',
253
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
254
+ 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ),
255
+ 'value' => get_post_meta( $post_id, '_wc_booking_cost_' . $currency_code, true ),
256
+ 'type' => 'number',
257
+ 'desc_tip' => true,
258
+ 'custom_attributes' => array(
259
+ 'min' => '',
260
+ 'step' => '0.01'
261
+ )
262
+ ) );
263
+ break;
264
+ case 'wcml_wc_booking_base_cost':
265
+ woocommerce_wp_text_input( array(
266
+ 'id' => 'wcml_wc_booking_base_cost',
267
+ 'class' => 'wcml_bookings_custom_price',
268
+ 'name' => 'wcml_wc_booking_base_cost[' . $currency_code . ']',
269
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
270
+ 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ),
271
+ 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_' . $currency_code, true ),
272
+ 'type' => 'number',
273
+ 'desc_tip' => true,
274
+ 'custom_attributes' => array(
275
+ 'min' => '',
276
+ 'step' => '0.01'
277
+ )
278
+ ) );
279
+ break;
280
+ case 'wcml_wc_display_cost':
281
+ woocommerce_wp_text_input( array(
282
+ 'id' => 'wcml_wc_display_cost',
283
+ 'class' => 'wcml_bookings_custom_price',
284
+ 'name' => 'wcml_wc_display_cost[' . $currency_code . ']',
285
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
286
+ 'description' => __( 'The cost is displayed to the user on the frontend. Leave blank to have it calculated for you. If a booking has varying costs, this will be prefixed with the word "from:".', 'woocommerce-bookings' ),
287
+ 'value' => get_post_meta( $post_id, '_wc_display_cost_' . $currency_code, true ),
288
+ 'type' => 'number',
289
+ 'desc_tip' => true,
290
+ 'custom_attributes' => array(
291
+ 'min' => '',
292
+ 'step' => '0.01'
293
+ )
294
+ ) );
295
+ break;
296
+
297
+ case 'wcml_wc_booking_pricing_base_cost':
298
+
299
+ if ( isset( $pricing[ 'base_cost_' . $currency_code ] ) ) {
300
+ $value = $pricing[ 'base_cost_' . $currency_code ];
301
+ } else {
302
+ $value = '';
303
+ }
304
+
305
+ echo '<div class="wcml_bookings_range_block" >';
306
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
307
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_base_cost[' . $currency_code . '][]" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
308
+ echo '</div>';
309
+ break;
310
+
311
+ case 'wcml_wc_booking_pricing_cost':
312
+
313
+ if ( isset( $pricing[ 'cost_' . $currency_code ] ) ) {
314
+ $value = $pricing[ 'cost_' . $currency_code ];
315
+ } else {
316
+ $value = '';
317
+ }
318
+
319
+ echo '<div class="wcml_bookings_range_block" >';
320
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
321
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost[' . $currency_code . '][]" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
322
+ echo '</div>';
323
+ break;
324
+
325
+ case 'wcml_wc_booking_person_cost':
326
+
327
+ $value = get_post_meta( $post_id, 'cost_' . $currency_code, true );
328
+
329
+ echo '<div class="wcml_bookings_person_block" >';
330
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
331
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_person_cost[' . $post_id . '][' . $currency_code . ']" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
332
+ echo '</div>';
333
+ break;
334
+
335
+ case 'wcml_wc_booking_person_block_cost':
336
+
337
+ $value = get_post_meta( $post_id, 'block_cost_' . $currency_code, true );
338
+
339
+ echo '<div class="wcml_bookings_person_block" >';
340
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
341
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_person_block_cost[' . $post_id . '][' . $currency_code . ']" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
342
+ echo '</div>';
343
+ break;
344
+
345
+ case 'wcml_wc_booking_resource_cost':
346
+
347
+ $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
348
+
349
+ if ( isset( $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
350
+ $value = $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ];
351
+ } else {
352
+ $value = '';
353
+ }
354
+
355
+ echo '<div class="wcml_bookings_resource_block" >';
356
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
357
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_cost[' . $resource_id . '][' . $currency_code . ']" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
358
+ echo '</div>';
359
+ break;
360
+
361
+ case 'wcml_wc_booking_resource_block_cost':
362
+
363
+ $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
364
+
365
+ if ( isset( $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
366
+ $value = $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ];
367
+ } else {
368
+ $value = '';
369
+ }
370
+
371
+ echo '<div class="wcml_bookings_resource_block" >';
372
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
373
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_resource_block_cost[' . $resource_id . '][' . $currency_code . ']" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
374
+ echo '</div>';
375
+ break;
376
+
377
+ default:
378
+ break;
379
+
380
+ }
381
+
382
+ }
383
+
384
+ echo '</div>';
385
+
386
+ }
387
+ }
388
+
389
+ function after_bookings_pricing( $post_id ) {
390
+
391
+
392
+ if ( in_array( 'booking', wp_get_post_terms( $post_id, 'product_type', array( "fields" => "names" ) ) ) && $this->woocommerce_wpml->products->is_original_product( $post_id ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
393
+
394
+ $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
395
+
396
+ $checked = ! $custom_costs_status ? 'checked="checked"' : ' ';
397
+
398
+ echo '<div class="wcml_custom_costs">';
399
+
400
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" ' . $checked . ' />';
401
+ echo '<label for="wcml_custom_costs_auto">' . __( 'Calculate costs in other currencies automatically', 'woocommerce-multilingual' ) . '</label>';
402
+
403
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
404
+
405
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" ' . $checked . ' />';
406
+ echo '<label for="wcml_custom_costs_manually">' . __( 'Set costs in other currencies manually', 'woocommerce-multilingual' ) . '</label>';
407
+
408
+ wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
409
+
410
+ echo '</div>';
411
+ }
412
+
413
+ }
414
+
415
+ function save_custom_costs( $post_id ) {
416
+ $nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
417
+
418
+ if ( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
419
+
420
+ update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
421
+
422
+ if ( 1 === (int) $_POST['_wcml_custom_costs'] ) {
423
+
424
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
425
+ if ( empty( $currencies ) || 0 === $post_id ) {
426
+ return false;
427
+ }
428
+
429
+ $this->update_booking_costs( $currencies, $post_id );
430
+ $this->update_booking_pricing( $currencies, $post_id );
431
+
432
+
433
+ if ( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
434
+ $this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
435
+ }
436
+
437
+ if ( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
438
+ $this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
439
+ }
440
+
441
+ if ( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
442
+ $this->update_booking_resource_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_cost'] );
443
+ }
444
+
445
+ if ( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
446
+ $this->update_booking_resource_block_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_block_cost'] );
447
+ }
448
+
449
+ update_post_meta( $post_id, '_price', '' );
450
+ } else {
451
+ return false;
452
+ }
453
+ }
454
+
455
+ }
456
+
457
+ // sync existing product bookings for translations
458
+ function sync_bookings( $original_product_id, $product_id, $lang ) {
459
+ $all_bookings_for_product = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id as id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_product_id' AND meta_value = %d", $original_product_id ) );
460
+
461
+ foreach ( $all_bookings_for_product as $booking ) {
462
+ $check_if_exists = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT pm3.* FROM {$this->wpdb->postmeta} AS pm1
463
+ LEFT JOIN {$this->wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
464
+ LEFT JOIN {$this->wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
465
+ WHERE pm1.meta_key = '_booking_duplicate_of' AND pm1.meta_value = %s AND pm2.meta_key = '_language_code' AND pm2.meta_value = %s AND pm3.meta_key = '_booking_product_id'"
466
+ , $booking->id, $lang ) );
467
+
468
+ if ( is_null( $check_if_exists ) ) {
469
+ $this->duplicate_booking_for_translations( $booking->id, $lang );
470
+ } elseif ( '' === $check_if_exists->meta_value ) {
471
+ update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
472
+ update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
473
+ update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
474
+ }
475
+ }
476
+ }
477
+
478
+ function sync_booking_data( $original_product_id, $current_product_id ) {
479
+
480
+ if ( has_term( 'booking', 'product_type', $original_product_id ) ) {
481
+ global $pagenow, $iclTranslationManagement;
482
+
483
+ // get language code
484
+ $language_details = $this->sitepress->get_element_language_details( $original_product_id, 'post_product' );
485
+ if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
486
+ //translation editor support: sidestep icl_translations_cache
487
+ $language_details = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT element_id, trid, language_code, source_language_code FROM {$this->wpdb->prefix}icl_translations WHERE element_id = %d AND element_type = 'post_product'", $original_product_id ) );
488
+ }
489
+ if ( empty( $language_details ) ) {
490
+ return;
491
+ }
492
+
493
+ // pick posts to sync
494
+ $posts = array();
495
+ $translations = $this->sitepress->get_element_translations( $language_details->trid, 'post_product' );
496
+ foreach ( $translations as $translation ) {
497
+
498
+ if ( ! $translation->original ) {
499
+ $posts[ $translation->element_id ] = $translation;
500
+ }
501
+ }
502
+
503
+ foreach ( $posts as $post_id => $translation ) {
504
+
505
+ $trn_lang = $this->sitepress->get_language_for_element( $post_id, 'post_product' );
506
+
507
+ //sync_resources
508
+ $this->sync_resources( $original_product_id, $post_id, $trn_lang );
509
+
510
+ //sync_persons
511
+ $this->sync_persons( $original_product_id, $post_id, $trn_lang );
512
+ }
513
+
514
+ }
515
+
516
+ }
517
+
518
+ function sync_resources( $original_product_id, $translated_product_id, $lang_code, $duplicate = true ) {
519
+
520
+ $original_resources = $this->wpdb->get_results( $this->wpdb->prepare(
521
+ "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
522
+ $original_product_id ) );
523
+
524
+ $translated_resources = $this->wpdb->get_col( $this->wpdb->prepare(
525
+ "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
526
+ $translated_product_id ) );
527
+
528
+ $used_translated_resources = array();
529
+
530
+ foreach ( $original_resources as $resource ) {
531
+
532
+ $translated_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
533
+ if ( ! is_null( $translated_resource_id ) ) {
534
+
535
+ if ( in_array( $translated_resource_id, $translated_resources ) ) {
536
+ $this->update_product_resource( $translated_product_id, $translated_resource_id, $resource );
537
+ } else {
538
+ $this->add_product_resource( $translated_product_id, $translated_resource_id, $resource );
539
+ }
540
+ $used_translated_resources[] = $translated_resource_id;
541
+ } else {
542
+ if ( $duplicate ) {
543
+ $this->duplicate_resource( $translated_product_id, $resource, $lang_code );
544
+ }
545
+ }
546
+
547
+ }
548
+
549
+ $removed_translated_resources_id = array_diff( $translated_resources, $used_translated_resources );
550
+ foreach ( $removed_translated_resources_id as $resource_id ) {
551
+ $this->remove_resource_from_product( $translated_product_id, $resource_id );
552
+ }
553
+
554
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_base_costs', $lang_code );
555
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_block_costs', $lang_code );
556
+
557
+ }
558
+
559
+ function duplicate_resource( $tr_product_id, $resource, $lang_code ) {
560
+ global $iclTranslationManagement;
561
+
562
+ if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
563
+
564
+ $trns_resource_id = $this->sitepress->make_duplicate( $resource->resource_id, $lang_code );
565
+
566
+ } else {
567
+
568
+ if ( ! isset( $iclTranslationManagement ) ) {
569
+ $iclTranslationManagement = new TranslationManagement;
570
+ }
571
+
572
+ $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
573
+
574
+ }
575
+
576
+ $this->wpdb->insert(
577
+ $this->wpdb->prefix . 'wc_booking_relationships',
578
+ array(
579
+ 'product_id' => $tr_product_id,
580
+ 'resource_id' => $trns_resource_id,
581
+ 'sort_order' => $resource->sort_order
582
+ )
583
+ );
584
+
585
+ delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
586
+
587
+ return $trns_resource_id;
588
+ }
589
+
590
+ public function add_product_resource( $product_id, $resource_id, $resource_data ) {
591
+
592
+ $this->wpdb->insert(
593
+ $this->wpdb->prefix . 'wc_booking_relationships',
594
+ array(
595
+ 'sort_order' => $resource_data->sort_order,
596
+ 'product_id' => $product_id,
597
+ 'resource_id' => $resource_id
598
+ )
599
+ );
600
+
601
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
602
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
603
+
604
+ }
605
+
606
+ public function remove_resource_from_product( $product_id, $resource_id ) {
607
+
608
+ $this->wpdb->delete(
609
+ $this->wpdb->prefix . 'wc_booking_relationships',
610
+ array(
611
+ 'product_id' => $product_id,
612
+ 'resource_id' => $resource_id
613
+ )
614
+ );
615
+
616
+ }
617
+
618
+ public function update_product_resource( $product_id, $resource_id, $resource_data ) {
619
+
620
+ $this->wpdb->update(
621
+ $this->wpdb->prefix . 'wc_booking_relationships',
622
+ array(
623
+ 'sort_order' => $resource_data->sort_order
624
+ ),
625
+ array(
626
+ 'product_id' => $product_id,
627
+ 'resource_id' => $resource_id
628
+ )
629
+ );
630
+
631
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
632
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
633
+
634
+
635
+ }
636
+
637
+ function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ) {
638
+ $orig_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $original_product_id ) );
639
+
640
+ $trnsl_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person'", $tr_product_id ) );
641
+
642
+
643
+ foreach ( $orig_persons as $person ) {
644
+
645
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
646
+
647
+ if ( ! is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
648
+
649
+ if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
650
+
651
+ unset( $trnsl_persons[ $key ] );
652
+
653
+ update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
654
+ update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
655
+ update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
656
+ update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
657
+
658
+
659
+ if ( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
660
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
661
+
662
+ foreach ( $currencies as $code => $currency ) {
663
+
664
+ update_post_meta( $trnsl_person_id, 'block_cost_' . $code, get_post_meta( $person, 'block_cost_' . $code, true ) );
665
+ update_post_meta( $trnsl_person_id, 'cost_' . $code, get_post_meta( $person, 'cost_' . $code, true ) );
666
+
667
+ }
668
+ }
669
+
670
+ }
671
+
672
+ } else {
673
+
674
+ if ( $duplicate ) {
675
+
676
+ $this->duplicate_person( $tr_product_id, $person, $lang_code );
677
+
678
+ } else {
679
+
680
+ continue;
681
+
682
+ }
683
+
684
+ }
685
+
686
+ }
687
+
688
+ foreach ( $trnsl_persons as $trnsl_person ) {
689
+
690
+ wp_delete_post( $trnsl_person );
691
+
692
+ }
693
+
694
+ }
695
+
696
+ function duplicate_person( $tr_product_id, $person_id, $lang_code ) {
697
+ global $iclTranslationManagement;
698
+
699
+ if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
700
+
701
+ $new_person_id = $this->sitepress->make_duplicate( $person_id, $lang_code );
702
+
703
+ } else {
704
+
705
+ if ( ! isset( $iclTranslationManagement ) ) {
706
+ $iclTranslationManagement = new TranslationManagement;
707
+ }
708
+
709
+ $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
710
+
711
+ }
712
+
713
+ $this->wpdb->update(
714
+ $this->wpdb->posts,
715
+ array(
716
+ 'post_parent' => $tr_product_id
717
+ ),
718
+ array(
719
+ 'ID' => $new_person_id
720
+ )
721
+ );
722
+
723
+ delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
724
+
725
+ return $new_person_id;
726
+ }
727
+
728
+ function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ) {
729
+
730
+ if ( in_array( $meta_key, array(
731
+ '_wc_booking_cost',
732
+ '_wc_booking_base_cost',
733
+ '_wc_display_cost',
734
+ '_wc_booking_pricing',
735
+ 'cost',
736
+ 'block_cost',
737
+ '_resource_base_costs',
738
+ '_resource_block_costs'
739
+ ) ) ) {
740
+
741
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
742
+
743
+ $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
744
+
745
+ $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
746
+
747
+ $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
748
+
749
+ if ( $currency == get_option( 'woocommerce_currency' ) ) {
750
+ return $check;
751
+ }
752
+
753
+ if ( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
754
+
755
+ if ( get_post_type( $object_id ) == 'bookable_person' ) {
756
+
757
+ $original_id = apply_filters( 'translate_object_id', wp_get_post_parent_id( $object_id ), 'product', true, $this->woocommerce_wpml->products->get_original_product_language( wp_get_post_parent_id( $object_id ) ) );
758
+ $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
759
+
760
+ $value = get_post_meta( $object_id, $meta_key . '_' . $currency, true );
761
+
762
+ if ( $cost_status && $value ) {
763
+
764
+ return $value;
765
+
766
+ } else {
767
+
768
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
769
+
770
+ $cost = get_post_meta( $object_id, $meta_key, true );
771
+
772
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
773
+
774
+ return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
775
+ }
776
+
777
+ } else {
778
+
779
+ return $check;
780
+
781
+ }
782
+
783
+ }
784
+
785
+ if ( in_array( $meta_key, array(
786
+ '_wc_booking_pricing',
787
+ '_resource_base_costs',
788
+ '_resource_block_costs'
789
+ ) ) ) {
790
+
791
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
792
+
793
+ if ( $meta_key == '_wc_booking_pricing' ) {
794
+
795
+ if ( $original_id != $object_id ) {
796
+ $value = get_post_meta( $original_id, $meta_key );
797
+ } else {
798
+ $value = $check;
799
+ }
800
+
801
+ } else {
802
+
803
+ $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
804
+
805
+ if ( ! $costs ) {
806
+ $value = $check;
807
+ } elseif ( $cost_status && isset( $costs['custom_costs'][ $currency ] ) ) {
808
+
809
+ $res_costs = array();
810
+ foreach ( $costs['custom_costs'][ $currency ] as $resource_id => $cost ) {
811
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $this->sitepress->get_current_language() );
812
+ $res_costs[ $trns_resource_id ] = $cost;
813
+ }
814
+ $value = array( 0 => $res_costs );
815
+ } elseif ( $cost_status && isset( $costs[0]['custom_costs'][ $currency ] ) ) {
816
+ $value = array( 0 => $costs[0]['custom_costs'][ $currency ] );
817
+ } else {
818
+
819
+ $converted_values = array();
820
+
821
+ foreach ( $costs as $resource_id => $cost ) {
822
+ $converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
823
+ }
824
+
825
+ $value = $converted_values;
826
+ }
827
+
828
+ }
829
+
830
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
831
+
832
+ return $value;
833
+
834
+ }
835
+
836
+ $value = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
837
+
838
+ if ( $cost_status && ( ! empty( $value ) || ( empty( $value ) && $meta_key == '_wc_display_cost' ) ) ) {
839
+
840
+ return $value;
841
+
842
+ } else {
843
+
844
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
845
+
846
+ $value = get_post_meta( $original_id, $meta_key, true );
847
+
848
+ $value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
849
+
850
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
851
+
852
+ return $value;
853
+
854
+ }
855
+
856
+ }
857
+
858
+ }
859
+
860
+ return $check;
861
+ }
862
+
863
+ function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ) {
864
+
865
+
866
+ $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
867
+
868
+ if ( $object_id == $original_product_id ) {
869
+
870
+ $trid = $this->sitepress->get_element_trid( $object_id, 'post_product' );
871
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
872
+
873
+ foreach ( $translations as $translation ) {
874
+
875
+ if ( ! $translation->original ) {
876
+
877
+ $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
878
+
879
+ }
880
+ }
881
+
882
+ return $check;
883
+
884
+ } else {
885
+
886
+ $language_code = $this->sitepress->get_language_for_element( $object_id, 'post_product' );
887
+
888
+ $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
889
+
890
+ return true;
891
+
892
+ }
893
+
894
+ }
895
+
896
+ function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ) {
897
+
898
+ $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
899
+
900
+ $wc_booking_resource_costs = array();
901
+ if ( ! empty( $original_costs ) ) {
902
+ foreach ( $original_costs as $resource_id => $costs ) {
903
+
904
+ if ( $resource_id == 'custom_costs' && isset( $costs['custom_costs'] ) ) {
905
+
906
+ foreach ( $costs['custom_costs'] as $code => $currencies ) {
907
+
908
+ foreach ( $currencies as $custom_costs_resource_id => $custom_cost ) {
909
+
910
+ $trns_resource_id = apply_filters( 'translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code );
911
+
912
+ $wc_booking_resource_costs['custom_costs'][ $code ][ $trns_resource_id ] = $custom_cost;
913
+
914
+ }
915
+
916
+ }
917
+
918
+ } else {
919
+
920
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $language_code );
921
+
922
+ $wc_booking_resource_costs[ $trns_resource_id ] = $costs;
923
+
924
+ }
925
+
926
+ }
927
+ }
928
+
929
+ update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
930
+
931
+ }
932
+
933
+ function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ) {
934
+ return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
935
+ }
936
+
937
+ function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ) {
938
+ return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
939
+ }
940
+
941
+ function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ) {
942
+ return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
943
+ }
944
+
945
+ function filter_pricing_cost( $cost, $fields, $name, $key ) {
946
+ global $product;
947
+
948
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
949
+
950
+ $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
951
+
952
+ if ( $currency == get_option( 'woocommerce_currency' ) ) {
953
+ return $cost;
954
+ }
955
+
956
+ if ( isset( $_POST['form'] ) ) {
957
+ parse_str( $_POST['form'], $posted );
958
+
959
+ $booking_id = $posted['add-to-cart'];
960
+
961
+ } elseif ( isset( $_POST['add-to-cart'] ) ) {
962
+
963
+ $booking_id = $_POST['add-to-cart'];
964
+
965
+ }
966
+
967
+ if ( isset( $booking_id ) ) {
968
+ $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $booking_id ) );
969
+
970
+ if ( $booking_id != $original_id ) {
971
+ $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
972
+ $fields = $fields[ $key ];
973
+ }
974
+ }
975
+
976
+ if ( isset( $fields[ $name . $currency ] ) ) {
977
+ return $fields[ $name . $currency ];
978
+ } else {
979
+ return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
980
+ }
981
+
982
+ }
983
+
984
+ return $cost;
985
+
986
+ }
987
+
988
+ function load_assets( $external_product_type = false ) {
989
+ global $pagenow;
990
+
991
+ $product = $pagenow == 'post.php' && isset( $_GET['post'] ) ? wc_get_product( $_GET['post'] ) : false;
992
+
993
+ if ( ( $product && ( $product->product_type == 'booking' || $product->product_type == $external_product_type ) ) || $pagenow == 'post-new.php' ) {
994
+
995
+ wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
996
+ wp_enqueue_style( 'wcml-bookings-css' );
997
+
998
+ wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
999
+ wp_enqueue_script( 'wcml-bookings-js' );
1000
+
1001
+ }
1002
+
1003
+ }
1004
+
1005
+ function localize_lock_fields_js() {
1006
+ wp_localize_script( 'wcml-bookings-js', 'lock_settings', array( 'lock_fields' => 1 ) );
1007
+ }
1008
+
1009
+ function wcml_multi_currency_is_ajax( $actions ) {
1010
+
1011
+ $actions[] = 'wc_bookings_calculate_costs';
1012
+
1013
+ return $actions;
1014
+ }
1015
+
1016
+ function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ) {
1017
+
1018
+ if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['booking'] ) ) {
1019
+
1020
+
1021
+ $current_id = apply_filters( 'translate_object_id', $cart_item['data']->id, 'product', true, $current_language );
1022
+ $cart_product_id = $cart_item['data']->id;
1023
+
1024
+ if ( $current_id != $cart_product_id ) {
1025
+
1026
+ $cart_item['data'] = new WC_Product_Booking( $current_id );
1027
+
1028
+ }
1029
+
1030
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ) {
1031
+
1032
+ $booking_info = array(
1033
+ 'wc_bookings_field_start_date_year' => $cart_item['booking']['_year'],
1034
+ 'wc_bookings_field_start_date_month' => $cart_item['booking']['_month'],
1035
+ 'wc_bookings_field_start_date_day' => $cart_item['booking']['_day'],
1036
+ 'add-to-cart' => $current_id
1037
+ );
1038
+
1039
+ if ( isset( $cart_item['booking']['_persons'] ) ) {
1040
+ foreach ( $cart_item['booking']['_persons'] as $person_id => $value ) {
1041
+ $booking_info[ 'wc_bookings_field_persons_' . apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $current_language ) ] = $value;
1042
+ }
1043
+ }
1044
+
1045
+ if ( isset( $cart_item['booking']['_resource_id'] ) ) {
1046
+ $booking_info['wc_bookings_field_resource'] = apply_filters( 'translate_object_id', $cart_item['booking']['_resource_id'], 'bookable_resource', false, $current_language );
1047
+ }
1048
+
1049
+ if ( isset( $cart_item['booking']['_duration'] ) ) {
1050
+ $booking_info['wc_bookings_field_duration'] = $cart_item['booking']['_duration'];
1051
+ }
1052
+
1053
+ if ( isset( $cart_item['booking']['_time'] ) ) {
1054
+ $booking_info['wc_bookings_field_start_date_time'] = $cart_item['booking']['_time'];
1055
+ }
1056
+
1057
+ $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1058
+
1059
+ $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
1060
+ update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item['booking']['_qty'] ) );
1061
+ $cost = $booking_form->calculate_booking_cost( $booking_info );
1062
+ update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
1063
+
1064
+ if ( ! is_wp_error( $cost ) ) {
1065
+ $cart_item['data']->set_price( $cost );
1066
+ }
1067
+ }
1068
+
1069
+ }
1070
+
1071
+ return $cart_item;
1072
+
1073
+ }
1074
+
1075
+ function booking_currency_dropdown() {
1076
+
1077
+
1078
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1079
+ $current_booking_currency = $this->get_cookie_booking_currency();
1080
+
1081
+ $wc_currencies = get_woocommerce_currencies();
1082
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
1083
+ ?>
1084
+ <tr valign="top">
1085
+ <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
1086
+ <td>
1087
+ <select id="dropdown_booking_currency">
1088
+
1089
+ <?php foreach ( $currencies as $currency => $count ): ?>
1090
+
1091
+ <option
1092
+ value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo $wc_currencies[ $currency ]; ?></option>
1093
+
1094
+ <?php endforeach; ?>
1095
+
1096
+ </select>
1097
+ </td>
1098
+ </tr>
1099
+
1100
+ <?php
1101
+
1102
+ $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
1103
+
1104
+ wc_enqueue_js( "
1105
+
1106
+ jQuery(document).on('change', '#dropdown_booking_currency', function(){
1107
+ jQuery.ajax({
1108
+ url: ajaxurl,
1109
+ type: 'post',
1110
+ data: {
1111
+ action: 'wcml_booking_set_currency',
1112
+ currency: jQuery('#dropdown_booking_currency').val(),
1113
+ wcml_nonce: '" . $wcml_booking_set_currency_nonce . "'
1114
+ },
1115
+ success: function( response ){
1116
+ if(typeof response.error !== 'undefined'){
1117
+ alert(response.error);
1118
+ }else{
1119
+ window.location = window.location.href;
1120
+ }
1121
+ }
1122
+ })
1123
+ });
1124
+ " );
1125
+
1126
+ }
1127
+
1128
+ }
1129
+
1130
+ function set_booking_currency_ajax() {
1131
+
1132
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1133
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'booking_set_currency' ) ) {
1134
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
1135
+ die();
1136
+ }
1137
+
1138
+ $this->set_booking_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
1139
+
1140
+ die();
1141
+ }
1142
+
1143
+ function set_booking_currency( $currency_code = false ) {
1144
+
1145
+ if ( ! isset( $_COOKIE ['_wcml_booking_currency'] ) && ! headers_sent() ) {
1146
+
1147
+
1148
+ $currency_code = get_woocommerce_currency();
1149
+
1150
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1151
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
1152
+
1153
+ if ( ! isset( $order_currencies[ $currency_code ] ) ) {
1154
+ foreach ( $order_currencies as $currency_code => $count ) {
1155
+ $currency_code = $currency_code;
1156
+ break;
1157
+ }
1158
+ }
1159
+ }
1160
+ }
1161
+
1162
+ if ( $currency_code ) {
1163
+ setcookie( '_wcml_booking_currency', $currency_code, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
1164
+ }
1165
+
1166
+ }
1167
+
1168
+ function get_cookie_booking_currency() {
1169
+
1170
+ if ( isset( $_COOKIE ['_wcml_booking_currency'] ) ) {
1171
+ $currency = $_COOKIE['_wcml_booking_currency'];
1172
+ } else {
1173
+ $currency = get_woocommerce_currency();
1174
+ }
1175
+
1176
+ return $currency;
1177
+ }
1178
+
1179
+ function filter_booking_currency_symbol( $currency ) {
1180
+ global $pagenow;
1181
+
1182
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1183
+ if ( isset( $_COOKIE ['_wcml_booking_currency'] ) && $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) {
1184
+ $currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_booking_currency'] );
1185
+ }
1186
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1187
+
1188
+ return $currency;
1189
+ }
1190
+
1191
+ function create_booking_page_client_currency( $currency ) {
1192
+ global $pagenow;
1193
+
1194
+ if ( wpml_is_ajax() && isset( $_POST['form'] ) ) {
1195
+ parse_str( $_POST['form'], $posted );
1196
+ }
1197
+
1198
+ if ( ( $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) || ( isset( $posted['_wp_http_referer'] ) && strpos( $posted['_wp_http_referer'], 'page=create_booking' ) !== false ) ) {
1199
+ $currency = $this->get_cookie_booking_currency();
1200
+ }
1201
+
1202
+ return $currency;
1203
+ }
1204
+
1205
+ function set_order_currency_on_create_booking_page( $order_id ) {
1206
+ update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1207
+
1208
+ update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
1209
+
1210
+ }
1211
+
1212
+ function filter_get_booking_products_args( $args ) {
1213
+ if ( isset( $args['suppress_filters'] ) ) {
1214
+ $args['suppress_filters'] = false;
1215
+ }
1216
+
1217
+ return $args;
1218
+ }
1219
+
1220
+ function custom_box_html( $obj, $product_id, $data ) {
1221
+ if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1222
+ return;
1223
+ }
1224
+
1225
+ $bookings_section = new WPML_Editor_UI_Field_Section( __( 'Bookings', 'woocommerce-multilingual' ) );
1226
+
1227
+ if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1228
+ $group = new WPML_Editor_UI_Field_Group( '', true );
1229
+ $booking_field = new WPML_Editor_UI_Single_Line_Field( '_wc_booking_resouce_label', __( 'Resources Label', 'woocommerce-multilingual' ), $data, true );
1230
+ $group->add_field( $booking_field );
1231
+ $bookings_section->add_field( $group );
1232
+ }
1233
+
1234
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1235
+
1236
+ if ( $orig_resources ) {
1237
+ $group = new WPML_Editor_UI_Field_Group( __( 'Resources', 'woocommerce-multilingual' ) );
1238
+ $group_title = __( 'Resources', 'woocommerce-multilingual' );
1239
+ foreach ( $orig_resources as $resource_id => $cost ) {
1240
+
1241
+ if ( $resource_id == 'custom_costs' ) {
1242
+ continue;
1243
+ }
1244
+
1245
+ $group = new WPML_Editor_UI_Field_Group( $group_title );
1246
+ $group_title = '';
1247
+
1248
+ $resource_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-resource_' . $resource_id . '_title', __( 'Title', 'woocommerce-multilingual' ), $data, true );
1249
+ $group->add_field( $resource_field );
1250
+ $bookings_section->add_field( $group );
1251
+ }
1252
+
1253
+ }
1254
+
1255
+ $original_persons = $this->get_original_persons( $product_id );
1256
+ end( $original_persons );
1257
+ $last_key = key( $original_persons );
1258
+ $divider = true;
1259
+ $group_title = __( 'Person Types', 'woocommerce-multilingual' );
1260
+ foreach ( $original_persons as $person_id ) {
1261
+ if ( $person_id == $last_key ) {
1262
+ $divider = false;
1263
+ }
1264
+ $group = new WPML_Editor_UI_Field_Group( $group_title, $divider );
1265
+ $group_title = '';
1266
+
1267
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_title', __( 'Person Type Name', 'woocommerce-multilingual' ), $data, false );
1268
+ $group->add_field( $person_field );
1269
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
1270
+ $group->add_field( $person_field );
1271
+ $bookings_section->add_field( $group );
1272
+
1273
+ }
1274
+
1275
+ if ( $orig_resources || $original_persons ) {
1276
+ $obj->add_field( $bookings_section );
1277
+ }
1278
+
1279
+ }
1280
+
1281
+
1282
+ function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1283
+
1284
+ if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1285
+ return $data;
1286
+ }
1287
+
1288
+ if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1289
+
1290
+ $data['_wc_booking_resouce_label'] = array( 'original' => get_post_meta( $product_id, '_wc_booking_resouce_label', true ) );
1291
+ $data['_wc_booking_resouce_label']['translation'] = $translation ? get_post_meta( $translation->ID, '_wc_booking_resouce_label', true ) : '';
1292
+ }
1293
+
1294
+ $orig_resources = $this->get_original_resources( $product_id );
1295
+
1296
+ if ( $orig_resources && is_array( $orig_resources ) ) {
1297
+
1298
+ foreach ( $orig_resources as $resource_id => $cost ) {
1299
+
1300
+ if ( 'custom_costs' === $resource_id ) {
1301
+ continue;
1302
+ }
1303
+ $data[ 'bookings-resource_' . $resource_id . '_title' ] = array( 'original' => get_the_title( $resource_id ) );
1304
+ global $sitepress;
1305
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $lang );
1306
+ $data[ 'bookings-resource_' . $resource_id . '_title' ]['translation'] = $trns_resource_id ? get_the_title( $trns_resource_id ) : '';
1307
+ }
1308
+ }
1309
+
1310
+ $original_persons = $this->get_original_persons( $product_id );
1311
+
1312
+ foreach ( $original_persons as $person_id ) {
1313
+
1314
+ $data[ 'bookings-person_' . $person_id . '_title' ] = array( 'original' => get_the_title( $person_id ) );
1315
+ $data[ 'bookings-person_' . $person_id . '_description' ] = array( 'original' => get_post( $person_id )->post_excerpt );
1316
+
1317
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $lang );
1318
+ $data[ 'bookings-person_' . $person_id . '_title' ]['translation'] = $trnsl_person_id ? get_the_title( $trnsl_person_id ) : '';
1319
+ $data[ 'bookings-person_' . $person_id . '_description' ]['translation'] = $trnsl_person_id ? get_post( $trnsl_person_id )->post_excerpt : '';
1320
+
1321
+ }
1322
+
1323
+ return $data;
1324
+ }
1325
+
1326
+
1327
+ function get_original_resources( $product_id ) {
1328
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1329
+
1330
+ return $orig_resources;
1331
+ }
1332
+
1333
+ function get_original_persons( $product_id ) {
1334
+ $original_persons = $this->wpdb->get_col( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->posts} WHERE post_parent = %d AND post_type = 'bookable_person' AND post_status = 'publish'", $product_id ) );
1335
+
1336
+ return $original_persons;
1337
+ }
1338
+
1339
+ function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ) {
1340
+ if ( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ) {
1341
+ return false;
1342
+ }
1343
+
1344
+ return $check;
1345
+ }
1346
+
1347
+ function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ) {
1348
+ if ( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ) {
1349
+ $exception = true;
1350
+ }
1351
+
1352
+ return $exception;
1353
+ }
1354
+
1355
+ function remove_single_custom_fields_to_translate( $fields ) {
1356
+ $fields[] = '_wc_booking_resouce_label';
1357
+
1358
+ return $fields;
1359
+ }
1360
+
1361
+ function product_content_resource_label( $meta_key, $product_id ) {
1362
+ if ( $meta_key == '_wc_booking_resouce_label' ) {
1363
+ return __( 'Resources label', 'woocommerce-multilingual' );
1364
+ }
1365
+
1366
+ return $meta_key;
1367
+ }
1368
+
1369
+ function wcml_products_tab_sync_resources_and_persons( $original_product_id, $tr_product_id, $data, $language ) {
1370
+ global $wpml_post_translations;
1371
+
1372
+ remove_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1373
+
1374
+ $orig_resources = $orig_resources = $this->get_original_resources( $original_product_id );;
1375
+
1376
+ if ( $orig_resources ) {
1377
+
1378
+ foreach ( $orig_resources as $orig_resource_id => $cost ) {
1379
+
1380
+ $resource_id = apply_filters( 'translate_object_id', $orig_resource_id, 'bookable_resource', false, $language );
1381
+ $orig_resource = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $orig_resource_id, $original_product_id ), OBJECT );
1382
+
1383
+ if ( is_null( $resource_id ) ) {
1384
+
1385
+ if ( $orig_resource ) {
1386
+ $resource_id = $this->duplicate_resource( $tr_product_id, $orig_resource, $language );
1387
+ } else {
1388
+ continue;
1389
+ }
1390
+
1391
+ } else {
1392
+ //update_relationship
1393
+
1394
+ $exist = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT ID FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id = %d AND product_id = %d", $resource_id, $tr_product_id ) );
1395
+
1396
+ if ( ! $exist ) {
1397
+
1398
+ $this->wpdb->insert(
1399
+ $this->wpdb->prefix . 'wc_booking_relationships',
1400
+ array(
1401
+ 'product_id' => $tr_product_id,
1402
+ 'resource_id' => $resource_id,
1403
+ 'sort_order' => $orig_resource->sort_order
1404
+ )
1405
+ );
1406
+
1407
+ }
1408
+
1409
+ }
1410
+
1411
+
1412
+ $this->wpdb->update(
1413
+ $this->wpdb->posts,
1414
+ array(
1415
+ 'post_title' => $data[ md5( 'bookings-resource_' . $orig_resource_id . '_title' ) ]
1416
+ ),
1417
+ array(
1418
+ 'ID' => $resource_id
1419
+ )
1420
+ );
1421
+
1422
+ update_post_meta( $resource_id, 'wcml_is_translated', true );
1423
+
1424
+ }
1425
+
1426
+ //sync resources data
1427
+ $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1428
+
1429
+ }
1430
+
1431
+ $original_persons = $this->get_original_persons( $original_product_id );
1432
+
1433
+ //sync persons
1434
+ if ( $original_persons ) {
1435
+
1436
+ foreach ( $original_persons as $original_person_id ) {
1437
+
1438
+ $person_id = apply_filters( 'translate_object_id', $original_person_id, 'bookable_person', false, $language );
1439
+
1440
+ if ( is_null( $person_id ) ) {
1441
+
1442
+ $person_id = $this->duplicate_person( $tr_product_id, $original_person_id, $language );
1443
+
1444
+ } else {
1445
+
1446
+ $this->wpdb->update(
1447
+ $this->wpdb->posts,
1448
+ array(
1449
+ 'post_parent' => $tr_product_id
1450
+ ),
1451
+ array(
1452
+ 'ID' => $person_id
1453
+ )
1454
+ );
1455
+
1456
+ }
1457
+
1458
+ $this->wpdb->update(
1459
+ $this->wpdb->posts,
1460
+ array(
1461
+ 'post_title' => $data[ md5( 'bookings-person_' . $original_person_id . '_title' ) ],
1462
+ 'post_excerpt' => $data[ md5( 'bookings-person_' . $original_person_id . '_description' ) ],
1463
+ ),
1464
+ array(
1465
+ 'ID' => $person_id
1466
+ )
1467
+ );
1468
+
1469
+ update_post_meta( $person_id, 'wcml_is_translated', true );
1470
+
1471
+ }
1472
+
1473
+ //sync persons data
1474
+ $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1475
+
1476
+ }
1477
+
1478
+ add_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1479
+
1480
+ }
1481
+
1482
+ function duplicate_booking_for_translations( $booking_id, $lang = false ) {
1483
+ $booking_object = get_post( $booking_id );
1484
+
1485
+ $booking_data = array(
1486
+ 'post_type' => 'wc_booking',
1487
+ 'post_title' => $booking_object->post_title,
1488
+ 'post_status' => $booking_object->post_status,
1489
+ 'ping_status' => 'closed',
1490
+ 'post_parent' => $booking_object->post_parent,
1491
+ );
1492
+
1493
+ $active_languages = $this->sitepress->get_active_languages();
1494
+
1495
+ foreach ( $active_languages as $language ) {
1496
+
1497
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1498
+
1499
+ if ( ! $lang ) {
1500
+ $booking_language = $this->sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1501
+ if ( $booking_language->language_code == $language['code'] ) {
1502
+ continue;
1503
+ }
1504
+ } elseif ( $lang != $language['code'] ) {
1505
+ continue;
1506
+ }
1507
+
1508
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1509
+ $trnsl_booking_persons = array();
1510
+
1511
+ if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1512
+ foreach ( $booking_persons as $person_id => $person_count ) {
1513
+
1514
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1515
+
1516
+ if ( is_null( $trnsl_person_id ) ) {
1517
+ $trnsl_booking_persons[] = $person_count;
1518
+ } else {
1519
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1520
+ }
1521
+
1522
+ }
1523
+ }
1524
+
1525
+ $trnsl_booking_id = wp_insert_post( $booking_data );
1526
+ $trid = $this->sitepress->get_element_trid( $booking_id );
1527
+ $this->sitepress->set_element_language_details( $trnsl_booking_id, 'post_wc_booking', $trid, $language['code'] );
1528
+
1529
+ $meta_args = array(
1530
+ '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1531
+ '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1532
+ '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1533
+ '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1534
+ '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1535
+ '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1536
+ '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1537
+ '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1538
+ '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1539
+ '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1540
+ '_booking_duplicate_of' => $booking_id,
1541
+ '_language_code' => $language['code'],
1542
+ );
1543
+
1544
+ foreach ( $meta_args as $key => $value ) {
1545
+ update_post_meta( $trnsl_booking_id, $key, $value );
1546
+ }
1547
+
1548
+ WC_Cache_Helper::get_transient_version( 'bookings', true );
1549
+
1550
+ }
1551
+
1552
+
1553
+ }
1554
+
1555
+ function get_translated_booking_product_id( $booking_id, $language ) {
1556
+
1557
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1558
+ $trnsl_booking_product_id = '';
1559
+
1560
+ if ( $booking_product_id ) {
1561
+ $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1562
+ if ( is_null( $trnsl_booking_product_id ) ) {
1563
+ $trnsl_booking_product_id = '';
1564
+ }
1565
+ }
1566
+
1567
+ return $trnsl_booking_product_id;
1568
+
1569
+ }
1570
+
1571
+ function get_translated_booking_resource_id( $booking_id, $language ) {
1572
+
1573
+ $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1574
+ $trnsl_booking_resource_id = '';
1575
+
1576
+ if ( $booking_resource_id ) {
1577
+ $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1578
+
1579
+ if ( is_null( $trnsl_booking_resource_id ) ) {
1580
+ $trnsl_booking_resource_id = '';
1581
+ }
1582
+ }
1583
+
1584
+ return $trnsl_booking_resource_id;
1585
+ }
1586
+
1587
+ function get_translated_booking_persons_ids( $booking_id, $language ) {
1588
+
1589
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1590
+ $trnsl_booking_persons = array();
1591
+
1592
+ if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1593
+ foreach ( $booking_persons as $person_id => $person_count ) {
1594
+
1595
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1596
+
1597
+ if ( is_null( $trnsl_person_id ) ) {
1598
+ $trnsl_booking_persons[] = $person_count;
1599
+ } else {
1600
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1601
+ }
1602
+
1603
+ }
1604
+ }
1605
+
1606
+ return $trnsl_booking_persons;
1607
+
1608
+ }
1609
+
1610
+ function update_status_for_translations( $booking_id ) {
1611
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1612
+
1613
+ foreach ( $translated_bookings as $booking ) {
1614
+
1615
+ $status = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT post_status FROM {$this->wpdb->posts} WHERE ID = %d", $booking_id ) ); //get_post_status( $booking_id );
1616
+ $language = get_post_meta( $booking->post_id, '_language_code', true );
1617
+
1618
+ $this->wpdb->update(
1619
+ $this->wpdb->posts,
1620
+ array(
1621
+ 'post_status' => $status,
1622
+ 'post_parent' => wp_get_post_parent_id( $booking_id ),
1623
+ ),
1624
+ array(
1625
+ 'ID' => $booking->post_id
1626
+ )
1627
+ );
1628
+
1629
+ update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1630
+ update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1631
+ update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1632
+
1633
+ }
1634
+
1635
+ }
1636
+
1637
+ function get_translated_bookings( $booking_id ) {
1638
+ $translated_bookings = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key = '_booking_duplicate_of' AND meta_value = %d", $booking_id ) );
1639
+
1640
+ return $translated_bookings;
1641
+ }
1642
+
1643
+ public function booking_filters_query( $query ) {
1644
+ global $typenow;
1645
+
1646
+ if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1647
+
1648
+ $current_lang = $this->sitepress->get_current_language();
1649
+
1650
+ $product_ids = $this->wpdb->get_col( $this->wpdb->prepare(
1651
+ "SELECT element_id
1652
+ FROM {$this->wpdb->prefix}icl_translations
1653
+ WHERE language_code = %s AND element_type = 'post_product'", $current_lang ) );
1654
+
1655
+ $product_ids = array_diff( $product_ids, array( null ) );
1656
+
1657
+ if ( ( ! isset( $_GET['lang'] ) || ( isset( $_GET['lang'] ) && $_GET['lang'] != 'all' ) ) ) {
1658
+ $query->query_vars['meta_query'][] = array(
1659
+ 'relation' => 'OR',
1660
+ array(
1661
+ 'key' => '_language_code',
1662
+ 'value' => $current_lang,
1663
+ 'compare ' => '='
1664
+ ),
1665
+ array(
1666
+ 'key' => '_booking_product_id',
1667
+ 'value' => $product_ids,
1668
+ 'compare ' => 'IN'
1669
+ )
1670
+ );
1671
+ }
1672
+ }
1673
+
1674
+ return $query;
1675
+ }
1676
+
1677
+ function bookings_in_date_range_query( $booking_ids ) {
1678
+ foreach ( $booking_ids as $key => $booking_id ) {
1679
+
1680
+ $language_code = $this->sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ), 'post_product' );
1681
+ $current_language = $this->sitepress->get_current_language();
1682
+
1683
+ if ( $language_code != $current_language ) {
1684
+ unset( $booking_ids[ $key ] );
1685
+ }
1686
+
1687
+ }
1688
+
1689
+ return $booking_ids;
1690
+
1691
+ }
1692
+
1693
+ function clear_transient_fields() {
1694
+
1695
+ if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1696
+
1697
+ //delete transient fields
1698
+ $this->wpdb->query( "
1699
+ DELETE FROM {$this->wpdb->options}
1700
+ WHERE option_name LIKE '%book_dr_%'
1701
+ " );
1702
+
1703
+ }
1704
+
1705
+ }
1706
+
1707
+ function delete_bookings( $booking_id ) {
1708
+
1709
+ if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1710
+
1711
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1712
+
1713
+ remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1714
+
1715
+ foreach ( $translated_bookings as $booking ) {
1716
+ $this->wpdb->update(
1717
+ $this->wpdb->posts,
1718
+ array(
1719
+ 'post_parent' => 0
1720
+ ),
1721
+ array(
1722
+ 'ID' => $booking->post_id
1723
+ )
1724
+ );
1725
+
1726
+ wp_delete_post( $booking->post_id );
1727
+
1728
+ }
1729
+
1730
+ add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1731
+ }
1732
+
1733
+ }
1734
+
1735
+ function trash_bookings( $booking_id ) {
1736
+
1737
+ if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1738
+
1739
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1740
+
1741
+ foreach ( $translated_bookings as $booking ) {
1742
+
1743
+ $this->wpdb->update(
1744
+ $this->wpdb->posts,
1745
+ array(
1746
+ 'post_status' => 'trash'
1747
+ ),
1748
+ array(
1749
+ 'ID' => $booking->post_id
1750
+ )
1751
+ );
1752
+
1753
+ }
1754
+
1755
+ }
1756
+
1757
+ }
1758
+
1759
+ function append_persons_to_translation_package( $package, $post ) {
1760
+
1761
+ if ( $post->post_type == 'product' ) {
1762
+ $product = wc_get_product( $post->ID );
1763
+
1764
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1765
+ $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1766
+
1767
+ if ( $product_type == 'booking' ) {
1768
+
1769
+ $bookable_product = new WC_Product_Booking( $post->ID );
1770
+
1771
+ $person_types = $bookable_product->get_person_types();
1772
+
1773
+ foreach ( $person_types as $person_type ) {
1774
+
1775
+ $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':name' ] = array(
1776
+ 'translate' => 1,
1777
+ 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1778
+ 'format' => 'base64'
1779
+ );
1780
+
1781
+ $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':description' ] = array(
1782
+ 'translate' => 1,
1783
+ 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1784
+ 'format' => 'base64'
1785
+ );
1786
+
1787
+ }
1788
+
1789
+ }
1790
+
1791
+ }
1792
+
1793
+ return $package;
1794
+
1795
+ }
1796
+
1797
+ function save_person_translation( $post_id, $data, $job ) {
1798
+ $person_translations = array();
1799
+
1800
+ $product = wc_get_product( $post_id );
1801
+
1802
+ if ( $product && $product->product_type == 'booking' ) {
1803
+
1804
+
1805
+ foreach ( $data as $value ) {
1806
+
1807
+ if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1808
+
1809
+ $exp = explode( ':', $value['field_type'] );
1810
+
1811
+ $person_id = $exp[2];
1812
+ $field = $exp[3];
1813
+
1814
+ $person_translations[ $person_id ][ $field ] = $value['data'];
1815
+
1816
+ }
1817
+
1818
+ }
1819
+
1820
+ if ( $person_translations ) {
1821
+
1822
+ foreach ( $person_translations as $person_id => $pt ) {
1823
+
1824
+ $person_trid = $this->sitepress->get_element_trid( $person_id, 'post_bookable_person' );
1825
+
1826
+
1827
+ $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1828
+
1829
+ if ( empty( $person_id_translated ) ) {
1830
+
1831
+ $person_post = array(
1832
+
1833
+ 'post_type' => 'bookable_person',
1834
+ 'post_status' => 'publish',
1835
+ 'post_title' => $pt['name'],
1836
+ 'post_parent' => $post_id,
1837
+ 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1838
+
1839
+ );
1840
+
1841
+ $person_id_translated = wp_insert_post( $person_post );
1842
+
1843
+ $this->sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1844
+
1845
+ } else {
1846
+
1847
+ $person_post = array(
1848
+ 'ID' => $person_id_translated,
1849
+ 'post_title' => $pt['name'],
1850
+ 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1851
+ );
1852
+
1853
+ wp_update_post( $person_post );
1854
+
1855
+ }
1856
+
1857
+ }
1858
+
1859
+ }
1860
+
1861
+ }
1862
+
1863
+ }
1864
+
1865
+ function append_resources_to_translation_package( $package, $post ) {
1866
+
1867
+ if ( $post->post_type == 'product' ) {
1868
+ $product = wc_get_product( $post->ID );
1869
+
1870
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1871
+ $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1872
+
1873
+ if ( $product_type == 'booking' && $product->has_resources() ) {
1874
+
1875
+ $resources = $product->get_resources();
1876
+
1877
+ foreach ( $resources as $resource ) {
1878
+
1879
+ $package['contents'][ 'wc_bookings:resource:' . $resource->ID . ':name' ] = array(
1880
+ 'translate' => 1,
1881
+ 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1882
+ 'format' => 'base64'
1883
+ );
1884
+
1885
+ }
1886
+
1887
+ }
1888
+
1889
+ }
1890
+
1891
+ return $package;
1892
+
1893
+ }
1894
+
1895
+ function save_resource_translation( $post_id, $data, $job ) {
1896
+ $resource_translations = array();
1897
+
1898
+ $product = wc_get_product( $post_id );
1899
+
1900
+ if ( $product && $product->product_type == 'booking' ) {
1901
+
1902
+ foreach ( $data as $value ) {
1903
+
1904
+ if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1905
+
1906
+ $exp = explode( ':', $value['field_type'] );
1907
+
1908
+ $resource_id = $exp[2];
1909
+ $field = $exp[3];
1910
+
1911
+ $resource_translations[ $resource_id ][ $field ] = $value['data'];
1912
+
1913
+ }
1914
+
1915
+ }
1916
+
1917
+ if ( $resource_translations ) {
1918
+
1919
+ foreach ( $resource_translations as $resource_id => $rt ) {
1920
+
1921
+ $resource_trid = $this->sitepress->get_element_trid( $resource_id, 'post_bookable_resource' );
1922
+
1923
+ $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1924
+
1925
+ if ( empty( $resource_id_translated ) ) {
1926
+
1927
+ $resource_post = array(
1928
+
1929
+ 'post_type' => 'bookable_resource',
1930
+ 'post_status' => 'publish',
1931
+ 'post_title' => $rt['name'],
1932
+ 'post_parent' => $post_id
1933
+ );
1934
+
1935
+ $resource_id_translated = wp_insert_post( $resource_post );
1936
+
1937
+ $this->sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
1938
+
1939
+ $sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1940
+ $relationship = array(
1941
+ 'product_id' => $post_id,
1942
+ 'resource_id' => $resource_id_translated,
1943
+ 'sort_order' => $sort_order
1944
+ );
1945
+ $this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship );
1946
+
1947
+ } else {
1948
+
1949
+ $resource_post = array(
1950
+ 'ID' => $resource_id_translated,
1951
+ 'post_title' => $rt['name']
1952
+ );
1953
+
1954
+ wp_update_post( $resource_post );
1955
+
1956
+ $sort_order = $this->wpdb->get_var( $this->wpdb->prepare( "SELECT sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1957
+ $this->wpdb->update( $this->wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1958
+ array( 'product_id' => $post_id, 'resource_id' => $resource_id_translated ) );
1959
+
1960
+
1961
+ }
1962
+
1963
+
1964
+ }
1965
+
1966
+ }
1967
+
1968
+ }
1969
+
1970
+ }
1971
+
1972
+ function wcml_js_lock_fields_ids( $ids ) {
1973
+
1974
+ $ids = array_merge( $ids, array(
1975
+ '_wc_booking_has_resources',
1976
+ '_wc_booking_has_persons',
1977
+ '_wc_booking_duration_type',
1978
+ '_wc_booking_duration',
1979
+ '_wc_booking_duration_unit',
1980
+ '_wc_booking_calendar_display_mode',
1981
+ '_wc_booking_requires_confirmation',
1982
+ '_wc_booking_user_can_cancel',
1983
+ '_wc_accommodation_booking_min_duration',
1984
+ '_wc_accommodation_booking_max_duration',
1985
+ '_wc_accommodation_booking_max_duration',
1986
+ '_wc_accommodation_booking_calendar_display_mode',
1987
+ '_wc_accommodation_booking_requires_confirmation',
1988
+ '_wc_accommodation_booking_user_can_cancel',
1989
+ '_wc_accommodation_booking_cancel_limit',
1990
+ '_wc_accommodation_booking_cancel_limit_unit',
1991
+ '_wc_accommodation_booking_qty',
1992
+ '_wc_accommodation_booking_min_date',
1993
+ '_wc_accommodation_booking_min_date_unit',
1994
+ '_wc_accommodation_booking_max_date',
1995
+ '_wc_accommodation_booking_max_date_unit',
1996
+ 'bookings_pricing select',
1997
+ 'bookings_resources select',
1998
+ 'bookings_availability select',
1999
+ 'bookings_persons input[type="checkbox"]'
2000
+ ) );
2001
+
2002
+ return $ids;
2003
+ }
2004
+
2005
+ /**
2006
+ * @param array $args
2007
+ *
2008
+ * @return array
2009
+ */
2010
+ public function filter_get_booking_resources_args( $args ) {
2011
+
2012
+ $screen = get_current_screen();
2013
+ if ( $screen->id == 'product' ) {
2014
+ $args['suppress_filters'] = false;
2015
+ }
2016
+
2017
+ return $args;
2018
+
2019
+ }
2020
+
2021
+ /**
2022
+ * @param array $currencies
2023
+ * @param int $post_id
2024
+ *
2025
+ * @return bool
2026
+ */
2027
+ private function update_booking_costs( $currencies = array(), $post_id = 0 ) {
2028
+ $booking_options = array(
2029
+ 'wcml_wc_booking_cost' => '_wc_booking_cost_',
2030
+ 'wcml_wc_booking_base_cost' => '_wc_booking_base_cost_',
2031
+ 'wcml_wc_display_cost' => '_wc_display_cost_',
2032
+ );
2033
+
2034
+ foreach ( $currencies as $code => $currency ) {
2035
+ foreach ( $booking_options as $booking_options_post_key => $booking_options_meta_key_prefix ) {
2036
+ if ( isset( $_POST[ $booking_options_post_key ][ $code ] ) ) {
2037
+ update_post_meta( $post_id, $booking_options_meta_key_prefix . $code, sanitize_text_field( $_POST[ $booking_options_post_key ][ $code ] ) );
2038
+ }
2039
+ }
2040
+ }
2041
+
2042
+ return true;
2043
+ }
2044
+
2045
+ /**
2046
+ * @param array $currencies
2047
+ * @param int $post_id
2048
+ *
2049
+ * @return bool
2050
+ */
2051
+ private function update_booking_pricing( $currencies = array(), $post_id = 0 ) {
2052
+ $updated_meta = array();
2053
+ $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
2054
+ if ( empty( $booking_pricing ) ) {
2055
+ return false;
2056
+ }
2057
+
2058
+ foreach ( $booking_pricing as $key => $prices ) {
2059
+ $updated_meta[ $key ] = $prices;
2060
+ foreach ( $currencies as $code => $currency ) {
2061
+ if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
2062
+ $updated_meta[ $key ][ 'base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
2063
+ }
2064
+ if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
2065
+ $updated_meta[ $key ][ 'cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
2066
+ }
2067
+ }
2068
+
2069
+ }
2070
+
2071
+ update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
2072
+
2073
+ return true;
2074
+ }
2075
+
2076
+ /**
2077
+ * @param array $currencies
2078
+ * @param array $person_costs
2079
+ *
2080
+ * @return bool
2081
+ */
2082
+ private function update_booking_person_cost( $currencies = array(), $person_costs = array() ) {
2083
+ if ( empty( $person_costs ) ) {
2084
+ return false;
2085
+ }
2086
+
2087
+ foreach ( $person_costs as $person_id => $costs ) {
2088
+ foreach ( $currencies as $code => $currency ) {
2089
+ if ( isset( $costs[ $code ] ) ) {
2090
+ update_post_meta( $person_id, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2091
+ }
2092
+ }
2093
+ }
2094
+
2095
+ return true;
2096
+ }
2097
+
2098
+ /**
2099
+ * @param array $currencies
2100
+ * @param array $block_costs
2101
+ *
2102
+ * @return bool
2103
+ */
2104
+ private function update_booking_person_block_cost( $currencies = array(), $block_costs = array() ) {
2105
+ if ( empty( $block_costs ) ) {
2106
+ return false;
2107
+ }
2108
+
2109
+ foreach ( $block_costs as $person_id => $costs ) {
2110
+ foreach ( $currencies as $code => $currency ) {
2111
+ if ( isset( $costs[ $code ] ) ) {
2112
+ update_post_meta( $person_id, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2113
+ }
2114
+ }
2115
+ }
2116
+
2117
+ return true;
2118
+ }
2119
+
2120
+ /**
2121
+ * @param array $currencies
2122
+ * @param int $post_id
2123
+ * @param array $resource_cost
2124
+ *
2125
+ * @return bool
2126
+ */
2127
+ private function update_booking_resource_cost( $currencies = array(), $post_id = 0, $resource_cost = array() ) {
2128
+ if ( empty( $resource_cost ) ) {
2129
+ return false;
2130
+ }
2131
+
2132
+ $updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
2133
+ if ( ! is_array( $updated_meta ) ) {
2134
+ $updated_meta = array();
2135
+ }
2136
+
2137
+ $wc_booking_resource_costs = array();
2138
+
2139
+ foreach ( $resource_cost as $resource_id => $costs ) {
2140
+
2141
+ foreach ( $currencies as $code => $currency ) {
2142
+
2143
+ if ( isset( $costs[ $code ] ) ) {
2144
+ $wc_booking_resource_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2145
+ }
2146
+
2147
+ }
2148
+
2149
+ }
2150
+
2151
+ $updated_meta['custom_costs'] = $wc_booking_resource_costs;
2152
+
2153
+ update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
2154
+
2155
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
2156
+
2157
+ return true;
2158
+ }
2159
+
2160
+ /**
2161
+ * @param array $currencies
2162
+ * @param int $post_id
2163
+ *
2164
+ * @return bool
2165
+ */
2166
+ private function update_booking_resource_block_cost( $currencies = array(), $post_id = 0, $resource_block_cost = array() ) {
2167
+ if ( empty( $resource_block_cost ) ) {
2168
+ return false;
2169
+ }
2170
+
2171
+ $updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
2172
+
2173
+ $wc_booking_resource_block_costs = array();
2174
+
2175
+ foreach ( $resource_block_cost as $resource_id => $costs ) {
2176
+
2177
+ foreach ( $currencies as $code => $currency ) {
2178
+
2179
+ if ( isset( $costs[ $code ] ) ) {
2180
+ $wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2181
+ }
2182
+
2183
+ }
2184
+
2185
+ }
2186
+
2187
+ $updated_meta['custom_costs'] = $wc_booking_resource_block_costs;
2188
+
2189
+ update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
2190
+
2191
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
2192
+
2193
+ return true;
2194
+ }
2195
+
2196
+ public function maybe_fix_double_serialized_wc_booking_availability( $mid, $object_id, $meta_key, $_meta_value ) {
2197
+ global $wpdb;
2198
+
2199
+ if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
2200
+
2201
+ $meta_keys_to_fix = array(
2202
+ '_wc_booking_availability',
2203
+ '_wc_booking_pricing'
2204
+ );
2205
+
2206
+ if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
2207
+
2208
+ if ( is_string( $_meta_value ) ) {
2209
+ $wpdb->update( $wpdb->postmeta, array( 'meta_value' => $_meta_value ), array( 'meta_id' => $mid ) );
2210
+ }
2211
+
2212
+ }
2213
+
2214
+ }
2215
+
2216
+ }
2217
+
2218
  }
compatibility/class-wcml-bulk-stock-management.php CHANGED
@@ -1,45 +1,45 @@
1
- <?php
2
- /**
3
- * Compatibility class for plugin WooCommerce Bulk Stock Management
4
- * http://www.woothemes.com/products/bulk-stock-management/
5
- *
6
- * @author konrad
7
- */
8
- class WCML_Bulk_Stock_Management {
9
- function __construct() {
10
- if (is_admin() && isset($_GET['page']) && $_GET['page'] == 'woocommerce-bulk-stock-management') {
11
- global $sitepress;
12
- remove_action('admin_enqueue_scripts', array($sitepress, 'language_filter'));
13
- }
14
-
15
- add_action( 'wc_bulk_stock_after_process_qty', array($this, 'wc_bulk_stock_after_process_qty_action'), 10, 1 );
16
- }
17
-
18
- function wc_bulk_stock_after_process_qty_action($id) {
19
- global $sitepress;
20
-
21
- $new_quantity = get_post_meta($id, '_stock', true);
22
-
23
- if (is_numeric($new_quantity)) {
24
-
25
- $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock";
26
- wc_update_product_stock_status($id, $new_stock_status);
27
-
28
- $trid = $sitepress->get_element_trid( $id, 'post_product' );
29
- if (is_numeric($trid)) {
30
- $translations = $sitepress->get_element_translations( $trid, 'post_product' );
31
-
32
- if (is_array($translations)) {
33
- foreach ($translations as $translation) {
34
- if ( !isset($translation->element_id) || $translation->element_id == $id) {
35
- continue;
36
- }
37
- update_post_meta($translation->element_id, '_stock', $new_quantity);
38
- wc_update_product_stock_status($translation->element_id, $new_stock_status);
39
- }
40
- }
41
- }
42
- }
43
-
44
- }
45
- }
1
+ <?php
2
+ /**
3
+ * Compatibility class for plugin WooCommerce Bulk Stock Management
4
+ * http://www.woothemes.com/products/bulk-stock-management/
5
+ *
6
+ * @author konrad
7
+ */
8
+ class WCML_Bulk_Stock_Management {
9
+ function __construct() {
10
+ if (is_admin() && isset($_GET['page']) && $_GET['page'] == 'woocommerce-bulk-stock-management') {
11
+ global $sitepress;
12
+ remove_action('admin_enqueue_scripts', array($sitepress, 'language_filter'));
13
+ }
14
+
15
+ add_action( 'wc_bulk_stock_after_process_qty', array($this, 'wc_bulk_stock_after_process_qty_action'), 10, 1 );
16
+ }
17
+
18
+ function wc_bulk_stock_after_process_qty_action($id) {
19
+ global $sitepress;
20
+
21
+ $new_quantity = get_post_meta($id, '_stock', true);
22
+
23
+ if (is_numeric($new_quantity)) {
24
+
25
+ $new_stock_status = ($new_quantity > 0) ? "instock" : "outofstock";
26
+ wc_update_product_stock_status($id, $new_stock_status);
27
+
28
+ $trid = $sitepress->get_element_trid( $id, 'post_product' );
29
+ if (is_numeric($trid)) {
30
+ $translations = $sitepress->get_element_translations( $trid, 'post_product' );
31
+
32
+ if (is_array($translations)) {
33
+ foreach ($translations as $translation) {
34
+ if ( !isset($translation->element_id) || $translation->element_id == $id) {
35
+ continue;
36
+ }
37
+ update_post_meta($translation->element_id, '_stock', $new_quantity);
38
+ wc_update_product_stock_status($translation->element_id, $new_stock_status);
39
+ }
40
+ }
41
+ }
42
+ }
43
+
44
+ }
45
+ }
compatibility/class-wcml-checkout-addons.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
- /**
3
- * Description of wc_checkout_addons
4
- *
5
- * @author konrad
6
- */
7
- class WCML_Checkout_Addons {
8
- public function __construct() {
9
- add_filter( 'wc_checkout_add_ons_options', array( $this, 'wc_checkout_add_ons_options_wpml_multi_currency_support' ) );
10
- }
11
-
12
- public function wc_checkout_add_ons_options_wpml_multi_currency_support( $options ) {
13
-
14
- foreach ( $options as $i => $option ) {
15
- $options[ $i ]['cost'] = apply_filters( 'wcml_raw_price_amount', $options[ $i ]['cost'] );
16
- }
17
-
18
- return $options;
19
- }
20
- }
1
+ <?php
2
+ /**
3
+ * Description of wc_checkout_addons
4
+ *
5
+ * @author konrad
6
+ */
7
+ class WCML_Checkout_Addons {
8
+ public function __construct() {
9
+ add_filter( 'wc_checkout_add_ons_options', array( $this, 'wc_checkout_add_ons_options_wpml_multi_currency_support' ) );
10
+ }
11
+
12
+ public function wc_checkout_add_ons_options_wpml_multi_currency_support( $options ) {
13
+
14
+ foreach ( $options as $i => $option ) {
15
+ $options[ $i ]['cost'] = apply_filters( 'wcml_raw_price_amount', $options[ $i ]['cost'] );
16
+ }
17
+
18
+ return $options;
19
+ }
20
+ }
compatibility/class-wcml-checkout-field-editor.php CHANGED
@@ -1,125 +1,125 @@
1
- <?php
2
-
3
- class WCML_Checkout_Field_Editor {
4
-
5
- protected $package, $billing, $shipping, $additional;
6
-
7
- function __construct() {
8
- $this->package = (object) array(
9
- 'kind' => 'WooCommerce Add-On',
10
- 'kind_slug' => 'woocommerce-add-on',
11
- 'name' => 'checkout-field-editor',
12
- 'title' => 'WooCommerce Checkout Field Editor'
13
- );
14
- global $supress_field_modification;
15
- if ( !is_admin() && !$supress_field_modification ) {
16
- add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
17
- add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
18
- add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
19
- }
20
- add_filter( 'pre_update_option_wc_fields_billing', array($this, 'register_fields') );
21
- add_filter( 'pre_update_option_wc_fields_shipping', array($this, 'register_fields') );
22
- add_filter( 'pre_update_option_wc_fields_additional', array($this, 'register_fields') );
23
- }
24
-
25
- public function register_fields( $fields ) {
26
- foreach ( $fields as $string_name => $field ) {
27
- // Translate label
28
- if ( !empty( $field['label'] ) ) {
29
- do_action( 'wpml_register_string',
30
- $field['label'],
31
- "{$string_name}_label",
32
- $this->package,
33
- "{$string_name} Label",
34
- $this->package->kind
35
- );
36
- }
37
- // Translate placeholder
38
- if ( !empty( $field['placeholder'] ) ) {
39
- do_action( 'wpml_register_string',
40
- $field['placeholder'],
41
- "{$string_name}_placeholder",
42
- $this->package,
43
- "{$string_name} Placeholder",
44
- $this->package->kind
45
- );
46
- }
47
- // Translate options
48
- if ( !empty( $field['options'] ) ) {
49
- $i = 1;
50
- foreach ( $field['options'] as $option ) {
51
- do_action( 'wpml_register_string',
52
- $option,
53
- "{$string_name}_option_{$i}",
54
- $this->package,
55
- "{$string_name} Option {$i}",
56
- $this->package->kind
57
- );
58
- $i++;
59
- }
60
- }
61
- }
62
- return $fields;
63
- }
64
-
65
- public function translate_fields( $fields ) {
66
- foreach ( $fields as $string_name => &$field ) {
67
- // Translate label
68
- if ( !empty( $field['label'] ) ) {
69
- $field['label'] = apply_filters( 'wpml_translate_string',
70
- $field['label'],
71
- "{$string_name}_label",
72
- $this->package
73
- );
74
- }
75
- // Translate placeholder
76
- if ( !empty( $field['placeholder'] ) ) {
77
- $field['placeholder'] = apply_filters( 'wpml_translate_string',
78
- $field['label'],
79
- "{$string_name}_placeholder",
80
- $this->package
81
- );
82
- }
83
- // Translate options
84
- if ( !empty( $field['options'] ) ) {
85
- $i = 1;
86
- foreach ( $field['options'] as $k => $option ) {
87
- $field['options'][$k] = apply_filters( 'wpml_translate_string',
88
- $option,
89
- "{$string_name}_option_{$i}",
90
- $this->package
91
- );
92
- $i++;
93
- }
94
- }
95
- }
96
- return $fields;
97
- }
98
-
99
- public function get_billing() {
100
- if ( is_null( $this->billing ) ) {
101
- remove_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
102
- $this->billing = $this->translate_fields( get_option( 'wc_fields_billing', array() ) );
103
- add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
104
- }
105
- return $this->billing;
106
- }
107
-
108
- public function get_shipping() {
109
- if ( is_null( $this->shipping ) ) {
110
- remove_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
111
- $this->shipping = $this->translate_fields( get_option( 'wc_fields_shipping', array() ) );
112
- add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
113
- }
114
- return $this->shipping;
115
- }
116
-
117
- public function get_additional() {
118
- if ( is_null( $this->additional ) ) {
119
- remove_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
120
- $this->additional = $this->translate_fields( get_option( 'wc_fields_additional', array() ) );
121
- add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
122
- }
123
- return $this->additional;
124
- }
125
- }
1
+ <?php
2
+
3
+ class WCML_Checkout_Field_Editor {
4
+
5
+ protected $package, $billing, $shipping, $additional;
6
+
7
+ function __construct() {
8
+ $this->package = (object) array(
9
+ 'kind' => 'WooCommerce Add-On',
10
+ 'kind_slug' => 'woocommerce-add-on',
11
+ 'name' => 'checkout-field-editor',
12
+ 'title' => 'WooCommerce Checkout Field Editor'
13
+ );
14
+ global $supress_field_modification;
15
+ if ( !is_admin() && !$supress_field_modification ) {
16
+ add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
17
+ add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
18
+ add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
19
+ }
20
+ add_filter( 'pre_update_option_wc_fields_billing', array($this, 'register_fields') );
21
+ add_filter( 'pre_update_option_wc_fields_shipping', array($this, 'register_fields') );
22
+ add_filter( 'pre_update_option_wc_fields_additional', array($this, 'register_fields') );
23
+ }
24
+
25
+ public function register_fields( $fields ) {
26
+ foreach ( $fields as $string_name => $field ) {
27
+ // Translate label
28
+ if ( !empty( $field['label'] ) ) {
29
+ do_action( 'wpml_register_string',
30
+ $field['label'],
31
+ "{$string_name}_label",
32
+ $this->package,
33
+ "{$string_name} Label",
34
+ $this->package->kind
35
+ );
36
+ }
37
+ // Translate placeholder
38
+ if ( !empty( $field['placeholder'] ) ) {
39
+ do_action( 'wpml_register_string',
40
+ $field['placeholder'],
41
+ "{$string_name}_placeholder",
42
+ $this->package,
43
+ "{$string_name} Placeholder",
44
+ $this->package->kind
45
+ );
46
+ }
47
+ // Translate options
48
+ if ( !empty( $field['options'] ) ) {
49
+ $i = 1;
50
+ foreach ( $field['options'] as $option ) {
51
+ do_action( 'wpml_register_string',
52
+ $option,
53
+ "{$string_name}_option_{$i}",
54
+ $this->package,
55
+ "{$string_name} Option {$i}",
56
+ $this->package->kind
57
+ );
58
+ $i++;
59
+ }
60
+ }
61
+ }
62
+ return $fields;
63
+ }
64
+
65
+ public function translate_fields( $fields ) {
66
+ foreach ( $fields as $string_name => &$field ) {
67
+ // Translate label
68
+ if ( !empty( $field['label'] ) ) {
69
+ $field['label'] = apply_filters( 'wpml_translate_string',
70
+ $field['label'],
71
+ "{$string_name}_label",
72
+ $this->package
73
+ );
74
+ }
75
+ // Translate placeholder
76
+ if ( !empty( $field['placeholder'] ) ) {
77
+ $field['placeholder'] = apply_filters( 'wpml_translate_string',
78
+ $field['label'],
79
+ "{$string_name}_placeholder",
80
+ $this->package
81
+ );
82
+ }
83
+ // Translate options
84
+ if ( !empty( $field['options'] ) ) {
85
+ $i = 1;
86
+ foreach ( $field['options'] as $k => $option ) {
87
+ $field['options'][$k] = apply_filters( 'wpml_translate_string',
88
+ $option,
89
+ "{$string_name}_option_{$i}",
90
+ $this->package
91
+ );
92
+ $i++;
93
+ }
94
+ }
95
+ }
96
+ return $fields;
97
+ }
98
+
99
+ public function get_billing() {
100
+ if ( is_null( $this->billing ) ) {
101
+ remove_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
102
+ $this->billing = $this->translate_fields( get_option( 'wc_fields_billing', array() ) );
103
+ add_filter( 'pre_option_wc_fields_billing', array($this, 'get_billing') );
104
+ }
105
+ return $this->billing;
106
+ }
107
+
108
+ public function get_shipping() {
109
+ if ( is_null( $this->shipping ) ) {
110
+ remove_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
111
+ $this->shipping = $this->translate_fields( get_option( 'wc_fields_shipping', array() ) );
112
+ add_filter( 'pre_option_wc_fields_shipping', array($this, 'get_shipping') );
113
+ }
114
+ return $this->shipping;
115
+ }
116
+
117
+ public function get_additional() {
118
+ if ( is_null( $this->additional ) ) {
119
+ remove_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
120
+ $this->additional = $this->translate_fields( get_option( 'wc_fields_additional', array() ) );
121
+ add_filter( 'pre_option_wc_fields_additional', array($this, 'get_additional') );
122
+ }
123
+ return $this->additional;
124
+ }
125
+ }
compatibility/class-wcml-compatibility-helper.php CHANGED
@@ -1,19 +1,19 @@
1
- <?php
2
-
3
- class WCML_Compatibility_Helper{
4
-
5
- function get_product_type($product_id){
6
-
7
- if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
8
- $product_type = sanitize_title( current( $terms )->name );
9
- } else {
10
- $product_type = apply_filters( 'default_product_type', 'simple' );
11
- }
12
-
13
- return $product_type;
14
-
15
- }
16
-
17
- }
18
-
19
  ?>
1
+ <?php
2
+
3
+ class WCML_Compatibility_Helper{
4
+
5
+ function get_product_type($product_id){
6
+
7
+ if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
8
+ $product_type = sanitize_title( current( $terms )->name );
9
+ } else {
10
+ $product_type = apply_filters( 'default_product_type', 'simple' );
11
+ }
12
+
13
+ return $product_type;
14
+
15
+ }
16
+
17
+ }
18
+
19
  ?>
compatibility/class-wcml-composite-products.php CHANGED
@@ -1,479 +1,479 @@
1
- <?php
2
-
3
-
4
- class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
-
6
- /**
7
- * @var SitePress
8
- */
9
- public $sitepress;
10
-
11
- /**
12
- * @var woocommerce_wpml
13
- */
14
- public $woocommerce_wpml;
15
-
16
- private $tp;
17
-
18
- function __construct( &$sitepress, &$woocommerce_wpml ) {
19
- $this->sitepress = $sitepress;
20
- $this->woocommerce_wpml = $woocommerce_wpml;
21
-
22
- add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
23
- add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
24
- add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
25
- add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
26
-
27
- if( is_admin() ){
28
-
29
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
30
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
31
- add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 4 );
32
- add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
-
34
- $this->tp = new WPML_Element_Translation_Package();
35
-
36
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
37
- add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
38
- //lock fields on translations pages
39
- add_filter( 'wcml_js_lock_fields_input_names', array( $this, 'wcml_js_lock_fields_input_names' ) );
40
- add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
41
- add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
42
- add_action( 'init', array( $this, 'load_assets' ) );
43
- }
44
- }
45
-
46
- function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
47
-
48
- if( !empty( $selected_value ) )
49
- $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
50
-
51
-
52
- return $selected_value;
53
- }
54
-
55
- function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
56
-
57
- if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
58
-
59
- $buff = $new_cart_data[ $new_key ];
60
-
61
- unset( $new_cart_data[ $new_key ] );
62
-
63
- $new_cart_data[ $key ] = $buff;
64
- }
65
-
66
- return $new_cart_data;
67
- }
68
-
69
- function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
70
-
71
- $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
72
-
73
- return $args;
74
- }
75
-
76
- function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
77
-
78
- if( $this->get_product_type( $original_product_id ) == 'composite' ){
79
-
80
- $composite_data = $this->get_composite_data( $original_product_id );
81
-
82
- $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
83
- $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
84
-
85
- foreach ( $product_translations as $product_translation ) {
86
-
87
- if ( empty($product_translation->original) ) {
88
-
89
- $translated_composite_data = $this->get_composite_data( $product_translation->element_id );
90
-
91
- foreach ( $composite_data as $component_id => $component ) {
92
-
93
- if( isset( $translated_composite_data[$component_id]['title'] ) ){
94
- $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
95
- }
96
-
97
- if( isset( $translated_composite_data[$component_id]['description'] ) ){
98
- $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
99
- }
100
-
101
- if ( $component['query_type'] == 'product_ids' ) {
102
-
103
- foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
104
- $composite_data[$component_id]['assigned_ids'][$idx] =
105
- apply_filters( 'translate_object_id', $assigned_id, 'product', true, $product_translation->language_code );
106
- }
107
-
108
- } elseif( $component['query_type'] == 'category_ids' ){
109
-
110
- foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
111
- $composite_data[$component_id]['assigned_category_ids'][$idx] =
112
- apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $product_translation->language_code );
113
-
114
- }
115
-
116
- }
117
-
118
- }
119
-
120
- update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
121
-
122
- }
123
-
124
- }
125
- }
126
-
127
- }
128
-
129
- function custom_box_html( $obj, $product_id, $data ){
130
-
131
- if( $this->get_product_type( $product_id ) == 'composite' ){
132
-
133
- $composite_data = $this->get_composite_data( $product_id );
134
-
135
- $composite_section = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Components )', 'woocommerce-multilingual' ) );
136
- end( $composite_data );
137
- $last_key = key( $composite_data );
138
- $divider = true;
139
- foreach( $composite_data as $component_id => $component ) {
140
- if( $component_id == $last_key ){
141
- $divider = false;
142
- }
143
- $group = new WPML_Editor_UI_Field_Group( '', $divider );
144
- $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
145
- $group->add_field( $composite_field );
146
- $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
147
- $group->add_field( $composite_field );
148
- $composite_section->add_field( $group );
149
-
150
- }
151
-
152
- if( $composite_data ){
153
- $obj->add_field( $composite_section );
154
- }
155
-
156
- $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
157
- if( $composite_scenarios_meta ){
158
-
159
- $composite_scenarios = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Scenarios )', 'woocommerce-multilingual' ) );
160
- end( $composite_scenarios_meta );
161
- $last_key = key( $composite_scenarios_meta );
162
- $divider = true;
163
- foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ) {
164
- if( $scenario_key == $last_key ){
165
- $divider = false;
166
- }
167
- $group = new WPML_Editor_UI_Field_Group( '', $divider );
168
- $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
169
- $group->add_field( $composite_scenario_field );
170
- $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
171
- $group->add_field( $composite_scenario_field );
172
- $composite_scenarios->add_field( $group );
173
-
174
- }
175
-
176
- $obj->add_field( $composite_scenarios );
177
-
178
- }
179
-
180
- }
181
-
182
- }
183
-
184
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
185
-
186
- if( $this->get_product_type( $product_id ) == 'composite' ){
187
-
188
- $composite_data = $this->get_composite_data( $product_id );
189
-
190
- foreach( $composite_data as $component_id => $component ) {
191
-
192
- $data['composite_'.$component_id.'_title'] = array( 'original' =>
193
- isset( $composite_data[$component_id]['title'] ) ? $composite_data[$component_id]['title'] : '' );
194
-
195
- $data['composite_'.$component_id.'_description'] = array( 'original' =>
196
- isset( $composite_data[$component_id]['description'] ) ? $composite_data[$component_id]['description'] : '' );
197
-
198
- }
199
-
200
- $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
201
- if( $composite_scenarios_meta ){
202
- foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
203
- $data[ 'composite_scenario_'.$scenario_key.'_title' ] = array(
204
- 'original' => isset( $scenario_meta['title'] ) ? $scenario_meta['title'] : '',
205
- 'translation' => ''
206
- );
207
-
208
- $data[ 'composite_scenario_'.$scenario_key.'_description' ] = array(
209
- 'original' => isset( $scenario_meta['description'] ) ? $scenario_meta['description'] : '',
210
- 'translation' => ''
211
- );
212
- }
213
- }
214
-
215
- if( $translation ){
216
- $translated_composite_data = $this->get_composite_data( $translation->ID );
217
-
218
- foreach( $composite_data as $component_id => $component ){
219
-
220
- $data['composite_'.$component_id.'_title'][ 'translation' ] =
221
- isset( $translated_composite_data[$component_id]['title'] ) ? $translated_composite_data[$component_id]['title'] : '';
222
-
223
- $data['composite_'.$component_id.'_description'][ 'translation' ] =
224
- isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
225
-
226
- }
227
-
228
- $translated_composite_scenarios_meta = $this->get_composite_scenarios_meta( $translation->ID );
229
- if( $translated_composite_scenarios_meta ){
230
- foreach( $translated_composite_scenarios_meta as $scenario_key => $translated_scenario_meta ){
231
- $data[ 'composite_scenario_'.$scenario_key.'_title' ][ 'translation' ] =
232
- isset( $translated_scenario_meta['title'] ) ? $translated_scenario_meta['title'] : '';
233
-
234
- $data[ 'composite_scenario_'.$scenario_key.'_description' ][ 'translation' ] =
235
- isset( $translated_scenario_meta['description'] ) ? $translated_scenario_meta['description'] : '';
236
- }
237
- }
238
-
239
- }
240
-
241
- }
242
-
243
- return $data;
244
- }
245
-
246
- function components_update( $original_product_id, $product_id, $data, $language ){
247
-
248
- $composite_data = $this->get_composite_data( $original_product_id );
249
-
250
- foreach( $composite_data as $component_id => $component ) {
251
-
252
- if(!empty($data[ md5( 'composite_'.$component_id.'_title' ) ] ) ){
253
- $composite_data[$component_id]['title'] = $data[ md5( 'composite_'.$component_id.'_title' ) ];
254
- }
255
-
256
- if(!empty($data[ md5( 'composite_'.$component_id.'_description' ) ])) {
257
- $composite_data[$component_id]['description'] = $data[ md5( 'composite_'.$component_id.'_description' ) ];
258
- }
259
-
260
- //sync product ids
261
- if( $component[ 'query_type' ] == 'product_ids' ){
262
- foreach( $component[ 'assigned_ids' ] as $key => $assigned_id ){
263
- $assigned_id_current_language = apply_filters( 'translate_object_id', $assigned_id, get_post_type( $assigned_id ), false, $language );
264
- if( $assigned_id_current_language ){
265
- $composite_data[ $component_id ][ 'assigned_ids' ][ $key ] = $assigned_id_current_language;
266
- }
267
- }
268
- //sync default
269
- if( $component[ 'default_id' ] ){
270
- $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], get_post_type( $component[ 'default_id' ] ), false, $language );
271
- if( $trnsl_default_id ){
272
- $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
273
- }
274
- }
275
-
276
- }elseif( $component[ 'query_type' ] == 'category_ids' ){
277
- foreach( $component[ 'assigned_category_ids' ] as $key => $assigned_id ){
278
- $trsl_term_id = apply_filters( 'translate_object_id', $assigned_id, 'product_cat', false, $language );
279
- if( $trsl_term_id ){
280
- $composite_data[ $component_id ][ 'assigned_category_ids' ][ $key ] = $trsl_term_id;
281
- }
282
- }
283
- //sync default
284
- if( $component[ 'default_id' ] ){
285
- $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], 'product_cat', false, $language );
286
- if( $trnsl_default_id ){
287
- $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
288
- }
289
- }
290
- }
291
- }
292
-
293
- update_post_meta( $product_id, '_bto_data', $composite_data );
294
-
295
- $composite_scenarios_meta = $this->get_composite_scenarios_meta( $original_product_id );
296
- if( $composite_scenarios_meta ){
297
- foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
298
- if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ] ) ){
299
- $composite_scenarios_meta[ $scenario_key ][ 'title' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ];
300
- }
301
-
302
- if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ])) {
303
- $composite_scenarios_meta[ $scenario_key ][ 'description' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ];
304
- }
305
-
306
- //sync product ids
307
- foreach( $scenario_meta[ 'component_data' ] as $compon_id => $component_data ){
308
- if( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'product_ids' ){
309
- foreach( $component_data as $key => $assigned_prod_id ){
310
- $trnsl_assigned_prod_id = apply_filters( 'translate_object_id', $assigned_prod_id, get_post_type( $assigned_prod_id ), false, $language );
311
- if( $trnsl_assigned_prod_id ){
312
- $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trnsl_assigned_prod_id;
313
- }
314
- }
315
- }elseif( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'category_ids' ){
316
- foreach( $component_data as $key => $assigned_cat_id ){
317
- $trslt_assigned_cat_id = apply_filters( 'translate_object_id', $assigned_cat_id, 'product_cat', false, $language );
318
- if( $trslt_assigned_cat_id ){
319
- $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trslt_assigned_cat_id;
320
- }
321
- }
322
- }
323
- }
324
- }
325
- }
326
-
327
- update_post_meta( $product_id, '_bto_scenario_data', $composite_scenarios_meta );
328
-
329
- return array(
330
- 'components' => $composite_data,
331
- 'scenarios' => $composite_scenarios_meta,
332
- );
333
- }
334
-
335
- function append_composite_data_translation_package( $package, $post ){
336
-
337
- if( $post->post_type == 'product' ) {
338
-
339
- $composite_data = get_post_meta( $post->ID, '_bto_data', true );
340
-
341
- if( $composite_data ){
342
-
343
- $fields = array( 'title', 'description' );
344
-
345
- foreach( $composite_data as $component_id => $component ){
346
-
347
- foreach( $fields as $field ) {
348
- if ( !empty($component[$field]) ) {
349
-
350
- $package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
351
- 'translate' => 1,
352
- 'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
353
- 'format' => 'base64'
354
- );
355
-
356
- }
357
- }
358
-
359
- }
360
-
361
- }
362
-
363
- }
364
-
365
- return $package;
366
-
367
- }
368
-
369
- function save_composite_data_translation( $post_id, $data, $job ){
370
-
371
-
372
- $translated_composite_data = array();
373
- foreach( $data as $value){
374
-
375
- if( preg_match( '/wc_composite:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
376
-
377
- $component_id = $matches[1];
378
- $field = $matches[2];
379
-
380
- $translated_composite_data[$component_id][$field] = $value['data'];
381
-
382
- }
383
-
384
- }
385
-
386
- if( $translated_composite_data ){
387
-
388
- $composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
389
-
390
-
391
- foreach ( $composite_data as $component_id => $component ) {
392
-
393
- if( isset( $translated_composite_data[$component_id]['title'] ) ){
394
- $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
395
- }
396
-
397
- if( isset( $translated_composite_data[$component_id]['description'] ) ){
398
- $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
399
- }
400
-
401
- if ( $component['query_type'] == 'product_ids' ) {
402
-
403
- foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
404
- $composite_data[$component_id]['assigned_ids'][$idx] =
405
- apply_filters( 'translate_object_id', $assigned_id, 'product', true, $job->language_code );
406
- }
407
-
408
- } elseif( $component['query_type'] == 'category_ids' ){
409
-
410
- foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
411
- $composite_data[$component_id]['assigned_category_ids'][$idx] =
412
- apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $job->language_code );
413
-
414
- }
415
-
416
- }
417
-
418
- }
419
-
420
- }
421
-
422
- update_post_meta( $post_id, '_bto_data', $composite_data );
423
-
424
- }
425
-
426
- function wcml_js_lock_fields_input_names( $names ){
427
-
428
- $names[] = '_base_regular_price';
429
- $names[] = '_base_sale_price';
430
- $names[] = 'bto_style';
431
-
432
- return $names;
433
- }
434
-
435
- function wcml_js_lock_fields_ids( $names ){
436
-
437
- $names[] = '_per_product_pricing_bto';
438
- $names[] = '_per_product_shipping_bto';
439
- $names[] = '_bto_hide_shop_price';
440
-
441
- return $names;
442
- }
443
-
444
- function localize_lock_fields_js(){
445
- wp_localize_script( 'wcml-composite-js', 'lock_settings' , array( 'lock_fields' => 1 ) );
446
- }
447
-
448
- function load_assets( ){
449
- global $pagenow;
450
-
451
- if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && wc_get_product( $_GET[ 'post' ] )->product_type == '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
-
455
- }
456
-
457
- }
458
-
459
- function woocommerce_json_search_found_products( $found_products ){
460
- global $wpml_post_translations;
461
-
462
- foreach( $found_products as $id => $product_name ){
463
- if( $wpml_post_translations->get_element_lang_code ( $id ) != $this->sitepress->get_current_language() ){
464
- unset( $found_products[ $id ] );
465
- }
466
- }
467
-
468
- return $found_products;
469
- }
470
-
471
- public function get_composite_scenarios_meta( $product_id ){
472
- return get_post_meta( $product_id, '_bto_scenario_data', true );
473
- }
474
-
475
- public function get_composite_data( $product_id ){
476
- return get_post_meta( $product_id, '_bto_data', true );
477
- }
478
-
479
- }
1
+ <?php
2
+
3
+
4
+ class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
+
6
+ /**
7
+ * @var SitePress
8
+ */
9
+ public $sitepress;
10
+
11
+ /**
12
+ * @var woocommerce_wpml
13
+ */
14
+ public $woocommerce_wpml;
15
+
16
+ private $tp;
17
+
18
+ function __construct( &$sitepress, &$woocommerce_wpml ) {
19
+ $this->sitepress = $sitepress;
20
+ $this->woocommerce_wpml = $woocommerce_wpml;
21
+
22
+ add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
23
+ add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
24
+ add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
25
+ add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
26
+
27
+ if( is_admin() ){
28
+
29
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
30
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
31
+ add_action( 'wcml_update_extra_fields', array( $this, 'components_update' ), 10, 4 );
32
+ add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
33
+
34
+ $this->tp = new WPML_Element_Translation_Package();
35
+
36
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
37
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
38
+ //lock fields on translations pages
39
+ add_filter( 'wcml_js_lock_fields_input_names', array( $this, 'wcml_js_lock_fields_input_names' ) );
40
+ add_filter( 'wcml_js_lock_fields_ids', array( $this, 'wcml_js_lock_fields_ids' ) );
41
+ add_filter( 'wcml_after_load_lock_fields_js', array( $this, 'localize_lock_fields_js' ) );
42
+ add_action( 'init', array( $this, 'load_assets' ) );
43
+ }
44
+ }
45
+
46
+ function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
47
+
48
+ if( !empty( $selected_value ) )
49
+ $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
50
+
51
+
52
+ return $selected_value;
53
+ }
54
+
55
+ function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
56
+
57
+ if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
58
+
59
+ $buff = $new_cart_data[ $new_key ];
60
+
61
+ unset( $new_cart_data[ $new_key ] );
62
+
63
+ $new_cart_data[ $key ] = $buff;
64
+ }
65
+
66
+ return $new_cart_data;
67
+ }
68
+
69
+ function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
70
+
71
+ $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
72
+
73
+ return $args;
74
+ }
75
+
76
+ function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
77
+
78
+ if( $this->get_product_type( $original_product_id ) == 'composite' ){
79
+
80
+ $composite_data = $this->get_composite_data( $original_product_id );
81
+
82
+ $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
83
+ $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
84
+
85
+ foreach ( $product_translations as $product_translation ) {
86
+
87
+ if ( empty($product_translation->original) ) {
88
+
89
+ $translated_composite_data = $this->get_composite_data( $product_translation->element_id );
90
+
91
+ foreach ( $composite_data as $component_id => $component ) {
92
+
93
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
94
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
95
+ }
96
+
97
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
98
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
99
+ }
100
+
101
+ if ( $component['query_type'] == 'product_ids' ) {
102
+
103
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
104
+ $composite_data[$component_id]['assigned_ids'][$idx] =
105
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $product_translation->language_code );
106
+ }
107
+
108
+ } elseif( $component['query_type'] == 'category_ids' ){
109
+
110
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
111
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
112
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $product_translation->language_code );
113
+
114
+ }
115
+
116
+ }
117
+
118
+ }
119
+
120
+ update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
121
+
122
+ }
123
+
124
+ }
125
+ }
126
+
127
+ }
128
+
129
+ function custom_box_html( $obj, $product_id, $data ){
130
+
131
+ if( $this->get_product_type( $product_id ) == 'composite' ){
132
+
133
+ $composite_data = $this->get_composite_data( $product_id );
134
+
135
+ $composite_section = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Components )', 'woocommerce-multilingual' ) );
136
+ end( $composite_data );
137
+ $last_key = key( $composite_data );
138
+ $divider = true;
139
+ foreach( $composite_data as $component_id => $component ) {
140
+ if( $component_id == $last_key ){
141
+ $divider = false;
142
+ }
143
+ $group = new WPML_Editor_UI_Field_Group( '', $divider );
144
+ $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
145
+ $group->add_field( $composite_field );
146
+ $composite_field = new WPML_Editor_UI_Single_Line_Field( 'composite_'.$component_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
147
+ $group->add_field( $composite_field );
148
+ $composite_section->add_field( $group );
149
+
150
+ }
151
+
152
+ if( $composite_data ){
153
+ $obj->add_field( $composite_section );
154
+ }
155
+
156
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
157
+ if( $composite_scenarios_meta ){
158
+
159
+ $composite_scenarios = new WPML_Editor_UI_Field_Section( __( 'Composite Products ( Scenarios )', 'woocommerce-multilingual' ) );
160
+ end( $composite_scenarios_meta );
161
+ $last_key = key( $composite_scenarios_meta );
162
+ $divider = true;
163
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ) {
164
+ if( $scenario_key == $last_key ){
165
+ $divider = false;
166
+ }
167
+ $group = new WPML_Editor_UI_Field_Group( '', $divider );
168
+ $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_title', __( 'Name', 'woocommerce-multilingual' ), $data, false );
169
+ $group->add_field( $composite_scenario_field );
170
+ $composite_scenario_field = new WPML_Editor_UI_Single_Line_Field( 'composite_scenario_'.$scenario_key.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
171
+ $group->add_field( $composite_scenario_field );
172
+ $composite_scenarios->add_field( $group );
173
+
174
+ }
175
+
176
+ $obj->add_field( $composite_scenarios );
177
+
178
+ }
179
+
180
+ }
181
+
182
+ }
183
+
184
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
185
+
186
+ if( $this->get_product_type( $product_id ) == 'composite' ){
187
+
188
+ $composite_data = $this->get_composite_data( $product_id );
189
+
190
+ foreach( $composite_data as $component_id => $component ) {
191
+
192
+ $data['composite_'.$component_id.'_title'] = array( 'original' =>
193
+ isset( $composite_data[$component_id]['title'] ) ? $composite_data[$component_id]['title'] : '' );
194
+
195
+ $data['composite_'.$component_id.'_description'] = array( 'original' =>
196
+ isset( $composite_data[$component_id]['description'] ) ? $composite_data[$component_id]['description'] : '' );
197
+
198
+ }
199
+
200
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $product_id );
201
+ if( $composite_scenarios_meta ){
202
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
203
+ $data[ 'composite_scenario_'.$scenario_key.'_title' ] = array(
204
+ 'original' => isset( $scenario_meta['title'] ) ? $scenario_meta['title'] : '',
205
+ 'translation' => ''
206
+ );
207
+
208
+ $data[ 'composite_scenario_'.$scenario_key.'_description' ] = array(
209
+ 'original' => isset( $scenario_meta['description'] ) ? $scenario_meta['description'] : '',
210
+ 'translation' => ''
211
+ );
212
+ }
213
+ }
214
+
215
+ if( $translation ){
216
+ $translated_composite_data = $this->get_composite_data( $translation->ID );
217
+
218
+ foreach( $composite_data as $component_id => $component ){
219
+
220
+ $data['composite_'.$component_id.'_title'][ 'translation' ] =
221
+ isset( $translated_composite_data[$component_id]['title'] ) ? $translated_composite_data[$component_id]['title'] : '';
222
+
223
+ $data['composite_'.$component_id.'_description'][ 'translation' ] =
224
+ isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
225
+
226
+ }
227
+
228
+ $translated_composite_scenarios_meta = $this->get_composite_scenarios_meta( $translation->ID );
229
+ if( $translated_composite_scenarios_meta ){
230
+ foreach( $translated_composite_scenarios_meta as $scenario_key => $translated_scenario_meta ){
231
+ $data[ 'composite_scenario_'.$scenario_key.'_title' ][ 'translation' ] =
232
+ isset( $translated_scenario_meta['title'] ) ? $translated_scenario_meta['title'] : '';
233
+
234
+ $data[ 'composite_scenario_'.$scenario_key.'_description' ][ 'translation' ] =
235
+ isset( $translated_scenario_meta['description'] ) ? $translated_scenario_meta['description'] : '';
236
+ }
237
+ }
238
+
239
+ }
240
+
241
+ }
242
+
243
+ return $data;
244
+ }
245
+
246
+ function components_update( $original_product_id, $product_id, $data, $language ){
247
+
248
+ $composite_data = $this->get_composite_data( $original_product_id );
249
+
250
+ foreach( $composite_data as $component_id => $component ) {
251
+
252
+ if(!empty($data[ md5( 'composite_'.$component_id.'_title' ) ] ) ){
253
+ $composite_data[$component_id]['title'] = $data[ md5( 'composite_'.$component_id.'_title' ) ];
254
+ }
255
+
256
+ if(!empty($data[ md5( 'composite_'.$component_id.'_description' ) ])) {
257
+ $composite_data[$component_id]['description'] = $data[ md5( 'composite_'.$component_id.'_description' ) ];
258
+ }
259
+
260
+ //sync product ids
261
+ if( $component[ 'query_type' ] == 'product_ids' ){
262
+ foreach( $component[ 'assigned_ids' ] as $key => $assigned_id ){
263
+ $assigned_id_current_language = apply_filters( 'translate_object_id', $assigned_id, get_post_type( $assigned_id ), false, $language );
264
+ if( $assigned_id_current_language ){
265
+ $composite_data[ $component_id ][ 'assigned_ids' ][ $key ] = $assigned_id_current_language;
266
+ }
267
+ }
268
+ //sync default
269
+ if( $component[ 'default_id' ] ){
270
+ $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], get_post_type( $component[ 'default_id' ] ), false, $language );
271
+ if( $trnsl_default_id ){
272
+ $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
273
+ }
274
+ }
275
+
276
+ }elseif( $component[ 'query_type' ] == 'category_ids' ){
277
+ foreach( $component[ 'assigned_category_ids' ] as $key => $assigned_id ){
278
+ $trsl_term_id = apply_filters( 'translate_object_id', $assigned_id, 'product_cat', false, $language );
279
+ if( $trsl_term_id ){
280
+ $composite_data[ $component_id ][ 'assigned_category_ids' ][ $key ] = $trsl_term_id;
281
+ }
282
+ }
283
+ //sync default
284
+ if( $component[ 'default_id' ] ){
285
+ $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], 'product_cat', false, $language );
286
+ if( $trnsl_default_id ){
287
+ $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
288
+ }
289
+ }
290
+ }
291
+ }
292
+
293
+ update_post_meta( $product_id, '_bto_data', $composite_data );
294
+
295
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $original_product_id );
296
+ if( $composite_scenarios_meta ){
297
+ foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
298
+ if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ] ) ){
299
+ $composite_scenarios_meta[ $scenario_key ][ 'title' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_title' ) ];
300
+ }
301
+
302
+ if( !empty( $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ])) {
303
+ $composite_scenarios_meta[ $scenario_key ][ 'description' ] = $data[ md5( 'composite_scenario_'.$scenario_key.'_description' ) ];
304
+ }
305
+
306
+ //sync product ids
307
+ foreach( $scenario_meta[ 'component_data' ] as $compon_id => $component_data ){
308
+ if( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'product_ids' ){
309
+ foreach( $component_data as $key => $assigned_prod_id ){
310
+ $trnsl_assigned_prod_id = apply_filters( 'translate_object_id', $assigned_prod_id, get_post_type( $assigned_prod_id ), false, $language );
311
+ if( $trnsl_assigned_prod_id ){
312
+ $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trnsl_assigned_prod_id;
313
+ }
314
+ }
315
+ }elseif( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'category_ids' ){
316
+ foreach( $component_data as $key => $assigned_cat_id ){
317
+ $trslt_assigned_cat_id = apply_filters( 'translate_object_id', $assigned_cat_id, 'product_cat', false, $language );
318
+ if( $trslt_assigned_cat_id ){
319
+ $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trslt_assigned_cat_id;
320
+ }
321
+ }
322
+ }
323
+ }
324
+ }
325
+ }
326
+
327
+ update_post_meta( $product_id, '_bto_scenario_data', $composite_scenarios_meta );
328
+
329
+ return array(
330
+ 'components' => $composite_data,
331
+ 'scenarios' => $composite_scenarios_meta,
332
+ );
333
+ }
334
+
335
+ function append_composite_data_translation_package( $package, $post ){
336
+
337
+ if( $post->post_type == 'product' ) {
338
+
339
+ $composite_data = get_post_meta( $post->ID, '_bto_data', true );
340
+
341
+ if( $composite_data ){
342
+
343
+ $fields = array( 'title', 'description' );
344
+
345
+ foreach( $composite_data as $component_id => $component ){
346
+
347
+ foreach( $fields as $field ) {
348
+ if ( !empty($component[$field]) ) {
349
+
350
+ $package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
351
+ 'translate' => 1,
352
+ 'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
353
+ 'format' => 'base64'
354
+ );
355
+
356
+ }
357
+ }
358
+
359
+ }
360
+
361
+ }
362
+
363
+ }
364
+
365
+ return $package;
366
+
367
+ }
368
+
369
+ function save_composite_data_translation( $post_id, $data, $job ){
370
+
371
+
372
+ $translated_composite_data = array();
373
+ foreach( $data as $value){
374
+
375
+ if( preg_match( '/wc_composite:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
376
+
377
+ $component_id = $matches[1];
378
+ $field = $matches[2];
379
+
380
+ $translated_composite_data[$component_id][$field] = $value['data'];
381
+
382
+ }
383
+
384
+ }
385
+
386
+ if( $translated_composite_data ){
387
+
388
+ $composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
389
+
390
+
391
+ foreach ( $composite_data as $component_id => $component ) {
392
+
393
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
394
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
395
+ }
396
+
397
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
398
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
399
+ }
400
+
401
+ if ( $component['query_type'] == 'product_ids' ) {
402
+
403
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
404
+ $composite_data[$component_id]['assigned_ids'][$idx] =
405
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $job->language_code );
406
+ }
407
+
408
+ } elseif( $component['query_type'] == 'category_ids' ){
409
+
410
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
411
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
412
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $job->language_code );
413
+
414
+ }
415
+
416
+ }
417
+
418
+ }
419
+
420
+ }
421
+
422
+ update_post_meta( $post_id, '_bto_data', $composite_data );
423
+
424
+ }
425
+
426
+ function wcml_js_lock_fields_input_names( $names ){
427
+
428
+ $names[] = '_base_regular_price';
429
+ $names[] = '_base_sale_price';
430
+ $names[] = 'bto_style';
431
+
432
+ return $names;
433
+ }
434
+
435
+ function wcml_js_lock_fields_ids( $names ){
436
+
437
+ $names[] = '_per_product_pricing_bto';
438
+ $names[] = '_per_product_shipping_bto';
439
+ $names[] = '_bto_hide_shop_price';
440
+
441
+ return $names;
442
+ }
443
+
444
+ function localize_lock_fields_js(){
445
+ wp_localize_script( 'wcml-composite-js', 'lock_settings' , array( 'lock_fields' => 1 ) );
446
+ }
447
+
448
+ function load_assets( ){
449
+ global $pagenow;
450
+
451
+ if( ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) && wc_get_product( $_GET[ 'post' ] )->product_type == '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
+
455
+ }
456
+
457
+ }
458
+
459
+ function woocommerce_json_search_found_products( $found_products ){
460
+ global $wpml_post_translations;
461
+
462
+ foreach( $found_products as $id => $product_name ){
463
+ if( $wpml_post_translations->get_element_lang_code ( $id ) != $this->sitepress->get_current_language() ){
464
+ unset( $found_products[ $id ] );
465
+ }
466
+ }
467
+
468
+ return $found_products;
469
+ }
470
+
471
+ public function get_composite_scenarios_meta( $product_id ){
472
+ return get_post_meta( $product_id, '_bto_scenario_data', true );
473
+ }
474
+
475
+ public function get_composite_data( $product_id ){
476
+ return get_post_meta( $product_id, '_bto_data', true );
477
+ }
478
+
479
+ }
compatibility/class-wcml-dynamic-pricing.php CHANGED
@@ -1,116 +1,116 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Dynamic_Pricing
5
- */
6
- class WCML_Dynamic_Pricing {
7
-
8
- /**
9
- * @var SitePress
10
- */
11
- public $sitepress;
12
-
13
- /**
14
- * WCML_Dynamic_Pricing constructor.
15
- *
16
- * @param $sitepress
17
- */
18
- function __construct( &$sitepress ) {
19
- if ( ! is_admin() ) {
20
- $this->sitepress = $sitepress;
21
- add_filter( 'wc_dynamic_pricing_load_modules', array( $this, 'filter_price' ) );
22
- add_filter( 'woocommerce_dynamic_pricing_is_applied_to', array( $this, 'woocommerce_dynamic_pricing_is_applied_to' ), 10, 5 );
23
- add_filter( 'woocommerce_dynamic_pricing_get_rule_amount', array( $this, 'woocommerce_dynamic_pricing_get_rule_amount' ), 10, 2 );
24
- add_filter( 'dynamic_pricing_product_rules', array( $this, 'dynamic_pricing_product_rules' ) );
25
- add_filter( 'wcml_calculate_totals_exception', array( $this, 'calculate_totals_exception' ) );
26
- }
27
- }
28
-
29
- /**
30
- * @param $modules
31
- *
32
- * @return mixed
33
- */
34
- function filter_price( $modules ) {
35
-
36
- foreach ( $modules as $mod_key => $module ) {
37
- if ( isset( $module->available_rulesets ) ) {
38
- $available_rulesets = $module->available_rulesets;
39
- foreach ( $available_rulesets as $rule_key => $available_ruleset ) {
40
- $rules = $available_ruleset['rules'];
41
- if ( $rules ) {
42
- foreach ( $rules as $r_key => $rule ) {
43
- if ( 'fixed_product' === $rule['type'] ) {
44
- $rules[ $r_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $rule['amount'] );
45
- }
46
- }
47
- $modules[ $mod_key ]->available_rulesets[ $rule_key ]['rules'] = $rules;
48
- }
49
- }
50
- }
51
- }
52
-
53
- return $modules;
54
- }
55
-
56
-
57
- /**
58
- * @param $process_discounts
59
- * @param $_product
60
- * @param $module_id
61
- * @param $obj
62
- * @param $cat_id
63
- *
64
- * @return bool|WP_Error
65
- */
66
- function woocommerce_dynamic_pricing_is_applied_to( $process_discounts, $_product, $module_id, $obj, $cat_id ) {
67
- if ( $cat_id && isset( $obj->available_rulesets ) && count( $obj->available_rulesets ) > 0 ) {
68
- $cat_id = apply_filters( 'translate_object_id', $cat_id, 'product_cat', true, $this->sitepress->get_current_language() );
69
- $process_discounts = is_object_in_term( $_product->id, 'product_cat', $cat_id );
70
- }
71
-
72
- return $process_discounts;
73
- }
74
-
75
-
76
- /**
77
- * @param $amount
78
- * @param $rule
79
- *
80
- * @return mixed|void
81
- */
82
- function woocommerce_dynamic_pricing_get_rule_amount( $amount, $rule ) {
83
-
84
- if ( 'price_discount' === $rule['type'] || 'fixed_price' === $rule['type'] ) {
85
- $amount = apply_filters( 'wcml_raw_price_amount', $amount );
86
- }
87
-
88
- return $amount;
89
- }
90
-
91
-
92
- /**
93
- * @param $rules
94
- *
95
- * @return array
96
- */
97
- function dynamic_pricing_product_rules( $rules ) {
98
- if ( is_array( $rules ) ) {
99
- foreach ( $rules as $r_key => $rule ) {
100
- foreach ( $rule['rules'] as $key => $product_rule ) {
101
- if ( 'price_discount' === $product_rule['type'] || 'fixed_price' === $product_rule['type'] ) {
102
- $rules[ $r_key ]['rules'][ $key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $product_rule['amount'] );
103
- }
104
- }
105
- }
106
- }
107
- return $rules;
108
- }
109
-
110
- /**
111
- * @return bool
112
- */
113
- function calculate_totals_exception() {
114
- return false;
115
- }
116
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Dynamic_Pricing
5
+ */
6
+ class WCML_Dynamic_Pricing {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * WCML_Dynamic_Pricing constructor.
15
+ *
16
+ * @param $sitepress
17
+ */
18
+ function __construct( &$sitepress ) {
19
+ if ( ! is_admin() ) {
20
+ $this->sitepress = $sitepress;
21
+ add_filter( 'wc_dynamic_pricing_load_modules', array( $this, 'filter_price' ) );
22
+ add_filter( 'woocommerce_dynamic_pricing_is_applied_to', array( $this, 'woocommerce_dynamic_pricing_is_applied_to' ), 10, 5 );
23
+ add_filter( 'woocommerce_dynamic_pricing_get_rule_amount', array( $this, 'woocommerce_dynamic_pricing_get_rule_amount' ), 10, 2 );
24
+ add_filter( 'dynamic_pricing_product_rules', array( $this, 'dynamic_pricing_product_rules' ) );
25
+ add_filter( 'wcml_calculate_totals_exception', array( $this, 'calculate_totals_exception' ) );
26
+ }
27
+ }
28
+
29
+ /**
30
+ * @param $modules
31
+ *
32
+ * @return mixed
33
+ */
34
+ function filter_price( $modules ) {
35
+
36
+ foreach ( $modules as $mod_key => $module ) {
37
+ if ( isset( $module->available_rulesets ) ) {
38
+ $available_rulesets = $module->available_rulesets;
39
+ foreach ( $available_rulesets as $rule_key => $available_ruleset ) {
40
+ $rules = $available_ruleset['rules'];
41
+ if ( $rules ) {
42
+ foreach ( $rules as $r_key => $rule ) {
43
+ if ( 'fixed_product' === $rule['type'] ) {
44
+ $rules[ $r_key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $rule['amount'] );
45
+ }
46
+ }
47
+ $modules[ $mod_key ]->available_rulesets[ $rule_key ]['rules'] = $rules;
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ return $modules;
54
+ }
55
+
56
+
57
+ /**
58
+ * @param $process_discounts
59
+ * @param $_product
60
+ * @param $module_id
61
+ * @param $obj
62
+ * @param $cat_id
63
+ *
64
+ * @return bool|WP_Error
65
+ */
66
+ function woocommerce_dynamic_pricing_is_applied_to( $process_discounts, $_product, $module_id, $obj, $cat_id ) {
67
+ if ( $cat_id && isset( $obj->available_rulesets ) && count( $obj->available_rulesets ) > 0 ) {
68
+ $cat_id = apply_filters( 'translate_object_id', $cat_id, 'product_cat', true, $this->sitepress->get_current_language() );
69
+ $process_discounts = is_object_in_term( $_product->id, 'product_cat', $cat_id );
70
+ }
71
+
72
+ return $process_discounts;
73
+ }
74
+
75
+
76
+ /**
77
+ * @param $amount
78
+ * @param $rule
79
+ *
80
+ * @return mixed|void
81
+ */
82
+ function woocommerce_dynamic_pricing_get_rule_amount( $amount, $rule ) {
83
+
84
+ if ( 'price_discount' === $rule['type'] || 'fixed_price' === $rule['type'] ) {
85
+ $amount = apply_filters( 'wcml_raw_price_amount', $amount );
86
+ }
87
+
88
+ return $amount;
89
+ }
90
+
91
+
92
+ /**
93
+ * @param $rules
94
+ *
95
+ * @return array
96
+ */
97
+ function dynamic_pricing_product_rules( $rules ) {
98
+ if ( is_array( $rules ) ) {
99
+ foreach ( $rules as $r_key => $rule ) {
100
+ foreach ( $rule['rules'] as $key => $product_rule ) {
101
+ if ( 'price_discount' === $product_rule['type'] || 'fixed_price' === $product_rule['type'] ) {
102
+ $rules[ $r_key ]['rules'][ $key ]['amount'] = apply_filters( 'wcml_raw_price_amount', $product_rule['amount'] );
103
+ }
104
+ }
105
+ }
106
+ }
107
+ return $rules;
108
+ }
109
+
110
+ /**
111
+ * @return bool
112
+ */
113
+ function calculate_totals_exception() {
114
+ return false;
115
+ }
116
+ }
compatibility/class-wcml-extra-product-options.php CHANGED
@@ -1,107 +1,107 @@
1
- <?php
2
-
3
- class WCML_Extra_Product_Options{
4
-
5
- function __construct(){
6
-
7
- // commented out because of wcml-1218
8
- // add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
9
- // add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
10
-
11
- add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
12
- add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
13
- }
14
-
15
- // commented out because of wcml-1218
16
- /*
17
-
18
- function register_options_strings( $meta_id, $id, $meta_key, $options ){
19
- if( $meta_key != 'tm_meta' )
20
- return false;
21
-
22
- $this->filter_options( $options, $id, 'register' );
23
-
24
- }
25
-
26
- function product_options_filter( $null, $object_id, $meta_key, $single ){
27
- static $no_filter = false;
28
-
29
- if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
30
- $no_filter = true;
31
-
32
- $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
33
-
34
- $options = $this->filter_options( $options, $object_id, 'translate' );
35
-
36
- $no_filter = false;
37
- }
38
-
39
- return isset( $options ) ? array( $options ) : $null;
40
- }
41
-
42
- function filter_options( $options, $id, $action ){
43
-
44
- if( !isset( $options[ 'tmfbuilder' ] ) ){
45
- return $options;
46
- }
47
-
48
- global $sitepress,$woocommerce_wpml;
49
- $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
50
-
51
- $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
52
-
53
- foreach( $options[ 'tmfbuilder' ] as $key => $values ){
54
- foreach( $keys_to_translate as $key_text ){
55
- if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
56
- foreach( $values as $value_key => $value ){
57
- if( $value ){
58
- if( $action == 'register'){
59
- do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
60
- }else{
61
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
62
- }
63
- }
64
-
65
- }
66
- }
67
- }
68
-
69
- //convert prices
70
- if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
71
- foreach( $values as $value_key => $value ){
72
- if( $value ){
73
- if( is_array( $value ) ){
74
- foreach( $value as $key_price => $price ){
75
- $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
76
- }
77
- }else{
78
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
79
- }
80
- }
81
- }
82
- }
83
-
84
- }
85
-
86
- return $options;
87
- }
88
-
89
- */
90
-
91
- function inf_translate_strings(){
92
- if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
93
- $this->inf_message( 'Options Form' );
94
- }
95
-
96
- function inf_translate_product_page_strings(){
97
- $this->inf_message( 'Product' );
98
- }
99
-
100
- function inf_message( $text ){
101
- $message = '<div><p class="icl_cyan_box">';
102
- $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
103
- $message .= '</p></div>';
104
-
105
- echo $message;
106
- }
107
- }
1
+ <?php
2
+
3
+ class WCML_Extra_Product_Options{
4
+
5
+ function __construct(){
6
+
7
+ // commented out because of wcml-1218
8
+ // add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
9
+ // add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
10
+
11
+ add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
12
+ add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
13
+ }
14
+
15
+ // commented out because of wcml-1218
16
+ /*
17
+
18
+ function register_options_strings( $meta_id, $id, $meta_key, $options ){
19
+ if( $meta_key != 'tm_meta' )
20
+ return false;
21
+
22
+ $this->filter_options( $options, $id, 'register' );
23
+
24
+ }
25
+
26
+ function product_options_filter( $null, $object_id, $meta_key, $single ){
27
+ static $no_filter = false;
28
+
29
+ if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
30
+ $no_filter = true;
31
+
32
+ $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
33
+
34
+ $options = $this->filter_options( $options, $object_id, 'translate' );
35
+
36
+ $no_filter = false;
37
+ }
38
+
39
+ return isset( $options ) ? array( $options ) : $null;
40
+ }
41
+
42
+ function filter_options( $options, $id, $action ){
43
+
44
+ if( !isset( $options[ 'tmfbuilder' ] ) ){
45
+ return $options;
46
+ }
47
+
48
+ global $sitepress,$woocommerce_wpml;
49
+ $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
50
+
51
+ $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
52
+
53
+ foreach( $options[ 'tmfbuilder' ] as $key => $values ){
54
+ foreach( $keys_to_translate as $key_text ){
55
+ if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
56
+ foreach( $values as $value_key => $value ){
57
+ if( $value ){
58
+ if( $action == 'register'){
59
+ do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
60
+ }else{
61
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
62
+ }
63
+ }
64
+
65
+ }
66
+ }
67
+ }
68
+
69
+ //convert prices
70
+ if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
71
+ foreach( $values as $value_key => $value ){
72
+ if( $value ){
73
+ if( is_array( $value ) ){
74
+ foreach( $value as $key_price => $price ){
75
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
76
+ }
77
+ }else{
78
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ }
85
+
86
+ return $options;
87
+ }
88
+
89
+ */
90
+
91
+ function inf_translate_strings(){
92
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
93
+ $this->inf_message( 'Options Form' );
94
+ }
95
+
96
+ function inf_translate_product_page_strings(){
97
+ $this->inf_message( 'Product' );
98
+ }
99
+
100
+ function inf_message( $text ){
101
+ $message = '<div><p class="icl_cyan_box">';
102
+ $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
103
+ $message .= '</p></div>';
104
+
105
+ echo $message;
106
+ }
107
+ }
compatibility/class-wcml-flatsome.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
-
3
- class WCML_Flatsome{
4
-
5
- function __construct(){
6
- add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
- }
8
-
9
- function add_action_to_multi_currency_ajax($actions){
10
- $actions[] = 'ux_quickview';
11
- return $actions;
12
- }
13
-
14
-
15
- }
16
-
1
+ <?php
2
+
3
+ class WCML_Flatsome{
4
+
5
+ function __construct(){
6
+ add_filter( 'wcml_multi_currency_is_ajax', array( $this, 'add_action_to_multi_currency_ajax' ) );
7
+ }
8
+
9
+ function add_action_to_multi_currency_ajax($actions){
10
+ $actions[] = 'ux_quickview';
11
+ return $actions;
12
+ }
13
+
14
+
15
+ }
16
+
compatibility/class-wcml-gravityforms.php CHANGED
@@ -1,47 +1,47 @@
1
- <?php
2
-
3
- class WCML_gravityforms{
4
-
5
- function __construct(){
6
- add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
- add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
-
9
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
10
- }
11
-
12
- function wcml_convert_price($formatted, $unformatted){
13
- if ( ! is_admin() ) {
14
- $currency = apply_filters('wcml_price_currency', get_woocommerce_currency());
15
- $formatted = strip_tags(wc_price(apply_filters('wcml_raw_price_amount', $unformatted), array('currency'=>$currency)));
16
- }
17
- return $formatted;
18
- }
19
-
20
-
21
- function add_ajax_action($actions){
22
- $actions[] = 'get_updated_price';
23
- return $actions;
24
- }
25
-
26
- function sync_gf_data($original_product_id, $trnsl_product_id, $data){
27
- $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
28
- $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
29
-
30
- if( !$trnsl_gf ){
31
- update_post_meta( $trnsl_product_id, '_gravity_form_data', $orig_gf );
32
- }else{
33
- $trnsl_gf['id'] = $orig_gf['id'];
34
- $trnsl_gf['display_title'] = $orig_gf['display_title'];
35
- $trnsl_gf['display_description'] = $orig_gf['display_description'];
36
- $trnsl_gf['disable_woocommerce_price'] = $orig_gf['disable_woocommerce_price'];
37
- $trnsl_gf['disable_calculations'] = $orig_gf['disable_calculations'];
38
- $trnsl_gf['disable_label_subtotal'] = $orig_gf['disable_label_subtotal'];
39
- $trnsl_gf['disable_label_options'] = $orig_gf['disable_label_options'];
40
- $trnsl_gf['disable_label_total'] = $orig_gf['disable_label_total'];
41
- $trnsl_gf['disable_anchor'] = $orig_gf['disable_anchor'];
42
-
43
- update_post_meta( $trnsl_product_id, '_gravity_form_data', $trnsl_gf );
44
- }
45
- }
46
-
47
- }
1
+ <?php
2
+
3
+ class WCML_gravityforms{
4
+
5
+ function __construct(){
6
+ add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
+ add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
+
9
+ add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
10
+ }
11
+
12
+ function wcml_convert_price($formatted, $unformatted){
13
+ if ( ! is_admin() ) {
14
+ $currency = apply_filters('wcml_price_currency', get_woocommerce_currency());
15
+ $formatted = strip_tags(wc_price(apply_filters('wcml_raw_price_amount', $unformatted), array('currency'=>$currency)));
16
+ }
17
+ return $formatted;
18
+ }
19
+
20
+
21
+ function add_ajax_action($actions){
22
+ $actions[] = 'get_updated_price';
23
+ return $actions;
24
+ }
25
+
26
+ function sync_gf_data($original_product_id, $trnsl_product_id, $data){
27
+ $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
28
+ $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
29
+
30
+ if( !$trnsl_gf ){
31
+ update_post_meta( $trnsl_product_id, '_gravity_form_data', $orig_gf );
32
+ }else{
33
+ $trnsl_gf['id'] = $orig_gf['id'];
34
+ $trnsl_gf['display_title'] = $orig_gf['display_title'];
35
+ $trnsl_gf['display_description'] = $orig_gf['display_description'];
36
+ $trnsl_gf['disable_woocommerce_price'] = $orig_gf['disable_woocommerce_price'];
37
+ $trnsl_gf['disable_calculations'] = $orig_gf['disable_calculations'];
38
+ $trnsl_gf['disable_label_subtotal'] = $orig_gf['disable_label_subtotal'];
39
+ $trnsl_gf['disable_label_options'] = $orig_gf['disable_label_options'];
40
+ $trnsl_gf['disable_label_total'] = $orig_gf['disable_label_total'];
41
+ $trnsl_gf['disable_anchor'] = $orig_gf['disable_anchor'];
42
+
43
+ update_post_meta( $trnsl_product_id, '_gravity_form_data', $trnsl_gf );
44
+ }
45
+ }
46
+
47
+ }
compatibility/class-wcml-jck-wssv.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- class WCML_JCK_WSSV{
4
-
5
- private $transient_name = 'jck_wssv_term_counts';
6
-
7
- public function __construct(){
8
-
9
- add_filter( 'pre_transient_' . $this->transient_name, array( $this, 'get_language_specific_transient' ) );
10
- add_filter( 'set_transient_' . $this->transient_name, array( $this, 'set_language_specific_transient' ), 10, 2 );
11
- }
12
-
13
- public function get_language_specific_transient(){
14
- return get_transient( $this->transient_name . '_' . ICL_LANGUAGE_CODE );
15
- }
16
-
17
- public function set_language_specific_transient( $value, $expiration ){
18
-
19
- delete_transient( $this->transient_name );
20
- set_transient( $this->transient_name . '_' . ICL_LANGUAGE_CODE, $value, $expiration );
21
-
22
- }
23
-
24
  }
1
+ <?php
2
+
3
+ class WCML_JCK_WSSV{
4
+
5
+ private $transient_name = 'jck_wssv_term_counts';
6
+
7
+ public function __construct(){
8
+
9
+ add_filter( 'pre_transient_' . $this->transient_name, array( $this, 'get_language_specific_transient' ) );
10
+ add_filter( 'set_transient_' . $this->transient_name, array( $this, 'set_language_specific_transient' ), 10, 2 );
11
+ }
12
+
13
+ public function get_language_specific_transient(){
14
+ return get_transient( $this->transient_name . '_' . ICL_LANGUAGE_CODE );
15
+ }
16
+
17
+ public function set_language_specific_transient( $value, $expiration ){
18
+
19
+ delete_transient( $this->transient_name );
20
+ set_transient( $this->transient_name . '_' . ICL_LANGUAGE_CODE, $value, $expiration );
21
+
22
+ }
23
+
24
  }
compatibility/class-wcml-mix-and-match-products.php CHANGED
@@ -1,67 +1,67 @@
1
- <?php
2
-
3
- class WCML_Mix_and_Match_Products{
4
-
5
- function __construct(){
6
- add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
7
- }
8
-
9
- function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ){
10
-
11
- if( $meta_key != '_mnm_data' )
12
- return false;
13
-
14
- global $sitepress, $woocommerce_wpml;
15
-
16
- $post = get_post( $post_id );
17
-
18
- // skip auto-drafts // skip autosave
19
- if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
20
- return;
21
- }
22
-
23
- if( $post->post_type == 'product' ) {
24
-
25
- remove_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
26
-
27
- if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
28
-
29
- $original_product_id = $post_id;
30
-
31
- } else {
32
-
33
- $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
34
- $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
35
-
36
- }
37
-
38
- $mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
39
- $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
40
- $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
41
-
42
- foreach ( $product_translations as $product_translation ) {
43
-
44
- if (empty($product_translation->original)) {
45
-
46
- foreach ($mnm_data as $key => $mnm_element) {
47
-
48
- $trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
49
- $mnm_element['product_id'] = $trnsl_prod;
50
- $mnm_data[ $trnsl_prod ] = $mnm_element;
51
- unset( $mnm_data[$key]);
52
- }
53
-
54
- update_post_meta($product_translation->element_id, '_mnm_data', $mnm_data);
55
-
56
- }
57
-
58
- }
59
-
60
- add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
61
-
62
- }
63
-
64
- }
65
-
66
-
67
- }
1
+ <?php
2
+
3
+ class WCML_Mix_and_Match_Products{
4
+
5
+ function __construct(){
6
+ add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
7
+ }
8
+
9
+ function sync_mnm_data( $meta_id, $post_id, $meta_key, $meta_value ){
10
+
11
+ if( $meta_key != '_mnm_data' )
12
+ return false;
13
+
14
+ global $sitepress, $woocommerce_wpml;
15
+
16
+ $post = get_post( $post_id );
17
+
18
+ // skip auto-drafts // skip autosave
19
+ if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
20
+ return;
21
+ }
22
+
23
+ if( $post->post_type == 'product' ) {
24
+
25
+ remove_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
26
+
27
+ if ( $woocommerce_wpml->products->is_original_product( $post_id ) ) {
28
+
29
+ $original_product_id = $post_id;
30
+
31
+ } else {
32
+
33
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
34
+ $original_product_id = apply_filters( 'translate_object_id', $post_id, 'product', true, $original_product_language );
35
+
36
+ }
37
+
38
+ $mnm_data = maybe_unserialize( get_post_meta( $original_product_id, '_mnm_data', true ) );
39
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
40
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
41
+
42
+ foreach ( $product_translations as $product_translation ) {
43
+
44
+ if (empty($product_translation->original)) {
45
+
46
+ foreach ($mnm_data as $key => $mnm_element) {
47
+
48
+ $trnsl_prod = apply_filters( 'translate_object_id', $key, 'product', true, $product_translation->language_code );
49
+ $mnm_element['product_id'] = $trnsl_prod;
50
+ $mnm_data[ $trnsl_prod ] = $mnm_element;
51
+ unset( $mnm_data[$key]);
52
+ }
53
+
54
+ update_post_meta($product_translation->element_id, '_mnm_data', $mnm_data);
55
+
56
+ }
57
+
58
+ }
59
+
60
+ add_action( 'updated_post_meta', array( $this, 'sync_mnm_data'), 10, 4 );
61
+
62
+ }
63
+
64
+ }
65
+
66
+
67
+ }
compatibility/class-wcml-per-product-shipping.php CHANGED
@@ -1,30 +1,30 @@
1
- <?php
2
-
3
- class WCML_Per_Product_Shipping{
4
-
5
- function __construct(){
6
-
7
- if(!is_admin()){
8
-
9
- add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
-
11
- }
12
-
13
-
14
- }
15
-
16
- function original_product_id( $product_id ){
17
- global $sitepress;
18
-
19
- $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
- $translations = $sitepress->get_element_translations($trid, 'post_product');
21
- foreach($translations as $language_code =>$translation){
22
- if($translation->original){
23
- $product_id = $translation->element_id;
24
- }
25
- }
26
-
27
- return $product_id;
28
- }
29
-
30
- }
1
+ <?php
2
+
3
+ class WCML_Per_Product_Shipping{
4
+
5
+ function __construct(){
6
+
7
+ if(!is_admin()){
8
+
9
+ add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
+
11
+ }
12
+
13
+
14
+ }
15
+
16
+ function original_product_id( $product_id ){
17
+ global $sitepress;
18
+
19
+ $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
+ $translations = $sitepress->get_element_translations($trid, 'post_product');
21
+ foreach($translations as $language_code =>$translation){
22
+ if($translation->original){
23
+ $product_id = $translation->element_id;
24
+ }
25
+ }
26
+
27
+ return $product_id;
28
+ }
29
+
30
+ }
compatibility/class-wcml-product-addons.php CHANGED
@@ -1,247 +1,247 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Product_Addons
5
- */
6
- class WCML_Product_Addons {
7
-
8
- /**
9
- * @var SitePress
10
- */
11
- public $sitepress;
12
-
13
- /**
14
- * WCML_Product_Addons constructor.
15
- */
16
- function __construct( &$sitepress ) {
17
- $this->sitepress = $sitepress;
18
- add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
19
- add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
20
-
21
- add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
22
- add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
23
- add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
24
-
25
- global $pagenow;
26
- if ( 'edit.php' === $pagenow &&
27
- isset( $_GET['post_type'] ) &&
28
- 'product' === $_GET['post_type'] &&
29
- isset( $_GET['page'] ) &&
30
- 'global_addons' === $_GET['page'] &&
31
- ! isset( $_GET['edit'] )
32
- ) {
33
- add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
34
- }
35
-
36
- add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
37
-
38
- if ( is_admin() ) {
39
-
40
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
41
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 3 );
42
- add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
43
- }
44
- }
45
-
46
- /**
47
- * @param $meta_id
48
- * @param $id
49
- * @param $meta_key
50
- * @param $addons
51
- */
52
- function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
53
- if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
54
- foreach ( $addons as $addon ) {
55
- //register name
56
- do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name'] );
57
- //register description
58
- do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description', $addon['description'] );
59
- //register options labels
60
- foreach ( $addon['options'] as $key => $option ) {
61
- do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key, $option['label'] );
62
- }
63
- }
64
- }
65
- }
66
-
67
- /**
68
- * @param $null
69
- * @param $object_id
70
- * @param $meta_key
71
- * @param $single
72
- *
73
- * @return array
74
- */
75
- function translate_addons_strings( $null, $object_id, $meta_key, $single ) {
76
-
77
- if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $object_id ) ) {
78
-
79
- remove_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
80
- $addons = get_post_meta( $object_id, $meta_key, true );
81
- add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
82
-
83
- if ( is_array( $addons ) ) {
84
- foreach ( $addons as $key => $addon ) {
85
- //register name
86
- $addons[ $key ]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name' );
87
- //register description
88
- $addons[ $key ]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description' );
89
- //register options labels
90
- foreach ( $addon['options'] as $opt_key => $option ) {
91
- $addons[ $key ]['options'][ $opt_key ]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $opt_key );
92
- }
93
- }
94
- }
95
-
96
- return array( 0 => $addons );
97
- }
98
-
99
- return $null;
100
-
101
- }
102
-
103
- /**
104
- * @param $addons
105
- *
106
- * @return mixed
107
- */
108
- function product_addons_filter( $addons ) {
109
-
110
- foreach ( $addons as $add_id => $addon ) {
111
- foreach ( $addon['options'] as $key => $option ) {
112
- //price filter
113
- $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
114
- }
115
- }
116
-
117
- return $addons;
118
- }
119
-
120
-
121
- /**
122
- * @param $product_terms
123
- *
124
- * @return array
125
- */
126
- function addons_product_terms( $product_terms ) {
127
- foreach ( $product_terms as $key => $product_term ) {
128
- $product_terms[ $key ] = apply_filters( 'translate_object_id', $product_term, 'product_cat', true, $this->sitepress->get_default_language() );
129
- }
130
-
131
- return $product_terms;
132
- }
133
-
134
- function inf_translate_strings() {
135
- $message = '<div><p class="icl_cyan_box">';
136
- $message .= sprintf( __( 'To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual' ), admin_url( 'admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings' ) );
137
- $message .= '</p></div>';
138
-
139
- echo $message;
140
- }
141
-
142
- /**
143
- * @param $obj
144
- * @param $product_id
145
- * @param $data
146
- */
147
- function custom_box_html( $obj, $product_id, $data ) {
148
-
149
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
150
-
151
- if ( ! empty( $product_addons ) ) {
152
- foreach ( $product_addons as $addon_id => $product_addon ) {
153
-
154
- $addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $product_addon['name'] ) );
155
-
156
- $group = new WPML_Editor_UI_Field_Group( '' , true );
157
- $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
158
- $group->add_field( $addon_field );
159
- $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
160
- $group->add_field( $addon_field );
161
-
162
- $addons_section->add_field( $group );
163
-
164
- if ( ! empty( $product_addon['options'] ) ) {
165
-
166
- $labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ) , true );
167
-
168
- foreach ( $product_addon['options'] as $option_id => $option ) {
169
- $option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_option_'.$option_id.'_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
170
- $labels_group->add_field( $option_label_field );
171
- }
172
- $addons_section->add_field( $labels_group );
173
- }
174
- $obj->add_field( $addons_section );
175
- }
176
- }
177
- }
178
-
179
- /**
180
- * @param $data
181
- * @param $product_id
182
- * @param $translation
183
- *
184
- * @return mixed
185
- */
186
- function custom_box_html_data( $data, $product_id, $translation ) {
187
-
188
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
189
-
190
- if ( ! empty( $product_addons ) ) {
191
- foreach ( $product_addons as $addon_id => $product_addon ) {
192
- $data[ 'addon_' . $addon_id . '_name' ] = array( 'original' => $product_addon['name'] );
193
- $data[ 'addon_' . $addon_id . '_description' ] = array( 'original' => $product_addon['description'] );
194
- if ( ! empty( $product_addon['options'] ) ) {
195
- foreach ( $product_addon['options'] as $option_id => $option ) {
196
- $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ] = array( 'original' => $option['label'] );
197
- }
198
- }
199
- }
200
-
201
- if ( $translation ) {
202
- $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
203
- if ( ! empty( $transalted_product_addons ) ) {
204
- foreach ( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
205
- $data[ 'addon_' . $addon_id . '_name' ]['translation'] = $transalted_product_addon['name'];
206
- $data[ 'addon_' . $addon_id . '_description' ]['translation'] = $transalted_product_addon['description'];
207
- if ( ! empty( $transalted_product_addon['options'] ) ) {
208
- foreach ( $transalted_product_addon['options'] as $option_id => $option ) {
209
- $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ]['translation'] = $option['label'];
210
- }
211
- }
212
- }
213
- }
214
- }
215
- }
216
-
217
- return $data;
218
- }
219
-
220
- /**
221
- * @param $original_product_id
222
- * @param $product_id
223
- * @param $data
224
- */
225
- function addons_update( $original_product_id, $product_id, $data ) {
226
-
227
- $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
228
-
229
- if ( ! empty( $product_addons ) ) {
230
-
231
- foreach ( $product_addons as $addon_id => $product_addon ) {
232
-
233
- $product_addons[ $addon_id ]['name'] = $data[ md5( 'addon_' . $addon_id . '_name' ) ];
234
- $product_addons[ $addon_id ]['description'] = $data[ md5( 'addon_' . $addon_id . '_description' ) ];
235
-
236
- if ( ! empty( $product_addon['options'] ) ) {
237
-
238
- foreach ( $product_addon['options'] as $option_id => $option ) {
239
- $product_addons[ $addon_id ]['options'][ $option_id ]['label'] = $data[ md5( 'addon_'.$addon_id.'_option_'.$option_id.'_label' ) ];
240
- }
241
- }
242
- }
243
- }
244
-
245
- update_post_meta( $product_id, '_product_addons', $product_addons );
246
- }
247
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Product_Addons
5
+ */
6
+ class WCML_Product_Addons {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * WCML_Product_Addons constructor.
15
+ */
16
+ function __construct( &$sitepress ) {
17
+ $this->sitepress = $sitepress;
18
+ add_filter( 'get_product_addons_product_terms', array( $this, 'addons_product_terms' ) );
19
+ add_filter( 'get_product_addons_fields', array( $this, 'product_addons_filter' ), 10, 1 );
20
+
21
+ add_action( 'updated_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
22
+ add_action( 'added_post_meta', array( $this, 'register_addons_strings' ), 10, 4 );
23
+ add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
24
+
25
+ global $pagenow;
26
+ if ( 'edit.php' === $pagenow &&
27
+ isset( $_GET['post_type'] ) &&
28
+ 'product' === $_GET['post_type'] &&
29
+ isset( $_GET['page'] ) &&
30
+ 'global_addons' === $_GET['page'] &&
31
+ ! isset( $_GET['edit'] )
32
+ ) {
33
+ add_action( 'admin_notices', array( $this, 'inf_translate_strings' ) );
34
+ }
35
+
36
+ add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
37
+
38
+ if ( is_admin() ) {
39
+
40
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
41
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 3 );
42
+ add_action( 'wcml_update_extra_fields', array( $this, 'addons_update' ), 10, 3 );
43
+ }
44
+ }
45
+
46
+ /**
47
+ * @param $meta_id
48
+ * @param $id
49
+ * @param $meta_key
50
+ * @param $addons
51
+ */
52
+ function register_addons_strings( $meta_id, $id, $meta_key, $addons ) {
53
+ if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $id ) ) {
54
+ foreach ( $addons as $addon ) {
55
+ //register name
56
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name', $addon['name'] );
57
+ //register description
58
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description', $addon['description'] );
59
+ //register options labels
60
+ foreach ( $addon['options'] as $key => $option ) {
61
+ do_action( 'wpml_register_single_string', 'wc_product_addons_strings', $id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $key, $option['label'] );
62
+ }
63
+ }
64
+ }
65
+ }
66
+
67
+ /**
68
+ * @param $null
69
+ * @param $object_id
70
+ * @param $meta_key
71
+ * @param $single
72
+ *
73
+ * @return array
74
+ */
75
+ function translate_addons_strings( $null, $object_id, $meta_key, $single ) {
76
+
77
+ if ( '_product_addons' === $meta_key && 'global_product_addon' === get_post_type( $object_id ) ) {
78
+
79
+ remove_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
80
+ $addons = get_post_meta( $object_id, $meta_key, true );
81
+ add_filter( 'get_post_metadata', array( $this, 'translate_addons_strings' ), 10, 4 );
82
+
83
+ if ( is_array( $addons ) ) {
84
+ foreach ( $addons as $key => $addon ) {
85
+ //register name
86
+ $addons[ $key ]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_name' );
87
+ //register description
88
+ $addons[ $key ]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_description' );
89
+ //register options labels
90
+ foreach ( $addon['options'] as $opt_key => $option ) {
91
+ $addons[ $key ]['options'][ $opt_key ]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id . '_addon_' . $addon['type'] . '_' . $addon['position'] . '_option_label_' . $opt_key );
92
+ }
93
+ }
94
+ }
95
+
96
+ return array( 0 => $addons );
97
+ }
98
+
99
+ return $null;
100
+
101
+ }
102
+
103
+ /**
104
+ * @param $addons
105
+ *
106
+ * @return mixed
107
+ */
108
+ function product_addons_filter( $addons ) {
109
+
110
+ foreach ( $addons as $add_id => $addon ) {
111
+ foreach ( $addon['options'] as $key => $option ) {
112
+ //price filter
113
+ $addons[ $add_id ]['options'][ $key ]['price'] = apply_filters( 'wcml_raw_price_amount', $option['price'] );
114
+ }
115
+ }
116
+
117
+ return $addons;
118
+ }
119
+
120
+
121
+ /**
122
+ * @param $product_terms
123
+ *
124
+ * @return array
125
+ */
126
+ function addons_product_terms( $product_terms ) {
127
+ foreach ( $product_terms as $key => $product_term ) {
128
+ $product_terms[ $key ] = apply_filters( 'translate_object_id', $product_term, 'product_cat', true, $this->sitepress->get_default_language() );
129
+ }
130
+
131
+ return $product_terms;
132
+ }
133
+
134
+ function inf_translate_strings() {
135
+ $message = '<div><p class="icl_cyan_box">';
136
+ $message .= sprintf( __( 'To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual' ), admin_url( 'admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings' ) );
137
+ $message .= '</p></div>';
138
+
139
+ echo $message;
140
+ }
141
+
142
+ /**
143
+ * @param $obj
144
+ * @param $product_id
145
+ * @param $data
146
+ */
147
+ function custom_box_html( $obj, $product_id, $data ) {
148
+
149
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
150
+
151
+ if ( ! empty( $product_addons ) ) {
152
+ foreach ( $product_addons as $addon_id => $product_addon ) {
153
+
154
+ $addons_section = new WPML_Editor_UI_Field_Section( sprintf( __( 'Product Add-ons Group "%s"', 'woocommerce-multilingual' ), $product_addon['name'] ) );
155
+
156
+ $group = new WPML_Editor_UI_Field_Group( '' , true );
157
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_name', __( 'Name', 'woocommerce-multilingual' ), $data, false );
158
+ $group->add_field( $addon_field );
159
+ $addon_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_description' , __( 'Description', 'woocommerce-multilingual' ), $data, false );
160
+ $group->add_field( $addon_field );
161
+
162
+ $addons_section->add_field( $group );
163
+
164
+ if ( ! empty( $product_addon['options'] ) ) {
165
+
166
+ $labels_group = new WPML_Editor_UI_Field_Group( __( 'Options', 'woocommerce-multilingual' ) , true );
167
+
168
+ foreach ( $product_addon['options'] as $option_id => $option ) {
169
+ $option_label_field = new WPML_Editor_UI_Single_Line_Field( 'addon_'.$addon_id.'_option_'.$option_id.'_label', __( 'Label', 'woocommerce-multilingual' ), $data, false );
170
+ $labels_group->add_field( $option_label_field );
171
+ }
172
+ $addons_section->add_field( $labels_group );
173
+ }
174
+ $obj->add_field( $addons_section );
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * @param $data
181
+ * @param $product_id
182
+ * @param $translation
183
+ *
184
+ * @return mixed
185
+ */
186
+ function custom_box_html_data( $data, $product_id, $translation ) {
187
+
188
+ $product_addons = maybe_unserialize( get_post_meta( $product_id, '_product_addons', true ) );
189
+
190
+ if ( ! empty( $product_addons ) ) {
191
+ foreach ( $product_addons as $addon_id => $product_addon ) {
192
+ $data[ 'addon_' . $addon_id . '_name' ] = array( 'original' => $product_addon['name'] );
193
+ $data[ 'addon_' . $addon_id . '_description' ] = array( 'original' => $product_addon['description'] );
194
+ if ( ! empty( $product_addon['options'] ) ) {
195
+ foreach ( $product_addon['options'] as $option_id => $option ) {
196
+ $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ] = array( 'original' => $option['label'] );
197
+ }
198
+ }
199
+ }
200
+
201
+ if ( $translation ) {
202
+ $transalted_product_addons = maybe_unserialize( get_post_meta( $translation->ID, '_product_addons', true ) );
203
+ if ( ! empty( $transalted_product_addons ) ) {
204
+ foreach ( $transalted_product_addons as $addon_id => $transalted_product_addon ) {
205
+ $data[ 'addon_' . $addon_id . '_name' ]['translation'] = $transalted_product_addon['name'];
206
+ $data[ 'addon_' . $addon_id . '_description' ]['translation'] = $transalted_product_addon['description'];
207
+ if ( ! empty( $transalted_product_addon['options'] ) ) {
208
+ foreach ( $transalted_product_addon['options'] as $option_id => $option ) {
209
+ $data[ 'addon_' . $addon_id . '_option_' . $option_id . '_label' ]['translation'] = $option['label'];
210
+ }
211
+ }
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ return $data;
218
+ }
219
+
220
+ /**
221
+ * @param $original_product_id
222
+ * @param $product_id
223
+ * @param $data
224
+ */
225
+ function addons_update( $original_product_id, $product_id, $data ) {
226
+
227
+ $product_addons = maybe_unserialize( get_post_meta( $original_product_id, '_product_addons', true ) );
228
+
229
+ if ( ! empty( $product_addons ) ) {
230
+
231
+ foreach ( $product_addons as $addon_id => $product_addon ) {
232
+
233
+ $product_addons[ $addon_id ]['name'] = $data[ md5( 'addon_' . $addon_id . '_name' ) ];
234
+ $product_addons[ $addon_id ]['description'] = $data[ md5( 'addon_' . $addon_id . '_description' ) ];
235
+
236
+ if ( ! empty( $product_addon['options'] ) ) {
237
+
238
+ foreach ( $product_addon['options'] as $option_id => $option ) {
239
+ $product_addons[ $addon_id ]['options'][ $option_id ]['label'] = $data[ md5( 'addon_'.$addon_id.'_option_'.$option_id.'_label' ) ];
240
+ }
241
+ }
242
+ }
243
+ }
244
+
245
+ update_post_meta( $product_id, '_product_addons', $product_addons );
246
+ }
247
+ }
compatibility/class-wcml-product-bundles.php CHANGED
@@ -1,409 +1,409 @@
1
- <?php
2
- class WCML_Product_Bundles{
3
-
4
- /**
5
- * @var WPML_Element_Translation_Package
6
- */
7
- var $tp;
8
-
9
- /**
10
- * @var SitePress
11
- */
12
- private $sitepress;
13
-
14
- /**
15
- * @var woocommerce_wpml
16
- */
17
- private $woocommerce_wpml;
18
-
19
- /**
20
- * WCML_Product_Bundles constructor.
21
- */
22
- function __construct( &$sitepress, &$woocommerce_wpml ){
23
- $this->sitepress = $sitepress;
24
- $this->woocommerce_wpml = $woocommerce_wpml;
25
-
26
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
27
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
28
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
29
- add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 );
30
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
31
- add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
32
-
33
- if( version_compare( WCML_VERSION, '3.7.2', '>' ) ){
34
- add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 );
35
- }
36
-
37
- if( is_admin() ){
38
- $this->tp = new WPML_Element_Translation_Package();
39
-
40
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
41
- add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
42
-
43
- }
44
-
45
-
46
- }
47
-
48
- function make__bundle_data_not_translatable_by_default( $wpml_config_array ){
49
-
50
- if( isset( $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ) ){
51
- $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] =
52
- str_replace(
53
- '<custom-field action="translate">_bundle_data</custom-field>',
54
- '<custom-field action="nothing">_bundle_data</custom-field>',
55
- $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] );
56
- }
57
-
58
- return $wpml_config_array;
59
- }
60
-
61
- // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
62
- function sync_bundled_ids( $original_product_id, $trnsl_product_id ){
63
-
64
- $bundle_data_array = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
65
- if( $bundle_data_array ){
66
- $lang = $this->sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
67
- $tr_bundle_meta = maybe_unserialize( get_post_meta( $trnsl_product_id, '_bundle_data', true ) );
68
- $tr_ids = array();
69
- $i = 2;
70
- foreach( $bundle_data_array as $id => $bundle_data ){
71
- $tr_id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $lang );
72
- if( isset( $tr_bundle_meta[ $tr_id ] ) ){
73
- $bundle_key = $tr_id.'_'.$i;
74
- $i++;
75
- }else{
76
- $bundle_key = $tr_id;
77
- }
78
- $tr_bundle[ $bundle_key ] = $bundle_data;
79
- $tr_bundle[ $bundle_key ][ 'product_id' ] = $tr_id;
80
- if( isset( $bundle_data[ 'product_title' ] ) ){
81
- if( $bundle_data[ 'override_title' ] == 'yes' ){
82
- $tr_bundle[ $bundle_key ][ 'product_title' ] =
83
- isset( $tr_bundle_meta[ $bundle_key ][ 'product_title' ] ) ?
84
- $tr_bundle_meta[ $bundle_key ][ 'product_title' ] :
85
- '';
86
- }else{
87
- $tr_title= get_the_title( $tr_id );
88
- $tr_bundle[ $bundle_key ][ 'product_title' ] = $tr_title;
89
- }
90
- }
91
- if( isset( $bundle_data[ 'product_description' ] ) ){
92
- if( $bundle_data[ 'override_description' ] == 'yes' ){
93
- $tr_bundle[ $bundle_key ][ 'product_description' ] =
94
- isset( $tr_bundle_meta[ $bundle_key ][ 'product_description' ] ) ?
95
- $tr_bundle_meta[ $bundle_key ][ 'product_description' ] :
96
- '';
97
- }else{
98
- $tr_prod = get_post( $tr_id );
99
- $tr_desc = $tr_prod->post_excerpt;
100
- $tr_bundle[ $bundle_key ][ 'product_description' ] = $tr_desc;
101
- }
102
- }
103
- if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
104
- $allowed_var = $bundle_data[ 'allowed_variations' ];
105
- foreach( $allowed_var as $key => $var_id ){
106
- $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
107
- $tr_bundle[ $bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
108
- }
109
- }
110
- if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
111
- foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
112
-
113
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
114
- if( $term_id ){
115
- // Global Attribute
116
- $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
117
- $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
118
- $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
119
- }else{
120
- // Custom Attribute
121
- $args = array(
122
- 'post_type' => 'product_variation',
123
- 'meta_key' => 'attribute_'.$tax,
124
- 'meta_value' => $term_slug,
125
- 'meta_compare' => '='
126
- );
127
- $variationloop = new WP_Query( $args );
128
- while ( $variationloop->have_posts() ) : $variationloop->the_post();
129
- $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
130
- $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
131
- $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
132
- endwhile;
133
- }
134
- }
135
- }
136
- }
137
- update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
138
-
139
- return $tr_bundle;
140
- }
141
-
142
- }
143
- // Update Bundled products title and descritpion after saving the translation
144
- function bundle_update( $original_product_id, $tr_id, $data, $lang ){
145
-
146
- $tr_bundle_data = array();
147
- $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
148
-
149
- $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
150
-
151
- if( empty( $bundle_data ) ){
152
- return;
153
- }
154
-
155
- $product_bundles = array_keys( $bundle_data );
156
-
157
- foreach ( $product_bundles as $key => $bundle_id ) {
158
- $bundle_product_tr_id = apply_filters( 'translate_object_id', $bundle_id, get_post_type( $bundle_id ), true, $lang );
159
- if( isset( $tr_bundle_data[ $bundle_product_tr_id ] ) ){
160
- $tr_bundle_data[ $bundle_product_tr_id ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_id.'_title' ) ];
161
- $tr_bundle_data[ $bundle_product_tr_id ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_id.'_desc' ) ];
162
- }
163
- }
164
- update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
165
-
166
- return $tr_bundle_data;
167
- }
168
-
169
- // Add Bundles Box to WCML Translation GUI
170
- function custom_box_html( $obj, $product_id, $data ){
171
-
172
- $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
173
-
174
- if( empty( $product_bundles ) || $product_bundles == false ){
175
- return false;
176
- }
177
-
178
- $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
179
- end( $product_bundles );
180
- $last_key = key( $product_bundles );
181
- $divider = true;
182
- $flag = false;
183
-
184
- foreach ( $product_bundles as $bundle_id => $product_bundle ) {
185
- $add_group = false;
186
- if( $bundle_id == $last_key ){
187
- $divider = false;
188
- }
189
-
190
- $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
191
-
192
- if( $product_bundle[ 'override_title' ] == 'yes' ) {
193
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
194
- 'bundle_' . $bundle_id . '_title',
195
- __( 'Name', 'woocommerce-multilingual' ),
196
- $data,
197
- false
198
- );
199
- $group->add_field( $bundle_field );
200
- $add_group = true;
201
- }
202
-
203
- if( $product_bundle[ 'override_description' ] == 'yes' ){
204
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
205
- 'bundle_'.$bundle_id.'_desc' ,
206
- __( 'Description', 'woocommerce-multilingual' ),
207
- $data,
208
- false
209
- );
210
- $group->add_field( $bundle_field );
211
- $add_group = true;
212
- }
213
-
214
- if( $add_group ){
215
- $bundles_section->add_field( $group );
216
- $flag = true;
217
- }
218
- }
219
-
220
- if( $flag ){
221
- $obj->add_field( $bundles_section );
222
- }
223
- }
224
-
225
-
226
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
227
- $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
228
-
229
- if( $translation ) {
230
- $tr_product_id = $translation->ID;
231
- $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
232
- }
233
-
234
- if( empty( $bundle_data ) || $bundle_data == false ){
235
- return $data;
236
- }
237
-
238
- $product_bundles = array_keys( $bundle_data );
239
-
240
- foreach ( $product_bundles as $bundle_id ) {
241
-
242
- $curr_bundle_id = apply_filters( 'translate_object_id', $bundle_id, 'product', false, $lang );
243
-
244
- if( $bundle_data[ $bundle_id ][ 'override_title' ] == 'yes' ){
245
- $data[ 'bundle_'.$bundle_id.'_title' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_title' ] );
246
- if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_title' ] ) ){
247
- $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_title' ];
248
- }else{
249
- $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = '';
250
- }
251
- }
252
-
253
- if( $bundle_data[ $bundle_id ][ 'override_description' ] == 'yes' ){
254
- $data[ 'bundle_'.$bundle_id.'_desc' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_description' ] );
255
- if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_description' ] ) ){
256
- $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_description' ];
257
- }else{
258
- $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = '';
259
- }
260
- }
261
- }
262
-
263
- return $data;
264
- }
265
-
266
- function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
267
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
268
- $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
269
- if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
270
- $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
271
- $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
272
- if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
273
- $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
274
- $remapped_bundled_item_ids = array();
275
- foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
276
- $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
277
- }
278
- $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
279
- if ( isset( $cart_item[ 'stamp' ] ) ) {
280
- $new_stamp = array();
281
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
282
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
283
- }
284
- $cart_item[ 'stamp' ] = $new_stamp;
285
- }
286
- }
287
- }
288
- }
289
- if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
290
- $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
291
- if (
292
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
293
- isset( $cart_item[ 'bundled_item_id' ] ) &&
294
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
295
- ) {
296
- $old_id = $cart_item[ 'bundled_item_id' ];
297
- $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
298
- $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
299
- if ( isset( $cart_item[ 'stamp' ] ) ) {
300
- $new_stamp = array();
301
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
302
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
303
- }
304
- $cart_item[ 'stamp' ] = $new_stamp;
305
- }
306
- }
307
- }
308
-
309
- return $cart_item;
310
- }
311
-
312
- function resync_bundle_clean( $cart ) {
313
- foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
314
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
315
- if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
316
- unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
317
- }
318
- }
319
- }
320
- }
321
-
322
- function append_bundle_data_translation_package( $package, $post ){
323
-
324
- if( $post->post_type == 'product' ) {
325
-
326
- $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
327
-
328
- if( $bundle_data ){
329
-
330
- $fields = array( 'title', 'description' );
331
-
332
- foreach( $bundle_data as $product ){
333
-
334
- foreach( $fields as $field ) {
335
- if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
336
-
337
- $package[ 'contents' ][ 'product_bundles:' . $product['product_id'] . ':' . $field ] = array(
338
- 'translate' => 1,
339
- 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
340
- 'format' => 'base64'
341
- );
342
-
343
- }
344
- }
345
- }
346
- }
347
- }
348
-
349
- return $package;
350
-
351
- }
352
-
353
- function save_bundle_data_translation( $post_id, $data, $job ){
354
-
355
- remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
356
-
357
- $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
358
-
359
- $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
360
-
361
- $translated_bundle_pieces = array();
362
-
363
- foreach( $data as $value){
364
-
365
- if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
366
-
367
- $product_id = $matches[1];
368
- $field = $matches[2];
369
-
370
- $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
371
-
372
- $products_translation_map[ $translated_product_id ] = $product_id;
373
-
374
- if( $translated_product_id ){
375
-
376
- $translated_bundle_pieces[ $translated_product_id ][ $field ] = $value[ 'data' ];
377
-
378
- }
379
- }
380
- }
381
-
382
- if( $translated_bundle_pieces ){
383
- foreach( $translated_bundle_pieces as $product_id => $piece ){
384
-
385
- if( isset( $products_translation_map[ $product_id ] ) ) {
386
-
387
- $bundle_data[ $product_id ] = array(
388
-
389
- 'product_id' => $product_id,
390
- 'hide_thumbnail' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'hide_thumbnail' ],
391
- 'override_title' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_title' ],
392
- 'product_title' => isset( $piece[ 'title' ] ) ? $piece[ 'title' ] : '',
393
- 'override_description' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_description' ],
394
- 'product_description' => isset( $piece[ 'description' ] ) ? $piece[ 'description' ] : '',
395
- 'optional' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'optional' ],
396
- 'bundle_quantity' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity' ],
397
- 'bundle_quantity_max' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity_max' ],
398
- 'bundle_discount' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_discount' ],
399
- 'visibility' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'visibility' ],
400
-
401
- );
402
- }
403
- }
404
- }
405
-
406
- update_post_meta( $post_id, '_bundle_data', $bundle_data );
407
-
408
- }
409
  }
1
+ <?php
2
+ class WCML_Product_Bundles{
3
+
4
+ /**
5
+ * @var WPML_Element_Translation_Package
6
+ */
7
+ var $tp;
8
+
9
+ /**
10
+ * @var SitePress
11
+ */
12
+ private $sitepress;
13
+
14
+ /**
15
+ * @var woocommerce_wpml
16
+ */
17
+ private $woocommerce_wpml;
18
+
19
+ /**
20
+ * WCML_Product_Bundles constructor.
21
+ */
22
+ function __construct( &$sitepress, &$woocommerce_wpml ){
23
+ $this->sitepress = $sitepress;
24
+ $this->woocommerce_wpml = $woocommerce_wpml;
25
+
26
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
27
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
28
+ add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
29
+ add_action( 'wcml_update_extra_fields', array( $this, 'bundle_update' ), 10, 4 );
30
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle' ), 5, 3 );
31
+ add_filter( 'woocommerce_cart_loaded_from_session', array( $this, 'resync_bundle_clean' ), 10 );
32
+
33
+ if( version_compare( WCML_VERSION, '3.7.2', '>' ) ){
34
+ add_filter( 'option_wpml_config_files_arr', array( $this, 'make__bundle_data_not_translatable_by_default' ), 0 );
35
+ }
36
+
37
+ if( is_admin() ){
38
+ $this->tp = new WPML_Element_Translation_Package();
39
+
40
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
41
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
42
+
43
+ }
44
+
45
+
46
+ }
47
+
48
+ function make__bundle_data_not_translatable_by_default( $wpml_config_array ){
49
+
50
+ if( isset( $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] ) ){
51
+ $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] =
52
+ str_replace(
53
+ '<custom-field action="translate">_bundle_data</custom-field>',
54
+ '<custom-field action="nothing">_bundle_data</custom-field>',
55
+ $wpml_config_array->plugins[ 'WooCommerce Product Bundles' ] );
56
+ }
57
+
58
+ return $wpml_config_array;
59
+ }
60
+
61
+ // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
62
+ function sync_bundled_ids( $original_product_id, $trnsl_product_id ){
63
+
64
+ $bundle_data_array = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
65
+ if( $bundle_data_array ){
66
+ $lang = $this->sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
67
+ $tr_bundle_meta = maybe_unserialize( get_post_meta( $trnsl_product_id, '_bundle_data', true ) );
68
+ $tr_ids = array();
69
+ $i = 2;
70
+ foreach( $bundle_data_array as $id => $bundle_data ){
71
+ $tr_id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $lang );
72
+ if( isset( $tr_bundle_meta[ $tr_id ] ) ){
73
+ $bundle_key = $tr_id.'_'.$i;
74
+ $i++;
75
+ }else{
76
+ $bundle_key = $tr_id;
77
+ }
78
+ $tr_bundle[ $bundle_key ] = $bundle_data;
79
+ $tr_bundle[ $bundle_key ][ 'product_id' ] = $tr_id;
80
+ if( isset( $bundle_data[ 'product_title' ] ) ){
81
+ if( $bundle_data[ 'override_title' ] == 'yes' ){
82
+ $tr_bundle[ $bundle_key ][ 'product_title' ] =
83
+ isset( $tr_bundle_meta[ $bundle_key ][ 'product_title' ] ) ?
84
+ $tr_bundle_meta[ $bundle_key ][ 'product_title' ] :
85
+ '';
86
+ }else{
87
+ $tr_title= get_the_title( $tr_id );
88
+ $tr_bundle[ $bundle_key ][ 'product_title' ] = $tr_title;
89
+ }
90
+ }
91
+ if( isset( $bundle_data[ 'product_description' ] ) ){
92
+ if( $bundle_data[ 'override_description' ] == 'yes' ){
93
+ $tr_bundle[ $bundle_key ][ 'product_description' ] =
94
+ isset( $tr_bundle_meta[ $bundle_key ][ 'product_description' ] ) ?
95
+ $tr_bundle_meta[ $bundle_key ][ 'product_description' ] :
96
+ '';
97
+ }else{
98
+ $tr_prod = get_post( $tr_id );
99
+ $tr_desc = $tr_prod->post_excerpt;
100
+ $tr_bundle[ $bundle_key ][ 'product_description' ] = $tr_desc;
101
+ }
102
+ }
103
+ if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
104
+ $allowed_var = $bundle_data[ 'allowed_variations' ];
105
+ foreach( $allowed_var as $key => $var_id ){
106
+ $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
107
+ $tr_bundle[ $bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
108
+ }
109
+ }
110
+ if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
111
+ foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
112
+
113
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
114
+ if( $term_id ){
115
+ // Global Attribute
116
+ $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
117
+ $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
118
+ $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
119
+ }else{
120
+ // Custom Attribute
121
+ $args = array(
122
+ 'post_type' => 'product_variation',
123
+ 'meta_key' => 'attribute_'.$tax,
124
+ 'meta_value' => $term_slug,
125
+ 'meta_compare' => '='
126
+ );
127
+ $variationloop = new WP_Query( $args );
128
+ while ( $variationloop->have_posts() ) : $variationloop->the_post();
129
+ $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
130
+ $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
131
+ $tr_bundle[ $bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
132
+ endwhile;
133
+ }
134
+ }
135
+ }
136
+ }
137
+ update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
138
+
139
+ return $tr_bundle;
140
+ }
141
+
142
+ }
143
+ // Update Bundled products title and descritpion after saving the translation
144
+ function bundle_update( $original_product_id, $tr_id, $data, $lang ){
145
+
146
+ $tr_bundle_data = array();
147
+ $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
148
+
149
+ $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
150
+
151
+ if( empty( $bundle_data ) ){
152
+ return;
153
+ }
154
+
155
+ $product_bundles = array_keys( $bundle_data );
156
+
157
+ foreach ( $product_bundles as $key => $bundle_id ) {
158
+ $bundle_product_tr_id = apply_filters( 'translate_object_id', $bundle_id, get_post_type( $bundle_id ), true, $lang );
159
+ if( isset( $tr_bundle_data[ $bundle_product_tr_id ] ) ){
160
+ $tr_bundle_data[ $bundle_product_tr_id ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_id.'_title' ) ];
161
+ $tr_bundle_data[ $bundle_product_tr_id ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_id.'_desc' ) ];
162
+ }
163
+ }
164
+ update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
165
+
166
+ return $tr_bundle_data;
167
+ }
168
+
169
+ // Add Bundles Box to WCML Translation GUI
170
+ function custom_box_html( $obj, $product_id, $data ){
171
+
172
+ $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
173
+
174
+ if( empty( $product_bundles ) || $product_bundles == false ){
175
+ return false;
176
+ }
177
+
178
+ $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
179
+ end( $product_bundles );
180
+ $last_key = key( $product_bundles );
181
+ $divider = true;
182
+ $flag = false;
183
+
184
+ foreach ( $product_bundles as $bundle_id => $product_bundle ) {
185
+ $add_group = false;
186
+ if( $bundle_id == $last_key ){
187
+ $divider = false;
188
+ }
189
+
190
+ $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
191
+
192
+ if( $product_bundle[ 'override_title' ] == 'yes' ) {
193
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
194
+ 'bundle_' . $bundle_id . '_title',
195
+ __( 'Name', 'woocommerce-multilingual' ),
196
+ $data,
197
+ false
198
+ );
199
+ $group->add_field( $bundle_field );
200
+ $add_group = true;
201
+ }
202
+
203
+ if( $product_bundle[ 'override_description' ] == 'yes' ){
204
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
205
+ 'bundle_'.$bundle_id.'_desc' ,
206
+ __( 'Description', 'woocommerce-multilingual' ),
207
+ $data,
208
+ false
209
+ );
210
+ $group->add_field( $bundle_field );
211
+ $add_group = true;
212
+ }
213
+
214
+ if( $add_group ){
215
+ $bundles_section->add_field( $group );
216
+ $flag = true;
217
+ }
218
+ }
219
+
220
+ if( $flag ){
221
+ $obj->add_field( $bundles_section );
222
+ }
223
+ }
224
+
225
+
226
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
227
+ $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
228
+
229
+ if( $translation ) {
230
+ $tr_product_id = $translation->ID;
231
+ $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
232
+ }
233
+
234
+ if( empty( $bundle_data ) || $bundle_data == false ){
235
+ return $data;
236
+ }
237
+
238
+ $product_bundles = array_keys( $bundle_data );
239
+
240
+ foreach ( $product_bundles as $bundle_id ) {
241
+
242
+ $curr_bundle_id = apply_filters( 'translate_object_id', $bundle_id, 'product', false, $lang );
243
+
244
+ if( $bundle_data[ $bundle_id ][ 'override_title' ] == 'yes' ){
245
+ $data[ 'bundle_'.$bundle_id.'_title' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_title' ] );
246
+ if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_title' ] ) ){
247
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_title' ];
248
+ }else{
249
+ $data[ 'bundle_'.$bundle_id.'_title' ][ 'translation' ] = '';
250
+ }
251
+ }
252
+
253
+ if( $bundle_data[ $bundle_id ][ 'override_description' ] == 'yes' ){
254
+ $data[ 'bundle_'.$bundle_id.'_desc' ] = array( 'original' => $bundle_data[ $bundle_id ][ 'product_description' ] );
255
+ if( isset( $tr_bundle_data[ $curr_bundle_id ][ 'override_description' ] ) ){
256
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = $tr_bundle_data[ $curr_bundle_id ][ 'product_description' ];
257
+ }else{
258
+ $data[ 'bundle_'.$bundle_id.'_desc' ][ 'translation' ] = '';
259
+ }
260
+ }
261
+ }
262
+
263
+ return $data;
264
+ }
265
+
266
+ function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
267
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
268
+ $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
269
+ if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
270
+ $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
271
+ $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
272
+ if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
273
+ $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
274
+ $remapped_bundled_item_ids = array();
275
+ foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
276
+ $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
277
+ }
278
+ $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
279
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
280
+ $new_stamp = array();
281
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
282
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
283
+ }
284
+ $cart_item[ 'stamp' ] = $new_stamp;
285
+ }
286
+ }
287
+ }
288
+ }
289
+ if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
290
+ $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
291
+ if (
292
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
293
+ isset( $cart_item[ 'bundled_item_id' ] ) &&
294
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
295
+ ) {
296
+ $old_id = $cart_item[ 'bundled_item_id' ];
297
+ $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
298
+ $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
299
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
300
+ $new_stamp = array();
301
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
302
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
303
+ }
304
+ $cart_item[ 'stamp' ] = $new_stamp;
305
+ }
306
+ }
307
+ }
308
+
309
+ return $cart_item;
310
+ }
311
+
312
+ function resync_bundle_clean( $cart ) {
313
+ foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
314
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
315
+ if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
316
+ unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
317
+ }
318
+ }
319
+ }
320
+ }
321
+
322
+ function append_bundle_data_translation_package( $package, $post ){
323
+
324
+ if( $post->post_type == 'product' ) {
325
+
326
+ $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
327
+
328
+ if( $bundle_data ){
329
+
330
+ $fields = array( 'title', 'description' );
331
+
332
+ foreach( $bundle_data as $product ){
333
+
334
+ foreach( $fields as $field ) {
335
+ if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
336
+
337
+ $package[ 'contents' ][ 'product_bundles:' . $product['product_id'] . ':' . $field ] = array(
338
+ 'translate' => 1,
339
+ 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
340
+ 'format' => 'base64'
341
+ );
342
+
343
+ }
344
+ }
345
+ }
346
+ }
347
+ }
348
+
349
+ return $package;
350
+
351
+ }
352
+
353
+ function save_bundle_data_translation( $post_id, $data, $job ){
354
+
355
+ remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
356
+
357
+ $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
358
+
359
+ $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
360
+
361
+ $translated_bundle_pieces = array();
362
+
363
+ foreach( $data as $value){
364
+
365
+ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
366
+
367
+ $product_id = $matches[1];
368
+ $field = $matches[2];
369
+
370
+ $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
371
+
372
+ $products_translation_map[ $translated_product_id ] = $product_id;
373
+
374
+ if( $translated_product_id ){
375
+
376
+ $translated_bundle_pieces[ $translated_product_id ][ $field ] = $value[ 'data' ];
377
+
378
+ }
379
+ }
380
+ }
381
+
382
+ if( $translated_bundle_pieces ){
383
+ foreach( $translated_bundle_pieces as $product_id => $piece ){
384
+
385
+ if( isset( $products_translation_map[ $product_id ] ) ) {
386
+
387
+ $bundle_data[ $product_id ] = array(
388
+
389
+ 'product_id' => $product_id,
390
+ 'hide_thumbnail' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'hide_thumbnail' ],
391
+ 'override_title' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_title' ],
392
+ 'product_title' => isset( $piece[ 'title' ] ) ? $piece[ 'title' ] : '',
393
+ 'override_description' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'override_description' ],
394
+ 'product_description' => isset( $piece[ 'description' ] ) ? $piece[ 'description' ] : '',
395
+ 'optional' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'optional' ],
396
+ 'bundle_quantity' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity' ],
397
+ 'bundle_quantity_max' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_quantity_max' ],
398
+ 'bundle_discount' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'bundle_discount' ],
399
+ 'visibility' => $bundle_data_original[ $products_translation_map[ $product_id ] ][ 'visibility' ],
400
+
401
+ );
402
+ }
403
+ }
404
+ }
405
+
406
+ update_post_meta( $post_id, '_bundle_data', $bundle_data );
407
+
408
+ }
409
  }
compatibility/class-wcml-sensei.php CHANGED
@@ -1,231 +1,231 @@
1
- <?php
2
-
3
- class WCML_sensei{
4
-
5
- function __construct(){
6
- global $sitepress;
7
- add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
- add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
-
10
- add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
- add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
- add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
- add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
-
15
- add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
-
17
- if( is_admin() &&
18
- (
19
- ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
- ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
- ) ){
22
- remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
- }
24
-
25
- }
26
-
27
- function save_post_actions( $post_id, $post ){
28
- global $sitepress;
29
-
30
- // skip not related post types
31
- if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
- return;
33
- }
34
- // skip auto-drafts
35
- if ( $post->post_status == 'auto-draft' ) {
36
- return;
37
- }
38
- // skip autosave
39
- if ( isset( $_POST[ 'autosave' ] ) ) {
40
- return;
41
- }
42
-
43
- if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
- $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
- }
46
-
47
-
48
- // sync fields from original
49
- $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
- $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
-
52
- if ( !empty( $translations ) ) {
53
- $original_post_id = false;
54
- foreach ( $translations as $t ) {
55
- if ( $t->original ) {
56
- $original_post_id = $t->element_id;
57
- break;
58
- }
59
- }
60
-
61
- if ( $post_id != $original_post_id ) {
62
- $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
- } else {
64
- foreach ( $translations as $t ) {
65
- if ( $original_post_id != $t->element_id ) {
66
- $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
- }
68
- }
69
- }
70
- }
71
-
72
- }
73
-
74
-
75
- function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
- global $sitepress;
77
-
78
- $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
- if( $post_type == 'quiz' ){
80
-
81
- //sync quiz lesson
82
- $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
-
84
- if( $lesson_id ){
85
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
-
87
- if( !is_null( $tr_lesson_id ) ){
88
- update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
- }
90
- }else{
91
- delete_post_meta( $post_id, '_quiz_lesson' );
92
- }
93
-
94
- } elseif( $post_type == 'lesson' ){
95
- //sync lesson course
96
- $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
-
98
- if( $course_id ){
99
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
-
101
- if( !is_null( $tr_course_id ) ){
102
- update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
- }
104
- }else{
105
- delete_post_meta( $post_id, '_lesson_course' );
106
- }
107
-
108
- //sync lesson prerequisite
109
- $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
-
111
- if( $lesson_id ){
112
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
-
114
- if( !is_null( $tr_lesson_id ) ){
115
- update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
- }
117
- }else{
118
- delete_post_meta( $post_id, '_lesson_prerequisite' );
119
- }
120
-
121
- }else{
122
-
123
- //sync course woocommerce_product
124
- $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
-
126
- if( $product_id ){
127
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
-
129
- if( !is_null( $tr_product_id ) ){
130
- update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
- }
132
- }else{
133
- delete_post_meta( $post_id, '_course_woocommerce_product' );
134
- }
135
-
136
- //sync course prerequisite
137
- $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
-
139
- if( $course_id ){
140
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
-
142
- if( !is_null( $tr_course_id ) ){
143
- update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
- }
145
- }else{
146
- delete_post_meta( $post_id, '_course_prerequisite' );
147
- }
148
-
149
- }
150
-
151
- }
152
-
153
- function log_activity_after ( $args, $data, $comment_id = false ){
154
- global $sitepress;
155
-
156
- if( !$comment_id ){
157
- return false;
158
- }
159
-
160
- $comment_post_id = $data['comment_post_ID'];
161
- $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
- $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
-
164
- foreach($translations as $translation){
165
-
166
- if( $comment_post_id != $translation->element_id ){
167
- $data['comment_post_ID'] = $translation->element_id;
168
-
169
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
-
171
- $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
- if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
- $data['comment_ID'] = $tr_comment_id;
174
- $tr_comment_id = wp_update_comment( $data );
175
- }else{
176
- $tr_comment_id = wp_insert_comment( $data );
177
- $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
- }
179
- }
180
-
181
- }
182
-
183
- }
184
-
185
- function filter_bought_product_id( $product_id, $order ){
186
-
187
- $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
-
189
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
-
191
- if( !is_null( $tr_product_id ) ){
192
- return $tr_product_id;
193
- }else{
194
- return $product_id;
195
- }
196
- }
197
-
198
- function delete_user_activity ( $comment_id ){
199
- global $sitepress;
200
-
201
- $comment_type = get_comment_type( $comment_id );
202
-
203
- if( strstr( $comment_type, "sensei" ) ){
204
-
205
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
- $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
-
208
- remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
- foreach ( $translations as $translation ){
210
- if( $comment_id != $translation->element_id ){
211
- wp_delete_comment( $translation->element_id, true );
212
- }
213
- }
214
-
215
- }
216
-
217
-
218
- }
219
-
220
- function pre_get_comments($obj){
221
- global $sitepress;
222
-
223
- if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
-
225
- remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
-
227
- }
228
-
229
- }
230
-
231
- }
1
+ <?php
2
+
3
+ class WCML_sensei{
4
+
5
+ function __construct(){
6
+ global $sitepress;
7
+ add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
+ add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
+
10
+ add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
+ add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
+ add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
+ add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
+
15
+ add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
+
17
+ if( is_admin() &&
18
+ (
19
+ ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
+ ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
+ ) ){
22
+ remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
+ }
24
+
25
+ }
26
+
27
+ function save_post_actions( $post_id, $post ){
28
+ global $sitepress;
29
+
30
+ // skip not related post types
31
+ if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
+ return;
33
+ }
34
+ // skip auto-drafts
35
+ if ( $post->post_status == 'auto-draft' ) {
36
+ return;
37
+ }
38
+ // skip autosave
39
+ if ( isset( $_POST[ 'autosave' ] ) ) {
40
+ return;
41
+ }
42
+
43
+ if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
+ $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
+ }
46
+
47
+
48
+ // sync fields from original
49
+ $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
+
52
+ if ( !empty( $translations ) ) {
53
+ $original_post_id = false;
54
+ foreach ( $translations as $t ) {
55
+ if ( $t->original ) {
56
+ $original_post_id = $t->element_id;
57
+ break;
58
+ }
59
+ }
60
+
61
+ if ( $post_id != $original_post_id ) {
62
+ $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
+ } else {
64
+ foreach ( $translations as $t ) {
65
+ if ( $original_post_id != $t->element_id ) {
66
+ $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ }
73
+
74
+
75
+ function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
+ global $sitepress;
77
+
78
+ $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
+ if( $post_type == 'quiz' ){
80
+
81
+ //sync quiz lesson
82
+ $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
+
84
+ if( $lesson_id ){
85
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
+
87
+ if( !is_null( $tr_lesson_id ) ){
88
+ update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
+ }
90
+ }else{
91
+ delete_post_meta( $post_id, '_quiz_lesson' );
92
+ }
93
+
94
+ } elseif( $post_type == 'lesson' ){
95
+ //sync lesson course
96
+ $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
+
98
+ if( $course_id ){
99
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
+
101
+ if( !is_null( $tr_course_id ) ){
102
+ update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
+ }
104
+ }else{
105
+ delete_post_meta( $post_id, '_lesson_course' );
106
+ }
107
+
108
+ //sync lesson prerequisite
109
+ $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
+
111
+ if( $lesson_id ){
112
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
+
114
+ if( !is_null( $tr_lesson_id ) ){
115
+ update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
+ }
117
+ }else{
118
+ delete_post_meta( $post_id, '_lesson_prerequisite' );
119
+ }
120
+
121
+ }else{
122
+
123
+ //sync course woocommerce_product
124
+ $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
+
126
+ if( $product_id ){
127
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
+
129
+ if( !is_null( $tr_product_id ) ){
130
+ update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
+ }
132
+ }else{
133
+ delete_post_meta( $post_id, '_course_woocommerce_product' );
134
+ }
135
+
136
+ //sync course prerequisite
137
+ $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
+
139
+ if( $course_id ){
140
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
+
142
+ if( !is_null( $tr_course_id ) ){
143
+ update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
+ }
145
+ }else{
146
+ delete_post_meta( $post_id, '_course_prerequisite' );
147
+ }
148
+
149
+ }
150
+
151
+ }
152
+
153
+ function log_activity_after ( $args, $data, $comment_id = false ){
154
+ global $sitepress;
155
+
156
+ if( !$comment_id ){
157
+ return false;
158
+ }
159
+
160
+ $comment_post_id = $data['comment_post_ID'];
161
+ $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
+ $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
+
164
+ foreach($translations as $translation){
165
+
166
+ if( $comment_post_id != $translation->element_id ){
167
+ $data['comment_post_ID'] = $translation->element_id;
168
+
169
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
+
171
+ $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
+ if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
+ $data['comment_ID'] = $tr_comment_id;
174
+ $tr_comment_id = wp_update_comment( $data );
175
+ }else{
176
+ $tr_comment_id = wp_insert_comment( $data );
177
+ $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
+ }
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ function filter_bought_product_id( $product_id, $order ){
186
+
187
+ $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
+
189
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
+
191
+ if( !is_null( $tr_product_id ) ){
192
+ return $tr_product_id;
193
+ }else{
194
+ return $product_id;
195
+ }
196
+ }
197
+
198
+ function delete_user_activity ( $comment_id ){
199
+ global $sitepress;
200
+
201
+ $comment_type = get_comment_type( $comment_id );
202
+
203
+ if( strstr( $comment_type, "sensei" ) ){
204
+
205
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
+ $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
+
208
+ remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
+ foreach ( $translations as $translation ){
210
+ if( $comment_id != $translation->element_id ){
211
+ wp_delete_comment( $translation->element_id, true );
212
+ }
213
+ }
214
+
215
+ }
216
+
217
+
218
+ }
219
+
220
+ function pre_get_comments($obj){
221
+ global $sitepress;
222
+
223
+ if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
+
225
+ remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
+
227
+ }
228
+
229
+ }
230
+
231
+ }
compatibility/class-wcml-tab-manager.php CHANGED
@@ -1,628 +1,707 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Tab_Manager
5
- */
6
- class WCML_Tab_Manager {
7
- /**
8
- * @var WPML_Element_Translation_Package
9
- */
10
- public $tp;
11
-
12
- /**
13
- * @var SitePress
14
- */
15
- public $sitepress;
16
-
17
- /**
18
- * @var WooCommerce
19
- */
20
- public $woocommerce;
21
-
22
- /**
23
- * @var woocommerce_wpml
24
- */
25
- public $woocommerce_wpml;
26
-
27
- /**
28
- * @var wpdb
29
- */
30
- public $wpdb;
31
-
32
- /**
33
- * WCML_Tab_Manager constructor.
34
- *
35
- * @param $sitepress
36
- * @param $woocommerce
37
- * @param $woocommerce_wpml
38
- * @param $wpdb
39
- */
40
- function __construct( &$sitepress, &$woocommerce, &$woocommerce_wpml, &$wpdb ) {
41
- $this->sitepress = $sitepress;
42
- $this->woocommerce = $woocommerce;
43
- $this->woocommerce_wpml = $woocommerce_wpml;
44
- $this->wpdb = $wpdb;
45
- add_action( 'wcml_update_extra_fields', array( $this, 'sync_tabs' ), 10, 4 );
46
- add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
47
- add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
48
- add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
49
- add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs' ) , 10, 2 );
50
-
51
- add_filter( 'wc_tab_manager_tab_id', array( $this, 'wc_tab_manager_tab_id' ), 10, 1 );
52
-
53
- if ( version_compare( WCML_VERSION, '3.7.2', '>' ) ) {
54
- add_filter( 'option_wpml_config_files_arr', array( $this, 'make__product_tabs_not_translatable_by_default' ), 0 );
55
- }
56
-
57
- if ( is_admin() ) {
58
-
59
- $this->tp = new WPML_Element_Translation_Package;
60
-
61
- add_action( 'save_post', array( $this, 'force_set_language_information_on_product_tabs' ), 10, 2 );
62
-
63
- add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_tabs_to_translation_package' ), 10, 2 );
64
- add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
65
-
66
- }
67
-
68
- }
69
-
70
- /**
71
- * @param $wpml_config_array
72
- *
73
- * @return mixed
74
- */
75
- function make__product_tabs_not_translatable_by_default( $wpml_config_array ) {
76
-
77
- if ( isset( $wpml_config_array->plugins['WooCommerce Tab Manager'] ) ) {
78
- $wpml_config_array->plugins['WooCommerce Tab Manager'] =
79
- str_replace( '<custom-field action="translate">_product_tabs</custom-field>',
80
- '<custom-field action="nothing">_product_tabs</custom-field>',
81
- $wpml_config_array->plugins['WooCommerce Tab Manager']
82
- );
83
- }
84
-
85
- return $wpml_config_array;
86
- }
87
-
88
- /**
89
- * @param $original_product_id
90
- * @param $trnsl_product_id
91
- * @param $data
92
- * @param $lang
93
- *
94
- * @return bool
95
- */
96
- function sync_tabs( $original_product_id, $trnsl_product_id, $data, $lang ) {
97
- //check if "duplicate" product
98
- if ( ( isset( $_POST['icl_ajx_action'] ) && ( 'make_duplicates' === $_POST['icl_ajx_action'] ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ) {
99
- $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
100
- }
101
-
102
- $orig_prod_tabs = $this->get_product_tabs( $original_product_id );
103
-
104
- if ( $orig_prod_tabs ) {
105
- $trnsl_product_tabs = array();
106
- $i = 0;
107
- foreach ( $orig_prod_tabs as $key => $orig_prod_tab ) {
108
- switch ( $orig_prod_tab['type'] ) {
109
- case 'core':
110
- $default_language = $this->woocommerce_wpml->products->get_original_product_language( $original_product_id );
111
- $current_language = $this->sitepress->get_current_language();
112
- $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
113
- $title = isset( $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] ) ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] : '';
114
- $heading = isset( $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] ) ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] : '';
115
-
116
- if ( $default_language !== $lang ) {
117
-
118
- $this->refresh_text_domain( $lang );
119
-
120
- if ( ! $title ) {
121
- $title = isset( $_POST['product_tab_title'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_title'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ]['title'];
122
- $title = __( $title, 'woocommerce' );
123
- }
124
-
125
- if ( ! $heading && ( isset( $orig_prod_tabs[ $key ]['heading'] ) || isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ) ) {
126
- $heading = isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ]['heading'];
127
- $heading = __( $heading, 'woocommerce' );
128
- }
129
-
130
- $this->refresh_text_domain( $current_language );
131
- }
132
-
133
- $trnsl_product_tabs[ $key ]['title'] = $title;
134
- $trnsl_product_tabs[ $key ]['heading'] = $heading;
135
- break;
136
- case 'global':
137
- $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
138
- break;
139
- case 'product':
140
- $tab_id = false;
141
- $title_key = md5( 'tab_' . $orig_prod_tab['position'] . '_title' );
142
- $heading_key = md5( 'tab_' . $orig_prod_tab['position'] . '_heading' );
143
- $title = isset( $data[ $title_key ] ) ? sanitize_text_field( $data[ $title_key ] ) : '';
144
- $content = isset( $data[ $heading_key ] ) ? sanitize_text_field( $data[ $heading_key ] ) : '';
145
-
146
- $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
147
-
148
- $i++;
149
- break;
150
- }
151
- }
152
- update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
153
-
154
- return true;
155
- }
156
-
157
- return false;
158
- }
159
-
160
- /**
161
- * @param $original_product_id
162
- * @param $trnsl_product_id
163
- * @param $lang
164
- */
165
- function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ) {
166
- $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
167
- $prod_tabs = array();
168
- foreach ( $orig_prod_tabs as $key => $orig_prod_tab ) {
169
- switch ( $orig_prod_tab['type'] ) {
170
- case 'core':
171
- $prod_tabs[ $key ] = $orig_prod_tab;
172
- $this->refresh_text_domain( $lang );
173
- $prod_tabs[ $key ]['title'] = __( $orig_prod_tab['title'], 'woocommerce' );
174
- if ( isset( $orig_prod_tab['heading'] ) ) {
175
- $prod_tabs[ $key ]['heading'] = __( $orig_prod_tab['heading'], 'woocommerce' );
176
- }
177
- $orig_lang = $this->sitepress->get_language_for_element( $original_product_id, 'post_product' );
178
- $this->refresh_text_domain( $orig_lang );
179
- break;
180
- case 'global':
181
- $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
182
- break;
183
- case 'product':
184
- $original_tab = get_post( $orig_prod_tab['id'] );
185
- $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
186
- break;
187
- }
188
- }
189
-
190
- update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
191
- }
192
-
193
- /**
194
- * @param $lang
195
- */
196
- function refresh_text_domain( $lang ) {
197
- unload_textdomain( 'woocommerce' );
198
- $this->sitepress->switch_lang( $lang );
199
- $this->woocommerce->load_plugin_textdomain();
200
- }
201
-
202
- /**
203
- * @param $orig_prod_tab
204
- * @param $trnsl_product_tabs
205
- * @param $lang
206
- *
207
- * @return mixed
208
- */
209
- function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ) {
210
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab['id'], 'wc_product_tab', true, $lang );
211
- $trnsl_product_tabs[ $orig_prod_tab['type'].'_tab_'. $tr_tab_id ] = array(
212
- 'position' => $orig_prod_tab['position'],
213
- 'type' => $orig_prod_tab['type'],
214
- 'id' => $tr_tab_id,
215
- 'name' => get_post( $tr_tab_id )->post_name,
216
- );
217
- return $trnsl_product_tabs;
218
- }
219
-
220
- /**
221
- * @param $orig_prod_tab
222
- * @param $trnsl_product_tabs
223
- * @param $lang
224
- * @param $trnsl_product_id
225
- * @param $tab_id
226
- * @param $title
227
- * @param $content
228
- *
229
- * @return mixed
230
- */
231
- function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ) {
232
- if ( ! $tab_id ) {
233
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab['id'], 'wc_product_tab', false, $lang );
234
-
235
- if ( ! is_null( $tr_tab_id ) ) {
236
- $tab_id = $tr_tab_id;
237
- }
238
- }
239
-
240
- if ( $tab_id ) {
241
- //update existing tab
242
- $args = array();
243
- $args['post_title'] = $title;
244
- $args['post_content'] = $content;
245
- $this->wpdb->update( $this->wpdb->posts, $args, array( 'ID' => $tab_id ) );
246
- } else {
247
- //tab not exist creating new
248
- $args = array();
249
- $args['post_title'] = $title;
250
- $args['post_content'] = $content;
251
- $args['post_author'] = get_current_user_id();
252
- $args['post_name'] = sanitize_title( $title );
253
- $args['post_type'] = 'wc_product_tab';
254
- $args['post_parent'] = $trnsl_product_id;
255
- $args['post_status'] = 'publish';
256
- $this->wpdb->insert( $this->wpdb->posts, $args );
257
-
258
- $tab_id = $this->wpdb->insert_id;
259
- $tab_trid = $this->sitepress->get_element_trid( $orig_prod_tab['id'], 'post_wc_product_tab' );
260
- if ( ! $tab_trid ) {
261
- $this->sitepress->set_element_language_details( $orig_prod_tab['id'], 'post_wc_product_tab', false, $this->sitepress->get_default_language() );
262
- $tab_trid = $this->sitepress->get_element_trid( $orig_prod_tab['id'], 'post_wc_product_tab' );
263
- }
264
- $this->sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
265
- }
266
-
267
- $trnsl_product_tabs[ $orig_prod_tab['type'] . '_tab_' . $tab_id ] = array(
268
- 'position' => $orig_prod_tab['position'],
269
- 'type' => $orig_prod_tab['type'],
270
- 'id' => $tab_id,
271
- 'name' => get_post( $tab_id )->post_name,
272
- );
273
-
274
- return $trnsl_product_tabs;
275
- }
276
-
277
- /**
278
- * @param $exceptions
279
- *
280
- * @return array
281
- */
282
- function duplicate_custom_fields_exceptions( $exceptions ) {
283
- $exceptions[] = '_product_tabs';
284
- return $exceptions;
285
- }
286
-
287
- /**
288
- * @param $obj
289
- * @param $product_id
290
- * @param $data
291
- *
292
- * @return bool
293
- */
294
- function custom_box_html( $obj, $product_id, $data ) {
295
-
296
- if ( 'yes' !== get_post_meta( $product_id, '_override_tab_layout', true ) ) {
297
- return false;
298
- }
299
-
300
- $orig_prod_tabs = $this->get_product_tabs( $product_id );
301
- if ( ! $orig_prod_tabs ) {
302
- return false;
303
- }
304
-
305
- $tabs_section = new WPML_Editor_UI_Field_Section( __( 'Product tabs', 'woocommerce-multilingual' ) );
306
- end( $orig_prod_tabs );
307
- $last_key = key( $orig_prod_tabs );
308
- $divider = true;
309
- foreach ( $orig_prod_tabs as $key => $prod_tab ) {
310
- if ( $key === $last_key ) {
311
- $divider = false;
312
- }
313
-
314
- if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
315
- if ( 'core' === $prod_tab['type'] ) {
316
- $group = new WPML_Editor_UI_Field_Group( $prod_tab['title'], $divider );
317
- $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_' . $prod_tab['id'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
318
- $group->add_field( $tab_field );
319
- $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_' . $prod_tab['id'].'_heading' , __( 'Heading', 'woocommerce-multilingual' ), $data, false );
320
- $group->add_field( $tab_field );
321
- $tabs_section->add_field( $group );
322
- } else {
323
- $group = new WPML_Editor_UI_Field_Group( ucfirst( str_replace( '-', ' ', $prod_tab['name'] ) ), $divider );
324
- $tab_field = new WPML_Editor_UI_Single_Line_Field( 'tab_'.$prod_tab['position'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
325
- $group->add_field( $tab_field );
326
- $tab_field = new WPML_Editor_UI_WYSIWYG_Field( 'tab_'.$prod_tab['position'].'_heading' , null, $data, false );
327
- $group->add_field( $tab_field );
328
- $tabs_section->add_field( $group );
329
- }
330
- }
331
- }
332
- $obj->add_field( $tabs_section );
333
-
334
- return true;
335
- }
336
-
337
- /**
338
- * @param $data
339
- * @param $product_id
340
- * @param $translation
341
- * @param $lang
342
- *
343
- * @return mixed
344
- */
345
- function custom_box_html_data( $data, $product_id, $translation, $lang ) {
346
-
347
- $orig_prod_tabs = $this->get_product_tabs( $product_id );
348
-
349
- if ( empty( $orig_prod_tabs ) ) {
350
- return $data;
351
- }
352
-
353
- foreach ( $orig_prod_tabs as $key => $prod_tab ) {
354
- if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
355
- if ( 'core' === $prod_tab['type'] ) {
356
- $data[ 'coretab_' . $prod_tab['id'] . '_title' ] = array( 'original' => $prod_tab['title'] );
357
- $data[ 'coretab_' . $prod_tab['id'] . '_heading' ] = array( 'original' => isset( $prod_tab['heading'] ) ? $prod_tab['heading'] : '' );
358
- } else {
359
- $data[ 'tab_' . $prod_tab['position'] . '_title' ] = array( 'original' => get_the_title( $prod_tab['id'] ) );
360
- $data[ 'tab_' . $prod_tab['position'] . '_heading' ] = array( 'original' => get_post( $prod_tab['id'] )->post_content );
361
- }
362
- }
363
- }
364
-
365
- if ( $translation ) {
366
- $tr_prod_tabs = $this->get_product_tabs( $translation->ID );
367
-
368
- if ( ! is_array( $tr_prod_tabs ) ) {
369
- return $data; // __('Please update original product','woocommerce-multilingual');
370
- }
371
-
372
- foreach ( $tr_prod_tabs as $key => $prod_tab ) {
373
- if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
374
- if ( 'core' === $prod_tab['type'] ) {
375
- $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $prod_tab['title'];
376
- $data[ 'coretab_' . $prod_tab['id'] . '_heading' ]['translation'] = isset( $prod_tab['heading'] ) ? $prod_tab['heading'] : '';
377
- } else {
378
- $data[ 'tab_'.$prod_tab['position'].'_title' ]['translation'] = get_the_title( $prod_tab['id'] );
379
- $data[ 'tab_'.$prod_tab['position'].'_heading' ]['translation'] = get_post( $prod_tab['id'] )->post_content;
380
- }
381
- }
382
- }
383
- } else {
384
- $current_language = $this->sitepress->get_current_language();
385
- foreach ( $orig_prod_tabs as $key => $prod_tab ) {
386
- if ( 'core' === $prod_tab['type'] ) {
387
- unload_textdomain( 'woocommerce' );
388
- $this->sitepress->switch_lang( $lang );
389
- $this->woocommerce->load_plugin_textdomain();
390
- $title = __( $prod_tab['title'], 'woocommerce' );
391
- if ( $prod_tab['title'] !== $title ) {
392
- $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $title;
393
- }
394
-
395
- if ( ! isset( $prod_tab['heading'] ) ) {
396
- $data[ 'coretab_'.$prod_tab['id'].'_heading' ]['translation'] = '';
397
- } else {
398
- $heading = __( $prod_tab['heading'], 'woocommerce' );
399
- if ( $prod_tab['heading'] !== $heading ) {
400
- $data[ 'coretab_' . $prod_tab['id'] . '_heading' ]['translation'] = $heading;
401
- }
402
- }
403
-
404
- unload_textdomain( 'woocommerce' );
405
- $this->sitepress->switch_lang( $current_language );
406
- $this->woocommerce->load_plugin_textdomain();
407
- }
408
- }
409
- }
410
-
411
- return $data;
412
-
413
- }
414
-
415
- /**
416
- * @param $new_id
417
- * @param $original_post
418
- */
419
- function duplicate_product_tabs( $new_id, $original_post ) {
420
- if ( function_exists( 'wc_tab_manager_duplicate_product' ) ) {
421
- wc_tab_manager_duplicate_product( $new_id, $original_post );
422
- }
423
- }
424
-
425
- /**
426
- * @param $post_id
427
- * @param $post
428
- */
429
- function force_set_language_information_on_product_tabs( $post_id, $post ) {
430
- if ( 'wc_product_tab' === $post->post_type ) {
431
-
432
- $language = $this->sitepress->get_language_for_element( $post_id, 'post_wc_product_tab' );
433
- if ( empty( $language ) && $post->post_parent ) {
434
- $parent_language = $this->sitepress->get_language_for_element( $post->post_parent, 'post_product' );
435
- if ( $parent_language ) {
436
- $this->sitepress->set_element_language_details( $post_id, 'post_wc_product_tab', null, $parent_language );
437
- }
438
- }
439
- }
440
-
441
- }
442
-
443
- /**
444
- * @param $package
445
- * @param $post
446
- *
447
- * @return mixed
448
- */
449
- function append_custom_tabs_to_translation_package( $package, $post ) {
450
-
451
- if ( 'product' === $post->post_type ) {
452
-
453
- $override_tab_layout = get_post_meta( $post->ID , '_override_tab_layout', true );
454
-
455
- if ( 'yes' === $override_tab_layout ) {
456
-
457
- $meta = (array) get_post_meta( $post->ID, '_product_tabs', true );
458
-
459
- foreach ( $meta as $key => $value ) {
460
-
461
- if ( preg_match( '/product_tab_([0-9]+)/', $key, $matches ) ) {
462
-
463
- $wc_product_tab_id = $matches[1];
464
- $wc_product_tab = get_post( $wc_product_tab_id );
465
-
466
- $package['contents'][ 'product_tabs:product_tab:' . $wc_product_tab_id . ':title' ] = array(
467
- 'translate' => 1,
468
- 'data' => $this->tp->encode_field_data( $wc_product_tab->post_title, 'base64' ),
469
- 'format' => 'base64',
470
- );
471
-
472
- $package['contents'][ 'product_tabs:product_tab:' . $wc_product_tab_id . ':description' ] = array(
473
- 'translate' => 1,
474
- 'data' => $this->tp->encode_field_data( $wc_product_tab->post_content, 'base64' ),
475
- 'format' => 'base64',
476
- );
477
-
478
- } elseif ( preg_match( '/^core_tab_(.+)$/', $key, $matches ) ) {
479
-
480
- $package['contents'][ 'product_tabs:core_tab_title:' . $matches[1] ] = array(
481
- 'translate' => 1,
482
- 'data' => $this->tp->encode_field_data( $value['title'], 'base64' ),
483
- 'format' => 'base64',
484
- );
485
-
486
- if ( isset( $value['heading'] ) ) {
487
- $package['contents'][ 'product_tabs:core_tab_heading:' . $matches[1] ] = array(
488
- 'translate' => 1,
489
- 'data' => $this->tp->encode_field_data( $value['heading'], 'base64' ),
490
- 'format' => 'base64',
491
- );
492
- }
493
- }
494
- }
495
- }
496
- }
497
-
498
- return $package;
499
- }
500
-
501
- /**
502
- * @param $post_id
503
- * @param $data
504
- * @param $job
505
- */
506
- function save_custom_tabs_translation( $post_id, $data, $job ) {
507
- $translated_product_tabs_updated = false;
508
-
509
- $original_product_tabs = get_post_meta( $job->original_doc_id, '_product_tabs', true );
510
-
511
- if ( $original_product_tabs ) {
512
-
513
- // custom tabs
514
- $product_tab_translations = array();
515
-
516
- foreach ( $data as $value ) {
517
-
518
- if ( preg_match( '/product_tabs:product_tab:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
519
-
520
- $wc_product_tab_id = $matches[1];
521
- $field = $matches[2];
522
-
523
- $product_tab_translations[ $wc_product_tab_id ][ $field ] = $value['data'];
524
- }
525
- }
526
-
527
- if ( $product_tab_translations ) {
528
-
529
- $translated_product_tabs = get_post_meta( $post_id, '_product_tabs', true );
530
-
531
- foreach ( $product_tab_translations as $wc_product_tab_id => $value ) {
532
-
533
- $new_wc_product_tab = array(
534
- 'post_type' => 'wp_product_tab',
535
- 'post_title' => $value['title'],
536
- 'post_content' => $value['description'],
537
- 'post_status' => 'publish',
538
- );
539
-
540
- $wc_product_tab_id_translated = wp_insert_post( $new_wc_product_tab );
541
-
542
- if ( $wc_product_tab_id_translated ) {
543
-
544
- $wc_product_tab_trid = $this->sitepress->get_element_trid( $wc_product_tab_id, 'post_wc_product_tab' );
545
- $this->sitepress->set_element_language_details( $wc_product_tab_id_translated, 'post_wc_product_tab', $wc_product_tab_trid, $job->language_code );
546
-
547
- $wc_product_tab_translated = get_post( $wc_product_tab_id_translated );
548
-
549
- $translated_product_tabs[ 'product_tab_' . $wc_product_tab_id_translated ] = array(
550
- 'position' => $original_product_tabs[ 'product_tab_' . $wc_product_tab_id ]['position'],
551
- 'type' => 'product',
552
- 'id' => $wc_product_tab_id_translated,
553
- 'name' => $wc_product_tab_translated->post_name,
554
-
555
- );
556
- }
557
- }
558
-
559
- $translated_product_tabs_updated = true;
560
- }
561
-
562
- // the other tabs
563
- $product_tab_translations = array();
564
-
565
- foreach ( $data as $value ) {
566
-
567
- if ( preg_match( '/product_tabs:core_tab_(.+):(.+)/', $value['field_type'], $matches ) ) {
568
-
569
- $tab_field = $matches[1];
570
- $tab_id = $matches[2];
571
-
572
- $product_tab_translations[ $tab_id ][ $tab_field ] = $value['data'];
573
- }
574
- }
575
-
576
- if ( $product_tab_translations ) {
577
- foreach ( $product_tab_translations as $id => $tab ) {
578
-
579
- $translated_product_tabs[ 'core_tab_' . $id ] = array(
580
- 'type' => 'core',
581
- 'position' => $original_product_tabs[ 'core_tab_' . $id ]['position'],
582
- 'id' => $id,
583
- 'title' => $tab['title'],
584
- );
585
-
586
- if ( isset( $tab['heading'] ) ) {
587
- $translated_product_tabs[ 'core_tab_' . $id ]['heading'] = $tab['heading'];
588
- }
589
- }
590
-
591
- $translated_product_tabs_updated = true;
592
- }
593
-
594
- if ( true === $translated_product_tabs_updated && isset( $translated_product_tabs ) ) {
595
- update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
596
- }
597
- }
598
- }
599
-
600
- /**
601
- * @param $product_id
602
- *
603
- * @return mixed|void
604
- */
605
- public function get_product_tabs( $product_id ) {
606
-
607
- $override_tab_layout = get_post_meta( $product_id, '_override_tab_layout', true );
608
-
609
- if ( 'yes' == $override_tab_layout ) {
610
- // product defines its own tab layout?
611
- $product_tabs = get_post_meta( $product_id, '_product_tabs', true );
612
- } else {
613
- // otherwise, get the default layout if any
614
- $product_tabs = get_option( 'wc_tab_manager_default_layout', false );
615
- }
616
-
617
- return $product_tabs;
618
- }
619
-
620
- /**
621
- * @param $tab_id
622
- *
623
- * @return mixed|void
624
- */
625
- function wc_tab_manager_tab_id( $tab_id ) {
626
- return apply_filters( 'wpml_object_id', $tab_id, 'wc_product_tab', true );
627
- }
628
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Tab_Manager
5
+ */
6
+ class WCML_Tab_Manager {
7
+ /**
8
+ * @var WPML_Element_Translation_Package
9
+ */
10
+ public $tp;
11
+
12
+ /**
13
+ * @var SitePress
14
+ */
15
+ public $sitepress;
16
+
17
+ /**
18
+ * @var WooCommerce
19
+ */
20
+ public $woocommerce;
21
+
22
+ /**
23
+ * @var woocommerce_wpml
24
+ */
25
+ public $woocommerce_wpml;
26
+
27
+ /**
28
+ * @var wpdb
29
+ */
30
+ public $wpdb;
31
+
32
+ /**
33
+ * WCML_Tab_Manager constructor.
34
+ *
35
+ * @param $sitepress
36
+ * @param $woocommerce
37
+ * @param $woocommerce_wpml
38
+ * @param $wpdb
39
+ */
40
+ function __construct( &$sitepress, &$woocommerce, &$woocommerce_wpml, &$wpdb ) {
41
+ $this->sitepress = $sitepress;
42
+ $this->woocommerce = $woocommerce;
43
+ $this->woocommerce_wpml = $woocommerce_wpml;
44
+ $this->wpdb = $wpdb;
45
+ add_action( 'wcml_update_extra_fields', array( $this, 'sync_tabs' ), 10, 4 );
46
+ add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
47
+ add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
48
+ add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
49
+ add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs' ) , 10, 2 );
50
+
51
+ add_filter( 'wc_tab_manager_tab_id', array( $this, 'wc_tab_manager_tab_id' ), 10, 1 );
52
+
53
+ if ( version_compare( WCML_VERSION, '3.7.2', '>' ) ) {
54
+ add_filter( 'option_wpml_config_files_arr', array( $this, 'make__product_tabs_not_translatable_by_default' ), 0 );
55
+ }
56
+
57
+ if ( is_admin() ) {
58
+
59
+ $this->tp = new WPML_Element_Translation_Package;
60
+
61
+ add_action( 'save_post', array( $this, 'force_set_language_information_on_product_tabs' ), 10, 2 );
62
+ add_action( 'save_post', array( $this, 'sync_product_tabs' ), 10, 2 );
63
+
64
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_tabs_to_translation_package' ), 10, 2 );
65
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
66
+
67
+ }else{
68
+ add_filter( 'option_wc_tab_manager_default_layout', array( $this, 'filter_default_layout' ) );
69
+ }
70
+
71
+ }
72
+
73
+ /**
74
+ * @param $wpml_config_array
75
+ *
76
+ * @return mixed
77
+ */
78
+ function make__product_tabs_not_translatable_by_default( $wpml_config_array ) {
79
+
80
+ if ( isset( $wpml_config_array->plugins['WooCommerce Tab Manager'] ) ) {
81
+ $wpml_config_array->plugins['WooCommerce Tab Manager'] =
82
+ str_replace( '<custom-field action="translate">_product_tabs</custom-field>',
83
+ '<custom-field action="nothing">_product_tabs</custom-field>',
84
+ $wpml_config_array->plugins['WooCommerce Tab Manager']
85
+ );
86
+ }
87
+
88
+ return $wpml_config_array;
89
+ }
90
+
91
+ /**
92
+ * @param $original_product_id
93
+ * @param $trnsl_product_id
94
+ * @param $data
95
+ * @param $lang
96
+ *
97
+ * @return bool
98
+ */
99
+ function sync_tabs( $original_product_id, $trnsl_product_id, $data, $lang ) {
100
+ //check if "duplicate" product
101
+ if ( ( isset( $_POST['icl_ajx_action'] ) && ( 'make_duplicates' === $_POST['icl_ajx_action'] ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ) {
102
+ $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
103
+ }
104
+
105
+ $orig_prod_tabs = $this->get_product_tabs( $original_product_id );
106
+
107
+ if ( $orig_prod_tabs ) {
108
+ $trnsl_product_tabs = array();
109
+ $i = 0;
110
+ foreach ( $orig_prod_tabs as $key => $orig_prod_tab ) {
111
+ switch ( $orig_prod_tab['type'] ) {
112
+ case 'core':
113
+ $default_language = $this->woocommerce_wpml->products->get_original_product_language( $original_product_id );
114
+ $current_language = $this->sitepress->get_current_language();
115
+ $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
116
+ $title = isset( $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] ) ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_title' ) ] : '';
117
+ $heading = isset( $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] ) ? $data[ md5( 'coretab_'.$orig_prod_tab['id'].'_heading' ) ] : '';
118
+
119
+ if ( $default_language !== $lang ) {
120
+
121
+ $this->refresh_text_domain( $lang );
122
+
123
+ if ( ! $title ) {
124
+ $title = isset( $_POST['product_tab_title'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_title'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ]['title'];
125
+ $title = __( $title, 'woocommerce' );
126
+ }
127
+
128
+ if ( ! $heading && ( isset( $orig_prod_tabs[ $key ]['heading'] ) || isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ) ) {
129
+ $heading = isset( $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] ) ? $_POST['product_tab_heading'][ $orig_prod_tab['position'] ] : $orig_prod_tabs[ $key ]['heading'];
130
+ $heading = __( $heading, 'woocommerce' );
131
+ }
132
+
133
+ $this->refresh_text_domain( $current_language );
134
+ }
135
+
136
+ $trnsl_product_tabs[ $key ]['title'] = $title;
137
+ $trnsl_product_tabs[ $key ]['heading'] = $heading;
138
+ break;
139
+ case 'global':
140
+ $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
141
+ break;
142
+ case 'product':
143
+ $tab_id = false;
144
+ $title_key = md5( 'tab_' . $orig_prod_tab['position'] . '_title' );
145
+ $heading_key = md5( 'tab_' . $orig_prod_tab['position'] . '_heading' );
146
+ $title = isset( $data[ $title_key ] ) ? sanitize_text_field( $data[ $title_key ] ) : '';
147
+ $content = isset( $data[ $heading_key ] ) ? sanitize_text_field( $data[ $heading_key ] ) : '';
148
+
149
+ $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
150
+
151
+ $i++;
152
+ break;
153
+ }
154
+ }
155
+ update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
156
+
157
+ return true;
158
+ }
159
+
160
+ return false;
161
+ }
162
+
163
+ /**
164
+ * @param $original_product_id
165
+ * @param $trnsl_product_id
166
+ * @param $lang
167
+ */
168
+ function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ) {
169
+ $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
170
+ $prod_tabs = array();
171
+ foreach ( $orig_prod_tabs as $key => $orig_prod_tab ) {
172
+ switch ( $orig_prod_tab['type'] ) {
173
+ case 'core':
174
+ $prod_tabs[ $key ] = $orig_prod_tab;
175
+ $this->refresh_text_domain( $lang );
176
+ $prod_tabs[ $key ]['title'] = __( $orig_prod_tab['title'], 'woocommerce' );
177
+ if ( isset( $orig_prod_tab['heading'] ) ) {
178
+ $prod_tabs[ $key ]['heading'] = __( $orig_prod_tab['heading'], 'woocommerce' );
179
+ }
180
+ $orig_lang = $this->sitepress->get_language_for_element( $original_product_id, 'post_product' );
181
+ $this->refresh_text_domain( $orig_lang );
182
+ break;
183
+ case 'global':
184
+ $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
185
+ break;
186
+ case 'product':
187
+ $original_tab = get_post( $orig_prod_tab['id'] );
188
+ $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
189
+ break;
190
+ }
191
+ }
192
+
193
+ update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
194
+ }
195
+
196
+ /**
197
+ * @param $lang
198
+ */
199
+ function refresh_text_domain( $lang ) {
200
+ unload_textdomain( 'woocommerce' );
201
+ $this->sitepress->switch_lang( $lang );
202
+ $this->woocommerce->load_plugin_textdomain();
203
+ }
204
+
205
+ /**
206
+ * @param $orig_prod_tab
207
+ * @param $trnsl_product_tabs
208
+ * @param $lang
209
+ *
210
+ * @return mixed
211
+ */
212
+ function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ) {
213
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab['id'], 'wc_product_tab', true, $lang );
214
+ $trnsl_product_tabs[ $orig_prod_tab['type'].'_tab_'. $tr_tab_id ] = array(
215
+ 'position' => $orig_prod_tab['position'],
216
+ 'type' => $orig_prod_tab['type'],
217
+ 'id' => $tr_tab_id,
218
+ 'name' => get_post( $tr_tab_id )->post_name,
219
+ );
220
+ return $trnsl_product_tabs;
221
+ }
222
+
223
+ /**
224
+ * @param $orig_prod_tab
225
+ * @param $trnsl_product_tabs
226
+ * @param $lang
227
+ * @param $trnsl_product_id
228
+ * @param $tab_id
229
+ * @param $title
230
+ * @param $content
231
+ *
232
+ * @return mixed
233
+ */
234
+ function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ) {
235
+ if ( ! $tab_id ) {
236
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab['id'], 'wc_product_tab', false, $lang );
237
+
238
+ if ( ! is_null( $tr_tab_id ) ) {
239
+ $tab_id = $tr_tab_id;
240
+ }
241
+ }
242
+
243
+ if ( $tab_id ) {
244
+ //update existing tab
245
+ $args = array();
246
+ $args['post_title'] = $title;
247
+ $args['post_content'] = $content;
248
+ $this->wpdb->update( $this->wpdb->posts, $args, array( 'ID' => $tab_id ) );
249
+ } else {
250
+ //tab not exist creating new
251
+ $args = array();
252
+ $args['post_title'] = $title;
253
+ $args['post_content'] = $content;
254
+ $args['post_author'] = get_current_user_id();
255
+ $args['post_name'] = sanitize_title( $title );
256
+ $args['post_type'] = 'wc_product_tab';
257
+ $args['post_parent'] = $trnsl_product_id;
258
+ $args['post_status'] = 'publish';
259
+ $this->wpdb->insert( $this->wpdb->posts, $args );
260
+
261
+ $tab_id = $this->wpdb->insert_id;
262
+ $tab_trid = $this->sitepress->get_element_trid( $orig_prod_tab['id'], 'post_wc_product_tab' );
263
+ if ( ! $tab_trid ) {
264
+ $this->sitepress->set_element_language_details( $orig_prod_tab['id'], 'post_wc_product_tab', false, $this->sitepress->get_default_language() );
265
+ $tab_trid = $this->sitepress->get_element_trid( $orig_prod_tab['id'], 'post_wc_product_tab' );
266
+ }
267
+ $this->sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
268
+ }
269
+
270
+
271
+ if ( empty( $title ) || strlen( $title ) != strlen( utf8_encode( $title ) ) ) {
272
+ $tab_name = "product-tab-". $tab_id;
273
+ } else {
274
+ $tab_name = sanitize_title( $title );
275
+ }
276
+
277
+ $trnsl_product_tabs[ $orig_prod_tab['type'] . '_tab_' . $tab_id ] = array(
278
+ 'position' => $orig_prod_tab['position'],
279
+ 'type' => $orig_prod_tab['type'],
280
+ 'id' => $tab_id,
281
+ 'name' => $tab_name,
282
+ );
283
+
284
+ return $trnsl_product_tabs;
285
+ }
286
+
287
+ /**
288
+ * @param $exceptions
289
+ *
290
+ * @return array
291
+ */
292
+ function duplicate_custom_fields_exceptions( $exceptions ) {
293
+ $exceptions[] = '_product_tabs';
294
+ return $exceptions;
295
+ }
296
+
297
+ /**
298
+ * @param $obj
299
+ * @param $product_id
300
+ * @param $data
301
+ *
302
+ * @return bool
303
+ */
304
+ function custom_box_html( $obj, $product_id, $data ) {
305
+
306
+ if ( 'yes' !== get_post_meta( $product_id, '_override_tab_layout', true ) ) {
307
+ return false;
308
+ }
309
+
310
+ $orig_prod_tabs = $this->get_product_tabs( $product_id );
311
+ if ( ! $orig_prod_tabs ) {
312
+ return false;
313
+ }
314
+
315
+ $tabs_section = new WPML_Editor_UI_Field_Section( __( 'Product tabs', 'woocommerce-multilingual' ) );
316
+
317
+ $keys = array_keys( $orig_prod_tabs );
318
+ $last_key = end( $keys );
319
+ $divider = true;
320
+
321
+ foreach ( $orig_prod_tabs as $key => $prod_tab ) {
322
+ if ( $key === $last_key ) {
323
+ $divider = false;
324
+ }
325
+
326
+ if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
327
+ if ( 'core' === $prod_tab['type'] ) {
328
+ $group = new WPML_Editor_UI_Field_Group( $prod_tab['title'], $divider );
329
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_' . $prod_tab['id'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
330
+ $group->add_field( $tab_field );
331
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'coretab_' . $prod_tab['id'].'_heading' , __( 'Heading', 'woocommerce-multilingual' ), $data, false );
332
+ $group->add_field( $tab_field );
333
+ $tabs_section->add_field( $group );
334
+ } else {
335
+ $group = new WPML_Editor_UI_Field_Group( ucfirst( str_replace( '-', ' ', $prod_tab['name'] ) ), $divider );
336
+ $tab_field = new WPML_Editor_UI_Single_Line_Field( 'tab_'.$prod_tab['position'].'_title', __( 'Title', 'woocommerce-multilingual' ), $data, false );
337
+ $group->add_field( $tab_field );
338
+ $tab_field = new WPML_Editor_UI_WYSIWYG_Field( 'tab_'.$prod_tab['position'].'_heading' , null, $data, false );
339
+ $group->add_field( $tab_field );
340
+ $tabs_section->add_field( $group );
341
+ }
342
+ }
343
+ }
344
+ $obj->add_field( $tabs_section );
345
+
346
+ return true;
347
+ }
348
+
349
+ /**
350
+ * @param $data
351
+ * @param $product_id
352
+ * @param $translation
353
+ * @param $lang
354
+ *
355
+ * @return mixed
356
+ */
357
+ function custom_box_html_data( $data, $product_id, $translation, $lang ) {
358
+
359
+ $orig_prod_tabs = $this->get_product_tabs( $product_id );
360
+
361
+ if ( empty( $orig_prod_tabs ) ) {
362
+ return $data;
363
+ }
364
+
365
+ foreach ( $orig_prod_tabs as $key => $prod_tab ) {
366
+ if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
367
+ if ( 'core' === $prod_tab['type'] ) {
368
+ $data[ 'coretab_' . $prod_tab['id'] . '_title' ] = array( 'original' => $prod_tab['title'] );
369
+ $data[ 'coretab_' . $prod_tab['id'] . '_heading' ] = array( 'original' => isset( $prod_tab['heading'] ) ? $prod_tab['heading'] : '' );
370
+ } else {
371
+ $data[ 'tab_' . $prod_tab['position'] . '_title' ] = array( 'original' => get_the_title( $prod_tab['id'] ) );
372
+ $data[ 'tab_' . $prod_tab['position'] . '_heading' ] = array( 'original' => get_post( $prod_tab['id'] )->post_content );
373
+ }
374
+ }
375
+ }
376
+
377
+ if ( $translation ) {
378
+ $tr_prod_tabs = $this->get_product_tabs( $translation->ID );
379
+
380
+
381
+ if ( ! is_array( $tr_prod_tabs ) ) {
382
+ return $data; // __('Please update original product','woocommerce-multilingual');
383
+ }
384
+
385
+ foreach ( $tr_prod_tabs as $key => $prod_tab ) {
386
+ if ( in_array( $prod_tab['type'], array( 'product', 'core' ) ) ) {
387
+ if ( 'core' === $prod_tab['type'] ) {
388
+ $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $prod_tab['title'];
389
+ $data[ 'coretab_' . $prod_tab['id'] . '_heading' ]['translation'] = isset( $prod_tab['heading'] ) ? $prod_tab['heading'] : '';
390
+ } else {
391
+ $data[ 'tab_'.$prod_tab['position'].'_title' ]['translation'] = get_the_title( $prod_tab['id'] );
392
+ $data[ 'tab_'.$prod_tab['position'].'_heading' ]['translation'] = get_post( $prod_tab['id'] )->post_content;
393
+ }
394
+ }
395
+ }
396
+ } else {
397
+ $current_language = $this->sitepress->get_current_language();
398
+ foreach ( $orig_prod_tabs as $key => $prod_tab ) {
399
+ if ( 'core' === $prod_tab['type'] ) {
400
+ unload_textdomain( 'woocommerce' );
401
+ $this->sitepress->switch_lang( $lang );
402
+ $this->woocommerce->load_plugin_textdomain();
403
+ $title = __( $prod_tab['title'], 'woocommerce' );
404
+ if ( $prod_tab['title'] !== $title ) {
405
+ $data[ 'coretab_' . $prod_tab['id'] . '_title' ]['translation'] = $title;
406
+ }
407
+
408
+ if ( ! isset( $prod_tab['heading'] ) ) {
409
+ $data[ 'coretab_'.$prod_tab['id'].'_heading' ]['translation'] = '';
410
+ } else {
411
+ $heading = __( $prod_tab['heading'], 'woocommerce' );
412
+ if ( $prod_tab['heading'] !== $heading ) {
413
+ $data[ 'coretab_' . $prod_tab['id'] . '_heading' ]['translation'] = $heading;
414
+ }
415
+ }
416
+
417
+ unload_textdomain( 'woocommerce' );
418
+ $this->sitepress->switch_lang( $current_language );
419
+ $this->woocommerce->load_plugin_textdomain();
420
+ }
421
+ }
422
+ }
423
+
424
+ return $data;
425
+
426
+ }
427
+
428
+ /**
429
+ * @param $new_id
430
+ * @param $original_post
431
+ */
432
+ function duplicate_product_tabs( $new_id, $original_post ) {
433
+ if ( function_exists( 'wc_tab_manager_duplicate_product' ) ) {
434
+ wc_tab_manager_duplicate_product( $new_id, $original_post );
435
+ }
436
+ }
437
+
438
+ /**
439
+ * @param $post_id
440
+ * @param $post
441
+ */
442
+ function force_set_language_information_on_product_tabs( $post_id, $post ) {
443
+ if ( 'wc_product_tab' === $post->post_type ) {
444
+
445
+ $language = $this->sitepress->get_language_for_element( $post_id, 'post_wc_product_tab' );
446
+ if ( empty( $language ) && $post->post_parent ) {
447
+ $parent_language = $this->sitepress->get_language_for_element( $post->post_parent, 'post_product' );
448
+ if ( $parent_language ) {
449
+ $this->sitepress->set_element_language_details( $post_id, 'post_wc_product_tab', null, $parent_language );
450
+ }
451
+ }
452
+ }
453
+
454
+ }
455
+
456
+ /**
457
+ * @param $package
458
+ * @param $post
459
+ *
460
+ * @return mixed
461
+ */
462
+ function append_custom_tabs_to_translation_package( $package, $post ) {
463
+
464
+ if ( 'product' === $post->post_type ) {
465
+
466
+ $override_tab_layout = get_post_meta( $post->ID , '_override_tab_layout', true );
467
+
468
+ if ( 'yes' === $override_tab_layout ) {
469
+
470
+ $meta = (array) get_post_meta( $post->ID, '_product_tabs', true );
471
+
472
+ foreach ( $meta as $key => $value ) {
473
+
474
+ if ( preg_match( '/product_tab_([0-9]+)/', $key, $matches ) ) {
475
+
476
+ $wc_product_tab_id = $matches[1];
477
+ $wc_product_tab = get_post( $wc_product_tab_id );
478
+
479
+ $package['contents'][ 'product_tabs:product_tab:' . $wc_product_tab_id . ':title' ] = array(
480
+ 'translate' => 1,
481
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_title, 'base64' ),
482
+ 'format' => 'base64',
483
+ );
484
+
485
+ $package['contents'][ 'product_tabs:product_tab:' . $wc_product_tab_id . ':description' ] = array(
486
+ 'translate' => 1,
487
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_content, 'base64' ),
488
+ 'format' => 'base64',
489
+ );
490
+
491
+ } elseif ( preg_match( '/^core_tab_(.+)$/', $key, $matches ) ) {
492
+
493
+ $package['contents'][ 'product_tabs:core_tab_title:' . $matches[1] ] = array(
494
+ 'translate' => 1,
495
+ 'data' => $this->tp->encode_field_data( $value['title'], 'base64' ),
496
+ 'format' => 'base64',
497
+ );
498
+
499
+ if ( isset( $value['heading'] ) ) {
500
+ $package['contents'][ 'product_tabs:core_tab_heading:' . $matches[1] ] = array(
501
+ 'translate' => 1,
502
+ 'data' => $this->tp->encode_field_data( $value['heading'], 'base64' ),
503
+ 'format' => 'base64',
504
+ );
505
+ }
506
+ }
507
+ }
508
+ }
509
+ }
510
+
511
+ return $package;
512
+ }
513
+
514
+ /**
515
+ * @param $post_id
516
+ * @param $data
517
+ * @param $job
518
+ */
519
+ function save_custom_tabs_translation( $post_id, $data, $job ) {
520
+ $translated_product_tabs_updated = false;
521
+
522
+ $original_product_tabs = get_post_meta( $job->original_doc_id, '_product_tabs', true );
523
+
524
+ if ( $original_product_tabs ) {
525
+
526
+ // custom tabs
527
+ $product_tab_translations = array();
528
+
529
+ foreach ( $data as $value ) {
530
+
531
+ if ( preg_match( '/product_tabs:product_tab:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
532
+
533
+ $wc_product_tab_id = $matches[1];
534
+ $field = $matches[2];
535
+
536
+ $product_tab_translations[ $wc_product_tab_id ][ $field ] = $value['data'];
537
+ }
538
+ }
539
+
540
+ if ( $product_tab_translations ) {
541
+
542
+ $translated_product_tabs = get_post_meta( $post_id, '_product_tabs', true );
543
+
544
+ foreach ( $product_tab_translations as $wc_product_tab_id => $value ) {
545
+
546
+ $new_wc_product_tab = array(
547
+ 'post_type' => 'wp_product_tab',
548
+ 'post_title' => $value['title'],
549
+ 'post_content' => $value['description'],
550
+ 'post_status' => 'publish',
551
+ );
552
+
553
+ $wc_product_tab_id_translated = wp_insert_post( $new_wc_product_tab );
554
+
555
+ if ( $wc_product_tab_id_translated ) {
556
+
557
+ $wc_product_tab_trid = $this->sitepress->get_element_trid( $wc_product_tab_id, 'post_wc_product_tab' );
558
+ $this->sitepress->set_element_language_details( $wc_product_tab_id_translated, 'post_wc_product_tab', $wc_product_tab_trid, $job->language_code );
559
+
560
+ $wc_product_tab_translated = get_post( $wc_product_tab_id_translated );
561
+
562
+ $translated_product_tabs[ 'product_tab_' . $wc_product_tab_id_translated ] = array(
563
+ 'position' => $original_product_tabs[ 'product_tab_' . $wc_product_tab_id ]['position'],
564
+ 'type' => 'product',
565
+ 'id' => $wc_product_tab_id_translated,
566
+ 'name' => $wc_product_tab_translated->post_name,
567
+
568
+ );
569
+ }
570
+ }
571
+
572
+ $translated_product_tabs_updated = true;
573
+ }
574
+
575
+ // the other tabs
576
+ $product_tab_translations = array();
577
+
578
+ foreach ( $data as $value ) {
579
+
580
+ if ( preg_match( '/product_tabs:core_tab_(.+):(.+)/', $value['field_type'], $matches ) ) {
581
+
582
+ $tab_field = $matches[1];
583
+ $tab_id = $matches[2];
584
+
585
+ $product_tab_translations[ $tab_id ][ $tab_field ] = $value['data'];
586
+ }
587
+ }
588
+
589
+ if ( $product_tab_translations ) {
590
+ foreach ( $product_tab_translations as $id => $tab ) {
591
+
592
+ $translated_product_tabs[ 'core_tab_' . $id ] = array(
593
+ 'type' => 'core',
594
+ 'position' => $original_product_tabs[ 'core_tab_' . $id ]['position'],
595
+ 'id' => $id,
596
+ 'title' => $tab['title'],
597
+ );
598
+
599
+ if ( isset( $tab['heading'] ) ) {
600
+ $translated_product_tabs[ 'core_tab_' . $id ]['heading'] = $tab['heading'];
601
+ }
602
+ }
603
+
604
+ $translated_product_tabs_updated = true;
605
+ }
606
+
607
+ if ( true === $translated_product_tabs_updated && isset( $translated_product_tabs ) ) {
608
+ update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
609
+ }
610
+ }
611
+ }
612
+
613
+ /**
614
+ * @param $product_id
615
+ *
616
+ * @return array
617
+ */
618
+ public function get_product_tabs( $product_id ) {
619
+
620
+ $override_tab_layout = get_post_meta( $product_id, '_override_tab_layout', true );
621
+
622
+ if ( 'yes' == $override_tab_layout ) {
623
+ // product defines its own tab layout?
624
+ $product_tabs = (array) get_post_meta( $product_id, '_product_tabs', true );
625
+ } else {
626
+ // otherwise, get the default layout if any
627
+ $product_tabs = (array) get_option( 'wc_tab_manager_default_layout', false );
628
+ }
629
+
630
+ return $product_tabs;
631
+ }
632
+
633
+ public function sync_product_tabs( $post_id, $post ){
634
+
635
+ $override_tab_layout = get_post_meta( $post_id, '_override_tab_layout', true );
636
+
637
+ if ( $override_tab_layout && $this->woocommerce_wpml->products->is_original_product( $post_id ) ){
638
+
639
+ $original_product_tabs = $this->get_product_tabs( $post_id );
640
+
641
+ $trid = $this->sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
642
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post->post_type, true );
643
+
644
+
645
+
646
+ foreach( $translations as $language => $translation ){
647
+
648
+ if( empty( $translation->original ) ){
649
+
650
+ $translated_product_tabs = $this->get_product_tabs( $translation->element_id );
651
+
652
+ // sync tab positions for product tabs
653
+ foreach( $original_product_tabs as $tab ){
654
+ if( $tab['type'] == 'product' ){
655
+ $translated_tab_product_id = apply_filters( 'translate_object_id', $tab['id'], 'wc_product_tab', false, $language );
656
+ if( $translated_tab_product_id && is_array( $translated_product_tabs['product_tab_' . $translated_tab_product_id ] ) ){
657
+ $translated_product_tabs['product_tab_' . $translated_tab_product_id ]['position'] = $tab['position'];
658
+ }
659
+ }
660
+ }
661
+
662
+ // sync translated core tabs with original tabs
663
+ foreach( $translated_product_tabs as $tab_key => $tab ){
664
+ if( $tab['type'] === 'core' && !isset( $original_product_tabs[$tab_key] ) ){
665
+ unset( $translated_product_tabs[$tab_key] );
666
+ }
667
+ }
668
+
669
+ update_post_meta( $translation->element_id, '_product_tabs', $translated_product_tabs );
670
+
671
+ }
672
+
673
+ }
674
+
675
+ }
676
+
677
+ }
678
+
679
+ /**
680
+ * @param $tab_id
681
+ *
682
+ * @return mixed|void
683
+ */
684
+ function wc_tab_manager_tab_id( $tab_id ) {
685
+ return apply_filters( 'wpml_object_id', $tab_id, 'wc_product_tab', true );
686
+ }
687
+
688
+ public function filter_default_layout( $default_tabs ){
689
+
690
+ if( is_array( $default_tabs ) ){
691
+ foreach( $default_tabs as $tab_key => $default_tab ){
692
+ if( substr( $tab_key, 0, 10 ) == 'global_tab' ){
693
+ $trnsl_tab_id = apply_filters( 'translate_object_id', $default_tab[ 'id' ], 'wc_product_tab', true, $this->sitepress->get_current_language() );
694
+
695
+ if( $trnsl_tab_id != $default_tab[ 'id' ] ){
696
+ $default_tabs[ 'global_tab_'.$trnsl_tab_id ] = $default_tab;
697
+ $default_tabs[ 'global_tab_'.$trnsl_tab_id ][ 'id' ] = $trnsl_tab_id;
698
+ $default_tabs[ 'global_tab_'.$trnsl_tab_id ][ 'name' ] = get_post( $trnsl_tab_id )->post_name;
699
+ unset( $default_tabs[ $tab_key ] );
700
+ }
701
+ }
702
+ }
703
+ }
704
+
705
+ return $default_tabs;
706
+ }
707
+ }
compatibility/class-wcml-table-rate-shipping.php CHANGED
@@ -1,89 +1,103 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Table_Rate_Shipping
5
- */
6
- class WCML_Table_Rate_Shipping {
7
-
8
- /**
9
- * @var SitePress
10
- */
11
- public $sitepress;
12
-
13
- /**
14
- * @var woocommerce_wpml
15
- */
16
- public $woocommerce_wpml;
17
-
18
- /**
19
- * WCML_Table_Rate_Shipping constructor.
20
- *
21
- * @param $sitepress
22
- * @param $woocommerce_wpml
23
- */
24
- function __construct( &$sitepress, &$woocommerce_wpml ) {
25
- $this->sitepress = $sitepress;
26
- $this->woocommerce_wpml = $woocommerce_wpml;
27
- add_action( 'init', array( $this, 'init' ), 9 );
28
- add_filter( 'get_the_terms',array( $this, 'shipping_class_id_in_default_language' ), 10, 3 );
29
-
30
- if( wcml_is_multi_currency_on() ){
31
- add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'filter_query_rates_args' ) );
32
- }
33
-
34
- }
35
-
36
- /**
37
- * Register shipping labels for string translation.
38
- */
39
- public function init() {
40
- // Register shipping label
41
- if ( isset( $_GET['page'] ) && 'shipping_zones' === $_GET['page'] && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] ) ) {
42
- do_action( 'wpml_register_single_string', 'woocommerce', sanitize_text_field( $_POST['woocommerce_table_rate_title'] ) . '_shipping_method_title', sanitize_text_field( $_POST['woocommerce_table_rate_title'] ) );
43
- $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
44
- foreach ( $shipping_labels as $shipping_label ) {
45
- do_action( 'wpml_register_single_string', 'woocommerce', $shipping_label . '_shipping_method_title', $shipping_label );
46
- }
47
- }
48
- }
49
-
50
- /**
51
- * @param $terms
52
- * @param $post_id
53
- * @param $taxonomy
54
- *
55
- * @return mixed
56
- */
57
- public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
58
- global $icl_adjust_id_url_filter_off;
59
- if ( 'product_shipping_class' === $taxonomy ) {
60
-
61
- foreach ( $terms as $k => $term ) {
62
- $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $this->sitepress->get_default_language() );
63
-
64
- $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
65
- $icl_adjust_id_url_filter_off = true;
66
-
67
- $terms[ $k ] = get_term( $shipping_class_id, 'product_shipping_class' );
68
-
69
- $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
70
- }
71
- }
72
-
73
- return $terms;
74
- }
75
-
76
- /**
77
- * It's not possible to filter rate_min and rate_max so we use the original price to compare against these values
78
- */
79
- public function filter_query_rates_args( $args ){
80
-
81
- if( isset( $args['price'] ) && get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
82
- $args['price'] = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $args['price'] );
83
- }
84
-
85
- return $args;
86
- }
87
-
88
-
89
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Table_Rate_Shipping
5
+ */
6
+ class WCML_Table_Rate_Shipping {
7
+
8
+ /**
9
+ * @var SitePress
10
+ */
11
+ public $sitepress;
12
+
13
+ /**
14
+ * @var woocommerce_wpml
15
+ */
16
+ public $woocommerce_wpml;
17
+
18
+ /**
19
+ * WCML_Table_Rate_Shipping constructor.
20
+ *
21
+ * @param $sitepress
22
+ * @param $woocommerce_wpml
23
+ */
24
+ function __construct( &$sitepress, &$woocommerce_wpml ) {
25
+ $this->sitepress = $sitepress;
26
+ $this->woocommerce_wpml = $woocommerce_wpml;
27
+ add_action( 'init', array( $this, 'init' ), 9 );
28
+ add_filter( 'get_the_terms',array( $this, 'shipping_class_id_in_default_language' ), 10, 3 );
29
+
30
+ if( wcml_is_multi_currency_on() ){
31
+ add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'filter_query_rates_args' ) );
32
+ }
33
+
34
+ }
35
+
36
+ /**
37
+ * Register shipping labels for string translation.
38
+ */
39
+ public function init() {
40
+ // Register shipping label
41
+ if (
42
+ isset( $_GET[ 'page' ] ) &&
43
+ (
44
+ $_GET[ 'page' ] === 'shipping_zones' ||
45
+ (
46
+ $_GET['page'] == 'wc-settings' &&
47
+ isset( $_GET[ 'tab' ] ) &&
48
+ $_GET['tab'] == 'shipping'
49
+ )
50
+ ) &&
51
+ isset( $_POST[ 'shipping_label' ] ) &&
52
+ isset( $_POST[ 'woocommerce_table_rate_title' ] )
53
+ ) {
54
+
55
+ do_action( 'wpml_register_single_string', 'woocommerce', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) . '_shipping_method_title', sanitize_text_field( $_POST[ 'woocommerce_table_rate_title' ] ) );
56
+ $shipping_labels = array_map( 'woocommerce_clean', $_POST[ 'shipping_label' ] );
57
+ foreach ( $shipping_labels as $key => $shipping_label ) {
58
+ $rate_key = isset( $_GET[ 'instance_id' ] ) ? 'table_rate'.$_GET[ 'instance_id' ].$_POST[ 'rate_id' ][ $key ] : $shipping_label;
59
+ do_action( 'wpml_register_single_string', 'woocommerce', $rate_key. '_shipping_method_title', $shipping_label );
60
+ }
61
+ }
62
+ }
63
+
64
+ /**
65
+ * @param $terms
66
+ * @param $post_id
67
+ * @param $taxonomy
68
+ *
69
+ * @return mixed
70
+ */
71
+ public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
72
+ global $icl_adjust_id_url_filter_off;
73
+ if ( 'product_shipping_class' === $taxonomy ) {
74
+
75
+ foreach ( $terms as $k => $term ) {
76
+ $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $this->sitepress->get_default_language() );
77
+
78
+ $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
79
+ $icl_adjust_id_url_filter_off = true;
80
+
81
+ $terms[ $k ] = get_term( $shipping_class_id, 'product_shipping_class' );
82
+
83
+ $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
84
+ }
85
+ }
86
+
87
+ return $terms;
88
+ }
89
+
90
+ /**
91
+ * It's not possible to filter rate_min and rate_max so we use the original price to compare against these values
92
+ */
93
+ public function filter_query_rates_args( $args ){
94
+
95
+ if( isset( $args['price'] ) && get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
96
+ $args['price'] = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $args['price'] );
97
+ }
98
+
99
+ return $args;
100
+ }
101
+
102
+
103
+ }
compatibility/class-wcml-variation-swatches-and-photos.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
-
3
- class WCML_Variation_Swatches_and_Photos{
4
-
5
- function __construct(){
6
- add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_variation_swatches_and_photos'),10,3);
7
- }
8
-
9
- function sync_variation_swatches_and_photos($original_product_id, $trnsl_product_id, $data = false){
10
- global $sitepress, $wpdb;
11
-
12
- $atts = maybe_unserialize(get_post_meta($original_product_id, '_swatch_type_options', true));
13
-
14
- if (!is_array($atts)) {
15
- return;
16
- }
17
-
18
- $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
19
- $tr_atts = $atts;
20
-
21
- $original_product_post = get_post($original_product_id);
22
-
23
- $original_product_taxonomies = get_object_taxonomies($original_product_post);
24
-
25
- $original_product_terms = get_terms($original_product_taxonomies);
26
-
27
- if (is_array($original_product_terms)) {
28
-
29
- foreach ($atts as $att_name=>$att_opts) {
30
-
31
- $attributes_hashed_names = array_keys($att_opts['attributes']);
32
-
33
- foreach($original_product_terms as $original_product_term) {
34
- $original_product_term_slug_md5 = md5($original_product_term->slug);
35
-
36
- if (in_array($original_product_term_slug_md5, $attributes_hashed_names)) {
37
-
38
- $translated_product_term_id = apply_filters('wpml_object_id', $original_product_term->term_id, $original_product_term->taxonomy, false, $lang);
39
-
40
- $translated_product_term = get_term($translated_product_term_id, $original_product_term->taxonomy);
41
-
42
- if (is_object($translated_product_term)) {
43
-
44
- $translated_product_term_slug_md5 = md5($translated_product_term->slug);
45
-
46
- $tr_atts[$att_name]['attributes'][$translated_product_term_slug_md5] = $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5];
47
-
48
- unset( $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5] );
49
- }
50
-
51
- }
52
-
53
- }
54
-
55
- }
56
-
57
- }
58
-
59
- update_post_meta($trnsl_product_id,'_swatch_type_options',$tr_atts); // Meta gets overwritten
60
- }
61
-
62
- }
1
+ <?php
2
+
3
+ class WCML_Variation_Swatches_and_Photos{
4
+
5
+ function __construct(){
6
+ add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_variation_swatches_and_photos'),10,3);
7
+ }
8
+
9
+ function sync_variation_swatches_and_photos($original_product_id, $trnsl_product_id, $data = false){
10
+ global $sitepress, $wpdb;
11
+
12
+ $atts = maybe_unserialize(get_post_meta($original_product_id, '_swatch_type_options', true));
13
+
14
+ if (!is_array($atts)) {
15
+ return;
16
+ }
17
+
18
+ $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
19
+ $tr_atts = $atts;
20
+
21
+ $original_product_post = get_post($original_product_id);
22
+
23
+ $original_product_taxonomies = get_object_taxonomies($original_product_post);
24
+
25
+ $original_product_terms = get_terms($original_product_taxonomies);
26
+
27
+ if (is_array($original_product_terms)) {
28
+
29
+ foreach ($atts as $att_name=>$att_opts) {
30
+
31
+ $attributes_hashed_names = array_keys($att_opts['attributes']);
32
+
33
+ foreach($original_product_terms as $original_product_term) {
34
+ $original_product_term_slug_md5 = md5($original_product_term->slug);
35
+
36
+ if (in_array($original_product_term_slug_md5, $attributes_hashed_names)) {
37
+
38
+ $translated_product_term_id = apply_filters('wpml_object_id', $original_product_term->term_id, $original_product_term->taxonomy, false, $lang);
39
+
40
+ $translated_product_term = get_term($translated_product_term_id, $original_product_term->taxonomy);
41
+
42
+ if (is_object($translated_product_term)) {
43
+
44
+ $translated_product_term_slug_md5 = md5($translated_product_term->slug);
45
+
46
+ $tr_atts[$att_name]['attributes'][$translated_product_term_slug_md5] = $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5];
47
+
48
+ unset( $tr_atts[$att_name]['attributes'][$original_product_term_slug_md5] );
49
+ }
50
+
51
+ }
52
+
53
+ }
54
+
55
+ }
56
+
57
+ }
58
+
59
+ update_post_meta($trnsl_product_id,'_swatch_type_options',$tr_atts); // Meta gets overwritten
60
+ }
61
+
62
+ }
compatibility/class-wcml-vpc.php CHANGED
@@ -1,20 +1,20 @@
1
- <?php
2
-
3
- class WCML_Vpc {
4
-
5
- function __construct() {
6
- add_filter( 'wcml_calculate_totals_exception', array( $this, 'wcml_vpc_cart_exc' ), 10, 2 );
7
- }
8
-
9
- function wcml_vpc_cart_exc( $exc, $cart ) {
10
-
11
- foreach( $cart->cart_contents as $cart_item ){
12
- if ( array_key_exists( 'visual-product-configuration', $cart_item ) ) {
13
- return false;
14
- }
15
- }
16
-
17
- return $exc;
18
- }
19
-
20
- }
1
+ <?php
2
+
3
+ class WCML_Vpc {
4
+
5
+ function __construct() {
6
+ add_filter( 'wcml_calculate_totals_exception', array( $this, 'wcml_vpc_cart_exc' ), 10, 2 );
7
+ }
8
+
9
+ function wcml_vpc_cart_exc( $exc, $cart ) {
10
+
11
+ foreach( $cart->cart_contents as $cart_item ){
12
+ if ( array_key_exists( 'visual-product-configuration', $cart_item ) ) {
13
+ return false;
14
+ }
15
+ }
16
+
17
+ return $exc;
18
+ }
19
+
20
+ }
compatibility/class-wcml-wc-ajax-cart.php CHANGED
@@ -1,16 +1,16 @@
1
- <?php
2
-
3
- class WCML_WC_Ajax_Cart{
4
-
5
- function __construct() {
6
- add_filter( 'wcml_calculate_totals_exception', array( $this, 'wac_update_ajax' ), 9 );
7
- }
8
-
9
- function wac_update_ajax( $exc ) {
10
- if ( !empty($_POST['is_wac_ajax'])) {
11
- return false;
12
- }
13
- return $exc;
14
- }
15
-
16
- }
1
+ <?php
2
+
3
+ class WCML_WC_Ajax_Cart{
4
+
5
+ function __construct() {
6
+ add_filter( 'wcml_calculate_totals_exception', array( $this, 'wac_update_ajax' ), 9 );
7
+ }
8
+
9
+ function wac_update_ajax( $exc ) {
10
+ if ( !empty($_POST['is_wac_ajax'])) {
11
+ return false;
12
+ }
13
+ return $exc;
14
+ }
15
+
16
+ }
compatibility/class-wcml-wc-name-your-price.php CHANGED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- class WCML_WC_Name_Your_Price{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
-
9
- }
10
-
11
- function init(){
12
- if( !is_admin() ){
13
- add_filter('woocommerce_raw_suggested_price', array($this, 'product_price_filter'), 10, 2);
14
- add_filter('woocommerce_raw_minimum_price', array($this, 'product_price_filter'), 10, 2);
15
- }
16
- }
17
-
18
- function product_price_filter($price, $product){
19
-
20
- return apply_filters('wcml_raw_price_amount', $price );
21
-
22
- }
23
-
24
- }
1
+ <?php
2
+
3
+ class WCML_WC_Name_Your_Price{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'),9);
8
+
9
+ }
10
+
11
+ function init(){
12
+ if( !is_admin() ){
13
+ add_filter('woocommerce_raw_suggested_price', array($this, 'product_price_filter'), 10, 2);
14
+ add_filter('woocommerce_raw_minimum_price', array($this, 'product_price_filter'), 10, 2);
15
+ }
16
+ }
17
+
18
+ function product_price_filter($price, $product){
19
+
20
+ return apply_filters('wcml_raw_price_amount', $price );
21
+
22
+ }
23
+
24
+ }
compatibility/class-wcml-wc-subscriptions.php CHANGED
@@ -1,185 +1,185 @@
1
- <?php
2
-
3
- class WCML_WC_Subscriptions{
4
-
5
- private $new_subscription = false;
6
-
7
- function __construct(){
8
-
9
- add_action('init', array($this, 'init'),9);
10
- add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
11
- add_filter('woocommerce_subscription_lengths', array($this, 'woocommerce_subscription_lengths'), 10, 2);
12
-
13
- add_filter('wcml_register_endpoints_query_vars', array($this, 'register_endpoint' ), 10, 3 );
14
- add_filter('wcml_endpoint_permalink_filter', array($this, 'endpoint_permalink_filter'), 10, 2);
15
-
16
- //custom prices
17
- add_filter( 'wcml_custom_prices_fields', array( $this, 'set_prices_fields' ), 10, 2 );
18
- add_filter( 'wcml_custom_prices_strings', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
19
- add_filter( 'wcml_custom_prices_fields_labels', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
20
- add_filter( 'wcml_update_custom_prices_values', array( $this, 'update_custom_prices_values' ), 10 ,3 );
21
- add_action( 'wcml_after_custom_prices_block', array( $this, 'new_subscription_prices_block') );
22
-
23
- // reenable coupons for subscriptions when multicurrency is on
24
- add_action('woocommerce_subscription_cart_after_grouping', array($this, 'woocommerce_subscription_cart_after_grouping'));
25
- }
26
-
27
- function init(){
28
- if( !is_admin() ){
29
- add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
30
- }
31
- }
32
-
33
- function product_price_filter($subscription_sign_up_fee, $product){
34
-
35
- $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
36
-
37
- return $subscription_sign_up_fee;
38
- }
39
-
40
- function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
41
- global $wpdb;
42
- $get_variation_term_taxonomy_id = $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.slug = 'variable-subscription'");
43
-
44
- if(!empty($get_variation_term_taxonomy_id)){
45
- $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
46
- }
47
-
48
- return $get_variation_term_taxonomy_ids;
49
- }
50
-
51
- public function woocommerce_subscription_lengths($subscription_ranges, $subscription_period) {
52
-
53
- if (is_array($subscription_ranges)) {
54
- foreach ($subscription_ranges as $period => $ranges) {
55
- if (is_array($ranges)) {
56
- foreach ($ranges as $range) {
57
- if ($range == "9 months") {
58
- $breakpoint = true;
59
- }
60
- $new_subscription_ranges[$period][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range);
61
- }
62
- }
63
- }
64
- }
65
-
66
- return isset($new_subscription_ranges) ? $new_subscription_ranges : $subscription_ranges;
67
- }
68
-
69
- public function woocommerce_subscription_cart_after_grouping() {
70
- global $woocommerce_wpml;
71
-
72
- if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
73
- remove_action('woocommerce_before_calculate_totals', 'WC_Subscriptions_Coupon::remove_coupons', 10);
74
- }
75
-
76
- }
77
-
78
- function set_prices_fields( $fields, $product_id ){
79
- if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
80
- $fields[] = '_subscription_sign_up_fee';
81
- }
82
-
83
- return $fields;
84
-
85
- }
86
-
87
- function set_labels_for_prices_fields( $labels, $product_id ){
88
-
89
- if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
90
- $labels[ '_regular_price' ] = __( 'Subscription Price', 'woocommerce-multilingual' );
91
- $labels[ '_subscription_sign_up_fee' ] = __( 'Sign-up Fee', 'woocommerce-multilingual' );
92
- }
93
-
94
- return $labels;
95
-
96
- }
97
-
98
- function update_custom_prices_values( $prices, $code, $variation_id = false ){
99
-
100
- if( isset( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] ) ){
101
- $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] );
102
- }
103
-
104
- if( $variation_id && isset( $_POST[ '_custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] ) ){
105
- $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom__custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] );
106
- }
107
-
108
- return $prices;
109
-
110
- }
111
-
112
- function is_subscriptions_product( $product_id ){
113
- global $wpdb;
114
- $get_variation_term_taxonomy_ids = $wpdb->get_col("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.slug IN ( 'subscription', 'variable-subscription' ) AND tt.taxonomy = 'product_type'");
115
-
116
- if( get_post_type( $product_id ) == 'product_variation' ){
117
- $product_id = wp_get_post_parent_id( $product_id );
118
- }
119
-
120
- $is_subscriptions_product = $wpdb->get_var($wpdb->prepare("SELECT count(object_id) FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN (".join(',',$get_variation_term_taxonomy_ids).")",$product_id));
121
- return $is_subscriptions_product;
122
- }
123
-
124
- function new_subscription_prices_block( $product_id ){
125
- global $woocommerce_wpml;
126
- if( $product_id == 'new' ){
127
- $this->new_subscription = true;
128
- echo '<div class="wcml_prices_if_subscription" style="display: none">';
129
- $custom_prices_ui = new WCML_Custom_Prices_UI( $woocommerce_wpml, 'new' );
130
- $custom_prices_ui->show();
131
- echo '</div>';
132
- ?>
133
- <script>
134
- jQuery(document).ready(function($) {
135
- jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new_subscription]').attr( 'id', '_wcml_custom_prices[new_subscription]');
136
- jQuery('.wcml_prices_if_subscription .wcml_custom_prices_options_block>label').attr('for', '_wcml_custom_prices[new_subscription]');
137
- jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
138
- jQuery(this).attr('name', jQuery(this).attr('name')+'_subscription');
139
- });
140
-
141
- jQuery('.options_group>.wcml_custom_prices_block .wcml_custom_prices_input:first-child').click();
142
- jQuery('.options_group>.wcml_custom_prices_block .wcml_schedule_options .wcml_schedule_input:first-child').click();
143
-
144
- jQuery(document).on('change', 'select#product-type', function () {
145
- if (jQuery(this).val() == 'subscription') {
146
- jQuery('.wcml_prices_if_subscription').show();
147
- jQuery('.options_group>.wcml_custom_prices_block').hide();
148
- } else if (jQuery(this).val() != 'variable-subscription') {
149
- jQuery('.wcml_prices_if_subscription').hide();
150
- jQuery('.options_group>.wcml_custom_prices_block').show();
151
- }
152
- });
153
-
154
- jQuery(document).on('click', '#publish', function () {
155
- if ( jQuery('.wcml_prices_if_subscription').is( ':visible' ) ) {
156
- jQuery('.options_group>.wcml_custom_prices_block').remove();
157
- jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new]');
158
- jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
159
- jQuery(this).attr('name', jQuery(this).attr('name').replace('_subscription','') );
160
- });
161
- }else{
162
- jQuery('.wcml_prices_if_subscription').remove();
163
- }
164
- });
165
- });
166
- </script>
167
- <?php
168
- }
169
- }
170
-
171
- function register_endpoint( $query_vars, $wc_vars, $obj ){
172
-
173
- $query_vars[ 'view-subscription' ] = $obj->get_endpoint_translation( 'view-subscription', isset( $wc_vars['view-subscription'] ) ? $wc_vars['view-subscription'] : 'view-subscription' );
174
- return $query_vars;
175
- }
176
-
177
- function endpoint_permalink_filter( $endpoint, $key ){
178
-
179
- if( $key == 'view-subscription' ){
180
- return 'view-subscription';
181
- }
182
-
183
- return $endpoint;
184
- }
185
- }
1
+ <?php
2
+
3
+ class WCML_WC_Subscriptions{
4
+
5
+ private $new_subscription = false;
6
+
7
+ function __construct(){
8
+
9
+ add_action('init', array($this, 'init'),9);
10
+ add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
11
+ add_filter('woocommerce_subscription_lengths', array($this, 'woocommerce_subscription_lengths'), 10, 2);
12
+
13
+ add_filter('wcml_register_endpoints_query_vars', array($this, 'register_endpoint' ), 10, 3 );
14
+ add_filter('wcml_endpoint_permalink_filter', array($this, 'endpoint_permalink_filter'), 10, 2);
15
+
16
+ //custom prices
17
+ add_filter( 'wcml_custom_prices_fields', array( $this, 'set_prices_fields' ), 10, 2 );
18
+ add_filter( 'wcml_custom_prices_strings', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
19
+ add_filter( 'wcml_custom_prices_fields_labels', array( $this, 'set_labels_for_prices_fields' ), 10, 2 );
20
+ add_filter( 'wcml_update_custom_prices_values', array( $this, 'update_custom_prices_values' ), 10 ,3 );
21
+ add_action( 'wcml_after_custom_prices_block', array( $this, 'new_subscription_prices_block') );
22
+
23
+ // reenable coupons for subscriptions when multicurrency is on
24
+ add_action('woocommerce_subscription_cart_after_grouping', array($this, 'woocommerce_subscription_cart_after_grouping'));
25
+ }
26
+
27
+ function init(){
28
+ if( !is_admin() ){
29
+ add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
30
+ }
31
+ }
32
+
33
+ function product_price_filter($subscription_sign_up_fee, $product){
34
+
35
+ $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
36
+
37
+ return $subscription_sign_up_fee;
38
+ }
39
+
40
+ function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
41
+ global $wpdb;
42
+ $get_variation_term_taxonomy_id = $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.slug = 'variable-subscription'");
43
+
44
+ if(!empty($get_variation_term_taxonomy_id)){
45
+ $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
46
+ }
47
+
48
+ return $get_variation_term_taxonomy_ids;
49
+ }
50
+
51
+ public function woocommerce_subscription_lengths($subscription_ranges, $subscription_period) {
52
+
53
+ if (is_array($subscription_ranges)) {
54
+ foreach ($subscription_ranges as $period => $ranges) {
55
+ if (is_array($ranges)) {
56
+ foreach ($ranges as $range) {
57
+ if ($range == "9 months") {
58
+ $breakpoint = true;
59
+ }
60
+ $new_subscription_ranges[$period][] = apply_filters( 'wpml_translate_single_string', $range, 'wc_subscription_ranges', $range);
61
+ }
62
+ }
63
+ }
64
+ }
65
+
66
+ return isset($new_subscription_ranges) ? $new_subscription_ranges : $subscription_ranges;
67
+ }
68
+
69
+ public function woocommerce_subscription_cart_after_grouping() {
70
+ global $woocommerce_wpml;
71
+
72
+ if( $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ){
73
+ remove_action('woocommerce_before_calculate_totals', 'WC_Subscriptions_Coupon::remove_coupons', 10);
74
+ }
75
+
76
+ }
77
+
78
+ function set_prices_fields( $fields, $product_id ){
79
+ if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
80
+ $fields[] = '_subscription_sign_up_fee';
81
+ }
82
+
83
+ return $fields;
84
+
85
+ }
86
+
87
+ function set_labels_for_prices_fields( $labels, $product_id ){
88
+
89
+ if( $this->is_subscriptions_product( $product_id ) || $this->new_subscription ){
90
+ $labels[ '_regular_price' ] = __( 'Subscription Price', 'woocommerce-multilingual' );
91
+ $labels[ '_subscription_sign_up_fee' ] = __( 'Sign-up Fee', 'woocommerce-multilingual' );
92
+ }
93
+
94
+ return $labels;
95
+
96
+ }
97
+
98
+ function update_custom_prices_values( $prices, $code, $variation_id = false ){
99
+
100
+ if( isset( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] ) ){
101
+ $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom_subscription_sign_up_fee' ][ $code ] );
102
+ }
103
+
104
+ if( $variation_id && isset( $_POST[ '_custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] ) ){
105
+ $prices[ '_subscription_sign_up_fee' ] = wc_format_decimal( $_POST[ '_custom__custom_variation_subscription_sign_up_fee' ][ $code ][ $variation_id ] );
106
+ }
107
+
108
+ return $prices;
109
+
110
+ }
111
+
112
+ function is_subscriptions_product( $product_id ){
113
+ global $wpdb;
114
+ $get_variation_term_taxonomy_ids = $wpdb->get_col("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.slug IN ( 'subscription', 'variable-subscription' ) AND tt.taxonomy = 'product_type'");
115
+
116
+ if( get_post_type( $product_id ) == 'product_variation' ){
117
+ $product_id = wp_get_post_parent_id( $product_id );
118
+ }
119
+
120
+ $is_subscriptions_product = $wpdb->get_var($wpdb->prepare("SELECT count(object_id) FROM $wpdb->term_relationships WHERE object_id = %d AND term_taxonomy_id IN (".join(',',$get_variation_term_taxonomy_ids).")",$product_id));
121
+ return $is_subscriptions_product;
122
+ }
123
+
124
+ function new_subscription_prices_block( $product_id ){
125
+ global $woocommerce_wpml;
126
+ if( $product_id == 'new' ){
127
+ $this->new_subscription = true;
128
+ echo '<div class="wcml_prices_if_subscription" style="display: none">';
129
+ $custom_prices_ui = new WCML_Custom_Prices_UI( $woocommerce_wpml, 'new' );
130
+ $custom_prices_ui->show();
131
+ echo '</div>';
132
+ ?>
133
+ <script>
134
+ jQuery(document).ready(function($) {
135
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new_subscription]').attr( 'id', '_wcml_custom_prices[new_subscription]');
136
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_options_block>label').attr('for', '_wcml_custom_prices[new_subscription]');
137
+ jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
138
+ jQuery(this).attr('name', jQuery(this).attr('name')+'_subscription');
139
+ });
140
+
141
+ jQuery('.options_group>.wcml_custom_prices_block .wcml_custom_prices_input:first-child').click();
142
+ jQuery('.options_group>.wcml_custom_prices_block .wcml_schedule_options .wcml_schedule_input:first-child').click();
143
+
144
+ jQuery(document).on('change', 'select#product-type', function () {
145
+ if (jQuery(this).val() == 'subscription') {
146
+ jQuery('.wcml_prices_if_subscription').show();
147
+ jQuery('.options_group>.wcml_custom_prices_block').hide();
148
+ } else if (jQuery(this).val() != 'variable-subscription') {
149
+ jQuery('.wcml_prices_if_subscription').hide();
150
+ jQuery('.options_group>.wcml_custom_prices_block').show();
151
+ }
152
+ });
153
+
154
+ jQuery(document).on('click', '#publish', function () {
155
+ if ( jQuery('.wcml_prices_if_subscription').is( ':visible' ) ) {
156
+ jQuery('.options_group>.wcml_custom_prices_block').remove();
157
+ jQuery('.wcml_prices_if_subscription .wcml_custom_prices_input').attr('name', '_wcml_custom_prices[new]');
158
+ jQuery('.wcml_prices_if_subscription .wcml_schedule_input').each( function(){
159
+ jQuery(this).attr('name', jQuery(this).attr('name').replace('_subscription','') );
160
+ });
161
+ }else{
162
+ jQuery('.wcml_prices_if_subscription').remove();
163
+ }
164
+ });
165
+ });
166
+ </script>
167
+ <?php
168
+ }
169
+ }
170
+
171
+ function register_endpoint( $query_vars, $wc_vars, $obj ){
172
+
173
+ $query_vars[ 'view-subscription' ] = $obj->get_endpoint_translation( 'view-subscription', isset( $wc_vars['view-subscription'] ) ? $wc_vars['view-subscription'] : 'view-subscription' );
174
+ return $query_vars;
175
+ }
176
+
177
+ function endpoint_permalink_filter( $endpoint, $key ){
178
+
179
+ if( $key == 'view-subscription' ){
180
+ return 'view-subscription';
181
+ }
182
+
183
+ return $endpoint;
184
+ }
185
+ }
compatibility/class-wcml-wcexporter.php CHANGED
@@ -1,70 +1,70 @@
1
- <?php
2
-
3
- class WCML_wcExporter{
4
-
5
- function __construct(){
6
-
7
- add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
- add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
- add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
- add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
- add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
- add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
- add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
-
15
- }
16
-
17
- function woo_ce_fields($fields){
18
- $fields[] = array(
19
- 'name' => 'language',
20
- 'label' => __( 'Language', 'woo_ce' ),
21
- 'default' => 1
22
- );
23
- $fields[] = array(
24
- 'name' => 'translation_of',
25
- 'label' => __( 'Translation of', 'woo_ce' ),
26
- 'default' => 1
27
- );
28
- return $fields;
29
- }
30
-
31
- function woo_ce_order_fields($fields){
32
- $fields[] = array(
33
- 'name' => 'language',
34
- 'label' => __( 'Language', 'woo_ce' ),
35
- 'default' => 1
36
- );
37
-
38
- return $fields;
39
- }
40
-
41
- function woo_ce_product_item($data, $product_id){
42
- global $sitepress,$woocommerce_wpml;
43
-
44
- $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
- $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
-
47
- return $data;
48
- }
49
-
50
- function woo_ce_category_item($data){
51
- global $sitepress;
52
-
53
- $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
- $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
-
56
- return $data;
57
- }
58
-
59
- function woo_ce_tags($tags){
60
- global $sitepress;
61
-
62
- foreach($tags as $key=>$tag){
63
- $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
- $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
- }
66
-
67
- return $tags;
68
- }
69
-
70
- }
1
+ <?php
2
+
3
+ class WCML_wcExporter{
4
+
5
+ function __construct(){
6
+
7
+ add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
+ add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
+ add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
+ add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
+ add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
+ add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
+ add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
+
15
+ }
16
+
17
+ function woo_ce_fields($fields){
18
+ $fields[] = array(
19
+ 'name' => 'language',
20
+ 'label' => __( 'Language', 'woo_ce' ),
21
+ 'default' => 1
22
+ );
23
+ $fields[] = array(
24
+ 'name' => 'translation_of',
25
+ 'label' => __( 'Translation of', 'woo_ce' ),
26
+ 'default' => 1
27
+ );
28
+ return $fields;
29
+ }
30
+
31
+ function woo_ce_order_fields($fields){
32
+ $fields[] = array(
33
+ 'name' => 'language',
34
+ 'label' => __( 'Language', 'woo_ce' ),
35
+ 'default' => 1
36
+ );
37
+
38
+ return $fields;
39
+ }
40
+
41
+ function woo_ce_product_item($data, $product_id){
42
+ global $sitepress,$woocommerce_wpml;
43
+
44
+ $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
+ $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
+
47
+ return $data;
48
+ }
49
+
50
+ function woo_ce_category_item($data){
51
+ global $sitepress;
52
+
53
+ $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
+ $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
+
56
+ return $data;
57
+ }
58
+
59
+ function woo_ce_tags($tags){
60
+ global $sitepress;
61
+
62
+ foreach($tags as $key=>$tag){
63
+ $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
+ $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
+ }
66
+
67
+ return $tags;
68
+ }
69
+
70
+ }
compatibility/class-wcml-wpseo.php CHANGED
@@ -1,41 +1,41 @@
1
- <?php
2
-
3
- class WCML_WPSEO{
4
-
5
- function __construct(){
6
-
7
- add_filter( 'wcml_product_content_label', array( $this, 'wpseo_custom_field_label' ), 10, 2 );
8
-
9
- if( defined( 'WPSEO_VERSION') && defined( 'WPSEO_PATH' ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wpml-wcml' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'products' ){
10
- if( version_compare( WPSEO_VERSION, '3', '<' ) ) {
11
- require_once WPSEO_PATH . 'admin/class-metabox.php';
12
- } elseif( file_exists( WPSEO_PATH . 'admin/metabox/class-metabox.php' ) ) {
13
- require_once WPSEO_PATH . 'admin/metabox/class-metabox.php';
14
- }
15
- }
16
-
17
- }
18
-
19
- function wpseo_custom_field_label( $field, $product_id ){
20
- global $woocommerce_wpml, $wpseo_metabox;
21
-
22
- $yoast_seo_fields = array( '_yoast_wpseo_focuskw', '_yoast_wpseo_title', '_yoast_wpseo_metadesc' );
23
-
24
- if ( !is_array( maybe_unserialize( get_post_meta( $product_id, $field, true ) ) ) ) {
25
-
26
- if ( !is_null( $wpseo_metabox ) && in_array( $field, $yoast_seo_fields ) ) {
27
-
28
- $wpseo_metabox_values = $wpseo_metabox->get_meta_boxes( 'product' );
29
-
30
- $label = $wpseo_metabox_values[ str_replace( '_yoast_wpseo_', '', $field ) ][ 'title' ];
31
-
32
- return $label;
33
- }
34
- }
35
-
36
- return $field;
37
- }
38
-
39
-
40
- }
41
-
1
+ <?php
2
+
3
+ class WCML_WPSEO{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'wcml_product_content_label', array( $this, 'wpseo_custom_field_label' ), 10, 2 );
8
+
9
+ if( defined( 'WPSEO_VERSION') && defined( 'WPSEO_PATH' ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wpml-wcml' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'products' ){
10
+ if( version_compare( WPSEO_VERSION, '3', '<' ) ) {
11
+ require_once WPSEO_PATH . 'admin/class-metabox.php';
12
+ } elseif( file_exists( WPSEO_PATH . 'admin/metabox/class-metabox.php' ) ) {
13
+ require_once WPSEO_PATH . 'admin/metabox/class-metabox.php';
14
+ }
15
+ }
16
+
17
+ }
18
+
19
+ function wpseo_custom_field_label( $field, $product_id ){
20
+ global $woocommerce_wpml, $wpseo_metabox;
21
+
22
+ $yoast_seo_fields = array( '_yoast_wpseo_focuskw', '_yoast_wpseo_title', '_yoast_wpseo_metadesc' );
23
+
24
+ if ( !is_array( maybe_unserialize( get_post_meta( $product_id, $field, true ) ) ) ) {
25
+
26
+ if ( !is_null( $wpseo_metabox ) && in_array( $field, $yoast_seo_fields ) ) {
27
+
28
+ $wpseo_metabox_values = $wpseo_metabox->get_meta_boxes( 'product' );
29
+
30
+ $label = $wpseo_metabox_values[ str_replace( '_yoast_wpseo_', '', $field ) ][ 'title' ];
31
+
32
+ return $label;
33
+ }
34
+ }
35
+
36
+ return $field;
37
+ }
38
+
39
+
40
+ }
41
+
compatibility/res/css/wcml-bookings.css CHANGED
@@ -1,61 +1,61 @@
1
- .wcml_custom_cost_field{
2
- display: none;
3
- clear: both;
4
- }
5
-
6
- .wcml_bookings_range_block,
7
- .wcml_bookings_person_block,
8
- .wcml_bookings_resource_block{
9
- padding: 5px 0;
10
- display: -webkit-flex;
11
- display: flex;
12
- display: -moz-box;
13
- -webkit-flex-direction: row;
14
- flex-direction: row;
15
- }
16
-
17
- .wcml_bookings_range_block label,
18
- .wcml_bookings_person_block label,
19
- .wcml_bookings_resource_block label{
20
- width: auto;
21
- margin: 0;
22
- padding: 6px 7px;
23
- }
24
-
25
- .wcml_custom_costs{
26
- padding: 9px 9px 0;
27
- display: inline-block;
28
- width: 100%;
29
- float:left;
30
- margin-top:10px;
31
- }
32
-
33
- #bookings_pricing .wcml_custom_costs label,
34
- .woocommerce_options_panel .wcml_custom_costs label{
35
- width: auto;
36
- margin: 0 5px;
37
- float: left;
38
- }
39
- .woocommerce_options_panel .wcml_bookings_range_block label{
40
- width: 10px;;
41
- margin: 0;
42
- padding: inherit;
43
- }
44
-
45
- #bookings_pricing .wcml_custom_cost_field label,
46
- #bookings_resources .woocommerce_booking_resource .wcml_bookings_resource_block label{
47
- width: 20px;
48
- margin: 0 5px;
49
- float: left;
50
- }
51
-
52
- .wcml_custom_costs input{
53
- width: 16px;
54
- clear: both;
55
- margin: 2px 5px 2px 0;
56
- float: left;
57
- }
58
- input.wcml_bookings_custom_price,
59
- #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
60
- background-color: #F5F2E1;
61
- }
1
+ .wcml_custom_cost_field{
2
+ display: none;
3
+ clear: both;
4
+ }
5
+
6
+ .wcml_bookings_range_block,
7
+ .wcml_bookings_person_block,
8
+ .wcml_bookings_resource_block{
9
+ padding: 5px 0;
10
+ display: -webkit-flex;
11
+ display: flex;
12
+ display: -moz-box;
13
+ -webkit-flex-direction: row;
14
+ flex-direction: row;
15
+ }
16
+
17
+ .wcml_bookings_range_block label,
18
+ .wcml_bookings_person_block label,
19
+ .wcml_bookings_resource_block label{
20
+ width: auto;
21
+ margin: 0;
22
+ padding: 6px 7px;
23
+ }
24
+
25
+ .wcml_custom_costs{
26
+ padding: 9px 9px 0;
27
+ display: inline-block;
28
+ width: 100%;
29
+ float:left;
30
+ margin-top:10px;
31
+ }
32
+
33
+ #bookings_pricing .wcml_custom_costs label,
34
+ .woocommerce_options_panel .wcml_custom_costs label{
35
+ width: auto;
36
+ margin: 0 5px;
37
+ float: left;
38
+ }
39
+ .woocommerce_options_panel .wcml_bookings_range_block label{
40
+ width: 10px;;
41
+ margin: 0;
42
+ padding: inherit;
43
+ }
44
+
45
+ #bookings_pricing .wcml_custom_cost_field label,
46
+ #bookings_resources .woocommerce_booking_resource .wcml_bookings_resource_block label{
47
+ width: 20px;
48
+ margin: 0 5px;
49
+ float: left;
50
+ }
51
+
52
+ .wcml_custom_costs input{
53
+ width: 16px;
54
+ clear: both;
55
+ margin: 2px 5px 2px 0;
56
+ float: left;
57
+ }
58
+ input.wcml_bookings_custom_price,
59
+ #bookings_pricing .table_grid table td input.wcml_bookings_custom_price{
60
+ background-color: #F5F2E1;
61
+ }
compatibility/res/js/wcml-adventure-tours.js CHANGED
@@ -1,31 +1,31 @@
1
- jQuery( document ).ready( function( $ ){
2
-
3
-
4
- $( '.wcml_custom_cost_field').each( function(){
5
-
6
- var tour_id = $(this).attr('data-tour');
7
-
8
- $('input[name="tour-booking-row['+tour_id+'][spec_price]"]').after( $(this) );
9
-
10
- if( $( '.wcml_custom_prices_input:checked' ).val() == 1 ){
11
- $(this).show();
12
- }
13
-
14
- });
15
-
16
- $(document).on( 'change', '.wcml_custom_prices_input', function(){
17
-
18
- if( $(this).val() == 1 ){
19
-
20
- $( '.wcml_custom_cost_field' ).show();
21
-
22
- }else{
23
-
24
- $( '.wcml_custom_cost_field' ).hide();
25
-
26
- }
27
-
28
- });
29
-
30
- });
31
-
1
+ jQuery( document ).ready( function( $ ){
2
+
3
+
4
+ $( '.wcml_custom_cost_field').each( function(){
5
+
6
+ var tour_id = $(this).attr('data-tour');
7
+
8
+ $('input[name="tour-booking-row['+tour_id+'][spec_price]"]').after( $(this) );
9
+
10
+ if( $( '.wcml_custom_prices_input:checked' ).val() == 1 ){
11
+ $(this).show();
12
+ }
13
+
14
+ });
15
+
16
+ $(document).on( 'change', '.wcml_custom_prices_input', function(){
17
+
18
+ if( $(this).val() == 1 ){
19
+
20
+ $( '.wcml_custom_cost_field' ).show();
21
+
22
+ }else{
23
+
24
+ $( '.wcml_custom_cost_field' ).hide();
25
+
26
+ }
27
+
28
+ });
29
+
30
+ });
31
+
compatibility/res/js/wcml-bookings.js CHANGED
@@ -1,91 +1,91 @@
1
- jQuery( document ).ready( function( $ ){
2
-
3
- wcml_lock_bookings_fields();
4
-
5
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ){
6
-
7
- $( '.wcml_custom_cost_field' ).show();
8
-
9
- }
10
-
11
- $(document).on( 'change', '.wcml_custom_costs_input', function(){
12
-
13
- if( $(this).val() == 1 ){
14
-
15
- $( '.wcml_custom_cost_field' ).show();
16
-
17
- }else{
18
-
19
- $( '.wcml_custom_cost_field' ).hide();
20
-
21
- }
22
-
23
- });
24
-
25
- $(document).on( 'mouseout', '.add_row', function(){
26
-
27
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
28
-
29
- $( '.wcml_custom_cost_field' ).show();
30
-
31
- }
32
-
33
- });
34
-
35
- $(document).on( 'mouseout', '.add_person', function(){
36
-
37
- if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
38
-
39
- setTimeout(
40
- function() {
41
- $( '.wcml_custom_cost_field' ).show();
42
- }, 3000);
43
-
44
- }
45
-
46
- });
47
-
48
- function wcml_lock_bookings_fields(){
49
- //lock fields
50
- if( typeof lock_settings != 'undefined' && typeof lock_settings.lock_fields != 'undefined' && lock_settings.lock_fields == 1 ){
51
-
52
- $('#bookings_pricing input[type="number"],' +
53
- '#accommodation_bookings_rates input[type="number"], ' +
54
- '#bookings_resources input[type="number"], ' +
55
- '#bookings_availability input[type="number"], ' +
56
- '#bookings_availability input[type="time"], ' +
57
-
58
- '#bookings_persons input[type="number"]').each(function(){
59
- $(this).attr('readonly','readonly');
60
- $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
61
- });
62
-
63
- var buttons = [ 'add_resource', 'add_row','remove_booking_resource','remove_booking_person','add_person' ];
64
-
65
- for (i = 0; i < buttons.length; i++) {
66
- $('.'+buttons[i]).attr('disabled','disabled');
67
- $('.'+buttons[i]).unbind('click');
68
- $('.'+buttons[i]).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
69
- }
70
- $('.add_row').removeAttr('data-row');
71
-
72
- $('form#post input[type="submit"]').click(function(){
73
-
74
- for (i = 0; i < non_standard_fields.ids.length; i++) {
75
- $('#'+non_standard_fields.ids[i]).removeAttr('disabled');
76
- }
77
-
78
- $('#bookings_pricing select, #bookings_resources select, #bookings_availability select,#bookings_persons input[type="checkbox"]').each(function(){
79
- $(this).removeAttr('disabled');
80
- });
81
-
82
- });
83
-
84
-
85
- }
86
- }
87
-
88
- });
89
-
90
-
91
-
1
+ jQuery( document ).ready( function( $ ){
2
+
3
+ wcml_lock_bookings_fields();
4
+
5
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ){
6
+
7
+ $( '.wcml_custom_cost_field' ).show();
8
+
9
+ }
10
+
11
+ $(document).on( 'change', '.wcml_custom_costs_input', function(){
12
+
13
+ if( $(this).val() == 1 ){
14
+
15
+ $( '.wcml_custom_cost_field' ).show();
16
+
17
+ }else{
18
+
19
+ $( '.wcml_custom_cost_field' ).hide();
20
+
21
+ }
22
+
23
+ });
24
+
25
+ $(document).on( 'mouseout', '.add_row', function(){
26
+
27
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
28
+
29
+ $( '.wcml_custom_cost_field' ).show();
30
+
31
+ }
32
+
33
+ });
34
+
35
+ $(document).on( 'mouseout', '.add_person', function(){
36
+
37
+ if( $( '.wcml_custom_costs_input:checked' ).val() == 1 ) {
38
+
39
+ setTimeout(
40
+ function() {
41
+ $( '.wcml_custom_cost_field' ).show();
42
+ }, 3000);
43
+
44
+ }
45
+
46
+ });
47
+
48
+ function wcml_lock_bookings_fields(){
49
+ //lock fields
50
+ if( typeof lock_settings != 'undefined' && typeof lock_settings.lock_fields != 'undefined' && lock_settings.lock_fields == 1 ){
51
+
52
+ $('#bookings_pricing input[type="number"],' +
53
+ '#accommodation_bookings_rates input[type="number"], ' +
54
+ '#bookings_resources input[type="number"], ' +
55
+ '#bookings_availability input[type="number"], ' +
56
+ '#bookings_availability input[type="time"], ' +
57
+
58
+ '#bookings_persons input[type="number"]').each(function(){
59
+ $(this).attr('readonly','readonly');
60
+ $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
61
+ });
62
+
63
+ var buttons = [ 'add_resource', 'add_row','remove_booking_resource','remove_booking_person','add_person' ];
64
+
65
+ for (i = 0; i < buttons.length; i++) {
66
+ $('.'+buttons[i]).attr('disabled','disabled');
67
+ $('.'+buttons[i]).unbind('click');
68
+ $('.'+buttons[i]).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
69
+ }
70
+ $('.add_row').removeAttr('data-row');
71
+
72
+ $('form#post input[type="submit"]').click(function(){
73
+
74
+ for (i = 0; i < non_standard_fields.ids.length; i++) {
75
+ $('#'+non_standard_fields.ids[i]).removeAttr('disabled');
76
+ }
77
+
78
+ $('#bookings_pricing select, #bookings_resources select, #bookings_availability select,#bookings_persons input[type="checkbox"]').each(function(){
79
+ $(this).removeAttr('disabled');
80
+ });
81
+
82
+ });
83
+
84
+
85
+ }
86
+ }
87
+
88
+ });
89
+
90
+
91
+
compatibility/res/js/wcml-composite.js CHANGED
@@ -1,32 +1,32 @@
1
- jQuery( document ).ready( function( $ ){
2
- //lock fields
3
- if( typeof lock_settings != 'undefined' && typeof lock_settings.lock_fields != 'undefined' && lock_settings.lock_fields == 1 ) {
4
-
5
- $('#bto_config_group_inner .remove_row,.add_bto_group,.save_composition').each(function(){
6
- $(this).attr('disabled','disabled');
7
- $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
8
- });
9
-
10
- $('#bto_product_data li,#bto_config_group_inner .subsubsub li a').bind({
11
- click: function(e) {
12
- return false;
13
- }
14
- });
15
-
16
-
17
- //components fields
18
- jQuery('input.group_quantity_min,input.group_quantity_max,input.group_discount,.bto_query_type_selector .wc-product-search').each(function(){
19
- jQuery(this).attr('readonly','readonly');
20
- jQuery(this).after(jQuery('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
21
- });
22
-
23
- jQuery('select.bto_query_type,.component_options_style select,.group_optional input').each(function(){
24
- jQuery(this).attr('disabled','disabled');
25
- jQuery(this).after(jQuery('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
26
- });
27
- }
28
-
29
- });
30
-
31
-
32
-
1
+ jQuery( document ).ready( function( $ ){
2
+ //lock fields
3
+ if( typeof lock_settings != 'undefined' && typeof lock_settings.lock_fields != 'undefined' && lock_settings.lock_fields == 1 ) {
4
+
5
+ $('#bto_config_group_inner .remove_row,.add_bto_group,.save_composition').each(function(){
6
+ $(this).attr('disabled','disabled');
7
+ $(this).after($('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
8
+ });
9
+
10
+ $('#bto_product_data li,#bto_config_group_inner .subsubsub li a').bind({
11
+ click: function(e) {
12
+ return false;
13
+ }
14
+ });
15
+
16
+
17
+ //components fields
18
+ jQuery('input.group_quantity_min,input.group_quantity_max,input.group_discount,.bto_query_type_selector .wc-product-search').each(function(){
19
+ jQuery(this).attr('readonly','readonly');
20
+ jQuery(this).after(jQuery('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
21
+ });
22
+
23
+ jQuery('select.bto_query_type,.component_options_style select,.group_optional input').each(function(){
24
+ jQuery(this).attr('disabled','disabled');
25
+ jQuery(this).after(jQuery('.wcml_lock_img').clone().removeClass('wcml_lock_img').show());
26
+ });
27
+ }
28
+
29
+ });
30
+
31
+
32
+
embedded/composer/installers/.gitignore DELETED
@@ -1,3 +0,0 @@
1
- vendor/
2
- composer.lock
3
- .idea/
 
 
 
embedded/composer/installers/composer.json DELETED
@@ -1,92 +0,0 @@
1
- {
2
- "name": "composer/installers",
3
- "type": "composer-plugin",
4
- "license": "MIT",
5
- "description": "A multi-framework Composer library installer",
6
- "keywords": [
7
- "installer",
8
- "Aimeos",
9
- "AGL",
10
- "AnnotateCms",
11
- "Attogram",
12
- "Bitrix",
13
- "CakePHP",
14
- "Chef",
15
- "Cockpit",
16
- "CodeIgniter",
17
- "concrete5",
18
- "Craft",
19
- "Croogo",
20
- "DokuWiki",
21
- "Dolibarr",
22
- "Drupal",
23
- "Elgg",
24
- "ExpressionEngine",
25
- "FuelPHP",
26
- "Grav",
27
- "Hurad",
28
- "ImageCMS",
29
- "Joomla",
30
- "Kohana",
31
- "Laravel",
32
- "Lithium",
33
- "Magento",
34
- "Mako",
35
- "Mautic",
36
- "MODX Evo",
37
- "MediaWiki",
38
- "OXID",
39
- "MODULEWork",
40
- "Moodle",
41
- "Piwik",
42
- "phpBB",
43
- "Plentymarkets",
44
- "PPI",
45
- "Puppet",
46
- "RadPHP",
47
- "ReIndex",
48
- "Roundcube",
49
- "shopware",
50
- "SilverStripe",
51
- "SMF",
52
- "symfony",
53
- "Thelia",
54
- "TYPO3",
55
- "WolfCMS",
56
- "WordPress",
57
- "YAWIK",
58
- "Zend",
59
- "Zikula"
60
- ],
61
- "homepage": "https://composer.github.io/installers/",
62
- "authors": [
63
- {
64
- "name": "Kyle Robinson Young",
65
- "email": "kyle@dontkry.com",
66
- "homepage": "https://github.com/shama"
67
- }
68
- ],
69
- "autoload": {
70
- "psr-4": { "Composer\\Installers\\": "src/Composer/Installers" }
71
- },
72
- "extra": {
73
- "class": "Composer\\Installers\\Plugin",
74
- "branch-alias": {
75
- "dev-master": "1.0-dev"
76
- }
77
- },
78
- "replace": {
79
- "shama/baton": "*",
80
- "roundcube/plugin-installer": "*"
81
- },
82
- "require": {
83
- "composer-plugin-api": "^1.0"
84
- },
85
- "require-dev": {
86
- "composer/composer": "1.0.*@dev",
87
- "phpunit/phpunit": "4.1.*"
88
- },
89
- "scripts": {
90
- "test": "phpunit"
91
- }
92
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -1,272 +1,292 @@
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' ) );
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
- }
29
-
30
- public static function register_menus(){
31
- global $WPML_Translation_Management;
32
-
33
- if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update){
34
- $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
35
-
36
- if( current_user_can('wpml_manage_woocommerce_multilingual') ){
37
- add_submenu_page($top_page, __('WooCommerce Multilingual', 'woocommerce-multilingual'),
38
- __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
39
-
40
- }elseif( current_user_can('wpml_operate_woocommerce_multilingual') ){
41
- add_menu_page( __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ), __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
42
- 'wpml_operate_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'), WCML_PLUGIN_URL . '/res/images/icon16.png' );
43
-
44
- //force add translations-queue page for shop manager
45
- $wp_api = self::$sitepress->get_wp_api();
46
- if ( !$wp_api->current_user_can( 'wpml_manage_translation_management' ) ) {
47
- $wp_api->add_submenu_page( null,
48
- __( 'Translations', 'wpml-translation-management' ), __( 'Translations', 'wpml-translation-management' ),
49
- 'wpml_operate_woocommerce_multilingual', WPML_TM_FOLDER . '/menu/translations-queue.php', array( $WPML_Translation_Management, 'translation_queue_page' ) );
50
- }
51
- }else{
52
- $user_lang_pairs = get_user_meta(get_current_user_id(), self::$wpdb->prefix.'language_pairs', true);
53
- if( !empty( $user_lang_pairs ) ){
54
- add_menu_page(__('WooCommerce Multilingual', 'woocommerce-multilingual'),
55
- __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'translate',
56
- 'wpml-wcml', array(__CLASS__, 'render_menus'), ICL_PLUGIN_URL . '/res/img/icon16.png');
57
- }
58
- }
59
-
60
- }elseif( current_user_can('wpml_manage_woocommerce_multilingual') ){
61
- if(!defined('ICL_SITEPRESS_VERSION')){
62
- add_menu_page( __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ), __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
63
- 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'), WCML_PLUGIN_URL . '/res/images/icon16.png' );
64
- }else{
65
- $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
66
- add_submenu_page($top_page, __('WooCommerce Multilingual', 'woocommerce-multilingual'),
67
- __('WooCommerce Multilingual', 'woocommerce-multilingual'), 'wpml_manage_woocommerce_multilingual', 'wpml-wcml', array(__CLASS__, 'render_menus'));
68
- }
69
-
70
- }
71
- }
72
-
73
- public static function render_menus(){
74
-
75
- if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update ){
76
- $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
77
- $menus_wrap->show();
78
- }else{
79
- global $sitepress;
80
- $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
81
- $plugins_wrap->show();
82
- }
83
-
84
- }
85
-
86
- private static function is_page_without_admin_language_switcher(){
87
- global $pagenow;
88
-
89
- $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
90
- $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
91
- $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
92
-
93
- $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
94
- $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
95
- $get_post_type &&
96
- in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
97
- $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
98
- in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
99
- $is_shipping_zones = $get_page == 'shipping_zones';
100
- $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
101
-
102
-
103
- return is_admin() && (
104
- $is_page_wpml_wcml ||
105
- $is_new_order_or_coupon ||
106
- $is_edit_order_or_coupon ||
107
- $is_shipping_zones ||
108
- $is_attributes_page
109
- );
110
-
111
- }
112
-
113
- public static function remove_wpml_admin_language_switcher(){
114
-
115
- remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
116
-
117
- }
118
-
119
- public static function documentation_links() {
120
- global $post, $pagenow;
121
-
122
- if ( is_null( $post ) )
123
- return;
124
-
125
- $get_post_type = get_post_type( $post->ID );
126
-
127
- if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
128
- $prot_link = '<span class="button"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon.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', '#4' ) . '" target="_blank">' .
129
- __( 'How to translate products', 'sitepress' ) . '<\/a>' . '<\/span>';
130
- $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
131
- sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
132
- 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
133
- __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
134
- '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
135
- ) . '</p></div>';
136
- $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
137
- ?>
138
- <script type="text/javascript">
139
- jQuery(".subsubsub").append('<?php echo $prot_link ?>');
140
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
141
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
142
- jQuery(".quick_hide a").on('click', function () {
143
- jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
144
- });
145
-
146
- //lock feautured for translations
147
- jQuery(document).on('click', '.featured a', function () {
148
-
149
- if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
150
-
151
- return false;
152
-
153
- }
154
-
155
- });
156
- </script>
157
- <?php
158
- }
159
-
160
- if ( isset($_GET['taxonomy']) ) {
161
- $pos = strpos( $_GET['taxonomy'], 'pa_' );
162
-
163
- if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
164
- $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;">' .
165
- __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
166
- ?>
167
- <script type="text/javascript">
168
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
169
- </script>
170
- <?php
171
- }
172
- }
173
-
174
- if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
175
-
176
- $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;">' .
177
- __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
178
- ?>
179
- <script type="text/javascript">
180
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
181
- </script>
182
- <?php
183
- }
184
- }
185
-
186
- public static function hide_multilingual_content_setup_box(){
187
- remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
188
- remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
189
- }
190
-
191
- public static function restrict_admin_with_redirect() {
192
- global $pagenow;
193
-
194
- $default_lang = self::$sitepress->get_default_language();
195
- $current_lang = self::$sitepress->get_current_language();
196
-
197
- if(
198
- ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
199
- ( $pagenow == 'admin.php' &&
200
- isset( $_GET[ 'action' ] ) &&
201
- $_GET[ 'action'] == 'duplicate_product' &&
202
- isset( $_GET[ 'post' ] )
203
- )
204
- ){
205
- $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
206
- }
207
-
208
- if(
209
- !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
210
- $pagenow == 'post.php' &&
211
- isset( $_GET[ 'post' ] )&&
212
- get_post_type( $_GET[ 'post' ] ) == 'product' &&
213
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
214
- {
215
- add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
216
- }
217
-
218
- if(
219
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
220
- $pagenow == 'post.php' &&
221
- !is_ajax() &&
222
- isset( $_GET[ 'post' ] ) &&
223
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
224
- get_post_type( $_GET[ 'post' ] ) == 'product'
225
- ) {
226
- if(
227
- !isset( $_GET[ 'action' ] ) ||
228
- ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
229
- ) {
230
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
231
- exit;
232
- }
233
- }
234
-
235
- if(
236
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
237
- $pagenow == 'admin.php' &&
238
- isset( $_GET[ 'action' ] ) &&
239
- $_GET[ 'action' ] == 'duplicate_product' &&
240
- $default_lang != $prod_lang )
241
- {
242
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
243
- exit;
244
- }
245
- }
246
-
247
- public static function inf_editing_product_in_non_default_lang(){
248
- $message = '<div class="message error"><p>';
249
- $message .= sprintf(
250
- __( 'The recommended way to translate WooCommerce products is using the
251
- %sWooCommerce Multilingual products translation%s page.
252
- Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
253
- 'woocommerce-multilingual' ),
254
- '<strong><a href="' .admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '">', '</a></strong>' );
255
- $message .= '</p></div>';
256
-
257
- echo $message;
258
- }
259
-
260
- public static function check_user_admin_access( $prevent_access ){
261
-
262
- if( self::$woocommerce_wpml->check_dependencies && self::$woocommerce_wpml->check_design_update ){
263
- $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
264
- if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
265
- return false;
266
- }
267
- }
268
-
269
- return $prevent_access;
270
- }
271
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  }
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_manage_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
+ $message = '<div class="message error"><p>';
238
+ $message .= sprintf(
239
+ __( 'The recommended way to translate WooCommerce products is using the
240
+ %sWooCommerce Multilingual products translation%s page.
241
+ Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
242
+ 'woocommerce-multilingual' ),
243
+ '<strong><a href="' .admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '">', '</a></strong>' );
244
+ $message .= '</p></div>';
245
+
246
+ echo $message;
247
+ }
248
+
249
+ public static function check_user_admin_access( $prevent_access ){
250
+
251
+ if( self::$woocommerce_wpml->check_dependencies ){
252
+ $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
253
+ if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
254
+ return false;
255
+ }
256
+ }
257
+
258
+ return $prevent_access;
259
+ }
260
+
261
+ public static function add_menu_warning(){
262
+ global $submenu, $menu;
263
+
264
+ if (
265
+ class_exists( 'woocommerce' ) &&
266
+ (
267
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
268
+ (
269
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
270
+ self::$woocommerce_wpml->settings['set_up_wizard_splash']
271
+ )
272
+ )
273
+ ) {
274
+ if( isset( $submenu[ 'woocommerce' ] ) ){
275
+ foreach( $submenu[ 'woocommerce' ] as $key => $menu_item ) {
276
+ if ( $menu_item[ 0 ] == __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ) ) {
277
+ $submenu[ 'woocommerce' ][ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
278
+ break;
279
+ }
280
+ }
281
+ }
282
+
283
+ foreach( $menu as $key => $menu_item ) {
284
+ if ( $menu_item[ 0 ] == __( 'WooCommerce', 'woocommerce' ) ) {
285
+ $menu[ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
286
+ break;
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
  }
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 ADDED
@@ -0,0 +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
+ }
inc/admin-menus/class-wcml-setup.php CHANGED
@@ -1,335 +1,343 @@
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->steps = array(
17
- 'introduction' => array(
18
- 'name' => __( 'Introduction', 'woocommerce-multilingual' ),
19
- 'view' => array( $this, 'setup_introduction' ),
20
- 'handler' => ''
21
- ),
22
- 'store-pages' => array(
23
- 'name' => __( 'Store Pages', 'woocommerce-multilingual' ),
24
- 'view' => array( $this, 'setup_store_pages' ),
25
- 'handler' => array( $this, 'install_store_pages' ),
26
- ),
27
- 'attributes' => array(
28
- 'name' => __( 'Global Attributes', 'woocommerce-multilingual' ),
29
- 'view' => array( $this, 'setup_attributes' ),
30
- 'handler' => array( $this, 'save_attributes' )
31
- ),
32
- 'multi-currency' => array(
33
- 'name' => __( 'Multiple Currencies', 'woocommerce-multilingual' ),
34
- 'view' => array( $this, 'setup_multi_currency' ),
35
- 'handler' => array( $this, 'save_multi_currency' )
36
- ),
37
- 'translation-interface' => array(
38
- 'name' => __( 'Translation Interface', 'woocommerce-multilingual' ),
39
- 'view' => array( $this, 'setup_translation_interface' ),
40
- 'handler' => array( $this, 'save_translation_interface' )
41
- ),
42
- 'ready' => array(
43
- 'name' => __( 'Ready!', 'woocommerce-multilingual' ),
44
- 'view' => array( $this, 'setup_ready' ),
45
- 'handler' => ''
46
- )
47
- );
48
-
49
- if( current_user_can( 'manage_options' ) ) {
50
- if ( isset( $_GET['page'] ) && $_GET['page'] === 'wcml-setup' ) {
51
- add_action( 'admin_menu', array( $this, 'admin_menus' ) );
52
- }
53
- add_action( 'admin_init', array($this, 'setup_wizard') );
54
-
55
- add_action( 'admin_init', array($this, 'handle_steps'), 0 );
56
- add_filter( 'wp_redirect', array($this, 'redirect_filters') );
57
- }
58
-
59
- if( !$this->has_completed()){
60
- add_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
61
- add_action( 'admin_init', array( $this, 'skip_setup' ), 1 );
62
- }
63
-
64
- }
65
-
66
- public function admin_menus() {
67
- add_dashboard_page( '', '', 'manage_options', 'wcml-setup', '' );
68
- }
69
-
70
- public function setup_wizard_notice(){
71
- ?>
72
- <div id="wcml-setup-wizard" class="updated message fade otgs-is-dismissible">
73
- <p><?php printf( __('Welcome to %sWooCommerce Multilingual!%s Please take a moment to configure the main settings and then you are ready to start translating your products.', 'woocommerce-multilingual'), '<strong>', '</strong>') ?></p>
74
- <p class="submit">
75
- <a href="<?php echo esc_url( admin_url('admin.php?page=wcml-setup') ); ?>" class="button-primary"><?php _e('Run the Setup Wizard', 'woocommerce-multilingual') ?></a>
76
- <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 Setup', 'woocommerce-multilingual') ?></a>
77
- </p>
78
- </div>
79
- <?php
80
- }
81
-
82
- public function skip_setup(){
83
-
84
- if ( isset( $_GET['wcml-setup-skip'] ) && isset( $_GET['_wcml_setup_nonce'] ) ) {
85
- if ( ! wp_verify_nonce( $_GET['_wcml_setup_nonce'], 'wcml_setup_skip_nonce' ) ) {
86
- wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-multilingual' ) );
87
- }
88
-
89
- if ( ! current_user_can( 'manage_options' ) ) {
90
- wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
91
- }
92
-
93
- $this->complete_setup();
94
- remove_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
95
- }
96
-
97
- }
98
-
99
- public function complete_setup(){
100
- $this->woocommerce_wpml->settings['set_up_wizard_run'] = 1;
101
- $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
102
- $this->woocommerce_wpml->update_settings();
103
- }
104
-
105
- public function has_completed(){
106
-
107
- return !empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] );
108
-
109
- }
110
-
111
- public function splash_wizard_on_wcml_pages(){
112
-
113
- if( isset( $_GET['src'] ) && $_GET['src'] == 'setup_later' ){
114
- $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
115
- $this->woocommerce_wpml->update_settings();
116
- }
117
-
118
- if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && !$this->has_completed() && empty( $this->woocommerce_wpml->settings['set_up_wizard_splash'] )){
119
- wp_redirect('admin.php?page=wcml-setup');
120
- exit;
121
- }
122
- }
123
-
124
- public function setup_wizard() {
125
-
126
- $this->splash_wizard_on_wcml_pages();
127
-
128
- if ( empty( $_GET['page'] ) || 'wcml-setup' !== $_GET['page'] ) {
129
- return;
130
- }
131
-
132
- $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
133
-
134
- wp_enqueue_style( 'wcml-setup', WCML_PLUGIN_URL . '/res/css/wcml-setup.css', array( 'dashicons', 'install' ), WCML_VERSION );
135
- wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array('jquery'), WCML_VERSION );
136
-
137
- $this->setup_header();
138
- $this->setup_steps();
139
- $this->setup_content();
140
- $this->setup_footer();
141
-
142
- if( $this->step == 'ready' ){
143
- $this->complete_setup();
144
- }
145
-
146
- exit;
147
- }
148
-
149
- private function setup_header() {
150
- set_current_screen('wcml-setup');
151
- ?>
152
- <!DOCTYPE html>
153
- <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
154
- <head>
155
- <meta name="viewport" content="width=device-width" />
156
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
157
- <title><?php _e( 'WooCommerce Multilingual &rsaquo; Setup Wizard', 'woocommerce-multilingual' ); ?></title>
158
- <?php wp_print_scripts( 'wcml-setup' ); ?>
159
- <?php do_action( 'admin_print_styles' ); ?>
160
- <?php do_action( 'admin_head' ); ?>
161
- </head>
162
- <body class="wcml-setup wp-core-ui">
163
- <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>
164
-
165
- <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
166
- <form class="wcml-setup-form" method="post">
167
- <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( $this->step ) ?>" />
168
- <input type="hidden" name="handle_step" value="<?php echo $this->step ?>" />
169
- <?php endif; ?>
170
- <?php
171
- }
172
-
173
- private function setup_content(){
174
-
175
- echo '<div class="wcml-setup-content">';
176
- call_user_func( $this->steps[ $this->step ]['view'] );
177
- echo '</div>';
178
-
179
- }
180
-
181
- private function setup_footer() {
182
- ?>
183
- <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
184
- </form>
185
- <?php endif ?>
186
- </body>
187
- </html>
188
- <?php
189
- }
190
-
191
- private function setup_steps() {
192
-
193
- $steps = array_keys( $this->steps );
194
- $step_index = array_search( $this->step, $steps );
195
- $this->next_step = isset( $steps[$step_index + 1] ) ? $steps[$step_index + 1] : '';
196
-
197
- $ouput_steps = $this->steps;
198
- array_shift( $ouput_steps );
199
- ?>
200
- <ol class="wcml-setup-steps">
201
- <?php foreach ( $ouput_steps as $step_key => $step ) : ?>
202
- <li class="<?php
203
- if ( $step_key === $this->step ) {
204
- echo 'active';
205
- } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
206
- echo 'done';
207
- }
208
- ?>"><?php echo esc_html( $step['name'] ); ?></li>
209
- <?php endforeach; ?>
210
- </ol>
211
- <?php
212
- }
213
-
214
- private function next_step_url(){
215
- $url = admin_url('admin.php?page=wcml-setup&step=' . $this->next_step );
216
- return $url;
217
- }
218
-
219
- public function setup_introduction(){
220
- $ui = new WCML_Setup_Introduction_UI( $this->woocommerce_wpml, $this->next_step_url() );
221
- echo $ui->get_view();
222
- }
223
-
224
- public function setup_store_pages(){
225
-
226
- $ui = new WCML_Setup_Store_Pages_UI( $this->woocommerce_wpml, $this->sitepress, $this->next_step_url() );
227
- echo $ui->get_view();
228
- }
229
-
230
- public function setup_attributes(){
231
- $ui = new WCML_Setup_Attributes_UI( $this->woocommerce_wpml, $this->next_step_url() );
232
- echo $ui->get_view();
233
- }
234
-
235
- public function setup_multi_currency(){
236
- $ui = new WCML_Setup_Multi_Currency_UI( $this->woocommerce_wpml, $this->next_step_url() );
237
- echo $ui->get_view();
238
- }
239
-
240
- public function setup_translation_interface(){
241
- $ui = new WCML_Setup_Translation_Interface_UI( $this->woocommerce_wpml, $this->next_step_url() );
242
- echo $ui->get_view();
243
- }
244
-
245
- public function setup_ready(){
246
- $ui = new WCML_Setup_Ready_UI( $this->woocommerce_wpml );
247
- echo $ui->get_view();
248
- }
249
-
250
-
251
- public function redirect_filters( $url ){
252
-
253
- if( isset($_POST['next_step_url']) && $_POST['next_step_url'] ){
254
- $url = sanitize_text_field( $_POST['next_step_url'] );
255
- }
256
-
257
- return $url;
258
- }
259
-
260
-
261
- private function get_handler( $step ){
262
- $handler = !empty( $this->steps[ $step ]['handler'] ) ? $this->steps[ $step ]['handler'] : '';
263
- return $handler;
264
-
265
- }
266
-
267
- public function handle_steps(){
268
-
269
- if( isset( $_POST[ 'handle_step' ] ) && $_POST['nonce'] == wp_create_nonce( $_POST[ 'handle_step' ] ) ){
270
-
271
- $step_name = sanitize_text_field( $_POST[ 'handle_step' ] );
272
-
273
- if( $handler = $this->get_handler( $step_name )){
274
- call_user_func( $handler, $_POST );
275
- }
276
-
277
- }
278
-
279
- }
280
-
281
- /**
282
- * handler
283
- */
284
- public function save_attributes( $data ){
285
-
286
- if ( isset( $data['attributes'] ) ) {
287
- $this->woocommerce_wpml->attributes->set_translatable_attributes( $data['attributes'] );
288
- }
289
-
290
- }
291
-
292
- /**
293
- * handler
294
- */
295
- public function save_multi_currency( $data ){
296
-
297
- if( empty( $this->woocommerce_wpml->multi_currency )){
298
- $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
299
- }
300
-
301
- if( !empty( $data['enabled'] ) ){
302
- $this->woocommerce_wpml->multi_currency->enable();
303
- } else{
304
- $this->woocommerce_wpml->multi_currency->disable();
305
- }
306
-
307
- }
308
-
309
- /**
310
- * handler
311
- */
312
- public function save_translation_interface( $data ){
313
-
314
- $this->woocommerce_wpml->settings['trnsl_interface'] = intval( $data['translation_interface'] );
315
- $this->woocommerce_wpml->update_settings();
316
-
317
- }
318
-
319
- /**
320
- * handler
321
- */
322
- public function install_store_pages( $data ){
323
-
324
- if( !empty( $data['create_pages'] ) ) {
325
- $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
326
- }elseif( !empty( $data['install_missing_pages'] ) ){
327
- WC_Install::create_pages();
328
- $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
329
- }
330
-
331
- }
332
-
333
-
334
-
 
 
 
 
 
 
 
 
335
  }
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
+ if ( get_transient( '_wcml_activation_redirect' ) ) {
65
+ delete_transient( '_wcml_activation_redirect' );
66
+
67
+ if ( ( ! empty( $_GET['page'] ) && in_array( $_GET['page'], array( 'wcml-setup' ) ) ) || is_network_admin() || isset( $_GET['activate-multi'] ) || ! current_user_can( 'manage_options' ) ) {
68
+ return;
69
+ }
70
+
71
+ if( !$this->has_completed()){
72
+ wp_safe_redirect( admin_url( 'index.php?page=wcml-setup' ) );
73
+ exit;
74
+ }
75
+ }
76
+ }
77
+
78
+ public function admin_menus() {
79
+ add_dashboard_page( '', '', 'manage_options', 'wcml-setup', '' );
80
+ }
81
+
82
+ public function setup_wizard_notice(){
83
+ wp_enqueue_style( 'wcml-setup-wizard-notice', WCML_PLUGIN_URL . '/res/css/wcml-setup-wizard-notice.css' );
84
+ ?>
85
+ <div id="wcml-setup-wizard" class="updated message wpml-message">
86
+ <p>
87
+ <strong><?php _e('Prepare your WooCommerce store to run multilingual!', 'woocommerce-multilingual'); ?></strong><br />
88
+ <?php _e('We need to help you with a few steps to turn your WooCommerce store multilingual. These steps include:', 'woocommerce-multilingual'); ?>
89
+ <ul class="wcml-notice-list">
90
+ <li><?php _e("Translating the 'store' pages", 'woocommerce-multilingual'); ?></li>
91
+ <li><?php _e("Choosing which attributes to make translatable", 'woocommerce-multilingual'); ?></li>
92
+ <li><?php _e("Choosing if you need multiple currencies", 'woocommerce-multilingual'); ?></li>
93
+ </ul>
94
+ </p>
95
+ <p class="submit">
96
+ <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>
97
+ <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>
98
+ </p>
99
+ </div>
100
+ <?php
101
+ }
102
+
103
+ public function skip_setup(){
104
+
105
+ if ( isset( $_GET['wcml-setup-skip'] ) && isset( $_GET['_wcml_setup_nonce'] ) ) {
106
+ if ( ! wp_verify_nonce( $_GET['_wcml_setup_nonce'], 'wcml_setup_skip_nonce' ) ) {
107
+ wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce-multilingual' ) );
108
+ }
109
+
110
+ if ( ! current_user_can( 'manage_options' ) ) {
111
+ wp_die( __( 'Cheatin&#8217; huh?', 'woocommerce' ) );
112
+ }
113
+
114
+ $this->complete_setup();
115
+ remove_filter( 'admin_notices', array( $this, 'setup_wizard_notice') );
116
+
117
+ delete_transient( '_wcml_activation_redirect' );
118
+ }
119
+
120
+ }
121
+
122
+ public function complete_setup(){
123
+ $this->woocommerce_wpml->settings['set_up_wizard_run'] = 1;
124
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
125
+ $this->woocommerce_wpml->update_settings();
126
+ }
127
+
128
+ public function has_completed(){
129
+
130
+ return !empty( $this->woocommerce_wpml->settings['set_up_wizard_run'] );
131
+
132
+ }
133
+
134
+ public function splash_wizard_on_wcml_pages(){
135
+
136
+ if( isset( $_GET['src'] ) && $_GET['src'] == 'setup_later' ){
137
+ $this->woocommerce_wpml->settings['set_up_wizard_splash'] = 1;
138
+ $this->woocommerce_wpml->update_settings();
139
+ }
140
+
141
+ if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && !$this->has_completed() && empty( $this->woocommerce_wpml->settings['set_up_wizard_splash'] )){
142
+ wp_redirect('admin.php?page=wcml-setup');
143
+ exit;
144
+ }
145
+ }
146
+
147
+ public function setup_wizard() {
148
+
149
+ $this->splash_wizard_on_wcml_pages();
150
+
151
+ if ( empty( $_GET['page'] ) || 'wcml-setup' !== $_GET['page'] ) {
152
+ return;
153
+ }
154
+
155
+ $this->step = isset( $_GET['step'] ) ? sanitize_key( $_GET['step'] ) : current( array_keys( $this->steps ) );
156
+
157
+ wp_enqueue_style( 'wcml-setup', WCML_PLUGIN_URL . '/res/css/wcml-setup.css', array( 'dashicons', 'install' ), WCML_VERSION );
158
+ wp_enqueue_script( 'wcml-setup', WCML_PLUGIN_URL . '/res/js/wcml-setup.js', array('jquery'), WCML_VERSION );
159
+
160
+ $this->setup_header();
161
+ $this->setup_steps();
162
+ $this->setup_content();
163
+ $this->setup_footer();
164
+
165
+ if( $this->step == 'ready' ){
166
+ $this->complete_setup();
167
+ }
168
+
169
+ exit;
170
+ }
171
+
172
+ private function setup_header() {
173
+ set_current_screen('wcml-setup');
174
+ ?>
175
+ <!DOCTYPE html>
176
+ <html xmlns="http://www.w3.org/1999/xhtml" <?php language_attributes(); ?>>
177
+ <head>
178
+ <meta name="viewport" content="width=device-width" />
179
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
180
+ <title><?php _e( 'WooCommerce Multilingual &rsaquo; Setup Wizard', 'woocommerce-multilingual' ); ?></title>
181
+ <?php wp_print_scripts( 'wcml-setup' ); ?>
182
+ <?php do_action( 'admin_print_styles' ); ?>
183
+ <?php do_action( 'admin_head' ); ?>
184
+ </head>
185
+ <body class="wcml-setup wp-core-ui">
186
+ <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>
187
+
188
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
189
+ <form class="wcml-setup-form" method="post">
190
+ <input type="hidden" name="nonce" value="<?php echo wp_create_nonce( $this->step ) ?>" />
191
+ <input type="hidden" name="handle_step" value="<?php echo $this->step ?>" />
192
+ <?php endif; ?>
193
+ <?php
194
+ }
195
+
196
+ private function setup_content(){
197
+
198
+ echo '<div class="wcml-setup-content">';
199
+ call_user_func( $this->steps[ $this->step ]['view'] );
200
+ echo '</div>';
201
+
202
+ }
203
+
204
+ private function setup_footer() {
205
+ ?>
206
+ <?php if( !empty( $this->steps[ $this->step ]['handler'] ) ): ?>
207
+ </form>
208
+ <?php endif ?>
209
+ </body>
210
+ </html>
211
+ <?php
212
+ }
213
+
214
+ private function setup_steps() {
215
+
216
+ $steps = array_keys( $this->steps );
217
+ $step_index = array_search( $this->step, $steps );
218
+ $this->next_step = isset( $steps[$step_index + 1] ) ? $steps[$step_index + 1] : '';
219
+
220
+ $ouput_steps = $this->steps;
221
+ array_shift( $ouput_steps );
222
+ ?>
223
+ <ol class="wcml-setup-steps">
224
+ <?php foreach ( $ouput_steps as $step_key => $step ) : ?>
225
+ <li class="<?php
226
+ if ( $step_key === $this->step ) {
227
+ echo 'active';
228
+ } elseif ( array_search( $this->step, array_keys( $this->steps ) ) > array_search( $step_key, array_keys( $this->steps ) ) ) {
229
+ echo 'done';
230
+ }
231
+ ?>"><?php echo esc_html( $step['name'] ); ?></li>
232
+ <?php endforeach; ?>
233
+ </ol>
234
+ <?php
235
+ }
236
+
237
+ private function next_step_url(){
238
+ $url = admin_url('admin.php?page=wcml-setup&step=' . $this->next_step );
239
+ return $url;
240
+ }
241
+
242
+ public function setup_introduction(){
243
+ $ui = new WCML_Setup_Introduction_UI( $this->woocommerce_wpml, $this->next_step_url() );
244
+ echo $ui->get_view();
245
+ }
246
+
247
+ public function setup_store_pages(){
248
+
249
+ $ui = new WCML_Setup_Store_Pages_UI( $this->woocommerce_wpml, $this->sitepress, $this->next_step_url() );
250
+ echo $ui->get_view();
251
+ }
252
+
253
+ public function setup_attributes(){
254
+ $ui = new WCML_Setup_Attributes_UI( $this->woocommerce_wpml, $this->next_step_url() );
255
+ echo $ui->get_view();
256
+ }
257
+
258
+ public function setup_multi_currency(){
259
+ $ui = new WCML_Setup_Multi_Currency_UI( $this->woocommerce_wpml, $this->next_step_url() );
260
+ echo $ui->get_view();
261
+ }
262
+
263
+ public function setup_ready(){
264
+ $ui = new WCML_Setup_Ready_UI( $this->woocommerce_wpml );
265
+ echo $ui->get_view();
266
+ }
267
+
268
+
269
+ public function redirect_filters( $url ){
270
+
271
+ if( isset($_POST['next_step_url']) && $_POST['next_step_url'] ){
272
+ $url = sanitize_text_field( $_POST['next_step_url'] );
273
+ }
274
+
275
+ return $url;
276
+ }
277
+
278
+
279
+ private function get_handler( $step ){
280
+ $handler = !empty( $this->steps[ $step ]['handler'] ) ? $this->steps[ $step ]['handler'] : '';
281
+ return $handler;
282
+
283
+ }
284
+
285
+ public function handle_steps(){
286
+
287
+ if( isset( $_POST[ 'handle_step' ] ) && $_POST['nonce'] == wp_create_nonce( $_POST[ 'handle_step' ] ) ){
288
+
289
+ $step_name = sanitize_text_field( $_POST[ 'handle_step' ] );
290
+
291
+ if( $handler = $this->get_handler( $step_name )){
292
+ call_user_func( $handler, $_POST );
293
+ }
294
+
295
+ }
296
+
297
+ }
298
+
299
+ /**
300
+ * handler
301
+ */
302
+ public function save_attributes( $data ){
303
+
304
+ if ( isset( $data['attributes'] ) ) {
305
+ $this->woocommerce_wpml->attributes->set_translatable_attributes( $data['attributes'] );
306
+ }
307
+
308
+ }
309
+
310
+ /**
311
+ * handler
312
+ */
313
+ public function save_multi_currency( $data ){
314
+
315
+ if( empty( $this->woocommerce_wpml->multi_currency )){
316
+ $this->woocommerce_wpml->multi_currency = new WCML_Multi_Currency();
317
+ }
318
+
319
+ if( !empty( $data['enabled'] ) ){
320
+ $this->woocommerce_wpml->multi_currency->enable();
321
+ } else{
322
+ $this->woocommerce_wpml->multi_currency->disable();
323
+ }
324
+
325
+ }
326
+
327
+ /**
328
+ * handler
329
+ */
330
+ public function install_store_pages( $data ){
331
+
332
+ if( !empty( $data['create_pages'] ) ) {
333
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
334
+ }elseif( !empty( $data['install_missing_pages'] ) ){
335
+ WC_Install::create_pages();
336
+ $this->woocommerce_wpml->store->create_missing_store_pages_with_redirect();
337
+ }
338
+
339
+ }
340
+
341
+
342
+
343
  }
inc/class-wcml-ajax-setup.php CHANGED
@@ -1,119 +1,131 @@
1
- <?php
2
-
3
-
4
- class WCML_Ajax_Setup{
5
-
6
- function __construct(){
7
-
8
- add_action('init', array($this, 'init'));
9
- add_action('localize_woocommerce_on_ajax', array($this, 'localize_woocommerce_on_ajax'));
10
-
11
- }
12
-
13
- function init(){
14
- if (wpml_is_ajax()){
15
- do_action('localize_woocommerce_on_ajax');
16
- }
17
-
18
- add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
19
-
20
- add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
21
- add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
22
- add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
23
- add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
24
-
25
- add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
26
- add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
27
- add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
28
-
29
- }
30
-
31
- function filter_woocommerce_order_review(){
32
- global $woocommerce;
33
- unload_textdomain('woocommerce');
34
- $woocommerce->load_plugin_textdomain();
35
- }
36
-
37
- function add_hidden_language_field(){
38
- if( function_exists('wpml_the_language_input_field') ){
39
- wpml_the_language_input_field();
40
- }else{
41
- global $sitepress;
42
- if (isset($sitepress) ) {
43
- return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
44
- }
45
- return null;
46
- }
47
- }
48
-
49
- function add_language_parameter_to_ajax_url($woocommerce_params){
50
- global $sitepress;
51
-
52
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
53
- $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
54
- }
55
-
56
- return $woocommerce_params;
57
- }
58
-
59
- function filter_woocommerce_ajax_params($woocommerce_params){
60
- global $sitepress, $post;
61
- $value = array();
62
- $value = $woocommerce_params;
63
-
64
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
65
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
66
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
67
- }
68
-
69
- if(!isset($post->ID)){
70
- return $value;
71
- }
72
-
73
- $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
74
-
75
- if(empty($ch_pages)){
76
-
77
- $ch_pages = array(
78
-
79
- 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
80
- 'pay_page_id' => get_option('woocommerce_pay_page_id'),
81
- 'cart_page_id' => get_option('woocommerce_cart_page_id'));
82
-
83
- $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
84
- $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
85
- $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
86
-
87
- }
88
-
89
- wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
90
-
91
- if($ch_pages['translated_cart_page_id'] == $post->ID){
92
- $value['is_cart'] = 1;
93
- $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
94
- } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
95
- $value['is_checkout'] = 1;
96
-
97
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
98
-
99
- } else if($ch_pages['translated_pay_page_id'] == $post->ID){
100
- $value['is_pay_page'] = 1;
101
- }
102
-
103
- return $value;
104
- }
105
-
106
- function localize_woocommerce_on_ajax(){
107
- if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
108
- return;
109
- }
110
-
111
- global $sitepress;
112
-
113
- $current_language = $sitepress->get_current_language();
114
-
115
- $sitepress->switch_lang($current_language, true);
116
- }
117
-
118
-
119
- }
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class WCML_Ajax_Setup{
5
+
6
+ function __construct(){
7
+
8
+ add_action( 'init', array( $this, 'init' ) );
9
+ add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
10
+
11
+ //@deprecated 3.9
12
+ add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
13
+
14
+ }
15
+
16
+ function init(){
17
+ if (wpml_is_ajax()){
18
+ do_action('wcml_localize_woocommerce_on_ajax');
19
+ }
20
+
21
+ add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
22
+
23
+ add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
24
+ add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
25
+ add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
26
+ add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
27
+
28
+ add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
29
+ add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
30
+ add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
31
+
32
+ }
33
+
34
+ function filter_woocommerce_order_review(){
35
+ global $woocommerce;
36
+ unload_textdomain('woocommerce');
37
+ $woocommerce->load_plugin_textdomain();
38
+ }
39
+
40
+ function add_hidden_language_field(){
41
+ if( function_exists('wpml_the_language_input_field') ){
42
+ wpml_the_language_input_field();
43
+ }else{
44
+ global $sitepress;
45
+ if (isset($sitepress) ) {
46
+ return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
47
+ }
48
+ return null;
49
+ }
50
+ }
51
+
52
+ function add_language_parameter_to_ajax_url($woocommerce_params){
53
+ global $sitepress;
54
+
55
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
56
+ $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
57
+ }
58
+
59
+ return $woocommerce_params;
60
+ }
61
+
62
+ function filter_woocommerce_ajax_params($woocommerce_params){
63
+ global $sitepress, $post;
64
+ $value = array();
65
+ $value = $woocommerce_params;
66
+
67
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
68
+ $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
69
+ $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
70
+ }
71
+
72
+ if(!isset($post->ID)){
73
+ return $value;
74
+ }
75
+
76
+ $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
77
+
78
+ if(empty($ch_pages)){
79
+
80
+ $ch_pages = array(
81
+
82
+ 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
83
+ 'pay_page_id' => get_option('woocommerce_pay_page_id'),
84
+ 'cart_page_id' => get_option('woocommerce_cart_page_id'));
85
+
86
+ $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
87
+ $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
88
+ $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
89
+
90
+ }
91
+
92
+ wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
93
+
94
+ if($ch_pages['translated_cart_page_id'] == $post->ID){
95
+ $value['is_cart'] = 1;
96
+ $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
97
+ } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
98
+ $value['is_checkout'] = 1;
99
+
100
+ $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
101
+
102
+ } else if($ch_pages['translated_pay_page_id'] == $post->ID){
103
+ $value['is_pay_page'] = 1;
104
+ }
105
+
106
+ return $value;
107
+ }
108
+
109
+
110
+ function wcml_localize_woocommerce_on_ajax(){
111
+ if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
112
+ return;
113
+ }
114
+
115
+ global $sitepress;
116
+
117
+ $current_language = $sitepress->get_current_language();
118
+
119
+ $sitepress->switch_lang($current_language, true);
120
+ }
121
+
122
+
123
+ /**
124
+ * @deprecated 3.9
125
+ */
126
+ function localize_woocommerce_on_ajax(){
127
+ $this->wcml_localize_woocommerce_on_ajax();
128
+ }
129
+
130
+
131
+ }
inc/class-wcml-attributes.php CHANGED
@@ -1,385 +1,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 = 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
  }
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
  }
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.php CHANGED
@@ -1,247 +1,262 @@
1
- <?php
2
- class WCML_Cart
3
- {
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
-
8
- public function __construct( &$woocommerce_wpml, &$sitepress )
9
- {
10
- $this->woocommerce_wpml = $woocommerce_wpml;
11
- $this->sitepress = $sitepress;
12
-
13
- //cart widget
14
- add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
15
- add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
16
- add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
17
- add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
18
-
19
- //cart
20
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
21
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ), 10, 3 );
22
- add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
23
- add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
24
-
25
- add_filter('woocommerce_paypal_args', array($this, 'filter_paypal_args'));
26
-
27
- $this->localize_flat_rates_shipping_classes();
28
- }
29
-
30
- public function wcml_refresh_fragments(){
31
- WC()->cart->calculate_totals();
32
- $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
33
- }
34
-
35
- /*
36
- * Update cart and cart session when switch language
37
- */
38
- public function woocommerce_calculate_totals( $cart ){
39
- global $woocommerce;
40
- $current_language = $this->sitepress->get_current_language();
41
- $new_cart_data = array();
42
-
43
- foreach( $cart->cart_contents as $key => $cart_item ){
44
- $tr_product_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', false, $current_language );
45
- //translate custom attr labels in cart object
46
- if( isset( $cart_item[ 'data' ]->product_attributes ) ){
47
- foreach( $cart_item[ 'data' ]->product_attributes as $attr_key => $product_attribute ){
48
- if( !$product_attribute[ 'is_taxonomy' ] ){
49
- $cart->cart_contents[ $key ][ 'data' ]->product_attributes[ $attr_key ][ 'name' ] = $this->woocommerce_wpml->strings->translated_attribute_label(
50
- $product_attribute[ 'name' ],
51
- $product_attribute[ 'name' ],
52
- $tr_product_id );
53
- }
54
- }
55
- }
56
-
57
- //translate custom attr value in cart object
58
- if( isset( $cart_item[ 'variation' ] ) && is_array( $cart_item[ 'variation' ] ) ){
59
- foreach( $cart_item[ 'variation' ] as $attr_key => $attribute ){
60
- $cart->cart_contents[ $key ][ 'variation' ][ $attr_key ] = $this->get_cart_attribute_translation(
61
- $attr_key,
62
- $attribute,
63
- $cart_item[ 'variation_id' ],
64
- $current_language,
65
- $cart_item[ 'data' ]->parent->id,
66
- $tr_product_id
67
- );
68
- }
69
- }
70
-
71
- if( $cart_item[ 'product_id' ] == $tr_product_id ){
72
- $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[$key], $key, $current_language );
73
- continue;
74
- }
75
-
76
- if( isset( $cart->cart_contents[ $key ][ 'variation_id' ] ) && $cart->cart_contents[ $key ][ 'variation_id' ] ){
77
- $tr_variation_id = apply_filters( 'translate_object_id', $cart_item[ 'variation_id' ], 'product_variation', false, $current_language );
78
- if( !is_null( $tr_variation_id ) ){
79
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
80
- $cart->cart_contents[ $key ][ 'variation_id' ] = intval( $tr_variation_id );
81
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
82
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
83
- }
84
- }else{
85
- if( !is_null( $tr_product_id ) ){
86
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
87
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
88
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
89
- }
90
- }
91
-
92
- if( !is_null( $tr_product_id ) ){
93
- $cart_item_data = $this->get_cart_item_data_from_cart( $cart->cart_contents[ $key ] );
94
- $new_key = $woocommerce->cart->generate_cart_id(
95
- $cart->cart_contents[ $key ][ 'product_id' ],
96
- $cart->cart_contents[ $key ][ 'variation_id' ],
97
- $cart->cart_contents[ $key ][ 'variation' ],
98
- $cart_item_data );
99
- $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
100
- $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
101
- $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
102
- }
103
- }
104
-
105
- $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
106
- $woocommerce->session->cart = $cart;
107
- return $cart;
108
- }
109
-
110
- public function wcml_check_on_duplicate_products_in_cart( $cart_contents ){
111
- global $woocommerce;
112
-
113
- $exists_products = array();
114
- remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
115
-
116
- foreach( $cart_contents as $key => $cart_content ){
117
- $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
118
- if( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ){
119
- continue;
120
- }
121
- $search_key = md5( serialize( $cart_content ) );
122
- if( array_key_exists( $search_key, $exists_products ) ){
123
- unset( $cart_contents[ $key ] );
124
- $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] = $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] + $cart_content[ 'quantity' ];
125
- $woocommerce->cart->calculate_totals();
126
- }else{
127
- $exists_products[ $search_key ] = $key;
128
- }
129
- }
130
-
131
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
132
- return $cart_contents;
133
- }
134
-
135
- public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ){
136
-
137
- $attr_translation = $attribute;
138
-
139
- if( !empty( $attribute ) ){
140
- //delete 'attribute_' at the beginning
141
- $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
142
-
143
- if( taxonomy_exists( $taxonomy ) ){
144
- if( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
145
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
146
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
147
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
148
- $attr_translation = $term->slug;
149
- }
150
- }else{
151
-
152
- $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
153
-
154
- if( $trnsl_attr ){
155
- $attr_translation = $trnsl_attr;
156
- }else{
157
- $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
158
- }
159
- }
160
- }
161
-
162
- return $attr_translation;
163
- }
164
-
165
- //get cart_item_data from existing cart array ( from session )
166
- public function get_cart_item_data_from_cart( $cart_contents ){
167
- unset( $cart_contents[ 'product_id' ] );
168
- unset( $cart_contents[ 'variation_id' ] );
169
- unset( $cart_contents[ 'variation' ] );
170
- unset( $cart_contents[ 'quantity' ] );
171
- unset( $cart_contents[ 'data' ] );
172
-
173
- return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
174
- }
175
-
176
- public function translate_cart_contents( $item, $values, $key ) {
177
- // translate the product id and product data
178
- $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
179
- if ($item[ 'variation_id' ]) {
180
- $item[ 'variation_id' ] = apply_filters( 'translate_object_id',$item[ 'variation_id' ], 'product_variation', true );
181
- }
182
- $product_id = $item[ 'variation_id' ] ? $item[ 'variation_id' ] : $item[ 'product_id' ];
183
- $item[ 'data' ]->post->post_title = get_the_title( $item[ 'product_id' ] );
184
- return $item;
185
- }
186
-
187
- public function translate_cart_subtotal( $cart ) {
188
-
189
- if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
190
- $cart->calculate_totals();
191
- }
192
-
193
- }
194
-
195
- // refresh cart total to return correct price from WC object
196
- public function wcml_refresh_cart_total() {
197
- WC()->cart->calculate_totals();
198
- }
199
-
200
-
201
- public function localize_flat_rates_shipping_classes(){
202
- global $woocommerce;
203
-
204
- if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
205
- $woocommerce->shipping->load_shipping_methods();
206
- $shipping_methods = $woocommerce->shipping->get_shipping_methods();
207
- foreach($shipping_methods as $method){
208
- if(isset($method->flat_rate_option)){
209
- add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
210
- }
211
- }
212
-
213
- }
214
- }
215
-
216
- public function translate_shipping_class($rates){
217
-
218
- if(is_array($rates)){
219
- foreach($rates as $shipping_class => $value){
220
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
221
-
222
- if($term_id && !is_wp_error($term_id)){
223
- $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
224
- if($translated_term_id != $term_id){
225
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
226
- unset($rates[$shipping_class]);
227
- $rates[$term->slug] = $value;
228
-
229
- }
230
- }
231
- }
232
- }
233
- return $rates;
234
- }
235
-
236
- public function filter_paypal_args( $args ) {
237
- $args['lc'] = $this->sitepress->get_current_language();
238
-
239
- //filter URL when default permalinks uses
240
- $wpml_settings = $this->sitepress->get_settings();
241
- if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
242
- $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
243
- }
244
-
245
- return $args;
246
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  }
1
+ <?php
2
+ class WCML_Cart
3
+ {
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+
8
+ public function __construct( &$woocommerce_wpml, &$sitepress )
9
+ {
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+
13
+ //cart widget
14
+ add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
15
+ add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
16
+ add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
17
+ add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
18
+
19
+ //cart
20
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
21
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ), 10, 3 );
22
+ add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
23
+ add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
24
+
25
+ add_filter('woocommerce_paypal_args', array($this, 'filter_paypal_args'));
26
+
27
+ $this->localize_flat_rates_shipping_classes();
28
+ }
29
+
30
+ public function wcml_refresh_fragments(){
31
+ WC()->cart->calculate_totals();
32
+ $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
33
+ }
34
+
35
+ /*
36
+ * Update cart and cart session when switch language
37
+ */
38
+ public function woocommerce_calculate_totals( $cart, $currency = false ){
39
+ global $woocommerce;
40
+
41
+ $current_language = $this->sitepress->get_current_language();
42
+ $new_cart_data = array();
43
+
44
+ foreach( $cart->cart_contents as $key => $cart_item ){
45
+ $tr_product_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', false, $current_language );
46
+ //translate custom attr labels in cart object
47
+ if( isset( $cart_item[ 'data' ]->product_attributes ) ){
48
+ foreach( $cart_item[ 'data' ]->product_attributes as $attr_key => $product_attribute ){
49
+ if( !$product_attribute[ 'is_taxonomy' ] ){
50
+ $cart->cart_contents[ $key ][ 'data' ]->product_attributes[ $attr_key ][ 'name' ] = $this->woocommerce_wpml->strings->translated_attribute_label(
51
+ $product_attribute[ 'name' ],
52
+ $product_attribute[ 'name' ],
53
+ $tr_product_id );
54
+ }
55
+ }
56
+ }
57
+
58
+ //translate custom attr value in cart object
59
+ if( isset( $cart_item[ 'variation' ] ) && is_array( $cart_item[ 'variation' ] ) ){
60
+ foreach( $cart_item[ 'variation' ] as $attr_key => $attribute ){
61
+ $cart->cart_contents[ $key ][ 'variation' ][ $attr_key ] = $this->get_cart_attribute_translation(
62
+ $attr_key,
63
+ $attribute,
64
+ $cart_item[ 'variation_id' ],
65
+ $current_language,
66
+ $cart_item[ 'data' ]->parent->id,
67
+ $tr_product_id
68
+ );
69
+ }
70
+ }
71
+
72
+ if( $currency !== false ){
73
+ $cart->cart_contents[ $key ][ 'data' ]->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
74
+ }
75
+
76
+ if( $cart_item[ 'product_id' ] == $tr_product_id ){
77
+ $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[$key], $key, $current_language );
78
+ continue;
79
+ }
80
+
81
+ if( isset( $cart->cart_contents[ $key ][ 'variation_id' ] ) && $cart->cart_contents[ $key ][ 'variation_id' ] ){
82
+ $tr_variation_id = apply_filters( 'translate_object_id', $cart_item[ 'variation_id' ], 'product_variation', false, $current_language );
83
+ if( !is_null( $tr_variation_id ) ){
84
+ $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
85
+ $cart->cart_contents[ $key ][ 'variation_id' ] = intval( $tr_variation_id );
86
+ $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
87
+ $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
88
+ }
89
+ }else{
90
+ if( !is_null( $tr_product_id ) ){
91
+ $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
92
+ $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
93
+ $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
94
+ }
95
+ }
96
+
97
+ if( !is_null( $tr_product_id ) ){
98
+ $cart_item_data = $this->get_cart_item_data_from_cart( $cart->cart_contents[ $key ] );
99
+ $new_key = $woocommerce->cart->generate_cart_id(
100
+ $cart->cart_contents[ $key ][ 'product_id' ],
101
+ $cart->cart_contents[ $key ][ 'variation_id' ],
102
+ $cart->cart_contents[ $key ][ 'variation' ],
103
+ $cart_item_data );
104
+ $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
105
+ $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
106
+ $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
107
+ }
108
+ }
109
+
110
+ $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
111
+ $woocommerce->session->cart = $cart;
112
+ return $cart;
113
+ }
114
+
115
+ public function wcml_check_on_duplicate_products_in_cart( $cart_contents ){
116
+ global $woocommerce;
117
+
118
+ $exists_products = array();
119
+ remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
120
+
121
+ foreach( $cart_contents as $key => $cart_content ){
122
+ $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
123
+ if( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ){
124
+ continue;
125
+ }
126
+
127
+ $quantity = $cart_content['quantity'];
128
+ // unset unnecessary data to generate id to check
129
+ unset( $cart_content['quantity'] );
130
+ unset( $cart_content['line_total'] );
131
+ unset( $cart_content['line_subtotal'] );
132
+ unset( $cart_content['line_tax'] );
133
+ unset( $cart_content['line_subtotal_tax'] );
134
+ unset( $cart_content['line_tax_data'] );
135
+
136
+ $search_key = md5( serialize( $cart_content ) );
137
+ if( array_key_exists( $search_key, $exists_products ) ){
138
+ unset( $cart_contents[ $key ] );
139
+ $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] = $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] + $quantity;
140
+ $woocommerce->cart->calculate_totals();
141
+ }else{
142
+ $exists_products[ $search_key ] = $key;
143
+ }
144
+ }
145
+
146
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
147
+ return $cart_contents;
148
+ }
149
+
150
+ public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ){
151
+
152
+ $attr_translation = $attribute;
153
+
154
+ if( !empty( $attribute ) ){
155
+ //delete 'attribute_' at the beginning
156
+ $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
157
+
158
+ if( taxonomy_exists( $taxonomy ) ){
159
+ if( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
160
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
161
+ $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
162
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
163
+ $attr_translation = $term->slug;
164
+ }
165
+ }else{
166
+
167
+ $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
168
+
169
+ if( $trnsl_attr ){
170
+ $attr_translation = $trnsl_attr;
171
+ }else{
172
+ $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
173
+ }
174
+ }
175
+ }
176
+
177
+ return $attr_translation;
178
+ }
179
+
180
+ //get cart_item_data from existing cart array ( from session )
181
+ public function get_cart_item_data_from_cart( $cart_contents ){
182
+ unset( $cart_contents[ 'product_id' ] );
183
+ unset( $cart_contents[ 'variation_id' ] );
184
+ unset( $cart_contents[ 'variation' ] );
185
+ unset( $cart_contents[ 'quantity' ] );
186
+ unset( $cart_contents[ 'data' ] );
187
+
188
+ return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
189
+ }
190
+
191
+ public function translate_cart_contents( $item, $values, $key ) {
192
+ // translate the product id and product data
193
+ $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
194
+ if ($item[ 'variation_id' ]) {
195
+ $item[ 'variation_id' ] = apply_filters( 'translate_object_id',$item[ 'variation_id' ], 'product_variation', true );
196
+ }
197
+ $product_id = $item[ 'variation_id' ] ? $item[ 'variation_id' ] : $item[ 'product_id' ];
198
+ $item[ 'data' ]->post->post_title = get_the_title( $item[ 'product_id' ] );
199
+ return $item;
200
+ }
201
+
202
+ public function translate_cart_subtotal( $cart ) {
203
+
204
+ if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
205
+ $cart->calculate_totals();
206
+ }
207
+
208
+ }
209
+
210
+ // refresh cart total to return correct price from WC object
211
+ public function wcml_refresh_cart_total() {
212
+ WC()->cart->calculate_totals();
213
+ }
214
+
215
+
216
+ public function localize_flat_rates_shipping_classes(){
217
+ global $woocommerce;
218
+
219
+ if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
220
+ $woocommerce->shipping->load_shipping_methods();
221
+ $shipping_methods = $woocommerce->shipping->get_shipping_methods();
222
+ foreach($shipping_methods as $method){
223
+ if(isset($method->flat_rate_option)){
224
+ add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
225
+ }
226
+ }
227
+
228
+ }
229
+ }
230
+
231
+ public function translate_shipping_class($rates){
232
+
233
+ if(is_array($rates)){
234
+ foreach($rates as $shipping_class => $value){
235
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
236
+
237
+ if($term_id && !is_wp_error($term_id)){
238
+ $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
239
+ if($translated_term_id != $term_id){
240
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
241
+ unset($rates[$shipping_class]);
242
+ $rates[$term->slug] = $value;
243
+
244
+ }
245
+ }
246
+ }
247
+ }
248
+ return $rates;
249
+ }
250
+
251
+ public function filter_paypal_args( $args ) {
252
+ $args['lc'] = $this->sitepress->get_current_language();
253
+
254
+ //filter URL when default permalinks uses
255
+ $wpml_settings = $this->sitepress->get_settings();
256
+ if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
257
+ $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
258
+ }
259
+
260
+ return $args;
261
+ }
262
  }
inc/class-wcml-compatibility.php CHANGED
@@ -1,171 +1,171 @@
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
-
169
- }
170
-
171
  }
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
+
169
+ }
170
+
171
  }
inc/class-wcml-coupons.php CHANGED
@@ -1,73 +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
- $product_ids = array();
18
- $exclude_product_ids = array();
19
- $product_categories_ids = array();
20
- $exclude_product_categories_ids = array();
21
-
22
- foreach( $coupons_data->product_ids as $prod_id ){
23
- $post_type = get_post_field( 'post_type', $prod_id );
24
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
25
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
26
- foreach( $translations as $translation ){
27
- $product_ids[] = $translation->element_id;
28
- }
29
- }
30
- foreach( $coupons_data->exclude_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
- $exclude_product_ids[] = $translation->element_id;
36
- }
37
- }
38
-
39
- foreach( $coupons_data->product_categories as $cat_id ){
40
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
41
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
42
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
43
-
44
- foreach( $translations as $translation ){
45
- $product_categories_ids[] = $translation->term_id;
46
- }
47
- }
48
-
49
- foreach( $coupons_data->exclude_product_categories as $cat_id ){
50
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
51
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
52
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
53
- foreach( $translations as $translation ){
54
- $exclude_product_categories_ids[] = $translation->term_id;
55
- }
56
- }
57
-
58
- $coupons_data->product_ids = $product_ids;
59
- $coupons_data->exclude_product_ids = $exclude_product_ids;
60
- $coupons_data->product_categories = $product_categories_ids;
61
- $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
62
-
63
- return $coupons_data;
64
- }
65
-
66
- public function icl_adjust_terms_filtering(){
67
- if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
68
- global $icl_adjust_id_url_filter_off;
69
- $icl_adjust_id_url_filter_off = true;
70
- }
71
- }
72
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
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,370 +1,347 @@
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.1.5', '<')){
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
- function check_design_update(){
82
-
83
- if( defined('ICL_SITEPRESS_VERSION') && version_compare( ICL_SITEPRESS_VERSION, '3.4-dev', '<' ) ){
84
- add_action( 'admin_notices', array( $this, '_old_backend_wpml_warning' ) );
85
- return false;
86
- }
87
-
88
- return true;
89
- }
90
-
91
- /**
92
- * Adds admin notice.
93
- */
94
- public function _old_wpml_warning(){
95
- ?>
96
- <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.',
97
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '3.1.5'); ?></p></div>
98
- <?php }
99
-
100
- function _old_wc_warning(){
101
- ?>
102
- <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.',
103
- 'woocommerce-multilingual'), 'http://www.woothemes.com/woocommerce/', '2.1' ); ?></p></div>
104
- <?php }
105
-
106
- public function _old_backend_wpml_warning(){
107
- ?>
108
- <?php if( !isset($_GET['page']) || $_GET['page'] != 'wpml-wcml'): ?>
109
- <div class="message error">
110
- <p><?php printf(__( 'You are using WooCommerce Multilingual %s. This version includes an important UI redesign for the configuration screens and it requires <a href="%s">WPML %s</a> or higher. Everything still works on the front end now but, in order to configure options for WooCommerce Multilingual, you need to upgrade WPML.', 'woocommerce-multilingual' ), WCML_VERSION, WCML_Links::generate_tracking_link( 'https://wpml.org/' ), '3.4'); ?></p>
111
- <p>
112
- <a class="button-primary" href="<?php echo $this->required_plugin_install_link( 'wpml' ) ?>"
113
- target="_blank"><?php _e( 'Upgrade WPML', 'woocommerce-multilingual' ); ?></a>
114
- </p>
115
- </div>
116
- <?php endif; ?>
117
- <?php }
118
-
119
- public function _old_wpml_tm_warning(){
120
- ?>
121
- <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.',
122
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '1.9'); ?></p></div>
123
- <?php }
124
-
125
- public function _old_wpml_st_warning(){
126
- ?>
127
- <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.',
128
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.0'); ?></p></div>
129
- <?php }
130
-
131
- public function _old_wpml_media_warning(){
132
- ?>
133
- <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.',
134
- 'woocommerce-multilingual'), WCML_Links::generate_tracking_link('https://wpml.org/'), '2.1'); ?></p></div>
135
- <?php }
136
-
137
-
138
- /**
139
- * Adds admin notice.
140
- */
141
- public function _missing_plugins_warning(){
142
-
143
- $missing = '';
144
- $counter = 0;
145
- foreach ($this->missing as $title => $url) {
146
- $counter ++;
147
- if ($counter == sizeof($this->missing)) {
148
- $sep = '';
149
- } elseif ($counter == sizeof($this->missing) - 1) {
150
- $sep = ' ' . __('and', 'woocommerce-multilingual') . ' ';
151
- } else {
152
- $sep = ', ';
153
- }
154
- $missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep;
155
- } ?>
156
-
157
- <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>
158
- <?php
159
- }
160
-
161
- /**
162
- * For all the urls to work we need either:
163
- * 1) the shop page slug must be the same in all languages
164
- * 2) or the shop prefix disabled in woocommerce settings
165
- * one of these must be true for product urls to work
166
- * if none of these are true, display a warning message
167
- */
168
- private function check_for_incompatible_permalinks() {
169
- global $sitepress, $sitepress_settings, $pagenow;
170
-
171
- // WooCommerce 2.x specific checks
172
- $permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
173
- if (empty($permalinks['product_base'])) {
174
- return;
175
- }
176
-
177
- $message = sprintf('Because this site uses the default permalink structure, you cannot use slug translation for product permalinks.', 'woocommerce-multilingual');
178
- $message .= '<br /><br />';
179
- $message .= sprintf('Please choose a different permalink structure or disable slug translation.', 'woocommerce-multilingual');
180
- $message .= '<br /><br />';
181
- $message .= '<a href="' . admin_url('options-permalink.php') . '">' . __('Permalink settings', 'woocommerce-multilingual') . '</a>';
182
- $message .= ' | ';
183
- $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>';
184
-
185
-
186
- // Check if translated shop pages have the same slug (only 1.x)
187
- $allsame = true;
188
- if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
189
- } else {
190
- $shop_page_id = get_option('woocommerce_shop_page_id', false);
191
- if (!empty($shop_page_id)) {
192
- $slug = @get_post($shop_page_id)->post_name;
193
- $languages = $sitepress->get_active_languages();
194
- if (sizeof($languages) < 2) {
195
- return;
196
- }
197
- foreach ($languages as $language) {
198
- if ($language['code'] != $sitepress->get_default_language()) {
199
- $translated_shop_page_id = apply_filters( 'translate_object_id',$shop_page_id, 'page', false, $language['code']);
200
- if (!empty($translated_shop_page_id)) {
201
- $translated_slug = get_post($translated_shop_page_id)->post_name;
202
- if (!empty($translated_slug) && $translated_slug != $slug) {
203
- $allsame = false;
204
- break;
205
- }
206
- }
207
- }
208
- }
209
- }
210
- }
211
-
212
- // Check if slug translation is enabled
213
- $compatible = true;
214
- $permalink_structure = get_option('permalink_structure');
215
- if ( empty($permalink_structure)
216
- && !empty($sitepress_settings['posts_slug_translation']['on'])
217
- && !empty($sitepress_settings['posts_slug_translation']['types'])
218
- && $sitepress_settings['posts_slug_translation']['types']['product']) {
219
- $compatible = false;
220
- }
221
-
222
- // display messages
223
- if (!$allsame) {
224
- $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'),
225
- $slug, $translated_slug, admin_url("admin.php?page=woocommerce_settings&tab=pages")).'</p></div>';
226
- add_action('admin_notices', array($this,'plugin_notice_message'));
227
- }
228
-
229
- if (!$compatible && ($pagenow == 'options-permalink.php' || (isset($_GET['page']) && $_GET['page'] == 'wpml-wcml'))) {
230
- $this->err_message = '<div class="message error"><p>'.$message.' </p></div>';
231
- add_action('admin_notices', array($this,'plugin_notice_message'));
232
- }
233
- }
234
-
235
- public function plugin_notice_message(){
236
- echo $this->err_message;
237
- }
238
-
239
- public function fix_strings_language(){
240
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
241
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_fix_strings_language')){
242
- die('Invalid nonce');
243
- }
244
-
245
- $ret = array();
246
-
247
- $ret['_wpnonce'] = wp_create_nonce('icl_sw_form');
248
-
249
- $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>');
250
-
251
-
252
- echo json_encode($ret);
253
-
254
- exit;
255
-
256
- }
257
-
258
- public function check_wpml_config(){
259
- global $sitepress_settings;
260
-
261
- if(empty($sitepress_settings)) return;
262
-
263
- $file = realpath(WCML_PLUGIN_PATH . '/wpml-config.xml');
264
- if(!file_exists($file)){
265
- $this->xml_config_errors[] = __('wpml-config.xml file missing from WooCommerce Multilingual folder.', 'woocommerce-multilingual');
266
- }else{
267
- $config = icl_xml2array(file_get_contents($file));
268
-
269
- if(isset($config['wpml-config'])){
270
-
271
- //custom-fields
272
- if(isset($config['wpml-config']['custom-fields'])){
273
- if(isset($config['wpml-config']['custom-fields']['custom-field']['value'])){ //single
274
- $cfs[] = $config['wpml-config']['custom-fields']['custom-field'];
275
- }else{
276
- foreach($config['wpml-config']['custom-fields']['custom-field'] as $cf){
277
- $cfs[] = $cf;
278
- }
279
- }
280
-
281
- if($cfs)
282
- foreach($cfs as $cf){
283
- if(!isset($sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']])) continue;
284
-
285
- $effective_config_value = $sitepress_settings['translation-management']['custom_fields_translation'][$cf['value']];
286
- $correct_config_value = $cf['attr']['action'] == 'copy' ? 1 : ($cf['attr']['action'] == 'translate' ? 2: 0);
287
-
288
- if($effective_config_value != $correct_config_value){
289
- $this->xml_config_errors[] = sprintf(__('Custom field %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $cf['value'] . '</i>');
290
- }
291
- }
292
-
293
- }
294
-
295
- //custom-types
296
- if(isset($config['wpml-config']['custom-types'])){
297
- if(isset($config['wpml-config']['custom-types']['custom-type']['value'])){ //single
298
- $cts[] = $config['wpml-config']['custom-types']['custom-type'];
299
- }else{
300
- foreach($config['wpml-config']['custom-types']['custom-type'] as $cf){
301
- $cts[] = $cf;
302
- }
303
- }
304
-
305
- if($cts)
306
- foreach($cts as $ct){
307
- if(!isset($sitepress_settings['custom_posts_sync_option'][$ct['value']])) continue;
308
- $effective_config_value = $sitepress_settings['custom_posts_sync_option'][$ct['value']];
309
- $correct_config_value = $ct['attr']['translate'];
310
-
311
- if($effective_config_value != $correct_config_value){
312
- $this->xml_config_errors[] = sprintf(__('Custom type %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $ct['value'] . '</i>');
313
- }
314
- }
315
-
316
- }
317
-
318
- //taxonomies
319
- if(isset($config['wpml-config']['taxonomies'])){
320
- if(isset($config['wpml-config']['taxonomies']['taxonomy']['value'])){ //single
321
- $txs[] = $config['wpml-config']['taxonomies']['taxonomy'];
322
- }else{
323
- foreach($config['wpml-config']['taxonomies']['taxonomy'] as $cf){
324
- $txs[] = $cf;
325
- }
326
- }
327
-
328
- if($txs)
329
- foreach($txs as $tx){
330
- if(!isset($sitepress_settings['taxonomies_sync_option'][$tx['value']])) continue;
331
- $effective_config_value = $sitepress_settings['taxonomies_sync_option'][$tx['value']];
332
- $correct_config_value = $tx['attr']['translate'];
333
-
334
- if($effective_config_value != $correct_config_value){
335
- $this->xml_config_errors[] = sprintf(__('Custom taxonomy %s configuration from wpml-config.xml file was altered!', 'woocommerce-multilingual'), '<i>' . $tx['value'] . '</i>');
336
- }
337
- }
338
-
339
- }
340
- }
341
- }
342
-
343
- }
344
-
345
- public function required_plugin_install_link($repository = 'wpml'){
346
-
347
- if( class_exists('WP_Installer_API') ){
348
- $url = WP_Installer_API::get_product_installer_link($repository);
349
- }else{
350
- $url = WCML_Links::generate_tracking_link('https://wpml.org/');
351
- }
352
-
353
- return $url;
354
- }
355
-
356
- /**
357
- * The support for the Twig templates comes from WPML by default
358
- * When WPML is not active, WCML will load it
359
- */
360
- private function load_twig_support(){
361
-
362
- if (!class_exists( 'Twig_Autoloader' )){
363
- require_once WCML_PLUGIN_PATH . '/lib/Twig/Autoloader.php';
364
- Twig_Autoloader::register();
365
- }
366
-
367
- }
368
-
369
- }
370
 
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
+ require_once WCML_PLUGIN_PATH . '/lib/Twig/Autoloader.php';
341
+ Twig_Autoloader::register();
342
+ }
343
+
344
+ }
345
+
346
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
347
 
inc/class-wcml-emails.php CHANGED
@@ -1,484 +1,459 @@
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
- if( is_admin() && $pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'email' ){
61
- add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
62
- $this->set_emails_string_lamguage();
63
- }
64
-
65
- add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
66
-
67
- if( !isset( $_GET['post_type'] ) || $_GET['post_type'] != 'shop_order' ){
68
- add_filter( 'woocommerce_order_get_items', array( $this, 'filter_order_items' ), 10, 2 );
69
- add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
70
- }
71
- }
72
-
73
- function email_refresh_in_ajax(){
74
- if(isset($_GET['order_id'])){
75
- $this->refresh_email_lang($_GET['order_id']);
76
- $this->email_heading_completed($_GET['order_id'],true);
77
- }
78
- }
79
-
80
- function refresh_email_lang_complete( $order_id ){
81
-
82
- $this->order_id = $order_id;
83
- $this->refresh_email_lang($order_id);
84
- $this->email_heading_completed($order_id,true);
85
-
86
- }
87
-
88
- /**
89
- * Translate WooCommerce emails.
90
- *
91
- * @global type $sitepress
92
- * @global type $order_id
93
- * @return type
94
- */
95
- function email_header($order) {
96
-
97
-
98
- if (is_array($order)) {
99
- $order = $order['order_id'];
100
- } elseif (is_object($order)) {
101
- $order = $order->id;
102
- }
103
-
104
- $this->refresh_email_lang($order);
105
-
106
- }
107
-
108
-
109
- function refresh_email_lang($order_id){
110
-
111
- if ( is_array( $order_id ) ) {
112
- if ( isset($order_id['order_id']) ) {
113
- $order_id = $order_id['order_id'];
114
- } else {
115
- return;
116
- }
117
-
118
- }
119
-
120
- $lang = get_post_meta($order_id, 'wpml_language', TRUE);
121
- if(!empty($lang)){
122
- $this->change_email_language($lang);
123
- }
124
- }
125
-
126
- /**
127
- * After email translation switch language to default.
128
- */
129
- function email_footer() {
130
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
131
- }
132
-
133
- function comments_language(){
134
- $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
135
-
136
- }
137
-
138
- function email_heading_completed( $order_id, $no_checking = false ){
139
- global $woocommerce;
140
- if(class_exists('WC_Email_Customer_Completed_Order') || $no_checking){
141
-
142
- $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' );
143
-
144
- $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' );
145
-
146
- $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' );
147
-
148
- $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' );
149
-
150
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
151
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
152
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
153
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
154
- }
155
- }
156
-
157
- function email_heading_processing($order_id){
158
- global $woocommerce;
159
- if(class_exists('WC_Email_Customer_Processing_Order')){
160
-
161
- $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' );
162
-
163
- $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' );
164
-
165
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
166
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
167
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
168
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
169
- }
170
- }
171
-
172
- function email_heading_note($args){
173
- global $woocommerce;
174
-
175
- if(class_exists('WC_Email_Customer_Note')){
176
-
177
- $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' );
178
-
179
- $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' );
180
-
181
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
182
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
183
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
184
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
185
- }
186
- }
187
-
188
- function email_heading_refund( $order_id, $refund_id = null ){
189
- global $woocommerce;
190
- if(class_exists('WC_Email_Customer_Refunded_Order')){
191
-
192
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
193
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
194
- '[woocommerce_customer_refunded_order_settings]heading_partial' );
195
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
196
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
197
- '[woocommerce_customer_refunded_order_settings]subject_partial' );
198
-
199
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
200
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
201
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
202
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
203
-
204
- }
205
- }
206
-
207
-
208
- function new_order_admin_email($order_id){
209
- global $woocommerce;
210
- if(isset( $woocommerce->mailer()->emails['WC_Email_New_Order'] )){
211
- $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
212
- foreach($recipients as $recipient){
213
- $user = get_user_by('email',$recipient);
214
- if($user){
215
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true);
216
- }else{
217
- $user_lang = get_post_meta($order_id, 'wpml_language', TRUE);
218
- }
219
-
220
- $this->change_email_language($user_lang);
221
-
222
- $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' );
223
-
224
- $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' );
225
-
226
- $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
227
-
228
- $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
229
- }
230
- $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
231
- $this->refresh_email_lang($order_id);
232
- }
233
- }
234
-
235
- public function backend_new_order_admin_email( $order_id ){
236
- if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
237
- $this->new_order_admin_email( $order_id );
238
- }
239
- }
240
-
241
- function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
242
- if( $meta_key == '_payment_method_title' ){
243
-
244
- $payment_method = get_post_meta( $object_id, '_payment_method', true );
245
-
246
- if( $payment_method ){
247
-
248
- $payment_gateways = WC()->payment_gateways->payment_gateways();
249
- if( isset( $payment_gateways[ $payment_method ] ) ){
250
- $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
251
-
252
- return $title;
253
- }
254
- }
255
-
256
-
257
- }
258
- return $check;
259
- }
260
-
261
- function filter_order_items( $items, $object){
262
-
263
- foreach( $items as $item_key => $item ){
264
-
265
- foreach( $item as $key => $item_meta ){
266
-
267
- if( $key == 'type' && $item_meta == 'line_item' ){
268
-
269
- $current_prod_id = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', false, $this->sitepress->get_current_language() );
270
- if( !is_null( $current_prod_id ) ){
271
- $items[ $item_key ][ 'name' ] = wc_get_product( $current_prod_id )->get_title();
272
- }
273
-
274
- } elseif( $key == 'type' && $item_meta == 'shipping' && isset( $item[ 'method_id' ] ) ){
275
-
276
- $items[ $item_key ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $this->sitepress->get_current_language() );
277
-
278
- }
279
-
280
- }
281
-
282
- }
283
-
284
-
285
- return $items;
286
- }
287
-
288
- function filter_formatted_items( $formatted_meta, $object ){
289
-
290
- if( $object->product->variation_id ){
291
-
292
- $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
293
-
294
- if( !is_null( $current_prod_variation_id ) ) {
295
-
296
- $var_data = wc_get_product( $object->product->id )->get_available_variation( $current_prod_variation_id );
297
-
298
- foreach( $formatted_meta as $key => $formatted_var ){
299
-
300
- foreach( $var_data[ 'attributes' ] as $attr_full_key => $attribute ){
301
-
302
- $attr_key = substr( $attr_full_key, 10 );
303
-
304
- if( $formatted_var[ 'key' ] == $attr_key ){
305
-
306
- $formatted_meta[ $key ][ 'value' ] = $attribute;
307
-
308
- if( !taxonomy_exists( wc_sanitize_taxonomy_name ( $attr_key ) ) ){
309
-
310
- $custom_attr_trnsl = $this->woocommerce_wpml->attributes->get_custom_attribute_translation( $object->product->id, $attr_key, array('is_taxonomy' => false), $this->sitepress->get_current_language() );
311
-
312
- $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
313
- }
314
- }
315
- }
316
- }
317
- }
318
- }
319
-
320
- return $formatted_meta;
321
-
322
- }
323
-
324
- function change_email_language($lang){
325
- global $woocommerce;
326
- $this->sitepress->switch_lang($lang,true);
327
- $this->locale = $this->sitepress->get_locale( $lang );
328
- unload_textdomain('woocommerce');
329
- unload_textdomain('default');
330
- $woocommerce->load_plugin_textdomain();
331
- load_default_textdomain();
332
- global $wp_locale;
333
- $wp_locale = new WP_Locale();
334
- }
335
-
336
- function admin_string_return_cached( $value, $option ){
337
- if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
338
- return false;
339
-
340
- return $value;
341
- }
342
-
343
- function wcml_get_translated_email_string( $context, $name ){
344
-
345
- if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
346
- global $wpdb;
347
-
348
- $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
349
-
350
- return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
351
- }else{
352
-
353
- return apply_filters( 'wpml_translate_single_string', false, $context, $name );
354
-
355
- }
356
-
357
- }
358
-
359
- function icl_current_string_language( $current_language, $name ){
360
- $order_id = false;
361
-
362
- 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' ){
363
- $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
364
- }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
365
- $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
366
- }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
367
- $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
368
- }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
369
- $order_id = $this->order_id;
370
- }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
371
- $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
372
- }
373
-
374
- if( $order_id ){
375
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
376
- if( $order_language ){
377
- $current_language = $order_language;
378
- }else{
379
- $current_language = $this->sitepress->get_current_language();
380
- }
381
- }
382
-
383
- return apply_filters( 'wcml_email_language', $current_language, $order_id );
384
- }
385
-
386
- // set correct locale code for emails
387
- function set_locale_for_emails( $locale, $domain ){
388
-
389
- if( $domain == 'woocommerce' && $this->locale ){
390
- $locale = $this->locale;
391
- }
392
-
393
- return $locale;
394
- }
395
-
396
- function show_language_links_for_wc_emails(){
397
-
398
- $emails_options = array(
399
- 'woocommerce_new_order_settings',
400
- 'woocommerce_cancelled_order_settings',
401
- 'woocommerce_failed_order_settings',
402
- 'woocommerce_customer_on_hold_order_settings',
403
- 'woocommerce_customer_processing_order_settings',
404
- 'woocommerce_customer_completed_order_settings',
405
- 'woocommerce_customer_refunded_order_settings',
406
- 'woocommerce_customer_invoice_settings',
407
- 'woocommerce_customer_note_settings',
408
- 'woocommerce_customer_reset_password_settings',
409
- 'woocommerce_customer_new_account_settings'
410
- );
411
-
412
- $text_keys = array(
413
- 'subject',
414
- 'heading',
415
- 'subject_downloadable',
416
- 'heading_downloadable',
417
- 'subject_full',
418
- 'subject_partial',
419
- 'heading_full',
420
- 'heading_partial',
421
- 'subject_paid',
422
- 'heading_paid'
423
- );
424
-
425
-
426
- foreach( $emails_options as $emails_option ) {
427
-
428
- $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
429
- $section_name = str_replace( '_settings', '', $section_name );
430
- if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
431
-
432
- $option_settings = get_option( $emails_option );
433
- foreach ($option_settings as $setting_key => $setting_value) {
434
- if ( in_array( $setting_key, $text_keys ) ) {
435
- $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
436
-
437
- $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
438
- $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
439
- if( is_null( $language ) ) {
440
- $language = $this->sitepress->get_default_language();
441
- }
442
-
443
- $lang_selector->render( array(
444
- 'id' => $emails_option.'_'.$setting_key.'_language_selector',
445
- 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
446
- 'selected' => $language,
447
- 'show_please_select' => false,
448
- 'echo' => true,
449
- 'style' => 'width: 18%;float: left'
450
- )
451
- );
452
-
453
- $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
454
- ?>
455
- <script>
456
- var input = jQuery('input[name="<?php echo $input_name ?>"]');
457
- if (input.length) {
458
- input.parent().append('<div class="translation_controls"></div>');
459
- input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
460
- jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
461
- }
462
- </script>
463
- <?php }
464
- }
465
- }
466
- }
467
- }
468
-
469
- function set_emails_string_lamguage(){
470
-
471
- foreach( $_POST as $key => $post_value ){
472
- if( substr( $key, 0, 9 ) == 'wcml_lang' ){
473
-
474
- $email_string = explode( '-', $key );
475
- $email_settings = get_option( $email_string[1], true );
476
-
477
- if( isset( $email_string[2] ) ){
478
- $this->woocommerce_wpml->strings->set_string_language( $email_settings[ $email_string[2] ], 'admin_texts_'.$email_string[1] , '['.$email_string[1].']'.$email_string[2], $post_value );
479
- }
480
- }
481
- }
482
- }
483
-
484
  }
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_lamguage();
64
+ }
65
+
66
+ add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
67
+
68
+ if( !isset( $_GET['post_type'] ) || $_GET['post_type'] != 'shop_order' ){
69
+ add_filter( 'woocommerce_order_items_meta_get_formatted', array( $this, 'filter_formatted_items' ), 10, 2 );
70
+ }
71
+ }
72
+
73
+ function email_refresh_in_ajax(){
74
+ if(isset($_GET['order_id'])){
75
+ $this->refresh_email_lang($_GET['order_id']);
76
+ $this->email_heading_completed($_GET['order_id'],true);
77
+ }
78
+ }
79
+
80
+ function refresh_email_lang_complete( $order_id ){
81
+
82
+ $this->order_id = $order_id;
83
+ $this->refresh_email_lang($order_id);
84
+ $this->email_heading_completed($order_id,true);
85
+
86
+ }
87
+
88
+ /**
89
+ * Translate WooCommerce emails.
90
+ *
91
+ * @global type $sitepress
92
+ * @global type $order_id
93
+ * @return type
94
+ */
95
+ function email_header($order) {
96
+
97
+
98
+ if (is_array($order)) {
99
+ $order = $order['order_id'];
100
+ } elseif (is_object($order)) {
101
+ $order = $order->id;
102
+ }
103
+
104
+ $this->refresh_email_lang($order);
105
+
106
+ }
107
+
108
+
109
+ function refresh_email_lang($order_id){
110
+
111
+ if ( is_array( $order_id ) ) {
112
+ if ( isset($order_id['order_id']) ) {
113
+ $order_id = $order_id['order_id'];
114
+ } else {
115
+ return;
116
+ }
117
+
118
+ }
119
+
120
+ $lang = get_post_meta($order_id, 'wpml_language', TRUE);
121
+ if(!empty($lang)){
122
+ $this->change_email_language($lang);
123
+ }
124
+ }
125
+
126
+ /**
127
+ * After email translation switch language to default.
128
+ */
129
+ function email_footer() {
130
+ $this->sitepress->switch_lang($this->sitepress->get_default_language());
131
+ }
132
+
133
+ function comments_language(){
134
+ $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
135
+
136
+ }
137
+
138
+ function email_heading_completed( $order_id, $no_checking = false ){
139
+ global $woocommerce;
140
+ if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
141
+
142
+ $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' );
143
+
144
+ $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' );
145
+
146
+ $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' );
147
+
148
+ $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' );
149
+
150
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
151
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
152
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
153
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
154
+ }
155
+ }
156
+
157
+ function email_heading_processing($order_id){
158
+ global $woocommerce;
159
+ if( class_exists( 'WC_Email_Customer_Processing_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Processing_Order' ] ) ){
160
+
161
+ $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' );
162
+
163
+ $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' );
164
+
165
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
166
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
167
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
168
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
169
+ }
170
+ }
171
+
172
+ function email_heading_note($args){
173
+ global $woocommerce;
174
+
175
+ if( class_exists( 'WC_Email_Customer_Note' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
176
+
177
+ $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' );
178
+
179
+ $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' );
180
+
181
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
182
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
183
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
184
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
185
+ }
186
+ }
187
+
188
+ function email_heading_refund( $order_id, $refund_id = null ){
189
+ global $woocommerce;
190
+ if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
191
+
192
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
193
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
194
+ '[woocommerce_customer_refunded_order_settings]heading_partial' );
195
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
196
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
197
+ '[woocommerce_customer_refunded_order_settings]subject_partial' );
198
+
199
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
200
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
201
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
202
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
203
+
204
+ }
205
+ }
206
+
207
+
208
+ function new_order_admin_email($order_id){
209
+ global $woocommerce;
210
+ if( class_exists( 'WC_Email_New_Order' ) && isset( $woocommerce->mailer()->emails['WC_Email_New_Order'] ) ){
211
+ $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
212
+ foreach($recipients as $recipient){
213
+ $user = get_user_by('email',$recipient);
214
+ if($user){
215
+ $user_lang = $this->sitepress->get_user_admin_language($user->ID, true);
216
+ }else{
217
+ $user_lang = get_post_meta($order_id, 'wpml_language', TRUE);
218
+ }
219
+
220
+ $this->change_email_language($user_lang);
221
+
222
+ $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' );
223
+
224
+ $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' );
225
+
226
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
227
+
228
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
229
+ }
230
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
231
+ $this->refresh_email_lang($order_id);
232
+ }
233
+ }
234
+
235
+ public function backend_new_order_admin_email( $order_id ){
236
+ if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
237
+ $this->new_order_admin_email( $order_id );
238
+ }
239
+ }
240
+
241
+ function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
242
+ if( $meta_key == '_payment_method_title' ){
243
+
244
+ $payment_method = get_post_meta( $object_id, '_payment_method', true );
245
+
246
+ if( $payment_method ){
247
+
248
+ $payment_gateways = WC()->payment_gateways->payment_gateways();
249
+ if( isset( $payment_gateways[ $payment_method ] ) ){
250
+ $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
251
+
252
+ return $title;
253
+ }
254
+ }
255
+
256
+
257
+ }
258
+ return $check;
259
+ }
260
+
261
+ function filter_formatted_items( $formatted_meta, $object ){
262
+
263
+ if( $object->product->variation_id ){
264
+
265
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
266
+
267
+ if( !is_null( $current_prod_variation_id ) ) {
268
+
269
+ foreach( $formatted_meta as $key => $formatted_var ){
270
+
271
+ if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
272
+
273
+ $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
274
+
275
+ if( taxonomy_exists( $attribute ) ){
276
+ $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
277
+ $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
278
+
279
+ if( $tr_id ){
280
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
281
+ $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
282
+ }
283
+
284
+ }else{
285
+
286
+ $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() );
287
+
288
+ $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
289
+ }
290
+ }
291
+ }
292
+ }
293
+ }
294
+
295
+ return $formatted_meta;
296
+
297
+ }
298
+
299
+ function change_email_language($lang){
300
+ global $woocommerce;
301
+ $this->sitepress->switch_lang($lang,true);
302
+ $this->locale = $this->sitepress->get_locale( $lang );
303
+ unload_textdomain('woocommerce');
304
+ unload_textdomain('default');
305
+ $woocommerce->load_plugin_textdomain();
306
+ load_default_textdomain();
307
+ global $wp_locale;
308
+ $wp_locale = new WP_Locale();
309
+ }
310
+
311
+ function admin_string_return_cached( $value, $option ){
312
+ if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
313
+ return false;
314
+
315
+ return $value;
316
+ }
317
+
318
+ function wcml_get_translated_email_string( $context, $name ){
319
+
320
+ if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
321
+ global $wpdb;
322
+
323
+ $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
324
+
325
+ return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
326
+ }else{
327
+
328
+ return apply_filters( 'wpml_translate_single_string', false, $context, $name );
329
+
330
+ }
331
+
332
+ }
333
+
334
+ function icl_current_string_language( $current_language, $name ){
335
+ $order_id = false;
336
+
337
+ 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' ){
338
+ $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
339
+ }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
340
+ $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
341
+ }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
342
+ $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
343
+ }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
344
+ $order_id = $this->order_id;
345
+ }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
346
+ $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
347
+ }
348
+
349
+ if( $order_id ){
350
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
351
+ if( $order_language ){
352
+ $current_language = $order_language;
353
+ }else{
354
+ $current_language = $this->sitepress->get_current_language();
355
+ }
356
+ }
357
+
358
+ return apply_filters( 'wcml_email_language', $current_language, $order_id );
359
+ }
360
+
361
+ // set correct locale code for emails
362
+ function set_locale_for_emails( $locale, $domain ){
363
+
364
+ if( $domain == 'woocommerce' && $this->locale ){
365
+ $locale = $this->locale;
366
+ }
367
+
368
+ return $locale;
369
+ }
370
+
371
+ function show_language_links_for_wc_emails(){
372
+
373
+ $emails_options = array(
374
+ 'woocommerce_new_order_settings',
375
+ 'woocommerce_cancelled_order_settings',
376
+ 'woocommerce_failed_order_settings',
377
+ 'woocommerce_customer_on_hold_order_settings',
378
+ 'woocommerce_customer_processing_order_settings',
379
+ 'woocommerce_customer_completed_order_settings',
380
+ 'woocommerce_customer_refunded_order_settings',
381
+ 'woocommerce_customer_invoice_settings',
382
+ 'woocommerce_customer_note_settings',
383
+ 'woocommerce_customer_reset_password_settings',
384
+ 'woocommerce_customer_new_account_settings'
385
+ );
386
+
387
+ $text_keys = array(
388
+ 'subject',
389
+ 'heading',
390
+ 'subject_downloadable',
391
+ 'heading_downloadable',
392
+ 'subject_full',
393
+ 'subject_partial',
394
+ 'heading_full',
395
+ 'heading_partial',
396
+ 'subject_paid',
397
+ 'heading_paid'
398
+ );
399
+
400
+
401
+ foreach( $emails_options as $emails_option ) {
402
+
403
+ $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
404
+ $section_name = str_replace( '_settings', '', $section_name );
405
+ if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
406
+
407
+ $option_settings = get_option( $emails_option );
408
+ foreach ($option_settings as $setting_key => $setting_value) {
409
+ if ( in_array( $setting_key, $text_keys ) ) {
410
+ $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
411
+
412
+ $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
413
+ $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
414
+ if( is_null( $language ) ) {
415
+ $language = $this->sitepress->get_default_language();
416
+ }
417
+
418
+ $lang_selector->render( array(
419
+ 'id' => $emails_option.'_'.$setting_key.'_language_selector',
420
+ 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
421
+ 'selected' => $language,
422
+ 'show_please_select' => false,
423
+ 'echo' => true,
424
+ 'style' => 'width: 18%;float: left'
425
+ )
426
+ );
427
+
428
+ $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
429
+ ?>
430
+ <script>
431
+ var input = jQuery('input[name="<?php echo $input_name ?>"]');
432
+ if (input.length) {
433
+ input.parent().append('<div class="translation_controls"></div>');
434
+ input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
435
+ jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
436
+ }
437
+ </script>
438
+ <?php }
439
+ }
440
+ }
441
+ }
442
+ }
443
+
444
+ function set_emails_string_lamguage(){
445
+
446
+ foreach( $_POST as $key => $post_value ){
447
+ if( substr( $key, 0, 9 ) == 'wcml_lang' ){
448
+
449
+ $email_string = explode( '-', $key );
450
+ $email_settings = get_option( $email_string[1], true );
451
+
452
+ if( isset( $email_string[2] ) ){
453
+ $this->woocommerce_wpml->strings->set_string_language( $email_settings[ $email_string[2] ], 'admin_texts_'.$email_string[1] , '['.$email_string[1].']'.$email_string[2], $post_value );
454
+ }
455
+ }
456
+ }
457
+ }
458
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  }
inc/class-wcml-endpoints.php CHANGED
@@ -1,266 +1,283 @@
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
- }
27
-
28
-
29
- function register_endpoints_translations(){
30
-
31
- if( !class_exists( 'woocommerce' ) || !defined( 'ICL_SITEPRESS_VERSION' ) || ICL_PLUGIN_INACTIVE || version_compare( WOOCOMMERCE_VERSION, '2.2', '<' ) ) return false;
32
-
33
- $wc_vars = WC()->query->query_vars;
34
-
35
- if ( !empty( $wc_vars ) ){
36
- $query_vars = array(
37
- // Checkout actions
38
- 'order-pay' => $this->get_endpoint_translation( 'order-pay', $wc_vars['order-pay'] ),
39
- 'order-received' => $this->get_endpoint_translation( 'order-received', $wc_vars['order-received'] ),
40
-
41
- // My account actions
42
- 'view-order' => $this->get_endpoint_translation( 'view-order', $wc_vars['view-order'] ),
43
- 'edit-account' => $this->get_endpoint_translation( 'edit-account', $wc_vars['edit-account'] ),
44
- 'edit-address' => $this->get_endpoint_translation( 'edit-address', $wc_vars['edit-address'] ),
45
- 'lost-password' => $this->get_endpoint_translation( 'lost-password', $wc_vars['lost-password'] ),
46
- 'customer-logout' => $this->get_endpoint_translation( 'customer-logout', $wc_vars['customer-logout'] ),
47
- 'add-payment-method' => $this->get_endpoint_translation( 'add-payment-method', $wc_vars['add-payment-method'] )
48
- );
49
-
50
- if( isset( $wc_vars['orders'] ) ) $query_vars[ 'orders' ] = $this->get_endpoint_translation( 'orders', $wc_vars['orders'] );
51
- if( isset( $wc_vars['downloads'] ) ) $query_vars[ 'downloads' ] = $this->get_endpoint_translation( 'downloads', $wc_vars['downloads'] );
52
- if( isset( $wc_vars['payment-methods'] ) ) $query_vars[ 'payment-methods' ] = $this->get_endpoint_translation( 'payment-methods', $wc_vars['payment-methods'] );
53
- if( isset( $wc_vars['delete-payment-method'] ) ) $query_vars[ 'delete-payment-method' ] = $this->get_endpoint_translation( 'delete-payment-method', $wc_vars['delete-payment-method'] );
54
- 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'] );
55
-
56
- $query_vars = apply_filters( 'wcml_register_endpoints_query_vars', $query_vars, $wc_vars, $this );
57
-
58
- $query_vars = array_merge( $wc_vars , $query_vars );
59
- WC()->query->query_vars = $query_vars;
60
-
61
- }
62
-
63
- }
64
-
65
- function get_endpoint_translation( $key, $endpoint, $language = null ){
66
- global $wpdb;
67
-
68
- $string = icl_get_string_id( $endpoint, 'WooCommerce Endpoints', $key );
69
-
70
- if( !$string && function_exists( 'icl_register_string' ) ){
71
- do_action('wpml_register_single_string', 'WooCommerce Endpoints', $key, $endpoint );
72
- }else{
73
- $this->endpoints_strings[] = $string;
74
- }
75
-
76
- if( function_exists('icl_t') ){
77
- $trnsl = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', $key, $language );
78
-
79
- if( !empty( $trnsl ) ){
80
- return $trnsl;
81
- }else{
82
- return $endpoint;
83
- }
84
- }else{
85
- return $endpoint;
86
- }
87
- }
88
-
89
- function rewrite_rule_endpoints( $call, $data ){
90
- if( $call == 'icl_st_save_translation' && in_array( $data['icl_st_string_id'], $this->endpoints_strings ) ){
91
- $this->add_endpoints();
92
- $this->flush_rules_for_endpoints_translations();
93
- }
94
- }
95
-
96
- function flush_rules_for_endpoints_translations( ){
97
- add_option( 'flush_rules_for_endpoints_translations', true );
98
- }
99
-
100
- function maybe_flush_rules(){
101
- if( get_option( 'flush_rules_for_endpoints_translations' ) ){
102
- WC()->query->init_query_vars();
103
- WC()->query->add_endpoints();
104
- flush_rewrite_rules();
105
- delete_option( 'flush_rules_for_endpoints_translations' );
106
- }
107
- }
108
-
109
- function update_rewrite_rules( $value, $old_value ){
110
- $this->add_endpoints();
111
- $this->flush_rules_for_endpoints_translations();
112
-
113
- return $value;
114
- }
115
-
116
- function add_endpoints(){
117
- if( !isset( $this->endpoints_strings ) )
118
- return;
119
-
120
- global $wpdb;
121
- //add endpoints and flush rules
122
- foreach( $this->endpoints_strings as $string_id ){
123
-
124
- $string_translations = icl_get_string_translations_by_id( $string_id );
125
-
126
- foreach( $string_translations as $string ){
127
- add_rewrite_endpoint( $string['value'], EP_ROOT | EP_PAGES );
128
- }
129
- }
130
-
131
- }
132
-
133
- function endpoint_permalink_filter( $p, $pid ){
134
- global $post;
135
-
136
- if( isset($post->ID) && !is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.2', '>=' ) && defined( 'ICL_SITEPRESS_VERSION' ) && !ICL_PLUGIN_INACTIVE ){
137
- global $wp,$sitepress;
138
-
139
- $current_lang = $sitepress->get_current_language();
140
- $page_lang = $sitepress->get_language_for_element( $post->ID, 'post_page');
141
- if( $current_lang != $page_lang && apply_filters( 'translate_object_id', $pid, 'page', false, $page_lang ) == $post->ID ){
142
-
143
- $endpoints = WC()->query->get_query_vars();
144
-
145
- foreach( $endpoints as $key => $endpoint ){
146
- if( isset($wp->query_vars[$key]) ){
147
- if( in_array( $key, array( 'pay', 'order-received' ) ) ){
148
- $endpoint = get_option( 'woocommerce_checkout_'.str_replace( '-','_',$key).'_endpoint' );
149
- }else{
150
- $endpoint = get_option( 'woocommerce_myaccount_'.str_replace( '-','_',$key).'_endpoint' );
151
- }
152
-
153
- $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
154
-
155
- $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
156
- }
157
- }
158
- }
159
- }
160
-
161
- return $p;
162
- }
163
-
164
- function get_endpoint_url($endpoint, $value = '', $permalink = '', $page_lang = false ){
165
- global $sitepress;
166
-
167
- if( $page_lang ){
168
- $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
169
- $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
170
-
171
- if( $edit_address_shipping == urldecode( $value ) ){
172
- $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
173
- }elseif( $edit_address_billing == urldecode( $value ) ){
174
- $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
175
- }
176
-
177
- }
178
-
179
-
180
- if ( get_option( 'permalink_structure' ) ) {
181
- if ( strstr( $permalink, '?' ) ) {
182
- $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
183
- $permalink = current( explode( '?', $permalink ) );
184
- } else {
185
- $query_string = '';
186
- }
187
- $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
188
- } else {
189
- $url = add_query_arg( $endpoint, $value, $permalink );
190
- }
191
- return $url;
192
- }
193
-
194
- /*
195
- * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
196
- */
197
- function check_if_endpoint_exists($q){
198
- global $wp_query;
199
-
200
- $my_account_id = wc_get_page_id('myaccount');
201
-
202
- $current_id = $q->query_vars['page_id'];
203
- if(!$current_id){
204
- $current_id = $q->queried_object_id;
205
- }
206
-
207
- if( !$q->is_404 && $current_id == $my_account_id && $q->is_page ){
208
-
209
- $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI']) );
210
- $endpoints = WC()->query->get_query_vars();
211
- $endpoint_in_url = urldecode( end( $uri_vars ) );
212
-
213
- $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
214
- $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
215
-
216
- 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 ) ){
217
- $wp_query->set_404();
218
- status_header(404);
219
- include( get_query_template( '404' ) );
220
- die();
221
- }
222
-
223
- }
224
-
225
- }
226
-
227
- function get_translated_edit_address_slug( $slug, $language = false ){
228
- global $woocommerce_wpml;
229
-
230
- $strings_language = $woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: '.$slug );
231
-
232
- if( $strings_language == $language ){
233
- return $slug;
234
- }
235
-
236
- $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: '.$slug, $language );
237
-
238
- if( $translated_slug == $slug ){
239
-
240
- if( $language ){
241
- $translated_slug = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug'. chr(4) .$slug, $language );
242
- }else{
243
- $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
244
- }
245
-
246
- }
247
-
248
- return $translated_slug;
249
- }
250
-
251
- function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ){
252
-
253
- // return translated edit account slugs
254
- if( isset( WC()->query->query_vars[ 'edit-address' ] ) && isset( WC()->query->query_vars[ 'edit-address' ] ) == $endpoint && in_array( $value, array('shipping','billing'))){
255
- remove_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
256
- $url = wc_get_endpoint_url( 'edit-address', $this->get_translated_edit_address_slug( $value ) );
257
- add_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
258
-
259
-
260
- }
261
-
262
- return $url;
263
- }
264
-
265
-
266
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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( in_array( $key, array( 'pay', 'order-received' ) ) ){
155
+ $endpoint = get_option( 'woocommerce_checkout_'.str_replace( '-','_',$key).'_endpoint' );
156
+ }else{
157
+ $endpoint = get_option( 'woocommerce_myaccount_'.str_replace( '-','_',$key).'_endpoint' );
158
+ }
159
+
160
+ $endpoint = apply_filters( 'wcml_endpoint_permalink_filter', $endpoint, $key );
161
+
162
+ $p = $this->get_endpoint_url( $this->get_endpoint_translation( $key, $endpoint, $current_lang ), $wp->query_vars[ $key ], $p, $page_lang );
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ return $p;
169
+ }
170
+
171
+ function get_endpoint_url($endpoint, $value = '', $permalink = '', $page_lang = false ){
172
+ global $sitepress;
173
+
174
+ if( $page_lang ){
175
+ $edit_address_shipping = $this->get_translated_edit_address_slug( 'shipping', $page_lang );
176
+ $edit_address_billing = $this->get_translated_edit_address_slug( 'billing', $page_lang );
177
+
178
+ if( $edit_address_shipping == urldecode( $value ) ){
179
+ $value = $this->get_translated_edit_address_slug( 'shipping', $sitepress->get_current_language() );
180
+ }elseif( $edit_address_billing == urldecode( $value ) ){
181
+ $value = $this->get_translated_edit_address_slug( 'billing', $sitepress->get_current_language() );
182
+ }
183
+
184
+ }
185
+
186
+
187
+ if ( get_option( 'permalink_structure' ) ) {
188
+ if ( strstr( $permalink, '?' ) ) {
189
+ $query_string = '?' . parse_url( $permalink, PHP_URL_QUERY );
190
+ $permalink = current( explode( '?', $permalink ) );
191
+ } else {
192
+ $query_string = '';
193
+ }
194
+ $url = trailingslashit( $permalink ) . $endpoint . '/' . $value . $query_string;
195
+ } else {
196
+ $url = add_query_arg( $endpoint, $value, $permalink );
197
+ }
198
+ return $url;
199
+ }
200
+
201
+ /*
202
+ * We need check special case - when you manually put in URL default not translated endpoint it not generated 404 error
203
+ */
204
+ function check_if_endpoint_exists($q){
205
+ global $wp_query;
206
+
207
+ $my_account_id = wc_get_page_id('myaccount');
208
+
209
+ $current_id = $q->query_vars['page_id'];
210
+ if(!$current_id){
211
+ $current_id = $q->queried_object_id;
212
+ }
213
+
214
+ if( !$q->is_404 && $current_id == $my_account_id && $q->is_page ){
215
+
216
+ $uri_vars = array_filter( explode( '/', $_SERVER['REQUEST_URI']) );
217
+ $endpoints = WC()->query->get_query_vars();
218
+ $endpoint_in_url = urldecode( end( $uri_vars ) );
219
+
220
+ $endpoints['shipping'] = urldecode( $this->get_translated_edit_address_slug( 'shipping' ) );
221
+ $endpoints['billing'] = urldecode( $this->get_translated_edit_address_slug( 'billing' ) );
222
+
223
+ 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 ) ){
224
+ $wp_query->set_404();
225
+ status_header(404);
226
+ include( get_query_template( '404' ) );
227
+ die();
228
+ }
229
+
230
+ }
231
+
232
+ }
233
+
234
+ function get_translated_edit_address_slug( $slug, $language = false ){
235
+ global $woocommerce_wpml;
236
+
237
+ $strings_language = $woocommerce_wpml->strings->get_string_language( $slug, 'woocommerce', 'edit-address-slug: '.$slug );
238
+
239
+ if( $strings_language == $language ){
240
+ return $slug;
241
+ }
242
+
243
+ $translated_slug = apply_filters( 'wpml_translate_single_string', $slug, 'woocommerce', 'edit-address-slug: '.$slug, $language );
244
+
245
+ if( $translated_slug == $slug ){
246
+
247
+ if( $language ){
248
+ $translated_slug = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'edit-address-slug'. chr(4) .$slug, $language );
249
+ }else{
250
+ $translated_slug = _x( $slug, 'edit-address-slug', 'woocommerce' );
251
+ }
252
+
253
+ }
254
+
255
+ return $translated_slug;
256
+ }
257
+
258
+ function filter_get_endpoint_url( $url, $endpoint, $value, $permalink ){
259
+
260
+ // return translated edit account slugs
261
+ if( isset( WC()->query->query_vars[ 'edit-address' ] ) && isset( WC()->query->query_vars[ 'edit-address' ] ) == $endpoint && in_array( $value, array('shipping','billing'))){
262
+ remove_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
263
+ $url = wc_get_endpoint_url( 'edit-address', $this->get_translated_edit_address_slug( $value ) );
264
+ add_filter('woocommerce_get_endpoint_url', array( $this, 'filter_get_endpoint_url'),10,4);
265
+
266
+
267
+ }
268
+
269
+ return $url;
270
+ }
271
+
272
+ public function update_original_endpoints_strings(){
273
+
274
+ foreach( WC()->query->query_vars as $endpoint_key => $endpoint ){
275
+
276
+ $this->register_endpoint_string( $endpoint_key, $endpoint );
277
+
278
+ }
279
+
280
+ }
281
+
282
+
283
+ }
inc/class-wcml-fix-copied-custom-fields-wpml353.php ADDED
@@ -0,0 +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
+ }
inc/class-wcml-install.php CHANGED
@@ -1,210 +1,222 @@
1
- <?php
2
-
3
- class WCML_Install{
4
-
5
- public static function initialize( &$woocommerce_wpml, &$sitepress ) {
6
-
7
- // Install routine
8
- if ( empty($woocommerce_wpml->settings['set_up']) ) { // from 3.2
9
-
10
- if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
11
- //global term ordering resync when moving to >= 3.3.x
12
- add_action( 'init', array($woocommerce_wpml->terms, 'sync_term_order_globally'), 20 );
13
- }
14
-
15
- if ( !isset($woocommerce_wpml->settings['wc_admin_options_saved']) ) {
16
- self::handle_admin_texts();
17
- $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
18
- }
19
-
20
- if ( !isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
21
- $woocommerce_wpml->settings['trnsl_interface'] = 1;
22
- }
23
-
24
- if ( !isset($woocommerce_wpml->settings['products_sync_date']) ) {
25
- $woocommerce_wpml->settings['products_sync_date'] = 1;
26
- }
27
-
28
- if ( !isset($woocommerce_wpml->settings['products_sync_order']) ) {
29
- $woocommerce_wpml->settings['products_sync_order'] = 1;
30
- }
31
-
32
- if ( !isset($woocommerce_wpml->settings['display_custom_prices']) ) {
33
- $woocommerce_wpml->settings['display_custom_prices'] = 0;
34
- }
35
-
36
- if ( !isset($woocommerce_wpml->settings['sync_taxonomies_checked']) ) {
37
- $woocommerce_wpml->terms->check_if_sync_terms_needed();
38
- $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
39
- }
40
-
41
- WCML_Capabilities::set_up_capabilities();
42
-
43
- self:: set_language_information( $sitepress );
44
- self:: check_product_type_terms( );
45
-
46
- $woocommerce_wpml->settings['set_up'] = 1;
47
- $woocommerce_wpml->update_settings();
48
-
49
- }
50
-
51
- if(empty($woocommerce_wpml->settings['downloaded_translations_for_wc'])){ //from 3.3.3
52
- $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
53
- $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
54
- $woocommerce_wpml->update_settings();
55
- }
56
-
57
- add_filter( 'wpml_tm_dashboard_translatable_types', array( __CLASS__, 'hide_variation_type_on_tm_dashboard') );
58
-
59
- new WCML_Setup( $woocommerce_wpml, $sitepress );
60
- if ( !empty($woocommerce_wpml->settings['set_up_wizard_run']) ) {
61
- add_action( 'admin_notices', array(__CLASS__, 'admin_notice_after_install') );
62
- }
63
-
64
- }
65
-
66
- private static function set_language_information( &$sitepress ){
67
- global $wpdb;
68
-
69
- $def_lang = $sitepress->get_default_language();
70
- //set language info for products
71
- $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
72
- foreach($products as $product){
73
- $exist = $sitepress->get_language_for_element($product->ID,'post_product');
74
- if(!$exist){
75
- $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
76
- }
77
- }
78
-
79
- //set language info for taxonomies
80
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
81
- foreach($terms as $term){
82
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
83
- if(!$exist){
84
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
85
- }
86
- }
87
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
88
- foreach($terms as $term){
89
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
90
- if(!$exist){
91
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
92
- }
93
- }
94
-
95
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
96
- foreach($terms as $term){
97
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
98
- if(!$exist){
99
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
100
- }
101
- }
102
- }
103
-
104
- //handle situation when product_type terms translated before activating WCML
105
- private static function check_product_type_terms(){
106
- global $wpdb;
107
- //check if terms were translated
108
- $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
109
-
110
- if( $translations ){
111
- foreach( $translations as $translation ){
112
- if( !is_null( $translation->source_language_code ) ){
113
- //check relationships
114
- $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
115
- if( $term_relationships ){
116
- $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 ) );
117
- if( $orig_term ){
118
- foreach( $term_relationships as $term_relationship ){
119
- $wpdb->update(
120
- $wpdb->term_relationships,
121
- array(
122
- 'term_taxonomy_id' => $orig_term
123
- ),
124
- array(
125
- 'object_id' => $term_relationship->object_id,
126
- 'term_taxonomy_id' => $translation->element_id
127
- )
128
- );
129
- }
130
- }
131
- }
132
- $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
133
-
134
- if( $term_id ){
135
- $wpdb->delete(
136
- $wpdb->terms,
137
- array(
138
- 'term_id' => $term_id
139
- )
140
- );
141
-
142
- $wpdb->delete(
143
- $wpdb->term_taxonomy,
144
- array(
145
- 'term_taxonomy_id' => $translation->element_id
146
- )
147
- );
148
- }
149
- }
150
- }
151
-
152
- foreach( $translations as $translation ){
153
- $wpdb->delete(
154
- $wpdb->prefix . 'icl_translations',
155
- array(
156
- 'translation_id' => $translation->translation_id
157
- )
158
- );
159
- }
160
- }
161
- }
162
-
163
- private static function handle_admin_texts(){
164
- if(class_exists('woocommerce')){
165
- //emails texts
166
- $emails = new WC_Emails();
167
- foreach($emails->emails as $email){
168
- $option_name = $email->plugin_id.$email->id.'_settings';
169
- if(!get_option($option_name)){
170
- add_option($option_name,$email->settings);
171
- }
172
- }
173
- }
174
- }
175
-
176
- public static function admin_notice_after_install(){
177
- global $woocommerce_wpml;
178
-
179
- if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
180
-
181
- $url = $_SERVER['REQUEST_URI'];
182
- $pos = strpos($url, '?');
183
-
184
- if($pos !== false){
185
- $url .= '&wcml_action=dismiss';
186
- } else {
187
- $url .= '?wcml_action=dismiss';
188
- }
189
- ?>
190
- <div id="message" class="updated message fade otgs-is-dismissible">
191
- <p>
192
- <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
193
- </p>
194
- <p>
195
- <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">
196
- <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
197
- </a>
198
- </p>
199
- <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
200
- </div>
201
- <?php
202
- }
203
- }
204
-
205
- public static function hide_variation_type_on_tm_dashboard( $types ){
206
- unset( $types['product_variation'] );
207
- return $types;
208
- }
209
-
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
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
+ add_filter( 'wpml_tm_dashboard_translatable_types', array(
65
+ __CLASS__,
66
+ 'hide_variation_type_on_tm_dashboard'
67
+ ) );
68
+
69
+ new WCML_Setup( $woocommerce_wpml, $sitepress );
70
+ if ( ! empty( $woocommerce_wpml->settings['set_up_wizard_run'] ) ) {
71
+ add_action( 'admin_notices', array( __CLASS__, 'admin_notice_after_install' ) );
72
+ }
73
+
74
+ }
75
+
76
+ }
77
+
78
+ private static function set_language_information( &$sitepress ){
79
+ global $wpdb;
80
+
81
+ $def_lang = $sitepress->get_default_language();
82
+ //set language info for products
83
+ $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
84
+ foreach($products as $product){
85
+ $exist = $sitepress->get_language_for_element($product->ID,'post_product');
86
+ if(!$exist){
87
+ $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
88
+ }
89
+ }
90
+
91
+ //set language info for taxonomies
92
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
93
+ foreach($terms as $term){
94
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
95
+ if(!$exist){
96
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
97
+ }
98
+ }
99
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
100
+ foreach($terms as $term){
101
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
102
+ if(!$exist){
103
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
104
+ }
105
+ }
106
+
107
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
108
+ foreach($terms as $term){
109
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
110
+ if(!$exist){
111
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
112
+ }
113
+ }
114
+ }
115
+
116
+ //handle situation when product_type terms translated before activating WCML
117
+ private static function check_product_type_terms(){
118
+ global $wpdb;
119
+ //check if terms were translated
120
+ $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
121
+
122
+ if( $translations ){
123
+ foreach( $translations as $translation ){
124
+ if( !is_null( $translation->source_language_code ) ){
125
+ //check relationships
126
+ $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
127
+ if( $term_relationships ){
128
+ $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 ) );
129
+ if( $orig_term ){
130
+ foreach( $term_relationships as $term_relationship ){
131
+ $wpdb->update(
132
+ $wpdb->term_relationships,
133
+ array(
134
+ 'term_taxonomy_id' => $orig_term
135
+ ),
136
+ array(
137
+ 'object_id' => $term_relationship->object_id,
138
+ 'term_taxonomy_id' => $translation->element_id
139
+ )
140
+ );
141
+ }
142
+ }
143
+ }
144
+ $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
145
+
146
+ if( $term_id ){
147
+ $wpdb->delete(
148
+ $wpdb->terms,
149
+ array(
150
+ 'term_id' => $term_id
151
+ )
152
+ );
153
+
154
+ $wpdb->delete(
155
+ $wpdb->term_taxonomy,
156
+ array(
157
+ 'term_taxonomy_id' => $translation->element_id
158
+ )
159
+ );
160
+ }
161
+ }
162
+ }
163
+
164
+ foreach( $translations as $translation ){
165
+ $wpdb->delete(
166
+ $wpdb->prefix . 'icl_translations',
167
+ array(
168
+ 'translation_id' => $translation->translation_id
169
+ )
170
+ );
171
+ }
172
+ }
173
+ }
174
+
175
+ private static function handle_admin_texts(){
176
+ if(class_exists('woocommerce')){
177
+ //emails texts
178
+ $emails = new WC_Emails();
179
+ foreach($emails->emails as $email){
180
+ $option_name = $email->plugin_id.$email->id.'_settings';
181
+ if(!get_option($option_name)){
182
+ add_option($option_name,$email->settings);
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ public static function admin_notice_after_install(){
189
+ global $woocommerce_wpml;
190
+
191
+ if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
192
+
193
+ $url = $_SERVER['REQUEST_URI'];
194
+ $pos = strpos($url, '?');
195
+
196
+ if($pos !== false){
197
+ $url .= '&wcml_action=dismiss';
198
+ } else {
199
+ $url .= '?wcml_action=dismiss';
200
+ }
201
+ ?>
202
+ <div id="message" class="updated message fade otgs-is-dismissible">
203
+ <p>
204
+ <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
205
+ </p>
206
+ <p>
207
+ <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">
208
+ <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
209
+ </a>
210
+ </p>
211
+ <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
212
+ </div>
213
+ <?php
214
+ }
215
+ }
216
+
217
+ public static function hide_variation_type_on_tm_dashboard( $types ){
218
+ unset( $types['product_variation'] );
219
+ return $types;
220
+ }
221
+
222
  }
inc/class-wcml-languages-upgrader.php CHANGED
@@ -1,284 +1,292 @@
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
-
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
- $upgrader->bulk_upgrade( $upgr_object );
56
-
57
- $this->save_translation_version( $locale, false, $wc_version );
58
- }
59
-
60
- }
61
-
62
-
63
- /*
64
- * Automatically download translations for WC for active languages
65
- *
66
- */
67
- function download_woocommerce_translations_for_active_languages( $wc_version = false ){
68
- global $sitepress, $woocommerce_wpml;
69
-
70
- $active_languages = $sitepress->get_active_languages();
71
-
72
- $current_language = $sitepress->get_current_language();
73
-
74
- foreach( $active_languages as $language ){
75
-
76
- $this->download_woocommerce_translations( $language['code'], $wc_version );
77
-
78
- }
79
-
80
- $sitepress->switch_lang( $current_language );
81
-
82
- if( isset( $woocommerce_wpml->url_translation ) ){
83
- $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
84
- }
85
-
86
- }
87
-
88
-
89
- /*
90
- * Check for WC language updates
91
- *
92
- * @param object $data Transient update data
93
- *
94
- * @return object
95
- */
96
- function check_for_update( $data ){
97
- global $sitepress;
98
-
99
- $active_languages = $sitepress->get_active_languages();
100
- $current_language = $sitepress->get_current_language();
101
-
102
- foreach( $active_languages as $language ){
103
- if( $language['code'] == 'en' )
104
- continue;
105
-
106
- $locale = $sitepress->get_locale( $language['code'] );
107
-
108
- if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
109
-
110
- $data->translations[] = array(
111
- 'type' => 'plugin',
112
- 'slug' => 'woocommerce',
113
- 'language' => $locale,
114
- 'version' => WC_VERSION,
115
- 'updated' => date( 'Y-m-d H:i:s' ),
116
- 'package' => $this->get_language_pack_uri( $locale ),
117
- 'autoupdate' => 1
118
- );
119
-
120
- }
121
-
122
- }
123
-
124
- return $data;
125
- }
126
-
127
-
128
- function get_language_pack_uri( $locale, $version = false ){
129
-
130
- if( !$version ){
131
- $version = WC_VERSION;
132
- }
133
-
134
- if( version_compare( $version, '2.5.0', '<') ){
135
- $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
136
- return $repo . $version . '/packages/' . $locale . '.zip';
137
-
138
- }else{
139
- $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
140
- return $repo . $version . '/' . $locale . '.zip';
141
- }
142
-
143
- }
144
-
145
- /*
146
- * Update the WC language version in database
147
- *
148
- *
149
- * @param bool $reply Whether to bail without returning the package (default: false)
150
- * @param string $package Package URL
151
- *
152
- * @return bool
153
- */
154
- function version_update( $reply, $package ) {
155
-
156
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
157
-
158
- if( !is_array( $notices ) ){
159
- return $reply;
160
- }
161
-
162
- foreach( $notices as $key => $locale){
163
- if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
164
-
165
- $this->save_translation_version( $locale, $key );
166
-
167
- }
168
- }
169
-
170
- return $reply;
171
- }
172
-
173
-
174
- function save_translation_version( $locale, $key = false, $wc_version = false ){
175
-
176
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
177
-
178
- // Update the language pack version
179
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
180
-
181
- if( is_array( $notices ) ){
182
-
183
- if( !$key )
184
- $key = array_search( $locale, $notices );
185
-
186
- // Remove the translation upgrade notice
187
- unset( $notices[ $key ] );
188
-
189
- update_option( 'wcml_translations_upgrade_notice', $notices );
190
-
191
- }
192
-
193
- }
194
-
195
- /*
196
- * Check if has available translation update
197
- *
198
- * @param string $locale Locale code
199
- *
200
- * @return bool
201
- */
202
- function has_available_update( $locale, $wc_version = false ) {
203
- $wc_version = $wc_version ? $wc_version : WC_VERSION;
204
-
205
- $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
206
-
207
- $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
208
- $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
209
-
210
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
211
-
212
- if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
213
- if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
214
-
215
- if( !$notices || !in_array( $locale, $notices )){
216
- $notices[] = $locale;
217
-
218
- update_option( 'wcml_translations_upgrade_notice', $notices );
219
- update_option( 'hide_wcml_translations_message', 0 );
220
- }
221
-
222
- return true;
223
- } else {
224
- // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
225
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
226
- }
227
- }
228
-
229
- return false;
230
- }
231
-
232
-
233
- /**
234
- * Check if language pack exists
235
- *
236
- * @return bool
237
- */
238
- function check_if_language_pack_exists( $locale, $wc_version ) {
239
-
240
- $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
241
-
242
- if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
243
- return true;
244
- } else {
245
- return false;
246
- }
247
- }
248
-
249
-
250
- /*
251
- * Display Translations upgrade notice message
252
- */
253
- function translation_upgrade_notice(){
254
- global $woocommerce_wpml;
255
-
256
- $screen = get_current_screen();
257
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
258
-
259
- if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
260
-
261
- wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
262
- wp_enqueue_script( 'wcml-lang-notice');
263
-
264
- $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
265
- $lang_notices->show();
266
- }
267
- }
268
-
269
- /*
270
- * Hide Translations upgrade notice message ( update option in DB )
271
- */
272
- function hide_wcml_translations_message(){
273
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
274
- if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
275
- die('Invalid nonce');
276
- }
277
- update_option( 'hide_wcml_translations_message', true );
278
-
279
- die();
280
- }
281
-
282
-
283
-
 
 
 
 
 
 
 
 
284
  }
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
+ $upgrader->bulk_upgrade( $upgr_object );
56
+
57
+ $this->save_translation_version( $locale, false, $wc_version );
58
+ }
59
+
60
+ }
61
+
62
+
63
+ /*
64
+ * Automatically download translations for WC for active languages
65
+ *
66
+ */
67
+ function download_woocommerce_translations_for_active_languages( $wc_version = false ){
68
+ global $sitepress, $woocommerce_wpml;
69
+
70
+ $active_languages = $sitepress->get_active_languages();
71
+
72
+ $current_language = $sitepress->get_current_language();
73
+
74
+ foreach( $active_languages as $language ){
75
+
76
+ $this->download_woocommerce_translations( $language['code'], $wc_version );
77
+
78
+ }
79
+
80
+ $sitepress->switch_lang( $current_language );
81
+
82
+ if( isset( $woocommerce_wpml->url_translation ) ){
83
+ $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
84
+ }
85
+
86
+ }
87
+
88
+
89
+ /*
90
+ * Check for WC language updates
91
+ *
92
+ * @param object $data Transient update data
93
+ *
94
+ * @return object
95
+ */
96
+ function check_for_update( $data ){
97
+ global $sitepress;
98
+
99
+ $active_languages = $sitepress->get_active_languages();
100
+ $current_language = $sitepress->get_current_language();
101
+
102
+ foreach( $active_languages as $language ){
103
+ if( $language['code'] == 'en' )
104
+ continue;
105
+
106
+ $locale = $sitepress->get_locale( $language['code'] );
107
+
108
+ if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
109
+
110
+ $data->translations[] = array(
111
+ 'type' => 'plugin',
112
+ 'slug' => 'woocommerce',
113
+ 'language' => $locale,
114
+ 'version' => WC_VERSION,
115
+ 'updated' => date( 'Y-m-d H:i:s' ),
116
+ 'package' => $this->get_language_pack_uri( $locale ),
117
+ 'autoupdate' => 1
118
+ );
119
+
120
+ }
121
+
122
+ }
123
+
124
+ return $data;
125
+ }
126
+
127
+
128
+ function get_language_pack_uri( $locale, $version = false ){
129
+
130
+ if( !$version ){
131
+ $version = WC_VERSION;
132
+ }
133
+
134
+ if( version_compare( $version, '2.5.0', '<') ){
135
+ $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
136
+ return $repo . $version . '/packages/' . $locale . '.zip';
137
+
138
+ }else{
139
+ $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
140
+ return $repo . $version . '/' . $locale . '.zip';
141
+ }
142
+
143
+ }
144
+
145
+ /*
146
+ * Update the WC language version in database
147
+ *
148
+ *
149
+ * @param bool $reply Whether to bail without returning the package (default: false)
150
+ * @param string $package Package URL
151
+ *
152
+ * @return bool
153
+ */
154
+ function version_update( $reply, $package ) {
155
+
156
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
157
+
158
+ if( !is_array( $notices ) ){
159
+ return $reply;
160
+ }
161
+
162
+ foreach( $notices as $key => $locale){
163
+ if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
164
+
165
+ $this->save_translation_version( $locale, $key );
166
+
167
+ }
168
+ }
169
+
170
+ return $reply;
171
+ }
172
+
173
+
174
+ function save_translation_version( $locale, $key = false, $wc_version = false ){
175
+
176
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
177
+
178
+ // Update the language pack version
179
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
180
+
181
+ if( is_array( $notices ) ){
182
+
183
+ if( !$key )
184
+ $key = array_search( $locale, $notices );
185
+
186
+ // Remove the translation upgrade notice
187
+ unset( $notices[ $key ] );
188
+
189
+ update_option( 'wcml_translations_upgrade_notice', $notices );
190
+
191
+ }
192
+
193
+ }
194
+
195
+ /*
196
+ * Check if has available translation update
197
+ *
198
+ * @param string $locale Locale code
199
+ *
200
+ * @return bool
201
+ */
202
+ function has_available_update( $locale, $wc_version = false ) {
203
+ $wc_version = $wc_version ? $wc_version : WC_VERSION;
204
+
205
+ $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
206
+
207
+ $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
208
+ $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
209
+
210
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
211
+
212
+ if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
213
+ if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
214
+
215
+ if( !$notices || !in_array( $locale, $notices )){
216
+ $notices[] = $locale;
217
+
218
+ update_option( 'wcml_translations_upgrade_notice', $notices );
219
+ update_option( 'hide_wcml_translations_message', 0 );
220
+ }
221
+
222
+ return true;
223
+ } else {
224
+ // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
225
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
226
+ }
227
+ }
228
+
229
+ return false;
230
+ }
231
+
232
+
233
+ /**
234
+ * Check if language pack exists
235
+ *
236
+ * @return bool
237
+ */
238
+ function check_if_language_pack_exists( $locale, $wc_version ) {
239
+
240
+ $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
241
+
242
+ if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
243
+ return true;
244
+ } else {
245
+ return false;
246
+ }
247
+ }
248
+
249
+
250
+ /*
251
+ * Display Translations upgrade notice message
252
+ */
253
+ function translation_upgrade_notice(){
254
+ global $woocommerce_wpml;
255
+
256
+ $screen = get_current_screen();
257
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
258
+
259
+ if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
260
+
261
+ $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
262
+ $lang_notices->show();
263
+ }
264
+ }
265
+
266
+ /*
267
+ * Hide Translations upgrade notice message ( update option in DB )
268
+ */
269
+ function hide_wcml_translations_message(){
270
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
271
+ if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
272
+ die('Invalid nonce');
273
+ }
274
+ update_option( 'hide_wcml_translations_message', true );
275
+
276
+ die();
277
+ }
278
+
279
+ public function load_js(){
280
+
281
+ wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
282
+ wp_enqueue_script( 'wcml-lang-notice');
283
+
284
+ wp_localize_script( 'wcml-lang-notice', 'wcml_settings',
285
+ array(
286
+ 'warn' => __( "Downloading translations... Please don't close this page.", 'woocommerce-multilingual' )
287
+ )
288
+ );
289
+
290
+ }
291
+
292
  }
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,309 +1,377 @@
1
- <?php
2
- class WCML_Orders{
3
-
4
- private $standart_order_notes = array('Order status changed from %s to %s.',
5
- '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.',
6
- 'Validation error: PayPal amounts do not match (gross %s).','Validation error: PayPal IPN response from a different email address (%s).','Payment pending: %s',
7
- 'Payment %s via IPN.','Validation error: PayPal amounts do not match (amt %s).','IPN payment completed','PDT payment completed'
8
- );
9
-
10
- function __construct(){
11
-
12
- add_action('init', array($this, 'init'));
13
-
14
- //checkout page
15
- add_action( 'wp_ajax_woocommerce_checkout',array($this,'switch_to_current'),9);
16
- add_action( 'wp_ajax_nopriv_woocommerce_checkout',array($this,'switch_to_current'),9);
17
-
18
- add_action( 'wp_ajax_wcml_order_delete_items', array( $this, 'order_delete_items' ) );
19
- }
20
-
21
- function init(){
22
-
23
- add_action('woocommerce_shipping_update_ajax', array($this, 'fix_shipping_update'));
24
- add_action('woocommerce_checkout_update_order_meta', array($this, 'set_order_language'));
25
-
26
- add_filter('icl_lang_sel_copy_parameters', array($this, 'append_query_parameters'));
27
-
28
- add_filter('the_comments', array($this, 'get_filtered_comments'));
29
- add_filter('gettext',array($this, 'filtered_woocommerce_new_order_note_data'),10,3);
30
-
31
- add_filter('woocommerce_order_get_items',array($this,'woocommerce_order_get_items'),10);
32
-
33
- add_action( 'woocommerce_process_shop_order_meta', array( $this, 'set_order_language_backend'), 10, 2 );
34
- add_action( 'woocommerce_order_actions_start', array( $this, 'order_language_dropdown' ), 11 ); //after order currency drop-down
35
-
36
- //special case for wcml-741
37
- add_action('updated_post_meta', array($this,'update_order_currency'), 100,4);
38
-
39
- add_action( 'woocommerce_before_order_itemmeta', array( $this, 'backend_before_order_itemmeta' ), 100, 3 );
40
- add_action( 'woocommerce_after_order_itemmeta', array( $this, 'backend_after_order_itemmeta' ), 100, 3 );
41
-
42
- }
43
-
44
- function filtered_woocommerce_new_order_note_data($translations, $text, $domain ){
45
- if(in_array($text,$this->standart_order_notes)){
46
- global $sitepress, $wpdb, $woocommerce_wpml;
47
-
48
- $language = $woocommerce_wpml->strings->get_string_language( $text, 'woocommerce' );
49
-
50
- if( $sitepress->get_user_admin_language( get_current_user_id(), true ) != $language ){
51
-
52
- $string_id = icl_get_string_id( $text, 'woocommerce');
53
- $strings = icl_get_string_translations_by_id( $string_id );
54
- if($strings){
55
- $translations = $strings[ $sitepress->get_user_admin_language( get_current_user_id(), true ) ]['value'];
56
- }
57
-
58
- }else{
59
- return $text;
60
- }
61
- }
62
-
63
- return $translations;
64
- }
65
-
66
- function get_filtered_comments($comments){
67
-
68
- $user_id = get_current_user_id();
69
-
70
- if( $user_id ){
71
-
72
- global $wpdb, $woocommerce_wpml;
73
-
74
- $user_language = get_user_meta( $user_id, 'icl_admin_language', true );
75
-
76
- foreach($comments as $key=>$comment){
77
-
78
- $comment_string_id = icl_get_string_id( $comment->comment_content, 'woocommerce');
79
-
80
- if($comment_string_id){
81
- $comment_strings = icl_get_string_translations_by_id( $comment_string_id );
82
- if($comment_strings){
83
- $comments[$key]->comment_content = $comment_strings[$user_language]['value'];
84
- }
85
- }
86
- }
87
-
88
- }
89
-
90
- return $comments;
91
-
92
- }
93
-
94
- function woocommerce_order_get_items($items){
95
- global $sitepress;
96
-
97
- if( isset( $_GET[ 'post' ] ) && get_post_type( $_GET[ 'post' ] ) == 'shop_order' ){
98
-
99
- foreach($items as $index=>$item){
100
- foreach($item as $key=>$item_data){
101
- if($key == 'product_id'){
102
- $tr_product_id = apply_filters( 'translate_object_id',$item_data,'product',false,$sitepress->get_user_admin_language( get_current_user_id(), true ) );
103
- if(!is_null($tr_product_id)){
104
- $items[$index][$key] = $tr_product_id;
105
- $items[$index]['name'] = get_the_title($tr_product_id);
106
- }
107
- }
108
- if($key == 'variation_id'){
109
- $tr_variation_id = apply_filters( 'translate_object_id',$item_data,'product_variation',false,$sitepress->get_user_admin_language( get_current_user_id(), true ) );
110
- if(!is_null($tr_variation_id)){
111
- $items[$index][$key] = $tr_variation_id;
112
- }
113
- }
114
-
115
- if (substr($key, 0, 3) == 'pa_') {
116
- global $wpdb, $woocommerce_wpml;
117
- //attr is taxonomy
118
- $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $key, $item_data );
119
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $item_data, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
120
-
121
- $items[$index][$key] = $translated_term->slug;
122
- }
123
- }
124
- }
125
- }
126
- return $items;
127
- }
128
-
129
- public function backend_before_order_itemmeta( $item_id, $item, $product ){
130
- global $sitepress;
131
-
132
- if( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
133
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
134
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
135
- foreach( $item_meta as $value ){
136
- $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
137
- }
138
- }
139
- }
140
- }
141
- }
142
-
143
- public function backend_after_order_itemmeta( $item_id, $item, $product ){
144
- global $sitepress;
145
-
146
- $order_languge = $this->get_order_language_by_item_id( $item_id );
147
- if( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
148
- foreach( $item[ 'item_meta' ] as $key => $item_meta ){
149
- if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
150
- foreach( $item_meta as $value ){
151
- $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
152
- }
153
- }
154
- }
155
- }
156
- }
157
-
158
- public function get_order_language_by_item_id( $item_id ){
159
- global $wpdb;
160
-
161
- $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
162
-
163
- return get_post_meta( $order_id, 'wpml_language', true );
164
- }
165
-
166
- //force update to display attribute in correct language on edit order page
167
- public function force_update_itemmeta( $item_id, $key, $value, $languge ){
168
- global $wpdb, $woocommerce_wpml;
169
-
170
- $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
171
- $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
172
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
173
- $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
174
-
175
- if( $translated_term ){
176
- $value = $translated_term->slug;
177
- $wpdb->update( $wpdb->prefix.'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array( 'order_item_id' => $item_id, 'meta_key' => $key ) );
178
- }
179
- }
180
-
181
- // Fix for shipping update on the checkout page.
182
- function fix_shipping_update($amount){
183
- global $sitepress, $post;
184
-
185
- if($sitepress->get_current_language() !== $sitepress->get_default_language() && $post->ID == $this->checkout_page_id()){
186
-
187
- $_SESSION['icl_checkout_shipping_amount'] = $amount;
188
-
189
- $amount = $_SESSION['icl_checkout_shipping_amount'];
190
-
191
- }
192
-
193
- return $amount;
194
- }
195
-
196
-
197
- /**
198
- * Adds language to order post type.
199
- *
200
- * Language was stored in the session created on checkout page.
201
- * See params().
202
- *
203
- * @param type $order_id
204
- */
205
- function set_order_language($order_id) {
206
- if(!get_post_meta($order_id, 'wpml_language')){
207
- $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
208
- update_post_meta($order_id, 'wpml_language', $language);
209
- }
210
- }
211
-
212
- function append_query_parameters($parameters){
213
-
214
- if(is_order_received_page() || is_checkout()){
215
- if(!in_array('order', $parameters)) $parameters[] = 'order';
216
- if(!in_array('key', $parameters)) $parameters[] = 'key';
217
- }
218
-
219
- return $parameters;
220
- }
221
-
222
- function switch_to_current(){
223
- global $sitepress,$woocommerce_wpml;
224
- $woocommerce_wpml->emails->change_email_language($sitepress->get_current_language());
225
- }
226
-
227
- function order_language_dropdown( $order_id ){
228
- global $woocommerce_wpml, $sitepress;
229
- if( !get_post_meta( $order_id, '_order_currency') ) {
230
- $languages = icl_get_languages('skip_missing=0&orderby=code');
231
- $selected_lang = isset( $_COOKIE [ '_wcml_dashboard_order_language' ] ) ? $_COOKIE [ '_wcml_dashboard_order_language' ] : $sitepress->get_default_language();
232
- ?>
233
- <li class="wide">
234
- <label><?php _e('Order language:'); ?></label>
235
- <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
236
- <?php if (!empty($languages)): ?>
237
-
238
- <?php foreach ($languages as $l): ?>
239
-
240
- <option
241
- value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
242
-
243
- <?php endforeach; ?>
244
-
245
- <?php endif; ?>
246
- </select>
247
- </li>
248
- <?php
249
- $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
250
- wc_enqueue_js( "
251
- var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
252
-
253
- jQuery('#dropdown_shop_order_language').on('change', function(){
254
- if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual')). "')){
255
- var lang = jQuery(this).val();
256
-
257
- jQuery.ajax({
258
- url: ajaxurl,
259
- type: 'post',
260
- dataType: 'json',
261
- data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '".$wcml_set_dashboard_order_language_nonce."' },
262
- success: function( response ){
263
- if(typeof response.error !== 'undefined'){
264
- alert(response.error);
265
- }else{
266
- window.location = window.location.href;
267
- }
268
- }
269
- });
270
- }else{
271
- jQuery(this).val( order_lang_current_value );
272
- return false;
273
- }
274
- });
275
-
276
- ");
277
- }
278
- }
279
-
280
- function order_delete_items(){
281
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
282
- if(!$nonce || !wp_verify_nonce($nonce, 'set_dashboard_order_language')){
283
- echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
284
- die();
285
- }
286
-
287
- setcookie('_wcml_dashboard_order_language', filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
288
-
289
- }
290
-
291
- function set_order_language_backend( $post_id, $post ){
292
-
293
- if( isset( $_POST['wcml_shop_order_language'] ) ){
294
- update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
295
- }
296
-
297
- }
298
-
299
- function update_order_currency( $meta_id, $object_id, $meta_key, $meta_value ){
300
- global $woocommerce_wpml;
301
-
302
- if( $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' ){
303
- update_post_meta( $object_id, '_order_currency', get_woocommerce_currency() );
304
- }
305
-
306
- }
307
-
308
-
309
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 );
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 ){
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
+ }else{
102
+ $language_to_filter = $this->sitepress->get_current_language();
103
+ }
104
+
105
+ foreach( $items as $index => $item ){
106
+ if( is_array( $item ) ){
107
+ // WC < 2.7
108
+ foreach( $item as $key => $item_data ){
109
+ if( $key == 'product_id' ){
110
+ $tr_product_id = apply_filters( 'translate_object_id', $item_data, 'product', false, $language_to_filter );
111
+ if( !is_null( $tr_product_id ) ){
112
+ $items[ $index ][ $key ] = $tr_product_id;
113
+ $items[ $index ][ 'name'] = get_the_title( $tr_product_id );
114
+ }
115
+ }
116
+ if( $key == 'variation_id' ){
117
+ $tr_variation_id = apply_filters( 'translate_object_id', $item_data, 'product_variation', false, $language_to_filter );
118
+ if( !is_null($tr_variation_id)){
119
+ $items[$index][$key] = $tr_variation_id;
120
+ }
121
+ }
122
+
123
+ if (substr($key, 0, 3) == 'pa_') {
124
+ //attr is taxonomy
125
+
126
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $key, $item_data );
127
+ $tr_id = apply_filters( 'translate_object_id', $term_id, $key, false, $language_to_filter );
128
+
129
+ if(!is_null($tr_id)){
130
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $key);
131
+ $items[$index][$key] = $translated_term->slug;
132
+ }
133
+ }
134
+
135
+ if( $key == 'type' && $item_data == 'shipping' && isset( $item[ 'method_id' ] ) ){
136
+
137
+ $items[ $index ][ 'name' ] = $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item[ 'name' ], $item[ 'method_id' ], $language_to_filter );
138
+
139
+ }
140
+ }
141
+ }else{
142
+ // WC >= 2.7
143
+ if( $item instanceof WC_Order_Item_Product ){
144
+ if( $item->get_type() == 'line_item' ){
145
+ $item_product_id = $item->get_product_id();
146
+ if( get_post_type( $item_product_id ) == 'product_variation' ){
147
+ $item_product_id = wp_get_post_parent_id( $item_product_id );
148
+ }
149
+
150
+ $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
151
+ if( !is_null( $tr_product_id ) ){
152
+ $item->set_product_id( $tr_product_id );
153
+ $item->set_name( get_the_title( $tr_product_id ) );
154
+ }
155
+ $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
156
+ if( !is_null( $tr_variation_id ) ){
157
+ $item->set_variation_id( $tr_variation_id );
158
+ }
159
+
160
+ $meta_data = array();
161
+ foreach( $item->get_meta_data() as $data ){
162
+
163
+ if( substr( $data->key, 0, 3) == 'pa_' ){
164
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $data->key, $data->value );
165
+ $tr_id = apply_filters( 'translate_object_id', $term_id, $data->key, false, $language_to_filter );
166
+
167
+ if(!is_null($tr_id)){
168
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $data->key);
169
+ $data->value = $translated_term->slug;
170
+ }
171
+ }
172
+
173
+ $meta_data[] = $data;
174
+
175
+ }
176
+ }
177
+ }elseif( $item instanceof WC_Order_Item_Shipping ){
178
+ if( $item->get_method_id() ){
179
+ $item->set_method_title( $this->woocommerce_wpml->shipping->translate_shipping_method_title( $item->get_method_title(), $item->get_method_id(), $language_to_filter ) );
180
+ }
181
+ }
182
+ }
183
+ }
184
+
185
+
186
+ return $items;
187
+
188
+ }
189
+
190
+ public function backend_before_order_itemmeta( $item_id, $item, $product ){
191
+ global $sitepress;
192
+
193
+ if( $this->get_order_language_by_item_id( $item_id ) != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
194
+ foreach( $item[ 'item_meta' ] as $key => $item_meta ){
195
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
196
+ //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
197
+ if( !is_array( $item_meta ) ){
198
+ $item_meta = array( $item_meta );
199
+ }
200
+
201
+ foreach( $item_meta as $value ){
202
+ $this->force_update_itemmeta( $item_id, $key, $value, $sitepress->get_user_admin_language( get_current_user_id(), true ) );
203
+ }
204
+ }
205
+ }
206
+ }
207
+ }
208
+
209
+ public function backend_after_order_itemmeta( $item_id, $item, $product ){
210
+ global $sitepress;
211
+
212
+ $order_languge = $this->get_order_language_by_item_id( $item_id );
213
+ if( $order_languge != $sitepress->get_user_admin_language( get_current_user_id(), true ) ){
214
+ foreach( $item[ 'item_meta' ] as $key => $item_meta ){
215
+ if ( taxonomy_exists( wc_attribute_taxonomy_name( $key ) ) || substr( $key, 0, 3 ) == 'pa_' ) {
216
+ //backward compatibility for WC < 2.7 - in WC 2.7 $item_meta is a single attribute value not an array
217
+ if( !is_array( $item_meta ) ){
218
+ $item_meta = array( $item_meta );
219
+ }
220
+
221
+ foreach( $item_meta as $value ){
222
+ $this->force_update_itemmeta( $item_id, $key, $value, $order_languge );
223
+ }
224
+ }
225
+ }
226
+ }
227
+ }
228
+
229
+ public function get_order_language_by_item_id( $item_id ){
230
+ global $wpdb;
231
+
232
+ $order_id = $wpdb->get_var( $wpdb->prepare( "SELECT order_id FROM {$wpdb->prefix}woocommerce_order_items WHERE order_item_id = %d", $item_id ) );
233
+
234
+ return get_post_meta( $order_id, 'wpml_language', true );
235
+ }
236
+
237
+ //force update to display attribute in correct language on edit order page
238
+ public function force_update_itemmeta( $item_id, $key, $value, $languge ){
239
+ global $wpdb, $woocommerce_wpml;
240
+
241
+ $taxonomy = substr( $key, 0, 3 ) != 'pa_' ? wc_attribute_taxonomy_name( $key ) : $key;
242
+ $term_id = $woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $value );
243
+ $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
244
+ $translated_term = $woocommerce_wpml->terms->wcml_get_translated_term( $term_id, $taxonomy, $languge );
245
+
246
+ if( $translated_term ){
247
+ $value = $translated_term->slug;
248
+ $wpdb->update( $wpdb->prefix.'woocommerce_order_itemmeta', array( 'meta_value' => $value ), array( 'order_item_id' => $item_id, 'meta_key' => $key ) );
249
+ }
250
+ }
251
+
252
+ // Fix for shipping update on the checkout page.
253
+ function fix_shipping_update($amount){
254
+ global $post;
255
+
256
+ if($this->sitepress->get_current_language() !== $this->sitepress->get_default_language() && $post->ID == $this->checkout_page_id()){
257
+
258
+ $_SESSION['icl_checkout_shipping_amount'] = $amount;
259
+
260
+ $amount = $_SESSION['icl_checkout_shipping_amount'];
261
+
262
+ }
263
+
264
+ return $amount;
265
+ }
266
+
267
+
268
+ /**
269
+ * Adds language to order post type.
270
+ *
271
+ * Language was stored in the session created on checkout page.
272
+ * See params().
273
+ *
274
+ * @param type $order_id
275
+ */
276
+ function set_order_language($order_id) {
277
+ if(!get_post_meta($order_id, 'wpml_language')){
278
+ $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
279
+ update_post_meta($order_id, 'wpml_language', $language);
280
+ }
281
+ }
282
+
283
+ function append_query_parameters($parameters){
284
+
285
+ if(is_order_received_page() || is_checkout()){
286
+ if(!in_array('order', $parameters)) $parameters[] = 'order';
287
+ if(!in_array('key', $parameters)) $parameters[] = 'key';
288
+ }
289
+
290
+ return $parameters;
291
+ }
292
+
293
+ function switch_to_current(){
294
+ $this->woocommerce_wpml->emails->change_email_language($this->sitepress->get_current_language());
295
+ }
296
+
297
+ function order_language_dropdown( $order_id ){
298
+ if( !get_post_meta( $order_id, '_order_currency') ) {
299
+ $languages = icl_get_languages('skip_missing=0&orderby=code');
300
+ $selected_lang = isset( $_COOKIE [ '_wcml_dashboard_order_language' ] ) ? $_COOKIE [ '_wcml_dashboard_order_language' ] : $this->sitepress->get_default_language();
301
+ ?>
302
+ <li class="wide">
303
+ <label><?php _e('Order language:'); ?></label>
304
+ <select id="dropdown_shop_order_language" name="wcml_shop_order_language">
305
+ <?php if (!empty($languages)): ?>
306
+
307
+ <?php foreach ($languages as $l): ?>
308
+
309
+ <option
310
+ value="<?php echo $l['language_code'] ?>" <?php echo $selected_lang == $l['language_code'] ? 'selected="selected"' : ''; ?>><?php echo $l['translated_name']; ?></option>
311
+
312
+ <?php endforeach; ?>
313
+
314
+ <?php endif; ?>
315
+ </select>
316
+ </li>
317
+ <?php
318
+ $wcml_set_dashboard_order_language_nonce = wp_create_nonce( 'set_dashboard_order_language' );
319
+ wc_enqueue_js( "
320
+ var order_lang_current_value = jQuery('#dropdown_shop_order_language option:selected').val();
321
+
322
+ jQuery('#dropdown_shop_order_language').on('change', function(){
323
+ if(confirm('" . esc_js(__("All the products will be removed from the current order in order to change the language", 'woocommerce-multilingual')). "')){
324
+ var lang = jQuery(this).val();
325
+
326
+ jQuery.ajax({
327
+ url: ajaxurl,
328
+ type: 'post',
329
+ dataType: 'json',
330
+ data: {action: 'wcml_order_delete_items', order_id: woocommerce_admin_meta_boxes.post_id, lang: lang , wcml_nonce: '".$wcml_set_dashboard_order_language_nonce."' },
331
+ success: function( response ){
332
+ if(typeof response.error !== 'undefined'){
333
+ alert(response.error);
334
+ }else{
335
+ window.location = window.location.href;
336
+ }
337
+ }
338
+ });
339
+ }else{
340
+ jQuery(this).val( order_lang_current_value );
341
+ return false;
342
+ }
343
+ });
344
+
345
+ ");
346
+ }
347
+ }
348
+
349
+ function order_delete_items(){
350
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
351
+ if(!$nonce || !wp_verify_nonce($nonce, 'set_dashboard_order_language')){
352
+ echo json_encode(array('error' => __('Invalid nonce', 'woocommerce-multilingual')));
353
+ die();
354
+ }
355
+
356
+ setcookie('_wcml_dashboard_order_language', filter_input( INPUT_POST, 'lang', FILTER_SANITIZE_FULL_SPECIAL_CHARS ), time() + 86400, COOKIEPATH, COOKIE_DOMAIN);
357
+
358
+ }
359
+
360
+ function set_order_language_backend( $post_id, $post ){
361
+
362
+ if( isset( $_POST['wcml_shop_order_language'] ) ){
363
+ update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
364
+ }
365
+
366
+ }
367
+
368
+ function update_order_currency( $meta_id, $object_id, $meta_key, $meta_value ){
369
+
370
+ 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' ){
371
+ update_post_meta( $object_id, '_order_currency', get_woocommerce_currency() );
372
+ }
373
+
374
+ }
375
+
376
+
377
+ }
inc/class-wcml-products-screen-options.php CHANGED
@@ -1,215 +1,46 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Screen_Options
5
- */
6
- class WCML_Products_Screen_Options extends WPML_Templates_Factory {
7
-
8
- /**
9
- * @var SitePress
10
- */
11
- private $sitepress;
12
-
13
- /**
14
- * WCML_Screen_Options constructor.
15
- *
16
- * @param $sitepress
17
- */
18
- public function __construct( &$sitepress ) {
19
- parent::__construct();
20
- $this->sitepress = $sitepress;
21
- }
22
-
23
- /**
24
- * Setup hooks.
25
- */
26
- public function init() {
27
- add_filter( 'default_hidden_columns', array( $this, 'filter_screen_options' ), 10, 2 );
28
- add_filter( 'wpml_hide_management_column', array( $this, 'sitepress_screen_option_filter' ), 10, 2 );
29
- add_action( 'admin_init', array( $this, 'save_translation_controls' ), 10, 1 );
30
- add_action( 'admin_notices', array( $this, 'product_page_admin_notices' ), 10 );
31
- add_action( 'wp_ajax_dismiss-notice', array( $this, 'dismiss_notice_permanently' ), 10 );
32
- add_action( 'wp_ajax_hidden-columns', array( $this, 'dismiss_notice_on_screen_option_change' ), 0 );
33
- }
34
-
35
- /**
36
- * Hide management column by default for products.
37
- *
38
- * @param $is_visible
39
- * @param $post_type
40
- *
41
- * @return bool
42
- */
43
- public function sitepress_screen_option_filter( $is_visible, $post_type ) {
44
- if ( 'product' === $post_type ) {
45
- $is_visible = false;
46
- }
47
-
48
- return $is_visible;
49
- }
50
-
51
- /**
52
- * Set default option for translations management column.
53
- *
54
- * @param $hidden
55
- * @param $screen
56
- *
57
- * @return array
58
- */
59
- public function filter_screen_options( $hidden, $screen ) {
60
- if ( 'edit-product' === $screen->id ) {
61
- $hidden[] = 'icl_translations';
62
- }
63
- return $hidden;
64
- }
65
-
66
- /**
67
- * Save user options for management column.
68
- */
69
- public function save_translation_controls() {
70
- if ( isset( $_GET['translation_controls'] )
71
- && isset( $_GET['nonce'] )
72
- && wp_verify_nonce( $_GET['nonce'], 'enable_translation_controls' )
73
- ) {
74
- $user = get_current_user_id();
75
- $hidden_columns = get_user_meta( $user, 'manageedit-productcolumnshidden', true );
76
- if ( ! is_array( $hidden_columns ) ) {
77
- $hidden_columns = array();
78
- }
79
- if ( 0 === (int) $_GET['translation_controls'] ) {
80
- $hidden_columns[] = 'icl_translations';
81
- } else {
82
- $tr_control_index = array_search( 'icl_translations', $hidden_columns );
83
- if ( false !== $tr_control_index ) {
84
- unset( $hidden_columns[ $tr_control_index ] );
85
- }
86
- }
87
-
88
- update_user_meta( $user, 'manageedit-productcolumnshidden', $hidden_columns );
89
- $this->sitepress->get_wp_api()->wp_safe_redirect( admin_url( 'edit.php?post_type=product' ), 301 );
90
- }
91
- }
92
-
93
- /**
94
- * Display admin notice for translation management column.
95
- */
96
- public function product_page_admin_notices() {
97
- $current_screen = get_current_screen();
98
- if ( 'edit-product' === $current_screen->id && $this->has_products() ) {
99
- $this->show();
100
- }
101
- }
102
-
103
- /**
104
- * Get model for view.
105
- *
106
- * @return array
107
- */
108
- public function get_model() {
109
- $translate_url = esc_url_raw( admin_url( 'admin.php?page=wpml-wcml' ) );
110
- $nonce = wp_create_nonce( 'enable_translation_controls' );
111
- $button_url = esc_url_raw( admin_url( 'edit.php?post_type=product&translation_controls=0&nonce=' . $nonce ) );
112
- $button_text = __( 'Disable translation controls', 'woocommerce-multilingual' );
113
- $first_line = __( 'Translation controls are enabled.', 'woocommerce-multilingual' );
114
- $second_line = sprintf( __( "Disabling the translation controls will make this page load faster.\nThe best place to translate products is in WPML-&gt;WooCommerce Multilingual %sproducts translation dashboard%s.", 'woocommerce-multilingual' ), '<a href="' . $translate_url . '">', '</a>' );
115
- $show_notice = ( 1 === (int) get_user_meta( get_current_user_id(), 'screen-option-enabled-notice-dismissed', true ) ) ? false : true;
116
- $div_id = 'enabled';
117
- if ( method_exists( $this->sitepress, 'show_management_column_content' ) && false === $this->sitepress->show_management_column_content( 'product' ) ) {
118
- $button_url = admin_url( 'edit.php?post_type=product&translation_controls=1&nonce=' . $nonce );
119
- $button_text = __( 'Enable translation controls anyway', 'woocommerce-multilingual' );
120
- $first_line = __( 'Translation controls are disabled.', 'woocommerce-multilingual' );
121
- $second_line = sprintf( __( "Enabling the translation controls in this page can increase the load time for this admin screen.\n The best place to translate products is in WPML-&gt;WooCommerce Multilingual %sproducts translation dashboard%s.", 'woocommerce-multilingual' ), '<a href="' . $translate_url . '">', '</a>' );
122
- $show_notice = ( 1 === (int) get_user_meta( get_current_user_id(), 'screen-option-disabled-notice-dismissed', true ) ) ? false : true;
123
- $div_id = 'disabled';
124
- }
125
- $model = array(
126
- 'first_line' => $first_line,
127
- 'second_line' => $second_line,
128
- 'button_url' => $button_url,
129
- 'button_text' => $button_text,
130
- 'show_notice' => $show_notice,
131
- 'div_id' => $div_id,
132
- );
133
-
134
- return $model;
135
- }
136
-
137
- /**
138
- * Get template directory path.
139
- */
140
- protected function init_template_base_dir() {
141
- $this->template_paths = array(
142
- WCML_PLUGIN_PATH . '/templates/products-list/',
143
- );
144
- }
145
-
146
- /**
147
- * Get template file name.
148
- *
149
- * @return string
150
- */
151
- public function get_template() {
152
- return 'admin-notice.twig';
153
- }
154
-
155
- public function dismiss_notice_permanently() {
156
- if ( defined( 'DOING_AJAX' )
157
- && DOING_AJAX
158
- && isset( $_POST['nonce'] )
159
- && wp_verify_nonce( $_POST['nonce'], 'products-screen-option-action' )
160
- && isset( $_POST['dismiss_notice'] )
161
- ) {
162
- $user = get_current_user_id();
163
- if ( 'enabled' === $_POST['dismiss_notice'] ) {
164
- update_user_meta( $user, 'screen-option-enabled-notice-dismissed', 1 );
165
- }
166
-
167
- if ( 'disabled' === $_POST['dismiss_notice'] ) {
168
- update_user_meta( $user, 'screen-option-disabled-notice-dismissed', 1 );
169
- }
170
- }
171
- }
172
-
173
- /**
174
- * Dismiss notices when screen option is updated manually.`
175
- */
176
- public function dismiss_notice_on_screen_option_change() {
177
- if ( defined( 'DOING_AJAX' )
178
- && DOING_AJAX
179
- && isset( $_POST['page'] )
180
- && 'edit-product' === $_POST['page']
181
- && check_ajax_referer( 'screen-options-nonce', 'screenoptionnonce' )
182
- && isset( $_POST['hidden'] )
183
- && '' === $_POST['hidden']
184
- ) {
185
- $user = get_current_user_id();
186
- update_user_meta( $user, 'screen-option-enabled-notice-dismissed', 1 );
187
- update_user_meta( $user, 'screen-option-disabled-notice-dismissed', 1 );
188
- }
189
- }
190
-
191
- /**
192
- * Check if there is at least on product added.
193
- *
194
- * @return bool
195
- */
196
- public function has_products() {
197
- $has_products = false;
198
- $args = array(
199
- 'post_type' => 'product',
200
- 'posts_per_page' => 1,
201
- 'no_found_rows' => true,
202
- 'fields' => 'ids',
203
- 'update_post_meta_cache' => false,
204
- 'update_post_term_cache' => false,
205
- 'suppress_filters' => false,
206
- );
207
- $query = new WP_Query( $args );
208
- if ( $query->have_posts() ) {
209
- $has_products = true;
210
- }
211
- wp_reset_postdata();
212
-
213
- return $has_products;
214
- }
215
- }
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,437 +1,497 @@
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
- if( defined( 'ICL_SITEPRESS_VERSION' ) && version_compare( ICL_SITEPRESS_VERSION, '3.2', '>=' ) ){
37
- $this->tp_support = new WCML_TP_Support();
38
- }
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
- $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'" );
93
- $get_variation_term_taxonomy_ids = apply_filters( 'wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids );
94
-
95
- $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 ) );
96
- return apply_filters( 'wcml_is_variable_product', $is_variable_product, $product_id );
97
- }
98
-
99
- public function is_grouped_product($product_id){
100
- $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'" );
101
- $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 ) );
102
-
103
- return $is_grouped_product;
104
- }
105
-
106
- public function get_translation_flags( $active_languages, $slang = false, $job_language = false ){
107
- $available_languages = array();
108
-
109
- foreach( $active_languages as $key => $language ){
110
- if( $job_language && $language[ 'code' ] != $job_language ) {
111
- continue;
112
- }elseif ( !$slang ||
113
- (
114
- ( $slang != $language[ 'code' ] ) &&
115
- ( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ||
116
- wpml_check_user_is_translator( $slang, $language[ 'code' ] ) ) &&
117
- ( !isset( $_POST[ 'translation_status_lang' ] ) ||
118
- ( isset( $_POST[ 'translation_status_lang' ] ) &&
119
- ( $_POST[ 'translation_status_lang' ] == $language[ 'code' ] ) ||
120
- $_POST[ 'translation_status_lang' ]=='' )
121
- )
122
- )
123
- ){
124
- $available_languages[ $key ][ 'name' ] = $language[ 'english_name' ];
125
- $available_languages[ $key ][ 'flag_url' ] = $this->sitepress->get_flag_url( $language[ 'code' ] );
126
- }
127
- }
128
-
129
- return $available_languages;
130
- }
131
-
132
- public function get_translation_statuses( $original_product_id, $product_translations, $active_languages, $slang = false, $trid = false, $job_language = false ){
133
- foreach ( $active_languages as $language ) {
134
- if( $job_language && $language['code'] != $job_language ) {
135
- continue;
136
- }elseif( isset( $product_translations[ $language[ 'code' ] ] ) && $product_translations[ $language[ 'code' ] ]->original ) { ?>
137
- <span title="<?php echo $language['english_name'] . ': ' . __('Original language', 'woocommerce-multilingual'); ?>">
138
- <i class="otgs-ico-original"></i>
139
- </span>
140
- <?php }elseif(
141
- $slang != $language[ 'code' ] &&
142
- ( !isset( $_POST[ 'translation_status_lang' ] ) ||
143
- ( isset( $_POST['translation_status_lang']) &&
144
- $_POST['translation_status_lang'] == $language['code'] ||
145
- $_POST['translation_status_lang'] == ''
146
- )
147
- )
148
- ) {
149
- if( isset( $product_translations[ $language[ 'code' ] ] ) ) {
150
- $job_id = $this->wpdb->get_var(
151
- $this->wpdb->prepare(
152
- "SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job AS tj
153
- LEFT JOIN {$this->wpdb->prefix}icl_translation_status AS ts
154
- ON tj.rid = ts.rid WHERE ts.translation_id=%d",
155
- $product_translations[ $language[ 'code' ] ]->translation_id )
156
- );
157
- }else{
158
- $job_id = false;
159
- }
160
-
161
- if( !current_user_can( 'wpml_manage_woocommerce_multilingual' ) && isset( $product_translations[ $language[ 'code' ] ] ) ) {
162
- $tr_status = $this->wpdb->get_row(
163
- $this->wpdb->prepare(
164
- "SELECT status,translator_id FROM {$this->wpdb->prefix}icl_translation_status
165
- WHERE translation_id = %d",
166
- $product_translations[ $language[ 'code' ] ]->translation_id )
167
- );
168
-
169
- if( !is_null( $tr_status ) && get_current_user_id() != $tr_status->translator_id ){
170
- if( $tr_status->status == ICL_TM_IN_PROGRESS ) { ?>
171
- <a title="<?php _e( 'Translation in progress', 'woocommerce-multilingual' ); ?>"><i
172
- class="otgs-ico-in-progress"></i></a>
173
- <?php continue;
174
- }elseif( $tr_status->status == ICL_TM_WAITING_FOR_TRANSLATOR && !$job_id ){
175
- $tr_job_id = $this->wpdb->get_var(
176
- $this->wpdb->prepare(
177
- "SELECT j.job_id FROM {$this->wpdb->prefix}icl_translate_job j
178
- JOIN {$this->wpdb->prefix}icl_translation_status s ON j.rid = s.rid
179
- WHERE s.translation_id = %d",
180
- $product_translations[ $language[ 'code' ] ]->translation_id )
181
- );
182
- $translation_queue_page = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $tr_job_id );
183
- $edit_url = apply_filters( 'icl_job_edit_url', $translation_queue_page, $tr_job_id );
184
- ?>
185
- <a href="<?php echo $edit_url ?>" title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Take this and edit', 'woocommerce-multilingual' ); ?>">
186
- <i class="otgs-ico-add"></i>
187
- </a>
188
- <?php continue;
189
- }
190
- }
191
- wpml_tm_load_status_display_filter();
192
- } ?>
193
- <a href="<?php echo apply_filters( 'wpml_link_to_translation', '', $original_product_id, $language[ 'code' ], $trid ) ?>"
194
- <?php if( isset( $product_translations[ $language[ 'code' ] ] ) ){
195
- $tr_status = $this->wpdb->get_row(
196
- $this->wpdb->prepare(
197
- "SELECT status,needs_update FROM {$this->wpdb->prefix}icl_translation_status
198
- WHERE translation_id = %d",
199
- $product_translations[ $language[ 'code' ] ]->translation_id )
200
- );
201
- if (!$tr_status ) { ?>
202
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
203
- <i class="otgs-ico-add"></i>
204
- <?php }elseif( $tr_status->needs_update ){ ?>
205
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Update translation', 'woocommerce-multilingual' ); ?>">
206
- <i class="otgs-ico-refresh"></i>
207
- <?php }elseif( $tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE ){ ?>
208
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Finish translating', 'woocommerce-multilingual' ); ?>">
209
- <i class="otgs-ico-refresh"></i>
210
- <?php }elseif( $tr_status->status == ICL_TM_COMPLETE ){ ?>
211
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
212
- <i class="otgs-ico-edit"></i>
213
- <?php }elseif( $tr_status->status == ICL_TM_DUPLICATE ){ ?>
214
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
215
- <i class="otgs-ico-duplicate"></i>
216
- <?php }
217
- } else { ?>
218
- title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
219
- <i class="otgs-ico-add"></i>
220
- <?php } ?>
221
- </a>
222
- <?php } ?>
223
- <?php }
224
- }
225
-
226
- public function wcml_override_is_translator( $is_translator, $user_id, $args ){
227
-
228
- if( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ){
229
- return true;
230
- }
231
-
232
- return $is_translator;
233
- }
234
-
235
- //product quickedit
236
- public function filter_product_actions( $actions, $post ){
237
- if(
238
- $post->post_type == 'product' &&
239
- !$this->is_original_product( $post->ID ) &&
240
- isset( $actions[ 'inline hide-if-no-js' ] ) )
241
- {
242
- $new_actions = array();
243
- foreach( $actions as $key => $action ) {
244
- if( $key == 'inline hide-if-no-js' ) {
245
- $new_actions[ 'quick_hide' ] = '<a href="#TB_inline?width=200&height=150&inlineId=quick_edit_notice" class="thickbox" title="' .
246
- __('Edit this item inline', 'woocommerce-multilingual') . '">' .
247
- __('Quick Edit', 'woocommerce-multilingual') . '</a>';
248
- } else {
249
- $new_actions[ $key ] = $action;
250
- }
251
- }
252
- return $new_actions;
253
- }
254
- return $actions;
255
- }
256
-
257
- /**
258
- * Filters upsell/crosell products in the correct language.
259
- */
260
- public function filter_found_products_by_language( $found_products ){
261
- $current_page_language = $this->sitepress->get_current_language();
262
-
263
- foreach( $found_products as $product_id => $output_v ){
264
- $post_data = $this->wpdb->get_row(
265
- $this->wpdb->prepare(
266
- "SELECT * FROM {$this->wpdb->prefix}icl_translations
267
- WHERE element_id = %d AND element_type LIKE 'post_%'", $product_id
268
- )
269
- );
270
-
271
- $product_language = $post_data->language_code;
272
-
273
- if( $product_language !== $current_page_language ){
274
- unset( $found_products[ $product_id ] );
275
- }
276
- }
277
-
278
- return $found_products;
279
- }
280
-
281
- /**
282
- * Takes off translated products from the Up-sells/Cross-sells tab.
283
- */
284
- public function filter_woocommerce_upsell_crosssell_posts_by_language( $posts ){
285
- foreach( $posts as $key => $post ){
286
- $post_id = $posts[ $key ]->ID;
287
- $post_data = $this->wpdb->get_row(
288
- $this->wpdb->prepare(
289
- "SELECT * FROM {$this->wpdb->prefix}icl_translations
290
- WHERE element_id = %d ", $post_id
291
- ),
292
- ARRAY_A );
293
-
294
- if( $post_data[ 'language_code' ] !== $this->sitepress->get_current_language() ){
295
- unset( $posts[ $key ] );
296
- }
297
- }
298
-
299
- return $posts;
300
- }
301
-
302
- public function woocommerce_json_search_found_products( $found_products ){
303
-
304
- foreach( $found_products as $post => $formatted_product_name ) {
305
- $parent = wp_get_post_parent_id( $post );
306
- if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
307
- && ( ( !$parent && $this->sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
308
- || ( $parent && $this->sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
309
- )
310
- ||
311
- ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
312
- && ( ( !$parent && $this->is_original_product($post) )
313
- || ( $parent && $this->is_original_product($parent) ) )
314
- )
315
- ) {
316
-
317
- $new_found_products[$post] = $formatted_product_name;
318
- }
319
- }
320
-
321
- return isset ( $new_found_products ) ? $new_found_products : $found_products ;
322
- }
323
-
324
- //update menu_order fro translations after ordering original products
325
- public function update_all_products_translations_ordering(){
326
- if( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) {
327
- $current_language = $this->sitepress->get_current_language();
328
- if( $current_language == $this->sitepress->get_default_language() ){
329
- $products = $this->wpdb->get_results(
330
- $this->wpdb->prepare(
331
- "SELECT p.ID FROM {$this->wpdb->posts} AS p
332
- LEFT JOIN {$this->wpdb->prefix}icl_translations AS icl
333
- ON icl.element_id = p.id
334
- WHERE p.post_type = 'product'
335
- AND p.post_status IN ( 'publish', 'future', 'draft', 'pending', 'private' )
336
- AND icl.element_type= 'post_product'
337
- AND icl.language_code = %s",
338
- $current_language )
339
- );
340
-
341
- foreach( $products as $product ){
342
- $this->update_order_for_product_translations( $product->ID );
343
- }
344
- }
345
- }
346
- }
347
-
348
- //update menu_order fro translations after ordering original products
349
- public function update_order_for_product_translations( $product_id ){
350
- if( isset( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) && $this->woocommerce_wpml->settings[ 'products_sync_order' ] ){
351
- $current_language = $this->sitepress->get_current_language();
352
-
353
- if ( $current_language == $this->sitepress->get_default_language() ) {
354
- $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
355
- $trid = $this->sitepress->get_element_trid($product_id, 'post_product');
356
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
357
-
358
- foreach( $translations as $translation ){
359
- if( $translation->element_id != $product_id ){
360
- $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation->element_id ) );
361
- }
362
- }
363
- }
364
- }
365
- }
366
-
367
- public function filter_excerpt_field_content_copy( $elements ) {
368
-
369
- if ( $elements[ 'post_type' ] == 'product' ) {
370
- $elements[ 'excerpt' ] ['editor_type'] = 'editor';
371
- }
372
- if ( function_exists( 'format_for_editor' ) ) {
373
- // WordPress 4.3 uses format_for_editor
374
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( format_for_editor( $elements[ 'excerpt' ][ 'value' ], $_POST[ 'excerpt_type' ] ) );
375
- } else {
376
- // Backwards compatible for WordPress < 4.3
377
- if($_POST[ 'excerpt_type'] == 'rich'){
378
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_richedit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
379
- }else{
380
- $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_htmledit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
381
- }
382
- }
383
- return $elements;
384
- }
385
-
386
- // Check if user can translate product
387
- public function user_can_translate_product( $trid, $language_code ){
388
- global $iclTranslationManagement;
389
-
390
- $current_translator = $iclTranslationManagement->get_current_translator();
391
- $job_id = $this->wpdb->get_var( $this->wpdb->prepare("
392
- SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job tj
393
- JOIN {$this->wpdb->prefix}icl_translation_status ts ON tj.rid = ts.rid
394
- JOIN {$this->wpdb->prefix}icl_translations t ON ts.translation_id = t.translation_id
395
- WHERE t.trid = %d AND t.language_code='%s'
396
- ORDER BY tj.job_id DESC LIMIT 1
397
- ", $trid, $language_code ) );
398
-
399
- if( $job_id && wpml_check_user_is_translator( $this->sitepress->get_source_language_by_trid( $trid ), $language_code ) ){
400
- return true;
401
- }
402
- return false;
403
- }
404
-
405
- public function filter_related_products_args( $args ){
406
- if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
407
- isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
408
- $this->woocommerce_wpml->settings[ 'display_custom_prices' ] )
409
- {
410
-
411
- $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
412
- $woocommerce_currency = get_option('woocommerce_currency');
413
-
414
- if( $client_currency != $woocommerce_currency ){
415
- $args['meta_query'][] = array(
416
- 'key' => '_wcml_custom_prices_status',
417
- 'value' => 1,
418
- 'compare' => '=',
419
- );
420
- }
421
-
422
- }
423
- return $args;
424
- }
425
-
426
- /*
427
- * get meta ids for multiple values post meta key
428
- */
429
- public function get_mid_ids_by_key( $post_id, $meta_key ) {
430
- $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 ) );
431
- if( $ids )
432
- return $ids;
433
-
434
- return false;
435
- }
436
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
437
  }
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
+ $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'" );
91
+ $get_variation_term_taxonomy_ids = apply_filters( 'wcml_variation_term_taxonomy_ids',(array)$get_variation_term_taxonomy_ids );
92
+
93
+ $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 ) );
94
+ return apply_filters( 'wcml_is_variable_product', $is_variable_product, $product_id );
95
+ }
96
+
97
+ public function is_grouped_product($product_id){
98
+ $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'" );
99
+ $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 ) );
100
+
101
+ return $is_grouped_product;
102
+ }
103
+
104
+ public function get_translation_flags( $active_languages, $slang = false, $job_language = false ){
105
+ $available_languages = array();
106
+
107
+ foreach( $active_languages as $key => $language ){
108
+ if( $job_language && $language[ 'code' ] != $job_language ) {
109
+ continue;
110
+ }elseif ( !$slang ||
111
+ (
112
+ ( $slang != $language[ 'code' ] ) &&
113
+ ( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ||
114
+ wpml_check_user_is_translator( $slang, $language[ 'code' ] ) ) &&
115
+ ( !isset( $_POST[ 'translation_status_lang' ] ) ||
116
+ ( isset( $_POST[ 'translation_status_lang' ] ) &&
117
+ ( $_POST[ 'translation_status_lang' ] == $language[ 'code' ] ) ||
118
+ $_POST[ 'translation_status_lang' ]=='' )
119
+ )
120
+ )
121
+ ){
122
+ $available_languages[ $key ][ 'name' ] = $language[ 'english_name' ];
123
+ $available_languages[ $key ][ 'flag_url' ] = $this->sitepress->get_flag_url( $language[ 'code' ] );
124
+ }
125
+ }
126
+
127
+ return $available_languages;
128
+ }
129
+
130
+ public function get_translation_statuses( $original_product_id, $product_translations, $active_languages, $slang = false, $trid = false, $job_language = false ){
131
+ foreach ( $active_languages as $language ) {
132
+ if( $job_language && $language['code'] != $job_language ) {
133
+ continue;
134
+ }elseif( isset( $product_translations[ $language[ 'code' ] ] ) && $product_translations[ $language[ 'code' ] ]->original ) { ?>
135
+ <span title="<?php echo $language['english_name'] . ': ' . __('Original language', 'woocommerce-multilingual'); ?>">
136
+ <i class="otgs-ico-original"></i>
137
+ </span>
138
+ <?php }elseif(
139
+ $slang != $language[ 'code' ] &&
140
+ ( !isset( $_POST[ 'translation_status_lang' ] ) ||
141
+ ( isset( $_POST['translation_status_lang']) &&
142
+ $_POST['translation_status_lang'] == $language['code'] ||
143
+ $_POST['translation_status_lang'] == ''
144
+ )
145
+ )
146
+ ) {
147
+ if( isset( $product_translations[ $language[ 'code' ] ] ) ) {
148
+ $job_id = $this->wpdb->get_var(
149
+ $this->wpdb->prepare(
150
+ "SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job AS tj
151
+ LEFT JOIN {$this->wpdb->prefix}icl_translation_status AS ts
152
+ ON tj.rid = ts.rid WHERE ts.translation_id=%d",
153
+ $product_translations[ $language[ 'code' ] ]->translation_id )
154
+ );
155
+ }else{
156
+ $job_id = false;
157
+ }
158
+
159
+ if( !current_user_can( 'wpml_manage_woocommerce_multilingual' ) && isset( $product_translations[ $language[ 'code' ] ] ) ) {
160
+ $tr_status = $this->wpdb->get_row(
161
+ $this->wpdb->prepare(
162
+ "SELECT status,translator_id FROM {$this->wpdb->prefix}icl_translation_status
163
+ WHERE translation_id = %d",
164
+ $product_translations[ $language[ 'code' ] ]->translation_id )
165
+ );
166
+
167
+ if( !is_null( $tr_status ) && get_current_user_id() != $tr_status->translator_id ){
168
+ if( $tr_status->status == ICL_TM_IN_PROGRESS ) { ?>
169
+ <a title="<?php _e( 'Translation in progress', 'woocommerce-multilingual' ); ?>"><i
170
+ class="otgs-ico-in-progress"></i></a>
171
+ <?php continue;
172
+ }elseif( $tr_status->status == ICL_TM_WAITING_FOR_TRANSLATOR && !$job_id ){
173
+ $tr_job_id = $this->wpdb->get_var(
174
+ $this->wpdb->prepare(
175
+ "SELECT j.job_id FROM {$this->wpdb->prefix}icl_translate_job j
176
+ JOIN {$this->wpdb->prefix}icl_translation_status s ON j.rid = s.rid
177
+ WHERE s.translation_id = %d",
178
+ $product_translations[ $language[ 'code' ] ]->translation_id )
179
+ );
180
+ $translation_queue_page = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php&job_id=' . $tr_job_id );
181
+ $edit_url = apply_filters( 'icl_job_edit_url', $translation_queue_page, $tr_job_id );
182
+ ?>
183
+ <a href="<?php echo $edit_url ?>" title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Take this and edit', 'woocommerce-multilingual' ); ?>">
184
+ <i class="otgs-ico-add"></i>
185
+ </a>
186
+ <?php continue;
187
+ }
188
+ }
189
+ wpml_tm_load_status_display_filter();
190
+ } ?>
191
+ <a href="<?php echo apply_filters( 'wpml_link_to_translation', '', $original_product_id, $language[ 'code' ], $trid ) ?>"
192
+ <?php if( isset( $product_translations[ $language[ 'code' ] ] ) ){
193
+ $tr_status = $this->wpdb->get_row(
194
+ $this->wpdb->prepare(
195
+ "SELECT status,needs_update FROM {$this->wpdb->prefix}icl_translation_status
196
+ WHERE translation_id = %d",
197
+ $product_translations[ $language[ 'code' ] ]->translation_id )
198
+ );
199
+ if (!$tr_status ) { ?>
200
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
201
+ <i class="otgs-ico-add"></i>
202
+ <?php }elseif( $tr_status->needs_update ){ ?>
203
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Update translation', 'woocommerce-multilingual' ); ?>">
204
+ <i class="otgs-ico-refresh"></i>
205
+ <?php }elseif( $tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE ){ ?>
206
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Finish translating', 'woocommerce-multilingual' ); ?>">
207
+ <i class="otgs-ico-refresh"></i>
208
+ <?php }elseif( $tr_status->status == ICL_TM_COMPLETE ){ ?>
209
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
210
+ <i class="otgs-ico-edit"></i>
211
+ <?php }elseif( $tr_status->status == ICL_TM_DUPLICATE ){ ?>
212
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Edit translation', 'woocommerce-multilingual' ); ?>">
213
+ <i class="otgs-ico-duplicate"></i>
214
+ <?php }
215
+ } else { ?>
216
+ title="<?php echo $language[ 'english_name' ] . ': ' . __( 'Add translation', 'woocommerce-multilingual' ); ?>">
217
+ <i class="otgs-ico-add"></i>
218
+ <?php } ?>
219
+ </a>
220
+ <?php } ?>
221
+ <?php }
222
+ }
223
+
224
+ public function wcml_override_is_translator( $is_translator, $user_id, $args ){
225
+
226
+ if( current_user_can( 'wpml_operate_woocommerce_multilingual' ) ){
227
+ return true;
228
+ }
229
+
230
+ return $is_translator;
231
+ }
232
+
233
+ //product quickedit
234
+ public function filter_product_actions( $actions, $post ){
235
+ if(
236
+ $post->post_type == 'product' &&
237
+ !$this->is_original_product( $post->ID ) &&
238
+ isset( $actions[ 'inline hide-if-no-js' ] ) )
239
+ {
240
+ $new_actions = array();
241
+ foreach( $actions as $key => $action ) {
242
+ if( $key == 'inline hide-if-no-js' ) {
243
+ $new_actions[ 'quick_hide' ] = '<a href="#TB_inline?width=200&height=150&inlineId=quick_edit_notice" class="thickbox" title="' .
244
+ __('Edit this item inline', 'woocommerce-multilingual') . '">' .
245
+ __('Quick Edit', 'woocommerce-multilingual') . '</a>';
246
+ } else {
247
+ $new_actions[ $key ] = $action;
248
+ }
249
+ }
250
+ return $new_actions;
251
+ }
252
+ return $actions;
253
+ }
254
+
255
+ /**
256
+ * Filters upsell/crosell products in the correct language.
257
+ */
258
+ public function filter_found_products_by_language( $found_products ){
259
+ $current_page_language = $this->sitepress->get_current_language();
260
+
261
+ foreach( $found_products as $product_id => $output_v ){
262
+ $post_data = $this->wpdb->get_row(
263
+ $this->wpdb->prepare(
264
+ "SELECT * FROM {$this->wpdb->prefix}icl_translations
265
+ WHERE element_id = %d AND element_type LIKE 'post_%'", $product_id
266
+ )
267
+ );
268
+
269
+ $product_language = $post_data->language_code;
270
+
271
+ if( $product_language !== $current_page_language ){
272
+ unset( $found_products[ $product_id ] );
273
+ }
274
+ }
275
+
276
+ return $found_products;
277
+ }
278
+
279
+ /**
280
+ * Takes off translated products from the Up-sells/Cross-sells tab.
281
+ */
282
+ public function filter_woocommerce_upsell_crosssell_posts_by_language( $posts ){
283
+ foreach( $posts as $key => $post ){
284
+ $post_id = $posts[ $key ]->ID;
285
+ $post_data = $this->wpdb->get_row(
286
+ $this->wpdb->prepare(
287
+ "SELECT * FROM {$this->wpdb->prefix}icl_translations
288
+ WHERE element_id = %d ", $post_id
289
+ ),
290
+ ARRAY_A );
291
+
292
+ if( $post_data[ 'language_code' ] !== $this->sitepress->get_current_language() ){
293
+ unset( $posts[ $key ] );
294
+ }
295
+ }
296
+
297
+ return $posts;
298
+ }
299
+
300
+ public function woocommerce_json_search_found_products( $found_products ){
301
+
302
+ foreach( $found_products as $post => $formatted_product_name ) {
303
+ $parent = wp_get_post_parent_id( $post );
304
+ if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
305
+ && ( ( !$parent && $this->sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
306
+ || ( $parent && $this->sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
307
+ )
308
+ ||
309
+ ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
310
+ && ( ( !$parent && $this->is_original_product($post) )
311
+ || ( $parent && $this->is_original_product($parent) ) )
312
+ )
313
+ ) {
314
+
315
+ $new_found_products[$post] = $formatted_product_name;
316
+ }
317
+ }
318
+
319
+ return isset ( $new_found_products ) ? $new_found_products : $found_products ;
320
+ }
321
+
322
+ //update menu_order fro translations after ordering original products
323
+ public function update_all_products_translations_ordering(){
324
+ if( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) {
325
+ $current_language = $this->sitepress->get_current_language();
326
+ if( $current_language == $this->sitepress->get_default_language() ){
327
+ $products = $this->wpdb->get_results(
328
+ $this->wpdb->prepare(
329
+ "SELECT p.ID FROM {$this->wpdb->posts} AS p
330
+ LEFT JOIN {$this->wpdb->prefix}icl_translations AS icl
331
+ ON icl.element_id = p.id
332
+ WHERE p.post_type = 'product'
333
+ AND p.post_status IN ( 'publish', 'future', 'draft', 'pending', 'private' )
334
+ AND icl.element_type= 'post_product'
335
+ AND icl.language_code = %s",
336
+ $current_language )
337
+ );
338
+
339
+ foreach( $products as $product ){
340
+ $this->update_order_for_product_translations( $product->ID );
341
+ }
342
+ }
343
+ }
344
+ }
345
+
346
+ //update menu_order fro translations after ordering original products
347
+ public function update_order_for_product_translations( $product_id ){
348
+ if( isset( $this->woocommerce_wpml->settings[ 'products_sync_order' ] ) && $this->woocommerce_wpml->settings[ 'products_sync_order' ] ){
349
+ $current_language = $this->sitepress->get_current_language();
350
+
351
+ if ( $current_language == $this->sitepress->get_default_language() ) {
352
+ $menu_order = $this->wpdb->get_var( $this->wpdb->prepare("SELECT menu_order FROM {$this->wpdb->posts} WHERE ID = %d", $product_id ) );
353
+ $trid = $this->sitepress->get_element_trid($product_id, 'post_product');
354
+ $translations = $this->sitepress->get_element_translations($trid, 'post_product');
355
+
356
+ foreach( $translations as $translation ){
357
+ if( $translation->element_id != $product_id ){
358
+ $this->wpdb->update( $this->wpdb->posts, array( 'menu_order' => $menu_order ), array( 'ID' => $translation->element_id ) );
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ public function filter_excerpt_field_content_copy( $elements ) {
366
+
367
+ if ( $elements[ 'post_type' ] == 'product' ) {
368
+ $elements[ 'excerpt' ] ['editor_type'] = 'editor';
369
+ }
370
+ if ( function_exists( 'format_for_editor' ) ) {
371
+ // WordPress 4.3 uses format_for_editor
372
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( format_for_editor( $elements[ 'excerpt' ][ 'value' ], $_POST[ 'excerpt_type' ] ) );
373
+ } else {
374
+ // Backwards compatible for WordPress < 4.3
375
+ if($_POST[ 'excerpt_type'] == 'rich'){
376
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_richedit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
377
+ }else{
378
+ $elements[ 'excerpt' ][ 'value' ] = htmlspecialchars_decode( wp_htmledit_pre( $elements[ 'excerpt' ][ 'value' ] ) );
379
+ }
380
+ }
381
+ return $elements;
382
+ }
383
+
384
+ // Check if user can translate product
385
+ public function user_can_translate_product( $trid, $language_code ){
386
+ global $iclTranslationManagement;
387
+
388
+ $current_translator = $iclTranslationManagement->get_current_translator();
389
+ $job_id = $this->wpdb->get_var( $this->wpdb->prepare("
390
+ SELECT tj.job_id FROM {$this->wpdb->prefix}icl_translate_job tj
391
+ JOIN {$this->wpdb->prefix}icl_translation_status ts ON tj.rid = ts.rid
392
+ JOIN {$this->wpdb->prefix}icl_translations t ON ts.translation_id = t.translation_id
393
+ WHERE t.trid = %d AND t.language_code='%s'
394
+ ORDER BY tj.job_id DESC LIMIT 1
395
+ ", $trid, $language_code ) );
396
+
397
+ if( $job_id && wpml_check_user_is_translator( $this->sitepress->get_source_language_by_trid( $trid ), $language_code ) ){
398
+ return true;
399
+ }
400
+ return false;
401
+ }
402
+
403
+ public function filter_related_products_args( $args ){
404
+ if( $this->woocommerce_wpml->settings[ 'enable_multi_currency' ] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
405
+ isset( $this->woocommerce_wpml->settings[ 'display_custom_prices' ] ) &&
406
+ $this->woocommerce_wpml->settings[ 'display_custom_prices' ] )
407
+ {
408
+
409
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
410
+ $woocommerce_currency = get_option('woocommerce_currency');
411
+
412
+ if( $client_currency != $woocommerce_currency ){
413
+ $args['meta_query'][] = array(
414
+ 'key' => '_wcml_custom_prices_status',
415
+ 'value' => 1,
416
+ 'compare' => '=',
417
+ );
418
+ }
419
+
420
+ }
421
+ return $args;
422
+ }
423
+
424
+ /*
425
+ * get meta ids for multiple values post meta key
426
+ */
427
+ public function get_mid_ids_by_key( $post_id, $meta_key ) {
428
+ $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 ) );
429
+ if( $ids )
430
+ return $ids;
431
+
432
+ return false;
433
+ }
434
+
435
+ // count "in progress" and "waiting on translation" as untranslated too
436
+ public function get_untranslated_products_count( $language ){
437
+
438
+ $count = 0;
439
+
440
+ $products = $this->wpdb->get_results( "
441
+ SELECT p.ID, t.trid, t.language_code
442
+ FROM {$this->wpdb->posts} AS p
443
+ LEFT JOIN {$this->wpdb->prefix}icl_translations AS t ON t.element_id = p.id
444
+ WHERE p.post_type = 'product' AND t.element_type = 'post_product' AND t.source_language_code IS NULL
445
+ " );
446
+
447
+ foreach( $products as $product ){
448
+ if( $product->language_code == $language ) continue;
449
+
450
+ $element_key = array( 'trid' => $product->trid, 'language_code' => $language );
451
+ $translation_status = apply_filters( 'wpml_tm_translation_status', null, $element_key );
452
+
453
+ if( in_array( $translation_status, array( ICL_TM_NOT_TRANSLATED, ICL_TM_WAITING_FOR_TRANSLATOR, ICL_TM_IN_PROGRESS ) ) ){
454
+ $count++;
455
+ }
456
+ }
457
+
458
+ return $count;
459
+ }
460
+
461
+ public function is_hide_resign_button(){
462
+ global $iclTranslationManagement;
463
+
464
+ $hide_resign = false;
465
+
466
+ if( isset( $_GET[ 'source_language_code' ] ) && isset( $_GET[ 'language_code' ] ) ){
467
+
468
+ $from_lang = $_GET[ 'source_language_code' ];
469
+ $to_lang = $_GET[ 'language_code' ];
470
+
471
+ }elseif( isset( $_GET[ 'job_id' ] ) ){
472
+
473
+ $job = $iclTranslationManagement->get_translation_job( $_GET[ 'job_id' ] );
474
+ $from_lang = $job->source_language_code;
475
+ $to_lang = $job->language_code;
476
+
477
+ }
478
+
479
+ if( isset( $from_lang ) ){
480
+
481
+ $translators = $iclTranslationManagement->get_blog_translators(
482
+ array(
483
+ 'from' => $from_lang,
484
+ 'to' => $to_lang
485
+ )
486
+ );
487
+
488
+ if( empty( $translators ) || ( sizeof( $translators ) == 1 && $translators[0]->ID == get_current_user_id() ) ){
489
+ $hide_resign = true;
490
+ }
491
+
492
+ }
493
+
494
+ return $hide_resign;
495
+ }
496
+
497
  }
inc/class-wcml-reports.php CHANGED
@@ -1,258 +1,258 @@
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
- add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
29
- add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
30
- add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
31
-
32
- }
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
- $query_from = preg_replace("/WHERE/", "LEFT JOIN {$wpdb->prefix}icl_translations AS t ON posts.ID = t.element_id WHERE", $query_from);
253
- $query_from .= " AND t.element_type IN ( 'post_product', 'post_product_variation' ) AND t.language_code = '".$sitepress->get_current_language()."'";
254
-
255
- return $query_from;
256
- }
257
-
258
- }
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
+ add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
29
+ add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
30
+ add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
31
+
32
+ }
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
+ $query_from = preg_replace("/WHERE/", "LEFT JOIN {$wpdb->prefix}icl_translations AS t ON posts.ID = t.element_id WHERE", $query_from);
253
+ $query_from .= " AND t.element_type IN ( 'post_product', 'post_product_variation' ) AND t.language_code = '".$sitepress->get_current_language()."'";
254
+
255
+ return $query_from;
256
+ }
257
+
258
+ }
inc/class-wcml-requests.php CHANGED
@@ -1,68 +1,68 @@
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
- $woocommerce_wpml->update_settings();
28
-
29
- $new_value =$wcml_file_path_sync == 0?2:$wcml_file_path_sync;
30
- $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
31
- $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
32
- $sitepress->save_settings($sitepress_settings);
33
- }
34
-
35
- if(isset($_GET['wcml_action']) && $_GET['wcml_action'] = 'dismiss'){
36
- $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
37
- $woocommerce_wpml->update_settings();
38
- }
39
-
40
-
41
- add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
42
-
43
- // Override cached widget id
44
- add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
45
- }
46
-
47
- function update_settings_from_warning(){
48
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
49
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
50
- die('Invalid nonce');
51
- }
52
- global $woocommerce_wpml;
53
-
54
- $woocommerce_wpml->settings[$_POST['setting']] = 1;
55
- $woocommerce_wpml->update_settings();
56
-
57
- }
58
-
59
- public function override_cached_widget_id( $widget_id ){
60
-
61
- if( defined( 'ICL_LANGUAGE_CODE' ) ){
62
- $widget_id .= ':' . ICL_LANGUAGE_CODE;
63
- }
64
-
65
- return $widget_id;
66
- }
67
-
68
  }
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
+ $woocommerce_wpml->update_settings();
28
+
29
+ $new_value =$wcml_file_path_sync == 0?2:$wcml_file_path_sync;
30
+ $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
31
+ $sitepress_settings['translation-management']['custom_fields_translation']['_file_paths'] = $new_value;
32
+ $sitepress->save_settings($sitepress_settings);
33
+ }
34
+
35
+ if(isset($_GET['wcml_action']) && $_GET['wcml_action'] = 'dismiss'){
36
+ $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
37
+ $woocommerce_wpml->update_settings();
38
+ }
39
+
40
+
41
+ add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
42
+
43
+ // Override cached widget id
44
+ add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
45
+ }
46
+
47
+ function update_settings_from_warning(){
48
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
49
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
50
+ die('Invalid nonce');
51
+ }
52
+ global $woocommerce_wpml;
53
+
54
+ $woocommerce_wpml->settings[$_POST['setting']] = 1;
55
+ $woocommerce_wpml->update_settings();
56
+
57
+ }
58
+
59
+ public function override_cached_widget_id( $widget_id ){
60
+
61
+ if( defined( 'ICL_LANGUAGE_CODE' ) ){
62
+ $widget_id .= ':' . ICL_LANGUAGE_CODE;
63
+ }
64
+
65
+ return $widget_id;
66
+ }
67
+
68
  }
inc/class-wcml-resources.php CHANGED
@@ -1,219 +1,229 @@
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
- }
55
-
56
- public static function load_management_css() {
57
- wp_register_style( 'wpml-wcml', WCML_PLUGIN_URL . '/res/css/management.css', array(), WCML_VERSION );
58
- wp_enqueue_style( 'wpml-wcml' );
59
- }
60
-
61
- private static function load_js() {
62
-
63
- wp_register_script( 'wcml-scripts', WCML_PLUGIN_URL . '/res/js/scripts' . WCML_JS_MIN . '.js', array(
64
- 'jquery',
65
- 'jquery-ui-core',
66
- 'jquery-ui-resizable'
67
- ), WCML_VERSION );
68
-
69
- if ( self::$is_wpml_wcml_page ) {
70
-
71
- wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
72
- 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 );
73
- wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
74
-
75
- wp_enqueue_script( 'wcml-dialogs' );
76
- wp_enqueue_script( 'wcml-scripts' );
77
- wp_enqueue_script( 'jquery-cookie' );
78
- wp_enqueue_script( 'wcml-troubleshooting' );
79
-
80
- wp_localize_script( 'wcml-scripts', 'wcml_settings',
81
- array(
82
- 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
83
- )
84
- );
85
-
86
- self::load_tooltip_resources();
87
- }
88
-
89
- if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
90
- wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
91
- wp_enqueue_script( 'wpml_tm' );
92
- }
93
-
94
- if ( self::$page == 'wpml-wcml' && self::$tab == 'multi-currency' ) {
95
- wp_register_script( 'multi-currency', WCML_PLUGIN_URL . '/res/js/multi-currency' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-sortable'), WCML_VERSION, true );
96
- wp_enqueue_script( 'multi-currency' );
97
- }
98
-
99
- if ( self::$page == 'wpml-wcml' && self::$tab == 'product-attributes' ) {
100
- wp_register_script( 'product-attributes', WCML_PLUGIN_URL . '/res/js/product-attributes' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
101
- wp_enqueue_script( 'product-attributes' );
102
- }
103
-
104
- if ( !is_admin() ) {
105
- $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
106
-
107
- wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
108
- wp_enqueue_script( 'cart-widget' );
109
- wp_localize_script( 'cart-widget', 'actions', array(
110
- 'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
111
- 'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0
112
- ) );
113
- } else {
114
- wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
115
- wp_enqueue_script( 'wcml-messages' );
116
- }
117
-
118
- $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
119
-
120
- if( $is_attr_page ){
121
- wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
122
- wp_enqueue_script( 'wcml-attributes' );
123
- }
124
-
125
- if( self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
126
- self::load_tooltip_resources();
127
- wp_enqueue_media();
128
- wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core'), WCML_VERSION);
129
- wp_enqueue_script( 'wcml-editor' );
130
- wp_localize_script( 'wcml-editor', 'strings',
131
- array(
132
- 'choose' => __( 'Choose a file', 'woocommerce_multilingual' ),
133
- 'save_tooltip' => __( 'At least one of these fields is required: title, content or excerpt', 'woocommerce_multilingual' ),
134
- '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')
135
- )
136
- );
137
- }
138
-
139
-
140
- if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
141
- self::load_tooltip_resources();
142
- wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION );
143
- wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
144
- }
145
- }
146
-
147
- public static function load_tooltip_resources() {
148
-
149
- if ( class_exists( 'woocommerce' ) ) {
150
- wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
151
- wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
152
- wp_enqueue_script( 'jquery-tiptip' );
153
- wp_enqueue_script( 'wcml-tooltip-init' );
154
- wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
155
- }
156
-
157
- }
158
-
159
- public static function load_lock_fields_js() {
160
-
161
- wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
162
- wp_enqueue_script( 'wcml-lock-script' );
163
-
164
- $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
165
- if( isset( $_GET[ 'post' ] ) ){
166
- $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET[ 'post' ] );
167
- $original_id = apply_filters( 'translate_object_id', $_GET[ 'post' ], 'product', true, $original_language );
168
- $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
169
- if( $custom_product_sync && $custom_product_sync == 'self' ) {
170
- $file_path_sync = false;
171
- }elseif( $custom_product_sync && $custom_product_sync == 'auto' ){
172
- $file_path_sync = true;
173
- }
174
- }
175
-
176
- wp_localize_script( 'wcml-lock-script', 'unlock_fields', array(
177
- 'menu_order' => self::$woocommerce_wpml->settings['products_sync_order'],
178
- 'file_paths' => $file_path_sync
179
- )
180
- );
181
- wp_localize_script( 'wcml-lock-script', 'non_standard_fields', array(
182
- 'ids' => apply_filters( 'wcml_js_lock_fields_ids', array() ),
183
- 'classes' => apply_filters( 'wcml_js_lock_fields_classes', array() ),
184
- 'input_names' => apply_filters( 'wcml_js_lock_fields_input_names', array() )
185
- ) );
186
-
187
- do_action( 'wcml_after_load_lock_fields_js' );
188
-
189
- }
190
-
191
- public static function hidden_label() {
192
- global $sitepress;
193
-
194
- echo '<img src="' . WCML_PLUGIN_URL . '/res/images/locked.png" class="wcml_lock_img wcml_lock_icon" alt="' .
195
- __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
196
- '" title="' . __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
197
- '" style="display: none;position:relative;left:2px;top:2px;">';
198
-
199
- if ( isset($_GET['post']) ) {
200
- $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET['post'] );
201
- $original_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $original_language );
202
- } elseif ( isset($_GET['trid']) ) {
203
- $original_id = $sitepress->get_original_element_id_by_trid( $_GET['trid'] );
204
- }
205
-
206
- if ( isset($_GET['lang']) ) {
207
- $language = $_GET['lang'];
208
- } else {
209
- return;
210
- }
211
-
212
- echo '<h3 class="wcml_prod_hidden_notice">' .
213
- sprintf( __( "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products.",
214
- 'woocommerce-multilingual' ),
215
- '<a href="' . get_edit_post_link( $original_id ) . '" >' . get_the_title( $original_id ) . '</a>',
216
- '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
217
- __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
218
- }
 
 
 
 
 
 
 
 
 
 
219
  }
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', null, 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
+ if ( self::$is_wpml_wcml_page ) {
72
+
73
+ wp_register_script( 'jquery-cookie', WCML_PLUGIN_URL . '/res/js/jquery.cookie' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
74
+ 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 );
75
+ wp_register_script( 'wcml-troubleshooting', WCML_PLUGIN_URL . '/res/js/troubleshooting' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
76
+
77
+ wp_enqueue_script( 'wcml-dialogs' );
78
+ wp_enqueue_script( 'wcml-scripts' );
79
+ wp_enqueue_script( 'jquery-cookie' );
80
+ wp_enqueue_script( 'wcml-troubleshooting' );
81
+
82
+ wp_localize_script( 'wcml-scripts', 'wcml_settings',
83
+ array(
84
+ 'nonce' => wp_create_nonce( 'woocommerce_multilingual' )
85
+ )
86
+ );
87
+
88
+ self::load_tooltip_resources();
89
+ }
90
+
91
+ if ( self::$page == WPML_TM_FOLDER . '/menu/main.php' ) {
92
+ wp_register_script( 'wpml_tm', WCML_PLUGIN_URL . '/res/js/wpml_tm' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
93
+ wp_enqueue_script( 'wpml_tm' );
94
+ }
95
+
96
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'multi-currency' ) {
97
+ wp_register_script( 'multi-currency', WCML_PLUGIN_URL . '/res/js/multi-currency' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-sortable'), WCML_VERSION, true );
98
+ wp_enqueue_script( 'multi-currency' );
99
+ }
100
+
101
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'product-attributes' ) {
102
+ wp_register_script( 'product-attributes', WCML_PLUGIN_URL . '/res/js/product-attributes' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
103
+ wp_enqueue_script( 'product-attributes' );
104
+ }
105
+
106
+ if ( self::$page == 'wpml-wcml' && self::$tab == 'custom-taxonomies' ) {
107
+ wp_register_script( 'custom-taxonomies', WCML_PLUGIN_URL . '/res/js/product-custom-taxonomies' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION, true );
108
+ wp_enqueue_script( 'custom-taxonomies' );
109
+ }
110
+
111
+ if ( !is_admin() ) {
112
+ $referer = isset( $_SERVER[ 'HTTP_REFERER' ] ) ? $_SERVER[ 'HTTP_REFERER' ] : '';
113
+
114
+ wp_register_script( 'cart-widget', WCML_PLUGIN_URL . '/res/js/cart_widget' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
115
+ wp_enqueue_script( 'cart-widget' );
116
+ wp_localize_script( 'cart-widget', 'actions', array(
117
+ 'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
118
+ 'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0
119
+ ) );
120
+ } else {
121
+ wp_register_script( 'wcml-messages', WCML_PLUGIN_URL . '/res/js/wcml-messages' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
122
+ wp_enqueue_script( 'wcml-messages' );
123
+ }
124
+
125
+ $is_attr_page = apply_filters( 'wcml_is_attributes_page', self::$page == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
126
+
127
+ if( $is_attr_page ){
128
+ wp_register_script( 'wcml-attributes', WCML_PLUGIN_URL . '/res/js/wcml-attributes' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
129
+ wp_enqueue_script( 'wcml-attributes' );
130
+ }
131
+
132
+ if( self::$page == WPML_TM_FOLDER . '/menu/translations-queue.php' ) {
133
+
134
+ self::load_tooltip_resources();
135
+ wp_enqueue_media();
136
+ wp_register_script( 'wcml-editor', WCML_PLUGIN_URL . '/res/js/wcml-translation-editor' . WCML_JS_MIN . '.js', array('jquery', 'jquery-ui-core'), WCML_VERSION);
137
+ wp_enqueue_script( 'wcml-editor' );
138
+ wp_localize_script( 'wcml-editor', 'wcml_settings',
139
+ array(
140
+ 'strings' => array(
141
+ 'choose' => __( 'Choose a file', 'woocommerce_multilingual' ),
142
+ 'save_tooltip' => __( 'At least one of these fields is required: title, content or excerpt', 'woocommerce_multilingual' ),
143
+ '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')
144
+ ),
145
+ 'hide_resign' => self::$woocommerce_wpml->products->is_hide_resign_button()
146
+ )
147
+ );
148
+ }
149
+
150
+ if ( isset( $_GET['post_type'] ) && 'product' === $_GET['post_type'] && 'edit.php' === self::$pagenow ) {
151
+ self::load_tooltip_resources();
152
+ wp_enqueue_script( 'products-screen-options', WCML_PLUGIN_URL . '/res/js/products-screen-option.js', array( 'jquery', 'wcml-tooltip-init' ), WCML_VERSION );
153
+ wp_localize_script( 'products-screen-options', 'products_screen_option', array( 'nonce' => wp_create_nonce( 'products-screen-option-action' ) ) );
154
+ }
155
+ }
156
+
157
+ public static function load_tooltip_resources() {
158
+
159
+ if ( class_exists( 'woocommerce' ) ) {
160
+ wp_register_script( 'jquery-tiptip', WC()->plugin_url() . '/assets/js/jquery-tiptip/jquery.tipTip.min.js', array('jquery'), WC_VERSION, true );
161
+ wp_register_script( 'wcml-tooltip-init', WCML_PLUGIN_URL . '/res/js/tooltip_init' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
162
+ wp_enqueue_script( 'jquery-tiptip' );
163
+ wp_enqueue_script( 'wcml-tooltip-init' );
164
+ wp_enqueue_style( 'woocommerce_admin_styles', WC()->plugin_url() . '/assets/css/admin.css', array(), WC_VERSION );
165
+ }
166
+
167
+ }
168
+
169
+ public static function load_lock_fields_js() {
170
+
171
+ wp_register_script( 'wcml-lock-script', WCML_PLUGIN_URL . '/res/js/lock_fields' . WCML_JS_MIN . '.js', array('jquery'), WCML_VERSION );
172
+ wp_enqueue_script( 'wcml-lock-script' );
173
+
174
+ $file_path_sync = self::$woocommerce_wpml->settings['file_path_sync'];
175
+ if( isset( $_GET[ 'post' ] ) ){
176
+ $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET[ 'post' ] );
177
+ $original_id = apply_filters( 'translate_object_id', $_GET[ 'post' ], 'product', true, $original_language );
178
+ $custom_product_sync = get_post_meta( $original_id, 'wcml_sync_files', true );
179
+ if( $custom_product_sync && $custom_product_sync == 'self' ) {
180
+ $file_path_sync = false;
181
+ }elseif( $custom_product_sync && $custom_product_sync == 'auto' ){
182
+ $file_path_sync = true;
183
+ }
184
+ }
185
+
186
+ wp_localize_script( 'wcml-lock-script', 'unlock_fields', array(
187
+ 'menu_order' => self::$woocommerce_wpml->settings['products_sync_order'],
188
+ 'file_paths' => $file_path_sync
189
+ )
190
+ );
191
+ wp_localize_script( 'wcml-lock-script', 'non_standard_fields', array(
192
+ 'ids' => apply_filters( 'wcml_js_lock_fields_ids', array() ),
193
+ 'classes' => apply_filters( 'wcml_js_lock_fields_classes', array() ),
194
+ 'input_names' => apply_filters( 'wcml_js_lock_fields_input_names', array() )
195
+ ) );
196
+
197
+ do_action( 'wcml_after_load_lock_fields_js' );
198
+
199
+ }
200
+
201
+ public static function hidden_label() {
202
+ global $sitepress;
203
+
204
+ echo '<img src="' . WCML_PLUGIN_URL . '/res/images/locked.png" class="wcml_lock_img wcml_lock_icon" alt="' .
205
+ __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
206
+ '" title="' . __( 'This field is locked for editing because WPML will copy its value from the original language.', 'woocommerce-multilingual' ) .
207
+ '" style="display: none;position:relative;left:2px;top:2px;">';
208
+
209
+ if ( isset($_GET['post']) ) {
210
+ $original_language = self::$woocommerce_wpml->products->get_original_product_language( $_GET['post'] );
211
+ $original_id = apply_filters( 'translate_object_id', $_GET['post'], 'product', true, $original_language );
212
+ } elseif ( isset($_GET['trid']) ) {
213
+ $original_id = $sitepress->get_original_element_id_by_trid( $_GET['trid'] );
214
+ }
215
+
216
+ if ( isset($_GET['lang']) ) {
217
+ $language = $_GET['lang'];
218
+ } else {
219
+ return;
220
+ }
221
+
222
+ echo '<h3 class="wcml_prod_hidden_notice">' .
223
+ sprintf( __( "This is a translation of %s. Some of the fields are not editable. It's recommended to use the %s for translating products.",
224
+ 'woocommerce-multilingual' ),
225
+ '<a href="' . get_edit_post_link( $original_id ) . '" >' . get_the_title( $original_id ) . '</a>',
226
+ '<a data-action="product-translation-dialog" class="js-wcml-dialog-trigger" data-id="' . $original_id . '" data-job_id="" data-language="' . $language . '">' .
227
+ __( 'WooCommerce Multilingual products translator', 'woocommerce-multilingual' ) . '</a>' ) . '</h3>';
228
+ }
229
  }
inc/class-wcml-store-pages.php CHANGED
@@ -1,519 +1,594 @@
1
- <?php
2
-
3
- class WCML_Store_Pages{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'));
8
- add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
9
- add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
10
- //update wc pages ids after change default language or create new if not exists
11
- add_action( 'icl_after_set_default_language', array( $this, 'after_set_default_language' ), 10, 2 );
12
- // Translate shop page ids
13
- $this->add_filter_to_get_shop_translated_page_id();
14
- add_filter( 'template_include', array( $this, 'template_loader' ), 100 );
15
- }
16
-
17
- function init(){
18
- global $woocommerce_wpml;
19
- if(!is_admin()){
20
- add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
21
- add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
22
- add_filter('parse_request', array($this, 'adjust_shop_page'));
23
- }
24
-
25
- add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
26
-
27
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
28
- if (isset($_POST['create_pages']) && wp_verify_nonce($nonce, 'create_pages')) {
29
- $this->create_missing_store_pages_with_redirect();
30
- }
31
-
32
- $this->front_page_id = get_option('page_on_front');
33
- $this->shop_page_id = wc_get_page_id('shop');
34
- $this->shop_page = get_post( $this->shop_page_id );
35
- }
36
-
37
- function switch_pages_language( $pages ){
38
- global $sitepress,$woocommerce_wpml;
39
-
40
- $default_language = $sitepress->get_default_language();
41
-
42
- if( $sitepress->get_current_language() != $default_language ){
43
- foreach( $pages as $key => $page ){
44
-
45
- switch( $key ){
46
- case 'shop':
47
- $page['name'] = 'shop';
48
- $page['title'] = 'Shop';
49
- break;
50
- case 'cart':
51
- $page['name'] = 'cart';
52
- $page['title'] = 'Cart';
53
- break;
54
- case 'checkout':
55
- $page['name'] = 'checkout';
56
- $page['title'] = 'Checkout';
57
- break;
58
- case 'myaccount':
59
- $page['name'] = 'my-account';
60
- $page['title'] = 'My account';
61
- break;
62
- }
63
-
64
- if( $sitepress->get_default_language() != 'en' ){
65
- $page['name'] = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page slug'.$page['name'], $default_language );
66
- $page['title'] = $woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page title'.$page['title'], $default_language );
67
- }
68
- }
69
- }
70
-
71
- return $pages;
72
- }
73
-
74
- function install_pages_action( $pages ){
75
- global $sitepress,$wpdb;
76
-
77
- foreach( $pages as $key => $page){
78
-
79
- if ( strlen( $page[ 'content' ] ) > 0 ) {
80
- // Search for an existing page with the specified page content (typically a shortcode)
81
- $page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . $wpdb->posts . " as p LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id WHERE post_type='page' AND post_content LIKE %s AND icl.element_type = 'post_page' AND icl.language_code = %s LIMIT 1;", "%{$page[ 'content' ]}%", $sitepress->get_default_language() ) );
82
- } else {
83
- // Search for an existing page with the specified page slug
84
- $page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . $wpdb->posts . " as p LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id WHERE post_type='page' AND post_name = %s AND icl.element_type = 'post_page' AND icl.language_code = %s LIMIT 1;", esc_sql( $page['name'] ), $sitepress->get_default_language() ) );
85
- }
86
-
87
- if( !$page_found ){
88
- $page_data = array(
89
- 'post_status' => 'publish',
90
- 'post_type' => 'page',
91
- 'post_author' => 1,
92
- 'post_name' => esc_sql( $page['name'] ),
93
- 'post_title' => $page['title'],
94
- 'post_content' => $page['content'],
95
- 'post_parent' => ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '',
96
- 'comment_status' => 'closed'
97
- );
98
- $page_id = wp_insert_post( $page_data );
99
-
100
- if ( 'woocommerce_' . $key . '_page_id' )
101
- update_option( 'woocommerce_' . $key . '_page_id', $page_id );
102
- }
103
-
104
- unset( $pages[ $key ] );
105
- }
106
-
107
- return $pages;
108
- }
109
-
110
- function add_filter_to_get_shop_translated_page_id(){
111
- $woo_pages = array(
112
- 'shop_page_id',
113
- 'cart_page_id',
114
- 'checkout_page_id',
115
- 'myaccount_page_id',
116
- 'lost_password_page_id',
117
- 'edit_address_page_id',
118
- 'view_order_page_id',
119
- 'change_password_page_id',
120
- 'logout_page_id',
121
- 'pay_page_id',
122
- 'thanks_page_id',
123
- 'terms_page_id',
124
- 'review_order_page_id'
125
- );
126
-
127
- foreach($woo_pages as $woo_page){
128
- add_filter('woocommerce_get_'.$woo_page, array($this, 'translate_pages_in_settings'));
129
- //I think following filter not needed because "option_woocommerce_..." not used in Woo, but I need ask David to confirm this
130
- add_filter('option_woocommerce_'.$woo_page, array($this, 'translate_pages_in_settings'));
131
- }
132
-
133
- add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_url'));
134
- }
135
-
136
- function translate_pages_in_settings($id) {
137
- global $pagenow;
138
- if( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ){
139
- return $id;
140
- }
141
-
142
- return apply_filters( 'translate_object_id',$id, 'page', true);
143
- }
144
-
145
- /**
146
- * Filters WooCommerce query for translated shop page
147
- *
148
- */
149
- function shop_page_query($q) {
150
- if ( ! $q->is_main_query() )
151
- return;
152
-
153
- //do not alter query_object and query_object_id (part 1 of 2)
154
- global $wp_query;
155
- $queried_object_original = isset($wp_query->queried_object) ? $wp_query->queried_object : null;
156
- $queried_object_id_original = isset($wp_query->queried_object_id) ? $wp_query->queried_object_id : null;
157
-
158
- if (
159
- !empty($this->shop_page) &&
160
- $this->shop_page->post_status == 'publish' &&
161
- !empty($this->front_page_id) &&
162
- $q->get('post_type') != 'product' &&
163
- $q->get('page_id') !== $this->front_page_id &&
164
- $this->shop_page_id == $q->get('page_id')
165
- ){
166
- $q->set( 'post_type', 'product' );
167
- $q->set( 'page_id', '' );
168
- if ( isset( $q->query['paged'] ) )
169
- $q->set( 'paged', $q->query['paged'] );
170
-
171
- // Get the actual WP page to avoid errors
172
- // This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
173
- global $wp_post_types;
174
-
175
- $q->is_page = true;
176
-
177
- $wp_post_types['product']->ID = $this->shop_page->ID;
178
- $wp_post_types['product']->post_title = $this->shop_page->post_title;
179
- $wp_post_types['product']->post_name = $this->shop_page->post_name;
180
-
181
- // Fix conditional functions
182
- $q->is_singular = false;
183
- $q->is_post_type_archive = true;
184
- $q->is_archive = true;
185
- }
186
-
187
- //do not alter query_object and query_object_id (part 2 of 2)
188
- if(is_null($queried_object_original)){
189
- unset($wp_query->queried_object);
190
- }else{
191
- $wp_query->queried_object = $queried_object_original;
192
- }
193
- if(is_null($queried_object_id_original)){
194
- unset($wp_query->queried_object_id);
195
- }else{
196
- $wp_query->queried_object_id = $queried_object_id_original;
197
- }
198
-
199
- }
200
-
201
-
202
- /**
203
- * Translate shop url
204
- */
205
- function translate_ls_shop_url($languages, $debug_mode = false) {
206
- global $sitepress;
207
- $shop_id = $this->shop_page_id;
208
- $front_id = apply_filters( 'translate_object_id',$this->front_page_id, 'page');
209
-
210
- foreach ($languages as $language) {
211
- // shop page
212
- // obsolete?
213
- if (is_post_type_archive('product') || $debug_mode ) {
214
- if ($front_id == $shop_id) {
215
- $url = $sitepress->language_url($language['language_code']);
216
- } else {
217
- $sitepress->switch_lang($language['language_code']);
218
- $url = get_permalink( apply_filters( 'translate_object_id', $shop_id, 'page', true, $language['language_code']) );
219
- $sitepress->switch_lang();
220
- }
221
-
222
- $languages[$language['language_code']]['url'] = $url;
223
- }
224
- }
225
-
226
- return $languages;
227
- }
228
-
229
- function adjust_shop_page($q) {
230
- global $sitepress;
231
- if ( $sitepress->get_default_language() != $sitepress->get_current_language() ) {
232
- if (!empty($q->query_vars['pagename'])) {
233
- $shop_page = get_post( wc_get_page_id('shop') );
234
- // we should explode by / for children page
235
- $query_var_page = explode('/',$q->query_vars['pagename']);
236
- 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]) ) ) ) {
237
- unset($q->query_vars['page']);
238
- unset($q->query_vars['pagename']);
239
- $q->query_vars['post_type'] = 'product';
240
- }
241
- }
242
- }
243
- }
244
-
245
- function create_missing_store_pages_with_redirect(){
246
- $this->create_missing_store_pages();
247
-
248
- wp_redirect(admin_url('admin.php?page=wpml-wcml&tab=status')); exit;
249
-
250
- }
251
-
252
- /**
253
- * create missing pages
254
- */
255
- function create_missing_store_pages() {
256
- global $sitepress,$wp_rewrite,$woocommerce_wpml,$woocommerce;
257
- $miss_lang = $this->get_missing_store_pages();
258
-
259
- //dummy array for names
260
- $names = array( __('Cart', 'woocommerce-multilingual'),
261
- __('Checkout', 'woocommerce-multilingual'),
262
- __('Checkout &rarr; Pay', 'woocommerce-multilingual'),
263
- __('Order Received', 'woocommerce-multilingual'),
264
- __('My Account', 'woocommerce-multilingual'),
265
- __('Change Password', 'woocommerce-multilingual'),
266
- __('Edit My Address', 'woocommerce-multilingual'),
267
- __('Logout', 'woocommerce-multilingual'),
268
- __('Lost Password', 'woocommerce-multilingual'),
269
- __('View Order', 'woocommerce-multilingual'),
270
- __('Shop', 'woocommerce-multilingual'));
271
-
272
- if (isset($miss_lang['codes'])) {
273
- $wp_rewrite = new WP_Rewrite();
274
-
275
- $check_pages = $this->get_wc_pages();
276
- $default_language = $sitepress->get_default_language();
277
- if(in_array($default_language, $miss_lang['codes'])){
278
- $miss_lang['codes'] = array_merge(array($default_language), array_diff($miss_lang['codes'], array($default_language)));
279
- }
280
-
281
- foreach ($miss_lang['codes'] as $mis_lang) {
282
- $args = array();
283
-
284
- $woocommerce_wpml->locale->switch_locale( $mis_lang );
285
-
286
- foreach ($check_pages as $page) {
287
- $orig_id = get_option($page);
288
- $trid = $sitepress->get_element_trid($orig_id,'post_page');
289
- $translations = $sitepress->get_element_translations($trid,'post_page',true);
290
-
291
- if (!isset( $translations[ $mis_lang ] ) || ( !is_null( $translations[$mis_lang]->element_id ) && get_post_status( $translations[$mis_lang]->element_id )!='publish' ) ) {
292
- $orig_page = get_post($orig_id);
293
-
294
- switch( $page ){
295
- case 'woocommerce_shop_page_id':
296
- $page_title = __( 'Shop', 'woocommerce-multilingual');
297
- break;
298
- case 'woocommerce_cart_page_id':
299
- $page_title = __( 'Cart', 'woocommerce-multilingual');
300
- break;
301
- case 'woocommerce_checkout_page_id':
302
- $page_title = __( 'Checkout', 'woocommerce-multilingual');
303
- break;
304
- case 'woocommerce_myaccount_page_id':
305
- $page_title = __( 'My Account', 'woocommerce-multilingual');
306
- break;
307
- default:
308
- $page_title = __( $orig_page->post_title, 'woocommerce-multilingual');
309
- break;
310
- }
311
-
312
- $args['post_title'] = $page_title;
313
- $args['post_type'] = $orig_page->post_type;
314
- $args['post_content'] = $orig_page->post_content;
315
- $args['post_excerpt'] = $orig_page->post_excerpt;
316
- $args['post_status'] = ( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) != 'publish' ) ? 'publish' : $orig_page->post_status;
317
- $args['menu_order'] = $orig_page->menu_order;
318
- $args['ping_status'] = $orig_page->ping_status;
319
- $args['comment_status'] = $orig_page->comment_status;
320
- $post_parent = apply_filters( 'translate_object_id',$orig_page->post_parent, 'page', false, $mis_lang);
321
- $args['post_parent'] = is_null($post_parent)?0:$post_parent;
322
- $new_page_id = wp_insert_post($args);
323
-
324
- if( isset($translations[$mis_lang]->element_id) && get_post_status($translations[$mis_lang]->element_id) == 'trash' && $mis_lang == $default_language){
325
- update_option($page, $new_page_id);
326
- }
327
-
328
- if( isset($translations[$mis_lang]->element_id) && !is_null($translations[$mis_lang]->element_id)){
329
- $sitepress->set_element_language_details($translations[$mis_lang]->element_id, 'post_page', false, $mis_lang);
330
- }
331
-
332
- $trid = $sitepress->get_element_trid($orig_id, 'post_page');
333
- $sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
334
- }
335
- }
336
- $woocommerce_wpml->locale->switch_locale();
337
- }
338
- }
339
- }
340
-
341
- /**
342
- * get missing pages
343
- * return array;
344
- */
345
- function get_missing_store_pages() {
346
-
347
- $check_pages = $this->get_wc_pages();
348
-
349
- $missing_lang = '';
350
- $pages_in_progress = array();
351
-
352
- foreach ($check_pages as $page) {
353
- $page_id = get_option($page);
354
- $page_obj = get_post($page_id);
355
- if(!$page_id || !$page_obj || $page_obj->post_status != 'publish' ){
356
- return 'non_exist';
357
- }
358
- }
359
-
360
- global $sitepress;
361
- $languages = $sitepress->get_active_languages();
362
-
363
- $missing_lang_codes = array();
364
-
365
- foreach ($check_pages as $page) {
366
- $store_page_id = get_option($page);
367
- $trid = $sitepress->get_element_trid($store_page_id,'post_page');
368
- $translations = $sitepress->get_element_translations($trid,'post_page',true);
369
- $pages_in_progress_miss_lang = '';
370
- foreach ($languages as $language) {
371
- if ( !in_array( $language['code'], $missing_lang_codes ) &&
372
- ( !isset( $translations[ $language['code'] ] ) || ( !is_null( $translations[$language['code']]->element_id ) && get_post_status( $translations[$language['code']]->element_id )!='publish' ) ) ) {
373
-
374
- $missing_lang_codes[] = $language['code'];
375
-
376
- $missing_lang[] = $language;
377
-
378
- continue;
379
- }
380
-
381
- if ( isset($translations[$language['code']] ) && is_null( $translations[$language['code']]->element_id ) ) {
382
-
383
- $pages_in_progress[$store_page_id][] = $language;
384
-
385
- }
386
- }
387
- }
388
-
389
-
390
- foreach( $pages_in_progress as $key => $page_in_progress ){
391
- $pages_in_progress_notice[$key]['page'] = get_the_title( $key ).' :';
392
- $pages_in_progress_notice[$key]['lang'] = $page_in_progress;
393
-
394
- }
395
-
396
- $status = array();
397
-
398
- if (!empty($missing_lang)) {
399
- $status['lang'] = $missing_lang;
400
- $status['codes'] = $missing_lang_codes;
401
- }
402
-
403
- if (!empty($pages_in_progress_notice)) {
404
- $status['in_progress'] = $pages_in_progress_notice;
405
- }
406
-
407
- if(!empty($status)){
408
- return $status;
409
- }else {
410
- return false;
411
- }
412
- }
413
-
414
- /**
415
- * Filters WooCommerce checkout link.
416
- */
417
- function get_checkout_page_url(){
418
- return get_permalink(apply_filters( 'translate_object_id',get_option('woocommerce_checkout_page_id'), 'page', true));
419
- }
420
-
421
- function get_wc_pages(){
422
- return apply_filters('wcml_wc_installed_pages', array(
423
- 'woocommerce_shop_page_id',
424
- 'woocommerce_cart_page_id',
425
- 'woocommerce_checkout_page_id',
426
- 'woocommerce_myaccount_page_id'
427
- ));
428
- }
429
-
430
- function after_set_default_language( $code, $previous_code ){
431
- global $wpdb;
432
-
433
- $this->create_missing_store_pages();
434
- $pages = $this->get_wc_pages();
435
-
436
- foreach( $pages as $page ){
437
-
438
- if( $page_id = get_option($page) ){
439
- $trnsl_id = apply_filters( 'translate_object_id', $page_id, 'page', false, $code );
440
- if( !is_null( $trnsl_id ) ){
441
- $wpdb->update( $wpdb->options, array( 'option_value' => $trnsl_id ), array( 'option_name' => $page ) );
442
- }
443
- }
444
-
445
- }
446
-
447
- // Clear any unwanted data
448
- wc_delete_product_transients();
449
- delete_transient( 'woocommerce_cache_excluded_uris' );
450
- }
451
-
452
- function template_loader( $template ){
453
-
454
- if ( is_product_taxonomy() ) {
455
- global $sitepress, $woocommerce_wpml;
456
-
457
- $current_language = $sitepress->get_current_language();
458
- $default_language = $sitepress->get_default_language();
459
-
460
- if( $current_language != $default_language ) {
461
-
462
- $templates = array( 'woocommerce.php' );
463
-
464
- $term = get_queried_object();
465
-
466
- if (is_tax('product_cat') || is_tax('product_tag')) {
467
- $file = 'taxonomy-' . $term->taxonomy . '.php';
468
- } else {
469
- $file = 'archive-product.php';
470
- }
471
-
472
- // check templates
473
- $term = get_queried_object();
474
- $taxonomy = $term->taxonomy;
475
- $prefix = 'taxonomy-'.$taxonomy;
476
- $original_term_id = icl_object_id($term->term_id, $taxonomy, true, $default_language);
477
- $original_term = $woocommerce_wpml->terms->wcml_get_term_by_id( $original_term_id, $taxonomy );
478
-
479
-
480
- $terms_to_check = array( $term->term_id => $term->slug );
481
- if ($original_term) {
482
- $terms_to_check[ $original_term_id ] = $original_term->slug;
483
- }
484
-
485
- $paths = array( '', WC()->template_path() );
486
-
487
- foreach( $paths as $path ){
488
-
489
- foreach( $terms_to_check as $term_id => $term_slug ){
490
-
491
- $templates[] = $path."$prefix-{$current_language}-{$term_slug}.php";
492
- $templates[] = $path."$prefix-{$current_language}-{$term_id}.php";
493
- $templates[] = $path."$prefix-{$term_slug}.php";
494
- $templates[] = $path."$prefix-{$term_id}.php";
495
-
496
- }
497
-
498
- $templates[] = $path."$prefix-{$current_language}.php";
499
- $templates[] = $path."$prefix.php";
500
- $templates[] = $path.$file;
501
- }
502
-
503
- $loaded_template = locate_template( array_unique( $templates ) );
504
-
505
- if ( $loaded_template ) {
506
-
507
- $template = $loaded_template;
508
-
509
- }
510
-
511
- }
512
-
513
- }
514
-
515
- return $template;
516
-
517
- }
518
-
519
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 = __( 'Shop', 'woocommerce-multilingual');
328
+ break;
329
+ case 'woocommerce_cart_page_id':
330
+ $page_title = __( 'Cart', 'woocommerce-multilingual');
331
+ break;
332
+ case 'woocommerce_checkout_page_id':
333
+ $page_title = __( 'Checkout', 'woocommerce-multilingual');
334
+ break;
335
+ case 'woocommerce_myaccount_page_id':
336
+ $page_title = __( 'My Account', 'woocommerce-multilingual');
337
+ break;
338
+ default:
339
+ $page_title = __( $orig_page->post_title, 'woocommerce-multilingual');
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
+ }
inc/class-wcml-terms.php CHANGED
@@ -1,1032 +1,1036 @@
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
- add_action('wp_ajax_wcml_ingore_taxonomy_translation', array( $this, 'wcml_ingore_taxonomy_translation'));
28
- add_action('wp_ajax_wcml_uningore_taxonomy_translation', array( $this, 'wcml_uningore_taxonomy_translation'));
29
-
30
- add_action('created_term', array( $this, 'set_flag_for_variation_on_attribute_update'), 10, 3);
31
-
32
- add_filter('wpml_taxonomy_translation_bottom', array( $this, 'sync_taxonomy_translations'), 10, 3 );
33
-
34
- add_action('wp_ajax_wcml_sync_product_variations', array( $this, 'wcml_sync_product_variations'));
35
- add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content', array( $this, 'wcml_sync_taxonomies_in_content'));
36
- add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content_preview', array( $this, 'wcml_sync_taxonomies_in_content_preview'));
37
-
38
- if(is_admin()){
39
- add_action('admin_menu', array($this, 'admin_menu_setup'));
40
- }
41
-
42
- add_action('delete_term',array($this, 'wcml_delete_term'),10,4);
43
- add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
44
- //filter coupons terms in admin
45
- add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
46
- add_filter('get_terms',array($this,'filter_shipping_classes_terms'),10,3);
47
-
48
- add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
49
- add_action( 'created_term_translation', array( $this, 'set_flag_to_sync'), 10, 3 );
50
- }
51
-
52
- function admin_menu_setup(){
53
- global $pagenow;
54
- if($pagenow == 'edit-tags.php' && isset($_GET['action']) && $_GET['action'] == 'edit'){
55
- add_action('admin_notices', array($this, 'show_term_translation_screen_notices'));
56
- }
57
-
58
- $page = isset( $_GET['page'] )? $_GET['page'] : '';
59
- if ( $page === ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' ) {
60
- WCML_Resources::load_management_css();
61
- wp_enqueue_script( 'wcml-scripts' );
62
- }
63
-
64
- }
65
-
66
- function save_wc_term_meta($original_tax, $result){
67
-
68
-
69
- // WooCommerce before termmeta table migration
70
- $wc_before_term_meta = get_option( 'db_version' ) < 34370;
71
-
72
- // backwards compatibility - before the termmeta table was added
73
- if( $wc_before_term_meta ){
74
-
75
- $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));
76
- foreach ( $term_wc_meta as $wc_meta ){
77
- $wc_original_metakey = $wc_meta->meta_key;
78
- $wc_original_metavalue = $wc_meta->meta_value;
79
- update_woocommerce_term_meta($result['term_id'], $wc_original_metakey, $wc_original_metavalue);
80
- }
81
- // End of backwards compatibility - before the termmeta table was added
82
- }else{
83
-
84
- $term_wc_meta = get_term_meta($original_tax->term_id, false, 1);
85
- foreach ( $term_wc_meta as $key => $values ) {
86
- update_term_meta( $result['term_id'], $key, array_pop( $values ) );
87
- }
88
-
89
- }
90
- }
91
-
92
- function show_term_translation_screen_notices(){
93
-
94
- $taxonomies = array_keys(get_taxonomies(array('object_type'=>array('product')),'objects'));
95
- $taxonomies = $taxonomies + array_keys(get_taxonomies(array('object_type'=>array('product_variations')),'objects'));
96
- $taxonomies = array_unique($taxonomies);
97
- $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : false;
98
- if($taxonomy && in_array($taxonomy, $taxonomies)){
99
- $taxonomy_obj = get_taxonomy($taxonomy);
100
- $language = isset($_GET['lang']) ? $_GET['lang'] : false;
101
- if(empty($language) && isset($_GET['tag_ID'])){
102
- $tax_id = $this->wpdb->get_var($this->wpdb->prepare("SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $_GET['tag_ID'], $taxonomy));
103
- $language = $this->sitepress->get_language_for_element($tax_id, 'tax_' . $taxonomy);
104
- }
105
- if(empty($language)){
106
- $language = $this->sitepress->get_default_language();
107
- }
108
-
109
- $message = sprintf(__('To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s.', 'woocommerce-multilingual'),
110
- $taxonomy_obj->labels->name,
111
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . $taxonomy_obj->labels->singular_name, '</a></strong>',
112
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml">'), '</a></strong>');
113
-
114
- echo '<div class="updated"><p>' . $message . '</p></div>';
115
-
116
- }
117
-
118
- }
119
-
120
- function sync_term_order_globally() {
121
- //syncs the term order of any taxonomy in $this->wpdb->prefix.'woocommerce_attribute_taxonomies'
122
- //use it when term orderings have become unsynched, e.g. before WCML 3.3.
123
-
124
- if(!defined('WOOCOMMERCE_VERSION')){
125
- return;
126
- }
127
-
128
- $cur_lang = $this->sitepress->get_current_language();
129
- $lang = $this->sitepress->get_default_language();
130
- $this->sitepress->switch_lang($lang);
131
-
132
- $taxes = wc_get_attribute_taxonomies ();
133
-
134
- if ($taxes) foreach ($taxes as $woo_tax) {
135
- $tax = 'pa_'.$woo_tax->attribute_name;
136
- $meta_key = 'order_'.$tax;
137
- //if ($tax != 'pa_frame') continue;
138
- $terms = get_terms($tax);
139
- if ($terms)foreach ($terms as $term) {
140
- $term_order = get_woocommerce_term_meta($term->term_id,$meta_key);
141
- $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_'.$tax);
142
- $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
143
- if ($translations) foreach ($translations as $trans) {
144
- if ($trans->language_code != $lang) {
145
- update_woocommerce_term_meta( $trans->term_id, $meta_key, $term_order);
146
- }
147
- }
148
- }
149
- }
150
-
151
- //sync product categories ordering
152
- $terms = get_terms('product_cat');
153
- if ($terms) foreach($terms as $term) {
154
- $term_order = get_woocommerce_term_meta($term->term_id,'order');
155
- $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
156
- $translations = $this->sitepress->get_element_translations($trid,'tax_product_cat');
157
- if ($translations) foreach ($translations as $trans) {
158
- if ($trans->language_code != $lang) {
159
- update_woocommerce_term_meta( $trans->term_id, 'order', $term_order);
160
- }
161
- }
162
- }
163
-
164
- $this->sitepress->switch_lang($cur_lang);
165
-
166
- $this->woocommerce_wpml->settings['is_term_order_synced'] = 'yes';
167
- $this->woocommerce_wpml->update_settings();
168
-
169
- }
170
-
171
- function sync_term_order($meta_id, $object_id, $meta_key, $meta_value) {
172
-
173
- // WooCommerce before termmeta table migration
174
- $wc_before_term_meta = get_option( 'db_version' ) < 34370;
175
-
176
- if (!isset($_POST['thetaxonomy']) || !taxonomy_exists($_POST['thetaxonomy']) || substr($meta_key,0,5) != 'order')
177
- return;
178
-
179
- $tax = filter_input( INPUT_POST, 'thetaxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
180
-
181
- $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));
182
- $trid = $this->sitepress->get_element_trid($term_taxonomy_id, 'tax_' . $tax);
183
- $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
184
- if ($translations) foreach ($translations as $trans) {
185
- if ($trans->element_id != $term_taxonomy_id) {
186
-
187
- // Backwards compatibility - WooCommerce termmeta table
188
- if( $wc_before_term_meta ) {
189
- $this->wpdb->update( $this->wpdb->prefix . 'woocommerce_termmeta',
190
- array('meta_value' => $meta_value),
191
- array('woocommerce_term_id' => $trans->term_id, 'meta_key' => $meta_key) );
192
- // END Backwards compatibility - WooCommerce termmeta table
193
- } else{
194
- update_term_meta( $trans->term_id, $meta_key, $meta_value);
195
- }
196
-
197
- }
198
- }
199
-
200
- }
201
-
202
- function translated_terms_status_update($term_id, $tt_id, $taxonomy){
203
-
204
- if ( isset( $_POST['product_cat_thumbnail_id'] ) || isset( $_POST['display_type'] ) ){
205
- global $sitepress_settings;
206
-
207
- if( $this->is_original_category($tt_id,'tax_'.$taxonomy) ){
208
- $trid = $this->sitepress->get_element_trid($tt_id,'tax_'.$taxonomy);
209
- $translations = $this->sitepress->get_element_translations($trid,'tax_'.$taxonomy);
210
-
211
- foreach($translations as $translation){
212
- if(!$translation->original){
213
- if(isset($_POST['display_type'])){
214
- update_woocommerce_term_meta( $translation->term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
215
- }
216
- 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));
217
- }
218
- }
219
- }
220
- }
221
-
222
- global $wp_taxonomies;
223
- if(in_array('product', $wp_taxonomies[$taxonomy]->object_type) || in_array('product_variation', $wp_taxonomies[$taxonomy]->object_type)){
224
- $this->update_terms_translated_status($taxonomy);
225
- }
226
-
227
- }
228
-
229
- function is_original_category( $tt_id, $taxonomy ){
230
- $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 ));
231
- return $is_original ? true : false;
232
- }
233
-
234
- public function wcml_update_term_translated_warnings(){
235
- $ret = array();
236
-
237
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
238
-
239
- $wcml_settings = $this->woocommerce_wpml->get_settings();
240
-
241
- $attribute_taxonomies = wc_get_attribute_taxonomies();
242
- $attribute_taxonomies_arr = array();
243
- foreach($attribute_taxonomies as $a){
244
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
245
- }
246
-
247
- $ret['is_attribute'] = intval( in_array( $taxonomy, $attribute_taxonomies_arr ) );
248
-
249
- if( isset( $wcml_settings['untranstaled_terms'][$taxonomy] ) &&
250
- (
251
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->ALL_TAXONOMY_TERMS_TRANSLATED ||
252
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_IGNORED
253
- )
254
- ){
255
-
256
- $ret['hide'] = 1;
257
-
258
- }else{
259
- $ret['hide'] = 0;
260
-
261
- if( isset( $wcml_settings['sync_'.$taxonomy ]) ){
262
- $ret['show_button'] = $wcml_settings['sync_'.$taxonomy ];
263
- }else{
264
-
265
- if( in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
266
- $ret['show_button'] = $wcml_settings['sync_variations'];
267
- }
268
- }
269
- }
270
-
271
- echo json_encode($ret);
272
- exit;
273
-
274
- }
275
-
276
- public function wcml_ingore_taxonomy_translation(){
277
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
278
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ingore_taxonomy_translation_nonce')){
279
- die('Invalid nonce');
280
- }
281
-
282
- $ret = array();
283
-
284
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
285
-
286
- $wcml_settings = $this->woocommerce_wpml->get_settings();
287
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->NEW_TAXONOMY_IGNORED;
288
-
289
- $this->woocommerce_wpml->update_settings($wcml_settings);
290
-
291
- $ret['html'] = '<i class="otgs-ico-ok"></i> ';
292
- $ret['html'] .= sprintf(__('%s do not require translation.', 'woocommerce-multilingual'), get_taxonomy($taxonomy)->labels->name);
293
- $ret['html'] .= '<small class="actions">';
294
- $ret['html'] .= '<a href="#unignore-' . $taxonomy . '">' . __( 'Include to translation', 'woocommerce-multilingual' ) . '</a>';
295
- $ret['html'] .= '</small>';
296
-
297
- echo json_encode($ret);
298
- exit;
299
- }
300
-
301
- public function wcml_uningore_taxonomy_translation(){
302
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
303
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ingore_taxonomy_translation_nonce')){
304
- die('Invalid nonce');
305
- }
306
-
307
- $ret = array();
308
-
309
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
310
-
311
- $wcml_settings = $this->woocommerce_wpml->get_settings();
312
-
313
- if($wcml_settings['untranstaled_terms'][$taxonomy]['count'] > 0){
314
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->NEW_TAXONOMY_TERMS;
315
-
316
- $ret['html'] = '<i class="otgs-ico-warning-sign"></i> ';
317
- $ret['html'] .= sprintf( __( '%d %s are missing translations.', 'woocommerce-multilingual' ), $wcml_settings['untranstaled_terms'][ $taxonomy ]['count'], get_taxonomy( $taxonomy )->labels->name );
318
- $ret['html'] .= ' <a class="button-secondary" href="' . admin_url( 'admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . sprintf( __( 'Translate %s', 'woocommerce-multilingual' ), get_taxonomy( $taxonomy )->labels->name ) . '</a>';
319
- $ret['html'] .= '<small class="actions">';
320
- $ret['html'] .= '<a href="#ignore-' . $taxonomy . '">' . __( 'Exclude from translation', 'woocommerce-multilingual' ) . '</a>';
321
- $ret['html'] .= '</small>';
322
-
323
- $ret['warn'] = 1;
324
-
325
- }else{
326
- $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->ALL_TAXONOMY_TERMS_TRANSLATED;
327
-
328
- $ret['html'] = '<i class="otgs-ico-ok"></i> ';
329
- $ret['html'] .= sprintf(__('All %s are translated.', 'woocommerce-multilingual'), get_taxonomy($taxonomy)->labels->name);
330
-
331
- $ret['warn'] = 0;
332
- }
333
-
334
- $this->woocommerce_wpml->update_settings($wcml_settings);
335
-
336
-
337
- echo json_encode($ret);
338
- exit;
339
- }
340
-
341
- public function update_terms_translated_status($taxonomy){
342
-
343
- $wcml_settings = $this->woocommerce_wpml->get_settings();
344
- $is_translatable= 1;
345
- $not_translated_count = 0;
346
-
347
- if( isset( $wcml_settings[ 'attributes_settings' ][ $taxonomy ] ) && !$wcml_settings[ 'attributes_settings' ][ $taxonomy ] ){
348
- $is_translatable = 0;
349
- }
350
-
351
- if( $is_translatable ){
352
-
353
- $active_languages = $this->sitepress->get_active_languages();
354
-
355
- foreach($active_languages as $language){
356
- $terms = $this->wpdb->get_results($this->wpdb->prepare("
357
- SELECT t1.element_id AS e1, t2.element_id AS e2 FROM {$this->wpdb->term_taxonomy} x
358
- 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
359
- LEFT JOIN {$this->wpdb->prefix}icl_translations t2 ON t2.trid = t1.trid AND t2.language_code = %s
360
- ", 'tax_' . $taxonomy, $language['code']));
361
- foreach($terms as $term){
362
- if( empty( $term->e2 ) ){
363
- $not_translated_count ++;
364
- }
365
- }
366
- }
367
- }
368
-
369
- $status = $not_translated_count ? $this->NEW_TAXONOMY_TERMS : $this->ALL_TAXONOMY_TERMS_TRANSLATED;
370
-
371
- if( isset( $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] ) && $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] === $this->NEW_TAXONOMY_IGNORED ){
372
- $status = $this->NEW_TAXONOMY_IGNORED;
373
- }
374
-
375
- $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] = array( 'count' => $not_translated_count , 'status' => $status );
376
-
377
- $this->woocommerce_wpml->update_settings( $wcml_settings );
378
-
379
- return $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ];
380
-
381
- }
382
-
383
- public function is_fully_translated($taxonomy){
384
-
385
- $wcml_settings = $this->woocommerce_wpml->get_settings();
386
-
387
- $return = true;
388
-
389
- if( !isset($wcml_settings['untranstaled_terms'][$taxonomy]) ){
390
- $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
391
- }
392
-
393
- if($wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_TERMS){
394
- $return = false;
395
- }
396
-
397
-
398
- return $return;
399
- }
400
-
401
- public function get_untranslated_terms_number($taxonomy){
402
-
403
- $wcml_settings = $this->woocommerce_wpml->get_settings();
404
-
405
- if(!isset($wcml_settings['untranstaled_terms'][$taxonomy])){
406
- $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
407
- }
408
-
409
- return $wcml_settings['untranstaled_terms'][$taxonomy]['count'];
410
-
411
- }
412
-
413
- public function set_flag_for_variation_on_attribute_update($term_id, $tt_id, $taxonomy){
414
-
415
- $attribute_taxonomies = wc_get_attribute_taxonomies();
416
- foreach($attribute_taxonomies as $a){
417
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
418
- }
419
-
420
- if(isset( $attribute_taxonomies_arr ) && in_array($taxonomy, $attribute_taxonomies_arr)){
421
-
422
- $wcml_settings = $this->woocommerce_wpml->get_settings();
423
-
424
- // get term language
425
- $term_language = $this->sitepress->get_element_language_details($tt_id, 'tax_' . $taxonomy);
426
-
427
- if( isset( $term_language->language_code ) && $term_language->language_code != $this->sitepress->get_default_language()){
428
- // get term in the default language
429
- $term_id = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $this->sitepress->get_default_language());
430
-
431
- //does it belong to any posts (variations)
432
- $objects = get_objects_in_term($term_id, $taxonomy);
433
-
434
- if(!isset($wcml_settings['variations_needed'][$taxonomy])){
435
- $wcml_settings['variations_needed'][$taxonomy] = 0;
436
- }
437
- $wcml_settings['variations_needed'][$taxonomy] += count($objects);
438
-
439
- $this->woocommerce_wpml->update_settings($wcml_settings);
440
-
441
- }
442
- }
443
-
444
- }
445
-
446
- public function sync_taxonomy_translations( $html, $taxonomy, $taxonomy_obj ){
447
-
448
- $is_wcml = is_admin() && $taxonomy && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']);
449
- $is_ajax = is_ajax() && $taxonomy && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_get_terms_and_labels_for_taxonomy_table';
450
- if( $is_wcml || $is_ajax ){
451
-
452
- $sync_tax = new WCML_Sync_Taxonomy( $this->woocommerce_wpml, $taxonomy, $taxonomy_obj );
453
- $html = $sync_tax->get_view();
454
- }
455
-
456
- return $html;
457
- }
458
-
459
- public function wcml_sync_product_variations($taxonomy){
460
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
461
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_product_variations')){
462
- die('Invalid nonce');
463
- }
464
-
465
- $VARIATIONS_THRESHOLD = 20;
466
-
467
- $wcml_settings = $this->woocommerce_wpml->get_settings();
468
- $response = array();
469
-
470
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
471
-
472
- $languages_processed = intval( $_POST['languages_processed']);
473
-
474
- $condition = $languages_processed?'>=':'>';
475
-
476
- $where = isset($_POST['last_post_id']) && $_POST['last_post_id'] ? ' ID '.$condition.' ' . intval($_POST['last_post_id']) . ' AND ' : '';
477
-
478
- $post_ids = $this->wpdb->get_col($this->wpdb->prepare("
479
- SELECT DISTINCT tr.object_id
480
- FROM {$this->wpdb->term_relationships} tr
481
- JOIN {$this->wpdb->term_taxonomy} tx on tr.term_taxonomy_id = tx.term_taxonomy_id
482
- JOIN {$this->wpdb->posts} p ON tr.object_id = p.ID
483
- JOIN {$this->wpdb->prefix}icl_translations t ON t.element_id = p.ID
484
- WHERE {$where} tx.taxonomy = %s AND p.post_type = 'product' AND t.element_type='post_product' AND t.language_code = %s
485
- ORDER BY ID ASC
486
-
487
- ", $taxonomy, $this->sitepress->get_default_language()));
488
-
489
- if($post_ids){
490
-
491
- $variations_processed = 0;
492
- $posts_processed = 0;
493
- foreach($post_ids as $post_id){
494
- $terms = wp_get_post_terms($post_id, $taxonomy);
495
- $terms_count = count($terms) . "\n\n";
496
-
497
- $trid = $this->sitepress->get_element_trid($post_id, 'post_product');
498
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
499
-
500
- $i = 1;
501
-
502
- foreach($translations as $translation){
503
-
504
- if($i > $languages_processed && $translation->element_id != $post_id){
505
- $this->woocommerce_wpml->sync_product_data->sync_product_taxonomies($post_id, $translation->element_id, $translation->language_code);
506
- $this->woocommerce_wpml->sync_variations_data->sync_product_variations($post_id, $translation->element_id, $translation->language_code, false, true);
507
- $this->woocommerce_wpml->translation_editor->create_product_translation_package($post_id,$trid, $translation->language_code,ICL_TM_COMPLETE);
508
- $variations_processed += $terms_count*2;
509
- $response['languages_processed'] = $i;
510
- $i++;
511
- //check if sum of 2 iterations doesn't exceed $VARIATIONS_THRESHOLD
512
- if($variations_processed >= $VARIATIONS_THRESHOLD){
513
- break;
514
- }
515
- }else{
516
- $i++;
517
- }
518
- }
519
- $response['last_post_id'] = $post_id;
520
- if(--$i == count($translations)){
521
- $response['languages_processed'] = 0;
522
- $languages_processed = 0;
523
- }else{
524
- break;
525
- }
526
-
527
- $posts_processed ++;
528
-
529
- }
530
-
531
- $response['go'] = 1;
532
-
533
- }else{
534
-
535
- $response['go'] = 0;
536
-
537
- }
538
-
539
- $response['progress'] = $response['go'] ? sprintf(__('%d products left', 'woocommerce-multilingual'), count($post_ids) - $posts_processed) : __('Synchronization complete!', 'woocommerce-multilingual');
540
-
541
- if($response['go'] && isset($wcml_settings['variations_needed'][$taxonomy]) && !empty($variations_processed)){
542
- $wcml_settings['variations_needed'][$taxonomy] = max($wcml_settings['variations_needed'][$taxonomy] - $variations_processed, 0);
543
- }else{
544
- if($response['go'] == 0){
545
- $wcml_settings['variations_needed'][$taxonomy] = 0;
546
- }
547
- }
548
- $wcml_settings['sync_variations'] = 0;
549
-
550
- $this->woocommerce_wpml->update_settings($wcml_settings);
551
-
552
- echo json_encode($response);
553
- exit;
554
- }
555
-
556
- public function wcml_sync_taxonomies_in_content_preview(){
557
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
558
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content_preview')){
559
- die('Invalid nonce');
560
- }
561
-
562
- global $wp_taxonomies;
563
-
564
- $html = $message = $errors = '';
565
-
566
-
567
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
568
- $object_types = $wp_taxonomies[$_POST['taxonomy']]->object_type;
569
-
570
- foreach($object_types as $object_type){
571
-
572
- $html .= $this->render_assignment_status($object_type, $_POST['taxonomy'], $preview = true);
573
-
574
- }
575
-
576
- }else{
577
- $errors = sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
578
- }
579
-
580
-
581
- echo json_encode(array('html' => $html, 'message'=> $message, 'errors' => $errors));
582
- exit;
583
- }
584
-
585
- public function wcml_sync_taxonomies_in_content(){
586
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
587
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content')){
588
- die('Invalid nonce');
589
- }
590
-
591
- global $wp_taxonomies;
592
-
593
- $html = $message = $errors = '';
594
-
595
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
596
- $html .= $this->render_assignment_status($_POST['post'], $_POST['taxonomy'], $preview = false);
597
-
598
- }else{
599
- $errors .= sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
600
- }
601
-
602
-
603
- echo json_encode(array('html' => $html, 'errors' => $errors));
604
- exit;
605
- }
606
-
607
- public function render_assignment_status($object_type, $taxonomy, $preview = true){
608
- global $wp_post_types, $wp_taxonomies;
609
-
610
- $default_language = $this->sitepress->get_default_language();
611
-
612
- $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 ) );
613
-
614
- foreach($posts as $post){
615
-
616
- $terms = wp_get_post_terms($post->ID, $taxonomy);
617
-
618
- $term_ids = array();
619
- foreach($terms as $term){
620
- $term_ids[] = $term->term_id;
621
- }
622
-
623
- $trid = $this->sitepress->get_element_trid($post->ID, 'post_' . $post->post_type);
624
- $translations = $this->sitepress->get_element_translations($trid, 'post_' . $post->post_type, true, true);
625
-
626
- foreach($translations as $language => $translation){
627
-
628
- if($language != $default_language && $translation->element_id){
629
-
630
- $terms_of_translation = wp_get_post_terms($translation->element_id, $taxonomy);
631
-
632
- $translation_term_ids = array();
633
- foreach($terms_of_translation as $term){
634
-
635
- $term_id_original = apply_filters( 'translate_object_id',$term->term_id, $taxonomy, false, $default_language );
636
- if(!$term_id_original || !in_array($term_id_original, $term_ids)){
637
- // remove term
638
-
639
- if($preview){
640
- $needs_sync = true;
641
- break(3);
642
- }
643
-
644
- $current_terms = wp_get_post_terms($translation->element_id, $taxonomy);
645
- $updated_terms = array();
646
- foreach($current_terms as $cterm){
647
- if($cterm->term_id != $term->term_id){
648
- $updated_terms[] = $taxonomy != 'product_type' ? $term->term_id : $term->name;
649
- }
650
- if(!$preview){
651
-
652
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
653
- $updated_terms = array_unique( array_map( 'intval', $updated_terms ) );
654
- }
655
-
656
- wp_set_post_terms($translation->element_id, $updated_terms, $taxonomy);
657
- }
658
-
659
- }
660
-
661
- }else{
662
- $translation_term_ids[] = $term_id_original;
663
- }
664
-
665
- }
666
-
667
- foreach($term_ids as $term_id){
668
-
669
- if(!in_array($term_id, $translation_term_ids)){
670
- // add term
671
-
672
- if($preview){
673
- $needs_sync = true;
674
- break(3);
675
- }
676
- $terms_array = array();
677
- $term_id_translated = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $language);
678
-
679
- // not using get_term
680
- $translated_term = $this->wpdb->get_row($this->wpdb->prepare("
681
- 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));
682
-
683
- if( $translated_term ){
684
- $terms_array[] = $translated_term->term_id;
685
- }
686
-
687
- if(!$preview){
688
-
689
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
690
- $terms_array = array_unique( array_map( 'intval', $terms_array ) );
691
- }
692
-
693
- wp_set_post_terms($translation->element_id, $terms_array, $taxonomy, true);
694
- }
695
-
696
- }
697
-
698
- }
699
-
700
- }
701
-
702
- }
703
-
704
- }
705
-
706
- $wcml_settings = $this->woocommerce_wpml->get_settings();
707
- $wcml_settings['sync_'.$taxonomy] = 0;
708
- $this->woocommerce_wpml->update_settings($wcml_settings);
709
-
710
- $out = '';
711
-
712
- if($preview){
713
-
714
- $out .= '<div class="wcml_tt_sync_row">';
715
- if(!empty($needs_sync)){
716
- $out .= '<form class="wcml_tt_do_sync">';
717
- $out .= '<input type="hidden" name="post" value="' . $object_type . '" />';
718
- $out .= wp_nonce_field('wcml_sync_taxonomies_in_content', 'wcml_sync_taxonomies_in_content_nonce',true,false);
719
- $out .= '<input type="hidden" name="taxonomy" value="' . $taxonomy . '" />';
720
- $out .= sprintf(__('Some translated %s have different %s assignments.', 'woocommerce-multilingual'),
721
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>',
722
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>');
723
- $out .= '&nbsp;<a class="submit button-secondary" href="#">' . sprintf(__('Update %s for all translated %s', 'woocommerce-multilingual'),
724
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
725
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>') . '</a>' .
726
- '&nbsp;<img src="'. ICL_PLUGIN_URL . '/res/img/ajax-loader.gif" alt="loading" height="16" width="16" class="wcml_tt_spinner" />';
727
- $out .= "</form>";
728
- }else{
729
- $out .= sprintf(__('All %s have the same %s assignments.', 'woocommerce-multilingual'),
730
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
731
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>');
732
- }
733
- $out .= "</div>";
734
-
735
- }else{
736
-
737
- $out .= sprintf(__('Successfully updated %s for all translated %s.', 'woocommerce-multilingual'), $wp_taxonomies[$taxonomy]->labels->name, $wp_post_types[$object_type]->labels->name);
738
-
739
- }
740
-
741
- return $out;
742
- }
743
-
744
- function shipping_terms($terms, $post_id, $taxonomy){
745
- global $pagenow;
746
-
747
- if( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_load_variations' ){
748
- return $terms;
749
- }
750
-
751
- if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
752
-
753
- remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
754
- $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');
755
- add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
756
- return $terms;
757
- }
758
-
759
- return $terms;
760
- }
761
-
762
- function filter_coupons_terms($terms, $taxonomies, $args){
763
- global $pagenow;
764
-
765
- 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)){
766
- remove_filter('get_terms',array($this,'filter_coupons_terms'));
767
- $current_language = $this->sitepress->get_current_language();
768
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
769
- $terms = get_terms( 'product_cat', 'orderby=name&hide_empty=0');
770
- add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
771
- $this->sitepress->switch_lang($current_language);
772
- }
773
-
774
- return $terms;
775
- }
776
-
777
- function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
778
- $is_shipping_settings = isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'shipping';
779
- if( is_admin() && in_array( 'product_shipping_class', (array) $taxonomies ) && $is_shipping_settings ){
780
- remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
781
- $current_language = $this->sitepress->get_current_language();
782
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
783
- add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
784
- $terms = get_terms( $taxonomies, $args );
785
- remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
786
- add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
787
- $this->sitepress->switch_lang($current_language);
788
- }
789
-
790
- return $terms;
791
- }
792
-
793
- function wcml_delete_term($term, $tt_id, $taxonomy, $deleted_term){
794
- global $wp_taxonomies;
795
-
796
- foreach($wp_taxonomies as $key=>$taxonomy_obj){
797
- if((in_array('product',$taxonomy_obj->object_type) || in_array('product_variation',$taxonomy_obj->object_type) ) && $key==$taxonomy){
798
- $this->update_terms_translated_status($taxonomy);
799
- break;
800
- }
801
- }
802
-
803
- }
804
-
805
- function get_product_terms_filter( $terms, $product_id, $taxonomy, $args ){
806
-
807
- $language = $this->sitepress->get_language_for_element( $product_id, 'post_'.get_post_type( $product_id ) );
808
-
809
- $is_objects_array = is_object( current ( $terms ) );
810
-
811
- $filtered_terms = array();
812
-
813
- foreach( $terms as $term ){
814
-
815
- if( !$is_objects_array ){
816
- $term_obj = get_term_by( 'name', $term, $taxonomy );
817
- if( !$term_obj ){
818
- $term_obj = get_term_by( 'slug', $term, $taxonomy );
819
- $is_slug = true;
820
- }
821
- }
822
-
823
- if( empty($term_obj) ){
824
- $filtered_terms[] = $term;
825
- continue;
826
- }
827
-
828
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_obj->term_id, $taxonomy, true, $language );
829
-
830
- if( $is_objects_array ){
831
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy );
832
- }else{
833
- if( isset( $is_slug ) ){
834
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy )->slug;
835
- }else{
836
- $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;
837
- }
838
- }
839
- }
840
-
841
- return $filtered_terms;
842
- }
843
-
844
-
845
-
846
-
847
- function set_flag_to_sync( $taxonomy, $el_id, $language_code ){
848
-
849
- $elem_details = $this->sitepress->get_element_language_details( $el_id, 'tax_'.$taxonomy );
850
- if( is_null( $elem_details->source_language_code ) )
851
- return;
852
-
853
- $this->check_if_sync_term_translation_needed( $el_id, $taxonomy );
854
-
855
- }
856
-
857
- function check_if_sync_terms_needed(){
858
-
859
- $wcml_settings = $this->woocommerce_wpml->get_settings();
860
- $wcml_settings['sync_variations'] = 0;
861
- $wcml_settings['sync_product_cat'] = 0;
862
- $wcml_settings['sync_product_tag'] = 0;
863
- $wcml_settings['sync_product_shipping_class'] = 0;
864
- $this->woocommerce_wpml->update_settings( $wcml_settings );
865
-
866
- $taxonomies_to_check = array( 'product_cat', 'product_tag', 'product_shipping_class' );
867
-
868
- foreach( $taxonomies_to_check as $check_taxonomy ){
869
- $terms = get_terms( $check_taxonomy, array( 'hide_empty' => false, 'fields' => 'ids' ) );
870
- if (is_array($terms)){
871
- foreach( $terms as $term ){
872
- if( $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], $check_taxonomy ) ){
873
- break;
874
- }
875
- }
876
- }
877
- }
878
-
879
- $attribute_taxonomies = wc_get_attribute_taxonomies();
880
- $flag_set = false;
881
- foreach( $attribute_taxonomies as $a ){
882
-
883
- $terms = get_terms( 'pa_' . $a->attribute_name, array( 'hide_empty' => false, 'fields' => 'ids' ) );
884
- if (is_array($terms)){
885
- foreach( $terms as $term ){
886
- $flag_set = $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], 'pa_' . $a->attribute_name );
887
- if( $flag_set ){
888
- break;
889
- }
890
- }
891
- }
892
-
893
- if( $flag_set ){
894
- break;
895
- }
896
- }
897
-
898
- }
899
-
900
- function check_if_sync_term_translation_needed( $t_id, $taxonomy ){
901
-
902
- $wcml_settings = $this->woocommerce_wpml->get_settings();
903
-
904
- $attribute_taxonomies = wc_get_attribute_taxonomies();
905
- $attribute_taxonomies_arr = array();
906
- foreach($attribute_taxonomies as $a){
907
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
908
- }
909
-
910
- 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'] ) ){
911
- return true;
912
- }
913
-
914
- $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 ) );
915
-
916
- foreach( $translations as $key => $translation ){
917
- if ( is_null( $translation->source_language_code ) ) {
918
- $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 ) );
919
- unset( $translations[ $key ] );
920
- }
921
- }
922
-
923
- foreach( $translations as $translation ){
924
-
925
- $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 ) );
926
- if( $original_count != $count ){
927
-
928
- if( in_array( $taxonomy, array( 'product_cat', 'product_tag', 'product_shipping_class' ) ) ){
929
- $wcml_settings[ 'sync_'.$taxonomy ] = 1;
930
- $this->woocommerce_wpml->update_settings($wcml_settings);
931
- return true;
932
- }
933
-
934
- if( isset( $attribute_taxonomies_arr ) && in_array( $taxonomy, $attribute_taxonomies_arr ) ){
935
- $wcml_settings['sync_variations'] = 1;
936
- $this->woocommerce_wpml->update_settings($wcml_settings);
937
- return true;
938
- }
939
-
940
- }
941
-
942
- }
943
-
944
- }
945
-
946
- function get_table_taxonomies( $taxonomies ){
947
-
948
- foreach( $taxonomies as $key => $taxonomy ){
949
- if (substr($key, 0, 3) != 'pa_') {
950
- unset( $taxonomies[$key]);
951
- }
952
- }
953
-
954
- return $taxonomies;
955
- }
956
-
957
- function get_wc_taxonomies(){
958
-
959
- global $wp_taxonomies;
960
- $taxonomies = array();
961
-
962
- //don't use get_taxonomies for product, because when one more post type registered for product taxonomy functions returned taxonomies only for product type
963
- foreach ( $wp_taxonomies as $key => $taxonomy ) {
964
- if (
965
- ( in_array( 'product', $taxonomy->object_type ) || in_array( 'product_variation', $taxonomy->object_type ) ) &&
966
- ! in_array( $key, $taxonomies ) &&
967
- $this->woocommerce_wpml->attributes->is_translatable_attribute( $key )
968
- ) {
969
- $taxonomies[] = $key;
970
- }
971
- }
972
-
973
- return $taxonomies;
974
-
975
- }
976
-
977
- function has_wc_taxonomies_to_translate(){
978
-
979
- $taxonomies = $this->get_wc_taxonomies();
980
-
981
- $no_tax_to_trnls = false;
982
- foreach ( $taxonomies as $taxonomy ){
983
- if ( $taxonomy == 'product_type' || $this->get_untranslated_terms_number( $taxonomy ) == 0 ) {
984
- continue;
985
- } else {
986
- $no_tax_to_trnls = true;
987
- }
988
- }
989
-
990
- return $no_tax_to_trnls;
991
-
992
- }
993
-
994
- /*
995
- * Use custom query, because get_term_by function return false for terms with "0" slug *
996
- */
997
- public function wcml_get_term_id_by_slug( $taxonomy, $slug ){
998
-
999
- return $this->wpdb->get_var(
1000
- $this->wpdb->prepare(
1001
- "SELECT tt.term_id FROM {$this->wpdb->terms} AS t
1002
- INNER JOIN {$this->wpdb->term_taxonomy} AS tt
1003
- ON t.term_id = tt.term_id
1004
- WHERE tt.taxonomy = %s AND t.slug = %s LIMIT 1",
1005
- $taxonomy, sanitize_title( $slug ) )
1006
- );
1007
- }
1008
-
1009
- public function wcml_get_term_by_id( $term_id, $taxonomy ){
1010
-
1011
- return $this->wpdb->get_row(
1012
- $this->wpdb->prepare("
1013
- SELECT * FROM {$this->wpdb->terms} t
1014
- JOIN {$this->wpdb->term_taxonomy} x
1015
- ON x.term_id = t.term_id
1016
- WHERE t.term_id = %d AND x.taxonomy = %s",
1017
- $term_id, $taxonomy )
1018
- );
1019
- }
1020
-
1021
- public function wcml_get_translated_term( $term_id, $taxonomy, $language ){
1022
-
1023
- $tr_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, false, $language );
1024
-
1025
- if( !is_null( $tr_id ) ) {
1026
- $term_id = $tr_id;
1027
- }
1028
-
1029
- return $this->wcml_get_term_by_id( $term_id, $taxonomy );
1030
- }
1031
-
1032
- }
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
+ add_action('wp_ajax_wcml_ingore_taxonomy_translation', array( $this, 'wcml_ingore_taxonomy_translation'));
28
+ add_action('wp_ajax_wcml_uningore_taxonomy_translation', array( $this, 'wcml_uningore_taxonomy_translation'));
29
+
30
+ add_action('created_term', array( $this, 'set_flag_for_variation_on_attribute_update'), 10, 3);
31
+
32
+ add_filter('wpml_taxonomy_translation_bottom', array( $this, 'sync_taxonomy_translations'), 10, 3 );
33
+
34
+ add_action('wp_ajax_wcml_sync_product_variations', array( $this, 'wcml_sync_product_variations'));
35
+ add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content', array( $this, 'wcml_sync_taxonomies_in_content'));
36
+ add_action('wp_ajax_wcml_tt_sync_taxonomies_in_content_preview', array( $this, 'wcml_sync_taxonomies_in_content_preview'));
37
+
38
+ if(is_admin()){
39
+ add_action('admin_menu', array($this, 'admin_menu_setup'));
40
+ }
41
+
42
+ add_action('delete_term',array($this, 'wcml_delete_term'),10,4);
43
+ add_filter('get_the_terms',array($this,'shipping_terms'),10,3);
44
+ //filter coupons terms in admin
45
+ add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
46
+ add_filter('get_terms',array($this,'filter_shipping_classes_terms'),10,3);
47
+
48
+ add_filter( 'woocommerce_get_product_terms', array( $this, 'get_product_terms_filter' ), 10, 4 );
49
+ add_action( 'created_term_translation', array( $this, 'set_flag_to_sync'), 10, 3 );
50
+ }
51
+
52
+ function admin_menu_setup(){
53
+ global $pagenow;
54
+ if($pagenow == 'edit-tags.php' && isset($_GET['action']) && $_GET['action'] == 'edit'){
55
+ add_action('admin_notices', array($this, 'show_term_translation_screen_notices'));
56
+ }
57
+
58
+ $page = isset( $_GET['page'] )? $_GET['page'] : '';
59
+ if ( $page === ICL_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' ) {
60
+ WCML_Resources::load_management_css();
61
+ wp_enqueue_script( 'wcml-scripts' );
62
+ }
63
+
64
+ }
65
+
66
+ function save_wc_term_meta($original_tax, $result){
67
+
68
+
69
+ // WooCommerce before termmeta table migration
70
+ $wc_before_term_meta = get_option( 'db_version' ) < 34370;
71
+
72
+ // backwards compatibility - before the termmeta table was added
73
+ if( $wc_before_term_meta ){
74
+
75
+ $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));
76
+ foreach ( $term_wc_meta as $wc_meta ){
77
+ $wc_original_metakey = $wc_meta->meta_key;
78
+ $wc_original_metavalue = $wc_meta->meta_value;
79
+ update_woocommerce_term_meta($result['term_id'], $wc_original_metakey, $wc_original_metavalue);
80
+ }
81
+ // End of backwards compatibility - before the termmeta table was added
82
+ }else{
83
+
84
+ $term_wc_meta = get_term_meta($original_tax->term_id, false, 1);
85
+ foreach ( $term_wc_meta as $key => $values ) {
86
+ update_term_meta( $result['term_id'], $key, array_pop( $values ) );
87
+ }
88
+
89
+ }
90
+ }
91
+
92
+ function show_term_translation_screen_notices(){
93
+
94
+ $taxonomies = array_keys(get_taxonomies(array('object_type'=>array('product')),'objects'));
95
+ $taxonomies = $taxonomies + array_keys(get_taxonomies(array('object_type'=>array('product_variations')),'objects'));
96
+ $taxonomies = array_unique($taxonomies);
97
+ $taxonomy = isset($_GET['taxonomy']) ? $_GET['taxonomy'] : false;
98
+ if($taxonomy && in_array($taxonomy, $taxonomies)){
99
+ $taxonomy_obj = get_taxonomy($taxonomy);
100
+ $language = isset($_GET['lang']) ? $_GET['lang'] : false;
101
+ if(empty($language) && isset($_GET['tag_ID'])){
102
+ $tax_id = $this->wpdb->get_var($this->wpdb->prepare("SELECT term_taxonomy_id FROM {$this->wpdb->term_taxonomy} WHERE term_id=%d AND taxonomy=%s", $_GET['tag_ID'], $taxonomy));
103
+ $language = $this->sitepress->get_language_for_element($tax_id, 'tax_' . $taxonomy);
104
+ }
105
+ if(empty($language)){
106
+ $language = $this->sitepress->get_default_language();
107
+ }
108
+
109
+ $message = sprintf(__('To translate %s please use the %s translation%s page, inside the %sWooCommerce Multilingual admin%s.', 'woocommerce-multilingual'),
110
+ $taxonomy_obj->labels->name,
111
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . $taxonomy_obj->labels->singular_name, '</a></strong>',
112
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml">'), '</a></strong>');
113
+
114
+ echo '<div class="updated"><p>' . $message . '</p></div>';
115
+
116
+ }
117
+
118
+ }
119
+
120
+ function sync_term_order_globally() {
121
+ //syncs the term order of any taxonomy in $this->wpdb->prefix.'woocommerce_attribute_taxonomies'
122
+ //use it when term orderings have become unsynched, e.g. before WCML 3.3.
123
+
124
+ if(!defined('WOOCOMMERCE_VERSION')){
125
+ return;
126
+ }
127
+
128
+ $cur_lang = $this->sitepress->get_current_language();
129
+ $lang = $this->sitepress->get_default_language();
130
+ $this->sitepress->switch_lang($lang);
131
+
132
+ $taxes = wc_get_attribute_taxonomies ();
133
+
134
+ if ($taxes) foreach ($taxes as $woo_tax) {
135
+ $tax = 'pa_'.$woo_tax->attribute_name;
136
+ $meta_key = 'order_'.$tax;
137
+ //if ($tax != 'pa_frame') continue;
138
+ $terms = get_terms($tax);
139
+ if ($terms)foreach ($terms as $term) {
140
+ $term_order = get_woocommerce_term_meta($term->term_id,$meta_key);
141
+ $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_'.$tax);
142
+ $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
143
+ if ($translations) foreach ($translations as $trans) {
144
+ if ($trans->language_code != $lang) {
145
+ update_woocommerce_term_meta( $trans->term_id, $meta_key, $term_order);
146
+ }
147
+ }
148
+ }
149
+ }
150
+
151
+ //sync product categories ordering
152
+ $terms = get_terms('product_cat');
153
+ if ($terms) foreach($terms as $term) {
154
+ $term_order = get_woocommerce_term_meta($term->term_id,'order');
155
+ $trid = $this->sitepress->get_element_trid($term->term_taxonomy_id,'tax_product_cat');
156
+ $translations = $this->sitepress->get_element_translations($trid,'tax_product_cat');
157
+ if ($translations) foreach ($translations as $trans) {
158
+ if ($trans->language_code != $lang) {
159
+ update_woocommerce_term_meta( $trans->term_id, 'order', $term_order);
160
+ }
161
+ }
162
+ }
163
+
164
+ $this->sitepress->switch_lang($cur_lang);
165
+
166
+ $this->woocommerce_wpml->settings['is_term_order_synced'] = 'yes';
167
+ $this->woocommerce_wpml->update_settings();
168
+
169
+ }
170
+
171
+ function sync_term_order($meta_id, $object_id, $meta_key, $meta_value) {
172
+
173
+ // WooCommerce before termmeta table migration
174
+ $wc_before_term_meta = get_option( 'db_version' ) < 34370;
175
+
176
+ if (!isset($_POST['thetaxonomy']) || !taxonomy_exists($_POST['thetaxonomy']) || substr($meta_key,0,5) != 'order')
177
+ return;
178
+
179
+ $tax = filter_input( INPUT_POST, 'thetaxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
180
+
181
+ $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));
182
+ $trid = $this->sitepress->get_element_trid($term_taxonomy_id, 'tax_' . $tax);
183
+ $translations = $this->sitepress->get_element_translations($trid,'tax_' . $tax);
184
+ if ($translations) foreach ($translations as $trans) {
185
+ if ($trans->element_id != $term_taxonomy_id) {
186
+
187
+ // Backwards compatibility - WooCommerce termmeta table
188
+ if( $wc_before_term_meta ) {
189
+ $this->wpdb->update( $this->wpdb->prefix . 'woocommerce_termmeta',
190
+ array('meta_value' => $meta_value),
191
+ array('woocommerce_term_id' => $trans->term_id, 'meta_key' => $meta_key) );
192
+ // END Backwards compatibility - WooCommerce termmeta table
193
+ } else{
194
+ update_term_meta( $trans->term_id, $meta_key, $meta_value);
195
+ }
196
+
197
+ }
198
+ }
199
+
200
+ }
201
+
202
+ function translated_terms_status_update($term_id, $tt_id, $taxonomy){
203
+
204
+ if ( isset( $_POST['product_cat_thumbnail_id'] ) || isset( $_POST['display_type'] ) ){
205
+ global $sitepress_settings;
206
+
207
+ if( $this->is_original_category($tt_id,'tax_'.$taxonomy) ){
208
+ $trid = $this->sitepress->get_element_trid($tt_id,'tax_'.$taxonomy);
209
+ $translations = $this->sitepress->get_element_translations($trid,'tax_'.$taxonomy);
210
+
211
+ foreach($translations as $translation){
212
+ if(!$translation->original){
213
+ if(isset($_POST['display_type'])){
214
+ update_woocommerce_term_meta( $translation->term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
215
+ }
216
+ 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));
217
+ }
218
+ }
219
+ }
220
+ }
221
+
222
+ global $wp_taxonomies;
223
+ if(in_array('product', $wp_taxonomies[$taxonomy]->object_type) || in_array('product_variation', $wp_taxonomies[$taxonomy]->object_type)){
224
+ $this->update_terms_translated_status($taxonomy);
225
+ }
226
+
227
+ }
228
+
229
+ function is_original_category( $tt_id, $taxonomy ){
230
+ $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 ));
231
+ return $is_original ? true : false;
232
+ }
233
+
234
+ public function wcml_update_term_translated_warnings(){
235
+ $ret = array();
236
+
237
+ $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
238
+
239
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
240
+
241
+ $attribute_taxonomies = $this->woocommerce_wpml->attributes->get_translatable_attributes();
242
+
243
+ $attribute_taxonomies_arr = array();
244
+ foreach($attribute_taxonomies as $a){
245
+ $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
246
+ }
247
+
248
+ $ret['is_attribute'] = intval( in_array( $taxonomy, $attribute_taxonomies_arr ) );
249
+
250
+ if( isset( $wcml_settings['untranstaled_terms'][$taxonomy] ) &&
251
+ (
252
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->ALL_TAXONOMY_TERMS_TRANSLATED ||
253
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_IGNORED
254
+ )
255
+ ){
256
+
257
+ $ret['hide'] = 1;
258
+ }else{
259
+
260
+ $ret['hide'] = 0;
261
+
262
+ if( isset( $wcml_settings[ 'sync_'.$taxonomy ]) ){
263
+ $ret[ 'show_button' ] = $wcml_settings[ 'sync_'.$taxonomy ];
264
+ }elseif( in_array( $taxonomy, $attribute_taxonomies_arr ) ) {
265
+ $ret[ 'show_button' ] = $wcml_settings[ 'sync_variations' ];
266
+ }
267
+ }
268
+
269
+ if( $ret[ 'is_attribute' ] ){
270
+ $ret['hide'] = $this->woocommerce_wpml->attributes->is_attributes_fully_translated();
271
+ }
272
+
273
+ echo json_encode($ret);
274
+ exit;
275
+
276
+ }
277
+
278
+ public function wcml_ingore_taxonomy_translation(){
279
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
280
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ingore_taxonomy_translation_nonce')){
281
+ die('Invalid nonce');
282
+ }
283
+
284
+ $ret = array();
285
+
286
+ $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
287
+
288
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
289
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->NEW_TAXONOMY_IGNORED;
290
+
291
+ $this->woocommerce_wpml->update_settings($wcml_settings);
292
+
293
+ $ret['html'] = '<i class="otgs-ico-ok"></i> ';
294
+ $ret['html'] .= sprintf(__('%s do not require translation.', 'woocommerce-multilingual'), get_taxonomy($taxonomy)->labels->name);
295
+ $ret['html'] .= '<small class="actions">';
296
+ $ret['html'] .= '<a href="#unignore-' . $taxonomy . '">' . __( 'Include to translation', 'woocommerce-multilingual' ) . '</a>';
297
+ $ret['html'] .= '</small>';
298
+
299
+ echo json_encode($ret);
300
+ exit;
301
+ }
302
+
303
+ public function wcml_uningore_taxonomy_translation(){
304
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
305
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ingore_taxonomy_translation_nonce')){
306
+ die('Invalid nonce');
307
+ }
308
+
309
+ $ret = array();
310
+
311
+ $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
312
+
313
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
314
+
315
+ if($wcml_settings['untranstaled_terms'][$taxonomy]['count'] > 0){
316
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->NEW_TAXONOMY_TERMS;
317
+
318
+ $ret['html'] = '<i class="otgs-ico-warning-sign"></i> ';
319
+ $ret['html'] .= sprintf( __( '%d %s are missing translations.', 'woocommerce-multilingual' ), $wcml_settings['untranstaled_terms'][ $taxonomy ]['count'], get_taxonomy( $taxonomy )->labels->name );
320
+ $ret['html'] .= ' <a class="button-secondary" href="' . admin_url( 'admin.php?page=wpml-wcml&tab=' . $taxonomy ) . '">' . sprintf( __( 'Translate %s', 'woocommerce-multilingual' ), get_taxonomy( $taxonomy )->labels->name ) . '</a>';
321
+ $ret['html'] .= '<small class="actions">';
322
+ $ret['html'] .= '<a href="#ignore-' . $taxonomy . '">' . __( 'Exclude from translation', 'woocommerce-multilingual' ) . '</a>';
323
+ $ret['html'] .= '</small>';
324
+
325
+ $ret['warn'] = 1;
326
+
327
+ }else{
328
+ $wcml_settings['untranstaled_terms'][$taxonomy]['status'] = $this->ALL_TAXONOMY_TERMS_TRANSLATED;
329
+
330
+ $ret['html'] = '<i class="otgs-ico-ok"></i> ';
331
+ $ret['html'] .= sprintf(__('All %s are translated.', 'woocommerce-multilingual'), get_taxonomy($taxonomy)->labels->name);
332
+
333
+ $ret['warn'] = 0;
334
+ }
335
+
336
+ $this->woocommerce_wpml->update_settings($wcml_settings);
337
+
338
+
339
+ echo json_encode($ret);
340
+ exit;
341
+ }
342
+
343
+ public function update_terms_translated_status($taxonomy){
344
+
345
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
346
+ $is_translatable= 1;
347
+ $not_translated_count = 0;
348
+ $original_terms = array();
349
+
350
+ if( isset( $wcml_settings[ 'attributes_settings' ][ $taxonomy ] ) && !$wcml_settings[ 'attributes_settings' ][ $taxonomy ] ){
351
+ $is_translatable = 0;
352
+ }
353
+
354
+ if( $is_translatable ){
355
+
356
+ $active_languages = $this->sitepress->get_active_languages();
357
+
358
+ foreach($active_languages as $language){
359
+ $terms = $this->wpdb->get_results($this->wpdb->prepare("
360
+ SELECT t1.element_id AS e1, t2.element_id AS e2 FROM {$this->wpdb->term_taxonomy} x
361
+ 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
362
+ LEFT JOIN {$this->wpdb->prefix}icl_translations t2 ON t2.trid = t1.trid AND t2.language_code = %s
363
+ ", 'tax_' . $taxonomy, $language['code']));
364
+ foreach($terms as $term){
365
+ if( empty( $term->e2 ) && !in_array( $term->e1, $original_terms ) ){
366
+ $original_terms[] = $term->e1;
367
+ $not_translated_count ++;
368
+ }
369
+ }
370
+ }
371
+ }
372
+
373
+ $status = $not_translated_count ? $this->NEW_TAXONOMY_TERMS : $this->ALL_TAXONOMY_TERMS_TRANSLATED;
374
+
375
+ if( isset( $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] ) && $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] === $this->NEW_TAXONOMY_IGNORED ){
376
+ $status = $this->NEW_TAXONOMY_IGNORED;
377
+ }
378
+
379
+ $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ] = array( 'count' => $not_translated_count , 'status' => $status );
380
+
381
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
382
+
383
+ return $wcml_settings[ 'untranstaled_terms' ][ $taxonomy ];
384
+
385
+ }
386
+
387
+ public function is_fully_translated($taxonomy){
388
+
389
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
390
+
391
+ $return = true;
392
+
393
+ if( !isset($wcml_settings['untranstaled_terms'][$taxonomy]) ){
394
+ $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
395
+ }
396
+
397
+ if($wcml_settings['untranstaled_terms'][$taxonomy]['status'] == $this->NEW_TAXONOMY_TERMS){
398
+ $return = false;
399
+ }
400
+
401
+
402
+ return $return;
403
+ }
404
+
405
+ public function get_untranslated_terms_number( $taxonomy, $force_update = false ){
406
+
407
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
408
+
409
+ if( $force_update || !isset($wcml_settings['untranstaled_terms'][$taxonomy] ) ){
410
+ $wcml_settings['untranstaled_terms'][$taxonomy] = $this->update_terms_translated_status($taxonomy);
411
+ }
412
+
413
+ return $wcml_settings['untranstaled_terms'][$taxonomy]['count'];
414
+
415
+ }
416
+
417
+ public function set_flag_for_variation_on_attribute_update($term_id, $tt_id, $taxonomy){
418
+
419
+ $attribute_taxonomies = wc_get_attribute_taxonomies();
420
+ foreach($attribute_taxonomies as $a){
421
+ $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
422
+ }
423
+
424
+ if(isset( $attribute_taxonomies_arr ) && in_array($taxonomy, $attribute_taxonomies_arr)){
425
+
426
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
427
+
428
+ // get term language
429
+ $term_language = $this->sitepress->get_element_language_details($tt_id, 'tax_' . $taxonomy);
430
+
431
+ if( isset( $term_language->language_code ) && $term_language->language_code != $this->sitepress->get_default_language()){
432
+ // get term in the default language
433
+ $term_id = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $this->sitepress->get_default_language());
434
+
435
+ //does it belong to any posts (variations)
436
+ $objects = get_objects_in_term($term_id, $taxonomy);
437
+
438
+ if(!isset($wcml_settings['variations_needed'][$taxonomy])){
439
+ $wcml_se