WooCommerce Multilingual – run WooCommerce with WPML - Version 1.3

Version Description

  • Fixed all custom fields synchronization between translations
  • Fixed the stock issue for translations
  • Fixed the price filter widget for multiple currencies feature
  • Fixed product duplication to a second language
  • Payment gateways texts now are translatable
  • Custom variables translations now will be shown in the correct language
Download this release

Release Info

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

Code changes from version 1.2 to 1.3

Files changed (4) hide show
  1. readme.txt +16 -5
  2. woocommerce_wpml.class.php +1190 -0
  3. wpml-config.xml +19 -13
  4. wpml-woocommerce.php +5 -975
readme.txt CHANGED
@@ -3,9 +3,9 @@ Contributors: AmirHelzer, dominykasgel
3
  Donate link: http://wp-types.com
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  Requires at least: 3.0
6
- Tested up to: 3.3.2
7
- Stable tag: 1.2
8
- Version: 1.2
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -29,8 +29,8 @@ Please go to [WooCommerce Multilingual Doc](http://wpml.org/documentation/relate
29
 
30
  You will need:
31
 
32
- * [WooCommerce](http://wordpress.org/extend/plugins/woocommerce/) version 1.4 and up - the actual e-commerce plugin (free)
33
- * [WPML](http://wpml.org) version 2.4.2 and up - the multilingual WordPress plugin (costs $79)
34
 
35
  == Installation ==
36
 
@@ -60,6 +60,14 @@ In order for the checkout and store pages to appear translated, you need to crea
60
 
61
  == Changelog ==
62
 
 
 
 
 
 
 
 
 
63
  = 1.2 =
64
  * Added helpful documentation buttons
65
  * Added makes new attributes translatable automatically
@@ -89,6 +97,9 @@ In order for the checkout and store pages to appear translated, you need to crea
89
 
90
  == Upgrade Notice ==
91
 
 
 
 
92
  = 1.2 =
93
  Added a few improvements and fixed bugs.
94
 
3
  Donate link: http://wp-types.com
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  Requires at least: 3.0
6
+ Tested up to: 3.4.1
7
+ Stable tag: 1.3
8
+ Version: 1.3
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
29
 
30
  You will need:
31
 
32
+ * [WooCommerce](http://wordpress.org/extend/plugins/woocommerce/) version 1.6.5 and up. Please note that the official WooCommerce release might not be 100% compatible. Always check the [development version on wpml.org](http://wpml.org/documentation/related-projects/woocommerce-multilingual/).
33
+ * [WPML](http://wpml.org) version 2.6.0 and up - the multilingual WordPress plugin
34
 
35
  == Installation ==
36
 
60
 
61
  == Changelog ==
62
 
63
+ = 1.3 =
64
+ * Fixed all custom fields synchronization between translations
65
+ * Fixed the stock issue for translations
66
+ * Fixed the price filter widget for multiple currencies feature
67
+ * Fixed product duplication to a second language
68
+ * Payment gateways texts now are translatable
69
+ * Custom variables translations now will be shown in the correct language
70
+
71
  = 1.2 =
72
  * Added helpful documentation buttons
73
  * Added makes new attributes translatable automatically
97
 
98
  == Upgrade Notice ==
99
 
100
+ = 1.3 =
101
+ Fixed compatibility between WooCommerce 1.5.8 and WPML 2.5.2
102
+
103
  = 1.2 =
104
  Added a few improvements and fixed bugs.
105
 
woocommerce_wpml.class.php ADDED
@@ -0,0 +1,1190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class woocommerce_wpml {
3
+
4
+ function __construct(){
5
+ add_action('plugins_loaded', array($this, 'init'), 2);
6
+ }
7
+
8
+ function init(){
9
+ if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
10
+ if(!function_exists('is_multisite') || !is_multisite()) {
11
+ add_action('admin_notices', array($this, 'no_wpml_warning'));
12
+ }
13
+ return false;
14
+ } else if(version_compare(ICL_SITEPRESS_VERSION, '2.0.5', '<')){
15
+ add_action('admin_notices', array($this, 'old_wpml_warning'));
16
+ return false;
17
+ } else if(!class_exists('woocommerce')){
18
+ add_action('admin_notices', array($this, 'no_woocommerce'));
19
+ return false;
20
+ }
21
+
22
+ if(get_option('icl_is_wcml_installed') !== 'yes'){
23
+ add_action('init', array($this, 'wcml_install'));
24
+ }
25
+
26
+ add_action('admin_notices', array($this, 'check_for_incompatible_permalinks'));
27
+
28
+ add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_id'));
29
+ add_filter('woocommerce_get_checkout_page_id', array($this, 'checkout_page_id'));
30
+ add_filter('woocommerce_get_cart_page_id', array($this, 'get_cart_page_id'));
31
+ add_filter('woocommerce_get_myaccount_page_id', array($this, 'get_myaccount_page_id'));
32
+ add_filter('woocommerce_get_edit_address_page_id', array($this, 'get_edit_address_page_id'));
33
+ add_filter('woocommerce_get_view_order_page_id', array($this, 'get_view_order_page_id'));
34
+ add_filter('woocommerce_get_change_password_page_id', array($this, 'get_change_password_page_id'));
35
+ add_filter('woocommerce_get_thanks_page_id', array($this, 'get_thanks_page_id'));
36
+ add_filter('woocommerce_get_shop_page_id', array($this, 'shop_page_id'));
37
+ add_filter('woocommerce_get_pay_page_id', array($this, 'pay_page_id'));
38
+ add_filter('woocommerce_get_checkout_payment_url', array($this, 'get_checkout_payment_url'));
39
+ add_filter('woocommerce_get_cancel_order_url', array($this, 'get_cancel_order_url'));
40
+ add_filter('woocommerce_get_return_url', array($this, 'get_return_url'));
41
+ add_filter('woocommerce_get_remove_url', array($this, 'get_remove_url'));
42
+ add_filter('woocommerce_in_cart_product_title', array($this, 'in_cart_product_title'), 13, 2);
43
+ add_filter('woocommerce_in_cart_product_id', array($this, 'in_cart_product_id'), 11, 2);
44
+ add_filter('woocommerce_params', array($this, 'ajax_params'));
45
+ add_filter('woocommerce_redirect', array($this, 'do_redirect'));
46
+ add_filter('woocommerce_attribute_label', array($this, 'translate_attributes'), 14, 2);
47
+ add_filter('woocommerce_upsell_crosssell_search_products', array($this, 'woocommerce_upsell_crosssell_search_posts'));
48
+ add_filter('icl_post_alternative_languages', array($this, 'post_alternative_languages'));
49
+ add_filter('woocommerce_variation_term_name', array($this, 'variation_term_name'));
50
+ add_filter('woocommerce_gateway_title', array($this, 'gateway_title'), 10);
51
+ add_filter('woocommerce_gateway_raw_description', array($this, 'gateway_description'), 10, 3);
52
+ add_filter('pre_get_posts', array($this, 'shop_page_query'), 10);
53
+ add_filter('woocommerce_json_search_found_products', array($this, 'search_products'));
54
+
55
+ if(get_option('icl_enable_multi_currency') == 'yes'){
56
+ add_filter('raw_woocommerce_price', array($this, 'woocommerce_price'));
57
+ add_filter('woocommerce_currency_symbol', array($this, 'woocommerce_currency_symbol'), 2);
58
+ }
59
+
60
+ add_action('woocommerce_email_header', array($this, 'email_header'), 0);
61
+ add_action('woocommerce_email_footer', array($this, 'email_footer'), 0);
62
+ add_action('localize_woocommerce_on_ajax', array($this, 'localize_on_ajax'));
63
+
64
+ add_action('woocommerce_reduce_order_stock', array($this, 'sync_product_stocks'));
65
+
66
+ add_action('woocommerce_checkout_update_order_meta', array($this, 'order_language'));
67
+
68
+ add_filter('woocommerce_price_filter_min_price', array($this, 'price_filter_min_price'));
69
+ add_filter('woocommerce_price_filter_max_price', array($this, 'price_filter_max_price'));
70
+
71
+ add_action('icl_make_duplicate', array($this, 'synchronize_variations'), 10, 4);
72
+
73
+ add_action('admin_menu', array($this, 'menu'));
74
+ add_action('init', array($this, 'load_css_and_js'));
75
+
76
+ if(is_admin()){
77
+ add_action('admin_init', array($this, 'make_new_attributes_translatable'));
78
+ add_action('admin_init', array($this, 'translate_custom_attributes'));
79
+ }
80
+
81
+ if(isset($_POST['general_options']) && check_admin_referer('general_options', 'general_options_nonce')){
82
+ $enable_multi_currency = (isset($_POST['multi_currency'])) ? trim($_POST['multi_currency']) : null;
83
+
84
+ if($enable_multi_currency == 'yes'){
85
+ add_option('icl_enable_multi_currency', 'yes');
86
+ } else {
87
+ delete_option('icl_enable_multi_currency');
88
+ }
89
+ }
90
+
91
+ if(isset($_POST['add_currency']) && check_admin_referer('add_currency', 'add_currency_nonce')){
92
+ global $wpdb, $pagenow;
93
+
94
+ $language_code = (isset($_POST['language'])) ? trim($_POST['language']) : null;
95
+ $currency_code = (isset($_POST['currency_code'])) ? mb_convert_case(trim($_POST['currency_code']), MB_CASE_UPPER, "UTF-8") : null;
96
+ $exchange_rate = (isset($_POST['exchange_rate'])) ? trim($_POST['exchange_rate']) : null;
97
+ $currency_id = (isset($_POST['currency_id'])) ? trim($_POST['currency_id']) : null;
98
+ $date = date('Y-m-d H:i:s');
99
+
100
+ if($currency_code == ''){
101
+ wp_die(__('<strong>ERROR</strong>: please fill the currency code field.'));
102
+ }
103
+
104
+ if($exchange_rate == ''){
105
+ wp_die(__('<strong>ERROR</strong>: please fill the exchange rate field.'));
106
+ } else if(!is_numeric($exchange_rate)){
107
+ wp_die(__('<strong>ERROR</strong>: please enter the correct exchange rate.'));
108
+ }
109
+
110
+ $result = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*)
111
+ FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '$language_code'"));
112
+
113
+ if($result && !$currency_id){
114
+ add_action('admin_notices', array($this, 'currency_exists_error'));
115
+ } else {
116
+ // Add
117
+ if(!$currency_id){
118
+ $wpdb->insert($wpdb->prefix .'icl_currencies', array(
119
+ 'language_code' => $language_code,
120
+ 'code' => $currency_code,
121
+ 'value' => (double) $exchange_rate,
122
+ 'changed' => $date
123
+ )
124
+ );
125
+
126
+ // Update
127
+ } else {
128
+ $wpdb->update(
129
+ $wpdb->prefix .'icl_currencies',
130
+ array(
131
+ 'code' => $currency_code,
132
+ 'value' => (double) $exchange_rate,
133
+ 'changed' => $date
134
+ ),
135
+ array( 'id' => $currency_id )
136
+ );
137
+
138
+ wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
139
+ }
140
+ }
141
+ }
142
+
143
+ if(isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['delete']) && $_GET['delete'] == $_GET['delete']){
144
+ global $wpdb;
145
+
146
+ $remove_id = $_GET['delete'];
147
+
148
+ $delete = $wpdb->query("DELETE FROM ". $wpdb->prefix ."icl_currencies WHERE id = '$remove_id'");
149
+
150
+ if(!$delete){
151
+ wp_die(__('<strong>ERROR</strong>: currency can not be deleted. Please try again.'));
152
+ }
153
+
154
+ wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
155
+ }
156
+
157
+ add_action('admin_footer', array($this, 'documentation_links'));
158
+ add_action('admin_notices', array($this, 'admin_notice_after_install'));
159
+
160
+ if(isset($_GET['wcml_action']) && $_GET['wcml_action'] = 'dismiss'){
161
+ update_option('wpml_dismiss_doc_main', 'yes');
162
+ }
163
+
164
+ if (defined('DOING_AJAX') && DOING_AJAX){
165
+ do_action('localize_woocommerce_on_ajax');
166
+ }
167
+
168
+ register_deactivation_hook(__FILE__, array($this, 'wcml_deactivate'));
169
+ }
170
+
171
+ /**
172
+ * Adds admin notice.
173
+ */
174
+ function no_wpml_warning(){
175
+ ?>
176
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires <a href="%s">WPML</a> in order to work.', 'plugin woocommerce'),
177
+ 'http://wpml.org/'); ?></p></div>
178
+ <?php
179
+ }
180
+
181
+ /**
182
+ * Adds admin notice.
183
+ */
184
+ function old_wpml_warning(){
185
+ ?>
186
+ <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 2.0.5.', 'plugin woocommerce'),
187
+ 'http://wpml.org/'); ?></p></div>
188
+ <?php
189
+ }
190
+
191
+ /**
192
+ * Adds admin notice.
193
+ */
194
+ function no_woocommerce(){
195
+ ?>
196
+ <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires <a href="%s">WooCommerce</a> in order to work.', 'plugin woocommerce'),
197
+ 'http://www.woothemes.com/woocommerce/'); ?></p></div>
198
+ <?php
199
+ }
200
+
201
+ /**
202
+ * Install the plugin.
203
+ */
204
+ function wcml_install(){
205
+ global $wpdb;
206
+
207
+ add_option('icl_is_wcml_installed', 'yes');
208
+
209
+ $sql = "CREATE TABLE IF NOT EXISTS `". $wpdb->prefix ."icl_currencies` (
210
+ `id` int(11) NOT NULL AUTO_INCREMENT,
211
+ `language_code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
212
+ `code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
213
+ `value` varchar(7) COLLATE utf8_unicode_ci DEFAULT NULL,
214
+ `changed` datetime DEFAULT NULL,
215
+ PRIMARY KEY (`id`)
216
+ )";
217
+
218
+ $install = $wpdb->query($sql);
219
+ }
220
+
221
+ /**
222
+ * For all the urls to work we need either:
223
+ * 1) the shop page slug must be the same in all languages
224
+ * 2) or the shop prefix disabled in woocommerce settings
225
+ * one of these must be true for product urls to work
226
+ * if none of these are true, display a warning message
227
+ */
228
+ function check_for_incompatible_permalinks() {
229
+ global $sitepress;
230
+ // Check if the shop prefix is disabled, if so we are ok
231
+ if (get_option('woocommerce_prepend_shop_page_to_products') != "yes") {
232
+ return;
233
+ }
234
+ // Check if translated shop pages have the same slug
235
+ $shop_page_id = get_option('woocommerce_shop_page_id');
236
+ $slug = get_page($shop_page_id)->post_name;
237
+ $languages = icl_get_languages('skip_missing=0');
238
+ $allsame = true;
239
+ foreach ($languages as $language) {
240
+ if ($language['language_code'] != $sitepress->get_default_language()) {
241
+ $translated_slug = get_page(icl_object_id($shop_page_id, 'page', false, $language['language_code']))->post_name;
242
+ if ($translated_slug != $slug) {
243
+ $allsame = false;
244
+ break;
245
+ }
246
+ }
247
+ }
248
+ if (!$allsame) {
249
+ ?>
250
+ <div class="message error"><p><?php printf(__('If you want different slugs for shop pages, you need to disable the shop prefix for products in <a href="%s">WooCommerce Settings</a>', 'plugin woocommerce'),
251
+ 'admin.php?page=woocommerce_settings&tab=pages'); ?></p></div>
252
+ <?php
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Switch the language on AJAX action, because in some ways the correct language is missing.
258
+ * Fix is for the checkout page review order table texts and the payment gateways table texts, they're loaded on AJAX.
259
+ */
260
+ function localize_on_ajax(){
261
+ global $sitepress;
262
+
263
+ $current_language = $sitepress->get_current_language();
264
+
265
+ $sitepress->switch_lang($current_language, true);
266
+ }
267
+
268
+ /**
269
+ * Filters upsell/crosell products in the correct language.
270
+ */
271
+ function search_products($found_products){
272
+ global $wpdb, $sitepress;
273
+
274
+ $current_page_language = $sitepress->get_current_language();
275
+
276
+ foreach($found_products as $product_id => $output_v){
277
+ $post_data = $wpdb->get_row("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$product_id'");
278
+ $product_language = $post_data->language_code;
279
+
280
+ if($product_language !== $current_page_language){
281
+ unset($found_products[$product_id]);
282
+ }
283
+ }
284
+
285
+ return $found_products;
286
+ }
287
+
288
+ /**
289
+ * Filters WooCommerce checkout link.
290
+ */
291
+ function get_checkout_page_id(){
292
+ return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
293
+ }
294
+
295
+ /**
296
+ * Filters WooCommerce checkout page id.
297
+ */
298
+ function checkout_page_id(){
299
+ return icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true);
300
+ }
301
+
302
+ /**
303
+ * Filters WooCommerce cart link.
304
+ */
305
+ function get_cart_page_id() {
306
+ return icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
307
+ }
308
+
309
+ /**
310
+ * Filters WooCommerce my account link.
311
+ */
312
+ function get_myaccount_page_id(){
313
+ return icl_object_id(get_option('woocommerce_myaccount_page_id'), 'page', true);
314
+ }
315
+
316
+ /**
317
+ * Filters WooCommerce my account edit address link.
318
+ */
319
+ function get_edit_address_page_id(){
320
+ return icl_object_id(get_option('woocommerce_edit_address_page_id'), 'page', true);
321
+ }
322
+
323
+ /**
324
+ * Filters WooCommerce view order link.
325
+ */
326
+ function get_view_order_page_id(){
327
+ // avoid redirect to the my account page
328
+ if(get_option('woocommerce_view_order_page_id') !== get_option('woocommerce_checkout_page_id')){
329
+ $return = icl_object_id(get_option('woocommerce_view_order_page_id'), 'page', true);
330
+ } else {
331
+ $return = false;
332
+ }
333
+
334
+ return $return;
335
+ }
336
+
337
+ /**
338
+ * Filters WooCommerce my account change password link.
339
+ */
340
+ function get_change_password_page_id(){
341
+ return icl_object_id(get_option('woocommerce_change_password_page_id'), 'page', true);
342
+ }
343
+
344
+ /**
345
+ * Filters WooCommerce thanks link.
346
+ */
347
+ function get_thanks_page_id(){
348
+ return icl_object_id(get_option('woocommerce_thanks_page_id'), 'page', true);
349
+ }
350
+
351
+ /**
352
+ * Filters WooCommerce shop link.
353
+ */
354
+ function shop_page_id(){
355
+ return icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
356
+ }
357
+
358
+ /**
359
+ * Filters WooCommerce pay page id
360
+ */
361
+ function pay_page_id(){
362
+ $is_cart_page = icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
363
+
364
+ if(is_page($is_cart_page)){
365
+ //return
366
+ } else {
367
+ return icl_object_id(get_option('woocommerce_pay_page_id'), 'page', true);
368
+ }
369
+ }
370
+
371
+ /**
372
+ * Filters WooCommerce payment link for unpaid - pending orders.
373
+ *
374
+ * @global type $sitepress
375
+ * @param type $link
376
+ * @return type
377
+ */
378
+ function get_checkout_payment_url($link){
379
+ global $sitepress;
380
+ return $sitepress->convert_url($link);
381
+ }
382
+
383
+ /**
384
+ * Filters WooCommerce cancel order.
385
+ *
386
+ * @global type $sitepress
387
+ * @param type $link
388
+ * @return type
389
+ */
390
+ function get_cancel_order_url($link){
391
+ global $sitepress;
392
+ return $sitepress->convert_url($link);
393
+ }
394
+
395
+ /**
396
+ * Filters WooCommerce return URL after payment.
397
+ *
398
+ * @global type $sitepress
399
+ * @param type $link
400
+ * @return type
401
+ */
402
+ function get_return_url($link){
403
+ global $sitepress;
404
+ return $sitepress->convert_url($link);
405
+ }
406
+
407
+ /**
408
+ * Filters WooCommerce product remove link.
409
+ *
410
+ * @param type $link
411
+ * @return type
412
+ */
413
+ function get_remove_url($link){
414
+ // outputs raw
415
+ return $link;
416
+ }
417
+
418
+ /**
419
+ * After email translation switch language to default.
420
+ *
421
+ * @param type $title
422
+ * @param $_product
423
+ * @return type
424
+ */
425
+ function in_cart_product_title($title, $_product){
426
+ $product_id = icl_object_id($_product['product_id'], 'product', false, ICL_LANGUAGE_CODE);
427
+
428
+ if($product_id){
429
+ $title = get_the_title($product_id);
430
+ }
431
+
432
+ return $title;
433
+ }
434
+
435
+ /**
436
+ * Adjusts WooCommerce product ID to be added in cart (original product ID).
437
+ *
438
+ * @param type $product_id
439
+ * @return type
440
+ */
441
+ function in_cart_product_id($product_id) {
442
+ return icl_object_id($product_id, 'product', true);
443
+ }
444
+
445
+ /**
446
+ * Filters WooCommerce AJAX params
447
+ *
448
+ * @global type $sitepress
449
+ * @global type $post
450
+ * @param type $value
451
+ * @return type
452
+ */
453
+ function ajax_params($value){
454
+ global $sitepress, $post;
455
+
456
+ if(!isset($post->ID)){
457
+ $post->ID = null;
458
+ }
459
+
460
+ if($sitepress->get_current_language() !== $sitepress->get_default_language()){
461
+ $value['checkout_url'] = admin_url('admin-ajax.php?action=woocommerce-checkout&lang=' . ICL_LANGUAGE_CODE);
462
+ $value['ajax_url'] = admin_url('admin-ajax.php?lang=' . ICL_LANGUAGE_CODE);
463
+ }
464
+
465
+ $checkout_page_id = get_option('woocommerce_checkout_page_id');
466
+ $pay_page_id = get_option('woocommerce_pay_page_id');
467
+ $cart_page_id = get_option('woocommerce_cart_page_id');
468
+
469
+ $translated_checkout_page_id = icl_object_id($checkout_page_id, 'page', false);
470
+ $translated_pay_page_id = icl_object_id($pay_page_id, 'page', false);
471
+ $translated_cart_page_id = icl_object_id($cart_page_id, 'page', false);
472
+
473
+ if($translated_cart_page_id == $post->ID){
474
+ $value['is_cart'] = 1;
475
+ } else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
476
+ $value['is_checkout'] = 1;
477
+
478
+ $value['locale'] = '';
479
+
480
+ $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
481
+
482
+ } else if($translated_pay_page_id == $post->ID){
483
+ $value['is_pay_page'] = 1;
484
+ }
485
+
486
+ return $value;
487
+ }
488
+
489
+ /**
490
+ * Filters WooCommerce redirect location.
491
+ *
492
+ * @global type $sitepress
493
+ * @param type $link
494
+ * @return type
495
+ */
496
+ function do_redirect($link){
497
+ global $sitepress;
498
+ return $sitepress->convert_url($link);
499
+ }
500
+
501
+ /**
502
+ * Translates attributes names.
503
+ *
504
+ * @param type $name
505
+ * @return type
506
+ */
507
+ function translate_attributes($name){
508
+ if(function_exists('icl_register_string')){
509
+ icl_register_string('woocommerce', $name .'_attribute', $name);
510
+
511
+ $name = icl_t('woocommerce', $name .'_attribute', $name);
512
+ }
513
+
514
+ return $name;
515
+ }
516
+
517
+ /**
518
+ * Takes off translated products from the Up-sells/Cross-sells tab.
519
+ *
520
+ * @global type $sitepress
521
+ * @global type $wpdb
522
+ * @return type
523
+ */
524
+ function woocommerce_upsell_crosssell_search_posts($posts){
525
+ global $sitepress, $wpdb;
526
+
527
+ foreach($posts as $key => $post){
528
+ $post_id = $posts[$key]->ID;
529
+ $post_data = $wpdb->get_row("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$post_id'", ARRAY_A);
530
+
531
+ if($post_data['language_code'] !== $sitepress->get_current_language()){
532
+ unset($posts[$key]);
533
+ }
534
+ }
535
+
536
+ return $posts;
537
+ }
538
+
539
+ /**
540
+ * Avoids the post translation links on the product post type.
541
+ *
542
+ * @global type $post
543
+ * @return type
544
+ */
545
+ function post_alternative_languages($output){
546
+ global $post;
547
+
548
+ $post_type = get_post_type($post->ID);
549
+ $checkout_page_id = wpml_checkout_page_id();
550
+
551
+ if($post_type == 'product' || is_page($checkout_page_id)){
552
+ $output = '';
553
+ }
554
+
555
+ return $output;
556
+ }
557
+
558
+ /**
559
+ * Translates custom attribute/variation title.
560
+ *
561
+ * @return type
562
+ */
563
+ function variation_term_name($term_name){
564
+ if(function_exists('icl_t')){
565
+ $term_name = icl_t('woocommerce', $term_name .'_attribute_name', $term_name);
566
+ }
567
+
568
+ return $term_name;
569
+ }
570
+
571
+ /**
572
+ * Translates the payment gateway title text.
573
+ *
574
+ * @return type
575
+ */
576
+ function gateway_title($title){
577
+
578
+ if(function_exists('icl_t')){
579
+ $translated_title = icl_t('woocommerce', $title .'_gateway_title', $title);
580
+ }
581
+
582
+ if(!$translated_title){
583
+
584
+ if(function_exists('icl_register_string')){
585
+ icl_register_string('woocommerce', $title .'_gateway_title', $title);
586
+ }
587
+
588
+ } else {
589
+
590
+ return $translated_title;
591
+
592
+ }
593
+
594
+ return $title;
595
+ }
596
+
597
+ /**
598
+ * Translates the payment gateway description text.
599
+ *
600
+ * @return type
601
+ */
602
+ function gateway_description($description, $description_raw, $gateway_title){
603
+
604
+ if(function_exists('icl_t')){
605
+ $translated_description = icl_t('woocommerce', $gateway_title .'_gateway_description', $description_raw);
606
+ }
607
+
608
+ if(!$translated_description){
609
+
610
+ if(function_exists('icl_register_string')){
611
+ icl_register_string('woocommerce', $gateway_title .'_gateway_description', $description_raw);
612
+ }
613
+
614
+ } else {
615
+
616
+ return $translated_description;
617
+ }
618
+
619
+ return $description;
620
+ }
621
+
622
+ /**
623
+ * Filters WooCommerce query for translated shop page
624
+ *
625
+ */
626
+ function shop_page_query($q) {
627
+ if ( ! $q->is_main_query() )
628
+ return;
629
+
630
+ $shop_page_id = get_option('woocommerce_shop_page_id');
631
+ $translated_shop_page_id = icl_object_id($shop_page_id, 'page', false);
632
+ if (!empty($translated_shop_page_id) && $translated_shop_page_id == $q->get('page_id')) {
633
+ $q->set( 'post_type', 'product' );
634
+ $q->set( 'page_id', '' );
635
+ if ( isset( $q->query['paged'] ) )
636
+ $q->set( 'paged', $q->query['paged'] );
637
+
638
+ // Fix conditional functions
639
+ $q->is_singular = false;
640
+ $q->is_archive = true;
641
+ }
642
+ return $q;
643
+ }
644
+
645
+ /**
646
+ * Filters the currency symbol.
647
+ */
648
+ function woocommerce_currency_symbol($currency_symbol){
649
+ global $sitepress, $wpdb;
650
+
651
+ $sql = "SELECT (code) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
652
+ $db_currency = $wpdb->get_results($sql, OBJECT);
653
+
654
+ if($db_currency){
655
+ $currency = $db_currency[0]->code;
656
+ $currencies = array('BRL', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'ZAR', 'CZK', 'THB', 'GBP');
657
+
658
+ if(in_array($currency, $currencies)){
659
+ switch ($currency) :
660
+ case 'BRL' : $currency_symbol = 'R&#36;'; break;
661
+ case 'USD' : $currency_symbol = '&#36;'; break;
662
+ case 'EUR' : $currency_symbol = '&euro;'; break;
663
+ case 'JPY' : $currency_symbol = '&yen;'; break;
664
+ case 'TRY' : $currency_symbol = 'TL'; break;
665
+ case 'NOK' : $currency_symbol = 'kr'; break;
666
+ case 'ZAR' : $currency_symbol = 'R'; break;
667
+ case 'CZK' : $currency_symbol = '&#75;&#269;'; break;
668
+ case 'GBP' : $currency_symbol = '&pound;'; break;
669
+ endswitch;
670
+ } else {
671
+ $currency_symbol = $currency;
672
+ }
673
+ }
674
+
675
+ return $currency_symbol;
676
+ }
677
+
678
+ /**
679
+ * Filters the product price.
680
+ */
681
+ function woocommerce_price($price){
682
+ global $sitepress, $wpdb;
683
+
684
+ $sql = "SELECT (value) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
685
+ $currency = $wpdb->get_results($sql, OBJECT);
686
+
687
+ if($currency){
688
+ $exchange_rate = $currency[0]->value;
689
+ $price = $price * $exchange_rate;
690
+
691
+ $price = apply_filters('woocommerce_multilingual_price', $price);
692
+ }
693
+
694
+ return $price;
695
+ }
696
+
697
+ /**
698
+ * Translates WooCommerce emails.
699
+ *
700
+ * @global type $sitepress
701
+ * @global type $order_id
702
+ * @return type
703
+ */
704
+ function email_header() {
705
+ global $sitepress, $order_id;
706
+
707
+ $lang = get_post_meta($order_id, 'wpml_language', TRUE);
708
+
709
+ if(empty($lang)){
710
+ if(isset($_SESSION['wpml_globalcart_language'])){
711
+ $lang = $_SESSION['wpml_globalcart_language'];
712
+ } else {
713
+ $lang = $sitepress->get_current_language();
714
+ }
715
+ }
716
+
717
+ $sitepress->switch_lang($lang, true);
718
+ }
719
+
720
+ /**
721
+ * After email translation switch language to default.
722
+ *
723
+ * @global type $sitepress
724
+ * @return type
725
+ */
726
+ function email_footer() {
727
+ global $sitepress;
728
+
729
+ $sitepress->switch_lang();
730
+ }
731
+
732
+ /*
733
+ Only when translated products are ordered, force adjusting stuck information for all translations
734
+ When a product in the default language is ordered stocks are adjusted automatically
735
+ */
736
+ function sync_product_stocks($order){
737
+ global $sitepress;
738
+ $order_id = $order->id;
739
+ $order_language = get_post_meta($order_id, 'wpml_language', true);
740
+
741
+ if($sitepress->get_default_language() != $order_language){
742
+ $items = $order->items;
743
+ foreach($items as $item){
744
+
745
+ if (isset($item['variation_id']) && $item['variation_id']>0){
746
+ $_product = new WC_Product_Variation( $item['variation_id'] );
747
+ }else{
748
+ $_product = new WC_Product( $item['id'] );
749
+ }
750
+
751
+ // Out of stock attribute
752
+ if ($_product->managing_stock() && !$_product->backorders_allowed() && $_product->get_total_stock()<=0){
753
+ $outofstock = 'outofstock';
754
+ }else{
755
+ $outofstock = false;
756
+ }
757
+
758
+
759
+ if ( $_product && $_product->exists() && $_product->managing_stock() ) {
760
+
761
+ $trid = $sitepress->get_element_trid($_product->id, 'post_product');
762
+ $translations = $sitepress->get_element_translations($trid, 'post_product', true);
763
+
764
+ $stock = get_post_meta($_product->id, '_stock', true);
765
+ $total_sales = get_post_meta($_product->id, 'total_sales', true);
766
+
767
+ foreach($translations as $translation){
768
+ if($translation->element_id != $_product->id){
769
+ update_post_meta($translation->element_id, '_stock', $stock);
770
+ update_post_meta($translation->element_id, 'total_sales', $total_sales);
771
+ if($outofstock){
772
+ update_post_meta($translation->element_id, '_stock_status', 'outofstock');
773
+ }
774
+ }
775
+ }
776
+
777
+ }
778
+
779
+ }
780
+ }
781
+
782
+ }
783
+
784
+ /**
785
+ * Adds language to order post type.
786
+ *
787
+ * Language was stored in the session created on checkout page.
788
+ * See params().
789
+ *
790
+ * @param type $order_id
791
+ */
792
+ function order_language($order_id) {
793
+ if(!get_post_meta($order_id, 'wpml_language')){
794
+ $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
795
+ update_post_meta($order_id, 'wpml_language', $language);
796
+ }
797
+ }
798
+
799
+ /**
800
+ * Filters the minimum price of price filter widget, when the multi-currency feature is enabled.
801
+ *
802
+ * @param type $min_price
803
+ * @global type $sitepress
804
+ * @global type $wpdb
805
+ * @return type
806
+ */
807
+ function price_filter_min_price($min_price){
808
+ global $sitepress, $wpdb;
809
+
810
+ if(get_option('icl_enable_multi_currency') == 'yes'){
811
+ $sql = "SELECT (value) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
812
+ $currency = $wpdb->get_results($sql, OBJECT);
813
+
814
+ if($currency){
815
+ $exchange_rate = $currency[0]->value;
816
+ $min_price = $min_price / $exchange_rate;
817
+ $min_price = round($min_price);
818
+ }
819
+ }
820
+
821
+ return $min_price;
822
+ }
823
+
824
+ /**
825
+ * Filters the maximum price of price filter widget, when the multi-currency feature is enabled.
826
+ *
827
+ * @param type $min_price
828
+ * @global type $sitepress
829
+ * @global type $wpdb
830
+ * @return type
831
+ */
832
+ function price_filter_max_price($max_price){
833
+ global $sitepress, $wpdb;
834
+
835
+ if(get_option('icl_enable_multi_currency') == 'yes'){
836
+ $sql = "SELECT (value) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
837
+ $currency = $wpdb->get_results($sql, OBJECT);
838
+
839
+ if($currency){
840
+ $exchange_rate = $currency[0]->value;
841
+ $max_price = $max_price / $exchange_rate;
842
+ $max_price = round($max_price);
843
+ }
844
+ }
845
+
846
+ return $max_price;
847
+ }
848
+
849
+ /**
850
+ * If upsell and crosell products exists for the product, filter them for translations.
851
+ * Sync attributes and variations during product duplication.
852
+ * Sync: term relationship, post meta, post variations, post variations meta.
853
+ *
854
+ * @global type $wpdb
855
+ * @global type $pagenow
856
+ * @global type $post
857
+ * @return type
858
+ */
859
+ function synchronize_variations($duplicated_post_id, $lang, $postarr, $post_id) {
860
+ global $wpdb, $pagenow, $sitepress;
861
+
862
+ $post_type = @get_post_type($post_id);
863
+
864
+ $ajax_call = (!empty($_POST['icl_ajx_action']) && $_POST['icl_ajx_action'] == 'make_duplicates');
865
+
866
+ // Filter upsell and crosell products for translations
867
+ if(($pagenow == 'post.php' || $ajax_call ) && $post_type == 'product'){
868
+
869
+ $original_product_upsell_ids = get_post_meta($duplicated_post_id, '_upsell_ids', TRUE);
870
+ $original_product_crosssell_ids = get_post_meta($duplicated_post_id, '_crosssell_ids', TRUE);
871
+
872
+ if(!empty($original_product_upsell_ids)){
873
+ $unserialized_upsell_ids = maybe_unserialize($original_product_upsell_ids);
874
+
875
+ foreach($unserialized_upsell_ids as $k => $product_id){
876
+ // get the correct language
877
+ $upsell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
878
+
879
+ if($upsell_product_translation_id){
880
+ $unserialized_upsell_ids[$k] = $upsell_product_translation_id;
881
+ // if it isn't translated - unset it
882
+ } else {
883
+ unset($unserialized_upsell_ids[$k]);
884
+ }
885
+ }
886
+
887
+ update_post_meta($post_id, '_upsell_ids', $unserialized_upsell_ids);
888
+ }
889
+
890
+ if(!empty($original_product_crosssell_ids)){
891
+ $unserialized_crosssell_ids = maybe_unserialize($original_product_crosssell_ids);
892
+
893
+ foreach($unserialized_crosssell_ids as $k => $product_id){
894
+ // get the correct language
895
+ $crosssell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
896
+
897
+ if($crosssell_product_translation_id){
898
+ $unserialized_crosssell_ids[$k] = $crosssell_product_translation_id;
899
+ // if it isn't translated - unset it
900
+ } else {
901
+ unset($unserialized_crosssell_ids[$k]);
902
+ }
903
+ }
904
+
905
+ update_post_meta($post_id, '_crosssell_ids', $unserialized_crosssell_ids);
906
+ }
907
+
908
+ }
909
+
910
+ if( ($pagenow == 'post.php' || $ajax_call ) && $post_type == 'product' && !empty($duplicated_post_id)){
911
+
912
+ $get_variation_term_name = $wpdb->get_results("SELECT * FROM $wpdb->terms WHERE name = 'variable'");
913
+ $get_variation_term_id = $get_variation_term_name[0]->term_id;
914
+
915
+ $is_post_has_variations = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id' AND term_taxonomy_id = '$get_variation_term_id'");
916
+ if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
917
+
918
+ // synchronize term data, postmeta and post variations
919
+ if($is_post_has_variations){
920
+ // synchronize post variations
921
+ $get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
922
+ WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
923
+
924
+ foreach($get_all_post_variations as $k => $post_data){
925
+ $duplicated_post_variation_ids[] = $post_data->ID;
926
+ }
927
+
928
+ foreach($get_all_post_variations as $k => $post_data){
929
+ // Find if this has already been duplicated
930
+ $variation_id = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta WHERE meta_key = '_wcml_duplicate_of_variation' AND meta_value = '$post_data->ID'");
931
+
932
+ if (!empty($variation_id)) {
933
+ // Update variation
934
+ $wpdb->update( $wpdb->posts, array(
935
+ 'post_author' => $post_data->post_author,
936
+ 'post_date_gmt' => $post_data->post_date_gmt,
937
+ 'post_content' => $post_data->post_content,
938
+ 'post_title' => $post_data->post_title,
939
+ 'post_excerpt' => $post_data->post_excerpt,
940
+ 'post_status' => $post_data->post_status,
941
+ 'comment_status' => $post_data->comment_status,
942
+ 'ping_status' => $post_data->ping_status,
943
+ 'post_password' => $post_data->post_password,
944
+ 'post_name' => $post_data->post_name,
945
+ 'to_ping' => $post_data->to_ping,
946
+ 'pinged' => $post_data->pinged,
947
+ 'post_modified' => $post_data->post_modified,
948
+ 'post_modified_gmt' => $post_data->post_modified_gmt,
949
+ 'post_content_filtered' => $post_data->post_content_filtered,
950
+ 'post_parent' => $post_id, // current post ID
951
+ 'menu_order' => $post_data->menu_order,
952
+ 'post_type' => $post_data->post_type,
953
+ 'post_mime_type' => $post_data->post_mime_type,
954
+ 'comment_count' => $post_data->comment_count
955
+ ), array('ID' => $variation_id));
956
+ } else {
957
+ // Add new variation
958
+ $guid = $post_data->guid;
959
+ $replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
960
+ $wpdb->insert( $wpdb->posts, array(
961
+ 'post_author' => $post_data->post_author,
962
+ 'post_date_gmt' => $post_data->post_date_gmt,
963
+ 'post_content' => $post_data->post_content,
964
+ 'post_title' => $post_data->post_title,
965
+ 'post_excerpt' => $post_data->post_excerpt,
966
+ 'post_status' => $post_data->post_status,
967
+ 'comment_status' => $post_data->comment_status,
968
+ 'ping_status' => $post_data->ping_status,
969
+ 'post_password' => $post_data->post_password,
970
+ 'post_name' => $post_data->post_name,
971
+ 'to_ping' => $post_data->to_ping,
972
+ 'pinged' => $post_data->pinged,
973
+ 'post_modified' => $post_data->post_modified,
974
+ 'post_modified_gmt' => $post_data->post_modified_gmt,
975
+ 'post_content_filtered' => $post_data->post_content_filtered,
976
+ 'post_parent' => $post_id, // current post ID
977
+ 'guid' => $replaced_guid,
978
+ 'menu_order' => $post_data->menu_order,
979
+ 'post_type' => $post_data->post_type,
980
+ 'post_mime_type' => $post_data->post_mime_type,
981
+ 'comment_count' => $post_data->comment_count
982
+ ));
983
+ update_post_meta($wpdb->insert_id, '_wcml_duplicate_of_variation', $post_data->ID);
984
+ }
985
+ }
986
+
987
+ $get_current_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
988
+ WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$post_id'");
989
+
990
+ // Delete variations that no longer exist
991
+ foreach ($get_current_post_variations as $post_data) {
992
+ $variation_id = get_post_meta($post_data->ID, '_wcml_duplicate_of_variation', true);
993
+ if (!in_array($variation_id, $duplicated_post_variation_ids)) {
994
+ wp_delete_post($id, true);
995
+ }
996
+ }
997
+
998
+ // synchronize post variations post meta
999
+ foreach($get_current_post_variations as $k => $post_data){
1000
+ $current_post_variation_ids[] = $post_data->ID;
1001
+ }
1002
+
1003
+ foreach($duplicated_post_variation_ids as $dp_key => $duplicated_post_variation_id){
1004
+ $get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_variation_id'");
1005
+
1006
+ foreach($get_all_post_meta as $k => $post_meta){
1007
+ $meta_key = $post_meta->meta_key;
1008
+ $meta_value = $post_meta->meta_value;
1009
+
1010
+ // adjust the global attribute slug in the custom field
1011
+ if (substr($meta_key, 0, 10) == 'attribute_') {
1012
+ $tax = substr($meta_key, 10);
1013
+ $attid = get_term_by('slug', $meta_value, $tax)->term_id;
1014
+ $attid = icl_object_id($attid, $tax, true, $lang);
1015
+ $meta_value = get_term_by('id', $attid, $tax)->slug;
1016
+ }
1017
+
1018
+ // update current post variations meta
1019
+ update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
1020
+ }
1021
+ }
1022
+ }
1023
+ }
1024
+ }
1025
+
1026
+ /**
1027
+ * Creates WCML page.
1028
+ */
1029
+ function menu(){
1030
+ $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
1031
+
1032
+ add_submenu_page($top_page, __('WooCommerce Multilingual','wpml-wcml'),
1033
+ __('WooCommerce Multilingual', 'wpml-wcml'), 'manage_options', 'wpml-wcml', array($this, 'menu_content'));
1034
+ }
1035
+
1036
+ /**
1037
+ * Creates WCML page content.
1038
+ */
1039
+ function menu_content(){
1040
+ include WCML_PLUGIN_PATH . '/menu/management.php';
1041
+ }
1042
+
1043
+ /**
1044
+ * Adds additional CSS and JS.
1045
+ */
1046
+ function load_css_and_js() {
1047
+ wp_enqueue_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array(), WCML_VERSION);
1048
+
1049
+ wp_enqueue_script(
1050
+ 'jquery-validate',
1051
+ plugin_dir_url(__FILE__) . '/assets/js/jquery.validate.min.js',
1052
+ array('jquery'),
1053
+ '1.8.1',
1054
+ true
1055
+ );
1056
+ }
1057
+
1058
+ /**
1059
+ * Makes all new attributes translatable.
1060
+ */
1061
+ function make_new_attributes_translatable(){
1062
+ if(isset($_GET['page']) && $_GET['page'] == 'woocommerce_attributes'){
1063
+
1064
+ $wpml_settings = get_option('icl_sitepress_settings');
1065
+
1066
+ $get_all_taxonomies = get_taxonomies();
1067
+
1068
+ foreach($get_all_taxonomies as $tax_key => $taxonomy){
1069
+ $pos = strpos($taxonomy, 'pa_');
1070
+
1071
+ // get only product attribute taxonomy name
1072
+ if($pos !== false){
1073
+ $wpml_settings['taxonomies_sync_option'][$taxonomy] = 1;
1074
+ }
1075
+ }
1076
+
1077
+ update_option('icl_sitepress_settings', $wpml_settings);
1078
+ }
1079
+ }
1080
+
1081
+ /**
1082
+ * Registers custom attribute/variation title for translation.
1083
+ *
1084
+ * @global type $wpdb
1085
+ * @return type
1086
+ */
1087
+ function translate_custom_attributes(){
1088
+ global $wpdb;
1089
+
1090
+ $all_variations = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'product_variation'");
1091
+
1092
+ $attribute_meta_keys = $wpdb->get_results("SELECT DISTINCT(meta_value) FROM $wpdb->postmeta WHERE meta_key LIKE 'attribute_%'");
1093
+
1094
+ foreach($attribute_meta_keys as $k => $meta){
1095
+ $variation_name = $meta->meta_value;
1096
+
1097
+ if(function_exists('icl_register_string')){
1098
+ icl_register_string('woocommerce', $variation_name .'_attribute_name', $variation_name);
1099
+ }
1100
+ }
1101
+ }
1102
+
1103
+ /**
1104
+ * Adds admin notice.
1105
+ */
1106
+ function currency_exists_error(){
1107
+ ?>
1108
+ <div class="message error"><p><?php echo __('Currency of the selected language already exists.', 'wpml-wcml'); ?></p></div>
1109
+ <?php
1110
+ }
1111
+
1112
+ /**
1113
+ * Outputs documentation links.
1114
+ */
1115
+ function documentation_links(){
1116
+ global $post, $pagenow;
1117
+
1118
+ $get_post_type = get_post_type(@$post->ID);
1119
+
1120
+ if($get_post_type == 'product' && $pagenow == 'edit.php'){
1121
+ $prot_link = '<span class="button" style="padding:4px;margin-top:10px;"><img align="baseline" src="' . ICL_PLUGIN_URL .'/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_products" target="_blank">' .
1122
+ __('How to translate products', 'sitepress') . '<\/a>' . '<\/span>'
1123
+ ?>
1124
+ <script type="text/javascript">
1125
+ jQuery(".subsubsub").append('<?php echo $prot_link ?>');
1126
+ </script>
1127
+ <?php
1128
+ }
1129
+
1130
+ if(isset($_GET['taxonomy'])){
1131
+ $pos = strpos($_GET['taxonomy'], 'pa_');
1132
+
1133
+ if($pos !== false && $pagenow == 'edit-tags.php'){
1134
+ $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="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_attributes" target="_blank" style="text-decoration: none;">' .
1135
+ __('How to translate attributes', 'sitepress') . '<\/a>' . '<\/span><br \/><br \/>'
1136
+ ?>
1137
+ <script type="text/javascript">
1138
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
1139
+ </script>
1140
+ <?php
1141
+ }
1142
+ }
1143
+
1144
+ if(isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat'){
1145
+
1146
+ $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="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_product_categories" target="_blank" style="text-decoration: none;">' .
1147
+ __('How to translate product categories', 'sitepress') . '<\/a>' . '<\/span><br \/><br \/>'
1148
+ ?>
1149
+ <script type="text/javascript">
1150
+ jQuery("table.widefat").before('<?php echo $prot_link ?>');
1151
+ </script>
1152
+ <?php
1153
+ }
1154
+ }
1155
+
1156
+ /**
1157
+ * Admin notice after plugin install.
1158
+ */
1159
+ function admin_notice_after_install(){
1160
+ if(get_option('wpml_dismiss_doc_main') != 'yes'){
1161
+
1162
+ $url = $_SERVER['REQUEST_URI'];
1163
+ $pos = strpos($url, '?');
1164
+
1165
+ if($pos !== false){
1166
+ $url .= '&wcml_action=dismiss';
1167
+ } else {
1168
+ $url .= '?wcml_action=dismiss';
1169
+ }
1170
+ ?>
1171
+ <div id="message" class="updated message fade" style="clear:both;margin-top:5px;"><p>
1172
+ <?php _e('Would you like to see a quick overview?', 'sitepress'); ?>
1173
+ </p>
1174
+ <p>
1175
+ <a class="button-primary" href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/" target="_blank">Learn how to turn your e-commerce site multilingual</a>
1176
+ <a class="button-secondary" href="<?php echo $url; ?>">Dismiss</a>
1177
+ </p>
1178
+ </div>
1179
+ <?php
1180
+ }
1181
+ }
1182
+
1183
+ /**
1184
+ * WooCommerce Multilingual deactivation hook.
1185
+ */
1186
+ function wcml_deactivate(){
1187
+ delete_option('wpml_dismiss_doc_main');
1188
+ }
1189
+
1190
+ }
wpml-config.xml CHANGED
@@ -8,7 +8,6 @@
8
  <custom-field action="copy">keywords</custom-field>
9
  <custom-field action="copy">length</custom-field>
10
  <custom-field action="copy">price</custom-field>
11
- <custom-field action="copy">product_attributes</custom-field>
12
  <custom-field action="copy">regular_price</custom-field>
13
  <custom-field action="copy">sale_price</custom-field>
14
  <custom-field action="copy">sale_price_dates_from</custom-field>
@@ -28,20 +27,23 @@
28
  <custom-field action="copy">weight</custom-field>
29
  <custom-field action="copy">width</custom-field>
30
  <custom-field action="copy">total_sales</custom-field>
 
31
  <custom-field action="copy">_default_attributes</custom-field>
 
32
  <custom-field action="copy">_download_limit</custom-field>
33
- <custom-field action="copy">_height</custom-field>
34
  <custom-field action="copy">_featured</custom-field>
 
 
35
  <custom-field action="copy">_length</custom-field>
36
  <custom-field action="copy">_manage_stock</custom-field>
37
  <custom-field action="copy">_max_variation_price</custom-field>
38
- <custom-field action="copy">_max_variation_regular_price</custom-field>
39
  <custom-field action="copy">_max_variation_sale_price</custom-field>
40
- <custom-field action="copy">_min_variation_price</custom-field>
41
  <custom-field action="copy">_min_variation_regular_price</custom-field>
42
  <custom-field action="copy">_min_variation_sale_price</custom-field>
43
- <custom-field action="copy">_price</custom-field>
44
- <custom-field action="copy">_product_attributes</custom-field>
45
  <custom-field action="copy">_regular_price</custom-field>
46
  <custom-field action="copy">_sale_price</custom-field>
47
  <custom-field action="copy">_sale_price_dates_from</custom-field>
@@ -50,24 +52,28 @@
50
  <custom-field action="copy">_stock</custom-field>
51
  <custom-field action="copy">_stock_status</custom-field>
52
  <custom-field action="copy">_tax_class</custom-field>
53
- <custom-field action="copy">_tax_status</custom-field>
 
54
  <custom-field action="copy">_virtual</custom-field>
55
  <custom-field action="copy">_visibility</custom-field>
56
  <custom-field action="copy">_weight</custom-field>
57
  <custom-field action="copy">_width</custom-field>
58
- <custom-field action="copy">_file_path</custom-field>
59
- <custom-field action="copy">_thumbnail_id</custom-field>
 
 
 
60
  </custom-fields>
61
  <custom-types>
62
  <custom-type translate="1">product</custom-type>
63
- <custom-type translate="1">product_variation</custom-type>
64
  <custom-type translate="0">shop_order</custom-type>
65
  </custom-types>
66
  <taxonomies>
67
  <taxonomy translate="1">product_cat</taxonomy>
68
- <taxonomy translate="1">product_type</taxonomy>
69
  <taxonomy translate="0">shop_order_status</taxonomy>
70
- <taxonomy translate="1">link_category</taxonomy>
71
  <taxonomy translate="1">product_tag</taxonomy>
 
72
  </taxonomies>
73
- </wpml-config>
8
  <custom-field action="copy">keywords</custom-field>
9
  <custom-field action="copy">length</custom-field>
10
  <custom-field action="copy">price</custom-field>
 
11
  <custom-field action="copy">regular_price</custom-field>
12
  <custom-field action="copy">sale_price</custom-field>
13
  <custom-field action="copy">sale_price_dates_from</custom-field>
27
  <custom-field action="copy">weight</custom-field>
28
  <custom-field action="copy">width</custom-field>
29
  <custom-field action="copy">total_sales</custom-field>
30
+ <custom-field action="copy">_backorders</custom-field>
31
  <custom-field action="copy">_default_attributes</custom-field>
32
+ <custom-field action="copy">_downloadable</custom-field>
33
  <custom-field action="copy">_download_limit</custom-field>
 
34
  <custom-field action="copy">_featured</custom-field>
35
+ <custom-field action="copy">_file_path</custom-field>
36
+ <custom-field action="copy">_height</custom-field>
37
  <custom-field action="copy">_length</custom-field>
38
  <custom-field action="copy">_manage_stock</custom-field>
39
  <custom-field action="copy">_max_variation_price</custom-field>
40
+ <custom-field action="copy">_max_variation_regular_price</custom-field>
41
  <custom-field action="copy">_max_variation_sale_price</custom-field>
42
+ <custom-field action="copy">_min_variation_price</custom-field>
43
  <custom-field action="copy">_min_variation_regular_price</custom-field>
44
  <custom-field action="copy">_min_variation_sale_price</custom-field>
45
+ <custom-field action="copy">_price</custom-field>
46
+ <custom-field action="copy">_purchase_note</custom-field>
47
  <custom-field action="copy">_regular_price</custom-field>
48
  <custom-field action="copy">_sale_price</custom-field>
49
  <custom-field action="copy">_sale_price_dates_from</custom-field>
52
  <custom-field action="copy">_stock</custom-field>
53
  <custom-field action="copy">_stock_status</custom-field>
54
  <custom-field action="copy">_tax_class</custom-field>
55
+ <custom-field action="copy">_tax_status</custom-field>
56
+ <custom-field action="copy">_thumbnail_id</custom-field>
57
  <custom-field action="copy">_virtual</custom-field>
58
  <custom-field action="copy">_visibility</custom-field>
59
  <custom-field action="copy">_weight</custom-field>
60
  <custom-field action="copy">_width</custom-field>
61
+ <custom-field action="copy">_woocommerce_exclude_image</custom-field>
62
+ <custom-field action="copy">_wp_attached_file</custom-field>
63
+ <custom-field action="copy">_product_attributes</custom-field>
64
+ <custom-field action="copy">_upsell_ids</custom-field>
65
+ <custom-field action="copy">_crosssell_ids</custom-field>
66
  </custom-fields>
67
  <custom-types>
68
  <custom-type translate="1">product</custom-type>
69
+ <custom-type translate="0">product_variation</custom-type>
70
  <custom-type translate="0">shop_order</custom-type>
71
  </custom-types>
72
  <taxonomies>
73
  <taxonomy translate="1">product_cat</taxonomy>
74
+ <taxonomy translate="0">product_type</taxonomy>
75
  <taxonomy translate="0">shop_order_status</taxonomy>
 
76
  <taxonomy translate="1">product_tag</taxonomy>
77
+ <taxonomy translate="1">product_shipping_class</taxonomy>
78
  </taxonomies>
79
+ </wpml-config>
wpml-woocommerce.php CHANGED
@@ -5,984 +5,14 @@
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
- Version: 1.2
9
  */
10
 
11
- define('WCML_VERSION', '1.2');
 
12
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
13
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
14
  define('WCML_PLUGIN_URL', plugins_url() . '/' . WCML_PLUGIN_FOLDER);
15
 
16
- add_action('plugins_loaded', 'wpml_woocommerce_multilingual_init', 2);
17
-
18
- function wpml_woocommerce_multilingual_init(){
19
- if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
20
- if(!function_exists('is_multisite') || !is_multisite()) {
21
- add_action('admin_notices', 'wpml_no_wpml_warning');
22
- }
23
- return false;
24
- } else if(version_compare(ICL_SITEPRESS_VERSION, '2.0.5', '<')){
25
- add_action('admin_notices', 'wpml_old_wpml_warning');
26
- return false;
27
- } else if(!class_exists('woocommerce')){
28
- add_action('admin_notices', 'wpml_no_woocommerce');
29
- return false;
30
- }
31
-
32
- if(get_option('icl_is_wcml_installed') !== 'yes'){
33
- add_action('init', 'wpml_install');
34
- }
35
-
36
- // Filters WPML language switcher
37
- add_filter('icl_ls_languages', 'wpml_ls_filter');
38
-
39
- add_filter('woocommerce_get_checkout_url', 'wpml_get_checkout_page_id');
40
- add_filter('woocommerce_get_checkout_page_id', 'wpml_checkout_page_id');
41
- add_filter('woocommerce_get_cart_page_id', 'wpml_get_cart_page_id');
42
- add_filter('woocommerce_get_myaccount_page_id', 'wpml_get_myaccount_page_id');
43
- add_filter('woocommerce_get_edit_address_page_id', 'wpml_get_edit_address_page_id');
44
- add_filter('woocommerce_get_view_order_page_id', 'wpml_get_view_order_page_id');
45
- add_filter('woocommerce_get_change_password_page_id', 'wpml_get_change_password_page_id');
46
- add_filter('woocommerce_get_thanks_page_id', 'wpml_get_thanks_page_id');
47
- add_filter('woocommerce_get_shop_page_id', 'wpml_shop_page_id');
48
- add_filter('woocommerce_get_pay_page_id', 'wpml_pay_page_id');
49
- add_filter('woocommerce_get_checkout_payment_url', 'wpml_get_checkout_payment_url');
50
- add_filter('woocommerce_get_cancel_order_url', 'wpml_get_cancel_order_url');
51
- add_filter('woocommerce_get_return_url', 'wpml_get_return_url');
52
- add_filter('woocommerce_get_remove_url', 'wpml_get_remove_url');
53
-
54
- add_filter('woocommerce_in_cart_product_title', 'wpml_in_cart_product_title', 13, 2);
55
- add_filter('woocommerce_in_cart_product_id', 'wpml_in_cart_product_id', 11, 2);
56
-
57
- add_filter('woocommerce_params', 'wpml_ajax_params');
58
- add_filter('woocommerce_redirect', 'wpml_do_redirect');
59
- add_filter('woocommerce_attribute_label', 'wpml_translate_attributes', 14, 2);
60
- add_filter('woocommerce_upsell_crosssell_search_products', 'wpml_woocommerce_upsell_crosssell_search_posts');
61
- add_filter('icl_post_alternative_languages', 'wpml_post_alternative_languages');
62
- add_filter('wp_head', 'wpml_redirect_to_the_base_page');
63
-
64
- if(get_option('icl_enable_multi_currency') == 'yes'){
65
- add_filter('raw_woocommerce_price', 'wpml_woocommerce_price');
66
- add_filter('woocommerce_currency_symbol', 'wpml_woocommerce_currency_symbol', 2);
67
- }
68
-
69
- add_action('woocommerce_email_header', 'wpml_email_header', 0);
70
- add_action('woocommerce_email_footer', 'wpml_email_footer', 0);
71
- add_action('woocommerce_new_order', 'wpml_order_language');
72
- add_action('updated_post_meta', 'wpml_updated_post_meta_hook', 10, 4);
73
-
74
- add_action('admin_head', 'wpml_synchronizate_variations', 15);
75
-
76
- add_action('admin_menu', 'wpml_menu');
77
- //add_action('init', 'wpml_change_permalinks');
78
- add_action('init', 'wpml_load_css_and_js');
79
-
80
- if(is_admin()){
81
- add_action('admin_init', 'wpml_make_new_attributes_translatable');
82
- }
83
-
84
- if(isset($_POST['general_options']) && check_admin_referer('general_options', 'general_options_nonce')){
85
- $enable_multi_currency = (isset($_POST['multi_currency'])) ? trim($_POST['multi_currency']) : null;
86
-
87
- if($enable_multi_currency == 'yes'){
88
- add_option('icl_enable_multi_currency', 'yes');
89
- } else {
90
- delete_option('icl_enable_multi_currency');
91
- }
92
- }
93
-
94
- if(isset($_POST['add_currency']) && check_admin_referer('add_currency', 'add_currency_nonce')){
95
- global $wpdb, $pagenow;
96
-
97
- $language_code = (isset($_POST['language'])) ? trim($_POST['language']) : null;
98
- $currency_code = (isset($_POST['currency_code'])) ? mb_convert_case(trim($_POST['currency_code']), MB_CASE_UPPER, "UTF-8") : null;
99
- $exchange_rate = (isset($_POST['exchange_rate'])) ? trim($_POST['exchange_rate']) : null;
100
- $currency_id = (isset($_POST['currency_id'])) ? trim($_POST['currency_id']) : null;
101
- $date = date('Y-m-d H:i:s');
102
-
103
- if($currency_code == ''){
104
- wp_die(__('<strong>ERROR</strong>: please fill the currency code field.'));
105
- }
106
-
107
- if($exchange_rate == ''){
108
- wp_die(__('<strong>ERROR</strong>: please fill the exchange rate field.'));
109
- } else if(!is_numeric($exchange_rate)){
110
- wp_die(__('<strong>ERROR</strong>: please enter the correct exchange rate.'));
111
- }
112
-
113
- $result = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*)
114
- FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '$language_code'"));
115
-
116
- if($result && !$currency_id){
117
- add_action('admin_notices', 'wpml_currency_exists_error');
118
- } else {
119
- // Add
120
- if(!$currency_id){
121
- $wpdb->insert($wpdb->prefix .'icl_currencies', array(
122
- 'language_code' => $language_code,
123
- 'code' => $currency_code,
124
- 'value' => (double) $exchange_rate,
125
- 'changed' => $date
126
- )
127
- );
128
-
129
- // Update
130
- } else {
131
- $wpdb->update(
132
- $wpdb->prefix .'icl_currencies',
133
- array(
134
- 'code' => $currency_code,
135
- 'value' => (double) $exchange_rate,
136
- 'changed' => $date
137
- ),
138
- array( 'id' => $currency_id )
139
- );
140
-
141
- wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
142
- }
143
- }
144
- }
145
-
146
- if(isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['delete']) && $_GET['delete'] == $_GET['delete']){
147
- global $wpdb;
148
-
149
- $remove_id = $_GET['delete'];
150
-
151
- $delete = $wpdb->query("DELETE FROM ". $wpdb->prefix ."icl_currencies WHERE id = '$remove_id'");
152
-
153
- if(!$delete){
154
- wp_die(__('<strong>ERROR</strong>: currency can not be deleted. Please try again.'));
155
- }
156
-
157
- wp_safe_redirect(admin_url('admin.php?page=wpml-wcml'));
158
- }
159
-
160
- add_action('admin_footer', 'documentation_links');
161
- add_action('admin_notices', 'admin_notice_after_install');
162
-
163
- if(isset($_GET['wcml_action']) && $_GET['wcml_action'] = 'dismiss'){
164
- update_option('wpml_dismiss_doc_main', 'yes');
165
- }
166
-
167
- register_deactivation_hook(__FILE__, 'wpml_wcml_deactivate');
168
- }
169
-
170
- /**
171
- * WooCommerce Multilingual deactivation hook.
172
- */
173
- function wpml_wcml_deactivate(){
174
- delete_option('wpml_dismiss_doc_main');
175
- }
176
-
177
- /**
178
- * Outputs documentation links.
179
- */
180
- function documentation_links(){
181
- global $post, $pagenow;
182
-
183
- $get_post_type = get_post_type(@$post->ID);
184
-
185
- if($get_post_type == 'product' && $pagenow == 'edit.php'){
186
- $prot_link = '<span class="button" style="padding:4px;margin-top:10px;"><img align="baseline" src="' . ICL_PLUGIN_URL .'/res/img/icon16.png" width="16" height="16" style="margin-bottom:-4px" /> <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_products" target="_blank">' .
187
- __('How to translate products', 'sitepress') . '<\/a>' . '<\/span>'
188
- ?>
189
- <script type="text/javascript">
190
- jQuery(".subsubsub").append('<?php echo $prot_link ?>');
191
- </script>
192
- <?php
193
- }
194
-
195
- if(isset($_GET['taxonomy'])){
196
- $pos = strpos($_GET['taxonomy'], 'pa_');
197
-
198
- if($pos !== false && $pagenow == 'edit-tags.php'){
199
- $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="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_attributes" target="_blank" style="text-decoration: none;">' .
200
- __('How to translate attributes', 'sitepress') . '<\/a>' . '<\/span><br \/><br \/>'
201
- ?>
202
- <script type="text/javascript">
203
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
204
- </script>
205
- <?php
206
- }
207
- }
208
-
209
- if(isset($_GET['taxonomy']) && $_GET['taxonomy'] == 'product_cat'){
210
-
211
- $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="http://wpml.org/documentation/related-projects/woocommerce-multilingual/#translating_product_categories" target="_blank" style="text-decoration: none;">' .
212
- __('How to translate product categories', 'sitepress') . '<\/a>' . '<\/span><br \/><br \/>'
213
- ?>
214
- <script type="text/javascript">
215
- jQuery("table.widefat").before('<?php echo $prot_link ?>');
216
- </script>
217
- <?php
218
- }
219
- }
220
-
221
- /**
222
- * Admin notice after plugin install.
223
- */
224
- function admin_notice_after_install(){
225
- if(get_option('wpml_dismiss_doc_main') != 'yes'){
226
-
227
- $url = $_SERVER['REQUEST_URI'];
228
- $pos = strpos($url, '?');
229
-
230
- if($pos !== false){
231
- $url .= '&wcml_action=dismiss';
232
- } else {
233
- $url .= '?wcml_action=dismiss';
234
- }
235
- ?>
236
- <div id="message" class="updated message fade" style="clear:both;margin-top:5px;"><p>
237
- <?php _e('Would you like to see a quick overview?', 'sitepress'); ?>
238
- </p>
239
- <p>
240
- <a class="button-primary" href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/" target="_blank">Learn how to turn your e-commerce site multilingual</a>
241
- <a class="button-secondary" href="<?php echo $url; ?>">Dismiss</a>
242
- </p>
243
- </div>
244
- <?php
245
- }
246
- }
247
-
248
- /**
249
- * Makes all new attributes as translatable.
250
- */
251
- function wpml_make_new_attributes_translatable(){
252
- if(isset($_GET['page']) && $_GET['page'] == 'woocommerce_attributes'){
253
-
254
- $wpml_settings = get_option('icl_sitepress_settings');
255
-
256
- $get_all_taxonomies = get_taxonomies(@$args['name']);
257
-
258
- foreach($get_all_taxonomies as $tax_key => $taxonomy){
259
- $pos = strpos($taxonomy, 'pa_');
260
-
261
- // get only product attribute taxonomy name
262
- if($pos !== false){
263
- foreach($wpml_settings['taxonomies_sync_option'] as $wpml_tax_key => $tax){
264
- // set it as translatable
265
- $wpml_settings['taxonomies_sync_option'][$taxonomy] = 1;
266
- }
267
- }
268
- }
269
-
270
- update_option('icl_sitepress_settings', $wpml_settings);
271
-
272
- }
273
- }
274
-
275
- /**
276
- * Filters the product price.
277
- */
278
- function wpml_woocommerce_price($price){
279
- global $sitepress, $wpdb;
280
-
281
- $sql = "SELECT (value) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
282
- $currency = $wpdb->get_results($sql, OBJECT);
283
-
284
- if($currency){
285
- $exchange_rate = $currency[0]->value;
286
- $price = $price * $exchange_rate;
287
-
288
- $price = apply_filters('woocommerce_multilingual_price', $price);
289
- }
290
-
291
- return $price;
292
- }
293
-
294
- /**
295
- * Filters the currency symbol.
296
- */
297
- function wpml_woocommerce_currency_symbol($currency_symbol){
298
- global $sitepress, $wpdb;
299
-
300
- $sql = "SELECT (code) FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
301
- $db_currency = $wpdb->get_results($sql, OBJECT);
302
-
303
- if($db_currency){
304
- $currency = $db_currency[0]->code;
305
- $currencies = array('BRL', 'USD', 'EUR', 'JPY', 'TRY', 'NOK', 'ZAR', 'CZK', 'THB', 'GBP');
306
-
307
- if(in_array($currency, $currencies)){
308
- switch ($currency) :
309
- case 'BRL' : $currency_symbol = 'R&#36;'; break;
310
- case 'USD' : $currency_symbol = '&#36;'; break;
311
- case 'EUR' : $currency_symbol = '&euro;'; break;
312
- case 'JPY' : $currency_symbol = '&yen;'; break;
313
- case 'TRY' : $currency_symbol = 'TL'; break;
314
- case 'NOK' : $currency_symbol = 'kr'; break;
315
- case 'ZAR' : $currency_symbol = 'R'; break;
316
- case 'CZK' : $currency_symbol = '&#75;&#269;'; break;
317
- case 'GBP' : $currency_symbol = '&pound;'; break;
318
- endswitch;
319
- } else {
320
- $currency_symbol = $currency;
321
- }
322
- }
323
-
324
- return $currency_symbol;
325
- }
326
-
327
- /**
328
- * Install the plugin.
329
- */
330
- function wpml_install(){
331
- global $wpdb;
332
-
333
- add_option('icl_is_wcml_installed', 'yes');
334
-
335
- $sql = "CREATE TABLE IF NOT EXISTS `". $wpdb->prefix ."icl_currencies` (
336
- `id` int(11) NOT NULL AUTO_INCREMENT,
337
- `language_code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
338
- `code` varchar(7) COLLATE utf8_unicode_ci NOT NULL,
339
- `value` varchar(7) COLLATE utf8_unicode_ci DEFAULT NULL,
340
- `changed` datetime DEFAULT NULL,
341
- PRIMARY KEY (`id`)
342
- )";
343
-
344
- $install = $wpdb->query($sql);
345
- }
346
-
347
- /**
348
- * Adds admin notice.
349
- */
350
- function wpml_no_wpml_warning(){
351
- ?>
352
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires <a href="%s">WPML</a> in order to work.', 'plugin woocommerce'),
353
- 'http://wpml.org/'); ?></p></div>
354
- <?php
355
- }
356
-
357
- /**
358
- * Adds admin notice.
359
- */
360
- function wpml_old_wpml_warning(){
361
- ?>
362
- <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 2.0.5.', 'plugin woocommerce'),
363
- 'http://wpml.org/'); ?></p></div>
364
- <?php
365
- }
366
-
367
- /**
368
- * Adds admin notice.
369
- */
370
- function wpml_no_woocommerce(){
371
- ?>
372
- <div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires <a href="%s">WooCommerce</a> in order to work.', 'plugin woocommerce'),
373
- 'http://www.woothemes.com/woocommerce/'); ?></p></div>
374
- <?php
375
- }
376
-
377
- /**
378
- * Adds admin notice.
379
- */
380
- function wpml_currency_exists_error(){
381
- ?>
382
- <div class="message error"><p><?php echo __('Currency of the selected language already exists.', 'wpml-wcml'); ?></p></div>
383
- <?php
384
- }
385
-
386
- /**
387
- * Filters WooCommerce product link in cart.
388
- *
389
- * @param type $url
390
- * @param type $product_id
391
- * @return type
392
- */
393
- function wpml_add_to_cart_product_id($url, $product_id) {
394
- return get_permalink(icl_object_id($product_id, 'product', true));
395
- }
396
-
397
- /**
398
- * Adjusts WooCommerce product ID to be added in cart (original product ID).
399
- *
400
- * @param type $product_id
401
- * @return type
402
- */
403
- function wpml_in_cart_product_id($product_id) {
404
- return icl_object_id($product_id, 'product', true);
405
- }
406
-
407
- /**
408
- * Synchronizes post meta 'stock' and 'stock_status' betweeen translated posts.
409
- *
410
- * @global type $sitepress
411
- * @param type $meta_id
412
- * @param type $object_id
413
- * @param type $meta_key
414
- * @param type $_meta_value
415
- */
416
- function wpml_updated_post_meta_hook($meta_id, $object_id, $meta_key, $_meta_value) {
417
- global $sitepress;
418
-
419
- $update_meta_keys = array('stock', 'stock_status');
420
-
421
- if (in_array($meta_key, $update_meta_keys)) {
422
- $translations = $sitepress->get_element_translations($object_id, 'product');
423
-
424
- foreach($translations as $t){
425
- if(!$t->original){
426
- if($meta_key == 'stock'){
427
- update_post_meta($t->translation_id, 'stock', $_meta_value);
428
- } else if($meta_key = 'stock_status'){
429
- update_post_meta($t->translation_id, 'stock_status', $_meta_value);
430
- }
431
- }
432
- }
433
- }
434
- }
435
-
436
- /**
437
- * Filters WooCommerce navigation menu translated shop page link (redirect to store).
438
- *
439
- * @global type $post
440
- * @global type $sitepress
441
- */
442
- function wpml_redirect_to_the_base_page(){
443
- global $post, $sitepress;
444
-
445
- $shop_page_id = get_option('woocommerce_shop_page_id');
446
- $translated_shop_page_id = icl_object_id($shop_page_id, 'page', false);
447
-
448
- if(is_page(array($translated_shop_page_id, $shop_page_id))){
449
- wp_safe_redirect($sitepress->convert_url(get_option('home') . '/?post_type=product'));
450
- }
451
- }
452
-
453
- /**
454
- * Filters WooCommerce cancel order.
455
- *
456
- * @global type $sitepress
457
- * @param type $link
458
- * @return type
459
- */
460
- function wpml_get_cancel_order_url($link){
461
- global $sitepress;
462
- return $sitepress->convert_url($link);
463
- }
464
-
465
- /**
466
- * Filters WooCommerce return URL after payment.
467
- *
468
- * @global type $sitepress
469
- * @param type $link
470
- * @return type
471
- */
472
- function wpml_get_return_url($link){
473
- global $sitepress;
474
- return $sitepress->convert_url($link);
475
- }
476
-
477
- /**
478
- * Filters WooCommerce redirect location.
479
- *
480
- * @global type $sitepress
481
- * @param type $link
482
- * @return type
483
- */
484
- function wpml_do_redirect($link){
485
- global $sitepress;
486
- return $sitepress->convert_url($link);
487
- }
488
-
489
- /**
490
- * Filters WooCommerce shop link.
491
- */
492
- function wpml_shop_page_id(){
493
- return icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
494
- }
495
-
496
- /**
497
- * Filters WooCommerce thanks link.
498
- */
499
- function wpml_get_thanks_page_id(){
500
- return icl_object_id(get_option('woocommerce_thanks_page_id'), 'page', true);
501
- }
502
-
503
- /**
504
- * Filters WooCommerce checkout page id.
505
- */
506
- function wpml_checkout_page_id(){
507
- return icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true);
508
- }
509
-
510
- /**
511
- * Filters WooCommerce payment link for unpaid - pending orders.
512
- *
513
- * @global type $sitepress
514
- * @param type $link
515
- * @return type
516
- */
517
- function wpml_get_checkout_payment_url($link){
518
- global $sitepress;
519
- return $sitepress->convert_url($link);
520
- }
521
-
522
- /**
523
- * Filters WooCommerce my account link.
524
- */
525
- function wpml_get_myaccount_page_id(){
526
- return icl_object_id(get_option('woocommerce_myaccount_page_id'), 'page', true);
527
- }
528
-
529
- /**
530
- * Filters WooCommerce my account edit address link.
531
- */
532
- function wpml_get_edit_address_page_id(){
533
- return icl_object_id(get_option('woocommerce_edit_address_page_id'), 'page', true);
534
- }
535
-
536
- /**
537
- * Filters WooCommerce view order link.
538
- */
539
- function wpml_get_view_order_page_id(){
540
- // avoid redirect to the my account page
541
- if(get_option('woocommerce_view_order_page_id') !== get_option('woocommerce_checkout_page_id')){
542
- $return = icl_object_id(get_option('woocommerce_view_order_page_id'), 'page', true);
543
- } else {
544
- $return = false;
545
- }
546
-
547
- return $return;
548
- }
549
-
550
- /**
551
- * Filters WooCommerce my account change password link.
552
- */
553
- function wpml_get_change_password_page_id(){
554
- return icl_object_id(get_option('woocommerce_change_password_page_id'), 'page', true);
555
- }
556
-
557
- /**
558
- * Filters WooCommerce pay page id
559
- */
560
- function wpml_pay_page_id(){
561
- $is_cart_page = icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
562
-
563
- if(is_page($is_cart_page)){
564
- //return
565
- } else {
566
- return icl_object_id(get_option('woocommerce_pay_page_id'), 'page', true);
567
- }
568
- }
569
-
570
- /**
571
- * Filters WooCommerce checkout link.
572
- */
573
- function wpml_get_checkout_page_id(){
574
- return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
575
- }
576
-
577
- /**
578
- * Filters WooCommerce cart link.
579
- */
580
- function wpml_get_cart_page_id() {
581
- return icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
582
- }
583
-
584
- /**
585
- * Filters WooCommerce product remove link.
586
- *
587
- * @param type $link
588
- * @return type
589
- */
590
- function wpml_get_remove_url($link){
591
- // outputs raw
592
- return $link;
593
- }
594
-
595
- /**
596
- * Filters WooCommerce AJAX params
597
- *
598
- * @global type $sitepress
599
- * @global type $post
600
- * @param type $value
601
- * @return type
602
- */
603
- function wpml_ajax_params($value){
604
- global $sitepress, $post;
605
-
606
- if(!isset($post->ID)){
607
- $post->ID = null;
608
- }
609
-
610
- if($sitepress->get_current_language() !== $sitepress->get_default_language()){
611
- $value['checkout_url'] = admin_url('admin-ajax.php?action=woocommerce-checkout&lang=' . ICL_LANGUAGE_CODE);
612
- $value['ajax_url'] = admin_url('admin-ajax.php?lang=' . ICL_LANGUAGE_CODE);
613
- }
614
-
615
- $checkout_page_id = get_option('woocommerce_checkout_page_id');
616
- $pay_page_id = get_option('woocommerce_pay_page_id');
617
- $cart_page_id = get_option('woocommerce_cart_page_id');
618
-
619
- $translated_checkout_page_id = icl_object_id($checkout_page_id, 'page', false);
620
- $translated_pay_page_id = icl_object_id($pay_page_id, 'page', false);
621
- $translated_cart_page_id = icl_object_id($cart_page_id, 'page', false);
622
-
623
- if($translated_cart_page_id == $post->ID){
624
- $value['is_cart'] = 1;
625
- } else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
626
- $value['is_checkout'] = 1;
627
-
628
- $value['locale'] = '';
629
-
630
- $_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
631
-
632
- } else if($translated_pay_page_id == $post->ID){
633
- $value['is_pay_page'] = 1;
634
- }
635
-
636
- return $value;
637
- }
638
-
639
- /**
640
- * Adds language to order post type.
641
- *
642
- * Language was stored in the session created on checkout page.
643
- * See params().
644
- *
645
- * @param type $order_id
646
- */
647
- function wpml_order_language($order_id) {
648
- if(!get_post_meta($order_id, 'wpml_language')){
649
- $language = isset($_SESSION['wpml_globalcart_language']) ? $_SESSION['wpml_globalcart_language'] : ICL_LANGUAGE_CODE;
650
- update_post_meta($order_id, 'wpml_language', $language);
651
- }
652
- }
653
-
654
- /**
655
- * Translates WooCommerce emails.
656
- *
657
- * @global type $sitepress
658
- * @global type $order_id
659
- * @return type
660
- */
661
- function wpml_email_header() {
662
- global $sitepress, $order_id;
663
-
664
- $lang = get_post_meta($order_id, 'wpml_language', TRUE);
665
-
666
- if(empty($lang)){
667
- if(isset($_SESSION['wpml_globalcart_language'])){
668
- $lang = $_SESSION['wpml_globalcart_language'];
669
- } else {
670
- $lang = $sitepress->get_current_language();
671
- }
672
- }
673
-
674
- $sitepress->switch_lang($lang, true);
675
- }
676
-
677
- /**
678
- * After email translation switch language to default.
679
- *
680
- * @global type $sitepress
681
- * @return type
682
- */
683
- function wpml_email_footer() {
684
- global $sitepress;
685
-
686
- $sitepress->switch_lang();
687
- }
688
-
689
- /**
690
- * After email translation switch language to default.
691
- *
692
- * @param type $title
693
- * @param $_product
694
- * @return type
695
- */
696
- function wpml_in_cart_product_title($title, $_product){
697
- $product_id = icl_object_id($_product->id, 'product', false, ICL_LANGUAGE_CODE);
698
-
699
- if($product_id){
700
- $title = get_the_title($product_id);
701
- }
702
-
703
- return $title;
704
- }
705
-
706
- /**
707
- * Filters WPML language switcher.
708
- *
709
- * @global type $post
710
- * @global type $sitepress
711
- * @param type $languages
712
- * @return type
713
- */
714
- function wpml_ls_filter($languages) {
715
- global $post, $sitepress;
716
-
717
- if(strpos(basename($_SERVER['REQUEST_URI']), 'post_type') !== false ||
718
- strpos(basename($_SERVER['REQUEST_URI']), 'shop') !== false){
719
-
720
- foreach($languages as $lang_code => $language){
721
- $languages[$lang_code]['url'] = $sitepress->convert_url(get_option('home')
722
- . '/?post_type=product', $language['language_code']);
723
- }
724
- }
725
-
726
-
727
- return $languages;
728
- }
729
-
730
- /**
731
- * Updates the shop base page permalink in the translated language.
732
- * Needed for the correct products URLs in the shop base page.
733
- *
734
- * @global type $wpdb
735
- * @return type
736
- */
737
- /*
738
- function wpml_change_permalinks(){
739
- global $wpdb;
740
-
741
- $translated_shop_page_id = icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
742
- $posts_query = $wpdb->get_row("SELECT * FROM $wpdb->posts WHERE `ID` = '$translated_shop_page_id'", ARRAY_A);
743
-
744
- if($posts_query['post_name'] !== 'shop'){
745
- $wpdb->update($wpdb->posts, array('post_name' => 'shop'), array('post_name' => $posts_query['post_name']));
746
- }
747
- }*/
748
-
749
- /**
750
- * Creates WCML page.
751
- */
752
- function wpml_menu(){
753
- $top_page = apply_filters('icl_menu_main_page', basename(ICL_PLUGIN_PATH) .'/menu/languages.php');
754
-
755
- add_submenu_page($top_page, __('WooCommerce Multilingual','wpml-wcml'),
756
- __('WooCommerce Multilingual', 'wpml-wcml'), 'manage_options', 'wpml-wcml', 'wpml_menu_content');
757
- }
758
-
759
- /**
760
- * Creates WCML page content.
761
- */
762
- function wpml_menu_content(){
763
- include WCML_PLUGIN_PATH . '/menu/management.php';
764
- }
765
-
766
- /**
767
- * Adds additional CSS and JS.
768
- */
769
- function wpml_load_css_and_js() {
770
- wp_enqueue_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array(), WCML_VERSION);
771
-
772
- wp_enqueue_script(
773
- 'jquery-validate',
774
- plugin_dir_url(__FILE__) . '/assets/js/jquery.validate.min.js',
775
- array('jquery'),
776
- '1.8.1',
777
- true
778
- );
779
- }
780
-
781
- /**
782
- * Avoids the post translation links on the product post type.
783
- *
784
- * @global type $post
785
- * @return type
786
- */
787
- function wpml_post_alternative_languages($output){
788
- global $post;
789
-
790
- $post_type = get_post_type($post->ID);
791
- $checkout_page_id = wpml_checkout_page_id();
792
-
793
- if($post_type == 'product' || is_page($checkout_page_id)){
794
- $output = '';
795
- }
796
-
797
- return $output;
798
- }
799
-
800
- /**
801
- * Translates attributes names.
802
- *
803
- * @param type $name
804
- * @return type
805
- */
806
- function wpml_translate_attributes($name){
807
- if(function_exists('icl_register_string')){
808
- icl_register_string('woocommerce', $name .'_attribute', $name);
809
-
810
- $name = icl_t('woocommerce', $name .'_attribute', $name);
811
- }
812
-
813
- return $name;
814
- }
815
-
816
- /**
817
- * Takes off translated products from the Up-sells/Cross-sells tab.
818
- *
819
- * @global type $sitepress
820
- * @global type $wpdb
821
- * @return type
822
- */
823
- function wpml_woocommerce_upsell_crosssell_search_posts($posts){
824
- global $sitepress, $wpdb;
825
-
826
- foreach($posts as $key => $post){
827
- $post_id = $posts[$key]->ID;
828
- $post_data = $wpdb->get_row("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$post_id'", ARRAY_A);
829
-
830
- if($post_data['language_code'] !== $sitepress->get_current_language()){
831
- unset($posts[$key]);
832
- }
833
- }
834
-
835
- return $posts;
836
- }
837
-
838
- /**
839
- * Sync attributes and variations during product duplication.
840
- * Sync: term relationship, post meta, post variations, post variations meta.
841
- *
842
- * @global type $wpdb
843
- * @global type $pagenow
844
- * @global type $post
845
- * @return type
846
- */
847
- function wpml_synchronizate_variations() {
848
- global $wpdb, $pagenow, $post, $sitepress;
849
-
850
- $post_id = @$post->ID;
851
- $post_type = @get_post_type($post->ID);
852
-
853
- if($pagenow == 'post.php' || $pagenow == 'post-new.php' && $post_type == 'product'){
854
- $duplicated_post_id = get_post_meta($post_id, '_icl_lang_duplicate_of', TRUE);
855
- $is_data_already_synced = get_post_meta($post_id, 'wpml_variations_already_synced', TRUE);
856
-
857
- // Only on duplication and run once
858
- if(!empty($duplicated_post_id) && empty($is_data_already_synced)){
859
-
860
- $get_variation_term_name = $wpdb->get_results("SELECT * FROM $wpdb->terms WHERE name = 'variable'");
861
- $get_variation_term_id = $get_variation_term_name[0]->term_id;
862
-
863
- $is_post_has_variations = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id' AND term_taxonomy_id = '$get_variation_term_id'");
864
- if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
865
-
866
- // synchronize term data, postmeta and post variations
867
- if($is_post_has_variations){
868
- $get_all_term_data = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id'");
869
-
870
- foreach($get_all_term_data as $k => $term_relationship){
871
- $term_taxonomy_id = $term_relationship->term_taxonomy_id;
872
- $term_taxonomy_id_data = $wpdb->get_results("SELECT * FROM $wpdb->term_taxonomy WHERE term_taxonomy_id = '$term_taxonomy_id'");
873
-
874
- $all_data = $wpdb->get_results("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$term_taxonomy_id'");
875
-
876
- $terms_translations[$k]['object_id'] = $term_relationship->object_id;
877
- $terms_translations[$k]['term_taxonomy_id'] = $term_relationship->term_taxonomy_id;
878
- $terms_translations[$k]['term_order'] = $term_relationship->term_order;
879
- $terms_translations[$k]['element_type'] = $all_data[0]->element_type;
880
- $terms_translations[$k]['trid'] = $all_data[0]->trid;
881
- $terms_translations[$k]['source_lang'] = $all_data[0]->source_language_code;
882
- }
883
-
884
- foreach($terms_translations as $key => $term){
885
- $trid = $term['trid'];
886
-
887
- $all_data_db = $wpdb->get_results("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE trid = '$trid'");
888
-
889
- foreach($all_data_db as $k => $value){
890
- if($value->source_language_code){
891
- $found_element_id = $value->element_id;
892
-
893
- $terms_translations[$key]['term_taxonomy_id'] = $found_element_id;
894
- }
895
- }
896
- }
897
-
898
- // synchronize term data
899
- foreach($terms_translations as $k => $term_relationship){
900
-
901
- $wpdb->insert(
902
- $wpdb->term_relationships,
903
- array(
904
- 'object_id' => $post_id,
905
- 'term_taxonomy_id' => $term_relationship['term_taxonomy_id'],
906
- 'term_order' => $term_relationship['term_order']
907
- ));
908
-
909
- }
910
-
911
- // synchronize post meta
912
- $get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_id'");
913
-
914
- foreach($get_all_post_meta as $k => $post_meta){
915
- $meta_key = $post_meta->meta_key;
916
- $meta_value = $post_meta->meta_value;
917
-
918
- update_post_meta($post_id, $meta_key, $meta_value);
919
- }
920
-
921
- // synchronize post variations
922
- $get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
923
- WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
924
-
925
- foreach($get_all_post_variations as $k => $post_data){
926
- $guid = $post_data->guid;
927
- $replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
928
-
929
- $wpdb->insert(
930
- $wpdb->posts,
931
- array(
932
- 'post_author' => $post_data->post_author,
933
- 'post_date_gmt' => $post_data->post_date_gmt,
934
- 'post_content' => $post_data->post_content,
935
- 'post_title' => $post_data->post_title,
936
- 'post_excerpt' => $post_data->post_excerpt,
937
- 'post_status' => $post_data->post_status,
938
- 'comment_status' => $post_data->comment_status,
939
- 'ping_status' => $post_data->ping_status,
940
- 'post_password' => $post_data->post_password,
941
- 'post_name' => $post_data->post_name,
942
- 'to_ping' => $post_data->to_ping,
943
- 'pinged' => $post_data->pinged,
944
- 'post_modified' => $post_data->post_modified,
945
- 'post_modified_gmt' => $post_data->post_modified_gmt,
946
- 'post_content_filtered' => $post_data->post_content_filtered,
947
- 'post_parent' => $post_id, // current post ID
948
- 'guid' => $replaced_guid,
949
- 'menu_order' => $post_data->menu_order,
950
- 'post_type' => $post_data->post_type,
951
- 'post_mime_type' => $post_data->post_mime_type,
952
- 'comment_count' => $post_data->comment_count
953
- ));
954
-
955
- }
956
-
957
- foreach($get_all_post_variations as $k => $post_data){
958
- $duplicated_post_variation_ids[] = $post_data->ID;
959
- }
960
-
961
- $get_current_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
962
- WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$post_id'");
963
-
964
- foreach($get_current_post_variations as $k => $post_data){
965
- $current_post_variation_ids[] = $post_data->ID;
966
- }
967
-
968
- // synchronize post variations post meta
969
- foreach($duplicated_post_variation_ids as $dp_key => $duplicated_post_variation_id){
970
- $get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_variation_id'");
971
-
972
- foreach($get_all_post_meta as $k => $post_meta){
973
- $meta_key = $post_meta->meta_key;
974
- $meta_value = $post_meta->meta_value;
975
-
976
- // update current post variations meta
977
- update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
978
- }
979
- }
980
-
981
- // add a record that data is already synced
982
- update_post_meta($post_id, 'wpml_variations_already_synced', '1');
983
- }
984
- }
985
- }
986
- }
987
-
988
- ?>
5
  Description: Allows running fully multilingual e-Commerce sites with WooCommerce and WPML. <a href="http://wpml.org/documentation/related-projects/woocommerce-multilingual/">Documentation</a>.
6
  Author: ICanLocalize
7
  Author URI: http://wpml.org/
8
+ Version: 1.3
9
  */
10
 
11
+ if(defined('WCML_VERSION')) return;
12
+ define('WCML_VERSION', '1.3');
13
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
14
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
15
  define('WCML_PLUGIN_URL', plugins_url() . '/' . WCML_PLUGIN_FOLDER);
16
 
17
+ require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
18
+ $woocommerce_wpml = new woocommerce_wpml();