WooCommerce Multilingual – run WooCommerce with WPML - Version 3.9.4

Version Description

  • Fixed an issue with custom prices (secondary currency) overriding the price in the default currency in some conditions
  • Fixed an issue with WooCommerce Authorize.Net AIM Gateway happening when using the credit cart checkout
  • Bug fix: the group products were excluded from the order notification emails
  • Fixed a compatibility issue with Revolution Slider
  • Changed the input field for variation descriptions to textarea in the tranlsation editor
  • Fixed an issue related to rates per shipping in secondary currencies when using WooCommerce Table Rate Shipping
  • Bug fix: the shipping class was not displayed in the backend when when using WooCommerce Table Rate Shipping and creating the product in a secondary language
  • Fixed a compatibility issue with WooCommerce Print Invoices
  • Fixed compatibility issues with Sensei
  • Added a filter for rounding rules logic
  • Added a currencies that do not use decimals
Download this release

Release Info

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

Code changes from version 3.9.3 to 3.9.4

Files changed (60) 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 +2234 -2234
  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-pip.php +93 -0
  19. compatibility/class-wcml-product-addons.php +247 -247
  20. compatibility/class-wcml-product-bundles.php +411 -411
  21. compatibility/class-wcml-sensei.php +234 -231
  22. compatibility/class-wcml-tab-manager.php +707 -707
  23. compatibility/class-wcml-table-rate-shipping.php +115 -103
  24. compatibility/class-wcml-variation-swatches-and-photos.php +62 -62
  25. compatibility/class-wcml-vpc.php +20 -20
  26. compatibility/class-wcml-wc-ajax-cart.php +16 -16
  27. compatibility/class-wcml-wc-name-your-price.php +24 -24
  28. compatibility/class-wcml-wc-subscriptions.php +185 -185
  29. compatibility/class-wcml-wcexporter.php +70 -70
  30. compatibility/class-wcml-wpseo.php +41 -41
  31. compatibility/res/css/wcml-bookings.css +61 -61
  32. compatibility/res/js/wcml-adventure-tours.js +31 -31
  33. compatibility/res/js/wcml-bookings.js +91 -91
  34. compatibility/res/js/wcml-composite.js +32 -32
  35. inc/admin-menus/class-wcml-admin-menus.php +296 -296
  36. inc/admin-menus/class-wcml-links.php +24 -24
  37. inc/admin-menus/class-wcml-pointers.php +81 -81
  38. inc/admin-menus/class-wcml-setup.php +342 -342
  39. inc/class-wcml-ajax-setup.php +159 -159
  40. inc/class-wcml-attributes.php +403 -403
  41. inc/class-wcml-capabilities.php +32 -32
  42. inc/class-wcml-cart.php +273 -273
  43. inc/class-wcml-compatibility.php +175 -170
  44. inc/class-wcml-coupons.php +87 -87
  45. inc/class-wcml-dependencies.php +346 -346
  46. inc/class-wcml-emails.php +479 -457
  47. inc/class-wcml-endpoints.php +283 -283
  48. inc/class-wcml-fix-copied-custom-fields-wpml353.php +39 -39
  49. inc/class-wcml-install.php +226 -226
  50. inc/class-wcml-languages-upgrader.php +300 -300
  51. inc/class-wcml-locale.php +61 -61
  52. inc/class-wcml-media.php +183 -183
  53. inc/class-wcml-orders.php +377 -377
  54. inc/class-wcml-products-screen-options.php +46 -46
  55. inc/class-wcml-products.php +496 -496
  56. inc/class-wcml-reports.php +258 -258
  57. inc/class-wcml-requests.php +70 -70
  58. inc/class-wcml-resources.php +228 -228
  59. inc/class-wcml-store-pages.php +594 -594
  60. inc/class-wcml-terms.php +167 -1036
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_ajax_actions', 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_ajax_actions', 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,2235 +1,2235 @@
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_ajax_actions', 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
- add_filter( 'wpml_extra_conditions_snippet', array( $this, 'extra_conditions_to_filter_bookings' ) );
176
-
177
- $this->clear_transient_fields();
178
-
179
- add_filter( 'wpml_tm_dashboard_translatable_types', array( $this, 'hide_bookings_type_on_tm_dashboard' ) );
180
-
181
- }
182
-
183
- function wcml_price_field_after_booking_base_cost( $post_id ) {
184
-
185
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
186
-
187
- }
188
-
189
- function wcml_price_field_after_booking_block_cost( $post_id ) {
190
-
191
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
192
-
193
- }
194
-
195
- function wcml_price_field_after_display_cost( $post_id ) {
196
-
197
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
198
-
199
- }
200
-
201
- function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ) {
202
-
203
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
204
-
205
- }
206
-
207
- function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ) {
208
-
209
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
210
-
211
- }
212
-
213
- function wcml_price_field_after_person_cost( $person_type_id ) {
214
-
215
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
216
-
217
- }
218
-
219
- function wcml_price_field_after_person_block_cost( $person_type_id ) {
220
-
221
- $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
222
-
223
- }
224
-
225
- function wcml_price_field_after_resource_cost( $resource_id, $post_id ) {
226
-
227
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
228
-
229
- }
230
-
231
- function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ) {
232
-
233
- $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
234
-
235
- }
236
-
237
- function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ) {
238
-
239
-
240
- if ( ( ! $check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
241
-
242
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
243
-
244
- $wc_currencies = get_woocommerce_currencies();
245
-
246
- echo '<div class="wcml_custom_cost_field" >';
247
-
248
- foreach ( $currencies as $currency_code => $currency ) {
249
-
250
- switch ( $field ) {
251
- case 'wcml_wc_booking_cost':
252
- woocommerce_wp_text_input( array(
253
- 'id' => 'wcml_wc_booking_cost',
254
- 'class' => 'wcml_bookings_custom_price',
255
- 'name' => 'wcml_wc_booking_cost[' . $currency_code . ']',
256
- 'label' => get_woocommerce_currency_symbol( $currency_code ),
257
- 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ),
258
- 'value' => get_post_meta( $post_id, '_wc_booking_cost_' . $currency_code, true ),
259
- 'type' => 'number',
260
- 'desc_tip' => true,
261
- 'custom_attributes' => array(
262
- 'min' => '',
263
- 'step' => '0.01'
264
- )
265
- ) );
266
- break;
267
- case 'wcml_wc_booking_base_cost':
268
- woocommerce_wp_text_input( array(
269
- 'id' => 'wcml_wc_booking_base_cost',
270
- 'class' => 'wcml_bookings_custom_price',
271
- 'name' => 'wcml_wc_booking_base_cost[' . $currency_code . ']',
272
- 'label' => get_woocommerce_currency_symbol( $currency_code ),
273
- 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ),
274
- 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_' . $currency_code, true ),
275
- 'type' => 'number',
276
- 'desc_tip' => true,
277
- 'custom_attributes' => array(
278
- 'min' => '',
279
- 'step' => '0.01'
280
- )
281
- ) );
282
- break;
283
- case 'wcml_wc_display_cost':
284
- woocommerce_wp_text_input( array(
285
- 'id' => 'wcml_wc_display_cost',
286
- 'class' => 'wcml_bookings_custom_price',
287
- 'name' => 'wcml_wc_display_cost[' . $currency_code . ']',
288
- 'label' => get_woocommerce_currency_symbol( $currency_code ),
289
- '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' ),
290
- 'value' => get_post_meta( $post_id, '_wc_display_cost_' . $currency_code, true ),
291
- 'type' => 'number',
292
- 'desc_tip' => true,
293
- 'custom_attributes' => array(
294
- 'min' => '',
295
- 'step' => '0.01'
296
- )
297
- ) );
298
- break;
299
-
300
- case 'wcml_wc_booking_pricing_base_cost':
301
-
302
- if ( isset( $pricing[ 'base_cost_' . $currency_code ] ) ) {
303
- $value = $pricing[ 'base_cost_' . $currency_code ];
304
- } else {
305
- $value = '';
306
- }
307
-
308
- echo '<div class="wcml_bookings_range_block" >';
309
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
310
- 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" />';
311
- echo '</div>';
312
- break;
313
-
314
- case 'wcml_wc_booking_pricing_cost':
315
-
316
- if ( isset( $pricing[ 'cost_' . $currency_code ] ) ) {
317
- $value = $pricing[ 'cost_' . $currency_code ];
318
- } else {
319
- $value = '';
320
- }
321
-
322
- echo '<div class="wcml_bookings_range_block" >';
323
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
324
- echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost[' . $currency_code . '][]" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
325
- echo '</div>';
326
- break;
327
-
328
- case 'wcml_wc_booking_person_cost':
329
-
330
- $value = get_post_meta( $post_id, 'cost_' . $currency_code, true );
331
-
332
- echo '<div class="wcml_bookings_person_block" >';
333
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
334
- 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" />';
335
- echo '</div>';
336
- break;
337
-
338
- case 'wcml_wc_booking_person_block_cost':
339
-
340
- $value = get_post_meta( $post_id, 'block_cost_' . $currency_code, true );
341
-
342
- echo '<div class="wcml_bookings_person_block" >';
343
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
344
- 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" />';
345
- echo '</div>';
346
- break;
347
-
348
- case 'wcml_wc_booking_resource_cost':
349
-
350
- $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
351
-
352
- if ( isset( $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
353
- $value = $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ];
354
- } else {
355
- $value = '';
356
- }
357
-
358
- echo '<div class="wcml_bookings_resource_block" >';
359
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
360
- 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" />';
361
- echo '</div>';
362
- break;
363
-
364
- case 'wcml_wc_booking_resource_block_cost':
365
-
366
- $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
367
-
368
- if ( isset( $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
369
- $value = $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ];
370
- } else {
371
- $value = '';
372
- }
373
-
374
- echo '<div class="wcml_bookings_resource_block" >';
375
- echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
376
- 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" />';
377
- echo '</div>';
378
- break;
379
-
380
- default:
381
- break;
382
-
383
- }
384
-
385
- }
386
-
387
- echo '</div>';
388
-
389
- }
390
- }
391
-
392
- function after_bookings_pricing( $post_id ) {
393
-
394
-
395
- 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 ) {
396
-
397
- $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
398
-
399
- $checked = ! $custom_costs_status ? 'checked="checked"' : ' ';
400
-
401
- echo '<div class="wcml_custom_costs">';
402
-
403
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" ' . $checked . ' />';
404
- echo '<label for="wcml_custom_costs_auto">' . __( 'Calculate costs in other currencies automatically', 'woocommerce-multilingual' ) . '</label>';
405
-
406
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
407
-
408
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" ' . $checked . ' />';
409
- echo '<label for="wcml_custom_costs_manually">' . __( 'Set costs in other currencies manually', 'woocommerce-multilingual' ) . '</label>';
410
-
411
- wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
412
-
413
- echo '</div>';
414
- }
415
-
416
- }
417
-
418
- function save_custom_costs( $post_id ) {
419
- $nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
420
-
421
- if ( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
422
-
423
- update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
424
-
425
- if ( 1 === (int) $_POST['_wcml_custom_costs'] ) {
426
-
427
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
428
- if ( empty( $currencies ) || 0 === $post_id ) {
429
- return false;
430
- }
431
-
432
- $this->update_booking_costs( $currencies, $post_id );
433
- $this->update_booking_pricing( $currencies, $post_id );
434
-
435
-
436
- if ( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
437
- $this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
438
- }
439
-
440
- if ( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
441
- $this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
442
- }
443
-
444
- if ( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
445
- $this->update_booking_resource_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_cost'] );
446
- }
447
-
448
- if ( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
449
- $this->update_booking_resource_block_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_block_cost'] );
450
- }
451
-
452
- update_post_meta( $post_id, '_price', '' );
453
- } else {
454
- return false;
455
- }
456
- }
457
-
458
- }
459
-
460
- // sync existing product bookings for translations
461
- function sync_bookings( $original_product_id, $product_id, $lang ) {
462
- $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 ) );
463
-
464
- foreach ( $all_bookings_for_product as $booking ) {
465
- $check_if_exists = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT pm3.* FROM {$this->wpdb->postmeta} AS pm1
466
- LEFT JOIN {$this->wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
467
- LEFT JOIN {$this->wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
468
- 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'"
469
- , $booking->id, $lang ) );
470
-
471
- if ( is_null( $check_if_exists ) ) {
472
- $this->duplicate_booking_for_translations( $booking->id, $lang );
473
- } elseif ( '' === $check_if_exists->meta_value ) {
474
- update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
475
- update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
476
- update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
477
- }
478
- }
479
- }
480
-
481
- function sync_booking_data( $original_product_id, $current_product_id ) {
482
-
483
- if ( has_term( 'booking', 'product_type', $original_product_id ) ) {
484
- global $pagenow, $iclTranslationManagement;
485
-
486
- // get language code
487
- $language_details = $this->sitepress->get_element_language_details( $original_product_id, 'post_product' );
488
- if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
489
- //translation editor support: sidestep icl_translations_cache
490
- $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 ) );
491
- }
492
- if ( empty( $language_details ) ) {
493
- return;
494
- }
495
-
496
- // pick posts to sync
497
- $posts = array();
498
- $translations = $this->sitepress->get_element_translations( $language_details->trid, 'post_product' );
499
- foreach ( $translations as $translation ) {
500
-
501
- if ( ! $translation->original ) {
502
- $posts[ $translation->element_id ] = $translation;
503
- }
504
- }
505
-
506
- foreach ( $posts as $post_id => $translation ) {
507
-
508
- $trn_lang = $this->sitepress->get_language_for_element( $post_id, 'post_product' );
509
-
510
- //sync_resources
511
- $this->sync_resources( $original_product_id, $post_id, $trn_lang );
512
-
513
- //sync_persons
514
- $this->sync_persons( $original_product_id, $post_id, $trn_lang );
515
- }
516
-
517
- }
518
-
519
- }
520
-
521
- function sync_resources( $original_product_id, $translated_product_id, $lang_code, $duplicate = true ) {
522
-
523
- $original_resources = $this->wpdb->get_results( $this->wpdb->prepare(
524
- "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
525
- $original_product_id ) );
526
-
527
- $translated_resources = $this->wpdb->get_col( $this->wpdb->prepare(
528
- "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
529
- $translated_product_id ) );
530
-
531
- $used_translated_resources = array();
532
-
533
- foreach ( $original_resources as $resource ) {
534
-
535
- $translated_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
536
- if ( ! is_null( $translated_resource_id ) ) {
537
-
538
- if ( in_array( $translated_resource_id, $translated_resources ) ) {
539
- $this->update_product_resource( $translated_product_id, $translated_resource_id, $resource );
540
- } else {
541
- $this->add_product_resource( $translated_product_id, $translated_resource_id, $resource );
542
- }
543
- $used_translated_resources[] = $translated_resource_id;
544
- } else {
545
- if ( $duplicate ) {
546
- $this->duplicate_resource( $translated_product_id, $resource, $lang_code );
547
- }
548
- }
549
-
550
- }
551
-
552
- $removed_translated_resources_id = array_diff( $translated_resources, $used_translated_resources );
553
- foreach ( $removed_translated_resources_id as $resource_id ) {
554
- $this->remove_resource_from_product( $translated_product_id, $resource_id );
555
- }
556
-
557
- $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_base_costs', $lang_code );
558
- $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_block_costs', $lang_code );
559
-
560
- }
561
-
562
- function duplicate_resource( $tr_product_id, $resource, $lang_code ) {
563
- global $iclTranslationManagement;
564
-
565
- if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
566
-
567
- $trns_resource_id = $this->sitepress->make_duplicate( $resource->resource_id, $lang_code );
568
-
569
- } else {
570
-
571
- if ( ! isset( $iclTranslationManagement ) ) {
572
- $iclTranslationManagement = new TranslationManagement;
573
- }
574
-
575
- $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
576
-
577
- }
578
-
579
- $this->wpdb->insert(
580
- $this->wpdb->prefix . 'wc_booking_relationships',
581
- array(
582
- 'product_id' => $tr_product_id,
583
- 'resource_id' => $trns_resource_id,
584
- 'sort_order' => $resource->sort_order
585
- )
586
- );
587
-
588
- delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
589
-
590
- return $trns_resource_id;
591
- }
592
-
593
- public function add_product_resource( $product_id, $resource_id, $resource_data ) {
594
-
595
- $this->wpdb->insert(
596
- $this->wpdb->prefix . 'wc_booking_relationships',
597
- array(
598
- 'sort_order' => $resource_data->sort_order,
599
- 'product_id' => $product_id,
600
- 'resource_id' => $resource_id
601
- )
602
- );
603
-
604
- update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
605
- update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
606
-
607
- }
608
-
609
- public function remove_resource_from_product( $product_id, $resource_id ) {
610
-
611
- $this->wpdb->delete(
612
- $this->wpdb->prefix . 'wc_booking_relationships',
613
- array(
614
- 'product_id' => $product_id,
615
- 'resource_id' => $resource_id
616
- )
617
- );
618
-
619
- }
620
-
621
- public function update_product_resource( $product_id, $resource_id, $resource_data ) {
622
-
623
- $this->wpdb->update(
624
- $this->wpdb->prefix . 'wc_booking_relationships',
625
- array(
626
- 'sort_order' => $resource_data->sort_order
627
- ),
628
- array(
629
- 'product_id' => $product_id,
630
- 'resource_id' => $resource_id
631
- )
632
- );
633
-
634
- update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
635
- update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
636
-
637
-
638
- }
639
-
640
- function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ) {
641
- $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 ) );
642
-
643
- $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 ) );
644
-
645
-
646
- foreach ( $orig_persons as $person ) {
647
-
648
- $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
649
-
650
- if ( ! is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
651
-
652
- if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
653
-
654
- unset( $trnsl_persons[ $key ] );
655
-
656
- update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
657
- update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
658
- update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
659
- update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
660
-
661
-
662
- if ( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
663
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
664
-
665
- foreach ( $currencies as $code => $currency ) {
666
-
667
- update_post_meta( $trnsl_person_id, 'block_cost_' . $code, get_post_meta( $person, 'block_cost_' . $code, true ) );
668
- update_post_meta( $trnsl_person_id, 'cost_' . $code, get_post_meta( $person, 'cost_' . $code, true ) );
669
-
670
- }
671
- }
672
-
673
- }
674
-
675
- } else {
676
-
677
- if ( $duplicate ) {
678
-
679
- $this->duplicate_person( $tr_product_id, $person, $lang_code );
680
-
681
- } else {
682
-
683
- continue;
684
-
685
- }
686
-
687
- }
688
-
689
- }
690
-
691
- foreach ( $trnsl_persons as $trnsl_person ) {
692
-
693
- wp_delete_post( $trnsl_person );
694
-
695
- }
696
-
697
- }
698
-
699
- function duplicate_person( $tr_product_id, $person_id, $lang_code ) {
700
- global $iclTranslationManagement;
701
-
702
- if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
703
-
704
- $new_person_id = $this->sitepress->make_duplicate( $person_id, $lang_code );
705
-
706
- } else {
707
-
708
- if ( ! isset( $iclTranslationManagement ) ) {
709
- $iclTranslationManagement = new TranslationManagement;
710
- }
711
-
712
- $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
713
-
714
- }
715
-
716
- $this->wpdb->update(
717
- $this->wpdb->posts,
718
- array(
719
- 'post_parent' => $tr_product_id
720
- ),
721
- array(
722
- 'ID' => $new_person_id
723
- )
724
- );
725
-
726
- delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
727
-
728
- return $new_person_id;
729
- }
730
-
731
- function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ) {
732
-
733
- if ( in_array( $meta_key, array(
734
- '_wc_booking_cost',
735
- '_wc_booking_base_cost',
736
- '_wc_display_cost',
737
- '_wc_booking_pricing',
738
- 'cost',
739
- 'block_cost',
740
- '_resource_base_costs',
741
- '_resource_block_costs'
742
- ) ) ) {
743
-
744
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
745
-
746
- $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
747
-
748
- $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
749
-
750
- $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
751
-
752
- if ( $currency == get_option( 'woocommerce_currency' ) ) {
753
- return $check;
754
- }
755
-
756
- if ( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
757
-
758
- if ( get_post_type( $object_id ) == 'bookable_person' ) {
759
-
760
- $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 ) ) );
761
- $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
762
-
763
- $value = get_post_meta( $object_id, $meta_key . '_' . $currency, true );
764
-
765
- if ( $cost_status && $value ) {
766
-
767
- return $value;
768
-
769
- } else {
770
-
771
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
772
-
773
- $cost = get_post_meta( $object_id, $meta_key, true );
774
-
775
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
776
-
777
- return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
778
- }
779
-
780
- } else {
781
-
782
- return $check;
783
-
784
- }
785
-
786
- }
787
-
788
- if ( in_array( $meta_key, array(
789
- '_wc_booking_pricing',
790
- '_resource_base_costs',
791
- '_resource_block_costs'
792
- ) ) ) {
793
-
794
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
795
-
796
- if ( $meta_key == '_wc_booking_pricing' ) {
797
-
798
- if ( $original_id != $object_id ) {
799
- $value = get_post_meta( $original_id, $meta_key );
800
- } else {
801
- $value = $check;
802
- }
803
-
804
- } else {
805
-
806
- $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
807
-
808
- if ( ! $costs ) {
809
- $value = $check;
810
- } elseif ( $cost_status && isset( $costs['custom_costs'][ $currency ] ) ) {
811
-
812
- $res_costs = array();
813
- foreach ( $costs['custom_costs'][ $currency ] as $resource_id => $cost ) {
814
- $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $this->sitepress->get_current_language() );
815
- $res_costs[ $trns_resource_id ] = $cost;
816
- }
817
- $value = array( 0 => $res_costs );
818
- } elseif ( $cost_status && isset( $costs[0]['custom_costs'][ $currency ] ) ) {
819
- $value = array( 0 => $costs[0]['custom_costs'][ $currency ] );
820
- } else {
821
-
822
- $converted_values = array();
823
-
824
- foreach ( $costs as $resource_id => $cost ) {
825
- $converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
826
- }
827
-
828
- $value = $converted_values;
829
- }
830
-
831
- }
832
-
833
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
834
-
835
- return $value;
836
-
837
- }
838
-
839
- $value = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
840
-
841
- if ( $cost_status && ( ! empty( $value ) || ( empty( $value ) && $meta_key == '_wc_display_cost' ) ) ) {
842
-
843
- return $value;
844
-
845
- } else {
846
-
847
- remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
848
-
849
- $value = get_post_meta( $original_id, $meta_key, true );
850
-
851
- $value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
852
-
853
- add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
854
-
855
- return $value;
856
-
857
- }
858
-
859
- }
860
-
861
- }
862
-
863
- return $check;
864
- }
865
-
866
- function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ) {
867
-
868
-
869
- $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
870
-
871
- if ( $object_id == $original_product_id ) {
872
-
873
- $trid = $this->sitepress->get_element_trid( $object_id, 'post_product' );
874
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
875
-
876
- foreach ( $translations as $translation ) {
877
-
878
- if ( ! $translation->original ) {
879
-
880
- $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
881
-
882
- }
883
- }
884
-
885
- return $check;
886
-
887
- } else {
888
-
889
- $language_code = $this->sitepress->get_language_for_element( $object_id, 'post_product' );
890
-
891
- $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
892
-
893
- return true;
894
-
895
- }
896
-
897
- }
898
-
899
- function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ) {
900
-
901
- $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
902
-
903
- $wc_booking_resource_costs = array();
904
- if ( ! empty( $original_costs ) ) {
905
- foreach ( $original_costs as $resource_id => $costs ) {
906
-
907
- if ( $resource_id == 'custom_costs' && isset( $costs['custom_costs'] ) ) {
908
-
909
- foreach ( $costs['custom_costs'] as $code => $currencies ) {
910
-
911
- foreach ( $currencies as $custom_costs_resource_id => $custom_cost ) {
912
-
913
- $trns_resource_id = apply_filters( 'translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code );
914
-
915
- $wc_booking_resource_costs['custom_costs'][ $code ][ $trns_resource_id ] = $custom_cost;
916
-
917
- }
918
-
919
- }
920
-
921
- } else {
922
-
923
- $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $language_code );
924
-
925
- $wc_booking_resource_costs[ $trns_resource_id ] = $costs;
926
-
927
- }
928
-
929
- }
930
- }
931
-
932
- update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
933
-
934
- }
935
-
936
- function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ) {
937
- return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
938
- }
939
-
940
- function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ) {
941
- return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
942
- }
943
-
944
- function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ) {
945
- return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
946
- }
947
-
948
- function filter_pricing_cost( $cost, $fields, $name, $key ) {
949
- global $product;
950
-
951
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
952
-
953
- $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
954
-
955
- if ( $currency == get_option( 'woocommerce_currency' ) ) {
956
- return $cost;
957
- }
958
-
959
- if ( isset( $_POST['form'] ) ) {
960
- parse_str( $_POST['form'], $posted );
961
-
962
- $booking_id = $posted['add-to-cart'];
963
-
964
- } elseif ( isset( $_POST['add-to-cart'] ) ) {
965
-
966
- $booking_id = $_POST['add-to-cart'];
967
-
968
- }
969
-
970
- if ( isset( $booking_id ) ) {
971
- $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $booking_id ) );
972
-
973
- if ( $booking_id != $original_id ) {
974
- $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
975
- $fields = $fields[ $key ];
976
- }
977
- }
978
-
979
- if ( isset( $fields[ $name . $currency ] ) ) {
980
- return $fields[ $name . $currency ];
981
- } else {
982
- return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
983
- }
984
-
985
- }
986
-
987
- return $cost;
988
-
989
- }
990
-
991
- function load_assets( $external_product_type = false ) {
992
- global $pagenow;
993
-
994
- $product = $pagenow == 'post.php' && isset( $_GET['post'] ) ? wc_get_product( $_GET['post'] ) : false;
995
-
996
- if ( ( $product && ( $product->product_type == 'booking' || $product->product_type == $external_product_type ) ) || $pagenow == 'post-new.php' ) {
997
-
998
- wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
999
- wp_enqueue_style( 'wcml-bookings-css' );
1000
-
1001
- wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
1002
- wp_enqueue_script( 'wcml-bookings-js' );
1003
-
1004
- }
1005
-
1006
- }
1007
-
1008
- function localize_lock_fields_js() {
1009
- wp_localize_script( 'wcml-bookings-js', 'lock_settings', array( 'lock_fields' => 1 ) );
1010
- }
1011
-
1012
- function wcml_multi_currency_is_ajax( $actions ) {
1013
-
1014
- $actions[] = 'wc_bookings_calculate_costs';
1015
-
1016
- return $actions;
1017
- }
1018
-
1019
- function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ) {
1020
-
1021
- if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['booking'] ) ) {
1022
-
1023
-
1024
- $current_id = apply_filters( 'translate_object_id', $cart_item['data']->id, 'product', true, $current_language );
1025
- $cart_product_id = $cart_item['data']->id;
1026
-
1027
- if ( $current_id != $cart_product_id ) {
1028
-
1029
- $cart_item['data'] = new WC_Product_Booking( $current_id );
1030
-
1031
- }
1032
-
1033
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ) {
1034
-
1035
- $booking_info = array(
1036
- 'wc_bookings_field_start_date_year' => $cart_item['booking']['_year'],
1037
- 'wc_bookings_field_start_date_month' => $cart_item['booking']['_month'],
1038
- 'wc_bookings_field_start_date_day' => $cart_item['booking']['_day'],
1039
- 'add-to-cart' => $current_id
1040
- );
1041
-
1042
- if ( isset( $cart_item['booking']['_persons'] ) ) {
1043
- foreach ( $cart_item['booking']['_persons'] as $person_id => $value ) {
1044
- $booking_info[ 'wc_bookings_field_persons_' . apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $current_language ) ] = $value;
1045
- }
1046
- }
1047
-
1048
- if ( isset( $cart_item['booking']['_resource_id'] ) ) {
1049
- $booking_info['wc_bookings_field_resource'] = apply_filters( 'translate_object_id', $cart_item['booking']['_resource_id'], 'bookable_resource', false, $current_language );
1050
- }
1051
-
1052
- if ( isset( $cart_item['booking']['_duration'] ) ) {
1053
- $booking_info['wc_bookings_field_duration'] = $cart_item['booking']['_duration'];
1054
- }
1055
-
1056
- if ( isset( $cart_item['booking']['_time'] ) ) {
1057
- $booking_info['wc_bookings_field_start_date_time'] = $cart_item['booking']['_time'];
1058
- }
1059
-
1060
- $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1061
-
1062
- $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
1063
- update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item['booking']['_qty'] ) );
1064
- $cost = $booking_form->calculate_booking_cost( $booking_info );
1065
- update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
1066
-
1067
- if ( ! is_wp_error( $cost ) ) {
1068
- $cart_item['data']->set_price( $cost );
1069
- }
1070
- }
1071
-
1072
- }
1073
-
1074
- return $cart_item;
1075
-
1076
- }
1077
-
1078
- function booking_currency_dropdown() {
1079
-
1080
-
1081
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1082
- $current_booking_currency = $this->get_cookie_booking_currency();
1083
-
1084
- $wc_currencies = get_woocommerce_currencies();
1085
- $currencies = $this->woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
1086
- ?>
1087
- <tr valign="top">
1088
- <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
1089
- <td>
1090
- <select id="dropdown_booking_currency">
1091
-
1092
- <?php foreach ( $currencies as $currency => $count ): ?>
1093
-
1094
- <option
1095
- value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo $wc_currencies[ $currency ]; ?></option>
1096
-
1097
- <?php endforeach; ?>
1098
-
1099
- </select>
1100
- </td>
1101
- </tr>
1102
-
1103
- <?php
1104
-
1105
- $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
1106
-
1107
- wc_enqueue_js( "
1108
-
1109
- jQuery(document).on('change', '#dropdown_booking_currency', function(){
1110
- jQuery.ajax({
1111
- url: ajaxurl,
1112
- type: 'post',
1113
- data: {
1114
- action: 'wcml_booking_set_currency',
1115
- currency: jQuery('#dropdown_booking_currency').val(),
1116
- wcml_nonce: '" . $wcml_booking_set_currency_nonce . "'
1117
- },
1118
- success: function( response ){
1119
- if(typeof response.error !== 'undefined'){
1120
- alert(response.error);
1121
- }else{
1122
- window.location = window.location.href;
1123
- }
1124
- }
1125
- })
1126
- });
1127
- " );
1128
-
1129
- }
1130
-
1131
- }
1132
-
1133
- function set_booking_currency_ajax() {
1134
-
1135
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1136
- if ( ! $nonce || ! wp_verify_nonce( $nonce, 'booking_set_currency' ) ) {
1137
- echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
1138
- die();
1139
- }
1140
-
1141
- $this->set_booking_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
1142
-
1143
- die();
1144
- }
1145
-
1146
- function set_booking_currency( $currency_code = false ) {
1147
-
1148
- if ( ! isset( $_COOKIE ['_wcml_booking_currency'] ) && ! headers_sent() ) {
1149
-
1150
-
1151
- $currency_code = get_woocommerce_currency();
1152
-
1153
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1154
- $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
1155
-
1156
- if ( ! isset( $order_currencies[ $currency_code ] ) ) {
1157
- foreach ( $order_currencies as $currency_code => $count ) {
1158
- $currency_code = $currency_code;
1159
- break;
1160
- }
1161
- }
1162
- }
1163
- }
1164
-
1165
- if ( $currency_code ) {
1166
- setcookie( '_wcml_booking_currency', $currency_code, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
1167
- }
1168
-
1169
- }
1170
-
1171
- function get_cookie_booking_currency() {
1172
-
1173
- if ( isset( $_COOKIE ['_wcml_booking_currency'] ) ) {
1174
- $currency = $_COOKIE['_wcml_booking_currency'];
1175
- } else {
1176
- $currency = get_woocommerce_currency();
1177
- }
1178
-
1179
- return $currency;
1180
- }
1181
-
1182
- function filter_booking_currency_symbol( $currency ) {
1183
- global $pagenow;
1184
-
1185
- remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1186
- if ( isset( $_COOKIE ['_wcml_booking_currency'] ) && $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) {
1187
- $currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_booking_currency'] );
1188
- }
1189
- add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1190
-
1191
- return $currency;
1192
- }
1193
-
1194
- function create_booking_page_client_currency( $currency ) {
1195
- global $pagenow;
1196
-
1197
- if ( wpml_is_ajax() && isset( $_POST['form'] ) ) {
1198
- parse_str( $_POST['form'], $posted );
1199
- }
1200
-
1201
- 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 ) ) {
1202
- $currency = $this->get_cookie_booking_currency();
1203
- }
1204
-
1205
- return $currency;
1206
- }
1207
-
1208
- function set_order_currency_on_create_booking_page( $order_id ) {
1209
- update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1210
-
1211
- update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
1212
-
1213
- }
1214
-
1215
- function filter_get_booking_products_args( $args ) {
1216
- if ( isset( $args['suppress_filters'] ) ) {
1217
- $args['suppress_filters'] = false;
1218
- }
1219
-
1220
- return $args;
1221
- }
1222
-
1223
- function custom_box_html( $obj, $product_id, $data ) {
1224
- if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1225
- return;
1226
- }
1227
-
1228
- $bookings_section = new WPML_Editor_UI_Field_Section( __( 'Bookings', 'woocommerce-multilingual' ) );
1229
-
1230
- if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1231
- $group = new WPML_Editor_UI_Field_Group( '', true );
1232
- $booking_field = new WPML_Editor_UI_Single_Line_Field( '_wc_booking_resouce_label', __( 'Resources Label', 'woocommerce-multilingual' ), $data, true );
1233
- $group->add_field( $booking_field );
1234
- $bookings_section->add_field( $group );
1235
- }
1236
-
1237
- $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1238
-
1239
- if ( $orig_resources ) {
1240
- $group = new WPML_Editor_UI_Field_Group( __( 'Resources', 'woocommerce-multilingual' ) );
1241
- $group_title = __( 'Resources', 'woocommerce-multilingual' );
1242
- foreach ( $orig_resources as $resource_id => $cost ) {
1243
-
1244
- if ( $resource_id == 'custom_costs' ) {
1245
- continue;
1246
- }
1247
-
1248
- $group = new WPML_Editor_UI_Field_Group( $group_title );
1249
- $group_title = '';
1250
-
1251
- $resource_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-resource_' . $resource_id . '_title', __( 'Title', 'woocommerce-multilingual' ), $data, true );
1252
- $group->add_field( $resource_field );
1253
- $bookings_section->add_field( $group );
1254
- }
1255
-
1256
- }
1257
-
1258
- $original_persons = $this->get_original_persons( $product_id );
1259
- end( $original_persons );
1260
- $last_key = key( $original_persons );
1261
- $divider = true;
1262
- $group_title = __( 'Person Types', 'woocommerce-multilingual' );
1263
- foreach ( $original_persons as $person_id ) {
1264
- if ( $person_id == $last_key ) {
1265
- $divider = false;
1266
- }
1267
- $group = new WPML_Editor_UI_Field_Group( $group_title, $divider );
1268
- $group_title = '';
1269
-
1270
- $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_title', __( 'Person Type Name', 'woocommerce-multilingual' ), $data, false );
1271
- $group->add_field( $person_field );
1272
- $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
1273
- $group->add_field( $person_field );
1274
- $bookings_section->add_field( $group );
1275
-
1276
- }
1277
-
1278
- if ( $orig_resources || $original_persons ) {
1279
- $obj->add_field( $bookings_section );
1280
- }
1281
-
1282
- }
1283
-
1284
-
1285
- function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1286
-
1287
- if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1288
- return $data;
1289
- }
1290
-
1291
- if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1292
-
1293
- $data['_wc_booking_resouce_label'] = array( 'original' => get_post_meta( $product_id, '_wc_booking_resouce_label', true ) );
1294
- $data['_wc_booking_resouce_label']['translation'] = $translation ? get_post_meta( $translation->ID, '_wc_booking_resouce_label', true ) : '';
1295
- }
1296
-
1297
- $orig_resources = $this->get_original_resources( $product_id );
1298
-
1299
- if ( $orig_resources && is_array( $orig_resources ) ) {
1300
-
1301
- foreach ( $orig_resources as $resource_id => $cost ) {
1302
-
1303
- if ( 'custom_costs' === $resource_id ) {
1304
- continue;
1305
- }
1306
- $data[ 'bookings-resource_' . $resource_id . '_title' ] = array( 'original' => get_the_title( $resource_id ) );
1307
- global $sitepress;
1308
- $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $lang );
1309
- $data[ 'bookings-resource_' . $resource_id . '_title' ]['translation'] = $trns_resource_id ? get_the_title( $trns_resource_id ) : '';
1310
- }
1311
- }
1312
-
1313
- $original_persons = $this->get_original_persons( $product_id );
1314
-
1315
- foreach ( $original_persons as $person_id ) {
1316
-
1317
- $data[ 'bookings-person_' . $person_id . '_title' ] = array( 'original' => get_the_title( $person_id ) );
1318
- $data[ 'bookings-person_' . $person_id . '_description' ] = array( 'original' => get_post( $person_id )->post_excerpt );
1319
-
1320
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $lang );
1321
- $data[ 'bookings-person_' . $person_id . '_title' ]['translation'] = $trnsl_person_id ? get_the_title( $trnsl_person_id ) : '';
1322
- $data[ 'bookings-person_' . $person_id . '_description' ]['translation'] = $trnsl_person_id ? get_post( $trnsl_person_id )->post_excerpt : '';
1323
-
1324
- }
1325
-
1326
- return $data;
1327
- }
1328
-
1329
-
1330
- function get_original_resources( $product_id ) {
1331
- $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1332
-
1333
- return $orig_resources;
1334
- }
1335
-
1336
- function get_original_persons( $product_id ) {
1337
- $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 ) );
1338
-
1339
- return $original_persons;
1340
- }
1341
-
1342
- function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ) {
1343
- if ( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ) {
1344
- return false;
1345
- }
1346
-
1347
- return $check;
1348
- }
1349
-
1350
- function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ) {
1351
- if ( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ) {
1352
- $exception = true;
1353
- }
1354
-
1355
- return $exception;
1356
- }
1357
-
1358
- function remove_single_custom_fields_to_translate( $fields ) {
1359
- $fields[] = '_wc_booking_resouce_label';
1360
-
1361
- return $fields;
1362
- }
1363
-
1364
- function product_content_resource_label( $meta_key, $product_id ) {
1365
- if ( $meta_key == '_wc_booking_resouce_label' ) {
1366
- return __( 'Resources label', 'woocommerce-multilingual' );
1367
- }
1368
-
1369
- return $meta_key;
1370
- }
1371
-
1372
- function wcml_products_tab_sync_resources_and_persons( $original_product_id, $tr_product_id, $data, $language ) {
1373
- global $wpml_post_translations;
1374
-
1375
- remove_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1376
-
1377
- $orig_resources = $orig_resources = $this->get_original_resources( $original_product_id );;
1378
-
1379
- if ( $orig_resources ) {
1380
-
1381
- foreach ( $orig_resources as $orig_resource_id => $cost ) {
1382
-
1383
- $resource_id = apply_filters( 'translate_object_id', $orig_resource_id, 'bookable_resource', false, $language );
1384
- $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 );
1385
-
1386
- if ( is_null( $resource_id ) ) {
1387
-
1388
- if ( $orig_resource ) {
1389
- $resource_id = $this->duplicate_resource( $tr_product_id, $orig_resource, $language );
1390
- } else {
1391
- continue;
1392
- }
1393
-
1394
- } else {
1395
- //update_relationship
1396
-
1397
- $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 ) );
1398
-
1399
- if ( ! $exist ) {
1400
-
1401
- $this->wpdb->insert(
1402
- $this->wpdb->prefix . 'wc_booking_relationships',
1403
- array(
1404
- 'product_id' => $tr_product_id,
1405
- 'resource_id' => $resource_id,
1406
- 'sort_order' => $orig_resource->sort_order
1407
- )
1408
- );
1409
-
1410
- }
1411
-
1412
- }
1413
-
1414
-
1415
- $this->wpdb->update(
1416
- $this->wpdb->posts,
1417
- array(
1418
- 'post_title' => $data[ md5( 'bookings-resource_' . $orig_resource_id . '_title' ) ]
1419
- ),
1420
- array(
1421
- 'ID' => $resource_id
1422
- )
1423
- );
1424
-
1425
- update_post_meta( $resource_id, 'wcml_is_translated', true );
1426
-
1427
- }
1428
-
1429
- //sync resources data
1430
- $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1431
-
1432
- }
1433
-
1434
- $original_persons = $this->get_original_persons( $original_product_id );
1435
-
1436
- //sync persons
1437
- if ( $original_persons ) {
1438
-
1439
- foreach ( $original_persons as $original_person_id ) {
1440
-
1441
- $person_id = apply_filters( 'translate_object_id', $original_person_id, 'bookable_person', false, $language );
1442
-
1443
- if ( is_null( $person_id ) ) {
1444
-
1445
- $person_id = $this->duplicate_person( $tr_product_id, $original_person_id, $language );
1446
-
1447
- } else {
1448
-
1449
- $this->wpdb->update(
1450
- $this->wpdb->posts,
1451
- array(
1452
- 'post_parent' => $tr_product_id
1453
- ),
1454
- array(
1455
- 'ID' => $person_id
1456
- )
1457
- );
1458
-
1459
- }
1460
-
1461
- $this->wpdb->update(
1462
- $this->wpdb->posts,
1463
- array(
1464
- 'post_title' => $data[ md5( 'bookings-person_' . $original_person_id . '_title' ) ],
1465
- 'post_excerpt' => $data[ md5( 'bookings-person_' . $original_person_id . '_description' ) ],
1466
- ),
1467
- array(
1468
- 'ID' => $person_id
1469
- )
1470
- );
1471
-
1472
- update_post_meta( $person_id, 'wcml_is_translated', true );
1473
-
1474
- }
1475
-
1476
- //sync persons data
1477
- $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1478
-
1479
- }
1480
-
1481
- add_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1482
-
1483
- }
1484
-
1485
- function duplicate_booking_for_translations( $booking_id, $lang = false ) {
1486
- $booking_object = get_post( $booking_id );
1487
-
1488
- $booking_data = array(
1489
- 'post_type' => 'wc_booking',
1490
- 'post_title' => $booking_object->post_title,
1491
- 'post_status' => $booking_object->post_status,
1492
- 'ping_status' => 'closed',
1493
- 'post_parent' => $booking_object->post_parent,
1494
- );
1495
-
1496
- $active_languages = $this->sitepress->get_active_languages();
1497
-
1498
- foreach ( $active_languages as $language ) {
1499
-
1500
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1501
-
1502
- if ( ! $lang ) {
1503
- $booking_language = $this->sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1504
- if ( $booking_language->language_code == $language['code'] ) {
1505
- continue;
1506
- }
1507
- } elseif ( $lang != $language['code'] ) {
1508
- continue;
1509
- }
1510
-
1511
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1512
- $trnsl_booking_persons = array();
1513
-
1514
- if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1515
- foreach ( $booking_persons as $person_id => $person_count ) {
1516
-
1517
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1518
-
1519
- if ( is_null( $trnsl_person_id ) ) {
1520
- $trnsl_booking_persons[] = $person_count;
1521
- } else {
1522
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1523
- }
1524
-
1525
- }
1526
- }
1527
-
1528
- $trnsl_booking_id = wp_insert_post( $booking_data );
1529
- $trid = $this->sitepress->get_element_trid( $booking_id );
1530
- $this->sitepress->set_element_language_details( $trnsl_booking_id, 'post_wc_booking', $trid, $language['code'] );
1531
-
1532
- $meta_args = array(
1533
- '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1534
- '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1535
- '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1536
- '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1537
- '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1538
- '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1539
- '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1540
- '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1541
- '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1542
- '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1543
- '_booking_duplicate_of' => $booking_id,
1544
- '_language_code' => $language['code'],
1545
- );
1546
-
1547
- foreach ( $meta_args as $key => $value ) {
1548
- update_post_meta( $trnsl_booking_id, $key, $value );
1549
- }
1550
-
1551
- WC_Cache_Helper::get_transient_version( 'bookings', true );
1552
-
1553
- }
1554
-
1555
-
1556
- }
1557
-
1558
- function get_translated_booking_product_id( $booking_id, $language ) {
1559
-
1560
- $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1561
- $trnsl_booking_product_id = '';
1562
-
1563
- if ( $booking_product_id ) {
1564
- $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1565
- if ( is_null( $trnsl_booking_product_id ) ) {
1566
- $trnsl_booking_product_id = '';
1567
- }
1568
- }
1569
-
1570
- return $trnsl_booking_product_id;
1571
-
1572
- }
1573
-
1574
- function get_translated_booking_resource_id( $booking_id, $language ) {
1575
-
1576
- $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1577
- $trnsl_booking_resource_id = '';
1578
-
1579
- if ( $booking_resource_id ) {
1580
- $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1581
-
1582
- if ( is_null( $trnsl_booking_resource_id ) ) {
1583
- $trnsl_booking_resource_id = '';
1584
- }
1585
- }
1586
-
1587
- return $trnsl_booking_resource_id;
1588
- }
1589
-
1590
- function get_translated_booking_persons_ids( $booking_id, $language ) {
1591
-
1592
- $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1593
- $trnsl_booking_persons = array();
1594
-
1595
- if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1596
- foreach ( $booking_persons as $person_id => $person_count ) {
1597
-
1598
- $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1599
-
1600
- if ( is_null( $trnsl_person_id ) ) {
1601
- $trnsl_booking_persons[] = $person_count;
1602
- } else {
1603
- $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1604
- }
1605
-
1606
- }
1607
- }
1608
-
1609
- return $trnsl_booking_persons;
1610
-
1611
- }
1612
-
1613
- function update_status_for_translations( $booking_id ) {
1614
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1615
-
1616
- foreach ( $translated_bookings as $booking ) {
1617
-
1618
- $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 );
1619
- $language = get_post_meta( $booking->post_id, '_language_code', true );
1620
-
1621
- $this->wpdb->update(
1622
- $this->wpdb->posts,
1623
- array(
1624
- 'post_status' => $status,
1625
- 'post_parent' => wp_get_post_parent_id( $booking_id ),
1626
- ),
1627
- array(
1628
- 'ID' => $booking->post_id
1629
- )
1630
- );
1631
-
1632
- update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1633
- update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1634
- update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1635
-
1636
- }
1637
-
1638
- }
1639
-
1640
- function get_translated_bookings( $booking_id ) {
1641
- $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 ) );
1642
-
1643
- return $translated_bookings;
1644
- }
1645
-
1646
- public function booking_filters_query( $query ) {
1647
- global $typenow;
1648
-
1649
- if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1650
-
1651
- $current_lang = $this->sitepress->get_current_language();
1652
-
1653
- $product_ids = $this->wpdb->get_col( $this->wpdb->prepare(
1654
- "SELECT element_id
1655
- FROM {$this->wpdb->prefix}icl_translations
1656
- WHERE language_code = %s AND element_type = 'post_product'", $current_lang ) );
1657
-
1658
- $product_ids = array_diff( $product_ids, array( null ) );
1659
-
1660
- if ( ( ! isset( $_GET['lang'] ) || ( isset( $_GET['lang'] ) && $_GET['lang'] != 'all' ) ) ) {
1661
- $query->query_vars['meta_query'][] = array(
1662
- 'relation' => 'OR',
1663
- array(
1664
- 'key' => '_language_code',
1665
- 'value' => $current_lang,
1666
- 'compare ' => '='
1667
- ),
1668
- array(
1669
- 'key' => '_booking_product_id',
1670
- 'value' => $product_ids,
1671
- 'compare ' => 'IN'
1672
- )
1673
- );
1674
- }
1675
- }
1676
-
1677
- return $query;
1678
- }
1679
-
1680
- function bookings_in_date_range_query( $booking_ids ) {
1681
- foreach ( $booking_ids as $key => $booking_id ) {
1682
-
1683
- $language_code = $this->sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ), 'post_product' );
1684
- $current_language = $this->sitepress->get_current_language();
1685
-
1686
- if ( $language_code != $current_language ) {
1687
- unset( $booking_ids[ $key ] );
1688
- }
1689
-
1690
- }
1691
-
1692
- return $booking_ids;
1693
-
1694
- }
1695
-
1696
- function clear_transient_fields() {
1697
-
1698
- if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1699
-
1700
- //delete transient fields
1701
- $this->wpdb->query( "
1702
- DELETE FROM {$this->wpdb->options}
1703
- WHERE option_name LIKE '%book_dr_%'
1704
- " );
1705
-
1706
- }
1707
-
1708
- }
1709
-
1710
- function delete_bookings( $booking_id ) {
1711
-
1712
- if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1713
-
1714
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1715
-
1716
- remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1717
-
1718
- foreach ( $translated_bookings as $booking ) {
1719
- $this->wpdb->update(
1720
- $this->wpdb->posts,
1721
- array(
1722
- 'post_parent' => 0
1723
- ),
1724
- array(
1725
- 'ID' => $booking->post_id
1726
- )
1727
- );
1728
-
1729
- wp_delete_post( $booking->post_id );
1730
-
1731
- }
1732
-
1733
- add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1734
- }
1735
-
1736
- }
1737
-
1738
- function trash_bookings( $booking_id ) {
1739
-
1740
- if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1741
-
1742
- $translated_bookings = $this->get_translated_bookings( $booking_id );
1743
-
1744
- foreach ( $translated_bookings as $booking ) {
1745
-
1746
- $this->wpdb->update(
1747
- $this->wpdb->posts,
1748
- array(
1749
- 'post_status' => 'trash'
1750
- ),
1751
- array(
1752
- 'ID' => $booking->post_id
1753
- )
1754
- );
1755
-
1756
- }
1757
-
1758
- }
1759
-
1760
- }
1761
-
1762
- function append_persons_to_translation_package( $package, $post ) {
1763
-
1764
- if ( $post->post_type == 'product' ) {
1765
- $product = wc_get_product( $post->ID );
1766
-
1767
- //WC_Product::get_type() available from WooCommerce 2.4.0
1768
- $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1769
-
1770
- if ( $product_type == 'booking' ) {
1771
-
1772
- $bookable_product = new WC_Product_Booking( $post->ID );
1773
-
1774
- $person_types = $bookable_product->get_person_types();
1775
-
1776
- foreach ( $person_types as $person_type ) {
1777
-
1778
- $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':name' ] = array(
1779
- 'translate' => 1,
1780
- 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1781
- 'format' => 'base64'
1782
- );
1783
-
1784
- $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':description' ] = array(
1785
- 'translate' => 1,
1786
- 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1787
- 'format' => 'base64'
1788
- );
1789
-
1790
- }
1791
-
1792
- }
1793
-
1794
- }
1795
-
1796
- return $package;
1797
-
1798
- }
1799
-
1800
- function save_person_translation( $post_id, $data, $job ) {
1801
- $person_translations = array();
1802
-
1803
- $product = wc_get_product( $post_id );
1804
-
1805
- if ( $product && $product->product_type == 'booking' ) {
1806
-
1807
-
1808
- foreach ( $data as $value ) {
1809
-
1810
- if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1811
-
1812
- $exp = explode( ':', $value['field_type'] );
1813
-
1814
- $person_id = $exp[2];
1815
- $field = $exp[3];
1816
-
1817
- $person_translations[ $person_id ][ $field ] = $value['data'];
1818
-
1819
- }
1820
-
1821
- }
1822
-
1823
- if ( $person_translations ) {
1824
-
1825
- foreach ( $person_translations as $person_id => $pt ) {
1826
-
1827
- $person_trid = $this->sitepress->get_element_trid( $person_id, 'post_bookable_person' );
1828
-
1829
-
1830
- $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1831
-
1832
- if ( empty( $person_id_translated ) ) {
1833
-
1834
- $person_post = array(
1835
-
1836
- 'post_type' => 'bookable_person',
1837
- 'post_status' => 'publish',
1838
- 'post_title' => $pt['name'],
1839
- 'post_parent' => $post_id,
1840
- 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1841
-
1842
- );
1843
-
1844
- $person_id_translated = wp_insert_post( $person_post );
1845
-
1846
- $this->sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1847
-
1848
- } else {
1849
-
1850
- $person_post = array(
1851
- 'ID' => $person_id_translated,
1852
- 'post_title' => $pt['name'],
1853
- 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1854
- );
1855
-
1856
- wp_update_post( $person_post );
1857
-
1858
- }
1859
-
1860
- }
1861
-
1862
- }
1863
-
1864
- }
1865
-
1866
- }
1867
-
1868
- function append_resources_to_translation_package( $package, $post ) {
1869
-
1870
- if ( $post->post_type == 'product' ) {
1871
- $product = wc_get_product( $post->ID );
1872
-
1873
- //WC_Product::get_type() available from WooCommerce 2.4.0
1874
- $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1875
-
1876
- if ( $product_type == 'booking' && $product->has_resources() ) {
1877
-
1878
- $resources = $product->get_resources();
1879
-
1880
- foreach ( $resources as $resource ) {
1881
-
1882
- $package['contents'][ 'wc_bookings:resource:' . $resource->ID . ':name' ] = array(
1883
- 'translate' => 1,
1884
- 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1885
- 'format' => 'base64'
1886
- );
1887
-
1888
- }
1889
-
1890
- }
1891
-
1892
- }
1893
-
1894
- return $package;
1895
-
1896
- }
1897
-
1898
- function save_resource_translation( $post_id, $data, $job ) {
1899
- $resource_translations = array();
1900
-
1901
- $product = wc_get_product( $post_id );
1902
-
1903
- if ( $product && $product->product_type == 'booking' ) {
1904
-
1905
- foreach ( $data as $value ) {
1906
-
1907
- if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1908
-
1909
- $exp = explode( ':', $value['field_type'] );
1910
-
1911
- $resource_id = $exp[2];
1912
- $field = $exp[3];
1913
-
1914
- $resource_translations[ $resource_id ][ $field ] = $value['data'];
1915
-
1916
- }
1917
-
1918
- }
1919
-
1920
- if ( $resource_translations ) {
1921
-
1922
- foreach ( $resource_translations as $resource_id => $rt ) {
1923
-
1924
- $resource_trid = $this->sitepress->get_element_trid( $resource_id, 'post_bookable_resource' );
1925
-
1926
- $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1927
-
1928
- if ( empty( $resource_id_translated ) ) {
1929
-
1930
- $resource_post = array(
1931
-
1932
- 'post_type' => 'bookable_resource',
1933
- 'post_status' => 'publish',
1934
- 'post_title' => $rt['name'],
1935
- 'post_parent' => $post_id
1936
- );
1937
-
1938
- $resource_id_translated = wp_insert_post( $resource_post );
1939
-
1940
- $this->sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
1941
-
1942
- $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 ) );
1943
- $relationship = array(
1944
- 'product_id' => $post_id,
1945
- 'resource_id' => $resource_id_translated,
1946
- 'sort_order' => $sort_order
1947
- );
1948
- $this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship );
1949
-
1950
- } else {
1951
-
1952
- $resource_post = array(
1953
- 'ID' => $resource_id_translated,
1954
- 'post_title' => $rt['name']
1955
- );
1956
-
1957
- wp_update_post( $resource_post );
1958
-
1959
- $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 ) );
1960
- $this->wpdb->update( $this->wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1961
- array( 'product_id' => $post_id, 'resource_id' => $resource_id_translated ) );
1962
-
1963
-
1964
- }
1965
-
1966
-
1967
- }
1968
-
1969
- }
1970
-
1971
- }
1972
-
1973
- }
1974
-
1975
- function wcml_js_lock_fields_ids( $ids ) {
1976
-
1977
- $ids = array_merge( $ids, array(
1978
- '_wc_booking_has_resources',
1979
- '_wc_booking_has_persons',
1980
- '_wc_booking_duration_type',
1981
- '_wc_booking_duration',
1982
- '_wc_booking_duration_unit',
1983
- '_wc_booking_calendar_display_mode',
1984
- '_wc_booking_requires_confirmation',
1985
- '_wc_booking_user_can_cancel',
1986
- '_wc_accommodation_booking_min_duration',
1987
- '_wc_accommodation_booking_max_duration',
1988
- '_wc_accommodation_booking_max_duration',
1989
- '_wc_accommodation_booking_calendar_display_mode',
1990
- '_wc_accommodation_booking_requires_confirmation',
1991
- '_wc_accommodation_booking_user_can_cancel',
1992
- '_wc_accommodation_booking_cancel_limit',
1993
- '_wc_accommodation_booking_cancel_limit_unit',
1994
- '_wc_accommodation_booking_qty',
1995
- '_wc_accommodation_booking_min_date',
1996
- '_wc_accommodation_booking_min_date_unit',
1997
- '_wc_accommodation_booking_max_date',
1998
- '_wc_accommodation_booking_max_date_unit',
1999
- 'bookings_pricing select',
2000
- 'bookings_resources select',
2001
- 'bookings_availability select',
2002
- 'bookings_persons input[type="checkbox"]'
2003
- ) );
2004
-
2005
- return $ids;
2006
- }
2007
-
2008
- /**
2009
- * @param array $args
2010
- *
2011
- * @return array
2012
- */
2013
- public function filter_get_booking_resources_args( $args ) {
2014
-
2015
- $screen = get_current_screen();
2016
- if ( $screen->id == 'product' ) {
2017
- $args['suppress_filters'] = false;
2018
- }
2019
-
2020
- return $args;
2021
-
2022
- }
2023
-
2024
- /**
2025
- * @param array $currencies
2026
- * @param int $post_id
2027
- *
2028
- * @return bool
2029
- */
2030
- private function update_booking_costs( $currencies = array(), $post_id = 0 ) {
2031
- $booking_options = array(
2032
- 'wcml_wc_booking_cost' => '_wc_booking_cost_',
2033
- 'wcml_wc_booking_base_cost' => '_wc_booking_base_cost_',
2034
- 'wcml_wc_display_cost' => '_wc_display_cost_',
2035
- );
2036
-
2037
- foreach ( $currencies as $code => $currency ) {
2038
- foreach ( $booking_options as $booking_options_post_key => $booking_options_meta_key_prefix ) {
2039
- if ( isset( $_POST[ $booking_options_post_key ][ $code ] ) ) {
2040
- update_post_meta( $post_id, $booking_options_meta_key_prefix . $code, sanitize_text_field( $_POST[ $booking_options_post_key ][ $code ] ) );
2041
- }
2042
- }
2043
- }
2044
-
2045
- return true;
2046
- }
2047
-
2048
- /**
2049
- * @param array $currencies
2050
- * @param int $post_id
2051
- *
2052
- * @return bool
2053
- */
2054
- private function update_booking_pricing( $currencies = array(), $post_id = 0 ) {
2055
- $updated_meta = array();
2056
- $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
2057
- if ( empty( $booking_pricing ) ) {
2058
- return false;
2059
- }
2060
-
2061
- foreach ( $booking_pricing as $key => $prices ) {
2062
- $updated_meta[ $key ] = $prices;
2063
- foreach ( $currencies as $code => $currency ) {
2064
- if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
2065
- $updated_meta[ $key ][ 'base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
2066
- }
2067
- if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
2068
- $updated_meta[ $key ][ 'cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
2069
- }
2070
- }
2071
-
2072
- }
2073
-
2074
- update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
2075
-
2076
- return true;
2077
- }
2078
-
2079
- /**
2080
- * @param array $currencies
2081
- * @param array $person_costs
2082
- *
2083
- * @return bool
2084
- */
2085
- private function update_booking_person_cost( $currencies = array(), $person_costs = array() ) {
2086
- if ( empty( $person_costs ) ) {
2087
- return false;
2088
- }
2089
-
2090
- foreach ( $person_costs as $person_id => $costs ) {
2091
- foreach ( $currencies as $code => $currency ) {
2092
- if ( isset( $costs[ $code ] ) ) {
2093
- update_post_meta( $person_id, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2094
- }
2095
- }
2096
- }
2097
-
2098
- return true;
2099
- }
2100
-
2101
- /**
2102
- * @param array $currencies
2103
- * @param array $block_costs
2104
- *
2105
- * @return bool
2106
- */
2107
- private function update_booking_person_block_cost( $currencies = array(), $block_costs = array() ) {
2108
- if ( empty( $block_costs ) ) {
2109
- return false;
2110
- }
2111
-
2112
- foreach ( $block_costs as $person_id => $costs ) {
2113
- foreach ( $currencies as $code => $currency ) {
2114
- if ( isset( $costs[ $code ] ) ) {
2115
- update_post_meta( $person_id, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2116
- }
2117
- }
2118
- }
2119
-
2120
- return true;
2121
- }
2122
-
2123
- /**
2124
- * @param array $currencies
2125
- * @param int $post_id
2126
- * @param array $resource_cost
2127
- *
2128
- * @return bool
2129
- */
2130
- private function update_booking_resource_cost( $currencies = array(), $post_id = 0, $resource_cost = array() ) {
2131
- if ( empty( $resource_cost ) ) {
2132
- return false;
2133
- }
2134
-
2135
- $updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
2136
- if ( ! is_array( $updated_meta ) ) {
2137
- $updated_meta = array();
2138
- }
2139
-
2140
- $wc_booking_resource_costs = array();
2141
-
2142
- foreach ( $resource_cost as $resource_id => $costs ) {
2143
-
2144
- foreach ( $currencies as $code => $currency ) {
2145
-
2146
- if ( isset( $costs[ $code ] ) ) {
2147
- $wc_booking_resource_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2148
- }
2149
-
2150
- }
2151
-
2152
- }
2153
-
2154
- $updated_meta['custom_costs'] = $wc_booking_resource_costs;
2155
-
2156
- update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
2157
-
2158
- $this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
2159
-
2160
- return true;
2161
- }
2162
-
2163
- /**
2164
- * @param array $currencies
2165
- * @param int $post_id
2166
- *
2167
- * @return bool
2168
- */
2169
- private function update_booking_resource_block_cost( $currencies = array(), $post_id = 0, $resource_block_cost = array() ) {
2170
- if ( empty( $resource_block_cost ) ) {
2171
- return false;
2172
- }
2173
-
2174
- $updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
2175
-
2176
- $wc_booking_resource_block_costs = array();
2177
-
2178
- foreach ( $resource_block_cost as $resource_id => $costs ) {
2179
-
2180
- foreach ( $currencies as $code => $currency ) {
2181
-
2182
- if ( isset( $costs[ $code ] ) ) {
2183
- $wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2184
- }
2185
-
2186
- }
2187
-
2188
- }
2189
-
2190
- $updated_meta['custom_costs'] = $wc_booking_resource_block_costs;
2191
-
2192
- update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
2193
-
2194
- $this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
2195
-
2196
- return true;
2197
- }
2198
-
2199
- public function maybe_fix_double_serialized_wc_booking_availability( $mid, $object_id, $meta_key, $_meta_value ) {
2200
- global $wpdb;
2201
-
2202
- if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
2203
-
2204
- $meta_keys_to_fix = array(
2205
- '_wc_booking_availability',
2206
- '_wc_booking_pricing'
2207
- );
2208
-
2209
- if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
2210
-
2211
- if ( is_string( $_meta_value ) ) {
2212
- $wpdb->update( $wpdb->postmeta, array( 'meta_value' => $_meta_value ), array( 'meta_id' => $mid ) );
2213
- }
2214
-
2215
- }
2216
-
2217
- }
2218
-
2219
- }
2220
-
2221
- public function extra_conditions_to_filter_bookings( $extra_conditions ){
2222
-
2223
- if( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'wc_booking' && !isset( $_GET[ 'post_status' ] ) ){
2224
- $extra_conditions = str_replace( "GROUP BY", " AND post_status = 'confirmed' GROUP BY", $extra_conditions );
2225
- }
2226
-
2227
- return $extra_conditions;
2228
- }
2229
-
2230
- public function hide_bookings_type_on_tm_dashboard( $types ){
2231
- unset( $types[ 'wc_booking' ] );
2232
- return $types;
2233
- }
2234
-
2235
  }
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_ajax_actions', 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
+ add_filter( 'wpml_extra_conditions_snippet', array( $this, 'extra_conditions_to_filter_bookings' ) );
176
+
177
+ $this->clear_transient_fields();
178
+
179
+ add_filter( 'wpml_tm_dashboard_translatable_types', array( $this, 'hide_bookings_type_on_tm_dashboard' ) );
180
+
181
+ }
182
+
183
+ function wcml_price_field_after_booking_base_cost( $post_id ) {
184
+
185
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_cost' );
186
+
187
+ }
188
+
189
+ function wcml_price_field_after_booking_block_cost( $post_id ) {
190
+
191
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_base_cost' );
192
+
193
+ }
194
+
195
+ function wcml_price_field_after_display_cost( $post_id ) {
196
+
197
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_display_cost' );
198
+
199
+ }
200
+
201
+ function wcml_price_field_after_booking_pricing_base_cost( $pricing, $post_id ) {
202
+
203
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_base_cost', $pricing );
204
+
205
+ }
206
+
207
+ function wcml_price_field_after_booking_pricing_cost( $pricing, $post_id ) {
208
+
209
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_pricing_cost', $pricing );
210
+
211
+ }
212
+
213
+ function wcml_price_field_after_person_cost( $person_type_id ) {
214
+
215
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_cost', false, false );
216
+
217
+ }
218
+
219
+ function wcml_price_field_after_person_block_cost( $person_type_id ) {
220
+
221
+ $this->echo_wcml_price_field( $person_type_id, 'wcml_wc_booking_person_block_cost', false, false );
222
+
223
+ }
224
+
225
+ function wcml_price_field_after_resource_cost( $resource_id, $post_id ) {
226
+
227
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_cost', false, true, $resource_id );
228
+
229
+ }
230
+
231
+ function wcml_price_field_after_resource_block_cost( $resource_id, $post_id ) {
232
+
233
+ $this->echo_wcml_price_field( $post_id, 'wcml_wc_booking_resource_block_cost', false, true, $resource_id );
234
+
235
+ }
236
+
237
+ function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ) {
238
+
239
+
240
+ if ( ( ! $check || $this->woocommerce_wpml->products->is_original_product( $post_id ) ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
241
+
242
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
243
+
244
+ $wc_currencies = get_woocommerce_currencies();
245
+
246
+ echo '<div class="wcml_custom_cost_field" >';
247
+
248
+ foreach ( $currencies as $currency_code => $currency ) {
249
+
250
+ switch ( $field ) {
251
+ case 'wcml_wc_booking_cost':
252
+ woocommerce_wp_text_input( array(
253
+ 'id' => 'wcml_wc_booking_cost',
254
+ 'class' => 'wcml_bookings_custom_price',
255
+ 'name' => 'wcml_wc_booking_cost[' . $currency_code . ']',
256
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
257
+ 'description' => __( 'One-off cost for the booking as a whole.', 'woocommerce-bookings' ),
258
+ 'value' => get_post_meta( $post_id, '_wc_booking_cost_' . $currency_code, true ),
259
+ 'type' => 'number',
260
+ 'desc_tip' => true,
261
+ 'custom_attributes' => array(
262
+ 'min' => '',
263
+ 'step' => '0.01'
264
+ )
265
+ ) );
266
+ break;
267
+ case 'wcml_wc_booking_base_cost':
268
+ woocommerce_wp_text_input( array(
269
+ 'id' => 'wcml_wc_booking_base_cost',
270
+ 'class' => 'wcml_bookings_custom_price',
271
+ 'name' => 'wcml_wc_booking_base_cost[' . $currency_code . ']',
272
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
273
+ 'description' => __( 'This is the cost per block booked. All other costs (for resources and persons) are added to this.', 'woocommerce-bookings' ),
274
+ 'value' => get_post_meta( $post_id, '_wc_booking_base_cost_' . $currency_code, true ),
275
+ 'type' => 'number',
276
+ 'desc_tip' => true,
277
+ 'custom_attributes' => array(
278
+ 'min' => '',
279
+ 'step' => '0.01'
280
+ )
281
+ ) );
282
+ break;
283
+ case 'wcml_wc_display_cost':
284
+ woocommerce_wp_text_input( array(
285
+ 'id' => 'wcml_wc_display_cost',
286
+ 'class' => 'wcml_bookings_custom_price',
287
+ 'name' => 'wcml_wc_display_cost[' . $currency_code . ']',
288
+ 'label' => get_woocommerce_currency_symbol( $currency_code ),
289
+ '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' ),
290
+ 'value' => get_post_meta( $post_id, '_wc_display_cost_' . $currency_code, true ),
291
+ 'type' => 'number',
292
+ 'desc_tip' => true,
293
+ 'custom_attributes' => array(
294
+ 'min' => '',
295
+ 'step' => '0.01'
296
+ )
297
+ ) );
298
+ break;
299
+
300
+ case 'wcml_wc_booking_pricing_base_cost':
301
+
302
+ if ( isset( $pricing[ 'base_cost_' . $currency_code ] ) ) {
303
+ $value = $pricing[ 'base_cost_' . $currency_code ];
304
+ } else {
305
+ $value = '';
306
+ }
307
+
308
+ echo '<div class="wcml_bookings_range_block" >';
309
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
310
+ 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" />';
311
+ echo '</div>';
312
+ break;
313
+
314
+ case 'wcml_wc_booking_pricing_cost':
315
+
316
+ if ( isset( $pricing[ 'cost_' . $currency_code ] ) ) {
317
+ $value = $pricing[ 'cost_' . $currency_code ];
318
+ } else {
319
+ $value = '';
320
+ }
321
+
322
+ echo '<div class="wcml_bookings_range_block" >';
323
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
324
+ echo '<input type="number" step="0.01" name="wcml_wc_booking_pricing_cost[' . $currency_code . '][]" class="wcml_bookings_custom_price" value="' . $value . '" placeholder="0" />';
325
+ echo '</div>';
326
+ break;
327
+
328
+ case 'wcml_wc_booking_person_cost':
329
+
330
+ $value = get_post_meta( $post_id, 'cost_' . $currency_code, true );
331
+
332
+ echo '<div class="wcml_bookings_person_block" >';
333
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
334
+ 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" />';
335
+ echo '</div>';
336
+ break;
337
+
338
+ case 'wcml_wc_booking_person_block_cost':
339
+
340
+ $value = get_post_meta( $post_id, 'block_cost_' . $currency_code, true );
341
+
342
+ echo '<div class="wcml_bookings_person_block" >';
343
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
344
+ 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" />';
345
+ echo '</div>';
346
+ break;
347
+
348
+ case 'wcml_wc_booking_resource_cost':
349
+
350
+ $resource_base_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_base_costs', true ) );
351
+
352
+ if ( isset( $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
353
+ $value = $resource_base_costs['custom_costs'][ $currency_code ][ $resource_id ];
354
+ } else {
355
+ $value = '';
356
+ }
357
+
358
+ echo '<div class="wcml_bookings_resource_block" >';
359
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
360
+ 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" />';
361
+ echo '</div>';
362
+ break;
363
+
364
+ case 'wcml_wc_booking_resource_block_cost':
365
+
366
+ $resource_block_costs = maybe_unserialize( get_post_meta( $post_id, '_resource_block_costs', true ) );
367
+
368
+ if ( isset( $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ] ) ) {
369
+ $value = $resource_block_costs['custom_costs'][ $currency_code ][ $resource_id ];
370
+ } else {
371
+ $value = '';
372
+ }
373
+
374
+ echo '<div class="wcml_bookings_resource_block" >';
375
+ echo '<label>' . get_woocommerce_currency_symbol( $currency_code ) . '</label>';
376
+ 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" />';
377
+ echo '</div>';
378
+ break;
379
+
380
+ default:
381
+ break;
382
+
383
+ }
384
+
385
+ }
386
+
387
+ echo '</div>';
388
+
389
+ }
390
+ }
391
+
392
+ function after_bookings_pricing( $post_id ) {
393
+
394
+
395
+ 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 ) {
396
+
397
+ $custom_costs_status = get_post_meta( $post_id, '_wcml_custom_costs_status', true );
398
+
399
+ $checked = ! $custom_costs_status ? 'checked="checked"' : ' ';
400
+
401
+ echo '<div class="wcml_custom_costs">';
402
+
403
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" ' . $checked . ' />';
404
+ echo '<label for="wcml_custom_costs_auto">' . __( 'Calculate costs in other currencies automatically', 'woocommerce-multilingual' ) . '</label>';
405
+
406
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
407
+
408
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" ' . $checked . ' />';
409
+ echo '<label for="wcml_custom_costs_manually">' . __( 'Set costs in other currencies manually', 'woocommerce-multilingual' ) . '</label>';
410
+
411
+ wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
412
+
413
+ echo '</div>';
414
+ }
415
+
416
+ }
417
+
418
+ function save_custom_costs( $post_id ) {
419
+ $nonce = filter_var( isset( $_POST['_wcml_custom_costs_nonce'] ) ? $_POST['_wcml_custom_costs_nonce'] : '', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
420
+
421
+ if ( isset( $_POST['_wcml_custom_costs'] ) && isset( $nonce ) && wp_verify_nonce( $nonce, 'wcml_save_custom_costs' ) ) {
422
+
423
+ update_post_meta( $post_id, '_wcml_custom_costs_status', $_POST['_wcml_custom_costs'] );
424
+
425
+ if ( 1 === (int) $_POST['_wcml_custom_costs'] ) {
426
+
427
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
428
+ if ( empty( $currencies ) || 0 === $post_id ) {
429
+ return false;
430
+ }
431
+
432
+ $this->update_booking_costs( $currencies, $post_id );
433
+ $this->update_booking_pricing( $currencies, $post_id );
434
+
435
+
436
+ if ( isset( $_POST['wcml_wc_booking_person_cost'] ) && is_array( $_POST['wcml_wc_booking_person_cost'] ) ) {
437
+ $this->update_booking_person_cost( $currencies, $_POST['wcml_wc_booking_person_cost'] );
438
+ }
439
+
440
+ if ( isset( $_POST['wcml_wc_booking_person_block_cost'] ) && is_array( $_POST['wcml_wc_booking_person_block_cost'] ) ) {
441
+ $this->update_booking_person_block_cost( $currencies, $_POST['wcml_wc_booking_person_block_cost'] );
442
+ }
443
+
444
+ if ( isset( $_POST['wcml_wc_booking_resource_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_cost'] ) ) {
445
+ $this->update_booking_resource_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_cost'] );
446
+ }
447
+
448
+ if ( isset( $_POST['wcml_wc_booking_resource_block_cost'] ) && is_array( $_POST['wcml_wc_booking_resource_block_cost'] ) ) {
449
+ $this->update_booking_resource_block_cost( $currencies, $post_id, $_POST['wcml_wc_booking_resource_block_cost'] );
450
+ }
451
+
452
+ update_post_meta( $post_id, '_price', '' );
453
+ } else {
454
+ return false;
455
+ }
456
+ }
457
+
458
+ }
459
+
460
+ // sync existing product bookings for translations
461
+ function sync_bookings( $original_product_id, $product_id, $lang ) {
462
+ $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 ) );
463
+
464
+ foreach ( $all_bookings_for_product as $booking ) {
465
+ $check_if_exists = $this->wpdb->get_row( $this->wpdb->prepare( "SELECT pm3.* FROM {$this->wpdb->postmeta} AS pm1
466
+ LEFT JOIN {$this->wpdb->postmeta} AS pm2 ON pm1.post_id = pm2.post_id
467
+ LEFT JOIN {$this->wpdb->postmeta} AS pm3 ON pm1.post_id = pm3.post_id
468
+ 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'"
469
+ , $booking->id, $lang ) );
470
+
471
+ if ( is_null( $check_if_exists ) ) {
472
+ $this->duplicate_booking_for_translations( $booking->id, $lang );
473
+ } elseif ( '' === $check_if_exists->meta_value ) {
474
+ update_post_meta( $check_if_exists->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking->id, $lang ) );
475
+ update_post_meta( $check_if_exists->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking->id, $lang ) );
476
+ update_post_meta( $check_if_exists->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking->id, $lang ) );
477
+ }
478
+ }
479
+ }
480
+
481
+ function sync_booking_data( $original_product_id, $current_product_id ) {
482
+
483
+ if ( has_term( 'booking', 'product_type', $original_product_id ) ) {
484
+ global $pagenow, $iclTranslationManagement;
485
+
486
+ // get language code
487
+ $language_details = $this->sitepress->get_element_language_details( $original_product_id, 'post_product' );
488
+ if ( $pagenow == 'admin.php' && empty( $language_details ) ) {
489
+ //translation editor support: sidestep icl_translations_cache
490
+ $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 ) );
491
+ }
492
+ if ( empty( $language_details ) ) {
493
+ return;
494
+ }
495
+
496
+ // pick posts to sync
497
+ $posts = array();
498
+ $translations = $this->sitepress->get_element_translations( $language_details->trid, 'post_product' );
499
+ foreach ( $translations as $translation ) {
500
+
501
+ if ( ! $translation->original ) {
502
+ $posts[ $translation->element_id ] = $translation;
503
+ }
504
+ }
505
+
506
+ foreach ( $posts as $post_id => $translation ) {
507
+
508
+ $trn_lang = $this->sitepress->get_language_for_element( $post_id, 'post_product' );
509
+
510
+ //sync_resources
511
+ $this->sync_resources( $original_product_id, $post_id, $trn_lang );
512
+
513
+ //sync_persons
514
+ $this->sync_persons( $original_product_id, $post_id, $trn_lang );
515
+ }
516
+
517
+ }
518
+
519
+ }
520
+
521
+ function sync_resources( $original_product_id, $translated_product_id, $lang_code, $duplicate = true ) {
522
+
523
+ $original_resources = $this->wpdb->get_results( $this->wpdb->prepare(
524
+ "SELECT resource_id, sort_order FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
525
+ $original_product_id ) );
526
+
527
+ $translated_resources = $this->wpdb->get_col( $this->wpdb->prepare(
528
+ "SELECT resource_id FROM {$this->wpdb->prefix}wc_booking_relationships WHERE product_id = %d",
529
+ $translated_product_id ) );
530
+
531
+ $used_translated_resources = array();
532
+
533
+ foreach ( $original_resources as $resource ) {
534
+
535
+ $translated_resource_id = apply_filters( 'translate_object_id', $resource->resource_id, 'bookable_resource', false, $lang_code );
536
+ if ( ! is_null( $translated_resource_id ) ) {
537
+
538
+ if ( in_array( $translated_resource_id, $translated_resources ) ) {
539
+ $this->update_product_resource( $translated_product_id, $translated_resource_id, $resource );
540
+ } else {
541
+ $this->add_product_resource( $translated_product_id, $translated_resource_id, $resource );
542
+ }
543
+ $used_translated_resources[] = $translated_resource_id;
544
+ } else {
545
+ if ( $duplicate ) {
546
+ $this->duplicate_resource( $translated_product_id, $resource, $lang_code );
547
+ }
548
+ }
549
+
550
+ }
551
+
552
+ $removed_translated_resources_id = array_diff( $translated_resources, $used_translated_resources );
553
+ foreach ( $removed_translated_resources_id as $resource_id ) {
554
+ $this->remove_resource_from_product( $translated_product_id, $resource_id );
555
+ }
556
+
557
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_base_costs', $lang_code );
558
+ $this->sync_resource_costs( $original_product_id, $translated_product_id, '_resource_block_costs', $lang_code );
559
+
560
+ }
561
+
562
+ function duplicate_resource( $tr_product_id, $resource, $lang_code ) {
563
+ global $iclTranslationManagement;
564
+
565
+ if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
566
+
567
+ $trns_resource_id = $this->sitepress->make_duplicate( $resource->resource_id, $lang_code );
568
+
569
+ } else {
570
+
571
+ if ( ! isset( $iclTranslationManagement ) ) {
572
+ $iclTranslationManagement = new TranslationManagement;
573
+ }
574
+
575
+ $trns_resource_id = $iclTranslationManagement->make_duplicate( $resource->resource_id, $lang_code );
576
+
577
+ }
578
+
579
+ $this->wpdb->insert(
580
+ $this->wpdb->prefix . 'wc_booking_relationships',
581
+ array(
582
+ 'product_id' => $tr_product_id,
583
+ 'resource_id' => $trns_resource_id,
584
+ 'sort_order' => $resource->sort_order
585
+ )
586
+ );
587
+
588
+ delete_post_meta( $trns_resource_id, '_icl_lang_duplicate_of' );
589
+
590
+ return $trns_resource_id;
591
+ }
592
+
593
+ public function add_product_resource( $product_id, $resource_id, $resource_data ) {
594
+
595
+ $this->wpdb->insert(
596
+ $this->wpdb->prefix . 'wc_booking_relationships',
597
+ array(
598
+ 'sort_order' => $resource_data->sort_order,
599
+ 'product_id' => $product_id,
600
+ 'resource_id' => $resource_id
601
+ )
602
+ );
603
+
604
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
605
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
606
+
607
+ }
608
+
609
+ public function remove_resource_from_product( $product_id, $resource_id ) {
610
+
611
+ $this->wpdb->delete(
612
+ $this->wpdb->prefix . 'wc_booking_relationships',
613
+ array(
614
+ 'product_id' => $product_id,
615
+ 'resource_id' => $resource_id
616
+ )
617
+ );
618
+
619
+ }
620
+
621
+ public function update_product_resource( $product_id, $resource_id, $resource_data ) {
622
+
623
+ $this->wpdb->update(
624
+ $this->wpdb->prefix . 'wc_booking_relationships',
625
+ array(
626
+ 'sort_order' => $resource_data->sort_order
627
+ ),
628
+ array(
629
+ 'product_id' => $product_id,
630
+ 'resource_id' => $resource_id
631
+ )
632
+ );
633
+
634
+ update_post_meta( $resource_id, 'qty', get_post_meta( $resource_data->resource_id, 'qty', true ) );
635
+ update_post_meta( $resource_id, '_wc_booking_availability', get_post_meta( $resource_data->resource_id, '_wc_booking_availability', true ) );
636
+
637
+
638
+ }
639
+
640
+ function sync_persons( $original_product_id, $tr_product_id, $lang_code, $duplicate = true ) {
641
+ $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 ) );
642
+
643
+ $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 ) );
644
+
645
+
646
+ foreach ( $orig_persons as $person ) {
647
+
648
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person, 'bookable_person', false, $lang_code );
649
+
650
+ if ( ! is_null( $trnsl_person_id ) && in_array( $trnsl_person_id, $trnsl_persons ) ) {
651
+
652
+ if ( ( $key = array_search( $trnsl_person_id, $trnsl_persons ) ) !== false ) {
653
+
654
+ unset( $trnsl_persons[ $key ] );
655
+
656
+ update_post_meta( $trnsl_person_id, 'block_cost', get_post_meta( $person, 'block_cost', true ) );
657
+ update_post_meta( $trnsl_person_id, 'cost', get_post_meta( $person, 'cost', true ) );
658
+ update_post_meta( $trnsl_person_id, 'max', get_post_meta( $person, 'max', true ) );
659
+ update_post_meta( $trnsl_person_id, 'min', get_post_meta( $person, 'min', true ) );
660
+
661
+
662
+ if ( get_post_meta( $person, '_wcml_custom_costs_status', true ) && $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
663
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies();
664
+
665
+ foreach ( $currencies as $code => $currency ) {
666
+
667
+ update_post_meta( $trnsl_person_id, 'block_cost_' . $code, get_post_meta( $person, 'block_cost_' . $code, true ) );
668
+ update_post_meta( $trnsl_person_id, 'cost_' . $code, get_post_meta( $person, 'cost_' . $code, true ) );
669
+
670
+ }
671
+ }
672
+
673
+ }
674
+
675
+ } else {
676
+
677
+ if ( $duplicate ) {
678
+
679
+ $this->duplicate_person( $tr_product_id, $person, $lang_code );
680
+
681
+ } else {
682
+
683
+ continue;
684
+
685
+ }
686
+
687
+ }
688
+
689
+ }
690
+
691
+ foreach ( $trnsl_persons as $trnsl_person ) {
692
+
693
+ wp_delete_post( $trnsl_person );
694
+
695
+ }
696
+
697
+ }
698
+
699
+ function duplicate_person( $tr_product_id, $person_id, $lang_code ) {
700
+ global $iclTranslationManagement;
701
+
702
+ if ( method_exists( $this->sitepress, 'make_duplicate' ) ) {
703
+
704
+ $new_person_id = $this->sitepress->make_duplicate( $person_id, $lang_code );
705
+
706
+ } else {
707
+
708
+ if ( ! isset( $iclTranslationManagement ) ) {
709
+ $iclTranslationManagement = new TranslationManagement;
710
+ }
711
+
712
+ $new_person_id = $iclTranslationManagement->make_duplicate( $person_id, $lang_code );
713
+
714
+ }
715
+
716
+ $this->wpdb->update(
717
+ $this->wpdb->posts,
718
+ array(
719
+ 'post_parent' => $tr_product_id
720
+ ),
721
+ array(
722
+ 'ID' => $new_person_id
723
+ )
724
+ );
725
+
726
+ delete_post_meta( $new_person_id, '_icl_lang_duplicate_of' );
727
+
728
+ return $new_person_id;
729
+ }
730
+
731
+ function filter_wc_booking_cost( $check, $object_id, $meta_key, $single ) {
732
+
733
+ if ( in_array( $meta_key, array(
734
+ '_wc_booking_cost',
735
+ '_wc_booking_base_cost',
736
+ '_wc_display_cost',
737
+ '_wc_booking_pricing',
738
+ 'cost',
739
+ 'block_cost',
740
+ '_resource_base_costs',
741
+ '_resource_block_costs'
742
+ ) ) ) {
743
+
744
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
745
+
746
+ $original_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
747
+
748
+ $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
749
+
750
+ $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
751
+
752
+ if ( $currency == get_option( 'woocommerce_currency' ) ) {
753
+ return $check;
754
+ }
755
+
756
+ if ( in_array( $meta_key, array( 'cost', 'block_cost' ) ) ) {
757
+
758
+ if ( get_post_type( $object_id ) == 'bookable_person' ) {
759
+
760
+ $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 ) ) );
761
+ $cost_status = get_post_meta( $original_id, '_wcml_custom_costs_status', true );
762
+
763
+ $value = get_post_meta( $object_id, $meta_key . '_' . $currency, true );
764
+
765
+ if ( $cost_status && $value ) {
766
+
767
+ return $value;
768
+
769
+ } else {
770
+
771
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
772
+
773
+ $cost = get_post_meta( $object_id, $meta_key, true );
774
+
775
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
776
+
777
+ return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
778
+ }
779
+
780
+ } else {
781
+
782
+ return $check;
783
+
784
+ }
785
+
786
+ }
787
+
788
+ if ( in_array( $meta_key, array(
789
+ '_wc_booking_pricing',
790
+ '_resource_base_costs',
791
+ '_resource_block_costs'
792
+ ) ) ) {
793
+
794
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
795
+
796
+ if ( $meta_key == '_wc_booking_pricing' ) {
797
+
798
+ if ( $original_id != $object_id ) {
799
+ $value = get_post_meta( $original_id, $meta_key );
800
+ } else {
801
+ $value = $check;
802
+ }
803
+
804
+ } else {
805
+
806
+ $costs = maybe_unserialize( get_post_meta( $object_id, $meta_key, true ) );
807
+
808
+ if ( ! $costs ) {
809
+ $value = $check;
810
+ } elseif ( $cost_status && isset( $costs['custom_costs'][ $currency ] ) ) {
811
+
812
+ $res_costs = array();
813
+ foreach ( $costs['custom_costs'][ $currency ] as $resource_id => $cost ) {
814
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $this->sitepress->get_current_language() );
815
+ $res_costs[ $trns_resource_id ] = $cost;
816
+ }
817
+ $value = array( 0 => $res_costs );
818
+ } elseif ( $cost_status && isset( $costs[0]['custom_costs'][ $currency ] ) ) {
819
+ $value = array( 0 => $costs[0]['custom_costs'][ $currency ] );
820
+ } else {
821
+
822
+ $converted_values = array();
823
+
824
+ foreach ( $costs as $resource_id => $cost ) {
825
+ $converted_values[0][ $resource_id ] = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
826
+ }
827
+
828
+ $value = $converted_values;
829
+ }
830
+
831
+ }
832
+
833
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
834
+
835
+ return $value;
836
+
837
+ }
838
+
839
+ $value = get_post_meta( $original_id, $meta_key . '_' . $currency, true );
840
+
841
+ if ( $cost_status && ( ! empty( $value ) || ( empty( $value ) && $meta_key == '_wc_display_cost' ) ) ) {
842
+
843
+ return $value;
844
+
845
+ } else {
846
+
847
+ remove_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
848
+
849
+ $value = get_post_meta( $original_id, $meta_key, true );
850
+
851
+ $value = $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $value, $currency );
852
+
853
+ add_filter( 'get_post_metadata', array( $this, 'filter_wc_booking_cost' ), 10, 4 );
854
+
855
+ return $value;
856
+
857
+ }
858
+
859
+ }
860
+
861
+ }
862
+
863
+ return $check;
864
+ }
865
+
866
+ function sync_resource_costs_with_translations( $object_id, $meta_key, $check = false ) {
867
+
868
+
869
+ $original_product_id = apply_filters( 'translate_object_id', $object_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $object_id ) );
870
+
871
+ if ( $object_id == $original_product_id ) {
872
+
873
+ $trid = $this->sitepress->get_element_trid( $object_id, 'post_product' );
874
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product' );
875
+
876
+ foreach ( $translations as $translation ) {
877
+
878
+ if ( ! $translation->original ) {
879
+
880
+ $this->sync_resource_costs( $original_product_id, $translation->element_id, $meta_key, $translation->language_code );
881
+
882
+ }
883
+ }
884
+
885
+ return $check;
886
+
887
+ } else {
888
+
889
+ $language_code = $this->sitepress->get_language_for_element( $object_id, 'post_product' );
890
+
891
+ $this->sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code );
892
+
893
+ return true;
894
+
895
+ }
896
+
897
+ }
898
+
899
+ function sync_resource_costs( $original_product_id, $object_id, $meta_key, $language_code ) {
900
+
901
+ $original_costs = maybe_unserialize( get_post_meta( $original_product_id, $meta_key, true ) );
902
+
903
+ $wc_booking_resource_costs = array();
904
+ if ( ! empty( $original_costs ) ) {
905
+ foreach ( $original_costs as $resource_id => $costs ) {
906
+
907
+ if ( $resource_id == 'custom_costs' && isset( $costs['custom_costs'] ) ) {
908
+
909
+ foreach ( $costs['custom_costs'] as $code => $currencies ) {
910
+
911
+ foreach ( $currencies as $custom_costs_resource_id => $custom_cost ) {
912
+
913
+ $trns_resource_id = apply_filters( 'translate_object_id', $custom_costs_resource_id, 'bookable_resource', true, $language_code );
914
+
915
+ $wc_booking_resource_costs['custom_costs'][ $code ][ $trns_resource_id ] = $custom_cost;
916
+
917
+ }
918
+
919
+ }
920
+
921
+ } else {
922
+
923
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', true, $language_code );
924
+
925
+ $wc_booking_resource_costs[ $trns_resource_id ] = $costs;
926
+
927
+ }
928
+
929
+ }
930
+ }
931
+
932
+ update_post_meta( $object_id, $meta_key, $wc_booking_resource_costs );
933
+
934
+ }
935
+
936
+ function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ) {
937
+ return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
938
+ }
939
+
940
+ function wc_bookings_process_cost_rules_base_cost( $base_cost, $fields, $key ) {
941
+ return $this->filter_pricing_cost( $base_cost, $fields, 'base_cost_', $key );
942
+ }
943
+
944
+ function wc_bookings_process_cost_rules_override_block_cost( $override_cost, $fields, $key ) {
945
+ return $this->filter_pricing_cost( $override_cost, $fields, 'override_block_', $key );
946
+ }
947
+
948
+ function filter_pricing_cost( $cost, $fields, $name, $key ) {
949
+ global $product;
950
+
951
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
952
+
953
+ $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
954
+
955
+ if ( $currency == get_option( 'woocommerce_currency' ) ) {
956
+ return $cost;
957
+ }
958
+
959
+ if ( isset( $_POST['form'] ) ) {
960
+ parse_str( $_POST['form'], $posted );
961
+
962
+ $booking_id = $posted['add-to-cart'];
963
+
964
+ } elseif ( isset( $_POST['add-to-cart'] ) ) {
965
+
966
+ $booking_id = $_POST['add-to-cart'];
967
+
968
+ }
969
+
970
+ if ( isset( $booking_id ) ) {
971
+ $original_id = apply_filters( 'translate_object_id', $booking_id, 'product', true, $this->woocommerce_wpml->products->get_original_product_language( $booking_id ) );
972
+
973
+ if ( $booking_id != $original_id ) {
974
+ $fields = maybe_unserialize( get_post_meta( $original_id, '_wc_booking_pricing', true ) );
975
+ $fields = $fields[ $key ];
976
+ }
977
+ }
978
+
979
+ if ( isset( $fields[ $name . $currency ] ) ) {
980
+ return $fields[ $name . $currency ];
981
+ } else {
982
+ return $this->woocommerce_wpml->multi_currency->prices->convert_price_amount( $cost, $currency );
983
+ }
984
+
985
+ }
986
+
987
+ return $cost;
988
+
989
+ }
990
+
991
+ function load_assets( $external_product_type = false ) {
992
+ global $pagenow;
993
+
994
+ $product = $pagenow == 'post.php' && isset( $_GET['post'] ) ? wc_get_product( $_GET['post'] ) : false;
995
+
996
+ if ( ( $product && ( $product->product_type == 'booking' || $product->product_type == $external_product_type ) ) || $pagenow == 'post-new.php' ) {
997
+
998
+ wp_register_style( 'wcml-bookings-css', WCML_PLUGIN_URL . '/compatibility/res/css/wcml-bookings.css', array(), WCML_VERSION );
999
+ wp_enqueue_style( 'wcml-bookings-css' );
1000
+
1001
+ wp_register_script( 'wcml-bookings-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-bookings.js', array( 'jquery' ), WCML_VERSION );
1002
+ wp_enqueue_script( 'wcml-bookings-js' );
1003
+
1004
+ }
1005
+
1006
+ }
1007
+
1008
+ function localize_lock_fields_js() {
1009
+ wp_localize_script( 'wcml-bookings-js', 'lock_settings', array( 'lock_fields' => 1 ) );
1010
+ }
1011
+
1012
+ function wcml_multi_currency_is_ajax( $actions ) {
1013
+
1014
+ $actions[] = 'wc_bookings_calculate_costs';
1015
+
1016
+ return $actions;
1017
+ }
1018
+
1019
+ function filter_bundled_product_in_cart_contents( $cart_item, $key, $current_language ) {
1020
+
1021
+ if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['booking'] ) ) {
1022
+
1023
+
1024
+ $current_id = apply_filters( 'translate_object_id', $cart_item['data']->id, 'product', true, $current_language );
1025
+ $cart_product_id = $cart_item['data']->id;
1026
+
1027
+ if ( $current_id != $cart_product_id ) {
1028
+
1029
+ $cart_item['data'] = new WC_Product_Booking( $current_id );
1030
+
1031
+ }
1032
+
1033
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT || $current_id != $cart_product_id ) {
1034
+
1035
+ $booking_info = array(
1036
+ 'wc_bookings_field_start_date_year' => $cart_item['booking']['_year'],
1037
+ 'wc_bookings_field_start_date_month' => $cart_item['booking']['_month'],
1038
+ 'wc_bookings_field_start_date_day' => $cart_item['booking']['_day'],
1039
+ 'add-to-cart' => $current_id
1040
+ );
1041
+
1042
+ if ( isset( $cart_item['booking']['_persons'] ) ) {
1043
+ foreach ( $cart_item['booking']['_persons'] as $person_id => $value ) {
1044
+ $booking_info[ 'wc_bookings_field_persons_' . apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $current_language ) ] = $value;
1045
+ }
1046
+ }
1047
+
1048
+ if ( isset( $cart_item['booking']['_resource_id'] ) ) {
1049
+ $booking_info['wc_bookings_field_resource'] = apply_filters( 'translate_object_id', $cart_item['booking']['_resource_id'], 'bookable_resource', false, $current_language );
1050
+ }
1051
+
1052
+ if ( isset( $cart_item['booking']['_duration'] ) ) {
1053
+ $booking_info['wc_bookings_field_duration'] = $cart_item['booking']['_duration'];
1054
+ }
1055
+
1056
+ if ( isset( $cart_item['booking']['_time'] ) ) {
1057
+ $booking_info['wc_bookings_field_start_date_time'] = $cart_item['booking']['_time'];
1058
+ }
1059
+
1060
+ $booking_form = new WC_Booking_Form( wc_get_product( $current_id ) );
1061
+
1062
+ $prod_qty = get_post_meta( $current_id, '_wc_booking_qty', true );
1063
+ update_post_meta( $current_id, '_wc_booking_qty', intval( $prod_qty + $cart_item['booking']['_qty'] ) );
1064
+ $cost = $booking_form->calculate_booking_cost( $booking_info );
1065
+ update_post_meta( $current_id, '_wc_booking_qty', $prod_qty );
1066
+
1067
+ if ( ! is_wp_error( $cost ) ) {
1068
+ $cart_item['data']->set_price( $cost );
1069
+ }
1070
+ }
1071
+
1072
+ }
1073
+
1074
+ return $cart_item;
1075
+
1076
+ }
1077
+
1078
+ function booking_currency_dropdown() {
1079
+
1080
+
1081
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1082
+ $current_booking_currency = $this->get_cookie_booking_currency();
1083
+
1084
+ $wc_currencies = get_woocommerce_currencies();
1085
+ $currencies = $this->woocommerce_wpml->multi_currency->get_currencies( $include_default = true );
1086
+ ?>
1087
+ <tr valign="top">
1088
+ <th scope="row"><?php _e( 'Booking currency', 'woocommerce-multilingual' ); ?></th>
1089
+ <td>
1090
+ <select id="dropdown_booking_currency">
1091
+
1092
+ <?php foreach ( $currencies as $currency => $count ): ?>
1093
+
1094
+ <option
1095
+ value="<?php echo $currency ?>" <?php echo $current_booking_currency == $currency ? 'selected="selected"' : ''; ?>><?php echo $wc_currencies[ $currency ]; ?></option>
1096
+
1097
+ <?php endforeach; ?>
1098
+
1099
+ </select>
1100
+ </td>
1101
+ </tr>
1102
+
1103
+ <?php
1104
+
1105
+ $wcml_booking_set_currency_nonce = wp_create_nonce( 'booking_set_currency' );
1106
+
1107
+ wc_enqueue_js( "
1108
+
1109
+ jQuery(document).on('change', '#dropdown_booking_currency', function(){
1110
+ jQuery.ajax({
1111
+ url: ajaxurl,
1112
+ type: 'post',
1113
+ data: {
1114
+ action: 'wcml_booking_set_currency',
1115
+ currency: jQuery('#dropdown_booking_currency').val(),
1116
+ wcml_nonce: '" . $wcml_booking_set_currency_nonce . "'
1117
+ },
1118
+ success: function( response ){
1119
+ if(typeof response.error !== 'undefined'){
1120
+ alert(response.error);
1121
+ }else{
1122
+ window.location = window.location.href;
1123
+ }
1124
+ }
1125
+ })
1126
+ });
1127
+ " );
1128
+
1129
+ }
1130
+
1131
+ }
1132
+
1133
+ function set_booking_currency_ajax() {
1134
+
1135
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
1136
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'booking_set_currency' ) ) {
1137
+ echo json_encode( array( 'error' => __( 'Invalid nonce', 'woocommerce-multilingual' ) ) );
1138
+ die();
1139
+ }
1140
+
1141
+ $this->set_booking_currency( filter_input( INPUT_POST, 'currency', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
1142
+
1143
+ die();
1144
+ }
1145
+
1146
+ function set_booking_currency( $currency_code = false ) {
1147
+
1148
+ if ( ! isset( $_COOKIE ['_wcml_booking_currency'] ) && ! headers_sent() ) {
1149
+
1150
+
1151
+ $currency_code = get_woocommerce_currency();
1152
+
1153
+ if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT ) {
1154
+ $order_currencies = $this->woocommerce_wpml->multi_currency->orders->get_orders_currencies();
1155
+
1156
+ if ( ! isset( $order_currencies[ $currency_code ] ) ) {
1157
+ foreach ( $order_currencies as $currency_code => $count ) {
1158
+ $currency_code = $currency_code;
1159
+ break;
1160
+ }
1161
+ }
1162
+ }
1163
+ }
1164
+
1165
+ if ( $currency_code ) {
1166
+ setcookie( '_wcml_booking_currency', $currency_code, time() + 86400, COOKIEPATH, COOKIE_DOMAIN );
1167
+ }
1168
+
1169
+ }
1170
+
1171
+ function get_cookie_booking_currency() {
1172
+
1173
+ if ( isset( $_COOKIE ['_wcml_booking_currency'] ) ) {
1174
+ $currency = $_COOKIE['_wcml_booking_currency'];
1175
+ } else {
1176
+ $currency = get_woocommerce_currency();
1177
+ }
1178
+
1179
+ return $currency;
1180
+ }
1181
+
1182
+ function filter_booking_currency_symbol( $currency ) {
1183
+ global $pagenow;
1184
+
1185
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1186
+ if ( isset( $_COOKIE ['_wcml_booking_currency'] ) && $pagenow == 'edit.php' && isset( $_GET['page'] ) && $_GET['page'] == 'create_booking' ) {
1187
+ $currency = get_woocommerce_currency_symbol( $_COOKIE ['_wcml_booking_currency'] );
1188
+ }
1189
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_booking_currency_symbol' ) );
1190
+
1191
+ return $currency;
1192
+ }
1193
+
1194
+ function create_booking_page_client_currency( $currency ) {
1195
+ global $pagenow;
1196
+
1197
+ if ( wpml_is_ajax() && isset( $_POST['form'] ) ) {
1198
+ parse_str( $_POST['form'], $posted );
1199
+ }
1200
+
1201
+ 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 ) ) {
1202
+ $currency = $this->get_cookie_booking_currency();
1203
+ }
1204
+
1205
+ return $currency;
1206
+ }
1207
+
1208
+ function set_order_currency_on_create_booking_page( $order_id ) {
1209
+ update_post_meta( $order_id, '_order_currency', $this->get_cookie_booking_currency() );
1210
+
1211
+ update_post_meta( $order_id, 'wpml_language', $this->sitepress->get_current_language() );
1212
+
1213
+ }
1214
+
1215
+ function filter_get_booking_products_args( $args ) {
1216
+ if ( isset( $args['suppress_filters'] ) ) {
1217
+ $args['suppress_filters'] = false;
1218
+ }
1219
+
1220
+ return $args;
1221
+ }
1222
+
1223
+ function custom_box_html( $obj, $product_id, $data ) {
1224
+ if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1225
+ return;
1226
+ }
1227
+
1228
+ $bookings_section = new WPML_Editor_UI_Field_Section( __( 'Bookings', 'woocommerce-multilingual' ) );
1229
+
1230
+ if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1231
+ $group = new WPML_Editor_UI_Field_Group( '', true );
1232
+ $booking_field = new WPML_Editor_UI_Single_Line_Field( '_wc_booking_resouce_label', __( 'Resources Label', 'woocommerce-multilingual' ), $data, true );
1233
+ $group->add_field( $booking_field );
1234
+ $bookings_section->add_field( $group );
1235
+ }
1236
+
1237
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1238
+
1239
+ if ( $orig_resources ) {
1240
+ $group = new WPML_Editor_UI_Field_Group( __( 'Resources', 'woocommerce-multilingual' ) );
1241
+ $group_title = __( 'Resources', 'woocommerce-multilingual' );
1242
+ foreach ( $orig_resources as $resource_id => $cost ) {
1243
+
1244
+ if ( $resource_id == 'custom_costs' ) {
1245
+ continue;
1246
+ }
1247
+
1248
+ $group = new WPML_Editor_UI_Field_Group( $group_title );
1249
+ $group_title = '';
1250
+
1251
+ $resource_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-resource_' . $resource_id . '_title', __( 'Title', 'woocommerce-multilingual' ), $data, true );
1252
+ $group->add_field( $resource_field );
1253
+ $bookings_section->add_field( $group );
1254
+ }
1255
+
1256
+ }
1257
+
1258
+ $original_persons = $this->get_original_persons( $product_id );
1259
+ end( $original_persons );
1260
+ $last_key = key( $original_persons );
1261
+ $divider = true;
1262
+ $group_title = __( 'Person Types', 'woocommerce-multilingual' );
1263
+ foreach ( $original_persons as $person_id ) {
1264
+ if ( $person_id == $last_key ) {
1265
+ $divider = false;
1266
+ }
1267
+ $group = new WPML_Editor_UI_Field_Group( $group_title, $divider );
1268
+ $group_title = '';
1269
+
1270
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_title', __( 'Person Type Name', 'woocommerce-multilingual' ), $data, false );
1271
+ $group->add_field( $person_field );
1272
+ $person_field = new WPML_Editor_UI_Single_Line_Field( 'bookings-person_' . $person_id . '_description', __( 'Description', 'woocommerce-multilingual' ), $data, false );
1273
+ $group->add_field( $person_field );
1274
+ $bookings_section->add_field( $group );
1275
+
1276
+ }
1277
+
1278
+ if ( $orig_resources || $original_persons ) {
1279
+ $obj->add_field( $bookings_section );
1280
+ }
1281
+
1282
+ }
1283
+
1284
+
1285
+ function custom_box_html_data( $data, $product_id, $translation, $lang ) {
1286
+
1287
+ if ( wc_get_product( $product_id )->product_type != 'booking' ) {
1288
+ return $data;
1289
+ }
1290
+
1291
+ if ( get_post_meta( $product_id, '_wc_booking_has_resources', true ) == 'yes' ) {
1292
+
1293
+ $data['_wc_booking_resouce_label'] = array( 'original' => get_post_meta( $product_id, '_wc_booking_resouce_label', true ) );
1294
+ $data['_wc_booking_resouce_label']['translation'] = $translation ? get_post_meta( $translation->ID, '_wc_booking_resouce_label', true ) : '';
1295
+ }
1296
+
1297
+ $orig_resources = $this->get_original_resources( $product_id );
1298
+
1299
+ if ( $orig_resources && is_array( $orig_resources ) ) {
1300
+
1301
+ foreach ( $orig_resources as $resource_id => $cost ) {
1302
+
1303
+ if ( 'custom_costs' === $resource_id ) {
1304
+ continue;
1305
+ }
1306
+ $data[ 'bookings-resource_' . $resource_id . '_title' ] = array( 'original' => get_the_title( $resource_id ) );
1307
+ global $sitepress;
1308
+ $trns_resource_id = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $lang );
1309
+ $data[ 'bookings-resource_' . $resource_id . '_title' ]['translation'] = $trns_resource_id ? get_the_title( $trns_resource_id ) : '';
1310
+ }
1311
+ }
1312
+
1313
+ $original_persons = $this->get_original_persons( $product_id );
1314
+
1315
+ foreach ( $original_persons as $person_id ) {
1316
+
1317
+ $data[ 'bookings-person_' . $person_id . '_title' ] = array( 'original' => get_the_title( $person_id ) );
1318
+ $data[ 'bookings-person_' . $person_id . '_description' ] = array( 'original' => get_post( $person_id )->post_excerpt );
1319
+
1320
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $lang );
1321
+ $data[ 'bookings-person_' . $person_id . '_title' ]['translation'] = $trnsl_person_id ? get_the_title( $trnsl_person_id ) : '';
1322
+ $data[ 'bookings-person_' . $person_id . '_description' ]['translation'] = $trnsl_person_id ? get_post( $trnsl_person_id )->post_excerpt : '';
1323
+
1324
+ }
1325
+
1326
+ return $data;
1327
+ }
1328
+
1329
+
1330
+ function get_original_resources( $product_id ) {
1331
+ $orig_resources = maybe_unserialize( get_post_meta( $product_id, '_resource_base_costs', true ) );
1332
+
1333
+ return $orig_resources;
1334
+ }
1335
+
1336
+ function get_original_persons( $product_id ) {
1337
+ $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 ) );
1338
+
1339
+ return $original_persons;
1340
+ }
1341
+
1342
+ function show_custom_blocks_for_resources_and_persons( $check, $product_id, $product_content ) {
1343
+ if ( in_array( $product_content, array( 'wc_booking_resources', 'wc_booking_persons' ) ) ) {
1344
+ return false;
1345
+ }
1346
+
1347
+ return $check;
1348
+ }
1349
+
1350
+ function remove_custom_fields_to_translate( $exception, $product_id, $meta_key ) {
1351
+ if ( in_array( $meta_key, array( '_resource_base_costs', '_resource_block_costs' ) ) ) {
1352
+ $exception = true;
1353
+ }
1354
+
1355
+ return $exception;
1356
+ }
1357
+
1358
+ function remove_single_custom_fields_to_translate( $fields ) {
1359
+ $fields[] = '_wc_booking_resouce_label';
1360
+
1361
+ return $fields;
1362
+ }
1363
+
1364
+ function product_content_resource_label( $meta_key, $product_id ) {
1365
+ if ( $meta_key == '_wc_booking_resouce_label' ) {
1366
+ return __( 'Resources label', 'woocommerce-multilingual' );
1367
+ }
1368
+
1369
+ return $meta_key;
1370
+ }
1371
+
1372
+ function wcml_products_tab_sync_resources_and_persons( $original_product_id, $tr_product_id, $data, $language ) {
1373
+ global $wpml_post_translations;
1374
+
1375
+ remove_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1376
+
1377
+ $orig_resources = $orig_resources = $this->get_original_resources( $original_product_id );;
1378
+
1379
+ if ( $orig_resources ) {
1380
+
1381
+ foreach ( $orig_resources as $orig_resource_id => $cost ) {
1382
+
1383
+ $resource_id = apply_filters( 'translate_object_id', $orig_resource_id, 'bookable_resource', false, $language );
1384
+ $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 );
1385
+
1386
+ if ( is_null( $resource_id ) ) {
1387
+
1388
+ if ( $orig_resource ) {
1389
+ $resource_id = $this->duplicate_resource( $tr_product_id, $orig_resource, $language );
1390
+ } else {
1391
+ continue;
1392
+ }
1393
+
1394
+ } else {
1395
+ //update_relationship
1396
+
1397
+ $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 ) );
1398
+
1399
+ if ( ! $exist ) {
1400
+
1401
+ $this->wpdb->insert(
1402
+ $this->wpdb->prefix . 'wc_booking_relationships',
1403
+ array(
1404
+ 'product_id' => $tr_product_id,
1405
+ 'resource_id' => $resource_id,
1406
+ 'sort_order' => $orig_resource->sort_order
1407
+ )
1408
+ );
1409
+
1410
+ }
1411
+
1412
+ }
1413
+
1414
+
1415
+ $this->wpdb->update(
1416
+ $this->wpdb->posts,
1417
+ array(
1418
+ 'post_title' => $data[ md5( 'bookings-resource_' . $orig_resource_id . '_title' ) ]
1419
+ ),
1420
+ array(
1421
+ 'ID' => $resource_id
1422
+ )
1423
+ );
1424
+
1425
+ update_post_meta( $resource_id, 'wcml_is_translated', true );
1426
+
1427
+ }
1428
+
1429
+ //sync resources data
1430
+ $this->sync_resources( $original_product_id, $tr_product_id, $language, false );
1431
+
1432
+ }
1433
+
1434
+ $original_persons = $this->get_original_persons( $original_product_id );
1435
+
1436
+ //sync persons
1437
+ if ( $original_persons ) {
1438
+
1439
+ foreach ( $original_persons as $original_person_id ) {
1440
+
1441
+ $person_id = apply_filters( 'translate_object_id', $original_person_id, 'bookable_person', false, $language );
1442
+
1443
+ if ( is_null( $person_id ) ) {
1444
+
1445
+ $person_id = $this->duplicate_person( $tr_product_id, $original_person_id, $language );
1446
+
1447
+ } else {
1448
+
1449
+ $this->wpdb->update(
1450
+ $this->wpdb->posts,
1451
+ array(
1452
+ 'post_parent' => $tr_product_id
1453
+ ),
1454
+ array(
1455
+ 'ID' => $person_id
1456
+ )
1457
+ );
1458
+
1459
+ }
1460
+
1461
+ $this->wpdb->update(
1462
+ $this->wpdb->posts,
1463
+ array(
1464
+ 'post_title' => $data[ md5( 'bookings-person_' . $original_person_id . '_title' ) ],
1465
+ 'post_excerpt' => $data[ md5( 'bookings-person_' . $original_person_id . '_description' ) ],
1466
+ ),
1467
+ array(
1468
+ 'ID' => $person_id
1469
+ )
1470
+ );
1471
+
1472
+ update_post_meta( $person_id, 'wcml_is_translated', true );
1473
+
1474
+ }
1475
+
1476
+ //sync persons data
1477
+ $this->sync_persons( $original_product_id, $tr_product_id, $language, false );
1478
+
1479
+ }
1480
+
1481
+ add_action( 'save_post', array( $wpml_post_translations, 'save_post_actions' ), 100, 2 );
1482
+
1483
+ }
1484
+
1485
+ function duplicate_booking_for_translations( $booking_id, $lang = false ) {
1486
+ $booking_object = get_post( $booking_id );
1487
+
1488
+ $booking_data = array(
1489
+ 'post_type' => 'wc_booking',
1490
+ 'post_title' => $booking_object->post_title,
1491
+ 'post_status' => $booking_object->post_status,
1492
+ 'ping_status' => 'closed',
1493
+ 'post_parent' => $booking_object->post_parent,
1494
+ );
1495
+
1496
+ $active_languages = $this->sitepress->get_active_languages();
1497
+
1498
+ foreach ( $active_languages as $language ) {
1499
+
1500
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1501
+
1502
+ if ( ! $lang ) {
1503
+ $booking_language = $this->sitepress->get_element_language_details( $booking_product_id, 'post_product' );
1504
+ if ( $booking_language->language_code == $language['code'] ) {
1505
+ continue;
1506
+ }
1507
+ } elseif ( $lang != $language['code'] ) {
1508
+ continue;
1509
+ }
1510
+
1511
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1512
+ $trnsl_booking_persons = array();
1513
+
1514
+ if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1515
+ foreach ( $booking_persons as $person_id => $person_count ) {
1516
+
1517
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language['code'] );
1518
+
1519
+ if ( is_null( $trnsl_person_id ) ) {
1520
+ $trnsl_booking_persons[] = $person_count;
1521
+ } else {
1522
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1523
+ }
1524
+
1525
+ }
1526
+ }
1527
+
1528
+ $trnsl_booking_id = wp_insert_post( $booking_data );
1529
+ $trid = $this->sitepress->get_element_trid( $booking_id );
1530
+ $this->sitepress->set_element_language_details( $trnsl_booking_id, 'post_wc_booking', $trid, $language['code'] );
1531
+
1532
+ $meta_args = array(
1533
+ '_booking_order_item_id' => get_post_meta( $booking_id, '_booking_order_item_id', true ),
1534
+ '_booking_product_id' => $this->get_translated_booking_product_id( $booking_id, $language['code'] ),
1535
+ '_booking_resource_id' => $this->get_translated_booking_resource_id( $booking_id, $language['code'] ),
1536
+ '_booking_persons' => $this->get_translated_booking_persons_ids( $booking_id, $language['code'] ),
1537
+ '_booking_cost' => get_post_meta( $booking_id, '_booking_cost', true ),
1538
+ '_booking_start' => get_post_meta( $booking_id, '_booking_start', true ),
1539
+ '_booking_end' => get_post_meta( $booking_id, '_booking_end', true ),
1540
+ '_booking_all_day' => intval( get_post_meta( $booking_id, '_booking_all_day', true ) ),
1541
+ '_booking_parent_id' => get_post_meta( $booking_id, '_booking_parent_id', true ),
1542
+ '_booking_customer_id' => get_post_meta( $booking_id, '_booking_customer_id', true ),
1543
+ '_booking_duplicate_of' => $booking_id,
1544
+ '_language_code' => $language['code'],
1545
+ );
1546
+
1547
+ foreach ( $meta_args as $key => $value ) {
1548
+ update_post_meta( $trnsl_booking_id, $key, $value );
1549
+ }
1550
+
1551
+ WC_Cache_Helper::get_transient_version( 'bookings', true );
1552
+
1553
+ }
1554
+
1555
+
1556
+ }
1557
+
1558
+ function get_translated_booking_product_id( $booking_id, $language ) {
1559
+
1560
+ $booking_product_id = get_post_meta( $booking_id, '_booking_product_id', true );
1561
+ $trnsl_booking_product_id = '';
1562
+
1563
+ if ( $booking_product_id ) {
1564
+ $trnsl_booking_product_id = apply_filters( 'translate_object_id', $booking_product_id, 'product', false, $language );
1565
+ if ( is_null( $trnsl_booking_product_id ) ) {
1566
+ $trnsl_booking_product_id = '';
1567
+ }
1568
+ }
1569
+
1570
+ return $trnsl_booking_product_id;
1571
+
1572
+ }
1573
+
1574
+ function get_translated_booking_resource_id( $booking_id, $language ) {
1575
+
1576
+ $booking_resource_id = get_post_meta( $booking_id, '_booking_resource_id', true );
1577
+ $trnsl_booking_resource_id = '';
1578
+
1579
+ if ( $booking_resource_id ) {
1580
+ $trnsl_booking_resource_id = apply_filters( 'translate_object_id', $booking_resource_id, 'bookable_resource', false, $language );
1581
+
1582
+ if ( is_null( $trnsl_booking_resource_id ) ) {
1583
+ $trnsl_booking_resource_id = '';
1584
+ }
1585
+ }
1586
+
1587
+ return $trnsl_booking_resource_id;
1588
+ }
1589
+
1590
+ function get_translated_booking_persons_ids( $booking_id, $language ) {
1591
+
1592
+ $booking_persons = maybe_unserialize( get_post_meta( $booking_id, '_booking_persons', true ) );
1593
+ $trnsl_booking_persons = array();
1594
+
1595
+ if ( is_array( $booking_persons ) && ! empty( $booking_persons ) ) {
1596
+ foreach ( $booking_persons as $person_id => $person_count ) {
1597
+
1598
+ $trnsl_person_id = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $language );
1599
+
1600
+ if ( is_null( $trnsl_person_id ) ) {
1601
+ $trnsl_booking_persons[] = $person_count;
1602
+ } else {
1603
+ $trnsl_booking_persons[ $trnsl_person_id ] = $person_count;
1604
+ }
1605
+
1606
+ }
1607
+ }
1608
+
1609
+ return $trnsl_booking_persons;
1610
+
1611
+ }
1612
+
1613
+ function update_status_for_translations( $booking_id ) {
1614
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1615
+
1616
+ foreach ( $translated_bookings as $booking ) {
1617
+
1618
+ $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 );
1619
+ $language = get_post_meta( $booking->post_id, '_language_code', true );
1620
+
1621
+ $this->wpdb->update(
1622
+ $this->wpdb->posts,
1623
+ array(
1624
+ 'post_status' => $status,
1625
+ 'post_parent' => wp_get_post_parent_id( $booking_id ),
1626
+ ),
1627
+ array(
1628
+ 'ID' => $booking->post_id
1629
+ )
1630
+ );
1631
+
1632
+ update_post_meta( $booking->post_id, '_booking_product_id', $this->get_translated_booking_product_id( $booking_id, $language ) );
1633
+ update_post_meta( $booking->post_id, '_booking_resource_id', $this->get_translated_booking_resource_id( $booking_id, $language ) );
1634
+ update_post_meta( $booking->post_id, '_booking_persons', $this->get_translated_booking_persons_ids( $booking_id, $language ) );
1635
+
1636
+ }
1637
+
1638
+ }
1639
+
1640
+ function get_translated_bookings( $booking_id ) {
1641
+ $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 ) );
1642
+
1643
+ return $translated_bookings;
1644
+ }
1645
+
1646
+ public function booking_filters_query( $query ) {
1647
+ global $typenow;
1648
+
1649
+ if ( ( isset( $query->query_vars['post_type'] ) && $query->query_vars['post_type'] == 'wc_booking' ) ) {
1650
+
1651
+ $current_lang = $this->sitepress->get_current_language();
1652
+
1653
+ $product_ids = $this->wpdb->get_col( $this->wpdb->prepare(
1654
+ "SELECT element_id
1655
+ FROM {$this->wpdb->prefix}icl_translations
1656
+ WHERE language_code = %s AND element_type = 'post_product'", $current_lang ) );
1657
+
1658
+ $product_ids = array_diff( $product_ids, array( null ) );
1659
+
1660
+ if ( ( ! isset( $_GET['lang'] ) || ( isset( $_GET['lang'] ) && $_GET['lang'] != 'all' ) ) ) {
1661
+ $query->query_vars['meta_query'][] = array(
1662
+ 'relation' => 'OR',
1663
+ array(
1664
+ 'key' => '_language_code',
1665
+ 'value' => $current_lang,
1666
+ 'compare ' => '='
1667
+ ),
1668
+ array(
1669
+ 'key' => '_booking_product_id',
1670
+ 'value' => $product_ids,
1671
+ 'compare ' => 'IN'
1672
+ )
1673
+ );
1674
+ }
1675
+ }
1676
+
1677
+ return $query;
1678
+ }
1679
+
1680
+ function bookings_in_date_range_query( $booking_ids ) {
1681
+ foreach ( $booking_ids as $key => $booking_id ) {
1682
+
1683
+ $language_code = $this->sitepress->get_language_for_element( get_post_meta( $booking_id, '_booking_product_id', true ), 'post_product' );
1684
+ $current_language = $this->sitepress->get_current_language();
1685
+
1686
+ if ( $language_code != $current_language ) {
1687
+ unset( $booking_ids[ $key ] );
1688
+ }
1689
+
1690
+ }
1691
+
1692
+ return $booking_ids;
1693
+
1694
+ }
1695
+
1696
+ function clear_transient_fields() {
1697
+
1698
+ if ( isset( $_GET['post_type'] ) && $_GET['post_type'] == 'wc_booking' && isset( $_GET['page'] ) && $_GET['page'] == 'booking_calendar' ) {
1699
+
1700
+ //delete transient fields
1701
+ $this->wpdb->query( "
1702
+ DELETE FROM {$this->wpdb->options}
1703
+ WHERE option_name LIKE '%book_dr_%'
1704
+ " );
1705
+
1706
+ }
1707
+
1708
+ }
1709
+
1710
+ function delete_bookings( $booking_id ) {
1711
+
1712
+ if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1713
+
1714
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1715
+
1716
+ remove_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1717
+
1718
+ foreach ( $translated_bookings as $booking ) {
1719
+ $this->wpdb->update(
1720
+ $this->wpdb->posts,
1721
+ array(
1722
+ 'post_parent' => 0
1723
+ ),
1724
+ array(
1725
+ 'ID' => $booking->post_id
1726
+ )
1727
+ );
1728
+
1729
+ wp_delete_post( $booking->post_id );
1730
+
1731
+ }
1732
+
1733
+ add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
1734
+ }
1735
+
1736
+ }
1737
+
1738
+ function trash_bookings( $booking_id ) {
1739
+
1740
+ if ( $booking_id > 0 && get_post_type( $booking_id ) == 'wc_booking' ) {
1741
+
1742
+ $translated_bookings = $this->get_translated_bookings( $booking_id );
1743
+
1744
+ foreach ( $translated_bookings as $booking ) {
1745
+
1746
+ $this->wpdb->update(
1747
+ $this->wpdb->posts,
1748
+ array(
1749
+ 'post_status' => 'trash'
1750
+ ),
1751
+ array(
1752
+ 'ID' => $booking->post_id
1753
+ )
1754
+ );
1755
+
1756
+ }
1757
+
1758
+ }
1759
+
1760
+ }
1761
+
1762
+ function append_persons_to_translation_package( $package, $post ) {
1763
+
1764
+ if ( $post->post_type == 'product' ) {
1765
+ $product = wc_get_product( $post->ID );
1766
+
1767
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1768
+ $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1769
+
1770
+ if ( $product_type == 'booking' ) {
1771
+
1772
+ $bookable_product = new WC_Product_Booking( $post->ID );
1773
+
1774
+ $person_types = $bookable_product->get_person_types();
1775
+
1776
+ foreach ( $person_types as $person_type ) {
1777
+
1778
+ $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':name' ] = array(
1779
+ 'translate' => 1,
1780
+ 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1781
+ 'format' => 'base64'
1782
+ );
1783
+
1784
+ $package['contents'][ 'wc_bookings:person:' . $person_type->ID . ':description' ] = array(
1785
+ 'translate' => 1,
1786
+ 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1787
+ 'format' => 'base64'
1788
+ );
1789
+
1790
+ }
1791
+
1792
+ }
1793
+
1794
+ }
1795
+
1796
+ return $package;
1797
+
1798
+ }
1799
+
1800
+ function save_person_translation( $post_id, $data, $job ) {
1801
+ $person_translations = array();
1802
+
1803
+ $product = wc_get_product( $post_id );
1804
+
1805
+ if ( $product && $product->product_type == 'booking' ) {
1806
+
1807
+
1808
+ foreach ( $data as $value ) {
1809
+
1810
+ if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1811
+
1812
+ $exp = explode( ':', $value['field_type'] );
1813
+
1814
+ $person_id = $exp[2];
1815
+ $field = $exp[3];
1816
+
1817
+ $person_translations[ $person_id ][ $field ] = $value['data'];
1818
+
1819
+ }
1820
+
1821
+ }
1822
+
1823
+ if ( $person_translations ) {
1824
+
1825
+ foreach ( $person_translations as $person_id => $pt ) {
1826
+
1827
+ $person_trid = $this->sitepress->get_element_trid( $person_id, 'post_bookable_person' );
1828
+
1829
+
1830
+ $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1831
+
1832
+ if ( empty( $person_id_translated ) ) {
1833
+
1834
+ $person_post = array(
1835
+
1836
+ 'post_type' => 'bookable_person',
1837
+ 'post_status' => 'publish',
1838
+ 'post_title' => $pt['name'],
1839
+ 'post_parent' => $post_id,
1840
+ 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1841
+
1842
+ );
1843
+
1844
+ $person_id_translated = wp_insert_post( $person_post );
1845
+
1846
+ $this->sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1847
+
1848
+ } else {
1849
+
1850
+ $person_post = array(
1851
+ 'ID' => $person_id_translated,
1852
+ 'post_title' => $pt['name'],
1853
+ 'post_excerpt' => isset( $pt['description'] ) ? $pt['description'] : ''
1854
+ );
1855
+
1856
+ wp_update_post( $person_post );
1857
+
1858
+ }
1859
+
1860
+ }
1861
+
1862
+ }
1863
+
1864
+ }
1865
+
1866
+ }
1867
+
1868
+ function append_resources_to_translation_package( $package, $post ) {
1869
+
1870
+ if ( $post->post_type == 'product' ) {
1871
+ $product = wc_get_product( $post->ID );
1872
+
1873
+ //WC_Product::get_type() available from WooCommerce 2.4.0
1874
+ $product_type = method_exists( $product, 'get_type' ) ? $product->get_type() : $product->product_type;
1875
+
1876
+ if ( $product_type == 'booking' && $product->has_resources() ) {
1877
+
1878
+ $resources = $product->get_resources();
1879
+
1880
+ foreach ( $resources as $resource ) {
1881
+
1882
+ $package['contents'][ 'wc_bookings:resource:' . $resource->ID . ':name' ] = array(
1883
+ 'translate' => 1,
1884
+ 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1885
+ 'format' => 'base64'
1886
+ );
1887
+
1888
+ }
1889
+
1890
+ }
1891
+
1892
+ }
1893
+
1894
+ return $package;
1895
+
1896
+ }
1897
+
1898
+ function save_resource_translation( $post_id, $data, $job ) {
1899
+ $resource_translations = array();
1900
+
1901
+ $product = wc_get_product( $post_id );
1902
+
1903
+ if ( $product && $product->product_type == 'booking' ) {
1904
+
1905
+ foreach ( $data as $value ) {
1906
+
1907
+ if ( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1908
+
1909
+ $exp = explode( ':', $value['field_type'] );
1910
+
1911
+ $resource_id = $exp[2];
1912
+ $field = $exp[3];
1913
+
1914
+ $resource_translations[ $resource_id ][ $field ] = $value['data'];
1915
+
1916
+ }
1917
+
1918
+ }
1919
+
1920
+ if ( $resource_translations ) {
1921
+
1922
+ foreach ( $resource_translations as $resource_id => $rt ) {
1923
+
1924
+ $resource_trid = $this->sitepress->get_element_trid( $resource_id, 'post_bookable_resource' );
1925
+
1926
+ $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1927
+
1928
+ if ( empty( $resource_id_translated ) ) {
1929
+
1930
+ $resource_post = array(
1931
+
1932
+ 'post_type' => 'bookable_resource',
1933
+ 'post_status' => 'publish',
1934
+ 'post_title' => $rt['name'],
1935
+ 'post_parent' => $post_id
1936
+ );
1937
+
1938
+ $resource_id_translated = wp_insert_post( $resource_post );
1939
+
1940
+ $this->sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_resource', $resource_trid, $job->language_code );
1941
+
1942
+ $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 ) );
1943
+ $relationship = array(
1944
+ 'product_id' => $post_id,
1945
+ 'resource_id' => $resource_id_translated,
1946
+ 'sort_order' => $sort_order
1947
+ );
1948
+ $this->wpdb->insert( $this->wpdb->prefix . 'wc_booking_relationships', $relationship );
1949
+
1950
+ } else {
1951
+
1952
+ $resource_post = array(
1953
+ 'ID' => $resource_id_translated,
1954
+ 'post_title' => $rt['name']
1955
+ );
1956
+
1957
+ wp_update_post( $resource_post );
1958
+
1959
+ $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 ) );
1960
+ $this->wpdb->update( $this->wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1961
+ array( 'product_id' => $post_id, 'resource_id' => $resource_id_translated ) );
1962
+
1963
+
1964
+ }
1965
+
1966
+
1967
+ }
1968
+
1969
+ }
1970
+
1971
+ }
1972
+
1973
+ }
1974
+
1975
+ function wcml_js_lock_fields_ids( $ids ) {
1976
+
1977
+ $ids = array_merge( $ids, array(
1978
+ '_wc_booking_has_resources',
1979
+ '_wc_booking_has_persons',
1980
+ '_wc_booking_duration_type',
1981
+ '_wc_booking_duration',
1982
+ '_wc_booking_duration_unit',
1983
+ '_wc_booking_calendar_display_mode',
1984
+ '_wc_booking_requires_confirmation',
1985
+ '_wc_booking_user_can_cancel',
1986
+ '_wc_accommodation_booking_min_duration',
1987
+ '_wc_accommodation_booking_max_duration',
1988
+ '_wc_accommodation_booking_max_duration',
1989
+ '_wc_accommodation_booking_calendar_display_mode',
1990
+ '_wc_accommodation_booking_requires_confirmation',
1991
+ '_wc_accommodation_booking_user_can_cancel',
1992
+ '_wc_accommodation_booking_cancel_limit',
1993
+ '_wc_accommodation_booking_cancel_limit_unit',
1994
+ '_wc_accommodation_booking_qty',
1995
+ '_wc_accommodation_booking_min_date',
1996
+ '_wc_accommodation_booking_min_date_unit',
1997
+ '_wc_accommodation_booking_max_date',
1998
+ '_wc_accommodation_booking_max_date_unit',
1999
+ 'bookings_pricing select',
2000
+ 'bookings_resources select',
2001
+ 'bookings_availability select',
2002
+ 'bookings_persons input[type="checkbox"]'
2003
+ ) );
2004
+
2005
+ return $ids;
2006
+ }
2007
+
2008
+ /**
2009
+ * @param array $args
2010
+ *
2011
+ * @return array
2012
+ */
2013
+ public function filter_get_booking_resources_args( $args ) {
2014
+
2015
+ $screen = get_current_screen();
2016
+ if ( $screen->id == 'product' ) {
2017
+ $args['suppress_filters'] = false;
2018
+ }
2019
+
2020
+ return $args;
2021
+
2022
+ }
2023
+
2024
+ /**
2025
+ * @param array $currencies
2026
+ * @param int $post_id
2027
+ *
2028
+ * @return bool
2029
+ */
2030
+ private function update_booking_costs( $currencies = array(), $post_id = 0 ) {
2031
+ $booking_options = array(
2032
+ 'wcml_wc_booking_cost' => '_wc_booking_cost_',
2033
+ 'wcml_wc_booking_base_cost' => '_wc_booking_base_cost_',
2034
+ 'wcml_wc_display_cost' => '_wc_display_cost_',
2035
+ );
2036
+
2037
+ foreach ( $currencies as $code => $currency ) {
2038
+ foreach ( $booking_options as $booking_options_post_key => $booking_options_meta_key_prefix ) {
2039
+ if ( isset( $_POST[ $booking_options_post_key ][ $code ] ) ) {
2040
+ update_post_meta( $post_id, $booking_options_meta_key_prefix . $code, sanitize_text_field( $_POST[ $booking_options_post_key ][ $code ] ) );
2041
+ }
2042
+ }
2043
+ }
2044
+
2045
+ return true;
2046
+ }
2047
+
2048
+ /**
2049
+ * @param array $currencies
2050
+ * @param int $post_id
2051
+ *
2052
+ * @return bool
2053
+ */
2054
+ private function update_booking_pricing( $currencies = array(), $post_id = 0 ) {
2055
+ $updated_meta = array();
2056
+ $booking_pricing = get_post_meta( $post_id, '_wc_booking_pricing', true );
2057
+ if ( empty( $booking_pricing ) ) {
2058
+ return false;
2059
+ }
2060
+
2061
+ foreach ( $booking_pricing as $key => $prices ) {
2062
+ $updated_meta[ $key ] = $prices;
2063
+ foreach ( $currencies as $code => $currency ) {
2064
+ if ( isset( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] ) ) {
2065
+ $updated_meta[ $key ][ 'base_cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_base_cost'][ $code ][ $key ] );
2066
+ }
2067
+ if ( isset( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] ) ) {
2068
+ $updated_meta[ $key ][ 'cost_' . $code ] = sanitize_text_field( $_POST['wcml_wc_booking_pricing_cost'][ $code ][ $key ] );
2069
+ }
2070
+ }
2071
+
2072
+ }
2073
+
2074
+ update_post_meta( $post_id, '_wc_booking_pricing', $updated_meta );
2075
+
2076
+ return true;
2077
+ }
2078
+
2079
+ /**
2080
+ * @param array $currencies
2081
+ * @param array $person_costs
2082
+ *
2083
+ * @return bool
2084
+ */
2085
+ private function update_booking_person_cost( $currencies = array(), $person_costs = array() ) {
2086
+ if ( empty( $person_costs ) ) {
2087
+ return false;
2088
+ }
2089
+
2090
+ foreach ( $person_costs as $person_id => $costs ) {
2091
+ foreach ( $currencies as $code => $currency ) {
2092
+ if ( isset( $costs[ $code ] ) ) {
2093
+ update_post_meta( $person_id, 'cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2094
+ }
2095
+ }
2096
+ }
2097
+
2098
+ return true;
2099
+ }
2100
+
2101
+ /**
2102
+ * @param array $currencies
2103
+ * @param array $block_costs
2104
+ *
2105
+ * @return bool
2106
+ */
2107
+ private function update_booking_person_block_cost( $currencies = array(), $block_costs = array() ) {
2108
+ if ( empty( $block_costs ) ) {
2109
+ return false;
2110
+ }
2111
+
2112
+ foreach ( $block_costs as $person_id => $costs ) {
2113
+ foreach ( $currencies as $code => $currency ) {
2114
+ if ( isset( $costs[ $code ] ) ) {
2115
+ update_post_meta( $person_id, 'block_cost_' . $code, sanitize_text_field( $costs[ $code ] ) );
2116
+ }
2117
+ }
2118
+ }
2119
+
2120
+ return true;
2121
+ }
2122
+
2123
+ /**
2124
+ * @param array $currencies
2125
+ * @param int $post_id
2126
+ * @param array $resource_cost
2127
+ *
2128
+ * @return bool
2129
+ */
2130
+ private function update_booking_resource_cost( $currencies = array(), $post_id = 0, $resource_cost = array() ) {
2131
+ if ( empty( $resource_cost ) ) {
2132
+ return false;
2133
+ }
2134
+
2135
+ $updated_meta = get_post_meta( $post_id, '_resource_base_costs', true );
2136
+ if ( ! is_array( $updated_meta ) ) {
2137
+ $updated_meta = array();
2138
+ }
2139
+
2140
+ $wc_booking_resource_costs = array();
2141
+
2142
+ foreach ( $resource_cost as $resource_id => $costs ) {
2143
+
2144
+ foreach ( $currencies as $code => $currency ) {
2145
+
2146
+ if ( isset( $costs[ $code ] ) ) {
2147
+ $wc_booking_resource_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2148
+ }
2149
+
2150
+ }
2151
+
2152
+ }
2153
+
2154
+ $updated_meta['custom_costs'] = $wc_booking_resource_costs;
2155
+
2156
+ update_post_meta( $post_id, '_resource_base_costs', $updated_meta );
2157
+
2158
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_base_costs' );
2159
+
2160
+ return true;
2161
+ }
2162
+
2163
+ /**
2164
+ * @param array $currencies
2165
+ * @param int $post_id
2166
+ *
2167
+ * @return bool
2168
+ */
2169
+ private function update_booking_resource_block_cost( $currencies = array(), $post_id = 0, $resource_block_cost = array() ) {
2170
+ if ( empty( $resource_block_cost ) ) {
2171
+ return false;
2172
+ }
2173
+
2174
+ $updated_meta = get_post_meta( $post_id, '_resource_block_costs', true );
2175
+
2176
+ $wc_booking_resource_block_costs = array();
2177
+
2178
+ foreach ( $resource_block_cost as $resource_id => $costs ) {
2179
+
2180
+ foreach ( $currencies as $code => $currency ) {
2181
+
2182
+ if ( isset( $costs[ $code ] ) ) {
2183
+ $wc_booking_resource_block_costs[ $code ][ $resource_id ] = sanitize_text_field( $costs[ $code ] );
2184
+ }
2185
+
2186
+ }
2187
+
2188
+ }
2189
+
2190
+ $updated_meta['custom_costs'] = $wc_booking_resource_block_costs;
2191
+
2192
+ update_post_meta( $post_id, '_resource_block_costs', $updated_meta );
2193
+
2194
+ $this->sync_resource_costs_with_translations( $post_id, '_resource_block_costs' );
2195
+
2196
+ return true;
2197
+ }
2198
+
2199
+ public function maybe_fix_double_serialized_wc_booking_availability( $mid, $object_id, $meta_key, $_meta_value ) {
2200
+ global $wpdb;
2201
+
2202
+ if ( version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
2203
+
2204
+ $meta_keys_to_fix = array(
2205
+ '_wc_booking_availability',
2206
+ '_wc_booking_pricing'
2207
+ );
2208
+
2209
+ if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
2210
+
2211
+ if ( is_string( $_meta_value ) ) {
2212
+ $wpdb->update( $wpdb->postmeta, array( 'meta_value' => $_meta_value ), array( 'meta_id' => $mid ) );
2213
+ }
2214
+
2215
+ }
2216
+
2217
+ }
2218
+
2219
+ }
2220
+
2221
+ public function extra_conditions_to_filter_bookings( $extra_conditions ){
2222
+
2223
+ if( isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'wc_booking' && !isset( $_GET[ 'post_status' ] ) ){
2224
+ $extra_conditions = str_replace( "GROUP BY", " AND post_status = 'confirmed' GROUP BY", $extra_conditions );
2225
+ }
2226
+
2227
+ return $extra_conditions;
2228
+ }
2229
+
2230
+ public function hide_bookings_type_on_tm_dashboard( $types ){
2231
+ unset( $types[ 'wc_booking' ] );
2232
+ return $types;
2233
+ }
2234
+
2235
  }
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_ajax_actions', 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_ajax_actions', 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_ajax_actions', 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_ajax_actions', 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-pip.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Pip{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'wcml_send_email_order_id', array( $this, 'wcml_send_email_order_id') );
8
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_pip_currency_symbol' ) );
9
+ add_filter( 'wcml_filter_currency_position', array( $this, 'filter_pip_currency_position' ) );
10
+
11
+ }
12
+
13
+ public function wcml_send_email_order_id( $order_id ){
14
+
15
+ $pip_order_id = $this->get_pip_order_id();
16
+
17
+ if( $pip_order_id ){
18
+ $order_id = $pip_order_id;
19
+ }
20
+
21
+ return $order_id;
22
+
23
+ }
24
+
25
+ public function filter_pip_currency_symbol( $currency_symbol ) {
26
+
27
+ remove_filter( 'woocommerce_currency_symbol', array( $this, 'filter_pip_currency_symbol' ) );
28
+
29
+ $currency = $this->get_pip_order_currency( );
30
+
31
+ if( $currency ){
32
+ $currency_symbol = get_woocommerce_currency_symbol( $currency );
33
+ }
34
+
35
+ add_filter( 'woocommerce_currency_symbol', array( $this, 'filter_pip_currency_symbol' ) );
36
+
37
+ return $currency_symbol;
38
+ }
39
+
40
+ public function filter_pip_currency_position( $currency ){
41
+
42
+ remove_filter( 'wcml_filter_currency_position', array( $this, 'filter_pip_currency_position' ) );
43
+
44
+ $currency = $this->get_pip_order_currency( $currency );
45
+
46
+ add_filter( 'wcml_filter_currency_position', array( $this, 'filter_pip_currency_position' ) );
47
+
48
+ return $currency;
49
+
50
+ }
51
+
52
+ public function get_pip_order_id(){
53
+
54
+ $order_id = false;
55
+
56
+ if( isset( $_GET[ 'wc_pip_action' ] ) && isset( $_GET[ 'order_id' ] ) ){
57
+ $order_id = $_GET[ 'order_id' ];
58
+ }elseif(
59
+ isset( $_POST[ 'action' ] ) &&
60
+ (
61
+ $_POST[ 'action' ] == 'wc_pip_order_send_email' ||
62
+ $_POST[ 'action' ] == 'wc_pip_send_email_packing_list'
63
+ ) &&
64
+ isset( $_POST[ 'order_id' ] )
65
+ ){
66
+ $order_id = $_POST[ 'order_id' ];
67
+ }
68
+
69
+ return $order_id;
70
+ }
71
+
72
+ public function get_pip_order_currency( $currency = false ){
73
+
74
+ $pip_order_id = $this->get_pip_order_id();
75
+
76
+ if( $pip_order_id ){
77
+
78
+ $the_order = new WC_Order( $pip_order_id );
79
+ if( $the_order ){
80
+ $currency = method_exists( $the_order, 'get_currency' ) ? $the_order->get_currency() : ( method_exists( $the_order, 'get_order_currency' ) ? $the_order->get_order_currency() : '' ) ;
81
+
82
+ if( !$currency && isset( $_COOKIE[ '_wcml_order_currency' ] ) ){
83
+ $currency = $_COOKIE[ '_wcml_order_currency' ];
84
+ }
85
+
86
+ }
87
+ }
88
+
89
+ return $currency;
90
+
91
+ }
92
+
93
+ }
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( $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
- }
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,412 +1,412 @@
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
-
69
- $i = 2;
70
- foreach( $bundle_data_array as $bundle_key => $bundle_data ){
71
-
72
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
73
- $tr_id = $key_data->tr_id;
74
- $tr_bundle_key = $key_data->tr_key;
75
-
76
- $tr_bundle[ $tr_bundle_key ] = $bundle_data;
77
- $tr_bundle[ $tr_bundle_key ][ 'product_id' ] = $tr_id;
78
- if( isset( $bundle_data[ 'product_title' ] ) ){
79
- if( $bundle_data[ 'override_title' ] == 'yes' ){
80
- $tr_bundle[ $tr_bundle_key ][ 'product_title' ] =
81
- isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] ) ?
82
- $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] :
83
- '';
84
- }else{
85
- $tr_title= get_the_title( $tr_id );
86
- $tr_bundle[ $tr_bundle_key ][ 'product_title' ] = $tr_title;
87
- }
88
- }
89
- if( isset( $bundle_data[ 'product_description' ] ) ){
90
- if( $bundle_data[ 'override_description' ] == 'yes' ){
91
- $tr_bundle[ $tr_bundle_key ][ 'product_description' ] =
92
- isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] ) ?
93
- $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] :
94
- '';
95
- }else{
96
- $tr_prod = get_post( $tr_id );
97
- $tr_desc = $tr_prod->post_excerpt;
98
- $tr_bundle[ $tr_bundle_key ][ 'product_description' ] = $tr_desc;
99
- }
100
- }
101
- if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
102
- $allowed_var = $bundle_data[ 'allowed_variations' ];
103
- foreach( $allowed_var as $key => $var_id ){
104
- $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
105
- $tr_bundle[ $tr_bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
106
- }
107
- }
108
- if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
109
- foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
110
-
111
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
112
- if( $term_id ){
113
- // Global Attribute
114
- $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
115
- $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
116
- $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
117
- }else{
118
- // Custom Attribute
119
- $args = array(
120
- 'post_type' => 'product_variation',
121
- 'meta_key' => 'attribute_'.$tax,
122
- 'meta_value' => $term_slug,
123
- 'meta_compare' => '='
124
- );
125
- $variationloop = new WP_Query( $args );
126
- while ( $variationloop->have_posts() ) : $variationloop->the_post();
127
- $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
128
- $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
129
- $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
130
- endwhile;
131
- }
132
- }
133
- }
134
- }
135
- update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
136
-
137
- return $tr_bundle;
138
- }
139
-
140
- }
141
-
142
-
143
- public function translate_bundle_key( $key, $lang, $return_original_if_missing = true ) {
144
- $key_parts = explode( '_', $key );
145
- $has_multiple_products = count( $key_parts ) > 1;
146
-
147
- $data = new stdClass;
148
- $data->id = $has_multiple_products ? $key_parts[ 0 ] : $key;
149
- $data->tr_id = apply_filters( 'translate_object_id', $data->id, get_post_type( $data->id ), $return_original_if_missing, $lang );
150
- $data->tr_key = $data->tr_id . ( $has_multiple_products ? '_' . $key_parts[ 1 ] : '' );
151
-
152
- return $data;
153
- }
154
-
155
- // Update Bundled products title and descritpion after saving the translation
156
- function bundle_update( $original_product_id, $tr_id, $data, $lang ){
157
-
158
- $tr_bundle_data = array();
159
- $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
160
-
161
- $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
162
-
163
- if( empty( $bundle_data ) ){
164
- return;
165
- }
166
-
167
- $product_bundles = array_keys( $bundle_data );
168
-
169
- foreach ( $product_bundles as $key => $bundle_key ) {
170
-
171
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
172
- $tr_bundle_key = $key_data->tr_key;
173
-
174
- if( isset( $tr_bundle_data[ $tr_bundle_key ] ) ){
175
- $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_key.'_title' ) ];
176
- $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_key.'_desc' ) ];
177
- }
178
- }
179
- update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
180
-
181
- return $tr_bundle_data;
182
- }
183
-
184
- // Add Bundles Box to WCML Translation GUI
185
- function custom_box_html( $obj, $product_id, $data ){
186
-
187
- $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
188
-
189
- if( empty( $product_bundles ) || $product_bundles == false ){
190
- return false;
191
- }
192
-
193
- $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
194
- end( $product_bundles );
195
- $last_key = key( $product_bundles );
196
- $divider = true;
197
- $flag = false;
198
-
199
- foreach ( $product_bundles as $bundle_id => $product_bundle ) {
200
- $add_group = false;
201
- if( $bundle_id == $last_key ){
202
- $divider = false;
203
- }
204
-
205
- $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
206
-
207
- if( $product_bundle[ 'override_title' ] == 'yes' ) {
208
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
209
- 'bundle_' . $bundle_id . '_title',
210
- __( 'Name', 'woocommerce-multilingual' ),
211
- $data,
212
- false
213
- );
214
- $group->add_field( $bundle_field );
215
- $add_group = true;
216
- }
217
-
218
- if( $product_bundle[ 'override_description' ] == 'yes' ){
219
- $bundle_field = new WPML_Editor_UI_Single_Line_Field(
220
- 'bundle_'.$bundle_id.'_desc' ,
221
- __( 'Description', 'woocommerce-multilingual' ),
222
- $data,
223
- false
224
- );
225
- $group->add_field( $bundle_field );
226
- $add_group = true;
227
- }
228
-
229
- if( $add_group ){
230
- $bundles_section->add_field( $group );
231
- $flag = true;
232
- }
233
- }
234
-
235
- if( $flag ){
236
- $obj->add_field( $bundles_section );
237
- }
238
- }
239
-
240
-
241
- function custom_box_html_data( $data, $product_id, $translation, $lang ){
242
- $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
243
-
244
- if( $translation ) {
245
- $tr_product_id = $translation->ID;
246
- $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
247
- }
248
-
249
- if( empty( $bundle_data ) || $bundle_data == false ){
250
- return $data;
251
- }
252
-
253
- $product_bundles = array_keys( $bundle_data );
254
-
255
- foreach ( $product_bundles as $bundle_key ) {
256
-
257
- $key_data = $this->translate_bundle_key( $bundle_key, $lang );
258
- $tr_bundle_key = $key_data->tr_key;
259
-
260
- if( $bundle_data[ $bundle_key ][ 'override_title' ] == 'yes' ){
261
- $data[ 'bundle_'.$bundle_key.'_title' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_title' ] );
262
- if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_title' ] ) ){
263
- $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ];
264
- }else{
265
- $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = '';
266
- }
267
- }
268
-
269
- if( $bundle_data[ $bundle_key ][ 'override_description' ] == 'yes' ){
270
- $data[ 'bundle_'.$bundle_key.'_desc' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_description' ] );
271
- if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_description' ] ) ){
272
- $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ];
273
- }else{
274
- $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = '';
275
- }
276
- }
277
- }
278
-
279
- return $data;
280
- }
281
-
282
- function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
283
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
284
- $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
285
- if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
286
- $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
287
- $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
288
- if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
289
- $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
290
- $remapped_bundled_item_ids = array();
291
- foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
292
- $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
293
- }
294
- $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
295
- if ( isset( $cart_item[ 'stamp' ] ) ) {
296
- $new_stamp = array();
297
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
298
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
299
- }
300
- $cart_item[ 'stamp' ] = $new_stamp;
301
- }
302
- }
303
- }
304
- }
305
- if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
306
- $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
307
- if (
308
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
309
- isset( $cart_item[ 'bundled_item_id' ] ) &&
310
- isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
311
- ) {
312
- $old_id = $cart_item[ 'bundled_item_id' ];
313
- $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
314
- $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
315
- if ( isset( $cart_item[ 'stamp' ] ) ) {
316
- $new_stamp = array();
317
- foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
318
- $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
319
- }
320
- $cart_item[ 'stamp' ] = $new_stamp;
321
- }
322
- }
323
- }
324
-
325
- return $cart_item;
326
- }
327
-
328
- function resync_bundle_clean( $cart ) {
329
- foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
330
- if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
331
- if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
332
- unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
333
- }
334
- }
335
- }
336
- }
337
-
338
- function append_bundle_data_translation_package( $package, $post ){
339
-
340
- if( $post->post_type == 'product' ) {
341
-
342
- $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
343
-
344
- if( $bundle_data ){
345
-
346
- $fields = array( 'title', 'description' );
347
-
348
- foreach( $bundle_data as $bundle_key => $product ){
349
-
350
- foreach( $fields as $field ) {
351
- if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
352
-
353
- $package[ 'contents' ][ 'product_bundles:' . $bundle_key . ':' . $field ] = array(
354
- 'translate' => 1,
355
- 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
356
- 'format' => 'base64'
357
- );
358
-
359
- }
360
- }
361
- }
362
- }
363
- }
364
-
365
- return $package;
366
-
367
- }
368
-
369
- function save_bundle_data_translation( $post_id, $data, $job ){
370
-
371
- remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
372
-
373
- $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
374
-
375
- $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
376
-
377
- $translated_bundle_pieces = array();
378
-
379
- foreach( $data as $value){
380
-
381
- if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
382
-
383
- $bundle_key = $matches[1];
384
- $field = $matches[2];
385
-
386
- $key_data = $this->translate_bundle_key( $bundle_key, $job->language_code );
387
-
388
- if( !isset( $bundle_data[ $key_data->tr_key ] ) ){
389
- $bundle_data[ $key_data->tr_key ] = array(
390
- 'product_id' => $key_data->tr_id,
391
- 'hide_thumbnail' => $bundle_data_original[ $bundle_key ][ 'hide_thumbnail' ],
392
- 'override_title' => $bundle_data_original[ $bundle_key ][ 'override_title' ],
393
- 'product_title' => '',
394
- 'override_description' => $bundle_data_original[ $bundle_key ][ 'override_description' ],
395
- 'product_description' => '',
396
- 'optional' => $bundle_data_original[ $bundle_key ][ 'optional' ],
397
- 'bundle_quantity' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity' ],
398
- 'bundle_quantity_max' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity_max' ],
399
- 'bundle_discount' => $bundle_data_original[ $bundle_key ][ 'bundle_discount' ],
400
- 'visibility' => $bundle_data_original[ $bundle_key ][ 'visibility' ],
401
- );
402
- }
403
-
404
- $bundle_data[ $key_data->tr_key ][ 'product_'.$field ] = $value[ 'data' ];
405
-
406
- }
407
- }
408
-
409
- update_post_meta( $post_id, '_bundle_data', $bundle_data );
410
-
411
- }
412
  }
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
+
69
+ $i = 2;
70
+ foreach( $bundle_data_array as $bundle_key => $bundle_data ){
71
+
72
+ $key_data = $this->translate_bundle_key( $bundle_key, $lang );
73
+ $tr_id = $key_data->tr_id;
74
+ $tr_bundle_key = $key_data->tr_key;
75
+
76
+ $tr_bundle[ $tr_bundle_key ] = $bundle_data;
77
+ $tr_bundle[ $tr_bundle_key ][ 'product_id' ] = $tr_id;
78
+ if( isset( $bundle_data[ 'product_title' ] ) ){
79
+ if( $bundle_data[ 'override_title' ] == 'yes' ){
80
+ $tr_bundle[ $tr_bundle_key ][ 'product_title' ] =
81
+ isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] ) ?
82
+ $tr_bundle_meta[ $tr_bundle_key ][ 'product_title' ] :
83
+ '';
84
+ }else{
85
+ $tr_title= get_the_title( $tr_id );
86
+ $tr_bundle[ $tr_bundle_key ][ 'product_title' ] = $tr_title;
87
+ }
88
+ }
89
+ if( isset( $bundle_data[ 'product_description' ] ) ){
90
+ if( $bundle_data[ 'override_description' ] == 'yes' ){
91
+ $tr_bundle[ $tr_bundle_key ][ 'product_description' ] =
92
+ isset( $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] ) ?
93
+ $tr_bundle_meta[ $tr_bundle_key ][ 'product_description' ] :
94
+ '';
95
+ }else{
96
+ $tr_prod = get_post( $tr_id );
97
+ $tr_desc = $tr_prod->post_excerpt;
98
+ $tr_bundle[ $tr_bundle_key ][ 'product_description' ] = $tr_desc;
99
+ }
100
+ }
101
+ if( isset( $bundle_data[ 'filter_variations' ] ) && $bundle_data[ 'filter_variations' ] == 'yes' ){
102
+ $allowed_var = $bundle_data[ 'allowed_variations' ];
103
+ foreach( $allowed_var as $key => $var_id ){
104
+ $tr_var_id = apply_filters( 'translate_object_id', $var_id, get_post_type( $var_id ), true, $lang );
105
+ $tr_bundle[ $tr_bundle_key ][ 'allowed_variations' ][ $key ] = $tr_var_id;
106
+ }
107
+ }
108
+ if( isset( $bundle_data[ 'bundle_defaults' ] ) && !empty( $bundle_data[ 'bundle_defaults' ] ) ){
109
+ foreach( $bundle_data[ 'bundle_defaults' ] as $tax => $term_slug ){
110
+
111
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $tax, $term_slug );
112
+ if( $term_id ){
113
+ // Global Attribute
114
+ $tr_def_id = apply_filters( 'translate_object_id', $term_id, $tax, true, $lang );
115
+ $tr_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_def_id, $tax );
116
+ $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_term->slug;
117
+ }else{
118
+ // Custom Attribute
119
+ $args = array(
120
+ 'post_type' => 'product_variation',
121
+ 'meta_key' => 'attribute_'.$tax,
122
+ 'meta_value' => $term_slug,
123
+ 'meta_compare' => '='
124
+ );
125
+ $variationloop = new WP_Query( $args );
126
+ while ( $variationloop->have_posts() ) : $variationloop->the_post();
127
+ $tr_var_id = apply_filters( 'translate_object_id', get_the_ID(), 'product_variation', true, $lang );
128
+ $tr_meta = get_post_meta( $tr_var_id, 'attribute_'.$tax , true );
129
+ $tr_bundle[ $tr_bundle_key ][ 'bundle_defaults' ][ $tax ] = $tr_meta;
130
+ endwhile;
131
+ }
132
+ }
133
+ }
134
+ }
135
+ update_post_meta( $trnsl_product_id, '_bundle_data', $tr_bundle );
136
+
137
+ return $tr_bundle;
138
+ }
139
+
140
+ }
141
+
142
+
143
+ public function translate_bundle_key( $key, $lang, $return_original_if_missing = true ) {
144
+ $key_parts = explode( '_', $key );
145
+ $has_multiple_products = count( $key_parts ) > 1;
146
+
147
+ $data = new stdClass;
148
+ $data->id = $has_multiple_products ? $key_parts[ 0 ] : $key;
149
+ $data->tr_id = apply_filters( 'translate_object_id', $data->id, get_post_type( $data->id ), $return_original_if_missing, $lang );
150
+ $data->tr_key = $data->tr_id . ( $has_multiple_products ? '_' . $key_parts[ 1 ] : '' );
151
+
152
+ return $data;
153
+ }
154
+
155
+ // Update Bundled products title and descritpion after saving the translation
156
+ function bundle_update( $original_product_id, $tr_id, $data, $lang ){
157
+
158
+ $tr_bundle_data = array();
159
+ $tr_bundle_data = maybe_unserialize( get_post_meta($tr_id,'_bundle_data', true ) );
160
+
161
+ $bundle_data = maybe_unserialize( get_post_meta( $original_product_id, '_bundle_data', true ) );
162
+
163
+ if( empty( $bundle_data ) ){
164
+ return;
165
+ }
166
+
167
+ $product_bundles = array_keys( $bundle_data );
168
+
169
+ foreach ( $product_bundles as $key => $bundle_key ) {
170
+
171
+ $key_data = $this->translate_bundle_key( $bundle_key, $lang );
172
+ $tr_bundle_key = $key_data->tr_key;
173
+
174
+ if( isset( $tr_bundle_data[ $tr_bundle_key ] ) ){
175
+ $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ] = $data[ md5( 'bundle_'.$bundle_key.'_title' ) ];
176
+ $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ] = $data[ md5( 'bundle_'.$bundle_key.'_desc' ) ];
177
+ }
178
+ }
179
+ update_post_meta( $tr_id, '_bundle_data', $tr_bundle_data );
180
+
181
+ return $tr_bundle_data;
182
+ }
183
+
184
+ // Add Bundles Box to WCML Translation GUI
185
+ function custom_box_html( $obj, $product_id, $data ){
186
+
187
+ $product_bundles = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
188
+
189
+ if( empty( $product_bundles ) || $product_bundles == false ){
190
+ return false;
191
+ }
192
+
193
+ $bundles_section = new WPML_Editor_UI_Field_Section( __( 'Product Bundles', 'woocommerce-multilingual' ) );
194
+ end( $product_bundles );
195
+ $last_key = key( $product_bundles );
196
+ $divider = true;
197
+ $flag = false;
198
+
199
+ foreach ( $product_bundles as $bundle_id => $product_bundle ) {
200
+ $add_group = false;
201
+ if( $bundle_id == $last_key ){
202
+ $divider = false;
203
+ }
204
+
205
+ $group = new WPML_Editor_UI_Field_Group( get_the_title( $bundle_id ), $divider );
206
+
207
+ if( $product_bundle[ 'override_title' ] == 'yes' ) {
208
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
209
+ 'bundle_' . $bundle_id . '_title',
210
+ __( 'Name', 'woocommerce-multilingual' ),
211
+ $data,
212
+ false
213
+ );
214
+ $group->add_field( $bundle_field );
215
+ $add_group = true;
216
+ }
217
+
218
+ if( $product_bundle[ 'override_description' ] == 'yes' ){
219
+ $bundle_field = new WPML_Editor_UI_Single_Line_Field(
220
+ 'bundle_'.$bundle_id.'_desc' ,
221
+ __( 'Description', 'woocommerce-multilingual' ),
222
+ $data,
223
+ false
224
+ );
225
+ $group->add_field( $bundle_field );
226
+ $add_group = true;
227
+ }
228
+
229
+ if( $add_group ){
230
+ $bundles_section->add_field( $group );
231
+ $flag = true;
232
+ }
233
+ }
234
+
235
+ if( $flag ){
236
+ $obj->add_field( $bundles_section );
237
+ }
238
+ }
239
+
240
+
241
+ function custom_box_html_data( $data, $product_id, $translation, $lang ){
242
+ $bundle_data = maybe_unserialize( get_post_meta( $product_id, '_bundle_data', true ) );
243
+
244
+ if( $translation ) {
245
+ $tr_product_id = $translation->ID;
246
+ $tr_bundle_data = maybe_unserialize( get_post_meta( $tr_product_id, '_bundle_data', true ) );
247
+ }
248
+
249
+ if( empty( $bundle_data ) || $bundle_data == false ){
250
+ return $data;
251
+ }
252
+
253
+ $product_bundles = array_keys( $bundle_data );
254
+
255
+ foreach ( $product_bundles as $bundle_key ) {
256
+
257
+ $key_data = $this->translate_bundle_key( $bundle_key, $lang );
258
+ $tr_bundle_key = $key_data->tr_key;
259
+
260
+ if( $bundle_data[ $bundle_key ][ 'override_title' ] == 'yes' ){
261
+ $data[ 'bundle_'.$bundle_key.'_title' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_title' ] );
262
+ if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_title' ] ) ){
263
+ $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_title' ];
264
+ }else{
265
+ $data[ 'bundle_'.$bundle_key.'_title' ][ 'translation' ] = '';
266
+ }
267
+ }
268
+
269
+ if( $bundle_data[ $bundle_key ][ 'override_description' ] == 'yes' ){
270
+ $data[ 'bundle_'.$bundle_key.'_desc' ] = array( 'original' => $bundle_data[ $bundle_key ][ 'product_description' ] );
271
+ if( isset( $tr_bundle_data[ $tr_bundle_key ][ 'override_description' ] ) ){
272
+ $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = $tr_bundle_data[ $tr_bundle_key ][ 'product_description' ];
273
+ }else{
274
+ $data[ 'bundle_'.$bundle_key.'_desc' ][ 'translation' ] = '';
275
+ }
276
+ }
277
+ }
278
+
279
+ return $data;
280
+ }
281
+
282
+ function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
283
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
284
+ $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
285
+ if ( $cart_item[ 'product_id' ] != $current_bundle_id ) {
286
+ $old_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
287
+ $cart_item[ 'data' ] = wc_get_product( $current_bundle_id );
288
+ if( is_array( $cart_item[ 'data' ]->bundle_data ) ){
289
+ $new_bundled_item_ids = array_keys( $cart_item[ 'data' ]->bundle_data );
290
+ $remapped_bundled_item_ids = array();
291
+ foreach ( $old_bundled_item_ids as $old_item_id_index => $old_item_id ) {
292
+ $remapped_bundled_item_ids[ $old_item_id ] = $new_bundled_item_ids[ $old_item_id_index ];
293
+ }
294
+ $cart_item[ 'remapped_bundled_item_ids' ] = $remapped_bundled_item_ids;
295
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
296
+ $new_stamp = array();
297
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
298
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
299
+ }
300
+ $cart_item[ 'stamp' ] = $new_stamp;
301
+ }
302
+ }
303
+ }
304
+ }
305
+ if ( isset( $cart_item[ 'bundled_by' ] ) && isset( WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ] ) ) {
306
+ $bundle_cart_item = WC()->cart->cart_contents[ $cart_item[ 'bundled_by' ] ];
307
+ if (
308
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ] ) &&
309
+ isset( $cart_item[ 'bundled_item_id' ] ) &&
310
+ isset( $bundle_cart_item[ 'remapped_bundled_item_ids' ][ $cart_item[ 'bundled_item_id' ] ] )
311
+ ) {
312
+ $old_id = $cart_item[ 'bundled_item_id' ];
313
+ $remapped_bundled_item_ids = $bundle_cart_item[ 'remapped_bundled_item_ids' ];
314
+ $cart_item[ 'bundled_item_id' ] = $remapped_bundled_item_ids[ $cart_item[ 'bundled_item_id' ] ];
315
+ if ( isset( $cart_item[ 'stamp' ] ) ) {
316
+ $new_stamp = array();
317
+ foreach ( $cart_item[ 'stamp' ] as $bundled_item_id => $stamp_data ) {
318
+ $new_stamp[ $remapped_bundled_item_ids[ $bundled_item_id ] ] = $stamp_data;
319
+ }
320
+ $cart_item[ 'stamp' ] = $new_stamp;
321
+ }
322
+ }
323
+ }
324
+
325
+ return $cart_item;
326
+ }
327
+
328
+ function resync_bundle_clean( $cart ) {
329
+ foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
330
+ if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
331
+ if ( isset( $cart_item[ 'remapped_bundled_item_ids' ] ) ) {
332
+ unset( WC()->cart->cart_contents[ $cart_item_key ][ 'remapped_bundled_item_ids' ] );
333
+ }
334
+ }
335
+ }
336
+ }
337
+
338
+ function append_bundle_data_translation_package( $package, $post ){
339
+
340
+ if( $post->post_type == 'product' ) {
341
+
342
+ $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
343
+
344
+ if( $bundle_data ){
345
+
346
+ $fields = array( 'title', 'description' );
347
+
348
+ foreach( $bundle_data as $bundle_key => $product ){
349
+
350
+ foreach( $fields as $field ) {
351
+ if ( $product[ 'override_' . $field ] == 'yes' && !empty( $product[ 'product_' . $field ] ) ) {
352
+
353
+ $package[ 'contents' ][ 'product_bundles:' . $bundle_key . ':' . $field ] = array(
354
+ 'translate' => 1,
355
+ 'data' => $this->tp->encode_field_data( $product[ 'product_' . $field ], 'base64' ),
356
+ 'format' => 'base64'
357
+ );
358
+
359
+ }
360
+ }
361
+ }
362
+ }
363
+ }
364
+
365
+ return $package;
366
+
367
+ }
368
+
369
+ function save_bundle_data_translation( $post_id, $data, $job ){
370
+
371
+ remove_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_bundled_ids' ), 10, 2 );
372
+
373
+ $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
374
+
375
+ $bundle_data_original = get_post_meta( $job->original_doc_id , '_bundle_data', true );
376
+
377
+ $translated_bundle_pieces = array();
378
+
379
+ foreach( $data as $value){
380
+
381
+ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value[ 'field_type' ], $matches ) ){
382
+
383
+ $bundle_key = $matches[1];
384
+ $field = $matches[2];
385
+
386
+ $key_data = $this->translate_bundle_key( $bundle_key, $job->language_code );
387
+
388
+ if( !isset( $bundle_data[ $key_data->tr_key ] ) ){
389
+ $bundle_data[ $key_data->tr_key ] = array(
390
+ 'product_id' => $key_data->tr_id,
391
+ 'hide_thumbnail' => $bundle_data_original[ $bundle_key ][ 'hide_thumbnail' ],
392
+ 'override_title' => $bundle_data_original[ $bundle_key ][ 'override_title' ],
393
+ 'product_title' => '',
394
+ 'override_description' => $bundle_data_original[ $bundle_key ][ 'override_description' ],
395
+ 'product_description' => '',
396
+ 'optional' => $bundle_data_original[ $bundle_key ][ 'optional' ],
397
+ 'bundle_quantity' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity' ],
398
+ 'bundle_quantity_max' => $bundle_data_original[ $bundle_key ][ 'bundle_quantity_max' ],
399
+ 'bundle_discount' => $bundle_data_original[ $bundle_key ][ 'bundle_discount' ],
400
+ 'visibility' => $bundle_data_original[ $bundle_key ][ 'visibility' ],
401
+ );
402
+ }
403
+
404
+ $bundle_data[ $key_data->tr_key ][ 'product_'.$field ] = $value[ 'data' ];
405
+
406
+ }
407
+ }
408
+
409
+ update_post_meta( $post_id, '_bundle_data', $bundle_data );
410
+
411
+ }
412
  }
compatibility/class-wcml-sensei.php CHANGED
@@ -1,231 +1,234 @@
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, $wpdb;
7
+
8
+ $custom_columns = new WPML_Custom_Columns( $wpdb, $sitepress );
9
+
10
+ add_filter( 'manage_edit-lesson_columns', array( $custom_columns, 'add_posts_management_column' ) );
11
+ add_filter( 'manage_edit-course_columns', array( $custom_columns, 'add_posts_management_column' ) );
12
+
13
+ add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
14
+ add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
15
+ add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
16
+ add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
17
+
18
+ add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
19
+
20
+ if( is_admin() &&
21
+ (
22
+ ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
23
+ ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
24
+ ) ){
25
+ remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
26
+ }
27
+
28
+ }
29
+
30
+ function save_post_actions( $post_id, $post ){
31
+ global $sitepress;
32
+
33
+ // skip not related post types
34
+ if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
35
+ return;
36
+ }
37
+ // skip auto-drafts
38
+ if ( $post->post_status == 'auto-draft' ) {
39
+ return;
40
+ }
41
+ // skip autosave
42
+ if ( isset( $_POST[ 'autosave' ] ) ) {
43
+ return;
44
+ }
45
+
46
+ if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
47
+ $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
48
+ }
49
+
50
+
51
+ // sync fields from original
52
+ $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
53
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
54
+
55
+ if ( !empty( $translations ) ) {
56
+ $original_post_id = false;
57
+ foreach ( $translations as $t ) {
58
+ if ( $t->original ) {
59
+ $original_post_id = $t->element_id;
60
+ break;
61
+ }
62
+ }
63
+
64
+ if ( $post_id != $original_post_id ) {
65
+ $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
66
+ } else {
67
+ foreach ( $translations as $t ) {
68
+ if ( $original_post_id != $t->element_id ) {
69
+ $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ }
76
+
77
+
78
+ function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
79
+ global $sitepress;
80
+
81
+ $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
82
+ if( $post_type == 'quiz' ){
83
+
84
+ //sync quiz lesson
85
+ $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
86
+
87
+ if( $lesson_id ){
88
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
89
+
90
+ if( !is_null( $tr_lesson_id ) ){
91
+ update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
92
+ }
93
+ }else{
94
+ delete_post_meta( $post_id, '_quiz_lesson' );
95
+ }
96
+
97
+ } elseif( $post_type == 'lesson' ){
98
+ //sync lesson course
99
+ $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
100
+
101
+ if( $course_id ){
102
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
103
+
104
+ if( !is_null( $tr_course_id ) ){
105
+ update_post_meta( $post_id, '_lesson_course', $tr_course_id );
106
+ }
107
+ }else{
108
+ delete_post_meta( $post_id, '_lesson_course' );
109
+ }
110
+
111
+ //sync lesson prerequisite
112
+ $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
113
+
114
+ if( $lesson_id ){
115
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
116
+
117
+ if( !is_null( $tr_lesson_id ) ){
118
+ update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
119
+ }
120
+ }else{
121
+ delete_post_meta( $post_id, '_lesson_prerequisite' );
122
+ }
123
+
124
+ }else{
125
+
126
+ //sync course woocommerce_product
127
+ $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
128
+
129
+ if( $product_id ){
130
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
131
+
132
+ if( !is_null( $tr_product_id ) ){
133
+ update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
134
+ }
135
+ }else{
136
+ delete_post_meta( $post_id, '_course_woocommerce_product' );
137
+ }
138
+
139
+ //sync course prerequisite
140
+ $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
141
+
142
+ if( $course_id ){
143
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
144
+
145
+ if( !is_null( $tr_course_id ) ){
146
+ update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
147
+ }
148
+ }else{
149
+ delete_post_meta( $post_id, '_course_prerequisite' );
150
+ }
151
+
152
+ }
153
+
154
+ }
155
+
156
+ function log_activity_after ( $args, $data, $comment_id = false ){
157
+ global $sitepress;
158
+
159
+ if( !$comment_id ){
160
+ return false;
161
+ }
162
+
163
+ $comment_post_id = $data['comment_post_ID'];
164
+ $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
165
+ $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
166
+
167
+ foreach($translations as $translation){
168
+
169
+ if( $comment_post_id != $translation->element_id ){
170
+ $data['comment_post_ID'] = $translation->element_id;
171
+
172
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
173
+
174
+ $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
175
+ if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
176
+ $data['comment_ID'] = $tr_comment_id;
177
+ $tr_comment_id = wp_update_comment( $data );
178
+ }else{
179
+ $tr_comment_id = wp_insert_comment( $data );
180
+ $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
181
+ }
182
+ }
183
+
184
+ }
185
+
186
+ }
187
+
188
+ function filter_bought_product_id( $product_id, $order ){
189
+
190
+ $order_language = get_post_meta( $order->id, 'wpml_language', true );
191
+
192
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
193
+
194
+ if( !is_null( $tr_product_id ) ){
195
+ return $tr_product_id;
196
+ }else{
197
+ return $product_id;
198
+ }
199
+ }
200
+
201
+ function delete_user_activity ( $comment_id ){
202
+ global $sitepress;
203
+
204
+ $comment_type = get_comment_type( $comment_id );
205
+
206
+ if( strstr( $comment_type, "sensei" ) ){
207
+
208
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
209
+ $translations = $sitepress->get_element_translations( $trid, 'comment' );
210
+
211
+ remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
212
+ foreach ( $translations as $translation ){
213
+ if( $comment_id != $translation->element_id ){
214
+ wp_delete_comment( $translation->element_id, true );
215
+ }
216
+ }
217
+
218
+ }
219
+
220
+
221
+ }
222
+
223
+ function pre_get_comments($obj){
224
+ global $sitepress;
225
+
226
+ if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
227
+
228
+ remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
229
+
230
+ }
231
+
232
+ }
233
+
234
+ }
compatibility/class-wcml-tab-manager.php CHANGED
@@ -1,707 +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
- 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
- }
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,103 +1,115 @@
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
- }
 
 
 
 
 
 
 
 
 
 
 
 
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
+
29
+ add_filter( 'get_the_terms',array( $this, 'shipping_class_id_in_default_language' ), 10, 3 );
30
+
31
+ if( wcml_is_multi_currency_on() ){
32
+ add_filter( 'woocommerce_table_rate_query_rates_args', array( $this, 'filter_query_rates_args' ) );
33
+ add_filter( 'woocommerce_table_rate_package_row_base_price', array( $this, 'filter_product_base_price' ), 10, 3 );
34
+ }
35
+
36
+ }
37
+
38
+ /**
39
+ * Register shipping labels for string translation.
40
+ */
41
+ public function init() {
42
+ // Register shipping label
43
+ if (
44
+ isset( $_GET[ 'page' ] ) &&
45
+ (
46
+ $_GET[ 'page' ] === 'shipping_zones' ||
47
+ (
48
+ $_GET['page'] == 'wc-settings' &&
49
+ isset( $_GET[ 'tab' ] ) &&
50
+ $_GET['tab'] == 'shipping'
51
+ )
52
+ ) &&
53
+ isset( $_POST[ 'shipping_label' ] ) &&
54
+ isset( $_POST[ 'woocommerce_table_rate_title' ] )
55
+ ) {
56
+
57
+ 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' ] ) );
58
+ $shipping_labels = array_map( 'woocommerce_clean', $_POST[ 'shipping_label' ] );
59
+ foreach ( $shipping_labels as $key => $shipping_label ) {
60
+ $rate_key = isset( $_GET[ 'instance_id' ] ) ? 'table_rate'.$_GET[ 'instance_id' ].$_POST[ 'rate_id' ][ $key ] : $shipping_label;
61
+ do_action( 'wpml_register_single_string', 'woocommerce', $rate_key. '_shipping_method_title', $shipping_label );
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ * @param $terms
68
+ * @param $post_id
69
+ * @param $taxonomy
70
+ *
71
+ * @return mixed
72
+ */
73
+ public function shipping_class_id_in_default_language( $terms, $post_id, $taxonomy ) {
74
+ global $icl_adjust_id_url_filter_off, $pagenow;
75
+
76
+ if( $pagenow != 'post.php' && ( get_post_type( $post_id ) == 'product' || get_post_type( $post_id ) == 'product_variation' ) && $taxonomy == 'product_shipping_class' ){
77
+
78
+ foreach ( $terms as $k => $term ) {
79
+ $shipping_class_id = apply_filters( 'translate_object_id', $term->term_id, 'product_shipping_class', false, $this->sitepress->get_default_language() );
80
+
81
+ $icl_adjust_id_url_filter = $icl_adjust_id_url_filter_off;
82
+ $icl_adjust_id_url_filter_off = true;
83
+
84
+ $terms[ $k ] = get_term( $shipping_class_id, 'product_shipping_class' );
85
+
86
+ $icl_adjust_id_url_filter_off = $icl_adjust_id_url_filter;
87
+ }
88
+ }
89
+
90
+ return $terms;
91
+ }
92
+
93
+ /**
94
+ * It's not possible to filter rate_min and rate_max so we use the original price to compare against these values
95
+ */
96
+ public function filter_query_rates_args( $args ){
97
+
98
+ if( isset( $args['price'] ) && get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
99
+ $args['price'] = $this->woocommerce_wpml->multi_currency->prices->unconvert_price_amount( $args['price'] );
100
+ }
101
+
102
+ return $args;
103
+ }
104
+
105
+
106
+ public function filter_product_base_price( $row_base_price, $_product, $qty ){
107
+
108
+ if( get_option( 'woocommerce_currency') != $this->woocommerce_wpml->multi_currency->get_client_currency() ){
109
+ $row_base_price = apply_filters( 'wcml_product_price_by_currency', $_product->id, get_option( 'woocommerce_currency') ) * $qty;
110
+ }
111
+
112
+ return $row_base_price;
113
+ }
114
+
115
+ }
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
+
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -1,297 +1,297 @@
1
- <?php
2
-
3
- class WCML_Admin_Menus{
4
-
5
- private static $woocommerce_wpml;
6
- private static $sitepress;
7
- private static $wpdb;
8
-
9
- public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
- self::$woocommerce_wpml =& $woocommerce_wpml;
11
- self::$sitepress =& $sitepress;
12
- self::$wpdb =& $wpdb;
13
-
14
- add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
15
-
16
- if( self::is_page_without_admin_language_switcher() ){
17
- self::remove_wpml_admin_language_switcher();
18
- }
19
-
20
- if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
- add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
22
- add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
23
- add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
24
- }
25
-
26
- add_filter( 'woocommerce_prevent_admin_access', array( __CLASS__, 'check_user_admin_access' ) );
27
-
28
- add_action( 'admin_head', array( __CLASS__, 'add_menu_warning' ) );
29
- }
30
-
31
- public static function register_menus(){
32
- global $WPML_Translation_Management;
33
-
34
- if( self::$woocommerce_wpml->check_dependencies || class_exists( 'WooCommerce' ) ) {
35
-
36
- add_submenu_page(
37
- 'woocommerce',
38
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
39
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
40
- 'wpml_operate_woocommerce_multilingual',
41
- 'wpml-wcml',
42
- array( __CLASS__, 'render_menus' )
43
- );
44
-
45
- if( !current_user_can('wpml_manage_woocommerce_multilingual') && current_user_can('wpml_operate_woocommerce_multilingual') ) {
46
- //force add translations-queue page for shop manager
47
- $wp_api = self::$sitepress->get_wp_api();
48
- if (!$wp_api->current_user_can('wpml_manage_translation_management')) {
49
- $wp_api->add_submenu_page(null,
50
- __('Translations', 'wpml-translation-management'), __('Translations', 'wpml-translation-management'),
51
- 'wpml_operate_woocommerce_multilingual', WPML_TM_FOLDER . '/menu/translations-queue.php', array($WPML_Translation_Management, 'translation_queue_page'));
52
- }
53
- }
54
- } else {
55
-
56
- add_menu_page(
57
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
58
- __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
59
- 'wpml_manage_woocommerce_multilingual',
60
- 'wpml-wcml',
61
- array( __CLASS__, 'render_menus' ),
62
- WCML_PLUGIN_URL . '/res/images/icon16.png'
63
- );
64
-
65
- }
66
- }
67
-
68
- public static function render_menus(){
69
-
70
- if( self::$woocommerce_wpml->check_dependencies ){
71
- $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
72
- $menus_wrap->show();
73
- }else{
74
- global $sitepress;
75
- $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
76
- $plugins_wrap->show();
77
- }
78
-
79
- }
80
-
81
- private static function is_page_without_admin_language_switcher(){
82
- global $pagenow;
83
-
84
- $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
85
- $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
86
- $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
87
-
88
- $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
89
- $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
90
- $get_post_type &&
91
- in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
92
- $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
93
- in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
94
- $is_shipping_zones = $get_page == 'shipping_zones';
95
- $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
96
-
97
-
98
- return is_admin() && (
99
- $is_page_wpml_wcml ||
100
- $is_new_order_or_coupon ||
101
- $is_edit_order_or_coupon ||
102
- $is_shipping_zones ||
103
- $is_attributes_page
104
- );
105
-
106
- }
107
-
108
- public static function remove_wpml_admin_language_switcher(){
109
-
110
- remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
111
-
112
- }
113
-
114
- public static function documentation_links() {
115
- global $post, $pagenow;
116
-
117
- if ( is_null( $post ) )
118
- return;
119
-
120
- $get_post_type = get_post_type( $post->ID );
121
-
122
- if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
123
- $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
124
- sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
125
- 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
126
- __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
127
- '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
128
- ) . '</p></div>';
129
- $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
130
- ?>
131
- <script type="text/javascript">
132
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
133
- jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
134
- jQuery(".quick_hide a").on('click', function () {
135
- jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
136
- });
137
-
138
- //lock feature for translations
139
- jQuery(document).on('click', '.featured a', function () {
140
- if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
141
- return false;
142
- }
143
-
144
- });
145
- </script>
146
- <?php
147
- }
148
-
149
- if ( isset($_GET['taxonomy']) ) {
150
- $pos = strpos( $_GET['taxonomy'], 'pa_' );
151
-
152
- if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
153
- $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
154
- __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
155
- ?>
156
- <script type="text/javascript">
157
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
158
- </script>
159
- <?php
160
- }
161
- }
162
-
163
- if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
164
-
165
- $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
166
- __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
167
- ?>
168
- <script type="text/javascript">
169
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
170
- </script>
171
- <?php
172
- }
173
- }
174
-
175
- public static function hide_multilingual_content_setup_box(){
176
- remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
177
- remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
178
- }
179
-
180
- public static function restrict_admin_with_redirect() {
181
- global $pagenow;
182
-
183
- $default_lang = self::$sitepress->get_default_language();
184
- $current_lang = self::$sitepress->get_current_language();
185
-
186
- if(
187
- ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
188
- ( $pagenow == 'admin.php' &&
189
- isset( $_GET[ 'action' ] ) &&
190
- $_GET[ 'action'] == 'duplicate_product' &&
191
- isset( $_GET[ 'post' ] )
192
- )
193
- ){
194
- $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
195
- }
196
-
197
- if(
198
- !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
199
- $pagenow == 'post.php' &&
200
- isset( $_GET[ 'post' ] )&&
201
- get_post_type( $_GET[ 'post' ] ) == 'product' &&
202
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
203
- {
204
- add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
205
- }
206
-
207
- if(
208
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
209
- $pagenow == 'post.php' &&
210
- !is_ajax() &&
211
- isset( $_GET[ 'post' ] ) &&
212
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
213
- get_post_type( $_GET[ 'post' ] ) == 'product'
214
- ) {
215
- if(
216
- !isset( $_GET[ 'action' ] ) ||
217
- ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
218
- ) {
219
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
220
- exit;
221
- }
222
- }
223
-
224
- if(
225
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
226
- $pagenow == 'admin.php' &&
227
- isset( $_GET[ 'action' ] ) &&
228
- $_GET[ 'action' ] == 'duplicate_product' &&
229
- $default_lang != $prod_lang )
230
- {
231
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
232
- exit;
233
- }
234
- }
235
-
236
- public static function inf_editing_product_in_non_default_lang(){
237
- if( !self::$woocommerce_wpml->settings[ 'dismiss_tm_warning' ] ) {
238
- $url = $_SERVER['REQUEST_URI'];
239
-
240
- $message = '<div class="message error otgs-is-dismissible"><p>';
241
- $message .= sprintf(
242
- __('The recommended way to translate WooCommerce products is using the
243
- %sWooCommerce Multilingual products translation%s page.
244
- Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
245
- 'woocommerce-multilingual'),
246
- '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=products') . '">', '</a></strong>');
247
- $message .= '</p><a class="notice-dismiss" href="' . $url . '&wcml_action=dismiss_tm_warning"><span class="screen-reader-text">' . __('Dismiss', 'woocommerce-multilingual') . '</a>';
248
- $message .= '</div>';
249
-
250
- echo $message;
251
- }
252
- }
253
-
254
- public static function check_user_admin_access( $prevent_access ){
255
-
256
- if( self::$woocommerce_wpml->check_dependencies ){
257
- $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
258
- if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
259
- return false;
260
- }
261
- }
262
-
263
- return $prevent_access;
264
- }
265
-
266
- public static function add_menu_warning(){
267
- global $submenu, $menu;
268
-
269
- if (
270
- class_exists( 'woocommerce' ) &&
271
- (
272
- empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
273
- (
274
- empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
275
- self::$woocommerce_wpml->settings['set_up_wizard_splash']
276
- )
277
- )
278
- ) {
279
- if( isset( $submenu[ 'woocommerce' ] ) ){
280
- foreach( $submenu[ 'woocommerce' ] as $key => $menu_item ) {
281
- if ( $menu_item[ 0 ] == __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ) ) {
282
- $submenu[ 'woocommerce' ][ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
283
- break;
284
- }
285
- }
286
- }
287
-
288
- foreach( $menu as $key => $menu_item ) {
289
- if ( $menu_item[ 0 ] == __( 'WooCommerce', 'woocommerce' ) ) {
290
- $menu[ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
291
- break;
292
- }
293
- }
294
- }
295
- }
296
-
297
  }
1
+ <?php
2
+
3
+ class WCML_Admin_Menus{
4
+
5
+ private static $woocommerce_wpml;
6
+ private static $sitepress;
7
+ private static $wpdb;
8
+
9
+ public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
+ self::$woocommerce_wpml =& $woocommerce_wpml;
11
+ self::$sitepress =& $sitepress;
12
+ self::$wpdb =& $wpdb;
13
+
14
+ add_action( 'admin_menu', array(__CLASS__, 'register_menus' ), 80 );
15
+
16
+ if( self::is_page_without_admin_language_switcher() ){
17
+ self::remove_wpml_admin_language_switcher();
18
+ }
19
+
20
+ if( is_admin() && !is_null( $sitepress ) && $check_dependencies ){
21
+ add_action( 'admin_footer', array(__CLASS__, 'documentation_links' ) );
22
+ add_action( 'admin_head', array( __CLASS__, 'hide_multilingual_content_setup_box' ) );
23
+ add_action( 'admin_init', array( __CLASS__, 'restrict_admin_with_redirect' ) );
24
+ }
25
+
26
+ add_filter( 'woocommerce_prevent_admin_access', array( __CLASS__, 'check_user_admin_access' ) );
27
+
28
+ add_action( 'admin_head', array( __CLASS__, 'add_menu_warning' ) );
29
+ }
30
+
31
+ public static function register_menus(){
32
+ global $WPML_Translation_Management;
33
+
34
+ if( self::$woocommerce_wpml->check_dependencies || class_exists( 'WooCommerce' ) ) {
35
+
36
+ add_submenu_page(
37
+ 'woocommerce',
38
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
39
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
40
+ 'wpml_operate_woocommerce_multilingual',
41
+ 'wpml-wcml',
42
+ array( __CLASS__, 'render_menus' )
43
+ );
44
+
45
+ if( !current_user_can('wpml_manage_woocommerce_multilingual') && current_user_can('wpml_operate_woocommerce_multilingual') ) {
46
+ //force add translations-queue page for shop manager
47
+ $wp_api = self::$sitepress->get_wp_api();
48
+ if (!$wp_api->current_user_can('wpml_manage_translation_management')) {
49
+ $wp_api->add_submenu_page(null,
50
+ __('Translations', 'wpml-translation-management'), __('Translations', 'wpml-translation-management'),
51
+ 'wpml_operate_woocommerce_multilingual', WPML_TM_FOLDER . '/menu/translations-queue.php', array($WPML_Translation_Management, 'translation_queue_page'));
52
+ }
53
+ }
54
+ } else {
55
+
56
+ add_menu_page(
57
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
58
+ __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ),
59
+ 'wpml_manage_woocommerce_multilingual',
60
+ 'wpml-wcml',
61
+ array( __CLASS__, 'render_menus' ),
62
+ WCML_PLUGIN_URL . '/res/images/icon16.png'
63
+ );
64
+
65
+ }
66
+ }
67
+
68
+ public static function render_menus(){
69
+
70
+ if( self::$woocommerce_wpml->check_dependencies ){
71
+ $menus_wrap = new WCML_Menus_Wrap( self::$woocommerce_wpml );
72
+ $menus_wrap->show();
73
+ }else{
74
+ global $sitepress;
75
+ $plugins_wrap = new WCML_Plugins_Wrap( self::$woocommerce_wpml, $sitepress );
76
+ $plugins_wrap->show();
77
+ }
78
+
79
+ }
80
+
81
+ private static function is_page_without_admin_language_switcher(){
82
+ global $pagenow;
83
+
84
+ $get_post_type = isset( $_GET['post_type'] ) ? $_GET['post_type'] : false;
85
+ $get_post = isset( $_GET['post'] ) ? $_GET['post'] : false;
86
+ $get_page = isset( $_GET['page'] ) ? $_GET['page'] : false;
87
+
88
+ $is_page_wpml_wcml = isset($_GET['page']) && $_GET['page'] == 'wpml-wcml';
89
+ $is_new_order_or_coupon = in_array( $pagenow, array( 'edit.php', 'post-new.php' ) ) &&
90
+ $get_post_type &&
91
+ in_array( $get_post_type, array( 'shop_coupon', 'shop_order' ) );
92
+ $is_edit_order_or_coupon = $pagenow == 'post.php' && $get_post &&
93
+ in_array( get_post_type( $get_post ), array( 'shop_coupon', 'shop_order' ) );
94
+ $is_shipping_zones = $get_page == 'shipping_zones';
95
+ $is_attributes_page = apply_filters( 'wcml_is_attributes_page', $get_page == 'product_attributes' );
96
+
97
+
98
+ return is_admin() && (
99
+ $is_page_wpml_wcml ||
100
+ $is_new_order_or_coupon ||
101
+ $is_edit_order_or_coupon ||
102
+ $is_shipping_zones ||
103
+ $is_attributes_page
104
+ );
105
+
106
+ }
107
+
108
+ public static function remove_wpml_admin_language_switcher(){
109
+
110
+ remove_action( 'wp_before_admin_bar_render', array(self::$sitepress, 'admin_language_switcher') );
111
+
112
+ }
113
+
114
+ public static function documentation_links() {
115
+ global $post, $pagenow;
116
+
117
+ if ( is_null( $post ) )
118
+ return;
119
+
120
+ $get_post_type = get_post_type( $post->ID );
121
+
122
+ if ( $get_post_type == 'product' && $pagenow == 'edit.php' ) {
123
+ $quick_edit_notice = '<div id="quick_edit_notice" style="display:none;"><p>' .
124
+ sprintf( __( "Quick edit is disabled for product translations. It\'s recommended to use the %s for editing products translations. %s",
125
+ 'woocommerce-multilingual' ), '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=products' ) . '" >' .
126
+ __( 'WooCommerce Multilingual products editor', 'woocommerce-multilingual' ) . '</a>',
127
+ '<a href="" class="quick_product_trnsl_link" >' . __( 'Edit this product translation', 'woocommerce-multilingual' ) . '</a>'
128
+ ) . '</p></div>';
129
+ $quick_edit_notice_prod_link = '<input type="hidden" id="wcml_product_trnsl_link" value="' . admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' ) . '">';
130
+ ?>
131
+ <script type="text/javascript">
132
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice ?>');
133
+ jQuery(".subsubsub").append('<?php echo $quick_edit_notice_prod_link ?>');
134
+ jQuery(".quick_hide a").on('click', function () {
135
+ jQuery(".quick_product_trnsl_link").attr('href', jQuery("#wcml_product_trnsl_link").val() + jQuery(this).closest('tr').attr('id').replace(/post-/, ''));
136
+ });
137
+
138
+ //lock feature for translations
139
+ jQuery(document).on('click', '.featured a', function () {
140
+ if (jQuery(this).closest('tr').find('.quick_hide').size() > 0) {
141
+ return false;
142
+ }
143
+
144
+ });
145
+ </script>
146
+ <?php
147
+ }
148
+
149
+ if ( isset($_GET['taxonomy']) ) {
150
+ $pos = strpos( $_GET['taxonomy'], 'pa_' );
151
+
152
+ if ( $pos !== false && $pagenow == 'edit-tags.php' ) {
153
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
154
+ __( 'How to translate attributes', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
155
+ ?>
156
+ <script type="text/javascript">
157
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
158
+ </script>
159
+ <?php
160
+ }
161
+ }
162
+
163
+ if ( isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat' ) {
164
+
165
+ $prot_link = '<span class="button" style="padding:4px;margin-top:0px; float: left;"><img align="baseline" src="' . ICL_PLUGIN_URL . '/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="' . WCML_Links::generate_tracking_link( 'https://wpml.org/documentation/related-projects/woocommerce-multilingual/', 'woocommerce-multilingual', 'documentation', '#3' ) . '" target="_blank" style="text-decoration: none;">' .
166
+ __( 'How to translate product categories', 'sitepress' ) . '<\/a>' . '<\/span><br \/><br \/>';
167
+ ?>
168
+ <script type="text/javascript">
169
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
170
+ </script>
171
+ <?php
172
+ }
173
+ }
174
+
175
+ public static function hide_multilingual_content_setup_box(){
176
+ remove_meta_box('icl_div_config', convert_to_screen('shop_order'), 'normal');
177
+ remove_meta_box('icl_div_config', convert_to_screen('shop_coupon'), 'normal');
178
+ }
179
+
180
+ public static function restrict_admin_with_redirect() {
181
+ global $pagenow;
182
+
183
+ $default_lang = self::$sitepress->get_default_language();
184
+ $current_lang = self::$sitepress->get_current_language();
185
+
186
+ if(
187
+ ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
188
+ ( $pagenow == 'admin.php' &&
189
+ isset( $_GET[ 'action' ] ) &&
190
+ $_GET[ 'action'] == 'duplicate_product' &&
191
+ isset( $_GET[ 'post' ] )
192
+ )
193
+ ){
194
+ $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
195
+ }
196
+
197
+ if(
198
+ !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
199
+ $pagenow == 'post.php' &&
200
+ isset( $_GET[ 'post' ] )&&
201
+ get_post_type( $_GET[ 'post' ] ) == 'product' &&
202
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
203
+ {
204
+ add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
205
+ }
206
+
207
+ if(
208
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
209
+ $pagenow == 'post.php' &&
210
+ !is_ajax() &&
211
+ isset( $_GET[ 'post' ] ) &&
212
+ !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
213
+ get_post_type( $_GET[ 'post' ] ) == 'product'
214
+ ) {
215
+ if(
216
+ !isset( $_GET[ 'action' ] ) ||
217
+ ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
218
+ ) {
219
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
220
+ exit;
221
+ }
222
+ }
223
+
224
+ if(
225
+ self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
226
+ $pagenow == 'admin.php' &&
227
+ isset( $_GET[ 'action' ] ) &&
228
+ $_GET[ 'action' ] == 'duplicate_product' &&
229
+ $default_lang != $prod_lang )
230
+ {
231
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
232
+ exit;
233
+ }
234
+ }
235
+
236
+ public static function inf_editing_product_in_non_default_lang(){
237
+ if( !self::$woocommerce_wpml->settings[ 'dismiss_tm_warning' ] ) {
238
+ $url = $_SERVER['REQUEST_URI'];
239
+
240
+ $message = '<div class="message error otgs-is-dismissible"><p>';
241
+ $message .= sprintf(
242
+ __('The recommended way to translate WooCommerce products is using the
243
+ %sWooCommerce Multilingual products translation%s page.
244
+ Please use this page only for translating elements that are not available in the WooCommerce Multilingual products translation table.',
245
+ 'woocommerce-multilingual'),
246
+ '<strong><a href="' . admin_url('admin.php?page=wpml-wcml&tab=products') . '">', '</a></strong>');
247
+ $message .= '</p><a class="notice-dismiss" href="' . $url . '&wcml_action=dismiss_tm_warning"><span class="screen-reader-text">' . __('Dismiss', 'woocommerce-multilingual') . '</a>';
248
+ $message .= '</div>';
249
+
250
+ echo $message;
251
+ }
252
+ }
253
+
254
+ public static function check_user_admin_access( $prevent_access ){
255
+
256
+ if( self::$woocommerce_wpml->check_dependencies ){
257
+ $user_lang_pairs = get_user_meta( get_current_user_id(), self::$wpdb->prefix.'language_pairs', true );
258
+ if( current_user_can( 'wpml_manage_woocommerce_multilingual' ) || !empty( $user_lang_pairs ) ){
259
+ return false;
260
+ }
261
+ }
262
+
263
+ return $prevent_access;
264
+ }
265
+
266
+ public static function add_menu_warning(){
267
+ global $submenu, $menu;
268
+
269
+ if (
270
+ class_exists( 'woocommerce' ) &&
271
+ (
272
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) ||
273
+ (
274
+ empty( self::$woocommerce_wpml->settings['set_up_wizard_run'] ) &&
275
+ self::$woocommerce_wpml->settings['set_up_wizard_splash']
276
+ )
277
+ )
278
+ ) {
279
+ if( isset( $submenu[ 'woocommerce' ] ) ){
280
+ foreach( $submenu[ 'woocommerce' ] as $key => $menu_item ) {
281
+ if ( $menu_item[ 0 ] == __( 'WooCommerce Multilingual', 'woocommerce-multilingual' ) ) {
282
+ $submenu[ 'woocommerce' ][ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
283
+ break;
284
+ }
285
+ }
286
+ }
287
+
288
+ foreach( $menu as $key => $menu_item ) {
289
+ if ( $menu_item[ 0 ] == __( 'WooCommerce', 'woocommerce' ) ) {
290
+ $menu[ $key ][ 0 ] .= '<span class="wcml-menu-warn"><i class="otgs-ico-warning"></i></span>';
291
+ break;
292
+ }
293
+ }
294
+ }
295
+ }
296
+
297
  }
inc/admin-menus/class-wcml-links.php CHANGED
@@ -1,25 +1,25 @@
1
- <?php
2
-
3
- class WCML_Links {
4
-
5
- public static function generate_tracking_link( $link, $term = false, $content = false, $id = false ) {
6
-
7
- $params = '?utm_source=wcml-admin&utm_medium=plugin&utm_term=';
8
- $params .= $term ? $term : 'WPML';
9
- $params .= '&utm_content=';
10
- $params .= $content ? $content : 'required-plugins';
11
- $params .= '&utm_campaign=WCML';
12
-
13
- if ( $id ) {
14
- $params .= $id;
15
- }
16
- return $link . $params;
17
-
18
- }
19
-
20
- public static function filter_woocommerce_redirect_location( $link ) {
21
- global $sitepress;
22
- return html_entity_decode( $sitepress->convert_url( $link ) );
23
- }
24
-
25
  }
1
+ <?php
2
+
3
+ class WCML_Links {
4
+
5
+ public static function generate_tracking_link( $link, $term = false, $content = false, $id = false ) {
6
+
7
+ $params = '?utm_source=wcml-admin&utm_medium=plugin&utm_term=';
8
+ $params .= $term ? $term : 'WPML';
9
+ $params .= '&utm_content=';
10
+ $params .= $content ? $content : 'required-plugins';
11
+ $params .= '&utm_campaign=WCML';
12
+
13
+ if ( $id ) {
14
+ $params .= $id;
15
+ }
16
+ return $link . $params;
17
+
18
+ }
19
+
20
+ public static function filter_woocommerce_redirect_location( $link ) {
21
+ global $sitepress;
22
+ return html_entity_decode( $sitepress->convert_url( $link ) );
23
+ }
24
+
25
  }
inc/admin-menus/class-wcml-pointers.php CHANGED
@@ -1,82 +1,82 @@
1
- <?php
2
-
3
- class WCML_Pointers{
4
-
5
- public function __construct(){
6
- add_action( 'admin_head', array( $this, 'setup') );
7
- }
8
-
9
- public function setup(){
10
- $current_screen = get_current_screen();
11
-
12
- if( empty($current_screen) ) {
13
- return;
14
- }
15
-
16
- $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
17
- $section = isset( $_GET['section'] ) ? $_GET['section'] : '';
18
- wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
19
-
20
- if( $current_screen->id == 'edit-product' ){
21
- add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
22
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'shipping' && $section == 'classes' ){
23
- add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
24
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && ( $tab == 'general' || empty($tab) ) ){
25
- add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
26
- }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'account'){
27
- add_filter( 'woocommerce_account_settings', array( $this, 'add_endpoints_translation_link' ) );
28
- }
29
-
30
- }
31
-
32
- public function add_products_translation_link(){
33
- $link = admin_url('admin.php?page=wpml-wcml');
34
- $name = __('Translate WooCommerce products', 'woocommerce-multilingual');
35
- wp_enqueue_style( 'wcml-pointers');
36
- ?>
37
- <script type="text/javascript">
38
- jQuery(".subsubsub").append('<a class="button button-small button-wpml wcml-pointer-products_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
39
- </script>
40
- <?php
41
- }
42
-
43
- public function add_shipping_classes_translation_link(){
44
- $link = admin_url('admin.php?page=wpml-wcml&tab=product_shipping_class');
45
- $name = __('Translate shipping classes', 'woocommerce-multilingual');
46
- wp_enqueue_style( 'wcml-pointers');
47
- ?>
48
- <script type="text/javascript">
49
- jQuery(".wc-shipping-classes").before('<a class="button button-small button-wpml wcml-pointer-shipping_classes_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
50
- </script>
51
- <?php
52
- }
53
-
54
- public function add_multi_currency_link( $settings ){
55
- $link = admin_url('admin.php?page=wpml-wcml&tab=multi-currency');
56
- $name = __('Configure multi-currency for multilingual sites', 'woocommerce-multilingual');
57
- wp_enqueue_style( 'wcml-pointers');
58
- foreach( $settings as $key => $value ){
59
- if( $value['id'] == 'pricing_options' && isset( $value['desc'] ) ){
60
-
61
- $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
62
- }
63
- }
64
-
65
- return $settings;
66
- }
67
-
68
- public function add_endpoints_translation_link( $settings ){
69
- $link = admin_url('admin.php?page=wpml-wcml&tab=slugs');
70
- $name = __('Translate endpoints', 'woocommerce-multilingual');
71
- wp_enqueue_style( 'wcml-pointers');
72
- foreach( $settings as $key => $value ){
73
- if( $value['id'] == 'account_endpoint_options' && isset( $value['desc'] ) ){
74
-
75
- $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
76
- }
77
- }
78
-
79
- return $settings;
80
- }
81
-
82
  }
1
+ <?php
2
+
3
+ class WCML_Pointers{
4
+
5
+ public function __construct(){
6
+ add_action( 'admin_head', array( $this, 'setup') );
7
+ }
8
+
9
+ public function setup(){
10
+ $current_screen = get_current_screen();
11
+
12
+ if( empty($current_screen) ) {
13
+ return;
14
+ }
15
+
16
+ $tab = isset( $_GET['tab'] ) ? $_GET['tab'] : '';
17
+ $section = isset( $_GET['section'] ) ? $_GET['section'] : '';
18
+ wp_register_style( 'wcml-pointers', WCML_PLUGIN_URL . '/res/css/wcml-pointers.css' );
19
+
20
+ if( $current_screen->id == 'edit-product' ){
21
+ add_action( 'admin_footer', array( $this, 'add_products_translation_link' ), 100 );
22
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'shipping' && $section == 'classes' ){
23
+ add_action( 'admin_footer', array( $this, 'add_shipping_classes_translation_link' ) );
24
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && ( $tab == 'general' || empty($tab) ) ){
25
+ add_filter( 'woocommerce_general_settings', array( $this, 'add_multi_currency_link' ) );
26
+ }elseif( $current_screen->id == 'woocommerce_page_wc-settings' && $tab == 'account'){
27
+ add_filter( 'woocommerce_account_settings', array( $this, 'add_endpoints_translation_link' ) );
28
+ }
29
+
30
+ }
31
+
32
+ public function add_products_translation_link(){
33
+ $link = admin_url('admin.php?page=wpml-wcml');
34
+ $name = __('Translate WooCommerce products', 'woocommerce-multilingual');
35
+ wp_enqueue_style( 'wcml-pointers');
36
+ ?>
37
+ <script type="text/javascript">
38
+ jQuery(".subsubsub").append('<a class="button button-small button-wpml wcml-pointer-products_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
39
+ </script>
40
+ <?php
41
+ }
42
+
43
+ public function add_shipping_classes_translation_link(){
44
+ $link = admin_url('admin.php?page=wpml-wcml&tab=product_shipping_class');
45
+ $name = __('Translate shipping classes', 'woocommerce-multilingual');
46
+ wp_enqueue_style( 'wcml-pointers');
47
+ ?>
48
+ <script type="text/javascript">
49
+ jQuery(".wc-shipping-classes").before('<a class="button button-small button-wpml wcml-pointer-shipping_classes_translation" href="<?php echo $link ?>"><?php echo $name ?></a>');
50
+ </script>
51
+ <?php
52
+ }
53
+
54
+ public function add_multi_currency_link( $settings ){
55
+ $link = admin_url('admin.php?page=wpml-wcml&tab=multi-currency');
56
+ $name = __('Configure multi-currency for multilingual sites', 'woocommerce-multilingual');
57
+ wp_enqueue_style( 'wcml-pointers');
58
+ foreach( $settings as $key => $value ){
59
+ if( $value['id'] == 'pricing_options' && isset( $value['desc'] ) ){
60
+
61
+ $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-multi_currency" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
62
+ }
63
+ }
64
+
65
+ return $settings;
66
+ }
67
+
68
+ public function add_endpoints_translation_link( $settings ){
69
+ $link = admin_url('admin.php?page=wpml-wcml&tab=slugs');
70
+ $name = __('Translate endpoints', 'woocommerce-multilingual');
71
+ wp_enqueue_style( 'wcml-pointers');
72
+ foreach( $settings as $key => $value ){
73
+ if( $value['id'] == 'account_endpoint_options' && isset( $value['desc'] ) ){
74
+
75
+ $settings[$key]['desc'] = '<a class="button button-small button-wpml wcml-pointer-endpoints_translation" href="' . $link . '">' . $name .'</a><br />' . $value['desc'];
76
+ }
77
+ }
78
+
79
+ return $settings;
80
+ }
81
+
82
  }
inc/admin-menus/class-wcml-setup.php CHANGED
@@ -1,343 +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->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
  }
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,159 +1,159 @@
1
- <?php
2
-
3
-
4
- class WCML_Ajax_Setup{
5
-
6
- /**
7
- * @var SitePress
8
- */
9
- private $sitepress;
10
-
11
- public function __construct( $sitepres ){
12
-
13
- $this->sitepress =& $sitepres;
14
-
15
- add_action( 'init', array( $this, 'init' ) );
16
- add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
17
-
18
- //@deprecated 3.9
19
- add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
20
-
21
- add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
22
- }
23
-
24
- public function init(){
25
- if (wpml_is_ajax()){
26
- do_action('wcml_localize_woocommerce_on_ajax');
27
- }
28
-
29
- add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
30
-
31
- add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
32
- add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
33
- add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
34
- add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
35
-
36
- add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
37
- add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
38
- add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
39
-
40
- }
41
-
42
- function filter_woocommerce_order_review(){
43
- global $woocommerce;
44
- unload_textdomain('woocommerce');
45
- $woocommerce->load_plugin_textdomain();
46
- }
47
-
48
- function add_hidden_language_field(){
49
- if( function_exists('wpml_the_language_input_field') ){
50
- wpml_the_language_input_field();
51
- }else{
52
- global $sitepress;
53
- if (isset($sitepress) ) {
54
- return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
55
- }
56
- return null;
57
- }
58
- }
59
-
60
- function add_language_parameter_to_ajax_url($woocommerce_params){
61
- global $sitepress;
62
-
63
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
64
- $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
65
- }
66
-
67
- return $woocommerce_params;
68
- }
69
-
70
- function filter_woocommerce_ajax_params($woocommerce_params){
71
- global $sitepress, $post;
72
- $value = array();
73
- $value = $woocommerce_params;
74
-
75
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
76
- $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
77
- $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
- }
79
-
80
- if(!isset($post->ID)){
81
- return $value;
82
- }
83
-
84
- $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
85
-
86
- if(empty($ch_pages)){
87
-
88
- $ch_pages = array(
89
-
90
- 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
91
- 'pay_page_id' => get_option('woocommerce_pay_page_id'),
92
- 'cart_page_id' => get_option('woocommerce_cart_page_id'));
93
-
94
- $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
95
- $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
96
- $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
97
-
98
- }
99
-
100
- wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
101
-
102
- if($ch_pages['translated_cart_page_id'] == $post->ID){
103
- $value['is_cart'] = 1;
104
- $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
105
- } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
106
- $value['is_checkout'] = 1;
107
-
108
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
109
-
110
- } else if($ch_pages['translated_pay_page_id'] == $post->ID){
111
- $value['is_pay_page'] = 1;
112
- }
113
-
114
- return $value;
115
- }
116
-
117
-
118
- function wcml_localize_woocommerce_on_ajax(){
119
- if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
120
- return;
121
- }
122
-
123
- global $sitepress;
124
-
125
- $current_language = $sitepress->get_current_language();
126
-
127
- $sitepress->switch_lang($current_language, true);
128
- }
129
-
130
- /**
131
- * @param $endpoint string
132
- *
133
- * Adds a language parameter to the url when different domains for each language are used
134
- *
135
- * @return string
136
- */
137
- public function add_language_to_endpoint( $endpoint ){
138
-
139
- $is_per_domain = WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
140
- if( $is_per_domain && $this->sitepress->get_current_language() != $this->sitepress->get_default_language() ){
141
-
142
- $endpoint = add_query_arg('lang', $this->sitepress->get_current_language(), remove_query_arg( 'lang', $endpoint ) );
143
- $endpoint = urldecode($endpoint);
144
-
145
- }
146
-
147
- return $endpoint;
148
- }
149
-
150
-
151
- /**
152
- * @deprecated 3.9
153
- */
154
- function localize_woocommerce_on_ajax(){
155
- $this->wcml_localize_woocommerce_on_ajax();
156
- }
157
-
158
-
159
- }
1
+ <?php
2
+
3
+
4
+ class WCML_Ajax_Setup{
5
+
6
+ /**
7
+ * @var SitePress
8
+ */
9
+ private $sitepress;
10
+
11
+ public function __construct( $sitepres ){
12
+
13
+ $this->sitepress =& $sitepres;
14
+
15
+ add_action( 'init', array( $this, 'init' ) );
16
+ add_action( 'wcml_localize_woocommerce_on_ajax', array( $this, 'wcml_localize_woocommerce_on_ajax' ) );
17
+
18
+ //@deprecated 3.9
19
+ add_action( 'localize_woocommerce_on_ajax', array( $this, 'localize_woocommerce_on_ajax' ) );
20
+
21
+ add_action( 'woocommerce_ajax_get_endpoint', array( $this, 'add_language_to_endpoint' ) );
22
+ }
23
+
24
+ public function init(){
25
+ if (wpml_is_ajax()){
26
+ do_action('wcml_localize_woocommerce_on_ajax');
27
+ }
28
+
29
+ add_filter('woocommerce_params', array($this, 'filter_woocommerce_ajax_params'));
30
+
31
+ add_filter('wc_checkout_params', array($this, 'add_language_parameter_to_ajax_url'));
32
+ add_filter('wc_cart', array($this, 'add_language_parameter_to_ajax_url'));
33
+ add_filter('wc_cart_fragments_params', array($this, 'add_language_parameter_to_ajax_url'));
34
+ add_filter('wc_add_to_cart_params', array($this, 'add_language_parameter_to_ajax_url'));
35
+
36
+ add_action( 'woocommerce_checkout_order_review', array($this,'filter_woocommerce_order_review'), 9 );
37
+ add_action( 'woocommerce_checkout_order_review', array($this,'add_hidden_language_field') );
38
+ add_action( 'woocommerce_checkout_update_order_review', array($this,'filter_woocommerce_order_review'), 9 );
39
+
40
+ }
41
+
42
+ function filter_woocommerce_order_review(){
43
+ global $woocommerce;
44
+ unload_textdomain('woocommerce');
45
+ $woocommerce->load_plugin_textdomain();
46
+ }
47
+
48
+ function add_hidden_language_field(){
49
+ if( function_exists('wpml_the_language_input_field') ){
50
+ wpml_the_language_input_field();
51
+ }else{
52
+ global $sitepress;
53
+ if (isset($sitepress) ) {
54
+ return "<input type='hidden' name='lang' value='" . $sitepress->get_current_language() . "' />";
55
+ }
56
+ return null;
57
+ }
58
+ }
59
+
60
+ function add_language_parameter_to_ajax_url($woocommerce_params){
61
+ global $sitepress;
62
+
63
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
64
+ $woocommerce_params['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
65
+ }
66
+
67
+ return $woocommerce_params;
68
+ }
69
+
70
+ function filter_woocommerce_ajax_params($woocommerce_params){
71
+ global $sitepress, $post;
72
+ $value = array();
73
+ $value = $woocommerce_params;
74
+
75
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
76
+ $value['ajax_url'] = add_query_arg('lang', ICL_LANGUAGE_CODE, $woocommerce_params['ajax_url']);
77
+ $value['checkout_url'] = add_query_arg('action', 'woocommerce-checkout', $value['ajax_url']);
78
+ }
79
+
80
+ if(!isset($post->ID)){
81
+ return $value;
82
+ }
83
+
84
+ $ch_pages = wp_cache_get('ch_pages', 'wcml_ch_pages');
85
+
86
+ if(empty($ch_pages)){
87
+
88
+ $ch_pages = array(
89
+
90
+ 'checkout_page_id' => get_option('woocommerce_checkout_page_id'),
91
+ 'pay_page_id' => get_option('woocommerce_pay_page_id'),
92
+ 'cart_page_id' => get_option('woocommerce_cart_page_id'));
93
+
94
+ $ch_pages['translated_checkout_page_id'] = apply_filters( 'translate_object_id',$ch_pages['checkout_page_id'], 'page', false);
95
+ $ch_pages['translated_pay_page_id'] = apply_filters( 'translate_object_id',$ch_pages['pay_page_id'], 'page', false);
96
+ $ch_pages['translated_cart_page_id'] = apply_filters( 'translate_object_id',$ch_pages['cart_page_id'], 'page', false);
97
+
98
+ }
99
+
100
+ wp_cache_set( 'ch_pages', $ch_pages, 'wcml_ch_pages' );
101
+
102
+ if($ch_pages['translated_cart_page_id'] == $post->ID){
103
+ $value['is_cart'] = 1;
104
+ $value['cart_url'] = get_permalink($ch_pages['translated_cart_page_id']);
105
+ } else if($ch_pages['translated_checkout_page_id'] == $post->ID || $ch_pages['checkout_page_id'] == $post->ID){
106
+ $value['is_checkout'] = 1;
107
+
108
+ $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
109
+
110
+ } else if($ch_pages['translated_pay_page_id'] == $post->ID){
111
+ $value['is_pay_page'] = 1;
112
+ }
113
+
114
+ return $value;
115
+ }
116
+
117
+
118
+ function wcml_localize_woocommerce_on_ajax(){
119
+ if( isset($_POST['action']) && in_array( $_POST['action'], array( 'wcml_product_data', 'wpml_translation_dialog_save_job' ) ) ){
120
+ return;
121
+ }
122
+
123
+ global $sitepress;
124
+
125
+ $current_language = $sitepress->get_current_language();
126
+
127
+ $sitepress->switch_lang($current_language, true);
128
+ }
129
+
130
+ /**
131
+ * @param $endpoint string
132
+ *
133
+ * Adds a language parameter to the url when different domains for each language are used
134
+ *
135
+ * @return string
136
+ */
137
+ public function add_language_to_endpoint( $endpoint ){
138
+
139
+ $is_per_domain = WPML_LANGUAGE_NEGOTIATION_TYPE_DOMAIN === (int) $this->sitepress->get_setting( 'language_negotiation_type' );
140
+ if( $is_per_domain && $this->sitepress->get_current_language() != $this->sitepress->get_default_language() ){
141
+
142
+ $endpoint = add_query_arg('lang', $this->sitepress->get_current_language(), remove_query_arg( 'lang', $endpoint ) );
143
+ $endpoint = urldecode($endpoint);
144
+
145
+ }
146
+
147
+ return $endpoint;
148
+ }
149
+
150
+
151
+ /**
152
+ * @deprecated 3.9
153
+ */
154
+ function localize_woocommerce_on_ajax(){
155
+ $this->wcml_localize_woocommerce_on_ajax();
156
+ }
157
+
158
+
159
+ }
inc/class-wcml-attributes.php CHANGED
@@ -1,404 +1,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
- public function is_attributes_fully_translated(){
386
-
387
- $product_attributes = $this->get_translatable_attributes();
388
-
389
- $fully_translated = true;
390
-
391
- if( $product_attributes ){
392
- foreach( $product_attributes as $attribute ){
393
- $is_fully_translated = $this->woocommerce_wpml->terms->is_fully_translated( 'pa_' . $attribute->attribute_name );
394
- if( !$is_fully_translated ){
395
- $fully_translated = false;
396
- break;
397
- }
398
- }
399
- }
400
-
401
- return $fully_translated;
402
- }
403
-
404
  }
1
+ <?php
2
+
3
+ class WCML_Attributes{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+ private $wpdb;
8
+
9
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+ $this->wpdb = $wpdb;
13
+
14
+ add_action( 'init', array( $this, 'init' ) );
15
+
16
+ add_action( 'woocommerce_attribute_added', array( $this, 'set_attribute_readonly_config' ), 100, 2 );
17
+ add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
18
+
19
+ if( isset( $_POST['icl_ajx_action'] ) && $_POST['icl_ajx_action'] == 'icl_custom_tax_sync_options' ){
20
+ $this->icl_custom_tax_sync_options();
21
+ }
22
+
23
+ }
24
+
25
+ public function init(){
26
+
27
+ $is_attr_page = apply_filters( 'wcml_is_attributes_page', isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'product_attributes' && isset( $_GET[ 'post_type' ] ) && $_GET[ 'post_type' ] == 'product' );
28
+
29
+ if( $is_attr_page ){
30
+
31
+ add_action( 'admin_init', array( $this, 'not_translatable_html' ) );
32
+
33
+ if( isset( $_POST[ 'save_attribute' ] ) && isset( $_GET[ 'edit' ] ) ){
34
+ $this->set_attribute_readonly_config( $_GET[ 'edit' ], $_POST );
35
+ }
36
+ }
37
+
38
+ }
39
+
40
+ public function not_translatable_html(){
41
+ $attr_id = isset( $_GET[ 'edit' ] ) ? absint( $_GET[ 'edit' ] ) : false;
42
+
43
+ $attr_is_tnaslt = new WCML_Not_Translatable_Attributes( $attr_id, $this->woocommerce_wpml );
44
+ $attr_is_tnaslt->show();
45
+ }
46
+
47
+ public function get_attribute_terms( $attribute ){
48
+
49
+ return $this->wpdb->get_results($this->wpdb->prepare("
50
+ SELECT * FROM {$this->wpdb->term_taxonomy} x JOIN {$this->wpdb->terms} t ON x.term_id = t.term_id WHERE x.taxonomy = %s", $attribute ) );
51
+
52
+ }
53
+
54
+ public function set_attribute_readonly_config( $id, $attribute ){
55
+
56
+ $is_translatable = isset( $_POST[ 'wcml-is-translatable-attr' ] ) ? 1 : 0;
57
+ $attribute_name = wc_attribute_taxonomy_name( $attribute['attribute_name'] );
58
+ if( $is_translatable === 0 ){
59
+ //delete all translated attributes terms if "Translatable?" option un-checked
60
+ $this->delete_translated_attribute_terms( $attribute_name );
61
+ $this->set_variations_to_use_original_attributes( $attribute_name );
62
+ $this->set_original_attributes_for_products( $attribute_name );
63
+ }
64
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
65
+ }
66
+
67
+ public function set_attribute_config_in_settings( $attribute_name, $is_translatable ){
68
+ $this->set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable );
69
+ $this->set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable );
70
+
71
+ $this->woocommerce_wpml->terms->update_terms_translated_status( $attribute_name );
72
+ }
73
+
74
+ public function set_attribute_config_in_wcml_settings( $attribute_name, $is_translatable ){
75
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
76
+ $wcml_settings[ 'attributes_settings' ][ $attribute_name ] = $is_translatable;
77
+ $this->woocommerce_wpml->update_settings( $wcml_settings );
78
+ }
79
+
80
+ public function set_attribute_config_in_wpml_settings( $attribute_name, $is_translatable ){
81
+
82
+ $sync_settings = $this->sitepress->get_setting( 'taxonomies_sync_option', array() );
83
+ $sync_settings[ $attribute_name ] = $is_translatable;
84
+ $this->sitepress->set_setting( 'taxonomies_sync_option', $sync_settings, true );
85
+ $this->sitepress->verify_taxonomy_translations( $attribute_name );
86
+ }
87
+
88
+ public function delete_translated_attribute_terms( $attribute ){
89
+ $terms = $this->get_attribute_terms( $attribute );
90
+
91
+ foreach( $terms as $term ){
92
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
93
+ if( $term_language_details && $term_language_details->source_language_code ){
94
+ wp_delete_term( $term->term_id, $attribute );
95
+ }
96
+ }
97
+
98
+ }
99
+
100
+ public function set_variations_to_use_original_attributes( $attribute ){
101
+ $terms = $this->get_attribute_terms( $attribute );
102
+
103
+ foreach( $terms as $term ){
104
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
105
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
106
+ $variations = $this->wpdb->get_results( $this->wpdb->prepare( "SELECT post_id FROM {$this->wpdb->postmeta} WHERE meta_key=%s AND meta_value = %s", 'attribute_'.$attribute, $term->slug ) );
107
+
108
+ foreach( $variations as $variation ){
109
+ //update taxonomy in translation of variation
110
+ foreach( $this->sitepress->get_active_languages() as $language ){
111
+
112
+ $trnsl_variation_id = apply_filters( 'translate_object_id', $variation->post_id, 'product_variation', false, $language['code'] );
113
+ if( !is_null( $trnsl_variation_id ) ){
114
+ update_post_meta( $trnsl_variation_id, 'attribute_'.$attribute, $term->slug );
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+ }
121
+
122
+ public function set_original_attributes_for_products( $attribute ){
123
+
124
+ $terms = $this->get_attribute_terms( $attribute );
125
+ $cleared_products = array();
126
+ foreach( $terms as $term ) {
127
+ $term_language_details = $this->sitepress->get_element_language_details( $term->term_id, 'tax_'.$attribute );
128
+ if( $term_language_details && is_null( $term_language_details->source_language_code ) ){
129
+ $args = array(
130
+ 'tax_query' => array(
131
+ array(
132
+ 'taxonomy' => $attribute,
133
+ 'field' => 'slug',
134
+ 'terms' => $term->slug
135
+ )
136
+ )
137
+ );
138
+
139
+ $products = get_posts($args);
140
+
141
+ foreach( $products as $product ){
142
+
143
+ foreach( $this->sitepress->get_active_languages() as $language ) {
144
+
145
+ $trnsl_product_id = apply_filters( 'translate_object_id', $product->ID, 'product', false, $language['code'] );
146
+
147
+ if ( !is_null( $trnsl_product_id ) ) {
148
+ if( !in_array( $trnsl_product_id, $trnsl_product_id ) ){
149
+ wp_delete_object_term_relationships( $trnsl_product_id, $attribute );
150
+ $cleared_products[] = $trnsl_product_id;
151
+ }
152
+ wp_set_object_terms( $trnsl_product_id, $term->slug, $attribute, true );
153
+ }
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
159
+
160
+
161
+ public function is_translatable_attribute( $attr_name ){
162
+
163
+ if( !isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ){
164
+ $this->set_attribute_config_in_settings( $attr_name, 1 );
165
+ }
166
+
167
+ return isset( $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] ) ? $this->woocommerce_wpml->settings[ 'attributes_settings' ][ $attr_name ] : 1;
168
+ }
169
+
170
+ public function get_translatable_attributes(){
171
+ $attributes = wc_get_attribute_taxonomies();
172
+
173
+ $translatable_attributes = array();
174
+ foreach( $attributes as $attribute ){
175
+ if( $this->is_translatable_attribute( wc_attribute_taxonomy_name( $attribute->attribute_name ) ) ){
176
+ $translatable_attributes[] = $attribute;
177
+ }
178
+ }
179
+
180
+ return $translatable_attributes;
181
+ }
182
+
183
+ public function set_translatable_attributes( $attributes ){
184
+
185
+ foreach( $attributes as $name => $is_translatable ){
186
+
187
+ $attribute_name = wc_attribute_taxonomy_name( $name );
188
+ $this->set_attribute_config_in_settings( $attribute_name, $is_translatable );
189
+
190
+ }
191
+ }
192
+
193
+ public function sync_product_attr( $original_product_id, $tr_product_id, $language = false, $data = false ){
194
+
195
+ //get "_product_attributes" from original product
196
+ $orig_product_attrs = $this->get_product_atributes( $original_product_id );
197
+ $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
198
+
199
+ $trnsl_labels = 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,274 +1,274 @@
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( isset( $_SERVER['REQUEST_URI'] ) ){
205
- //special case: check if attachment loading
206
- $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
207
-
208
- foreach( $attachments as $attachment ){
209
- $match = preg_match( '/\.'.$attachment.'$/', $_SERVER['REQUEST_URI'] );
210
- if( !empty( $match ) ){
211
- return false;
212
- }
213
- }
214
- }
215
-
216
- if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
217
- $cart->calculate_totals();
218
- }
219
-
220
- }
221
-
222
- // refresh cart total to return correct price from WC object
223
- public function wcml_refresh_cart_total() {
224
- WC()->cart->calculate_totals();
225
- }
226
-
227
-
228
- public function localize_flat_rates_shipping_classes(){
229
- global $woocommerce;
230
-
231
- if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
232
- $woocommerce->shipping->load_shipping_methods();
233
- $shipping_methods = $woocommerce->shipping->get_shipping_methods();
234
- foreach($shipping_methods as $method){
235
- if(isset($method->flat_rate_option)){
236
- add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
237
- }
238
- }
239
-
240
- }
241
- }
242
-
243
- public function translate_shipping_class($rates){
244
-
245
- if(is_array($rates)){
246
- foreach($rates as $shipping_class => $value){
247
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
248
-
249
- if($term_id && !is_wp_error($term_id)){
250
- $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
251
- if($translated_term_id != $term_id){
252
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
253
- unset($rates[$shipping_class]);
254
- $rates[$term->slug] = $value;
255
-
256
- }
257
- }
258
- }
259
- }
260
- return $rates;
261
- }
262
-
263
- public function filter_paypal_args( $args ) {
264
- $args['lc'] = $this->sitepress->get_current_language();
265
-
266
- //filter URL when default permalinks uses
267
- $wpml_settings = $this->sitepress->get_settings();
268
- if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
269
- $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
270
- }
271
-
272
- return $args;
273
- }
274
  }
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( isset( $_SERVER['REQUEST_URI'] ) ){
205
+ //special case: check if attachment loading
206
+ $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
207
+
208
+ foreach( $attachments as $attachment ){
209
+ $match = preg_match( '/\.'.$attachment.'$/', $_SERVER['REQUEST_URI'] );
210
+ if( !empty( $match ) ){
211
+ return false;
212
+ }
213
+ }
214
+ }
215
+
216
+ if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
217
+ $cart->calculate_totals();
218
+ }
219
+
220
+ }
221
+
222
+ // refresh cart total to return correct price from WC object
223
+ public function wcml_refresh_cart_total() {
224
+ WC()->cart->calculate_totals();
225
+ }
226
+
227
+
228
+ public function localize_flat_rates_shipping_classes(){
229
+ global $woocommerce;
230
+
231
+ if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
232
+ $woocommerce->shipping->load_shipping_methods();
233
+ $shipping_methods = $woocommerce->shipping->get_shipping_methods();
234
+ foreach($shipping_methods as $method){
235
+ if(isset($method->flat_rate_option)){
236
+ add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
237
+ }
238
+ }
239
+
240
+ }
241
+ }
242
+
243
+ public function translate_shipping_class($rates){
244
+
245
+ if(is_array($rates)){
246
+ foreach($rates as $shipping_class => $value){
247
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
248
+
249
+ if($term_id && !is_wp_error($term_id)){
250
+ $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
251
+ if($translated_term_id != $term_id){
252
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
253
+ unset($rates[$shipping_class]);
254
+ $rates[$term->slug] = $value;
255
+
256
+ }
257
+ }
258
+ }
259
+ }
260
+ return $rates;
261
+ }
262
+
263
+ public function filter_paypal_args( $args ) {
264
+ $args['lc'] = $this->sitepress->get_current_language();
265
+
266
+ //filter URL when default permalinks uses
267
+ $wpml_settings = $this->sitepress->get_settings();
268
+ if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
269
+ $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
270
+ }
271
+
272
+ return $args;
273
+ }
274
  }
inc/class-wcml-compatibility.php CHANGED
@@ -1,171 +1,176 @@
1
- <?php
2
-
3
- class WCML_Compatibility {
4
-
5
- /**
6
- * @var SitePress
7
- */
8
- public $sitepress;
9
-
10
- /**
11
- * @var woocommerce_wpml
12
- */
13
- public $woocommerce_wpml;
14
-
15
- /**
16
- * @var wpdb
17
- */
18
- public $wpdb;
19
-
20
- function __construct( &$sitepress, &$woocommerce_wpml, &$wpdb ) {
21
- $this->sitepress = $sitepress;
22
- $this->woocommerce_wpml = $woocommerce_wpml;
23
- $this->wpdb = $wpdb;
24
- $this->init();
25
-
26
- }
27
-
28
- function init(){
29
- //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
30
-
31
- //WooCommerce Tab Manager plugin
32
- if(class_exists('WC_Tab_Manager')){
33
- global $woocommerce;
34
- $this->tab_manager = new WCML_Tab_Manager( $this->sitepress, $woocommerce, $this->woocommerce_wpml, $this->wpdb );
35
- }
36
-
37
- //WooCommerce Table Rate Shipping plugin
38
- if(defined('TABLE_RATE_SHIPPING_VERSION')){
39
- $this->table_rate_shipping = new WCML_Table_Rate_Shipping( $this->sitepress, $this->woocommerce_wpml );
40
- }
41
-
42
- //WooCommerce Subscriptions
43
- if(class_exists('WC_Subscriptions')){
44
- $this->wp_subscriptions = new WCML_WC_Subscriptions();
45
- }
46
-
47
- //WooCommerce Name Your Price
48
- if(class_exists('WC_Name_Your_Price')){
49
- $this->name_your_price = new WCML_WC_Name_Your_Price();
50
- }
51
-
52
- //Product Bundle
53
- if(class_exists('WC_Product_Bundle')){
54
- $this->product_bundles = new WCML_Product_Bundles( $this->sitepress, $this->woocommerce_wpml );
55
- }
56
-
57
- // WooCommerce Variation Swatches and Photos
58
- if(class_exists('WC_SwatchesPlugin')){
59
- $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
60
- }
61
-
62
- // Product Add-ons
63
- if(class_exists( 'Product_Addon_Display' )){
64
- $this->product_addons = new WCML_Product_Addons( $this->sitepress );
65
- }
66
-
67
- // Product Per Product Shipping
68
- if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
69
- new WCML_Per_Product_Shipping();
70
- }
71
- //Store Exporter plugin
72
- if(defined('WOO_CE_PATH')){
73
- $this->wc_exporter = new WCML_wcExporter();
74
- }
75
-
76
- //Gravity Forms
77
- if(class_exists('GFForms')){
78
- $this->gravityforms = new WCML_gravityforms();
79
- }
80
-
81
- //Sensei WooThemes
82
- if(class_exists('WooThemes_Sensei')){
83
- $this->sensei = new WCML_sensei();
84
- }
85
-
86
- //Extra Product Options
87
- if(class_exists('TM_Extra_Product_Options')){
88
- $this->extra_product_options = new WCML_Extra_Product_Options();
89
- }
90
-
91
- // Dynamic Pricing
92
- if ( class_exists('WC_Dynamic_Pricing') ) {
93
- $this->dynamic_pricing = new WCML_Dynamic_Pricing( $this->sitepress );
94
- }
95
-
96
- // WooCommerce Bookings
97
- if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
98
- $this->bookings = new WCML_Bookings( $this->sitepress, $this->woocommerce_wpml, $this->wpdb );
99
-
100
- // WooCommerce Accommodation Bookings
101
- if( defined( 'WC_ACCOMMODATION_BOOKINGS_VERSION' ) ){
102
- $this->accomodation_bookings = new WCML_Accommodation_Bookings( $this->woocommerce_wpml );
103
- }
104
- }
105
-
106
- // WooCommerce Checkout Field Editor
107
- if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
108
- $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
109
- }
110
-
111
- if (class_exists('WC_Bulk_Stock_Management')) {
112
- $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
113
- }
114
-
115
- // WooCommerce Advanced Ajax Layered Navigation
116
- include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
117
- if ( is_plugin_active( 'woocommerce-ajax-layered-nav/ajax_layered_nav-widget.php' ) ) {
118
- $this->wc_ajax_layered_nav_widget = new WCML_Ajax_Layered_Nav_Widget();
119
- }
120
-
121
- if ( is_plugin_active( 'woocommerce-ajax-cart/wooajaxcart.php' ) ) {
122
- $this->wc_ajax_cart = new WCML_WC_Ajax_Cart();
123
- }
124
-
125
- // woocommerce composite products
126
- if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
127
- $this->wc_composite_products = new WCML_Composite_Products( $this->sitepress, $this->woocommerce_wpml );
128
- }
129
-
130
- // woocommerce checkout addons
131
- if (function_exists('init_woocommerce_checkout_add_ons')) {
132
- $this->wc_checkout_addons = new WCML_Checkout_Addons();
133
- }
134
-
135
- // woocommerce checkout addons
136
- if ( wp_get_theme() == 'Flatsome' ) {
137
- $this->flatsome = new WCML_Flatsome();
138
- }
139
-
140
- if (class_exists('WC_Mix_and_Match')) {
141
- $this->mix_and_match_products = new WCML_Mix_and_Match_Products();
142
- }
143
-
144
- if ( defined( 'WPSEO_VERSION') ) {
145
- $this->wpseo = new WCML_WPSEO();
146
- }
147
-
148
- //Adventure Tours theme
149
- if( function_exists( 'adventure_tours_check' ) ){
150
- $this->adventure_tours = new WCML_Adventure_tours();
151
- }
152
-
153
- //Aurum Theme
154
- if( wp_get_theme() == 'Aurum' ){
155
- new WCML_Aurum();
156
- }
157
-
158
- // Visual Products Configurator
159
- if( class_exists( 'Vpc' ) ){
160
- $this->vpc = new WCML_Vpc();
161
- }
162
-
163
- // WooCommerce Show Single Variations
164
- if( defined( 'JCK_WSSV_PATH' ) ){
165
- new WCML_JCK_WSSV();
166
- }
167
-
168
-
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
+ // WooCommerce Print Invoices
169
+ if( class_exists( 'WC_PIP' ) ){
170
+ $this->pip = new WCML_Pip();
171
+ }
172
+
173
+
174
+ }
175
+
176
  }
inc/class-wcml-coupons.php CHANGED
@@ -1,88 +1,88 @@
1
- <?php
2
-
3
- class WCML_Coupons{
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
-
8
- public function __construct( &$woocommerce_wpml, &$sitepress ){
9
- $this->woocommerce_wpml = $woocommerce_wpml;
10
- $this->sitepress = $sitepress;
11
-
12
- add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
13
- add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
14
- }
15
-
16
- public function wcml_coupon_loaded( $coupons_data ){
17
-
18
- $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
19
-
20
- $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
21
- $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
22
- $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
23
- $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
24
-
25
- $product_ids = array();
26
- $exclude_product_ids = array();
27
- $product_categories_ids = array();
28
- $exclude_product_categories_ids = array();
29
-
30
- foreach( $coupon_product_ids as $prod_id ){
31
- $post_type = get_post_field( 'post_type', $prod_id );
32
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
33
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
34
- foreach( $translations as $translation ){
35
- $product_ids[] = $translation->element_id;
36
- }
37
- }
38
- foreach( $coupon_excluded_product_ids as $prod_id ){
39
- $post_type = get_post_field( 'post_type', $prod_id );
40
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
41
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
42
- foreach( $translations as $translation ){
43
- $exclude_product_ids[] = $translation->element_id;
44
- }
45
- }
46
-
47
- foreach( $coupon_product_categories as $cat_id ){
48
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
49
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
50
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
51
-
52
- foreach( $translations as $translation ){
53
- $product_categories_ids[] = $translation->term_id;
54
- }
55
- }
56
-
57
- foreach( $coupon_excluded_product_categories as $cat_id ){
58
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
59
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
60
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
61
- foreach( $translations as $translation ){
62
- $exclude_product_categories_ids[] = $translation->term_id;
63
- }
64
- }
65
-
66
- if( $wc_27_coupons ){
67
- $coupons_data->set_product_ids( $product_ids );
68
- $coupons_data->set_excluded_product_ids( $exclude_product_ids );
69
- $coupons_data->set_product_categories( $product_categories_ids );
70
- $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
71
- } else {
72
- $coupons_data->product_ids = $product_ids;
73
- $coupons_data->exclude_product_ids = $exclude_product_ids;
74
- $coupons_data->product_categories = $product_categories_ids;
75
- $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
76
- }
77
-
78
- return $coupons_data;
79
- }
80
-
81
- public function icl_adjust_terms_filtering(){
82
- if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
83
- global $icl_adjust_id_url_filter_off;
84
- $icl_adjust_id_url_filter_off = true;
85
- }
86
- }
87
-
88
  }
1
+ <?php
2
+
3
+ class WCML_Coupons{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+
8
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
9
+ $this->woocommerce_wpml = $woocommerce_wpml;
10
+ $this->sitepress = $sitepress;
11
+
12
+ add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
13
+ add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
14
+ }
15
+
16
+ public function wcml_coupon_loaded( $coupons_data ){
17
+
18
+ $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
19
+
20
+ $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
21
+ $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
22
+ $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
23
+ $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
24
+
25
+ $product_ids = array();
26
+ $exclude_product_ids = array();
27
+ $product_categories_ids = array();
28
+ $exclude_product_categories_ids = array();
29
+
30
+ foreach( $coupon_product_ids as $prod_id ){
31
+ $post_type = get_post_field( 'post_type', $prod_id );
32
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
33
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
34
+ foreach( $translations as $translation ){
35
+ $product_ids[] = $translation->element_id;
36
+ }
37
+ }
38
+ foreach( $coupon_excluded_product_ids as $prod_id ){
39
+ $post_type = get_post_field( 'post_type', $prod_id );
40
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
41
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
42
+ foreach( $translations as $translation ){
43
+ $exclude_product_ids[] = $translation->element_id;
44
+ }
45
+ }
46
+
47
+ foreach( $coupon_product_categories as $cat_id ){
48
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
49
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
50
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
51
+
52
+ foreach( $translations as $translation ){
53
+ $product_categories_ids[] = $translation->term_id;
54
+ }
55
+ }
56
+
57
+ foreach( $coupon_excluded_product_categories as $cat_id ){
58
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
59
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
60
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
61
+ foreach( $translations as $translation ){
62
+ $exclude_product_categories_ids[] = $translation->term_id;
63
+ }
64
+ }
65
+
66
+ if( $wc_27_coupons ){
67
+ $coupons_data->set_product_ids( $product_ids );
68
+ $coupons_data->set_excluded_product_ids( $exclude_product_ids );
69
+ $coupons_data->set_product_categories( $product_categories_ids );
70
+ $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
71
+ } else {
72
+ $coupons_data->product_ids = $product_ids;
73
+ $coupons_data->exclude_product_ids = $exclude_product_ids;
74
+ $coupons_data->product_categories = $product_categories_ids;
75
+ $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
76
+ }
77
+
78
+ return $coupons_data;
79
+ }
80
+
81
+ public function icl_adjust_terms_filtering(){
82
+ if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
83
+ global $icl_adjust_id_url_filter_off;
84
+ $icl_adjust_id_url_filter_off = true;
85
+ }
86
+ }
87
+
88
  }
inc/class-wcml-dependencies.php CHANGED
@@ -1,347 +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.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
 
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,458 +1,480 @@
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
- * Translate WooCommerce emails.
89
- *
90
- * @global type $sitepress
91
- * @global type $order_id
92
- * @return type
93
- */
94
- function email_header( $order ) {
95
-
96
- if( is_array( $order ) ) {
97
- $order = $order[ 'order_id' ];
98
- } elseif( is_object( $order ) ) {
99
- $order = $order->id;
100
- }
101
-
102
- $this->refresh_email_lang( $order );
103
- }
104
-
105
-
106
- function refresh_email_lang( $order_id ){
107
-
108
- if ( is_array( $order_id ) ) {
109
- if ( isset( $order_id[ 'order_id' ] ) ) {
110
- $order_id = $order_id[ 'order_id' ];
111
- } else {
112
- return;
113
- }
114
- }
115
-
116
- $lang = get_post_meta( $order_id, 'wpml_language', true );
117
- if( !empty( $lang ) ){
118
- $this->change_email_language( $lang );
119
- }
120
- }
121
-
122
- /**
123
- * After email translation switch language to default.
124
- */
125
- function email_footer() {
126
- $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
127
- }
128
-
129
- function comments_language(){
130
- $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
131
-
132
- }
133
-
134
- function email_heading_completed( $order_id, $no_checking = false ){
135
- global $woocommerce;
136
- if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
137
-
138
- $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' );
139
-
140
- $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' );
141
-
142
- $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' );
143
-
144
- $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' );
145
-
146
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
147
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
148
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
149
- $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
150
- }
151
- }
152
-
153
- function email_heading_processing($order_id){
154
- global $woocommerce;
155
- if( class_exists( 'WC_Email_Customer_Processing_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Processing_Order' ] ) ){
156
-
157
- $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' );
158
-
159
- $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' );
160
-
161
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
162
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
163
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
164
- $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
165
- }
166
- }
167
-
168
- function email_heading_note($args){
169
- global $woocommerce;
170
-
171
- if( class_exists( 'WC_Email_Customer_Note' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
172
-
173
- $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' );
174
-
175
- $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' );
176
-
177
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
178
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
179
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
180
- $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
181
- }
182
- }
183
-
184
- function email_heading_refund( $order_id, $refund_id = null ){
185
- global $woocommerce;
186
- if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
187
-
188
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
189
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
190
- '[woocommerce_customer_refunded_order_settings]heading_partial' );
191
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
192
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
193
- '[woocommerce_customer_refunded_order_settings]subject_partial' );
194
-
195
- $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
196
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
197
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
198
- $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
199
-
200
- }
201
- }
202
-
203
-
204
- function new_order_admin_email($order_id){
205
- global $woocommerce;
206
- if( isset( $woocommerce->mailer()->emails[ 'WC_Email_New_Order' ] ) ){
207
- $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
208
- foreach($recipients as $recipient){
209
- $user = get_user_by('email',$recipient);
210
- if($user){
211
- $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
212
- }else{
213
- $user_lang = get_post_meta($order_id, 'wpml_language', true );
214
- }
215
-
216
- $this->change_email_language( $user_lang );
217
-
218
- $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' );
219
-
220
- $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' );
221
-
222
- $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
223
-
224
- $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
225
- }
226
- $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
227
- $this->refresh_email_lang($order_id);
228
- }
229
- }
230
-
231
- public function backend_new_order_admin_email( $order_id ){
232
- if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
233
- $this->new_order_admin_email( $order_id );
234
- }
235
- }
236
-
237
- function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
238
- if( $meta_key == '_payment_method_title' ){
239
-
240
- $payment_method = get_post_meta( $object_id, '_payment_method', true );
241
-
242
- if( $payment_method ){
243
-
244
- $payment_gateways = WC()->payment_gateways->payment_gateways();
245
- if( isset( $payment_gateways[ $payment_method ] ) ){
246
- $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
247
-
248
- return $title;
249
- }
250
- }
251
-
252
-
253
- }
254
- return $check;
255
- }
256
-
257
- function filter_formatted_items( $formatted_meta, $object ){
258
-
259
- if( $object->product->variation_id ){
260
-
261
- $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
262
-
263
- if( !is_null( $current_prod_variation_id ) ) {
264
-
265
- foreach( $formatted_meta as $key => $formatted_var ){
266
-
267
- if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
268
-
269
- $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
270
-
271
- if( taxonomy_exists( $attribute ) ){
272
- $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
273
- $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
274
-
275
- if( $tr_id ){
276
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
277
- $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
278
- }
279
-
280
- }else{
281
-
282
- $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() );
283
-
284
- if ( false !== $custom_attr_trnsl ) {
285
- $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
286
- }
287
- }
288
- }
289
- }
290
- }
291
- }
292
-
293
- return $formatted_meta;
294
-
295
- }
296
-
297
- function change_email_language($lang){
298
- global $woocommerce;
299
- $this->sitepress->switch_lang($lang,true);
300
- $this->locale = $this->sitepress->get_locale( $lang );
301
- unload_textdomain('woocommerce');
302
- unload_textdomain( 'default' );
303
- global $wp_locale;
304
- $wp_locale = new WP_Locale();
305
-
306
- $woocommerce->load_plugin_textdomain();
307
- load_default_textdomain( $this->locale );
308
- }
309
-
310
- function admin_string_return_cached( $value, $option ){
311
- if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
312
- return false;
313
-
314
- return $value;
315
- }
316
-
317
- function wcml_get_translated_email_string( $context, $name ){
318
-
319
- if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
320
- global $wpdb;
321
-
322
- $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
323
-
324
- return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
325
- }else{
326
-
327
- return apply_filters( 'wpml_translate_single_string', false, $context, $name );
328
-
329
- }
330
-
331
- }
332
-
333
- function icl_current_string_language( $current_language, $name ){
334
- $order_id = false;
335
-
336
- 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' ){
337
- $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
338
- }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
339
- $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
340
- }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
341
- $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
342
- }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
343
- $order_id = $this->order_id;
344
- }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
345
- $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
346
- }
347
-
348
- if( $order_id ){
349
- $order_language = get_post_meta( $order_id, 'wpml_language', true );
350
- if( $order_language ){
351
- $current_language = $order_language;
352
- }else{
353
- $current_language = $this->sitepress->get_current_language();
354
- }
355
- }
356
-
357
- return apply_filters( 'wcml_email_language', $current_language, $order_id );
358
- }
359
-
360
- // set correct locale code for emails
361
- function set_locale_for_emails( $locale, $domain ){
362
-
363
- if( $domain == 'woocommerce' && $this->locale ){
364
- $locale = $this->locale;
365
- }
366
-
367
- return $locale;
368
- }
369
-
370
- function show_language_links_for_wc_emails(){
371
-
372
- $emails_options = array(
373
- 'woocommerce_new_order_settings',
374
- 'woocommerce_cancelled_order_settings',
375
- 'woocommerce_failed_order_settings',
376
- 'woocommerce_customer_on_hold_order_settings',
377
- 'woocommerce_customer_processing_order_settings',
378
- 'woocommerce_customer_completed_order_settings',
379
- 'woocommerce_customer_refunded_order_settings',
380
- 'woocommerce_customer_invoice_settings',
381
- 'woocommerce_customer_note_settings',
382
- 'woocommerce_customer_reset_password_settings',
383
- 'woocommerce_customer_new_account_settings'
384
- );
385
-
386
- $text_keys = array(
387
- 'subject',
388
- 'heading',
389
- 'subject_downloadable',
390
- 'heading_downloadable',
391
- 'subject_full',
392
- 'subject_partial',
393
- 'heading_full',
394
- 'heading_partial',
395
- 'subject_paid',
396
- 'heading_paid'
397
- );
398
-
399
-
400
- foreach( $emails_options as $emails_option ) {
401
-
402
- $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
403
- $section_name = str_replace( '_settings', '', $section_name );
404
- if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
405
-
406
- $option_settings = get_option( $emails_option );
407
- foreach ($option_settings as $setting_key => $setting_value) {
408
- if ( in_array( $setting_key, $text_keys ) ) {
409
- $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
410
-
411
- $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
412
- $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
413
- if( is_null( $language ) ) {
414
- $language = $this->sitepress->get_default_language();
415
- }
416
-
417
- $lang_selector->render( array(
418
- 'id' => $emails_option.'_'.$setting_key.'_language_selector',
419
- 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
420
- 'selected' => $language,
421
- 'show_please_select' => false,
422
- 'echo' => true,
423
- 'style' => 'width: 18%;float: left'
424
- )
425
- );
426
-
427
- $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
428
- ?>
429
- <script>
430
- var input = jQuery('input[name="<?php echo $input_name ?>"]');
431
- if (input.length) {
432
- input.parent().append('<div class="translation_controls"></div>');
433
- input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
434
- jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
435
- }
436
- </script>
437
- <?php }
438
- }
439
- }
440
- }
441
- }
442
-
443
- function set_emails_string_lamguage(){
444
-
445
- foreach( $_POST as $key => $post_value ){
446
- if( substr( $key, 0, 9 ) == 'wcml_lang' ){
447
-
448
- $email_string = explode( '-', $key );
449
- $email_settings = get_option( $email_string[1], true );
450
-
451
- if( isset( $email_string[2] ) ){
452
- $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 );
453
- }
454
- }
455
- }
456
- }
457
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  }
1
+ <?php
2
+ class WCML_Emails{
3
+
4
+ private $order_id = false;
5
+ private $locale = false;
6
+ private $woocommerce_wpml;
7
+ private $sitepress;
8
+
9
+ function __construct( &$woocommerce_wpml, &$sitepress ) {
10
+ $this->woocommerce_wpml = $woocommerce_wpml;
11
+ $this->sitepress = $sitepress;
12
+ add_action( 'init', array( $this, 'init' ) );
13
+ }
14
+
15
+ function init(){
16
+ global $pagenow;
17
+ //wrappers for email's header
18
+ if(is_admin() && !defined( 'DOING_AJAX' )){
19
+ add_action('woocommerce_order_status_completed_notification', array($this, 'email_heading_completed'),9);
20
+ add_action('woocommerce_order_status_changed', array($this, 'comments_language'),10);
21
+ }
22
+
23
+ add_action('woocommerce_new_customer_note_notification', array($this, 'email_heading_note'),9);
24
+ add_action('wp_ajax_woocommerce_mark_order_complete',array($this,'email_refresh_in_ajax'),9);
25
+
26
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'email_heading_processing' ) );
27
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'email_heading_processing' ) );
28
+
29
+ //wrappers for email's body
30
+ add_action('woocommerce_before_resend_order_emails', array($this, 'email_header'));
31
+ add_action('woocommerce_after_resend_order_email', array($this, 'email_footer'));
32
+
33
+ //filter string language before for emails
34
+ add_filter('icl_current_string_language',array($this,'icl_current_string_language'),10 ,2);
35
+
36
+ //change order status
37
+ add_action('woocommerce_order_status_completed',array($this,'refresh_email_lang_complete'),9);
38
+ add_action('woocommerce_order_status_pending_to_processing_notification',array($this,'refresh_email_lang'),9);
39
+ add_action('woocommerce_order_status_pending_to_on-hold_notification',array($this,'refresh_email_lang'),9);
40
+ add_action('woocommerce_new_customer_note',array($this,'refresh_email_lang'),9);
41
+
42
+
43
+ add_action('woocommerce_order_partially_refunded_notification', array($this,'email_heading_refund'), 9);
44
+ add_action('woocommerce_order_partially_refunded_notification', array($this,'refresh_email_lang'), 9);
45
+
46
+
47
+ //new order admins email
48
+ add_action( 'woocommerce_order_status_pending_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
49
+ add_action( 'woocommerce_order_status_pending_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
50
+ add_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
51
+ add_action( 'woocommerce_order_status_failed_to_processing_notification', array( $this, 'new_order_admin_email' ), 9 );
52
+ add_action( 'woocommerce_order_status_failed_to_completed_notification', array( $this, 'new_order_admin_email' ), 9 );
53
+ add_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $this, 'new_order_admin_email' ), 9 );
54
+ add_action( 'woocommerce_before_resend_order_emails', array( $this, 'backend_new_order_admin_email' ), 9 );
55
+
56
+ add_filter( 'icl_st_admin_string_return_cached', array( $this, 'admin_string_return_cached' ), 10, 2 );
57
+
58
+ add_filter( 'plugin_locale', array( $this, 'set_locale_for_emails' ), 10, 2 );
59
+
60
+
61
+ if( is_admin() && $pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'email' ){
62
+ add_action('admin_footer', array($this, 'show_language_links_for_wc_emails'));
63
+ $this->set_emails_string_language();
64
+ }
65
+
66
+ add_filter( 'get_post_metadata', array( $this, 'filter_payment_method_string' ), 10, 4 );
67
+
68
+ if( !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
+ * Translate WooCommerce emails.
89
+ *
90
+ * @global type $sitepress
91
+ * @global type $order_id
92
+ * @return type
93
+ */
94
+ function email_header( $order ) {
95
+
96
+ if( is_array( $order ) ) {
97
+ $order = $order[ 'order_id' ];
98
+ } elseif( is_object( $order ) ) {
99
+ $order = $order->id;
100
+ }
101
+
102
+ $this->refresh_email_lang( $order );
103
+ }
104
+
105
+
106
+ function refresh_email_lang( $order_id ){
107
+
108
+ if ( is_array( $order_id ) ) {
109
+ if ( isset( $order_id[ 'order_id' ] ) ) {
110
+ $order_id = $order_id[ 'order_id' ];
111
+ } else {
112
+ return;
113
+ }
114
+ }
115
+
116
+ $lang = get_post_meta( $order_id, 'wpml_language', true );
117
+ if( !empty( $lang ) ){
118
+ $this->change_email_language( $lang );
119
+ }
120
+ }
121
+
122
+ /**
123
+ * After email translation switch language to default.
124
+ */
125
+ function email_footer() {
126
+ $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
127
+ }
128
+
129
+ function comments_language(){
130
+ $this->change_email_language( $this->woocommerce_wpml->strings->get_domain_language( 'woocommerce' ) );
131
+
132
+ }
133
+
134
+ function email_heading_completed( $order_id, $no_checking = false ){
135
+ global $woocommerce;
136
+ if( ( class_exists( 'WC_Email_Customer_Completed_Order' ) || $no_checking ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Completed_Order' ] ) ){
137
+
138
+ $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' );
139
+
140
+ $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' );
141
+
142
+ $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' );
143
+
144
+ $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' );
145
+
146
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled;
147
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = false;
148
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->trigger($order_id);
149
+ $woocommerce->mailer()->emails['WC_Email_Customer_Completed_Order']->enabled = $enabled;
150
+ }
151
+ }
152
+
153
+ function email_heading_processing($order_id){
154
+ global $woocommerce;
155
+ if( class_exists( 'WC_Email_Customer_Processing_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Processing_Order' ] ) ){
156
+
157
+ $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' );
158
+
159
+ $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' );
160
+
161
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled;
162
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = false;
163
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->trigger($order_id);
164
+ $woocommerce->mailer()->emails['WC_Email_Customer_Processing_Order']->enabled = $enabled;
165
+ }
166
+ }
167
+
168
+ function email_heading_note($args){
169
+ global $woocommerce;
170
+
171
+ if( class_exists( 'WC_Email_Customer_Note' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Note' ] ) ){
172
+
173
+ $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' );
174
+
175
+ $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' );
176
+
177
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled;
178
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = false;
179
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->trigger($args);
180
+ $woocommerce->mailer()->emails['WC_Email_Customer_Note']->enabled = $enabled;
181
+ }
182
+ }
183
+
184
+ function email_heading_refund( $order_id, $refund_id = null ){
185
+ global $woocommerce;
186
+ if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
187
+
188
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
189
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
190
+ '[woocommerce_customer_refunded_order_settings]heading_partial' );
191
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
192
+ $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
193
+ '[woocommerce_customer_refunded_order_settings]subject_partial' );
194
+
195
+ $enabled = $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
196
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
197
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
198
+ $woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
199
+
200
+ }
201
+ }
202
+
203
+
204
+ function new_order_admin_email($order_id){
205
+ global $woocommerce;
206
+ if( isset( $woocommerce->mailer()->emails[ 'WC_Email_New_Order' ] ) ){
207
+ $recipients = explode(',',$woocommerce->mailer()->emails['WC_Email_New_Order']->get_recipient());
208
+ foreach($recipients as $recipient){
209
+ $user = get_user_by('email',$recipient);
210
+ if($user){
211
+ $user_lang = $this->sitepress->get_user_admin_language($user->ID, true );
212
+ }else{
213
+ $user_lang = get_post_meta($order_id, 'wpml_language', true );
214
+ }
215
+
216
+ $this->change_email_language( $user_lang );
217
+
218
+ $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' );
219
+
220
+ $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' );
221
+
222
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
223
+
224
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->trigger($order_id);
225
+ }
226
+ $woocommerce->mailer()->emails['WC_Email_New_Order']->enabled = false;
227
+ $this->refresh_email_lang($order_id);
228
+ }
229
+ }
230
+
231
+ public function backend_new_order_admin_email( $order_id ){
232
+ if( isset( $_POST[ 'wc_order_action' ] ) && $_POST[ 'wc_order_action' ] == 'send_email_new_order' ){
233
+ $this->new_order_admin_email( $order_id );
234
+ }
235
+ }
236
+
237
+ function filter_payment_method_string( $check, $object_id, $meta_key, $single ){
238
+ if( $meta_key == '_payment_method_title' ){
239
+
240
+ $payment_method = get_post_meta( $object_id, '_payment_method', true );
241
+
242
+ if( $payment_method ){
243
+
244
+ $payment_gateways = WC()->payment_gateways->payment_gateways();
245
+ if( isset( $payment_gateways[ $payment_method ] ) ){
246
+ $title = $this->woocommerce_wpml->gateways->translate_gateway_title( $payment_gateways[ $payment_method ]->title, $payment_method, $this->sitepress->get_current_language() );
247
+
248
+ return $title;
249
+ }
250
+ }
251
+
252
+
253
+ }
254
+ return $check;
255
+ }
256
+
257
+ function filter_formatted_items( $formatted_meta, $object ){
258
+
259
+ if( isset( $object->product->variation_id ) ){
260
+
261
+ $current_prod_variation_id = apply_filters( 'translate_object_id', $object->product->variation_id, 'product_variation', false );
262
+
263
+ if( !is_null( $current_prod_variation_id ) ) {
264
+
265
+ foreach( $formatted_meta as $key => $formatted_var ){
266
+
267
+ if( substr( $formatted_var[ 'key' ], 0, 3 ) ){
268
+
269
+ $attribute = wc_sanitize_taxonomy_name( $formatted_var[ 'key' ] );
270
+
271
+ if( taxonomy_exists( $attribute ) ){
272
+ $attr_term = get_term_by( 'name', $formatted_meta[ $key ][ 'value' ], $attribute );
273
+ $tr_id = apply_filters( 'translate_object_id', $attr_term->term_id, $attribute, false, $this->sitepress->get_current_language() );
274
+
275
+ if( $tr_id ){
276
+ $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $attribute );
277
+ $formatted_meta[ $key ][ 'value' ] = $translated_term->name;
278
+ }
279
+
280
+ }else{
281
+
282
+ $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() );
283
+
284
+ if ( false !== $custom_attr_trnsl ) {
285
+ $formatted_meta[ $key ][ 'label' ] = $custom_attr_trnsl['name'];
286
+ }
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+
293
+ return $formatted_meta;
294
+
295
+ }
296
+
297
+ function change_email_language($lang){
298
+ global $woocommerce;
299
+ $this->sitepress->switch_lang($lang,true);
300
+ $this->locale = $this->sitepress->get_locale( $lang );
301
+ unload_textdomain('woocommerce');
302
+ unload_textdomain( 'default' );
303
+ global $wp_locale;
304
+ $wp_locale = new WP_Locale();
305
+
306
+ $woocommerce->load_plugin_textdomain();
307
+ load_default_textdomain( $this->locale );
308
+ }
309
+
310
+ function admin_string_return_cached( $value, $option ){
311
+ if( in_array( $option, array ( 'woocommerce_email_from_address', 'woocommerce_email_from_name' ) ) )
312
+ return false;
313
+
314
+ return $value;
315
+ }
316
+
317
+ function wcml_get_translated_email_string( $context, $name ){
318
+
319
+ if( version_compare(WPML_ST_VERSION, '2.2.6', '<=' ) ){
320
+ global $wpdb;
321
+
322
+ $result = $wpdb->get_var( $wpdb->prepare( "SELECT value FROM {$wpdb->prefix}icl_strings WHERE context = %s AND name = %s ", $context, $name ) );
323
+
324
+ return apply_filters( 'wpml_translate_single_string', $result, $context, $name );
325
+ }else{
326
+
327
+ return apply_filters( 'wpml_translate_single_string', false, $context, $name );
328
+
329
+ }
330
+
331
+ }
332
+
333
+ function icl_current_string_language( $current_language, $name ){
334
+ $order_id = false;
335
+
336
+ 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' ){
337
+ $order_id = filter_input( INPUT_POST, 'post_ID', FILTER_SANITIZE_NUMBER_INT );
338
+ }elseif( isset($_POST['action']) && $_POST['action'] == 'woocommerce_add_order_note' && isset($_POST['note_type']) && $_POST['note_type'] == 'customer' ) {
339
+ $order_id = filter_input( INPUT_POST, 'post_id', FILTER_SANITIZE_NUMBER_INT );
340
+ }elseif( isset($_GET['action']) && isset($_GET['order_id']) && ( $_GET['action'] == 'woocommerce_mark_order_complete' || $_GET['action'] == 'woocommerce_mark_order_status') ){
341
+ $order_id = filter_input( INPUT_GET, 'order_id', FILTER_SANITIZE_NUMBER_INT );
342
+ }elseif(isset($_GET['action']) && $_GET['action'] == 'mark_completed' && $this->order_id){
343
+ $order_id = $this->order_id;
344
+ }elseif(isset($_POST['action']) && $_POST['action'] == 'woocommerce_refund_line_items'){
345
+ $order_id = filter_input( INPUT_POST, 'order_id', FILTER_SANITIZE_NUMBER_INT );
346
+ }elseif( empty( $_POST ) && isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'wc-settings' && isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] == 'email' && substr( $name, 0, 12 ) == '[woocommerce' ){
347
+ $email_string = explode( ']', str_replace( '[', '', $name ) );
348
+ $email_option = get_option( $email_string[ 0 ], true );
349
+ $context = 'admin_texts_'.$email_string[ 0 ];
350
+
351
+ $current_language = $this->woocommerce_wpml->strings->get_string_language( $email_option[ $email_string[ 1 ] ], $context, $name );
352
+ }
353
+
354
+ $order_id = apply_filters( 'wcml_send_email_order_id', $order_id );
355
+
356
+ if( $order_id ){
357
+ $order_language = get_post_meta( $order_id, 'wpml_language', true );
358
+ if( $order_language ){
359
+ $current_language = $order_language;
360
+ }else{
361
+ $current_language = $this->sitepress->get_current_language();
362
+ }
363
+ }
364
+
365
+ return apply_filters( 'wcml_email_language', $current_language, $order_id );
366
+ }
367
+
368
+ // set correct locale code for emails
369
+ function set_locale_for_emails( $locale, $domain ){
370
+
371
+ if( $domain == 'woocommerce' && $this->locale ){
372
+ $locale = $this->locale;
373
+ }
374
+
375
+ return $locale;
376
+ }
377
+
378
+ function show_language_links_for_wc_emails(){
379
+
380
+ $emails_options = array(
381
+ 'woocommerce_new_order_settings',
382
+ 'woocommerce_cancelled_order_settings',
383
+ 'woocommerce_failed_order_settings',
384
+ 'woocommerce_customer_on_hold_order_settings',
385
+ 'woocommerce_customer_processing_order_settings',
386
+ 'woocommerce_customer_completed_order_settings',
387
+ 'woocommerce_customer_refunded_order_settings',
388
+ 'woocommerce_customer_invoice_settings',
389
+ 'woocommerce_customer_note_settings',
390
+ 'woocommerce_customer_reset_password_settings',
391
+ 'woocommerce_customer_new_account_settings'
392
+ );
393
+
394
+ $text_keys = array(
395
+ 'subject',
396
+ 'heading',
397
+ 'subject_downloadable',
398
+ 'heading_downloadable',
399
+ 'subject_full',
400
+ 'subject_partial',
401
+ 'heading_full',
402
+ 'heading_partial',
403
+ 'subject_paid',
404
+ 'heading_paid'
405
+ );
406
+
407
+
408
+ foreach( $emails_options as $emails_option ) {
409
+
410
+ $section_name = str_replace( 'woocommerce_', 'wc_email_', $emails_option );
411
+ $section_name = str_replace( '_settings', '', $section_name );
412
+ if( isset( $_GET['section'] ) && $_GET['section'] == $section_name ){
413
+
414
+ $option_settings = get_option( $emails_option );
415
+ foreach ($option_settings as $setting_key => $setting_value) {
416
+ if ( in_array( $setting_key, $text_keys ) ) {
417
+ $input_name = str_replace( '_settings', '', $emails_option ).'_'.$setting_key;
418
+
419
+ $lang_selector = new WPML_Simple_Language_Selector($this->sitepress);
420
+ $language = $this->woocommerce_wpml->strings->get_string_language( $setting_value, 'admin_texts_'.$emails_option, '['.$emails_option.']'.$setting_key );
421
+ if( is_null( $language ) ) {
422
+ $language = $this->sitepress->get_default_language();
423
+ }
424
+
425
+ $lang_selector->render( array(
426
+ 'id' => $emails_option.'_'.$setting_key.'_language_selector',
427
+ 'name' => 'wcml_lang-'.$emails_option.'-'.$setting_key,
428
+ 'selected' => $language,
429
+ 'show_please_select' => false,
430
+ 'echo' => true,
431
+ 'style' => 'width: 18%;float: left'
432
+ )
433
+ );
434
+
435
+ $st_page = admin_url( 'admin.php?page=' . WPML_ST_FOLDER . '/menu/string-translation.php&context=admin_texts_'.$emails_option.'&search='.$setting_value );
436
+ ?>
437
+ <script>
438
+ var input = jQuery('input[name="<?php echo $input_name ?>"]');
439
+ if (input.length) {
440
+ input.parent().append('<div class="translation_controls"></div>');
441
+ input.parent().find('.translation_controls').append('<a href="<?php echo $st_page ?>" style="margin-left: 10px"><?php _e('translations', 'woocommerce-multilingual') ?></a>');
442
+ jQuery('#<?php echo $emails_option.'_'.$setting_key.'_language_selector' ?>').prependTo(input.parent().find('.translation_controls'));
443
+ }
444
+ </script>
445
+ <?php }
446
+ }
447
+ }
448
+ }
449
+ }
450
+
451
+ function set_emails_string_language(){
452
+
453
+ foreach( $_POST as $key => $language ){
454
+
455
+ if( substr( $key, 0, 9 ) == 'wcml_lang' ){
456
+
457
+ $email_string = explode( '-', $key );
458
+
459
+ if( isset( $email_string[2] ) ){
460
+
461
+ $email_key = str_replace( '_settings', '', $email_string[1] );
462
+ $email_key .= '_'.$email_string[2];
463
+
464
+ $email_settings = get_option( $email_string[1], true );
465
+ $opt_string_value = $email_settings[ $email_string[2] ];
466
+
467
+ $string_value = isset( $_POST[ $email_key ] ) ? $_POST[ $email_key ] : $opt_string_value;
468
+
469
+ $context = 'admin_texts_'.$email_string[1];
470
+ $name = '['.$email_string[1].']'.$email_string[2];
471
+
472
+ do_action('wpml_register_single_string', $context, $name, $string_value, false, $this->woocommerce_wpml->strings->get_string_language( $opt_string_value, $context ) );
473
+
474
+ $this->woocommerce_wpml->strings->set_string_language( $string_value, $context, $name, $language );
475
+ }
476
+ }
477
+ }
478
+ }
479
+
480
  }
inc/class-wcml-endpoints.php CHANGED
@@ -1,283 +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
- 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
- }
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 CHANGED
@@ -1,40 +1,40 @@
1
- <?php
2
-
3
- class WCML_Fix_Copied_Custom_Fields_WPML353{
4
-
5
- public function __construct(){
6
- //@TODO review after WPML 3.6
7
- if ( is_admin() && version_compare( ICL_SITEPRESS_VERSION, '3.5.3', '>=' ) && version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
8
- add_action( 'added_post_meta', array(
9
- $this,
10
- 'fix_copied_custom_fields'
11
- ), 10, 4 );
12
- }
13
-
14
- }
15
-
16
- public function fix_copied_custom_fields( $mid, $object_id, $meta_key, $_meta_value ) {
17
- global $wpdb;
18
-
19
- if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ) ) ) {
20
-
21
- $meta_keys_to_fix = array(
22
- '_price',
23
- '_regular_price',
24
- '_sale_price',
25
- '_sku'
26
- );
27
-
28
- if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
29
-
30
- if ( is_null( $_meta_value ) ) {
31
- $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_id' => $mid ) );
32
- }
33
-
34
- }
35
-
36
- }
37
-
38
- }
39
-
40
  }
1
+ <?php
2
+
3
+ class WCML_Fix_Copied_Custom_Fields_WPML353{
4
+
5
+ public function __construct(){
6
+ //@TODO review after WPML 3.6
7
+ if ( is_admin() && version_compare( ICL_SITEPRESS_VERSION, '3.5.3', '>=' ) && version_compare( ICL_SITEPRESS_VERSION, '3.6', '<' ) ) {
8
+ add_action( 'added_post_meta', array(
9
+ $this,
10
+ 'fix_copied_custom_fields'
11
+ ), 10, 4 );
12
+ }
13
+
14
+ }
15
+
16
+ public function fix_copied_custom_fields( $mid, $object_id, $meta_key, $_meta_value ) {
17
+ global $wpdb;
18
+
19
+ if ( in_array( get_post_type( $object_id ), array( 'product', 'product_variation' ) ) ) {
20
+
21
+ $meta_keys_to_fix = array(
22
+ '_price',
23
+ '_regular_price',
24
+ '_sale_price',
25
+ '_sku'
26
+ );
27
+
28
+ if ( in_array( $meta_key, $meta_keys_to_fix ) ) {
29
+
30
+ if ( is_null( $_meta_value ) ) {
31
+ $wpdb->update( $wpdb->postmeta, array( 'meta_value' => '' ), array( 'meta_id' => $mid ) );
32
+ }
33
+
34
+ }
35
+
36
+ }
37
+
38
+ }
39
+
40
  }
inc/class-wcml-install.php CHANGED
@@ -1,227 +1,227 @@
1
- <?php
2
-
3
- class WCML_Install{
4
-
5
- public static function initialize( &$woocommerce_wpml, &$sitepress ) {
6
-
7
- if( is_admin() ) {
8
-
9
- // Install routine
10
- if ( empty( $woocommerce_wpml->settings['set_up'] ) ) { // from 3.2
11
-
12
- if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
13
- //global term ordering resync when moving to >= 3.3.x
14
- add_action( 'init', array( $woocommerce_wpml->terms, 'sync_term_order_globally' ), 20 );
15
- }
16
-
17
- if ( ! isset( $woocommerce_wpml->settings['wc_admin_options_saved'] ) ) {
18
- self::handle_admin_texts();
19
- $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
20
- }
21
-
22
- if ( ! isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
23
- $woocommerce_wpml->settings['trnsl_interface'] = 1;
24
- }
25
-
26
- if ( ! isset( $woocommerce_wpml->settings['products_sync_date'] ) ) {
27
- $woocommerce_wpml->settings['products_sync_date'] = 1;
28
- }
29
-
30
- if ( ! isset( $woocommerce_wpml->settings['products_sync_order'] ) ) {
31
- $woocommerce_wpml->settings['products_sync_order'] = 1;
32
- }
33
-
34
- if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
35
- $woocommerce_wpml->settings['display_custom_prices'] = 0;
36
- }
37
-
38
- if ( ! isset( $woocommerce_wpml->settings['sync_taxonomies_checked'] ) ) {
39
- $woocommerce_wpml->terms->check_if_sync_terms_needed();
40
- $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
41
- }
42
-
43
- WCML_Capabilities::set_up_capabilities();
44
-
45
- self:: set_language_information( $sitepress );
46
- self:: check_product_type_terms();
47
-
48
- set_transient( '_wcml_activation_redirect', 1, 30 );
49
-
50
- // Before the setup wizard redirects from plugins.php, allow WPML to scan the wpml-config.xml file
51
- WPML_Config::load_config_run();
52
-
53
- $woocommerce_wpml->settings['set_up'] = 1;
54
- $woocommerce_wpml->update_settings();
55
-
56
- }
57
-
58
- if ( empty( $woocommerce_wpml->settings['downloaded_translations_for_wc'] ) ) { //from 3.3.3
59
- $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
60
- $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
61
- $woocommerce_wpml->update_settings();
62
- }
63
-
64
- if ( empty( $woocommerce_wpml->settings[ 'rewrite_rules_flashed' ] ) ) {
65
- flush_rewrite_rules();
66
- $woocommerce_wpml->settings['rewrite_rules_flashed'] = 1;
67
- }
68
-
69
- add_filter( 'wpml_tm_dashboard_translatable_types', array(
70
- __CLASS__,
71
- 'hide_variation_type_on_tm_dashboard'
72
- ) );
73
-
74
- new WCML_Setup( $woocommerce_wpml, $sitepress );
75
- if ( ! empty( $woocommerce_wpml->settings['set_up_wizard_run'] ) ) {
76
- add_action( 'admin_notices', array( __CLASS__, 'admin_notice_after_install' ) );
77
- }
78
-
79
- }
80
-
81
- }
82
-
83
- private static function set_language_information( &$sitepress ){
84
- global $wpdb;
85
-
86
- $def_lang = $sitepress->get_default_language();
87
- //set language info for products
88
- $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
89
- foreach($products as $product){
90
- $exist = $sitepress->get_language_for_element($product->ID,'post_product');
91
- if(!$exist){
92
- $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
93
- }
94
- }
95
-
96
- //set language info for taxonomies
97
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
98
- foreach($terms as $term){
99
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
100
- if(!$exist){
101
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
102
- }
103
- }
104
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
105
- foreach($terms as $term){
106
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
107
- if(!$exist){
108
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
109
- }
110
- }
111
-
112
- $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
113
- foreach($terms as $term){
114
- $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
115
- if(!$exist){
116
- $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
117
- }
118
- }
119
- }
120
-
121
- //handle situation when product_type terms translated before activating WCML
122
- private static function check_product_type_terms(){
123
- global $wpdb;
124
- //check if terms were translated
125
- $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
126
-
127
- if( $translations ){
128
- foreach( $translations as $translation ){
129
- if( !is_null( $translation->source_language_code ) ){
130
- //check relationships
131
- $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
132
- if( $term_relationships ){
133
- $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 ) );
134
- if( $orig_term ){
135
- foreach( $term_relationships as $term_relationship ){
136
- $wpdb->update(
137
- $wpdb->term_relationships,
138
- array(
139
- 'term_taxonomy_id' => $orig_term
140
- ),
141
- array(
142
- 'object_id' => $term_relationship->object_id,
143
- 'term_taxonomy_id' => $translation->element_id
144
- )
145
- );
146
- }
147
- }
148
- }
149
- $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
150
-
151
- if( $term_id ){
152
- $wpdb->delete(
153
- $wpdb->terms,
154
- array(
155
- 'term_id' => $term_id
156
- )
157
- );
158
-
159
- $wpdb->delete(
160
- $wpdb->term_taxonomy,
161
- array(
162
- 'term_taxonomy_id' => $translation->element_id
163
- )
164
- );
165
- }
166
- }
167
- }
168
-
169
- foreach( $translations as $translation ){
170
- $wpdb->delete(
171
- $wpdb->prefix . 'icl_translations',
172
- array(
173
- 'translation_id' => $translation->translation_id
174
- )
175
- );
176
- }
177
- }
178
- }
179
-
180
- private static function handle_admin_texts(){
181
- if(class_exists('woocommerce')){
182
- //emails texts
183
- $emails = new WC_Emails();
184
- foreach($emails->emails as $email){
185
- $option_name = $email->plugin_id.$email->id.'_settings';
186
- if(!get_option($option_name)){
187
- add_option($option_name,$email->settings);
188
- }
189
- }
190
- }
191
- }
192
-
193
- public static function admin_notice_after_install(){
194
- global $woocommerce_wpml;
195
-
196
- if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
197
-
198
- $url = $_SERVER['REQUEST_URI'];
199
- $pos = strpos($url, '?');
200
-
201
- if($pos !== false){
202
- $url .= '&wcml_action=dismiss';
203
- } else {
204
- $url .= '?wcml_action=dismiss';
205
- }
206
- ?>
207
- <div id="message" class="updated message fade otgs-is-dismissible">
208
- <p>
209
- <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
210
- </p>
211
- <p>
212
- <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">
213
- <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
214
- </a>
215
- </p>
216
- <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
217
- </div>
218
- <?php
219
- }
220
- }
221
-
222
- public static function hide_variation_type_on_tm_dashboard( $types ){
223
- unset( $types['product_variation'] );
224
- return $types;
225
- }
226
-
227
  }
1
+ <?php
2
+
3
+ class WCML_Install{
4
+
5
+ public static function initialize( &$woocommerce_wpml, &$sitepress ) {
6
+
7
+ if( is_admin() ) {
8
+
9
+ // Install routine
10
+ if ( empty( $woocommerce_wpml->settings['set_up'] ) ) { // from 3.2
11
+
12
+ if ( $woocommerce_wpml->settings['is_term_order_synced'] !== 'yes' ) {
13
+ //global term ordering resync when moving to >= 3.3.x
14
+ add_action( 'init', array( $woocommerce_wpml->terms, 'sync_term_order_globally' ), 20 );
15
+ }
16
+
17
+ if ( ! isset( $woocommerce_wpml->settings['wc_admin_options_saved'] ) ) {
18
+ self::handle_admin_texts();
19
+ $woocommerce_wpml->settings['wc_admin_options_saved'] = 1;
20
+ }
21
+
22
+ if ( ! isset( $woocommerce_wpml->settings['trnsl_interface'] ) ) {
23
+ $woocommerce_wpml->settings['trnsl_interface'] = 1;
24
+ }
25
+
26
+ if ( ! isset( $woocommerce_wpml->settings['products_sync_date'] ) ) {
27
+ $woocommerce_wpml->settings['products_sync_date'] = 1;
28
+ }
29
+
30
+ if ( ! isset( $woocommerce_wpml->settings['products_sync_order'] ) ) {
31
+ $woocommerce_wpml->settings['products_sync_order'] = 1;
32
+ }
33
+
34
+ if ( ! isset( $woocommerce_wpml->settings['display_custom_prices'] ) ) {
35
+ $woocommerce_wpml->settings['display_custom_prices'] = 0;
36
+ }
37
+
38
+ if ( ! isset( $woocommerce_wpml->settings['sync_taxonomies_checked'] ) ) {
39
+ $woocommerce_wpml->terms->check_if_sync_terms_needed();
40
+ $woocommerce_wpml->settings['sync_taxonomies_checked'] = 1;
41
+ }
42
+
43
+ WCML_Capabilities::set_up_capabilities();
44
+
45
+ self:: set_language_information( $sitepress );
46
+ self:: check_product_type_terms();
47
+
48
+ set_transient( '_wcml_activation_redirect', 1, 30 );
49
+
50
+ // Before the setup wizard redirects from plugins.php, allow WPML to scan the wpml-config.xml file
51
+ WPML_Config::load_config_run();
52
+
53
+ $woocommerce_wpml->settings['set_up'] = 1;
54
+ $woocommerce_wpml->update_settings();
55
+
56
+ }
57
+
58
+ if ( empty( $woocommerce_wpml->settings['downloaded_translations_for_wc'] ) ) { //from 3.3.3
59
+ $woocommerce_wpml->languages_upgrader->download_woocommerce_translations_for_active_languages();
60
+ $woocommerce_wpml->settings['downloaded_translations_for_wc'] = 1;
61
+ $woocommerce_wpml->update_settings();
62
+ }
63
+
64
+ if ( empty( $woocommerce_wpml->settings[ 'rewrite_rules_flashed' ] ) ) {
65
+ flush_rewrite_rules();
66
+ $woocommerce_wpml->settings['rewrite_rules_flashed'] = 1;
67
+ }
68
+
69
+ add_filter( 'wpml_tm_dashboard_translatable_types', array(
70
+ __CLASS__,
71
+ 'hide_variation_type_on_tm_dashboard'
72
+ ) );
73
+
74
+ new WCML_Setup( $woocommerce_wpml, $sitepress );
75
+ if ( ! empty( $woocommerce_wpml->settings['set_up_wizard_run'] ) ) {
76
+ add_action( 'admin_notices', array( __CLASS__, 'admin_notice_after_install' ) );
77
+ }
78
+
79
+ }
80
+
81
+ }
82
+
83
+ private static function set_language_information( &$sitepress ){
84
+ global $wpdb;
85
+
86
+ $def_lang = $sitepress->get_default_language();
87
+ //set language info for products
88
+ $products = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_type = 'product' AND post_status <> 'auto-draft'");
89
+ foreach($products as $product){
90
+ $exist = $sitepress->get_language_for_element($product->ID,'post_product');
91
+ if(!$exist){
92
+ $sitepress->set_element_language_details($product->ID, 'post_product',false,$def_lang);
93
+ }
94
+ }
95
+
96
+ //set language info for taxonomies
97
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_cat'");
98
+ foreach($terms as $term){
99
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_cat');
100
+ if(!$exist){
101
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_cat',false,$def_lang);
102
+ }
103
+ }
104
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_tag'");
105
+ foreach($terms as $term){
106
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_tag');
107
+ if(!$exist){
108
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_tag',false,$def_lang);
109
+ }
110
+ }
111
+
112
+ $terms = $wpdb->get_results("SELECT term_taxonomy_id FROM $wpdb->term_taxonomy WHERE taxonomy = 'product_shipping_class'");
113
+ foreach($terms as $term){
114
+ $exist = $sitepress->get_language_for_element($term->term_taxonomy_id, 'tax_product_shipping_class');
115
+ if(!$exist){
116
+ $sitepress->set_element_language_details($term->term_taxonomy_id, 'tax_product_shipping_class',false,$def_lang);
117
+ }
118
+ }
119
+ }
120
+
121
+ //handle situation when product_type terms translated before activating WCML
122
+ private static function check_product_type_terms(){
123
+ global $wpdb;
124
+ //check if terms were translated
125
+ $translations = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}icl_translations WHERE element_type = 'tax_product_type'" );
126
+
127
+ if( $translations ){
128
+ foreach( $translations as $translation ){
129
+ if( !is_null( $translation->source_language_code ) ){
130
+ //check relationships
131
+ $term_relationships = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM {$wpdb->term_relationships} WHERE term_taxonomy_id = %d", $translation->element_id ) );
132
+ if( $term_relationships ){
133
+ $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 ) );
134
+ if( $orig_term ){
135
+ foreach( $term_relationships as $term_relationship ){
136
+ $wpdb->update(
137
+ $wpdb->term_relationships,
138
+ array(
139
+ 'term_taxonomy_id' => $orig_term
140
+ ),
141
+ array(
142
+ 'object_id' => $term_relationship->object_id,
143
+ 'term_taxonomy_id' => $translation->element_id
144
+ )
145
+ );
146
+ }
147
+ }
148
+ }
149
+ $term_id = $wpdb->get_var( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE term_taxonomy_id = %d", $translation->element_id ) );
150
+
151
+ if( $term_id ){
152
+ $wpdb->delete(
153
+ $wpdb->terms,
154
+ array(
155
+ 'term_id' => $term_id
156
+ )
157
+ );
158
+
159
+ $wpdb->delete(
160
+ $wpdb->term_taxonomy,
161
+ array(
162
+ 'term_taxonomy_id' => $translation->element_id
163
+ )
164
+ );
165
+ }
166
+ }
167
+ }
168
+
169
+ foreach( $translations as $translation ){
170
+ $wpdb->delete(
171
+ $wpdb->prefix . 'icl_translations',
172
+ array(
173
+ 'translation_id' => $translation->translation_id
174
+ )
175
+ );
176
+ }
177
+ }
178
+ }
179
+
180
+ private static function handle_admin_texts(){
181
+ if(class_exists('woocommerce')){
182
+ //emails texts
183
+ $emails = new WC_Emails();
184
+ foreach($emails->emails as $email){
185
+ $option_name = $email->plugin_id.$email->id.'_settings';
186
+ if(!get_option($option_name)){
187
+ add_option($option_name,$email->settings);
188
+ }
189
+ }
190
+ }
191
+ }
192
+
193
+ public static function admin_notice_after_install(){
194
+ global $woocommerce_wpml;
195
+
196
+ if( !$woocommerce_wpml->settings['dismiss_doc_main'] ){
197
+
198
+ $url = $_SERVER['REQUEST_URI'];
199
+ $pos = strpos($url, '?');
200
+
201
+ if($pos !== false){
202
+ $url .= '&wcml_action=dismiss';
203
+ } else {
204
+ $url .= '?wcml_action=dismiss';
205
+ }
206
+ ?>
207
+ <div id="message" class="updated message fade otgs-is-dismissible">
208
+ <p>
209
+ <?php printf(__("You've successfully installed %sWooCommerce Multilingual%s. Would you like to see a quick overview?", 'woocommerce-multilingual'), '<strong>', '</strong>'); ?>
210
+ </p>
211
+ <p>
212
+ <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">
213
+ <?php _e('Learn how to turn your e-commerce site multilingual', 'woocommerce-multilingual') ?>
214
+ </a>
215
+ </p>
216
+ <a class="notice-dismiss" href="<?php echo $url; ?>"><span class="screen-reader-text"><?php _e('Dismiss', 'woocommerce-multilingual') ?></span></a>
217
+ </div>
218
+ <?php
219
+ }
220
+ }
221
+
222
+ public static function hide_variation_type_on_tm_dashboard( $types ){
223
+ unset( $types['product_variation'] );
224
+ return $types;
225
+ }
226
+
227
  }
inc/class-wcml-languages-upgrader.php CHANGED
@@ -1,301 +1,301 @@
1
- <?php
2
-
3
- class WCML_Languages_Upgrader{
4
-
5
-
6
-
7
- function __construct(){
8
-
9
- add_action( 'icl_update_active_languages', array( $this, 'download_woocommerce_translations_for_active_languages' ) );
10
- add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_update' ), 11 );
11
- add_filter( 'upgrader_pre_download', array( $this, 'version_update' ), 10, 2 );
12
- add_action( 'admin_notices', array( $this, 'translation_upgrade_notice' ) );
13
- add_action( 'wp_ajax_hide_wcml_translations_message', array($this, 'hide_wcml_translations_message') );
14
-
15
- $this->load_js();
16
- }
17
-
18
- /**
19
- * Automatically download translations for WC ( when user install WCML ( from 3.3.3) / add new language in WPML )
20
- *
21
- * @param string $lang_code Language code
22
- *
23
- */
24
- function download_woocommerce_translations( $lang_code, $wc_version ){
25
- global $sitepress;
26
-
27
- $locale = $sitepress->get_locale( $lang_code );
28
-
29
- if( $locale != 'en_US' && $this->has_available_update( $locale, $wc_version ) ){
30
-
31
- $wc_version = $wc_version ? $wc_version : WC_VERSION;
32
-
33
- include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
34
- require_once( ABSPATH . 'wp-admin/includes/file.php' );
35
- require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
36
- require_once( ABSPATH . 'wp-admin/includes/template.php' );
37
-
38
- $url = 'update-core.php?action=do-translation-upgrade';
39
- $nonce = 'upgrade-translations';
40
- $title = '';
41
- $context = WP_LANG_DIR;
42
-
43
- $upgrader = new Language_Pack_Upgrader( new Automatic_Upgrader_Skin( compact( 'url', 'nonce', 'title', 'context' ) ) ); // use Language_Pack_Upgrader_Skin instead of Automatic_Upgrader_Skin to display upgrade process
44
-
45
- $upgr_object = array();
46
- $upgr_object[0] = new stdClass();
47
- $upgr_object[0]->type = 'plugin';
48
- $upgr_object[0]->slug = 'woocommerce';
49
- $upgr_object[0]->language = $locale;
50
- $upgr_object[0]->version = $wc_version;
51
- $upgr_object[0]->updated = date('Y-m-d H:i:s');
52
- $upgr_object[0]->package = $this->get_language_pack_uri( $locale, $wc_version );
53
- $upgr_object[0]->autoupdate = 1;
54
-
55
- $ob_level_before = ob_get_level();
56
-
57
- $upgrader->bulk_upgrade( $upgr_object );
58
-
59
- // Close a potential unclosed output buffer
60
- $ob_level_after = ob_get_level();
61
- if( $ob_level_after > $ob_level_before ){
62
- ob_end_clean();
63
- }
64
-
65
-
66
- $this->save_translation_version( $locale, false, $wc_version );
67
- }
68
-
69
- }
70
-
71
-
72
- /*
73
- * Automatically download translations for WC for active languages
74
- *
75
- */
76
- function download_woocommerce_translations_for_active_languages( $wc_version = false ){
77
- global $sitepress, $woocommerce_wpml;
78
-
79
- $active_languages = $sitepress->get_active_languages();
80
-
81
- $current_language = $sitepress->get_current_language();
82
-
83
- foreach( $active_languages as $language ){
84
-
85
- $this->download_woocommerce_translations( $language['code'], $wc_version );
86
-
87
- }
88
-
89
- $sitepress->switch_lang( $current_language );
90
-
91
- if( isset( $woocommerce_wpml->url_translation ) ){
92
- $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
93
- }
94
-
95
- }
96
-
97
-
98
- /*
99
- * Check for WC language updates
100
- *
101
- * @param object $data Transient update data
102
- *
103
- * @return object
104
- */
105
- function check_for_update( $data ){
106
- global $sitepress;
107
-
108
- $active_languages = $sitepress->get_active_languages();
109
- $current_language = $sitepress->get_current_language();
110
-
111
- foreach( $active_languages as $language ){
112
- if( $language['code'] == 'en' )
113
- continue;
114
-
115
- $locale = $sitepress->get_locale( $language['code'] );
116
-
117
- if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
118
-
119
- $data->translations[] = array(
120
- 'type' => 'plugin',
121
- 'slug' => 'woocommerce',
122
- 'language' => $locale,
123
- 'version' => WC_VERSION,
124
- 'updated' => date( 'Y-m-d H:i:s' ),
125
- 'package' => $this->get_language_pack_uri( $locale ),
126
- 'autoupdate' => 1
127
- );
128
-
129
- }
130
-
131
- }
132
-
133
- return $data;
134
- }
135
-
136
-
137
- function get_language_pack_uri( $locale, $version = false ){
138
-
139
- if( !$version ){
140
- $version = WC_VERSION;
141
- }
142
-
143
- if( version_compare( $version, '2.5.0', '<') ){
144
- $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
145
- return $repo . $version . '/packages/' . $locale . '.zip';
146
-
147
- }else{
148
- $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
149
- return $repo . $version . '/' . $locale . '.zip';
150
- }
151
-
152
- }
153
-
154
- /*
155
- * Update the WC language version in database
156
- *
157
- *
158
- * @param bool $reply Whether to bail without returning the package (default: false)
159
- * @param string $package Package URL
160
- *
161
- * @return bool
162
- */
163
- function version_update( $reply, $package ) {
164
-
165
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
166
-
167
- if( !is_array( $notices ) ){
168
- return $reply;
169
- }
170
-
171
- foreach( $notices as $key => $locale){
172
- if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
173
-
174
- $this->save_translation_version( $locale, $key );
175
-
176
- }
177
- }
178
-
179
- return $reply;
180
- }
181
-
182
-
183
- function save_translation_version( $locale, $key = false, $wc_version = false ){
184
-
185
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
186
-
187
- // Update the language pack version
188
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
189
-
190
- if( is_array( $notices ) ){
191
-
192
- if( !$key )
193
- $key = array_search( $locale, $notices );
194
-
195
- // Remove the translation upgrade notice
196
- unset( $notices[ $key ] );
197
-
198
- update_option( 'wcml_translations_upgrade_notice', $notices );
199
-
200
- }
201
-
202
- }
203
-
204
- /*
205
- * Check if has available translation update
206
- *
207
- * @param string $locale Locale code
208
- *
209
- * @return bool
210
- */
211
- function has_available_update( $locale, $wc_version = false ) {
212
- $wc_version = $wc_version ? $wc_version : WC_VERSION;
213
-
214
- $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
215
-
216
- $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
217
- $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
218
-
219
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
220
-
221
- if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
222
- if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
223
-
224
- if( !$notices || !in_array( $locale, $notices )){
225
- $notices[] = $locale;
226
-
227
- update_option( 'wcml_translations_upgrade_notice', $notices );
228
- update_option( 'hide_wcml_translations_message', 0 );
229
- }
230
-
231
- return true;
232
- } else {
233
- // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
234
- update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
235
- }
236
- }
237
-
238
- return false;
239
- }
240
-
241
-
242
- /**
243
- * Check if language pack exists
244
- *
245
- * @return bool
246
- */
247
- function check_if_language_pack_exists( $locale, $wc_version ) {
248
-
249
- $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
250
-
251
- if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
252
- return true;
253
- } else {
254
- return false;
255
- }
256
- }
257
-
258
-
259
- /*
260
- * Display Translations upgrade notice message
261
- */
262
- function translation_upgrade_notice(){
263
- global $woocommerce_wpml;
264
-
265
- $screen = get_current_screen();
266
- $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
267
-
268
- if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
269
-
270
- $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
271
- $lang_notices->show();
272
- }
273
- }
274
-
275
- /*
276
- * Hide Translations upgrade notice message ( update option in DB )
277
- */
278
- function hide_wcml_translations_message(){
279
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
280
- if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
281
- die('Invalid nonce');
282
- }
283
- update_option( 'hide_wcml_translations_message', true );
284
-
285
- die();
286
- }
287
-
288
- public function load_js(){
289
-
290
- wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
291
- wp_enqueue_script( 'wcml-lang-notice');
292
-
293
- wp_localize_script( 'wcml-lang-notice', 'wcml_settings',
294
- array(
295
- 'warn' => __( "Downloading translations... Please don't close this page.", 'woocommerce-multilingual' )
296
- )
297
- );
298
-
299
- }
300
-
301
  }
1
+ <?php
2
+
3
+ class WCML_Languages_Upgrader{
4
+
5
+
6
+
7
+ function __construct(){
8
+
9
+ add_action( 'icl_update_active_languages', array( $this, 'download_woocommerce_translations_for_active_languages' ) );
10
+ add_filter( 'pre_set_site_transient_update_plugins', array( $this, 'check_for_update' ), 11 );
11
+ add_filter( 'upgrader_pre_download', array( $this, 'version_update' ), 10, 2 );
12
+ add_action( 'admin_notices', array( $this, 'translation_upgrade_notice' ) );
13
+ add_action( 'wp_ajax_hide_wcml_translations_message', array($this, 'hide_wcml_translations_message') );
14
+
15
+ $this->load_js();
16
+ }
17
+
18
+ /**
19
+ * Automatically download translations for WC ( when user install WCML ( from 3.3.3) / add new language in WPML )
20
+ *
21
+ * @param string $lang_code Language code
22
+ *
23
+ */
24
+ function download_woocommerce_translations( $lang_code, $wc_version ){
25
+ global $sitepress;
26
+
27
+ $locale = $sitepress->get_locale( $lang_code );
28
+
29
+ if( $locale != 'en_US' && $this->has_available_update( $locale, $wc_version ) ){
30
+
31
+ $wc_version = $wc_version ? $wc_version : WC_VERSION;
32
+
33
+ include_once( ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' );
34
+ require_once( ABSPATH . 'wp-admin/includes/file.php' );
35
+ require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
36
+ require_once( ABSPATH . 'wp-admin/includes/template.php' );
37
+
38
+ $url = 'update-core.php?action=do-translation-upgrade';
39
+ $nonce = 'upgrade-translations';
40
+ $title = '';
41
+ $context = WP_LANG_DIR;
42
+
43
+ $upgrader = new Language_Pack_Upgrader( new Automatic_Upgrader_Skin( compact( 'url', 'nonce', 'title', 'context' ) ) ); // use Language_Pack_Upgrader_Skin instead of Automatic_Upgrader_Skin to display upgrade process
44
+
45
+ $upgr_object = array();
46
+ $upgr_object[0] = new stdClass();
47
+ $upgr_object[0]->type = 'plugin';
48
+ $upgr_object[0]->slug = 'woocommerce';
49
+ $upgr_object[0]->language = $locale;
50
+ $upgr_object[0]->version = $wc_version;
51
+ $upgr_object[0]->updated = date('Y-m-d H:i:s');
52
+ $upgr_object[0]->package = $this->get_language_pack_uri( $locale, $wc_version );
53
+ $upgr_object[0]->autoupdate = 1;
54
+
55
+ $ob_level_before = ob_get_level();
56
+
57
+ $upgrader->bulk_upgrade( $upgr_object );
58
+
59
+ // Close a potential unclosed output buffer
60
+ $ob_level_after = ob_get_level();
61
+ if( $ob_level_after > $ob_level_before ){
62
+ ob_end_clean();
63
+ }
64
+
65
+
66
+ $this->save_translation_version( $locale, false, $wc_version );
67
+ }
68
+
69
+ }
70
+
71
+
72
+ /*
73
+ * Automatically download translations for WC for active languages
74
+ *
75
+ */
76
+ function download_woocommerce_translations_for_active_languages( $wc_version = false ){
77
+ global $sitepress, $woocommerce_wpml;
78
+
79
+ $active_languages = $sitepress->get_active_languages();
80
+
81
+ $current_language = $sitepress->get_current_language();
82
+
83
+ foreach( $active_languages as $language ){
84
+
85
+ $this->download_woocommerce_translations( $language['code'], $wc_version );
86
+
87
+ }
88
+
89
+ $sitepress->switch_lang( $current_language );
90
+
91
+ if( isset( $woocommerce_wpml->url_translation ) ){
92
+ $woocommerce_wpml->url_translation->register_product_and_taxonomy_bases();
93
+ }
94
+
95
+ }
96
+
97
+
98
+ /*
99
+ * Check for WC language updates
100
+ *
101
+ * @param object $data Transient update data
102
+ *
103
+ * @return object
104
+ */
105
+ function check_for_update( $data ){
106
+ global $sitepress;
107
+
108
+ $active_languages = $sitepress->get_active_languages();
109
+ $current_language = $sitepress->get_current_language();
110
+
111
+ foreach( $active_languages as $language ){
112
+ if( $language['code'] == 'en' )
113
+ continue;
114
+
115
+ $locale = $sitepress->get_locale( $language['code'] );
116
+
117
+ if ( $this->has_available_update( $locale ) && isset( $data->translations ) ) {
118
+
119
+ $data->translations[] = array(
120
+ 'type' => 'plugin',
121
+ 'slug' => 'woocommerce',
122
+ 'language' => $locale,
123
+ 'version' => WC_VERSION,
124
+ 'updated' => date( 'Y-m-d H:i:s' ),
125
+ 'package' => $this->get_language_pack_uri( $locale ),
126
+ 'autoupdate' => 1
127
+ );
128
+
129
+ }
130
+
131
+ }
132
+
133
+ return $data;
134
+ }
135
+
136
+
137
+ function get_language_pack_uri( $locale, $version = false ){
138
+
139
+ if( !$version ){
140
+ $version = WC_VERSION;
141
+ }
142
+
143
+ if( version_compare( $version, '2.5.0', '<') ){
144
+ $repo = 'https://github.com/woothemes/woocommerce-language-packs/raw/v';
145
+ return $repo . $version . '/packages/' . $locale . '.zip';
146
+
147
+ }else{
148
+ $repo = 'https://downloads.wordpress.org/translation/plugin/woocommerce/';
149
+ return $repo . $version . '/' . $locale . '.zip';
150
+ }
151
+
152
+ }
153
+
154
+ /*
155
+ * Update the WC language version in database
156
+ *
157
+ *
158
+ * @param bool $reply Whether to bail without returning the package (default: false)
159
+ * @param string $package Package URL
160
+ *
161
+ * @return bool
162
+ */
163
+ function version_update( $reply, $package ) {
164
+
165
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
166
+
167
+ if( !is_array( $notices ) ){
168
+ return $reply;
169
+ }
170
+
171
+ foreach( $notices as $key => $locale){
172
+ if( strstr( $package, 'woocommerce') && strstr( $package, $locale) ){
173
+
174
+ $this->save_translation_version( $locale, $key );
175
+
176
+ }
177
+ }
178
+
179
+ return $reply;
180
+ }
181
+
182
+
183
+ function save_translation_version( $locale, $key = false, $wc_version = false ){
184
+
185
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
186
+
187
+ // Update the language pack version
188
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version ? $wc_version : WC_VERSION, $locale ) );
189
+
190
+ if( is_array( $notices ) ){
191
+
192
+ if( !$key )
193
+ $key = array_search( $locale, $notices );
194
+
195
+ // Remove the translation upgrade notice
196
+ unset( $notices[ $key ] );
197
+
198
+ update_option( 'wcml_translations_upgrade_notice', $notices );
199
+
200
+ }
201
+
202
+ }
203
+
204
+ /*
205
+ * Check if has available translation update
206
+ *
207
+ * @param string $locale Locale code
208
+ *
209
+ * @return bool
210
+ */
211
+ function has_available_update( $locale, $wc_version = false ) {
212
+ $wc_version = $wc_version ? $wc_version : WC_VERSION;
213
+
214
+ $version = get_option( 'woocommerce_language_pack_version_'.$locale, array( '0', $locale ) );
215
+
216
+ $is_new_version = !is_array( $version ) || version_compare( $version[0], $wc_version, '<' ) || $version[1] !== $locale;
217
+ $mo_file_absent = !file_exists( sprintf( WP_LANG_DIR . '/plugins/woocommerce-%s.mo', $locale ) );
218
+
219
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
220
+
221
+ if ( 'en_US' !== $locale && ( $is_new_version || $mo_file_absent ) ) {
222
+ if ( $this->check_if_language_pack_exists( $locale, $wc_version ) ){
223
+
224
+ if( !$notices || !in_array( $locale, $notices )){
225
+ $notices[] = $locale;
226
+
227
+ update_option( 'wcml_translations_upgrade_notice', $notices );
228
+ update_option( 'hide_wcml_translations_message', 0 );
229
+ }
230
+
231
+ return true;
232
+ } else {
233
+ // Updated the woocommerce_language_pack_version to avoid searching translations for this release again
234
+ update_option( 'woocommerce_language_pack_version_'.$locale, array( $wc_version, $locale ) );
235
+ }
236
+ }
237
+
238
+ return false;
239
+ }
240
+
241
+
242
+ /**
243
+ * Check if language pack exists
244
+ *
245
+ * @return bool
246
+ */
247
+ function check_if_language_pack_exists( $locale, $wc_version ) {
248
+
249
+ $response = wp_safe_remote_get( $this->get_language_pack_uri( $locale, $wc_version ), array( 'timeout' => 60 ) );
250
+
251
+ if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 && $response['body'] != '404 File not found' ) {
252
+ return true;
253
+ } else {
254
+ return false;
255
+ }
256
+ }
257
+
258
+
259
+ /*
260
+ * Display Translations upgrade notice message
261
+ */
262
+ function translation_upgrade_notice(){
263
+ global $woocommerce_wpml;
264
+
265
+ $screen = get_current_screen();
266
+ $notices = maybe_unserialize( get_option( 'wcml_translations_upgrade_notice' ) );
267
+
268
+ if ( 'update-core' !== $screen->id && !empty ( $notices ) && !get_option( 'hide_wcml_translations_message' ) ) {
269
+
270
+ $lang_notices = new WCML_Languages_Upgrade_Notice( $notices );
271
+ $lang_notices->show();
272
+ }
273
+ }
274
+
275
+ /*
276
+ * Hide Translations upgrade notice message ( update option in DB )
277
+ */
278
+ function hide_wcml_translations_message(){
279
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
280
+ if(!$nonce || !wp_verify_nonce($nonce, 'hide_wcml_translations_message' ) ){
281
+ die('Invalid nonce');
282
+ }
283
+ update_option( 'hide_wcml_translations_message', true );
284
+
285
+ die();
286
+ }
287
+
288
+ public function load_js(){
289
+
290
+ wp_register_script( 'wcml-lang-notice', WCML_PLUGIN_URL . '/res/js/languages_notice' . WCML_JS_MIN . '.js', array( 'jquery' ), WCML_VERSION );
291
+ wp_enqueue_script( 'wcml-lang-notice');
292
+
293
+ wp_localize_script( 'wcml-lang-notice', 'wcml_settings',
294
+ array(
295
+ 'warn' => __( "Downloading translations... Please don't close this page.", 'woocommerce-multilingual' )
296
+ )
297
+ );
298
+
299
+ }
300
+
301
  }
inc/class-wcml-locale.php CHANGED
@@ -1,62 +1,62 @@
1
- <?php
2
-
3
- class WCML_Locale{
4
-
5
- private $woocommerce_wpml;
6
- private $sitepress;
7
-
8
- public function __construct( &$woocommerce_wpml, &$sitepress ){
9
- $this->woocommerce_wpml = $woocommerce_wpml;
10
- $this->sitepress = $sitepress;
11
-
12
- $this->load_locale();
13
-
14
- add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
15
- add_action( 'woocommerce_email', array( $this, 'woocommerce_email_refresh_text_domain' ) );
16
- add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
17
- add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
18
-
19
- }
20
-
21
- function load_locale(){
22
- return load_plugin_textdomain( 'woocommerce-multilingual', false, WCML_PLUGIN_FOLDER.'/locale' );
23
- }
24
-
25
- public function switch_locale( $lang_code = false ) {
26
- global $l10n;
27
- static $original_l10n;
28
- if ( ! empty( $lang_code ) ) {
29
- $original_l10n = isset( $l10n[ 'woocommerce-multilingual' ] ) ? $l10n[ 'woocommerce-multilingual' ] : null;
30
- if ( $original_l10n !== null ) {
31
- unset( $l10n[ 'woocommerce-multilingual' ] );
32
- }
33
- return load_textdomain( 'woocommerce-multilingual',
34
- WCML_LOCALE_PATH . '/woocommerce-multilingual-' . $this->sitepress->get_locale( $lang_code ) . '.mo' );
35
-
36
- } else { // switch back
37
- $l10n[ 'woocommerce-multilingual' ] = $original_l10n;
38
- }
39
- }
40
-
41
- /* Change locale to saving language - needs for sanitize_title exception wcml-390 */
42
- public function update_product_action_locale_check( $locale ){
43
- if( isset($_POST['action']) && $_POST['action'] == 'wpml_translation_dialog_save_job' ){
44
- return $this->sitepress->get_locale( $_POST[ 'job_details' ][ 'target' ] );
45
- }
46
- return $locale;
47
- }
48
-
49
- public function woocommerce_email_refresh_text_domain(){
50
- if( !isset( $_GET[ 'page' ] ) || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] != 'wc-settings' ) ){
51
- $this->wcml_refresh_text_domain();
52
- }
53
- }
54
-
55
- public function wcml_refresh_text_domain(){
56
- global $woocommerce;
57
- $domain = 'woocommerce';
58
- unload_textdomain( $domain );
59
- $woocommerce->load_plugin_textdomain();
60
- }
61
-
62
  }
1
+ <?php
2
+
3
+ class WCML_Locale{
4
+
5
+ private $woocommerce_wpml;
6
+ private $sitepress;
7
+
8
+ public function __construct( &$woocommerce_wpml, &$sitepress ){
9
+ $this->woocommerce_wpml = $woocommerce_wpml;
10
+ $this->sitepress = $sitepress;
11
+
12
+ $this->load_locale();
13
+
14
+ add_filter( 'locale',array( $this, 'update_product_action_locale_check' ) );
15
+ add_action( 'woocommerce_email', array( $this, 'woocommerce_email_refresh_text_domain' ) );
16
+ add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
17
+ add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
18
+
19
+ }
20
+
21
+ function load_locale(){
22
+ return load_plugin_textdomain( 'woocommerce-multilingual', false, WCML_PLUGIN_FOLDER.'/locale' );
23
+ }
24
+
25
+ public function switch_locale( $lang_code = false ) {
26
+ global $l10n;
27
+ static $original_l10n;
28
+ if ( ! empty( $lang_code ) ) {
29
+ $original_l10n = isset( $l10n[ 'woocommerce-multilingual' ] ) ? $l10n[ 'woocommerce-multilingual' ] : null;
30
+ if ( $original_l10n !== null ) {
31
+ unset( $l10n[ 'woocommerce-multilingual' ] );
32
+ }
33
+ return load_textdomain( 'woocommerce-multilingual',
34
+ WCML_LOCALE_PATH . '/woocommerce-multilingual-' . $this->sitepress->get_locale( $lang_code ) . '.mo' );
35
+
36
+ } else { // switch back
37
+ $l10n[ 'woocommerce-multilingual' ] = $original_l10n;
38
+ }
39
+ }
40
+
41
+ /* Change locale to saving language - needs for sanitize_title exception wcml-390 */
42
+ public function update_product_action_locale_check( $locale ){
43
+ if( isset($_POST['action']) && $_POST['action'] == 'wpml_translation_dialog_save_job' ){
44
+ return $this->sitepress->get_locale( $_POST[ 'job_details' ][ 'target' ] );
45
+ }
46
+ return $locale;
47
+ }
48
+
49
+ public function woocommerce_email_refresh_text_domain(){
50
+ if( !isset( $_GET[ 'page' ] ) || ( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] != 'wc-settings' ) ){
51
+ $this->wcml_refresh_text_domain();
52
+ }
53
+ }
54
+
55
+ public function wcml_refresh_text_domain(){
56
+ global $woocommerce;
57
+ $domain = 'woocommerce';
58
+ unload_textdomain( $domain );
59
+ $woocommerce->load_plugin_textdomain();
60
+ }
61
+
62
  }
inc/class-wcml-media.php CHANGED
@@ -1,184 +1,184 @@
1
- <?php
2
-
3
- class WCML_Media{
4
-
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var SitePress */
8
- private $sitepress;
9
- /** @var wpdb */
10
- private $wpdb;
11
-
12
- public $settings = array();
13
-
14
- public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
15
-
16
- $this->woocommerce_wpml =& $woocommerce_wpml;
17
- $this->sitepress =& $sitepress;
18
- $this->wpdb =& $wpdb;
19
-
20
- $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
21
- $this->settings['translate_media'] = $wpml_media_options['new_content_settings']['always_translate_media'];
22
- $this->settings['duplicate_media'] = $wpml_media_options['new_content_settings']['duplicate_media'];
23
- $this->settings['duplicate_featured'] = $wpml_media_options['new_content_settings']['duplicate_featured'];
24
-
25
- //remove media sync on product page
26
- add_action( 'admin_head', array( $this, 'remove_language_options' ), 11 );
27
-
28
- //when save new attachment duplicate product gallery
29
- add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'sync_product_gallery_duplicate_attachment' ), 11, 2 );
30
- add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
31
- }
32
-
33
- public function sync_feature_product_meta(){
34
-
35
- if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) ) {
36
- $product_id = absint( $_GET[ 'product_id' ] );
37
-
38
- if ( 'product' === get_post_type( $product_id ) && $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
39
- $value = get_post_meta( $product_id, '_featured', true ) === 'yes' ? 'no' : 'yes';
40
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
41
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
42
- foreach( $translations as $translation ){
43
- if ( !$translation->original ) {
44
- update_post_meta( $translation->element_id, '_featured', $value );
45
- }
46
- }
47
- }
48
- }
49
- }
50
-
51
- public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ){
52
- if( defined( 'WPML_MEDIA_VERSION' ) ){
53
- $thumbnail_id = get_post_meta( $orig_post_id, '_thumbnail_id', true );
54
- $trnsl_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
55
- if( is_null( $trnsl_thumbnail ) && $thumbnail_id ){
56
- $trnsl_thumbnail = WPML_Media::create_duplicate_attachment( $thumbnail_id, wp_get_post_parent_id( $thumbnail_id ), $lang );
57
- }
58
-
59
- update_post_meta( $trnsl_post_id, '_thumbnail_id', $trnsl_thumbnail );
60
- update_post_meta( $orig_post_id, '_wpml_media_duplicate', 1 );
61
- update_post_meta( $orig_post_id, '_wpml_media_featured', 1 );
62
- }
63
- }
64
-
65
- public function sync_product_gallery( $product_id ){
66
- if( !defined( 'WPML_MEDIA_VERSION' ) ){
67
- return;
68
- }
69
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
70
- $gallery_ids = explode( ',', $product_gallery );
71
-
72
- $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
73
- $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
74
- foreach( $translations as $translation ){
75
- $duplicated_ids = '';
76
- if ( !$translation->original ) {
77
- foreach( $gallery_ids as $image_id ){
78
- if( get_post( $image_id ) ) {
79
- $duplicated_id = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $translation->language_code );
80
- if ( is_null( $duplicated_id ) && $image_id ) {
81
- $duplicated_id = WPML_Media::create_duplicate_attachment( $image_id, wp_get_post_parent_id( $image_id ), $translation->language_code );
82
- }
83
- $duplicated_ids .= $duplicated_id . ',';
84
- }
85
- }
86
- $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
87
- update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
88
- }
89
- }
90
- }
91
-
92
- public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ){
93
- $product_id = wp_get_post_parent_id( $att_id );
94
- $post_type = get_post_type( $product_id );
95
- if( $post_type != 'product' ){
96
- return;
97
- }
98
- $this->sync_product_gallery( $product_id );
99
- }
100
-
101
- public function product_images_ids( $product_id ){
102
- $product_images_ids = array();
103
-
104
- //thumbnail image
105
- $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
106
- if( $tmb ) {
107
- $product_images_ids[] = $tmb;
108
- }
109
-
110
- //product gallery
111
- $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
112
- if( $product_gallery ) {
113
- $product_gallery = explode( ',', $product_gallery );
114
- foreach( $product_gallery as $img ){
115
- if( !in_array( $img, $product_images_ids ) ){
116
- $product_images_ids[] = $img;
117
- }
118
- }
119
- }
120
-
121
- foreach( wp_get_post_terms( $product_id, 'product_type', array( "fields" => "names" ) ) as $type ){
122
- $product_type = $type;
123
- }
124
-
125
- if( isset( $product_type ) && $product_type == 'variable' ){
126
- $get_post_variations_image = $this->wpdb->get_col(
127
- $this->wpdb->prepare(
128
- "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
129
- LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
130
- WHERE pm.meta_key='_thumbnail_id'
131
- AND p.post_status IN ('publish','private')
132
- AND p.post_type = 'product_variation'
133
- AND p.post_parent = %d
134
- ORDER BY ID", $product_id )
135
- );
136
- foreach( $get_post_variations_image as $variation_image ){
137
- if( $variation_image && !in_array( $variation_image, $product_images_ids ) ){
138
- $product_images_ids[] = $variation_image;
139
- }
140
- }
141
- }
142
-
143
- foreach( $product_images_ids as $key => $image ){
144
- if( ! get_post_status ( $image ) ){
145
- unset( $product_images_ids[ $key ] );
146
- }
147
- }
148
-
149
- return $product_images_ids;
150
- }
151
-
152
- public function exclude_not_duplicated_attachments( &$product_images, $product_id ){
153
-
154
- $thumbnail_id = get_post_meta( $product_id, '_thumbnail_id', true );
155
-
156
- if ( empty( $this->settings[ 'duplicate_media' ] ) ) {
157
- $product_images = $thumbnail_id ? array( $thumbnail_id ) : array();
158
- }
159
-
160
- $key = $thumbnail_id ? array_search( $thumbnail_id, $product_images ) : false;
161
- if( false !== $key && empty( $this->settings[ 'duplicate_featured' ] ) ){
162
- unset( $product_images[$key] );
163
- }
164
-
165
- return $product_images;
166
- }
167
-
168
- public function remove_language_options(){
169
- global $WPML_media, $typenow;
170
- if( defined( 'WPML_MEDIA_VERSION' ) && $typenow == 'product' ){
171
- remove_action( 'icl_post_languages_options_after', array( $WPML_media, 'language_options' ) );
172
- add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
173
- }
174
- }
175
-
176
- public function media_inputs(){
177
- $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
178
-
179
- echo '<input name="icl_duplicate_attachments" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_media' ].'" />';
180
- echo '<input name="icl_duplicate_featured_image" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_featured' ].'" />';
181
- }
182
-
183
-
184
  }
1
+ <?php
2
+
3
+ class WCML_Media{
4
+
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var SitePress */
8
+ private $sitepress;
9
+ /** @var wpdb */
10
+ private $wpdb;
11
+
12
+ public $settings = array();
13
+
14
+ public function __construct( &$woocommerce_wpml, &$sitepress, &$wpdb ){
15
+
16
+ $this->woocommerce_wpml =& $woocommerce_wpml;
17
+ $this->sitepress =& $sitepress;
18
+ $this->wpdb =& $wpdb;
19
+
20
+ $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
21
+ $this->settings['translate_media'] = $wpml_media_options['new_content_settings']['always_translate_media'];
22
+ $this->settings['duplicate_media'] = $wpml_media_options['new_content_settings']['duplicate_media'];
23
+ $this->settings['duplicate_featured'] = $wpml_media_options['new_content_settings']['duplicate_featured'];
24
+
25
+ //remove media sync on product page
26
+ add_action( 'admin_head', array( $this, 'remove_language_options' ), 11 );
27
+
28
+ //when save new attachment duplicate product gallery
29
+ add_action( 'wpml_media_create_duplicate_attachment', array( $this, 'sync_product_gallery_duplicate_attachment' ), 11, 2 );
30
+ add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
31
+ }
32
+
33
+ public function sync_feature_product_meta(){
34
+
35
+ if ( current_user_can( 'edit_products' ) && check_admin_referer( 'woocommerce-feature-product' ) ) {
36
+ $product_id = absint( $_GET[ 'product_id' ] );
37
+
38
+ if ( 'product' === get_post_type( $product_id ) && $this->woocommerce_wpml->products->is_original_product( $product_id ) ) {
39
+ $value = get_post_meta( $product_id, '_featured', true ) === 'yes' ? 'no' : 'yes';
40
+ $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
41
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
42
+ foreach( $translations as $translation ){
43
+ if ( !$translation->original ) {
44
+ update_post_meta( $translation->element_id, '_featured', $value );
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+
51
+ public function sync_thumbnail_id( $orig_post_id, $trnsl_post_id, $lang ){
52
+ if( defined( 'WPML_MEDIA_VERSION' ) ){
53
+ $thumbnail_id = get_post_meta( $orig_post_id, '_thumbnail_id', true );
54
+ $trnsl_thumbnail = apply_filters( 'translate_object_id', $thumbnail_id, 'attachment', false, $lang );
55
+ if( is_null( $trnsl_thumbnail ) && $thumbnail_id ){
56
+ $trnsl_thumbnail = WPML_Media::create_duplicate_attachment( $thumbnail_id, wp_get_post_parent_id( $thumbnail_id ), $lang );
57
+ }
58
+
59
+ update_post_meta( $trnsl_post_id, '_thumbnail_id', $trnsl_thumbnail );
60
+ update_post_meta( $orig_post_id, '_wpml_media_duplicate', 1 );
61
+ update_post_meta( $orig_post_id, '_wpml_media_featured', 1 );
62
+ }
63
+ }
64
+
65
+ public function sync_product_gallery( $product_id ){
66
+ if( !defined( 'WPML_MEDIA_VERSION' ) ){
67
+ return;
68
+ }
69
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
70
+ $gallery_ids = explode( ',', $product_gallery );
71
+
72
+ $trid = $this->sitepress->get_element_trid( $product_id, 'post_product' );
73
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_product', true );
74
+ foreach( $translations as $translation ){
75
+ $duplicated_ids = '';
76
+ if ( !$translation->original ) {
77
+ foreach( $gallery_ids as $image_id ){
78
+ if( get_post( $image_id ) ) {
79
+ $duplicated_id = apply_filters( 'translate_object_id', $image_id, 'attachment', false, $translation->language_code );
80
+ if ( is_null( $duplicated_id ) && $image_id ) {
81
+ $duplicated_id = WPML_Media::create_duplicate_attachment( $image_id, wp_get_post_parent_id( $image_id ), $translation->language_code );
82
+ }
83
+ $duplicated_ids .= $duplicated_id . ',';
84
+ }
85
+ }
86
+ $duplicated_ids = substr( $duplicated_ids, 0, strlen( $duplicated_ids ) - 1 );
87
+ update_post_meta( $translation->element_id, '_product_image_gallery', $duplicated_ids );
88
+ }
89
+ }
90
+ }
91
+
92
+ public function sync_product_gallery_duplicate_attachment( $att_id, $dup_att_id ){
93
+ $product_id = wp_get_post_parent_id( $att_id );
94
+ $post_type = get_post_type( $product_id );
95
+ if( $post_type != 'product' ){
96
+ return;
97
+ }
98
+ $this->sync_product_gallery( $product_id );
99
+ }
100
+
101
+ public function product_images_ids( $product_id ){
102
+ $product_images_ids = array();
103
+
104
+ //thumbnail image
105
+ $tmb = get_post_meta( $product_id, '_thumbnail_id', true );
106
+ if( $tmb ) {
107
+ $product_images_ids[] = $tmb;
108
+ }
109
+
110
+ //product gallery
111
+ $product_gallery = get_post_meta( $product_id, '_product_image_gallery', true );
112
+ if( $product_gallery ) {
113
+ $product_gallery = explode( ',', $product_gallery );
114
+ foreach( $product_gallery as $img ){
115
+ if( !in_array( $img, $product_images_ids ) ){
116
+ $product_images_ids[] = $img;
117
+ }
118
+ }
119
+ }
120
+
121
+ foreach( wp_get_post_terms( $product_id, 'product_type', array( "fields" => "names" ) ) as $type ){
122
+ $product_type = $type;
123
+ }
124
+
125
+ if( isset( $product_type ) && $product_type == 'variable' ){
126
+ $get_post_variations_image = $this->wpdb->get_col(
127
+ $this->wpdb->prepare(
128
+ "SELECT pm.meta_value FROM {$this->wpdb->posts} AS p
129
+ LEFT JOIN {$this->wpdb->postmeta} AS pm ON p.ID = pm.post_id
130
+ WHERE pm.meta_key='_thumbnail_id'
131
+ AND p.post_status IN ('publish','private')
132
+ AND p.post_type = 'product_variation'
133
+ AND p.post_parent = %d
134
+ ORDER BY ID", $product_id )
135
+ );
136
+ foreach( $get_post_variations_image as $variation_image ){
137
+ if( $variation_image && !in_array( $variation_image, $product_images_ids ) ){
138
+ $product_images_ids[] = $variation_image;
139
+ }
140
+ }
141
+ }
142
+
143
+ foreach( $product_images_ids as $key => $image ){
144
+ if( ! get_post_status ( $image ) ){
145
+ unset( $product_images_ids[ $key ] );
146
+ }
147
+ }
148
+
149
+ return $product_images_ids;
150
+ }
151
+
152
+ public function exclude_not_duplicated_attachments( &$product_images, $product_id ){
153
+
154
+ $thumbnail_id = get_post_meta( $product_id, '_thumbnail_id', true );
155
+
156
+ if ( empty( $this->settings[ 'duplicate_media' ] ) ) {
157
+ $product_images = $thumbnail_id ? array( $thumbnail_id ) : array();
158
+ }
159
+
160
+ $key = $thumbnail_id ? array_search( $thumbnail_id, $product_images ) : false;
161
+ if( false !== $key && empty( $this->settings[ 'duplicate_featured' ] ) ){
162
+ unset( $product_images[$key] );
163
+ }
164
+
165
+ return $product_images;
166
+ }
167
+
168
+ public function remove_language_options(){
169
+ global $WPML_media, $typenow;
170
+ if( defined( 'WPML_MEDIA_VERSION' ) && $typenow == 'product' ){
171
+ remove_action( 'icl_post_languages_options_after', array( $WPML_media, 'language_options' ) );
172
+ add_action( 'icl_post_languages_options_after', array( $this, 'media_inputs' ) );
173
+ }
174
+ }
175
+
176
+ public function media_inputs(){
177
+ $wpml_media_options = maybe_unserialize( get_option( '_wpml_media' ) );
178
+
179
+ echo '<input name="icl_duplicate_attachments" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_media' ].'" />';
180
+ echo '<input name="icl_duplicate_featured_image" type="hidden" value="'.$wpml_media_options[ 'new_content_settings' ][ 'duplicate_featured' ].'" />';
181
+ }
182
+
183
+
184
  }
inc/class-wcml-orders.php CHANGED
@@ -1,377 +1,377 @@
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
- }
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'] = wc_get_product( $tr_product_id )->get_title();
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( wc_get_product( $tr_product_id )->get_title() );
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 = apply_filters( 'wpml_active_languages', array(), array( '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,46 +1,46 @@
1
- <?php
2
-
3
- /**
4
- * Class WCML_Screen_Options
5
- */
6
- class WCML_Products_Screen_Options {
7
-
8
- /**
9
- * Setup hooks.
10
- */
11
- public function init() {
12
- add_filter( 'default_hidden_columns', array( $this, 'filter_screen_options' ), 10, 2 );
13
- add_filter( 'wpml_hide_management_column', array( $this, 'sitepress_screen_option_filter' ), 10, 2 );
14
- }
15
-
16
- /**
17
- * Hide management column by default for products.
18
- *
19
- * @param $is_visible
20
- * @param $post_type
21
- *
22
- * @return bool
23
- */
24
- public function sitepress_screen_option_filter( $is_visible, $post_type ) {
25
- if ( 'product' === $post_type ) {
26
- $is_visible = false;
27
- }
28
-
29
- return $is_visible;
30
- }
31
-
32
- /**
33
- * Set default option for translations management column.
34
- *
35
- * @param $hidden
36
- * @param $screen
37
- *
38
- * @return array
39
- */
40
- public function filter_screen_options( $hidden, $screen ) {
41
- if ( 'edit-product' === $screen->id ) {
42
- $hidden[] = 'icl_translations';
43
- }
44
- return $hidden;
45
- }
46
- }
1
+ <?php
2
+
3
+ /**
4
+ * Class WCML_Screen_Options
5
+ */
6
+ class WCML_Products_Screen_Options {
7
+
8
+ /**
9
+ * Setup hooks.
10
+ */
11
+ public function init() {
12
+ add_filter( 'default_hidden_columns', array( $this, 'filter_screen_options' ), 10, 2 );
13
+ add_filter( 'wpml_hide_management_column', array( $this, 'sitepress_screen_option_filter' ), 10, 2 );
14
+ }
15
+
16
+ /**
17
+ * Hide management column by default for products.
18
+ *
19
+ * @param $is_visible
20
+ * @param $post_type
21
+ *
22
+ * @return bool
23
+ */
24
+ public function sitepress_screen_option_filter( $is_visible, $post_type ) {
25
+ if ( 'product' === $post_type ) {
26
+ $is_visible = false;
27
+ }
28
+
29
+ return $is_visible;
30
+ }
31
+
32
+ /**
33
+ * Set default option for translations management column.
34
+ *
35
+ * @param $hidden
36
+ * @param $screen
37
+ *
38
+ * @return array
39
+ */
40
+ public function filter_screen_options( $hidden, $screen ) {
41
+ if ( 'edit-product' === $screen->id ) {
42
+ $hidden[] = 'icl_translations';
43
+ }
44
+ return $hidden;
45
+ }
46
+ }
inc/class-wcml-products.php CHANGED
@@ -1,497 +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
- $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
  }
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
- }
29
-
30
- add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
31
- add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
32
- add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
33
-
34
- }
35
-
36
- public function filter_reports_query($query){
37
- global $wpdb, $sitepress;
38
-
39
- $current_language = $sitepress->get_current_language();
40
- $active_languages = $sitepress->get_active_languages();
41
-
42
- if($this->tab == 'orders' && $this->report == 'sales_by_product'){
43
-
44
- $sparkline_query = strpos( $query[ 'select'], 'sparkline_value' ) !== false;
45
-
46
- if(
47
-
48
- $sparkline_query ||
49
- isset( $query[ 'order_by' ] ) && ( $query[ 'order_by' ] == 'ORDER BY order_item_qty DESC' || $query[ 'order_by' ] == 'ORDER BY order_item_total DESC' )
50
-
51
- ){
52
-
53
-
54
- $query[ 'select' ] .= " , order_language.meta_value AS order_language , translations.trid";
55
-
56
- $query[ 'join' ] .= " LEFT JOIN {$wpdb->postmeta} order_language ON posts.ID = order_language.post_id";
57
- $query[ 'where' ] .= " AND order_language.meta_key = 'wpml_language' ";
58
-
59
- $query[ 'join' ] .= " LEFT JOIN {$wpdb->prefix}icl_translations translations ON translations.element_id = order_item_meta__product_id.meta_value";
60
- $query[ 'where' ] .= " AND translations.element_type IN ('post_product','post_product_variation') ";
61
-
62
- if(!$sparkline_query){
63
- $limit = str_replace('LIMIT ', '', trim($query[ 'limit' ]));
64
- $query[ 'limit' ] = sprintf(" LIMIT %d ", $limit * count($active_languages));
65
- }
66
-
67
-
68
- if($sparkline_query){
69
- preg_match("#order_item_meta__product_id\.meta_value = '([0-9]+)'#", $query[ 'where' ], $matches);
70
- $product_id = $matches[1];
71
- $post_type = get_post_type($product_id);
72
- $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
73
- $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
74
- $product_ids = array();
75
- foreach($translations as $translation){
76
- $product_ids[] = $translation->element_id;
77
- }
78
-
79
- $query[ 'where' ] = str_replace("order_item_meta__product_id.meta_value = '{$product_id}'", "order_item_meta__product_id.meta_value IN(" . join(',', $product_ids) . ")", $query[ 'where' ]);
80
-
81
- }
82
-
83
- $query[ 'select' ] .= ', translations.language_code AS language_code_' . esc_sql( $current_language ); // user for per-language caching
84
-
85
- }elseif(
86
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount' || //sales for the selected items
87
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count' || //purchases for the selected items
88
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' || //Get orders and dates in range - main chart: order_item_counts
89
- $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' //Get orders and dates in range - main chart: order_item_amounts
90
-
91
- ){
92
-
93
- preg_match("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", $query[ 'where' ], $matches);
94
- $product_ids = array();
95
- $exp = array_map('trim', explode(',', $matches[1]));
96
- foreach($exp as $e){
97
- $product_ids[] = trim($e, "'");
98
- }
99
- $all_product_ids = array();
100
- foreach($product_ids as $product_id){
101
- $post_type = get_post_type($product_id);
102
- $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
103
- $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
104
- foreach($translations as $translation){
105
- $all_product_ids[] = $translation->element_id;
106
- }
107
- }
108
-
109
- $query[ 'where' ] = preg_replace("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", "order_item_meta__product_id_array.meta_value IN (" . join(',', $all_product_ids) . ")", $query[ 'where' ]);
110
-
111
-
112
- }
113
-
114
- }
115
-
116
- return $query;
117
- }
118
-
119
-
120
- public function combine_report_by_languages($results){
121
- global $sitepress, $wpdb;
122
-
123
- if(is_array($results) && isset($results['0']->order_item_qty)){
124
- $mode = 'top_sellers';
125
- }elseif(is_array($results) && isset($results['0']->order_item_total)){
126
- $mode = 'top_earners';
127
- }elseif(isset($results['0']->sparkline_value)){
128
- $mode = 'top_sellers_spark';
129
- }else{
130
- return $results;
131
- }
132
-
133
- if(!isset($results['0']->trid)) return $results;
134
-
135
- $current_language = $sitepress->get_current_language();
136
-
137
- $combined_results = array();
138
-
139
- foreach($results as $k => $row){
140
-
141
- switch($mode){
142
- case 'top_sellers':
143
- case 'top_earners':
144
- $key = $row->trid;
145
- break;
146
- case 'top_sellers_spark':
147
- $key = $row->trid . '#' . substr($row->post_date, 0, 10);
148
- break;
149
- }
150
-
151
- if($row->order_language == $current_language){
152
-
153
- $combined_results[$key] = $row;
154
-
155
- }
156
-
157
- }
158
-
159
- foreach($results as $k => $row){
160
-
161
- if($row->order_language != $current_language){
162
-
163
- switch($mode){
164
- case 'top_sellers':
165
- case 'top_earners':
166
- $key = $row->trid;
167
- break;
168
- case 'top_sellers_spark':
169
- $key = $row->trid . '#' . substr($row->post_date, 0, 10);
170
- break;
171
- }
172
-
173
- if(isset($combined_results[$key])){
174
-
175
- switch($mode){
176
- case 'top_sellers':
177
- $combined_results[$key]->order_item_qty += $row->order_item_qty;
178
- break;
179
- case 'top_earners':
180
- $combined_results[$key]->order_item_total += $row->order_item_total;
181
- break;
182
- case 'top_sellers_spark':
183
- $combined_results[$key]->sparkline_value += $row->sparkline_value;
184
- break;
185
-
186
- }
187
-
188
- }else{
189
-
190
- $default_product_id = apply_filters( 'translate_object_id',$row->product_id, 'product', false, $current_language);
191
-
192
- if($default_product_id){
193
- $combined_results[$key] = new stdClass();
194
- $combined_results[$key]->product_id = $default_product_id;
195
-
196
- switch($mode){
197
- case 'top_sellers':
198
- $combined_results[$key]->order_item_qty = $row->order_item_qty;
199
- break;
200
- case 'top_earners':
201
- $combined_results[$key]->order_item_total = $row->order_item_total;
202
- break;
203
- case 'top_sellers_spark':
204
- $combined_results[$key]->sparkline_value = $row->sparkline_value;
205
- $combined_results[$key]->post_date = $row->post_date;
206
- break;
207
- }
208
-
209
- }
210
-
211
- }
212
-
213
-
214
- }
215
-
216
- }
217
-
218
- switch($mode){
219
- case 'top_sellers':
220
- usort($combined_results, array(__CLASS__, '_order_by_quantity'));
221
- array_slice($combined_results, 0, 12);
222
- break;
223
- case 'top_earners':
224
- usort($combined_results, array(__CLASS__, '_order_by_total'));
225
- array_slice($combined_results, 0, 12);
226
- break;
227
- case 'top_sellers_spark':
228
- break;
229
-
230
-
231
- }
232
-
233
- foreach($combined_results as $k => $row){
234
- unset($combined_results[$k]->trid, $combined_results[$k]->order_language);
235
- }
236
-
237
-
238
- return $combined_results;
239
- }
240
-
241
- private static function _order_by_quantity($a, $b){
242
- return $a->order_item_qty < $b->order_item_qty;
243
- }
244
-
245
- private static function _order_by_total($a, $b){
246
- return $a->order_item_total < $b->order_item_total;
247
- }
248
-
249
- public function filter_reports_stock_query( $query_from ){
250
- global $wpdb, $sitepress;
251
-
252
- $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
+ }
29
+
30
+ add_filter( 'woocommerce_report_most_stocked_query_from', array( $this, 'filter_reports_stock_query' ) );
31
+ add_filter( 'woocommerce_report_out_of_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
32
+ add_filter( 'woocommerce_report_low_in_stock_query_from', array( $this, 'filter_reports_stock_query' ) );
33
+
34
+ }
35
+
36
+ public function filter_reports_query($query){
37
+ global $wpdb, $sitepress;
38
+
39
+ $current_language = $sitepress->get_current_language();
40
+ $active_languages = $sitepress->get_active_languages();
41
+
42
+ if($this->tab == 'orders' && $this->report == 'sales_by_product'){
43
+
44
+ $sparkline_query = strpos( $query[ 'select'], 'sparkline_value' ) !== false;
45
+
46
+ if(
47
+
48
+ $sparkline_query ||
49
+ isset( $query[ 'order_by' ] ) && ( $query[ 'order_by' ] == 'ORDER BY order_item_qty DESC' || $query[ 'order_by' ] == 'ORDER BY order_item_total DESC' )
50
+
51
+ ){
52
+
53
+
54
+ $query[ 'select' ] .= " , order_language.meta_value AS order_language , translations.trid";
55
+
56
+ $query[ 'join' ] .= " LEFT JOIN {$wpdb->postmeta} order_language ON posts.ID = order_language.post_id";
57
+ $query[ 'where' ] .= " AND order_language.meta_key = 'wpml_language' ";
58
+
59
+ $query[ 'join' ] .= " LEFT JOIN {$wpdb->prefix}icl_translations translations ON translations.element_id = order_item_meta__product_id.meta_value";
60
+ $query[ 'where' ] .= " AND translations.element_type IN ('post_product','post_product_variation') ";
61
+
62
+ if(!$sparkline_query){
63
+ $limit = str_replace('LIMIT ', '', trim($query[ 'limit' ]));
64
+ $query[ 'limit' ] = sprintf(" LIMIT %d ", $limit * count($active_languages));
65
+ }
66
+
67
+
68
+ if($sparkline_query){
69
+ preg_match("#order_item_meta__product_id\.meta_value = '([0-9]+)'#", $query[ 'where' ], $matches);
70
+ $product_id = $matches[1];
71
+ $post_type = get_post_type($product_id);
72
+ $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
73
+ $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
74
+ $product_ids = array();
75
+ foreach($translations as $translation){
76
+ $product_ids[] = $translation->element_id;
77
+ }
78
+
79
+ $query[ 'where' ] = str_replace("order_item_meta__product_id.meta_value = '{$product_id}'", "order_item_meta__product_id.meta_value IN(" . join(',', $product_ids) . ")", $query[ 'where' ]);
80
+
81
+ }
82
+
83
+ $query[ 'select' ] .= ', translations.language_code AS language_code_' . esc_sql( $current_language ); // user for per-language caching
84
+
85
+ }elseif(
86
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount' || //sales for the selected items
87
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count' || //purchases for the selected items
88
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__qty.meta_value) as order_item_count, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' || //Get orders and dates in range - main chart: order_item_counts
89
+ $query[ 'select' ] == 'SELECT SUM( order_item_meta__line_total.meta_value) as order_item_amount, posts.post_date as post_date, order_item_meta__product_id.meta_value as product_id' //Get orders and dates in range - main chart: order_item_amounts
90
+
91
+ ){
92
+
93
+ preg_match("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", $query[ 'where' ], $matches);
94
+ $product_ids = array();
95
+ $exp = array_map('trim', explode(',', $matches[1]));
96
+ foreach($exp as $e){
97
+ $product_ids[] = trim($e, "'");
98
+ }
99
+ $all_product_ids = array();
100
+ foreach($product_ids as $product_id){
101
+ $post_type = get_post_type($product_id);
102
+ $trid = $sitepress->get_element_trid($product_id, 'post_'.$post_type);
103
+ $translations = $sitepress->get_element_translations($trid, 'post_'.$post_type, true);
104
+ foreach($translations as $translation){
105
+ $all_product_ids[] = $translation->element_id;
106
+ }
107
+ }
108
+
109
+ $query[ 'where' ] = preg_replace("#order_item_meta__product_id_array\.meta_value IN \(([^\)]+)\)#", "order_item_meta__product_id_array.meta_value IN (" . join(',', $all_product_ids) . ")", $query[ 'where' ]);
110
+
111
+
112
+ }
113
+
114
+ }
115
+
116
+ return $query;
117
+ }
118
+
119
+
120
+ public function combine_report_by_languages($results){
121
+ global $sitepress, $wpdb;
122
+
123
+ if(is_array($results) && isset($results['0']->order_item_qty)){
124
+ $mode = 'top_sellers';
125
+ }elseif(is_array($results) && isset($results['0']->order_item_total)){
126
+ $mode = 'top_earners';
127
+ }elseif(isset($results['0']->sparkline_value)){
128
+ $mode = 'top_sellers_spark';
129
+ }else{
130
+ return $results;
131
+ }
132
+
133
+ if(!isset($results['0']->trid)) return $results;
134
+
135
+ $current_language = $sitepress->get_current_language();
136
+
137
+ $combined_results = array();
138
+
139
+ foreach($results as $k => $row){
140
+
141
+ switch($mode){
142
+ case 'top_sellers':
143
+ case 'top_earners':
144
+ $key = $row->trid;
145
+ break;
146
+ case 'top_sellers_spark':
147
+ $key = $row->trid . '#' . substr($row->post_date, 0, 10);
148
+ break;
149
+ }
150
+
151
+ if($row->order_language == $current_language){
152
+
153
+ $combined_results[$key] = $row;
154
+
155
+ }
156
+
157
+ }
158
+
159
+ foreach($results as $k => $row){
160
+
161
+ if($row->order_language != $current_language){
162
+
163
+ switch($mode){
164
+ case 'top_sellers':
165
+ case 'top_earners':
166
+ $key = $row->trid;
167
+ break;
168
+ case 'top_sellers_spark':
169
+ $key = $row->trid . '#' . substr($row->post_date, 0, 10);
170
+ break;
171
+ }
172
+
173
+ if(isset($combined_results[$key])){
174
+
175
+ switch($mode){
176
+ case 'top_sellers':
177
+ $combined_results[$key]->order_item_qty += $row->order_item_qty;
178
+ break;
179
+ case 'top_earners':
180
+ $combined_results[$key]->order_item_total += $row->order_item_total;
181
+ break;
182
+ case 'top_sellers_spark':
183
+ $combined_results[$key]->sparkline_value += $row->sparkline_value;
184
+ break;
185
+
186
+ }
187
+
188
+ }else{
189
+
190
+ $default_product_id = apply_filters( 'translate_object_id',$row->product_id, 'product', false, $current_language);
191
+
192
+ if($default_product_id){
193
+ $combined_results[$key] = new stdClass();
194
+ $combined_results[$key]->product_id = $default_product_id;
195
+
196
+ switch($mode){
197
+ case 'top_sellers':
198
+ $combined_results[$key]->order_item_qty = $row->order_item_qty;
199
+ break;
200
+ case 'top_earners':
201
+ $combined_results[$key]->order_item_total = $row->order_item_total;
202
+ break;
203
+ case 'top_sellers_spark':
204
+ $combined_results[$key]->sparkline_value = $row->sparkline_value;
205
+ $combined_results[$key]->post_date = $row->post_date;
206
+ break;
207
+ }
208
+
209
+ }
210
+
211
+ }
212
+
213
+
214
+ }
215
+
216
+ }
217
+
218
+ switch($mode){
219
+ case 'top_sellers':
220
+ usort($combined_results, array(__CLASS__, '_order_by_quantity'));
221
+ array_slice($combined_results, 0, 12);
222
+ break;
223
+ case 'top_earners':
224
+ usort($combined_results, array(__CLASS__, '_order_by_total'));
225
+ array_slice($combined_results, 0, 12);
226
+ break;
227
+ case 'top_sellers_spark':
228
+ break;
229
+
230
+
231
+ }
232
+
233
+ foreach($combined_results as $k => $row){
234
+ unset($combined_results[$k]->trid, $combined_results[$k]->order_language);
235
+ }
236
+
237
+
238
+ return $combined_results;
239
+ }
240
+
241
+ private static function _order_by_quantity($a, $b){
242
+ return $a->order_item_qty < $b->order_item_qty;
243
+ }
244
+
245
+ private static function _order_by_total($a, $b){
246
+ return $a->order_item_total < $b->order_item_total;
247
+ }
248
+
249
+ public function filter_reports_stock_query( $query_from ){
250
+ global $wpdb, $sitepress;
251
+
252
+ $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,71 +1,71 @@
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' ] ) ){
36
- if( $_GET['wcml_action'] == 'dismiss' ){
37
- $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
38
- }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
39
- $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
40
- }
41
- $woocommerce_wpml->update_settings();
42
- }
43
-
44
- add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
45
-
46
- // Override cached widget id
47
- add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
48
- }
49
-
50
- function update_settings_from_warning(){
51
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
52
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
53
- die('Invalid nonce');
54
- }
55
- global $woocommerce_wpml;
56
-
57
- $woocommerce_wpml->settings[$_POST['setting']] = 1;
58
- $woocommerce_wpml->update_settings();
59
-
60
- }
61
-
62
- public function override_cached_widget_id( $widget_id ){
63
-
64
- if( defined( 'ICL_LANGUAGE_CODE' ) ){
65
- $widget_id .= ':' . ICL_LANGUAGE_CODE;
66
- }
67
-
68
- return $widget_id;
69
- }
70
-
71
  }
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' ] ) ){
36
+ if( $_GET['wcml_action'] == 'dismiss' ){
37
+ $woocommerce_wpml->settings['dismiss_doc_main'] = 1;
38
+ }elseif( $_GET['wcml_action'] == 'dismiss_tm_warning' ){
39
+ $woocommerce_wpml->settings['dismiss_tm_warning'] = 1;
40
+ }
41
+ $woocommerce_wpml->update_settings();
42
+ }
43
+
44
+ add_action('wp_ajax_wcml_ignore_warning', array( $this, 'update_settings_from_warning') );
45
+
46
+ // Override cached widget id
47
+ add_filter( 'woocommerce_cached_widget_id', array( $this, 'override_cached_widget_id' ) );
48
+ }
49
+
50
+ function update_settings_from_warning(){
51
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
52
+ if(!$nonce || !wp_verify_nonce($nonce, 'wcml_ignore_warning')){
53
+ die('Invalid nonce');
54
+ }
55
+ global $woocommerce_wpml;
56
+
57
+ $woocommerce_wpml->settings[$_POST['setting']] = 1;
58
+ $woocommerce_wpml->update_settings();
59
+
60
+ }
61
+
62
+ public function override_cached_widget_id( $widget_id ){
63
+
64
+ if( defined( 'ICL_LANGUAGE_CODE' ) ){
65
+ $widget_id .= ':' . ICL_LANGUAGE_CODE;
66
+ }
67
+
68
+ return $widget_id;
69
+ }
70
+
71
  }
inc/class-wcml-resources.php CHANGED
@@ -1,229 +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
- 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
  }
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,594 +1,594 @@
1
- <?php
2
-
3
- class WCML_Store_Pages{
4
-
5
- /**
6
- * @var woocommerce_wpml
7
- */
8
- private $woocommerce_wpml;
9
- /**
10
- * @var SitePress
11
- */
12
- private $sitepress;
13
-
14
- function __construct( $woocommerce_wpml, $sitepress ){
15
-
16
- $this->woocommerce_wpml =& $woocommerce_wpml;
17
- $this->sitepress =& $sitepress;
18
-
19
- add_action('init', array($this, 'init'));
20
- add_filter( 'woocommerce_create_pages', array( $this, 'switch_pages_language' ), 9 );
21
- add_filter( 'woocommerce_create_pages', array( $this, 'install_pages_action' ), 11 );
22
- //update wc pages ids after change default language or create new if not exists
23
- add_action( 'icl_after_set_default_language', array( $this, 'after_set_default_language' ), 10, 2 );
24
- // Translate shop page ids
25
- $this->add_filter_to_get_shop_translated_page_id();
26
- add_filter( 'template_include', array( $this, 'template_loader' ), 100 );
27
-
28
- if( is_admin() ){
29
- add_action( 'icl_post_languages_options_before', array( $this, 'show_translate_shop_pages_notice') );
30
- }
31
- }
32
-
33
- function init(){
34
-
35
- if(!is_admin()){
36
- add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
37
- add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
38
- add_filter('parse_request', array($this, 'adjust_shop_page'));
39
- }
40
-
41
- add_filter( 'woocommerce_create_page_id', array( $this, 'check_store_page_id'), 10 ,3 );
42
-
43
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
44
- if (isset($_POST['create_pages']) && wp_verify_nonce($nonce, 'create_pages')) {
45
- $this->create_missing_store_pages_with_redirect();
46
- }
47
-
48
- $this->front_page_id = get_option('page_on_front');
49
- $this->shop_page_id = wc_get_page_id('shop');
50
- $this->shop_page = get_post( $this->shop_page_id );
51
- }
52
-
53
- function switch_pages_language( $pages ){
54
-
55
- $default_language = $this->sitepress->get_default_language();
56
-
57
- if( $this->sitepress->get_current_language() != $default_language ){
58
- foreach( $pages as $key => $page ){
59
-
60
- switch( $key ){
61
- case 'shop':
62
- $page['name'] = 'shop';
63
- $page['title'] = 'Shop';
64
- break;
65
- case 'cart':
66
- $page['name'] = 'cart';
67
- $page['title'] = 'Cart';
68
- break;
69
- case 'checkout':
70
- $page['name'] = 'checkout';
71
- $page['title'] = 'Checkout';
72
- break;
73
- case 'myaccount':
74
- $page['name'] = 'my-account';
75
- $page['title'] = 'My account';
76
- break;
77
- }
78
-
79
- if( $this->sitepress->get_default_language() != 'en' ){
80
- $page['name'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page slug'.$page['name'], $default_language );
81
- $page['title'] = $this->woocommerce_wpml->strings->get_translation_from_woocommerce_mo_file( 'Page title'.$page['title'], $default_language );
82
- }
83
- }
84
- }
85
-
86
- return $pages;
87
- }
88
-
89
- function install_pages_action( $pages ){
90
- global $wpdb;
91
-
92
- foreach( $pages as $key => $page){
93
-
94
- if ( strlen( $page[ 'content' ] ) > 0 ) {
95
- // Search for an existing page with the specified page content (typically a shortcode)
96
- $page_found = $wpdb->get_var( $wpdb->prepare( "
97
- SELECT ID FROM " . $wpdb->posts . " as p
98
- LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
99
- WHERE post_type='page'
100
- AND post_content LIKE %s
101
- AND icl.element_type = 'post_page'
102
- AND icl.language_code = %s LIMIT 1;
103
- ",
104
- "%{$page[ 'content' ]}%", $this->sitepress->get_default_language() ) );
105
- } else {
106
- // Search for an existing page with the specified page slug
107
- $page_found = $wpdb->get_var( $wpdb->prepare( "
108
- SELECT ID FROM " . $wpdb->posts . " as p
109
- LEFT JOIN {$wpdb->prefix}icl_translations AS icl ON icl.element_id = p.id
110
- WHERE post_type='page'
111
- AND post_name = %s
112
- AND icl.element_type = 'post_page'
113
- AND icl.language_code = %s LIMIT 1;
114
- ",
115
- esc_sql( $page['name'] ), $this->sitepress->get_default_language() ) );
116
- }
117
-
118
- if( !$page_found ){
119
- $page_data = array(
120
- 'post_status' => 'publish',
121
- 'post_type' => 'page',
122
- 'post_author' => 1,
123
- 'post_name' => esc_sql( $page['name'] ),
124
- 'post_title' => $page['title'],
125
- 'post_content' => $page['content'],
126
- 'post_parent' => ! empty( $page['parent'] ) ? wc_get_page_id( $page['parent'] ) : '',
127
- 'comment_status' => 'closed'
128
- );
129
- $page_id = wp_insert_post( $page_data );
130
-
131
- if ( 'woocommerce_' . $key . '_page_id' )
132
- update_option( 'woocommerce_' . $key . '_page_id', $page_id );
133
- }
134
-
135
- unset( $pages[ $key ] );
136
- }
137
-
138
- return $pages;
139
- }
140
-
141
- function add_filter_to_get_shop_translated_page_id(){
142
- $woo_pages = array(
143
- 'shop_page_id',
144
- 'cart_page_id',
145
- 'checkout_page_id',
146
- 'myaccount_page_id',
147
- 'lost_password_page_id',
148
- 'edit_address_page_id',
149
- 'view_order_page_id',
150
- 'change_password_page_id',
151
- 'logout_page_id',
152
- 'pay_page_id',
153
- 'thanks_page_id',
154
- 'terms_page_id',
155
- 'review_order_page_id'
156
- );
157
-
158
- foreach($woo_pages as $woo_page){
159
- add_filter('woocommerce_get_'.$woo_page, array($this, 'translate_pages_in_settings'));
160
- //I think following filter not needed because "option_woocommerce_..." not used in Woo, but I need ask David to confirm this
161
- add_filter('option_woocommerce_'.$woo_page, array($this, 'translate_pages_in_settings'));
162
- }
163
-
164
- add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_url'));
165
- }
166
-
167
- function translate_pages_in_settings($id) {
168
- global $pagenow;
169
- if( $pagenow == 'options-permalink.php' || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' ) ){
170
- return $id;
171
- }
172
-
173
- return apply_filters( 'translate_object_id',$id, 'page', true);
174
- }
175
-
176
- /**
177
- * Filters WooCommerce query for translated shop page
178
- *
179
- */
180
- function shop_page_query($q) {
181
- if ( ! $q->is_main_query() )
182
- return;
183
-
184
- //do not alter query_object and query_object_id (part 1 of 2)
185
- global $wp_query;
186
- $queried_object_original = isset($wp_query->queried_object) ? $wp_query->queried_object : null;
187
- $queried_object_id_original = isset($wp_query->queried_object_id) ? $wp_query->queried_object_id : null;
188
-
189
- if (
190
- !empty($this->shop_page) &&
191
- $this->shop_page->post_status == 'publish' &&
192
- !empty($this->front_page_id) &&
193
- $q->get('post_type') != 'product' &&
194
- $q->get('page_id') !== $this->front_page_id &&
195
- $this->shop_page_id == $q->get('page_id')
196
- ){
197
- $q->set( 'post_type', 'product' );
198
- $q->set( 'page_id', '' );
199
- if ( isset( $q->query['paged'] ) )
200
- $q->set( 'paged', $q->query['paged'] );
201
-
202
- // Get the actual WP page to avoid errors
203
- // This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
204
- global $wp_post_types;
205
-
206
- $q->is_page = true;
207
-
208
- $wp_post_types['product']->ID = $this->shop_page->ID;
209
- $wp_post_types['product']->post_title = $this->shop_page->post_title;
210
- $wp_post_types['product']->post_name = $this->shop_page->post_name;
211
-
212
- // Fix conditional functions
213
- $q->is_singular = false;
214
- $q->is_post_type_archive = true;
215
- $q->is_archive = true;
216
- }
217
-
218
- //do not alter query_object and query_object_id (part 2 of 2)
219
- if(is_null($queried_object_original)){
220
- unset($wp_query->queried_object);
221
- }else{
222
- $wp_query->queried_object = $queried_object_original;
223
- }
224
- if(is_null($queried_object_id_original)){
225
- unset($wp_query->queried_object_id);
226
- }else{
227
- $wp_query->queried_object_id = $queried_object_id_original;
228
- }
229
-
230
- }
231
-
232
-
233
- /**
234
- * Translate shop url
235
- */
236
- function translate_ls_shop_url($languages, $debug_mode = false) {
237
-
238
- $shop_id = $this->shop_page_id;
239
- $front_id = apply_filters( 'translate_object_id',$this->front_page_id, 'page');
240
-
241
- foreach ($languages as $language) {
242
- // shop page
243
- // obsolete?
244
- if (is_post_type_archive('product') || $debug_mode ) {
245
- if ($front_id == $shop_id) {
246
- $url = $this->sitepress->language_url($language['language_code']);
247
- } else {
248
- $this->sitepress->switch_lang($language['language_code']);
249
- $url = get_permalink( apply_filters( 'translate_object_id', $shop_id, 'page', true, $language['language_code']) );
250
- $this->sitepress->switch_lang();
251
- }
252
-
253
- $languages[$language['language_code']]['url'] = $url;
254
- }
255
- }
256
-
257
- 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
- }
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,1036 +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 = $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_settings['variations_needed'][$taxonomy] = 0;
440
- }
441
- $wcml_settings['variations_needed'][$taxonomy] += count($objects);
442
-
443
- $this->woocommerce_wpml->update_settings($wcml_settings);
444
-
445
- }
446
- }
447
-
448
- }
449
-
450
- public function sync_taxonomy_translations( $html, $taxonomy, $taxonomy_obj ){
451
-
452
- $is_wcml = is_admin() && $taxonomy && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']);
453
- $is_ajax = is_ajax() && $taxonomy && isset( $_POST['action'] ) && $_POST['action'] === 'wpml_get_terms_and_labels_for_taxonomy_table';
454
- if( $is_wcml || $is_ajax ){
455
-
456
- $sync_tax = new WCML_Sync_Taxonomy( $this->woocommerce_wpml, $taxonomy, $taxonomy_obj );
457
- $html = $sync_tax->get_view();
458
- }
459
-
460
- return $html;
461
- }
462
-
463
- public function wcml_sync_product_variations($taxonomy){
464
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
465
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_product_variations')){
466
- die('Invalid nonce');
467
- }
468
-
469
- $VARIATIONS_THRESHOLD = 20;
470
-
471
- $wcml_settings = $this->woocommerce_wpml->get_settings();
472
- $response = array();
473
-
474
- $taxonomy = filter_input( INPUT_POST, 'taxonomy', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
475
-
476
- $languages_processed = intval( $_POST['languages_processed']);
477
-
478
- $condition = $languages_processed?'>=':'>';
479
-
480
- $where = isset($_POST['last_post_id']) && $_POST['last_post_id'] ? ' ID '.$condition.' ' . intval($_POST['last_post_id']) . ' AND ' : '';
481
-
482
- $post_ids = $this->wpdb->get_col($this->wpdb->prepare("
483
- SELECT DISTINCT tr.object_id
484
- FROM {$this->wpdb->term_relationships} tr
485
- JOIN {$this->wpdb->term_taxonomy} tx on tr.term_taxonomy_id = tx.term_taxonomy_id
486
- JOIN {$this->wpdb->posts} p ON tr.object_id = p.ID
487
- JOIN {$this->wpdb->prefix}icl_translations t ON t.element_id = p.ID
488
- WHERE {$where} tx.taxonomy = %s AND p.post_type = 'product' AND t.element_type='post_product' AND t.language_code = %s
489
- ORDER BY ID ASC
490
-
491
- ", $taxonomy, $this->sitepress->get_default_language()));
492
-
493
- if($post_ids){
494
-
495
- $variations_processed = 0;
496
- $posts_processed = 0;
497
- foreach($post_ids as $post_id){
498
- $terms = wp_get_post_terms($post_id, $taxonomy);
499
- $terms_count = count($terms) . "\n\n";
500
-
501
- $trid = $this->sitepress->get_element_trid($post_id, 'post_product');
502
- $translations = $this->sitepress->get_element_translations($trid, 'post_product');
503
-
504
- $i = 1;
505
-
506
- foreach($translations as $translation){
507
-
508
- if($i > $languages_processed && $translation->element_id != $post_id){
509
- $this->woocommerce_wpml->sync_product_data->sync_product_taxonomies($post_id, $translation->element_id, $translation->language_code);
510
- $this->woocommerce_wpml->sync_variations_data->sync_product_variations($post_id, $translation->element_id, $translation->language_code, false, true);
511
- $this->woocommerce_wpml->translation_editor->create_product_translation_package($post_id,$trid, $translation->language_code,ICL_TM_COMPLETE);
512
- $variations_processed += $terms_count*2;
513
- $response['languages_processed'] = $i;
514
- $i++;
515
- //check if sum of 2 iterations doesn't exceed $VARIATIONS_THRESHOLD
516
- if($variations_processed >= $VARIATIONS_THRESHOLD){
517
- break;
518
- }
519
- }else{
520
- $i++;
521
- }
522
- }
523
- $response['last_post_id'] = $post_id;
524
- if(--$i == count($translations)){
525
- $response['languages_processed'] = 0;
526
- $languages_processed = 0;
527
- }else{
528
- break;
529
- }
530
-
531
- $posts_processed ++;
532
-
533
- }
534
-
535
- $response['go'] = 1;
536
-
537
- }else{
538
-
539
- $response['go'] = 0;
540
-
541
- }
542
-
543
- $response['progress'] = $response['go'] ? sprintf(__('%d products left', 'woocommerce-multilingual'), count($post_ids) - $posts_processed) : __('Synchronization complete!', 'woocommerce-multilingual');
544
-
545
- if($response['go'] && isset($wcml_settings['variations_needed'][$taxonomy]) && !empty($variations_processed)){
546
- $wcml_settings['variations_needed'][$taxonomy] = max($wcml_settings['variations_needed'][$taxonomy] - $variations_processed, 0);
547
- }else{
548
- if($response['go'] == 0){
549
- $wcml_settings['variations_needed'][$taxonomy] = 0;
550
- }
551
- }
552
- $wcml_settings['sync_variations'] = 0;
553
-
554
- $this->woocommerce_wpml->update_settings($wcml_settings);
555
-
556
- echo json_encode($response);
557
- exit;
558
- }
559
-
560
- public function wcml_sync_taxonomies_in_content_preview(){
561
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
562
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content_preview')){
563
- die('Invalid nonce');
564
- }
565
-
566
- global $wp_taxonomies;
567
-
568
- $html = $message = $errors = '';
569
-
570
-
571
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
572
- $object_types = $wp_taxonomies[$_POST['taxonomy']]->object_type;
573
-
574
- foreach($object_types as $object_type){
575
-
576
- $html .= $this->render_assignment_status($object_type, $_POST['taxonomy'], $preview = true);
577
-
578
- }
579
-
580
- }else{
581
- $errors = sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
582
- }
583
-
584
-
585
- echo json_encode(array('html' => $html, 'message'=> $message, 'errors' => $errors));
586
- exit;
587
- }
588
-
589
- public function wcml_sync_taxonomies_in_content(){
590
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
591
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_sync_taxonomies_in_content')){
592
- die('Invalid nonce');
593
- }
594
-
595
- global $wp_taxonomies;
596
-
597
- $html = $message = $errors = '';
598
-
599
- if(isset($wp_taxonomies[$_POST['taxonomy']])){
600
- $html .= $this->render_assignment_status($_POST['post'], $_POST['taxonomy'], $preview = false);
601
-
602
- }else{
603
- $errors .= sprintf(__('Invalid taxonomy %s', 'woocommerce-multilingual'), $_POST['taxonomy']);
604
- }
605
-
606
-
607
- echo json_encode(array('html' => $html, 'errors' => $errors));
608
- exit;
609
- }
610
-
611
- public function render_assignment_status($object_type, $taxonomy, $preview = true){
612
- global $wp_post_types, $wp_taxonomies;
613
-
614
- $default_language = $this->sitepress->get_default_language();
615
-
616
- $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 ) );
617
-
618
- foreach($posts as $post){
619
-
620
- $terms = wp_get_post_terms($post->ID, $taxonomy);
621
-
622
- $term_ids = array();
623
- foreach($terms as $term){
624
- $term_ids[] = $term->term_id;
625
- }
626
-
627
- $trid = $this->sitepress->get_element_trid($post->ID, 'post_' . $post->post_type);
628
- $translations = $this->sitepress->get_element_translations($trid, 'post_' . $post->post_type, true, true);
629
-
630
- foreach($translations as $language => $translation){
631
-
632
- if($language != $default_language && $translation->element_id){
633
-
634
- $terms_of_translation = wp_get_post_terms($translation->element_id, $taxonomy);
635
-
636
- $translation_term_ids = array();
637
- foreach($terms_of_translation as $term){
638
-
639
- $term_id_original = apply_filters( 'translate_object_id',$term->term_id, $taxonomy, false, $default_language );
640
- if(!$term_id_original || !in_array($term_id_original, $term_ids)){
641
- // remove term
642
-
643
- if($preview){
644
- $needs_sync = true;
645
- break(3);
646
- }
647
-
648
- $current_terms = wp_get_post_terms($translation->element_id, $taxonomy);
649
- $updated_terms = array();
650
- foreach($current_terms as $cterm){
651
- if($cterm->term_id != $term->term_id){
652
- $updated_terms[] = $taxonomy != 'product_type' ? $term->term_id : $term->name;
653
- }
654
- if(!$preview){
655
-
656
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
657
- $updated_terms = array_unique( array_map( 'intval', $updated_terms ) );
658
- }
659
-
660
- wp_set_post_terms($translation->element_id, $updated_terms, $taxonomy);
661
- }
662
-
663
- }
664
-
665
- }else{
666
- $translation_term_ids[] = $term_id_original;
667
- }
668
-
669
- }
670
-
671
- foreach($term_ids as $term_id){
672
-
673
- if(!in_array($term_id, $translation_term_ids)){
674
- // add term
675
-
676
- if($preview){
677
- $needs_sync = true;
678
- break(3);
679
- }
680
- $terms_array = array();
681
- $term_id_translated = apply_filters( 'translate_object_id',$term_id, $taxonomy, false, $language);
682
-
683
- // not using get_term
684
- $translated_term = $this->wpdb->get_row($this->wpdb->prepare("
685
- 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));
686
-
687
- if( $translated_term ){
688
- $terms_array[] = $translated_term->term_id;
689
- }
690
-
691
- if(!$preview){
692
-
693
- if( $taxonomy != 'product_type' && !is_taxonomy_hierarchical($taxonomy)){
694
- $terms_array = array_unique( array_map( 'intval', $terms_array ) );
695
- }
696
-
697
- wp_set_post_terms($translation->element_id, $terms_array, $taxonomy, true);
698
- }
699
-
700
- }
701
-
702
- }
703
-
704
- }
705
-
706
- }
707
-
708
- }
709
-
710
- $wcml_settings = $this->woocommerce_wpml->get_settings();
711
- $wcml_settings['sync_'.$taxonomy] = 0;
712
- $this->woocommerce_wpml->update_settings($wcml_settings);
713
-
714
- $out = '';
715
-
716
- if($preview){
717
-
718
- $out .= '<div class="wcml_tt_sync_row">';
719
- if(!empty($needs_sync)){
720
- $out .= '<form class="wcml_tt_do_sync">';
721
- $out .= '<input type="hidden" name="post" value="' . $object_type . '" />';
722
- $out .= wp_nonce_field('wcml_sync_taxonomies_in_content', 'wcml_sync_taxonomies_in_content_nonce',true,false);
723
- $out .= '<input type="hidden" name="taxonomy" value="' . $taxonomy . '" />';
724
- $out .= sprintf(__('Some translated %s have different %s assignments.', 'woocommerce-multilingual'),
725
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>',
726
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>');
727
- $out .= '&nbsp;<a class="submit button-secondary" href="#">' . sprintf(__('Update %s for all translated %s', 'woocommerce-multilingual'),
728
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
729
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>') . '</a>' .
730
- '&nbsp;<img src="'. ICL_PLUGIN_URL . '/res/img/ajax-loader.gif" alt="loading" height="16" width="16" class="wcml_tt_spinner" />';
731
- $out .= "</form>";
732
- }else{
733
- $out .= sprintf(__('All %s have the same %s assignments.', 'woocommerce-multilingual'),
734
- '<strong>' . mb_strtolower($wp_taxonomies[$taxonomy]->labels->name) . '</strong>',
735
- '<strong>' . mb_strtolower($wp_post_types[$object_type]->labels->name) . '</strong>');
736
- }
737
- $out .= "</div>";
738
-
739
- }else{
740
-
741
- $out .= sprintf(__('Successfully updated %s for all translated %s.', 'woocommerce-multilingual'), $wp_taxonomies[$taxonomy]->labels->name, $wp_post_types[$object_type]->labels->name);
742
-
743
- }
744
-
745
- return $out;
746
- }
747
-
748
- function shipping_terms($terms, $post_id, $taxonomy){
749
- global $pagenow;
750
-
751
- if( isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_load_variations' ){
752
- return $terms;
753
- }
754
-
755
- if( $pagenow != 'post.php' && ( get_post_type($post_id) == 'product' || get_post_type($post_id) == 'product_variation' ) && $taxonomy == 'product_shipping_class'){
756
-
757
- remove_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
758
- $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');
759
- add_filter('get_the_terms',array($this,'shipping_terms'), 10, 3);
760
- return $terms;
761
- }
762
-
763
- return $terms;
764
- }
765
-
766
- function filter_coupons_terms($terms, $taxonomies, $args){
767
- global $pagenow;
768
-
769
- 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)){
770
- remove_filter('get_terms',array($this,'filter_coupons_terms'));
771
- $current_language = $this->sitepress->get_current_language();
772
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
773
- $terms = get_terms( 'product_cat', 'orderby=name&hide_empty=0');
774
- add_filter('get_terms',array($this,'filter_coupons_terms'),10,3);
775
- $this->sitepress->switch_lang($current_language);
776
- }
777
-
778
- return $terms;
779
- }
780
-
781
- function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
782
- $is_shipping_settings = isset($_GET['page']) && $_GET['page'] == 'wc-settings' && isset($_GET['tab']) && $_GET['tab'] == 'shipping';
783
- if( is_admin() && in_array( 'product_shipping_class', (array) $taxonomies ) && $is_shipping_settings ){
784
- remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
785
- $current_language = $this->sitepress->get_current_language();
786
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
787
- add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
788
- $terms = get_terms( $taxonomies, $args );
789
- remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
790
- add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
791
- $this->sitepress->switch_lang($current_language);
792
- }
793
-
794
- return $terms;
795
- }
796
-
797
- function wcml_delete_term($term, $tt_id, $taxonomy, $deleted_term){
798
- global $wp_taxonomies;
799
-
800
- foreach($wp_taxonomies as $key=>$taxonomy_obj){
801
- if((in_array('product',$taxonomy_obj->object_type) || in_array('product_variation',$taxonomy_obj->object_type) ) && $key==$taxonomy){
802
- $this->update_terms_translated_status($taxonomy);
803
- break;
804
- }
805
- }
806
-
807
- }
808
-
809
- function get_product_terms_filter( $terms, $product_id, $taxonomy, $args ){
810
-
811
- $language = $this->sitepress->get_language_for_element( $product_id, 'post_'.get_post_type( $product_id ) );
812
-
813
- $is_objects_array = is_object( current ( $terms ) );
814
-
815
- $filtered_terms = array();
816
-
817
- foreach( $terms as $term ){
818
-
819
- if( !$is_objects_array ){
820
- $term_obj = get_term_by( 'name', $term, $taxonomy );
821
- if( !$term_obj ){
822
- $term_obj = get_term_by( 'slug', $term, $taxonomy );
823
- $is_slug = true;
824
- }
825
- }
826
-
827
- if( empty($term_obj) ){
828
- $filtered_terms[] = $term;
829
- continue;
830
- }
831
-
832
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_obj->term_id, $taxonomy, true, $language );
833
-
834
- if( $is_objects_array ){
835
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy );
836
- }else{
837
- if( isset( $is_slug ) ){
838
- $filtered_terms[] = get_term( $trnsl_term_id, $taxonomy )->slug;
839
- }else{
840
- $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;
841
- }
842
- }
843
- }
844
-
845
- return $filtered_terms;
846
- }
847
-
848
-
849
-
850
-
851
- function set_flag_to_sync( $taxonomy, $el_id, $language_code ){
852
-
853
- $elem_details = $this->sitepress->get_element_language_details( $el_id, 'tax_'.$taxonomy );
854
- if( is_null( $elem_details->source_language_code ) )
855
- return;
856
-
857
- $this->check_if_sync_term_translation_needed( $el_id, $taxonomy );
858
-
859
- }
860
-
861
- function check_if_sync_terms_needed(){
862
-
863
- $wcml_settings = $this->woocommerce_wpml->get_settings();
864
- $wcml_settings['sync_variations'] = 0;
865
- $wcml_settings['sync_product_cat'] = 0;
866
- $wcml_settings['sync_product_tag'] = 0;
867
- $wcml_settings['sync_product_shipping_class'] = 0;
868
- $this->woocommerce_wpml->update_settings( $wcml_settings );
869
-
870
- $taxonomies_to_check = array( 'product_cat', 'product_tag', 'product_shipping_class' );
871
-
872
- foreach( $taxonomies_to_check as $check_taxonomy ){
873
- $terms = get_terms( $check_taxonomy, array( 'hide_empty' => false, 'fields' => 'ids' ) );
874
- if (is_array($terms)){
875
- foreach( $terms as $term ){
876
- if( $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], $check_taxonomy ) ){
877
- break;
878
- }
879
- }
880
- }
881
- }
882
-
883
- $attribute_taxonomies = wc_get_attribute_taxonomies();
884
- $flag_set = false;
885
- foreach( $attribute_taxonomies as $a ){
886
-
887
- $terms = get_terms( 'pa_' . $a->attribute_name, array( 'hide_empty' => false, 'fields' => 'ids' ) );
888
- if (is_array($terms)){
889
- foreach( $terms as $term ){
890
- $flag_set = $this->check_if_sync_term_translation_needed( $term[ 'term_taxonomy_id' ], 'pa_' . $a->attribute_name );
891
- if( $flag_set ){
892
- break;
893
- }
894
- }
895
- }
896
-
897
- if( $flag_set ){
898
- break;
899
- }
900
- }
901
-
902
- }
903
-
904
- function check_if_sync_term_translation_needed( $t_id, $taxonomy ){
905
-
906
- $wcml_settings = $this->woocommerce_wpml->get_settings();
907
-
908
- $attribute_taxonomies = wc_get_attribute_taxonomies();
909
- $attribute_taxonomies_arr = array();
910
- foreach($attribute_taxonomies as $a){
911
- $attribute_taxonomies_arr[] = 'pa_' . $a->attribute_name;
912
- }
913
-
914
- 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'] ) ){
915
- return true;
916
- }
917
-
918
- $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 ) );
919
-
920
- foreach( $translations as $key => $translation ){
921
- if ( is_null( $translation->source_language_code ) ) {
922
- $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 ) );
923
- unset( $translations[ $key ] );
924
- }
925
- }
926
-
927
- foreach( $translations as $translation ){
928
-
929
- $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 ) );
930
- if( $original_count != $count ){
931
-
932
- if( in_array( $taxonomy, array( 'product_cat', 'product_tag', 'product_shipping_class' ) ) ){
933
- $wcml_settings[ 'sync_'.$taxonomy ] = 1;
934
- $this->woocommerce_wpml->update_settings($wcml_settings);
935
- return true;
936
- }
937
-
938
- if( isset( $attribute_taxonomies_arr ) && in_array( $taxonomy, $attribute_taxonomies_arr ) ){
939
- $wcml_settings['sync_variations'] = 1;
940
- $this->woocommerce_wpml->update_settings($wcml_settings);
941
- return true;
942
- }
943
-
944
- }
945
-
946
- }
947
-
948
- }
949
-
950
- function get_table_taxonomies( $taxonomies ){
951
-
952
- foreach( $taxonomies as $key => $taxonomy ){
953
- if (substr($key, 0, 3) != 'pa_') {
954
- unset( $taxonomies[$key]);
955
- }
956
- }
957
-
958
- return $taxonomies;
959
- }
960
-
961
- function get_wc_taxonomies(){
962
-
963
- global $wp_taxonomies;
964
- $taxonomies = array();
965
-
966
- //don't use get_taxonomies for product, because when one more post type registered for product taxonomy functions returned taxonomies only for product type
967
- foreach ( $wp_taxonomies as $key => $taxonomy ) {
968
- if (
969
- ( in_array( 'product', $taxonomy->object_type ) || in_array( 'product_variation', $taxonomy->object_type ) ) &&
970
- ! in_array( $key, $taxonomies ) &&
971
- $this->woocommerce_wpml->attributes->is_translatable_attribute( $key )
972
- ) {
973
- $taxonomies[] = $key;
974
- }
975
- }
976
-
977
- return $taxonomies;
978
-
979
- }
980
-
981
- function has_wc_taxonomies_to_translate(){
982
-
983
- $taxonomies = $this->get_wc_taxonomies();
984
-
985
- $no_tax_to_trnls = false;
986
- foreach ( $taxonomies as $taxonomy ){
987
- if ( $taxonomy == 'product_type' || $this->get_untranslated_terms_number( $taxonomy ) == 0 ) {
988
- continue;
989
- } else {
990
- $no_tax_to_trnls = true;
991
- }
992
- }
993
-
994
- return $no_tax_to_trnls;
995
-
996
- }
997
-
998
- /*
999
- * Use custom query, because get_term_by function return false for terms with "0" slug *
1000
- */
1001
- public function wcml_get_term_id_by_slug( $taxonomy, $slug ){
1002
-
1003
- return $this->wpdb->get_var(
1004
- $this->wpdb->prepare(
1005
- "SELECT tt.term_id FROM {$this->wpdb->terms} AS t
1006
- INNER JOIN {$this->wpdb->term_taxonomy} AS tt
1007
- ON t.term_id = tt.term_id
1008
- WHERE tt.taxonomy = %s AND t.slug = %s LIMIT 1",
1009
- $taxonomy, sanitize_title( $slug ) )
1010
- );
1011
- }
1012
-
1013
- public function wcml_get_term_by_id( $term_id, $taxonomy ){
1014
-
1015
- return $this->wpdb->get_row(
1016
- $this->wpdb->prepare("
1017
- SELECT * FROM {$this->wpdb->terms} t
1018
- JOIN {$this->wpdb->term_taxonomy} x
1019
- ON x.term_id = t.term_id
1020
- WHERE t.term_id = %d AND x.taxonomy = %s",
1021
- $term_id, $taxonomy )
1022
- );
1023
- }
1024
-
1025
- public function wcml_get_translated_term( $term_id, $taxonomy, $language ){
1026
-
1027
- $tr_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, false, $language );
1028
-
1029
- if( !is_null( $tr_id ) ) {
1030
- $term_id = $tr_id;
1031
- }
1032
-
1033
- return $this->wcml_get_term_by_id( $term_id, $taxonomy );
1034
- }
1035
-
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->upd