Version Description
- Fixed manually setting prices in translated products.
- Take advantage of WPML's new slug translation feature.
- Added the possibility of translating custom attributes.
- Improvements to product variation synchronization.
- Fixed product stock sync for variable products .
- Fix and improve checks made to incompatible permalink configurations.
- Fix tax label translation when there is more than one of them.
- Send order notifications in the language the order was made.
- Removed several warnings and updated deprecated code.
- Cleanup language configuration file and add missing strings.
Download this release
Release Info
Developer | dgwatkins |
Plugin | WooCommerce Multilingual – run WooCommerce with WPML |
Version | 1.5 |
Comparing to | |
See all releases |
Code changes from version 1.4 to 1.5
- menu/management.php +1 -1
- readme.txt +32 -9
- woocommerce_wpml.class.php +273 -157
- wpml-config.xml +29 -61
- wpml-woocommerce.php +2 -2
menu/management.php
CHANGED
@@ -36,7 +36,7 @@
|
|
36 |
<table class="widefat">
|
37 |
<thead>
|
38 |
<tr>
|
39 |
-
<th><?php
|
40 |
</tr>
|
41 |
</thead>
|
42 |
<tbody>
|
36 |
<table class="widefat">
|
37 |
<thead>
|
38 |
<tr>
|
39 |
+
<th><?php if (!isset($_GET['edit'])): ?>Add currency<?php else: ?>Edit currency<?php endif; ?></th>
|
40 |
</tr>
|
41 |
</thead>
|
42 |
<tbody>
|
readme.txt
CHANGED
@@ -2,35 +2,43 @@
|
|
2 |
Contributors: AmirHelzer, dominykasgel, dgwatkins
|
3 |
Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
|
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.5
|
7 |
-
Stable tag: 1.
|
8 |
-
Version: 1.4
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
-
This 'glue' plugin makes it possible to run fully multilingual e-commerce sites using WooCommerce and WPML. It makes products and store pages translatable, lets visitors switch languages and order products in their language.
|
|
|
|
|
15 |
|
16 |
= Features =
|
17 |
|
18 |
-
* Lets you translate products, attributes and categories
|
|
|
19 |
* Keeps the same language through the checkout process
|
20 |
* Sends emails to clients and admins in their selected language
|
21 |
* Allows inventory tracking without breaking products into languages
|
22 |
* Enables running a single WooCommerce store with multiple currencies
|
23 |
|
24 |
-
=
|
|
|
|
|
|
|
|
|
25 |
|
26 |
-
|
|
|
|
|
27 |
|
28 |
= Downloads =
|
29 |
|
30 |
-
You
|
31 |
|
32 |
-
|
33 |
-
* [WPML](http://wpml.org) version 2.6.0 and up - the multilingual WordPress plugin
|
34 |
|
35 |
== Installation ==
|
36 |
|
@@ -60,6 +68,18 @@ In order for the checkout and store pages to appear translated, you need to crea
|
|
60 |
|
61 |
== Changelog ==
|
62 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
= 1.4 =
|
64 |
* Allow translating the 'Terms & Conditions' page.
|
65 |
* Register shipping methods strings for translation.
|
@@ -113,6 +133,9 @@ In order for the checkout and store pages to appear translated, you need to crea
|
|
113 |
|
114 |
== Upgrade Notice ==
|
115 |
|
|
|
|
|
|
|
116 |
= 1.4 =
|
117 |
This version runs with WooCommerce 1.6.5.x and 1.7.x. Recommeded WPML version is 2.6.2 and above.
|
118 |
|
2 |
Contributors: AmirHelzer, dominykasgel, dgwatkins
|
3 |
Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
|
4 |
Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
|
5 |
+
License: GPLv2
|
6 |
Requires at least: 3.0
|
7 |
Tested up to: 3.5
|
8 |
+
Stable tag: 1.5
|
|
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
12 |
== Description ==
|
13 |
|
14 |
+
This 'glue' plugin makes it possible to run fully multilingual e-commerce sites using [WooCommerce](http://wordpress.org/extend/plugins/woocommerce/) and [WPML](http://wpml.org). It makes products and store pages translatable, lets visitors switch languages and order products in their language.
|
15 |
+
|
16 |
+
>> WooCommerce Multilingual is currently compatible with WooCommerce 1.x only. We are working on a new version for WooCommerce 2.x. We will write about updates in [WPML blog](http://wpml.org/blog/).
|
17 |
|
18 |
= Features =
|
19 |
|
20 |
+
* Lets you translate products, variations, attributes and categories
|
21 |
+
* Easily synchronizes between products and variations between different languages
|
22 |
* Keeps the same language through the checkout process
|
23 |
* Sends emails to clients and admins in their selected language
|
24 |
* Allows inventory tracking without breaking products into languages
|
25 |
* Enables running a single WooCommerce store with multiple currencies
|
26 |
|
27 |
+
= Usage Instructions =
|
28 |
+
|
29 |
+
You will need to translate all the standard WooCommerce pages. Then, translate products and product categories and you're on your way.
|
30 |
+
|
31 |
+
Strings that are not part of any product, will be translatable via WPML's String Translation.
|
32 |
|
33 |
+
For complete information on setting up a multilingual shop, please go to [WooCommerce Multilingual Manual](http://wpml.org/documentation/related-projects/woocommerce-multilingual/) page.
|
34 |
+
|
35 |
+
When you need help, go to [WPML technical support forum](http://wpml.org/forums/forum/english-support/).
|
36 |
|
37 |
= Downloads =
|
38 |
|
39 |
+
This version of WooCommerce Multilingual works with WooCommerce 1.x. The latest version is [WooCommerce 1.6.6](http://downloads.wordpress.org/plugin/woocommerce.1.6.6.zip). You can see other versions in the [WooCommerce Developers](http://wordpress.org/extend/plugins/woocommerce/developers/) page.
|
40 |
|
41 |
+
You will also need [WPML](http://wpml.org), together with the String Translation module, which is part of the [Multilingual CMS](http://wpml.org/purchase/) package.
|
|
|
42 |
|
43 |
== Installation ==
|
44 |
|
68 |
|
69 |
== Changelog ==
|
70 |
|
71 |
+
= 1.5 =
|
72 |
+
* Fixed manually setting prices in translated products.
|
73 |
+
* Take advantage of WPML's new slug translation feature.
|
74 |
+
* Added the possibility of translating custom attributes.
|
75 |
+
* Improvements to product variation synchronization.
|
76 |
+
* Fixed product stock sync for variable products .
|
77 |
+
* Fix and improve checks made to incompatible permalink configurations.
|
78 |
+
* Fix tax label translation when there is more than one of them.
|
79 |
+
* Send order notifications in the language the order was made.
|
80 |
+
* Removed several warnings and updated deprecated code.
|
81 |
+
* Cleanup language configuration file and add missing strings.
|
82 |
+
|
83 |
= 1.4 =
|
84 |
* Allow translating the 'Terms & Conditions' page.
|
85 |
* Register shipping methods strings for translation.
|
133 |
|
134 |
== Upgrade Notice ==
|
135 |
|
136 |
+
= 1.5 =
|
137 |
+
Variation translation works a lot better now. This version runs best with WooCommerce 1.6.6.
|
138 |
+
|
139 |
= 1.4 =
|
140 |
This version runs with WooCommerce 1.6.5.x and 1.7.x. Recommeded WPML version is 2.6.2 and above.
|
141 |
|
woocommerce_wpml.class.php
CHANGED
@@ -19,6 +19,8 @@ class woocommerce_wpml {
|
|
19 |
}
|
20 |
|
21 |
function init(){
|
|
|
|
|
22 |
if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
|
23 |
if(!function_exists('is_multisite') || !is_multisite()) {
|
24 |
add_action('admin_notices', array($this, 'no_wpml_warning'));
|
@@ -57,17 +59,21 @@ class woocommerce_wpml {
|
|
57 |
add_filter('woocommerce_params', array($this, 'ajax_params'));
|
58 |
add_filter('woocommerce_redirect', array($this, 'do_redirect'));
|
59 |
add_filter('woocommerce_attribute_label', array($this, 'translate_attributes'), 14, 2);
|
|
|
|
|
60 |
add_filter('woocommerce_upsell_crosssell_search_products', array($this, 'woocommerce_upsell_crosssell_search_posts'));
|
61 |
add_filter('icl_post_alternative_languages', array($this, 'post_alternative_languages'));
|
62 |
add_filter('woocommerce_gateway_title', array($this, 'gateway_title'), 10);
|
63 |
add_filter('woocommerce_gateway_description', array($this, 'gateway_description'), 10, 2);
|
64 |
-
add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
|
65 |
add_filter('woocommerce_json_search_found_products', array($this, 'search_products'));
|
66 |
add_filter('woocommerce_currency', array($this, 'set_ml_currency'));
|
67 |
//add_filter('woocommerce_paypal_amount', array($this, 'paypal_amount'));
|
68 |
add_action('admin_print_scripts', array($this,'js_scripts_setup'), 11);
|
69 |
add_action('init', array($this, 'translate_email_notifications'));
|
70 |
|
|
|
|
|
|
|
71 |
// Translate shop page settings
|
72 |
add_filter('option_woocommerce_shop_page_id', array($this, 'translate_pages_in_settings'));
|
73 |
add_filter('option_woocommerce_terms_page_id', array($this, 'translate_pages_in_settings'));
|
@@ -84,6 +90,9 @@ class woocommerce_wpml {
|
|
84 |
if(get_option('currency_converting_option') == '1'){
|
85 |
add_filter('raw_woocommerce_price', array($this, 'woocommerce_price'));
|
86 |
add_filter('woocommerce_order_amount_total', array($this, 'woocommerce_price'));
|
|
|
|
|
|
|
87 |
}
|
88 |
|
89 |
add_filter('woocommerce_currency_symbol', array($this, 'woocommerce_currency_symbol'), 2);
|
@@ -102,6 +111,8 @@ class woocommerce_wpml {
|
|
102 |
add_filter('woocommerce_price_filter_max_price', array($this, 'price_filter_max_price'));
|
103 |
|
104 |
add_action('save_post', array($this, 'sync_variations'), 11, 2); // After WPML
|
|
|
|
|
105 |
|
106 |
add_action('admin_menu', array($this, 'menu'));
|
107 |
add_action('init', array($this, 'load_css_and_js'));
|
@@ -109,17 +120,13 @@ class woocommerce_wpml {
|
|
109 |
if(is_admin()){
|
110 |
add_action('admin_init', array($this, 'make_new_attributes_translatable'));
|
111 |
} else {
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
/*
|
116 |
-
// Hooks for translating product attribute values, not really needed as they can be translated
|
117 |
-
// with WPML as terms. Commenting it in case its requested.
|
118 |
-
add_filter('woocommerce_variation_term_name', array($this, 'variation_term_name'));
|
119 |
-
if(is_admin()){
|
120 |
-
add_action('admin_init', array($this, 'translate_custom_attributes'));
|
121 |
}
|
122 |
-
|
|
|
|
|
|
|
123 |
|
124 |
if(isset($_POST['general_options']) && check_admin_referer('general_options', 'general_options_nonce')){
|
125 |
$enable_multi_currency = (isset($_POST['multi_currency'])) ? trim($_POST['multi_currency']) : null;
|
@@ -139,6 +146,9 @@ class woocommerce_wpml {
|
|
139 |
|
140 |
}
|
141 |
|
|
|
|
|
|
|
142 |
if(isset($_POST['add_currency']) && check_admin_referer('add_currency', 'add_currency_nonce')){
|
143 |
global $wpdb, $pagenow;
|
144 |
|
@@ -222,6 +232,73 @@ class woocommerce_wpml {
|
|
222 |
add_action('option_woocommerce_tax_rates', array($this, 'tax_rates'));
|
223 |
}
|
224 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
function register_shipping_methods($available_methods){
|
226 |
|
227 |
foreach($available_methods as $method){
|
@@ -241,7 +318,7 @@ class woocommerce_wpml {
|
|
241 |
function tax_rates($rates){
|
242 |
if (!empty($rates)) {
|
243 |
foreach ($rates as &$rate) {
|
244 |
-
$rate['label'] = icl_translate('woocommerce', '
|
245 |
}
|
246 |
}
|
247 |
|
@@ -364,36 +441,59 @@ class woocommerce_wpml {
|
|
364 |
* one of these must be true for product urls to work
|
365 |
* if none of these are true, display a warning message
|
366 |
*/
|
367 |
-
|
368 |
-
|
369 |
-
|
370 |
-
|
371 |
-
|
372 |
-
|
373 |
-
|
374 |
-
|
375 |
-
|
376 |
-
|
377 |
-
|
378 |
-
|
379 |
-
|
380 |
-
|
381 |
-
|
382 |
-
|
383 |
-
|
384 |
-
|
385 |
-
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
397 |
|
398 |
/**
|
399 |
* Switch the language on AJAX action, because in some ways the correct language is missing.
|
@@ -617,7 +717,7 @@ class woocommerce_wpml {
|
|
617 |
} else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
|
618 |
$value['is_checkout'] = 1;
|
619 |
|
620 |
-
|
621 |
|
622 |
$_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
|
623 |
|
@@ -697,18 +797,30 @@ class woocommerce_wpml {
|
|
697 |
return $output;
|
698 |
}
|
699 |
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
}
|
709 |
|
710 |
-
|
711 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
712 |
|
713 |
/**
|
714 |
* Translates the payment gateway title text.
|
@@ -744,8 +856,9 @@ class woocommerce_wpml {
|
|
744 |
|
745 |
$front_page_id = get_option('page_on_front');
|
746 |
$shop_page_id = get_option('woocommerce_shop_page_id');
|
|
|
747 |
|
748 |
-
if ($q->get('page_id') !== $front_page_id && $shop_page_id == $q->get('page_id')) {
|
749 |
$q->set( 'post_type', 'product' );
|
750 |
$q->set( 'page_id', '' );
|
751 |
if ( isset( $q->query['paged'] ) )
|
@@ -755,7 +868,6 @@ class woocommerce_wpml {
|
|
755 |
// This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
|
756 |
global $wp_post_types;
|
757 |
|
758 |
-
$shop_page = get_post( woocommerce_get_page_id('shop') );
|
759 |
$q->is_page = true;
|
760 |
|
761 |
$wp_post_types['product']->ID = $shop_page->ID;
|
@@ -796,7 +908,7 @@ class woocommerce_wpml {
|
|
796 |
function woocommerce_price($price){
|
797 |
global $sitepress, $wpdb;
|
798 |
|
799 |
-
$sql = "SELECT
|
800 |
$currency = $wpdb->get_results($sql, OBJECT);
|
801 |
|
802 |
if($currency){
|
@@ -819,7 +931,10 @@ class woocommerce_wpml {
|
|
819 |
function email_header() {
|
820 |
global $sitepress, $order_id;
|
821 |
|
822 |
-
$lang =
|
|
|
|
|
|
|
823 |
|
824 |
if(empty($lang)){
|
825 |
if(isset($_SESSION['wpml_globalcart_language'])){
|
@@ -848,50 +963,40 @@ class woocommerce_wpml {
|
|
848 |
Only when translated products are ordered, force adjusting stock information for all translations
|
849 |
When a product in the default language is ordered stocks are adjusted automatically
|
850 |
*/
|
851 |
-
function sync_product_stocks($order){
|
852 |
-
|
853 |
-
|
854 |
-
|
855 |
-
|
856 |
-
|
857 |
-
|
858 |
-
|
859 |
-
|
860 |
-
|
861 |
-
|
862 |
-
|
863 |
-
|
864 |
-
|
865 |
-
|
866 |
-
if ($_product->managing_stock() && !$_product->backorders_allowed() && $_product->get_total_stock()<=0){
|
867 |
-
$outofstock = 'outofstock';
|
868 |
-
}else{
|
869 |
-
$outofstock = false;
|
870 |
-
}
|
871 |
-
|
872 |
-
|
873 |
-
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
|
874 |
-
$trid = $sitepress->get_element_trid($_product->id, 'post_product');
|
875 |
-
$translations = $sitepress->get_element_translations($trid, 'post_product', true);
|
876 |
|
877 |
-
|
878 |
-
|
879 |
|
880 |
-
|
881 |
-
|
882 |
-
|
883 |
-
|
884 |
-
|
885 |
-
|
886 |
-
update_post_meta($translation->element_id, '_stock_status', 'outofstock');
|
887 |
-
}
|
888 |
-
}
|
889 |
-
delete_transient('wc_product_total_stock_' . $translation->element_id);
|
890 |
-
}
|
891 |
-
}
|
892 |
|
893 |
-
|
894 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
895 |
|
896 |
}
|
897 |
|
@@ -959,6 +1064,10 @@ function sync_product_stocks($order){
|
|
959 |
|
960 |
return $max_price;
|
961 |
}
|
|
|
|
|
|
|
|
|
962 |
|
963 |
function sync_variations($post_id, $post){
|
964 |
global $wpdb, $pagenow, $sitepress;
|
@@ -1054,10 +1163,12 @@ function sync_product_stocks($order){
|
|
1054 |
|
1055 |
if( ($pagenow == 'post.php' || $ajax_call ) && $post_type == 'product' && !empty($duplicated_post_id)){
|
1056 |
|
1057 |
-
$
|
1058 |
-
$
|
|
|
|
|
1059 |
|
1060 |
-
$is_post_has_variations = $wpdb->get_results("SELECT * FROM $wpdb->term_relationships WHERE object_id = '$duplicated_post_id' AND term_taxonomy_id = '$
|
1061 |
if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
|
1062 |
|
1063 |
// synchronize term data, postmeta and post variations
|
@@ -1066,6 +1177,7 @@ function sync_product_stocks($order){
|
|
1066 |
$get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
|
1067 |
WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
|
1068 |
|
|
|
1069 |
foreach($get_all_post_variations as $k => $post_data){
|
1070 |
$duplicated_post_variation_ids[] = $post_data->ID;
|
1071 |
}
|
@@ -1076,7 +1188,8 @@ function sync_product_stocks($order){
|
|
1076 |
|
1077 |
if (!empty($variation_id)) {
|
1078 |
// Update variation
|
1079 |
-
|
|
|
1080 |
'post_author' => $post_data->post_author,
|
1081 |
'post_date_gmt' => $post_data->post_date_gmt,
|
1082 |
'post_content' => $post_data->post_content,
|
@@ -1097,14 +1210,14 @@ function sync_product_stocks($order){
|
|
1097 |
'post_type' => $post_data->post_type,
|
1098 |
'post_mime_type' => $post_data->post_mime_type,
|
1099 |
'comment_count' => $post_data->comment_count
|
1100 |
-
)
|
1101 |
} else {
|
1102 |
// Add new variation
|
1103 |
$guid = $post_data->guid;
|
1104 |
$replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
|
1105 |
$slug = $post_data->post_name;
|
1106 |
$replaced_slug = str_replace($duplicated_post_id, $post_id, $slug);
|
1107 |
-
$
|
1108 |
'post_author' => $post_data->post_author,
|
1109 |
'post_date_gmt' => $post_data->post_date_gmt,
|
1110 |
'post_content' => $post_data->post_content,
|
@@ -1127,8 +1240,8 @@ function sync_product_stocks($order){
|
|
1127 |
'post_mime_type' => $post_data->post_mime_type,
|
1128 |
'comment_count' => $post_data->comment_count
|
1129 |
));
|
1130 |
-
$variation_id = $wpdb->insert_id;
|
1131 |
update_post_meta($variation_id, '_wcml_duplicate_of_variation', $post_data->ID);
|
|
|
1132 |
$trid = $sitepress->get_element_trid($post_data->ID, 'post_product_variation');
|
1133 |
$sitepress->set_element_language_details($variation_id, 'post_product_variation', $trid, $lang, $sitepress->get_default_language());
|
1134 |
}
|
@@ -1144,43 +1257,67 @@ function sync_product_stocks($order){
|
|
1144 |
wp_delete_post($variation_id, true);
|
1145 |
}
|
1146 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1147 |
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1152 |
|
1153 |
-
$taxs = array();
|
1154 |
-
foreach($duplicated_post_variation_ids as $dp_key => $duplicated_post_variation_id){
|
1155 |
-
$get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_variation_id'");
|
1156 |
-
|
1157 |
-
foreach($get_all_post_meta as $k => $post_meta){
|
1158 |
-
$meta_key = $post_meta->meta_key;
|
1159 |
-
$meta_value = $post_meta->meta_value;
|
1160 |
-
|
1161 |
-
// adjust the global attribute slug in the custom field
|
1162 |
-
if (substr($meta_key, 0, 10) == 'attribute_') {
|
1163 |
-
$tax = substr($meta_key, 10);
|
1164 |
-
$taxs[] = $tax;
|
1165 |
-
$attid = get_term_by('slug', $meta_value, $tax)->term_id;
|
1166 |
-
$attid = icl_object_id($attid, $tax, true, $lang);
|
1167 |
-
$meta_value = get_term_by('id', $attid, $tax)->slug;
|
1168 |
-
}
|
1169 |
-
|
1170 |
-
// update current post variations meta
|
1171 |
-
update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
|
1172 |
-
}
|
1173 |
-
}
|
1174 |
// Sync terms
|
|
|
1175 |
$taxs = array_unique($taxs);
|
1176 |
foreach ($taxs as $tax) {
|
1177 |
$terms = wp_get_object_terms($duplicated_post_id, $tax);
|
1178 |
$update = array();
|
1179 |
foreach ($terms as $term) {
|
1180 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
1181 |
}
|
1182 |
-
|
1183 |
}
|
|
|
1184 |
}
|
1185 |
}
|
1186 |
}
|
@@ -1221,9 +1358,10 @@ function sync_product_stocks($order){
|
|
1221 |
* Makes all new attributes translatable.
|
1222 |
*/
|
1223 |
function make_new_attributes_translatable(){
|
|
|
1224 |
if(isset($_GET['page']) && $_GET['page'] == 'woocommerce_attributes'){
|
1225 |
|
1226 |
-
$wpml_settings =
|
1227 |
|
1228 |
$get_all_taxonomies = get_taxonomies();
|
1229 |
|
@@ -1236,29 +1374,7 @@ function sync_product_stocks($order){
|
|
1236 |
}
|
1237 |
}
|
1238 |
|
1239 |
-
|
1240 |
-
}
|
1241 |
-
}
|
1242 |
-
|
1243 |
-
/**
|
1244 |
-
* Registers custom attribute/variation title for translation.
|
1245 |
-
*
|
1246 |
-
* @global type $wpdb
|
1247 |
-
* @return type
|
1248 |
-
*/
|
1249 |
-
function translate_custom_attributes(){
|
1250 |
-
global $wpdb;
|
1251 |
-
|
1252 |
-
$all_variations = $wpdb->get_results("SELECT ID FROM $wpdb->posts WHERE post_status = 'publish' AND post_type = 'product_variation'");
|
1253 |
-
|
1254 |
-
$attribute_meta_keys = $wpdb->get_results("SELECT DISTINCT(meta_value) FROM $wpdb->postmeta WHERE meta_key LIKE 'attribute_%'");
|
1255 |
-
|
1256 |
-
foreach($attribute_meta_keys as $k => $meta){
|
1257 |
-
$variation_name = $meta->meta_value;
|
1258 |
-
|
1259 |
-
if(function_exists('icl_register_string')){
|
1260 |
-
icl_register_string('woocommerce', $variation_name .'_attribute_name', $variation_name);
|
1261 |
-
}
|
1262 |
}
|
1263 |
}
|
1264 |
|
19 |
}
|
20 |
|
21 |
function init(){
|
22 |
+
global $sitepress;
|
23 |
+
|
24 |
if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
|
25 |
if(!function_exists('is_multisite') || !is_multisite()) {
|
26 |
add_action('admin_notices', array($this, 'no_wpml_warning'));
|
59 |
add_filter('woocommerce_params', array($this, 'ajax_params'));
|
60 |
add_filter('woocommerce_redirect', array($this, 'do_redirect'));
|
61 |
add_filter('woocommerce_attribute_label', array($this, 'translate_attributes'), 14, 2);
|
62 |
+
add_filter('get_term', array($this, 'clean_term'), 14, 2);
|
63 |
+
add_filter('wp_get_object_terms', array($sitepress, 'get_terms_filter'));
|
64 |
add_filter('woocommerce_upsell_crosssell_search_products', array($this, 'woocommerce_upsell_crosssell_search_posts'));
|
65 |
add_filter('icl_post_alternative_languages', array($this, 'post_alternative_languages'));
|
66 |
add_filter('woocommerce_gateway_title', array($this, 'gateway_title'), 10);
|
67 |
add_filter('woocommerce_gateway_description', array($this, 'gateway_description'), 10, 2);
|
|
|
68 |
add_filter('woocommerce_json_search_found_products', array($this, 'search_products'));
|
69 |
add_filter('woocommerce_currency', array($this, 'set_ml_currency'));
|
70 |
//add_filter('woocommerce_paypal_amount', array($this, 'paypal_amount'));
|
71 |
add_action('admin_print_scripts', array($this,'js_scripts_setup'), 11);
|
72 |
add_action('init', array($this, 'translate_email_notifications'));
|
73 |
|
74 |
+
add_filter('gettext_with_context', array($this, 'default_slug_translation'), 0, 4);
|
75 |
+
add_filter('option_woocommerce_permalinks', array($this, 'custom_slug_translation'));
|
76 |
+
|
77 |
// Translate shop page settings
|
78 |
add_filter('option_woocommerce_shop_page_id', array($this, 'translate_pages_in_settings'));
|
79 |
add_filter('option_woocommerce_terms_page_id', array($this, 'translate_pages_in_settings'));
|
90 |
if(get_option('currency_converting_option') == '1'){
|
91 |
add_filter('raw_woocommerce_price', array($this, 'woocommerce_price'));
|
92 |
add_filter('woocommerce_order_amount_total', array($this, 'woocommerce_price'));
|
93 |
+
add_filter('woocommerce_order_amount_item_total', array($this, 'woocommerce_price'));
|
94 |
+
add_filter('woocommerce_order_amount_shipping', array($this, 'woocommerce_price'));
|
95 |
+
add_filter('woocommerce_order_amount_total_tax', array($this, 'woocommerce_price'));
|
96 |
}
|
97 |
|
98 |
add_filter('woocommerce_currency_symbol', array($this, 'woocommerce_currency_symbol'), 2);
|
111 |
add_filter('woocommerce_price_filter_max_price', array($this, 'price_filter_max_price'));
|
112 |
|
113 |
add_action('save_post', array($this, 'sync_variations'), 11, 2); // After WPML
|
114 |
+
add_filter('icl_make_duplicate', array($this, 'sync_variations_for_duplicates'), 11, 4);
|
115 |
+
|
116 |
|
117 |
add_action('admin_menu', array($this, 'menu'));
|
118 |
add_action('init', array($this, 'load_css_and_js'));
|
120 |
if(is_admin()){
|
121 |
add_action('admin_init', array($this, 'make_new_attributes_translatable'));
|
122 |
} else {
|
123 |
+
add_filter('pre_get_posts', array($this, 'shop_page_query'), 9);
|
124 |
+
add_filter('icl_ls_languages', array($this, 'translate_ls_shop_url'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
}
|
126 |
+
|
127 |
+
// Hooks for translating product attribute values
|
128 |
+
add_filter('woocommerce_variation_option_name', array($this, 'variation_term_name'));
|
129 |
+
add_filter('woocommerce_attribute', array($this, 'attribute_terms'));
|
130 |
|
131 |
if(isset($_POST['general_options']) && check_admin_referer('general_options', 'general_options_nonce')){
|
132 |
$enable_multi_currency = (isset($_POST['multi_currency'])) ? trim($_POST['multi_currency']) : null;
|
146 |
|
147 |
}
|
148 |
|
149 |
+
// set prices to copy/translate depending on settings
|
150 |
+
add_action('init', array($this, 'set_price_config'), 16); // After TM parses wpml-config.xml
|
151 |
+
|
152 |
if(isset($_POST['add_currency']) && check_admin_referer('add_currency', 'add_currency_nonce')){
|
153 |
global $wpdb, $pagenow;
|
154 |
|
232 |
add_action('option_woocommerce_tax_rates', array($this, 'tax_rates'));
|
233 |
}
|
234 |
|
235 |
+
function set_price_config() {
|
236 |
+
global $sitepress, $iclTranslationManagement;
|
237 |
+
|
238 |
+
$wpml_settings = $sitepress->get_settings();
|
239 |
+
if (!isset($wpml_settings['translation-management'])) {
|
240 |
+
return;
|
241 |
+
}
|
242 |
+
|
243 |
+
$multi = get_option('icl_enable_multi_currency', false);
|
244 |
+
$option = get_option('currency_converting_option', 1);
|
245 |
+
if ($multi && $option == 2) {
|
246 |
+
$mode = 2; // translate
|
247 |
+
} else {
|
248 |
+
$mode = 1; // copy
|
249 |
+
}
|
250 |
+
$keys = array(
|
251 |
+
'_regular_price',
|
252 |
+
'_sale_price',
|
253 |
+
'_price',
|
254 |
+
'_min_variation_regular_price',
|
255 |
+
'_min_variation_sale_price',
|
256 |
+
'_min_variation_price',
|
257 |
+
'_max_variation_regular_price',
|
258 |
+
'_max_variation_sale_price',
|
259 |
+
'_max_variation_price'
|
260 |
+
);
|
261 |
+
$save = false;
|
262 |
+
foreach ($keys as $key) {
|
263 |
+
$iclTranslationManagement->settings['custom_fields_readonly_config'][] = $key;
|
264 |
+
if (!isset($sitepress_settings['translation-management']['custom_fields_translation'][$key]) ||
|
265 |
+
$wpml_settings['translation-management']['custom_fields_translation'][$key] != $mode) {
|
266 |
+
$wpml_settings['translation-management']['custom_fields_translation'][$key] = $mode;
|
267 |
+
$save = true;
|
268 |
+
}
|
269 |
+
}
|
270 |
+
if ($save) {
|
271 |
+
$sitepress->save_settings($wpml_settings);
|
272 |
+
}
|
273 |
+
}
|
274 |
+
|
275 |
+
// Catch the default slugs for translation
|
276 |
+
function default_slug_translation($translation, $text, $context, $domain) {
|
277 |
+
if ($context == 'slug') {
|
278 |
+
// taxonomy slug translation is not ready yet, return no translation
|
279 |
+
if ($text == 'product-category' || $text == 'product-tag') {
|
280 |
+
return $text;
|
281 |
+
}
|
282 |
+
// re-request translation through URL slug context to trigger slug translation
|
283 |
+
return _x($text, 'URL slug', $domain);
|
284 |
+
}
|
285 |
+
return $translation;
|
286 |
+
}
|
287 |
+
|
288 |
+
function clean_term($terms) {
|
289 |
+
global $sitepress;
|
290 |
+
$terms->name = $sitepress->the_category_name_filter($terms->name);
|
291 |
+
return $terms;
|
292 |
+
}
|
293 |
+
|
294 |
+
// Catch custom slugs for translation
|
295 |
+
function custom_slug_translation($permalinks) {
|
296 |
+
if (!empty($permalinks['product_base'])) {
|
297 |
+
$permalinks['product_base'] = _x($permalinks['product_base'], 'URL slug', 'woocommerce');
|
298 |
+
}
|
299 |
+
return $permalinks;
|
300 |
+
}
|
301 |
+
|
302 |
function register_shipping_methods($available_methods){
|
303 |
|
304 |
foreach($available_methods as $method){
|
318 |
function tax_rates($rates){
|
319 |
if (!empty($rates)) {
|
320 |
foreach ($rates as &$rate) {
|
321 |
+
$rate['label'] = icl_translate('woocommerce', 'tax_label_' . esc_url_raw($rate['label']), $rate['label']);
|
322 |
}
|
323 |
}
|
324 |
|
441 |
* one of these must be true for product urls to work
|
442 |
* if none of these are true, display a warning message
|
443 |
*/
|
444 |
+
function check_for_incompatible_permalinks() {
|
445 |
+
global $sitepress, $sitepress_settings;
|
446 |
+
|
447 |
+
// Check if the shop prefix is disabled, if so we are ok
|
448 |
+
if (get_option('woocommerce_prepend_shop_page_to_products', 'yes') != "yes") {
|
449 |
+
return;
|
450 |
+
}
|
451 |
+
|
452 |
+
// Check if slug translation is enabled
|
453 |
+
$compatible = true;
|
454 |
+
if (!empty($sitepress_settings['posts_slug_translation']['on'])
|
455 |
+
&& !empty($sitepress_settings['posts_slug_translation']['types'])
|
456 |
+
&& $sitepress_settings['posts_slug_translation']['types']['product']) {
|
457 |
+
$compatible = false;
|
458 |
+
}
|
459 |
+
|
460 |
+
// Check if translated shop pages have the same slug
|
461 |
+
$allsame = true;
|
462 |
+
$shop_page_id = get_option('woocommerce_shop_page_id', false);
|
463 |
+
if (!empty($shop_page_id)) {
|
464 |
+
$slug = @get_page($shop_page_id)->post_name;
|
465 |
+
$languages = icl_get_languages('skip_missing=0');
|
466 |
+
if (sizeof($languages) < 2) {
|
467 |
+
return;
|
468 |
+
}
|
469 |
+
foreach ($languages as $language) {
|
470 |
+
if ($language['language_code'] != $sitepress->get_default_language()) {
|
471 |
+
$translated_shop_page_id = icl_object_id($shop_page_id, 'page', false, $language['language_code']);
|
472 |
+
if (!empty($translated_shop_page_id)) {
|
473 |
+
$translated_slug = get_page($translated_shop_page_id)->post_name;
|
474 |
+
if (!empty($translated_slug) && $translated_slug != $slug) {
|
475 |
+
$allsame = false;
|
476 |
+
break;
|
477 |
+
}
|
478 |
+
}
|
479 |
+
}
|
480 |
+
}
|
481 |
+
}
|
482 |
+
|
483 |
+
// display messages
|
484 |
+
if (!$allsame) {
|
485 |
+
?>
|
486 |
+
<div class="message error"><p><?php 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>', 'plugin woocommerce'),
|
487 |
+
$slug, $translated_slug, 'admin.php?page=woocommerce_settings&tab=pages'); ?></p></div>
|
488 |
+
<?php
|
489 |
+
}
|
490 |
+
if (!$compatible) {
|
491 |
+
?>
|
492 |
+
<div class="message error"><p><?php printf(__('If you want to translate product slugs, you need to disable the shop prefix for products in <a href="%s">WooCommerce Settings</a>', 'plugin woocommerce'),
|
493 |
+
'admin.php?page=woocommerce_settings&tab=pages'); ?></p></div>
|
494 |
+
<?php
|
495 |
+
}
|
496 |
+
}
|
497 |
|
498 |
/**
|
499 |
* Switch the language on AJAX action, because in some ways the correct language is missing.
|
717 |
} else if($translated_checkout_page_id == $post->ID || $checkout_page_id == $post->ID){
|
718 |
$value['is_checkout'] = 1;
|
719 |
|
720 |
+
//$value['locale'] = '';
|
721 |
|
722 |
$_SESSION['wpml_globalcart_language'] = $sitepress->get_current_language();
|
723 |
|
797 |
return $output;
|
798 |
}
|
799 |
|
800 |
+
/**
|
801 |
+
* Translates custom attribute/variation title.
|
802 |
+
*
|
803 |
+
* @return type
|
804 |
+
*/
|
805 |
+
function variation_term_name($term){
|
806 |
+
return icl_t('woocommerce', $term .'_attribute_name', $term);
|
807 |
+
}
|
|
|
808 |
|
809 |
+
function attribute_terms($terms){
|
810 |
+
// remove autop
|
811 |
+
$terms = str_replace('<p>', '', $terms);
|
812 |
+
$terms = str_replace('</p>', '', $terms);
|
813 |
+
|
814 |
+
// iterate terms translating
|
815 |
+
$terms = explode(",", $terms);
|
816 |
+
$out = array();
|
817 |
+
foreach ($terms as $term) {
|
818 |
+
$term = trim($term);
|
819 |
+
$out[] = icl_t('woocommerce', $term .'_attribute_name', $term);
|
820 |
+
}
|
821 |
+
|
822 |
+
return wpautop(wptexturize(implode(", ", $out)));
|
823 |
+
}
|
824 |
|
825 |
/**
|
826 |
* Translates the payment gateway title text.
|
856 |
|
857 |
$front_page_id = get_option('page_on_front');
|
858 |
$shop_page_id = get_option('woocommerce_shop_page_id');
|
859 |
+
$shop_page = get_post( woocommerce_get_page_id('shop') );
|
860 |
|
861 |
+
if (!empty($shop_page) && $q->get('page_id') !== $front_page_id && $shop_page_id == $q->get('page_id')) {
|
862 |
$q->set( 'post_type', 'product' );
|
863 |
$q->set( 'page_id', '' );
|
864 |
if ( isset( $q->query['paged'] ) )
|
868 |
// This is hacky but works. Awaiting http://core.trac.wordpress.org/ticket/21096
|
869 |
global $wp_post_types;
|
870 |
|
|
|
871 |
$q->is_page = true;
|
872 |
|
873 |
$wp_post_types['product']->ID = $shop_page->ID;
|
908 |
function woocommerce_price($price){
|
909 |
global $sitepress, $wpdb;
|
910 |
|
911 |
+
$sql = "SELECT value FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
|
912 |
$currency = $wpdb->get_results($sql, OBJECT);
|
913 |
|
914 |
if($currency){
|
931 |
function email_header() {
|
932 |
global $sitepress, $order_id;
|
933 |
|
934 |
+
$lang = null;
|
935 |
+
if (!current_user_can( 'manage_woocommerce' )) {
|
936 |
+
$lang = get_post_meta($order_id, 'wpml_language', TRUE);
|
937 |
+
}
|
938 |
|
939 |
if(empty($lang)){
|
940 |
if(isset($_SESSION['wpml_globalcart_language'])){
|
963 |
Only when translated products are ordered, force adjusting stock information for all translations
|
964 |
When a product in the default language is ordered stocks are adjusted automatically
|
965 |
*/
|
966 |
+
function sync_product_stocks($order){
|
967 |
+
global $sitepress;
|
968 |
+
$order_id = $order->id;
|
969 |
+
|
970 |
+
foreach ( $order->get_items() as $item ) {
|
971 |
+
|
972 |
+
if (isset($item['variation_id']) && $item['variation_id']>0){
|
973 |
+
$ld = $sitepress->get_element_language_details($item['variation_id'], 'post_product_variation');
|
974 |
+
$product_id = icl_object_id( $item['variation_id'], 'product_variation', true, $sitepress->get_default_language());
|
975 |
+
$_product = new WC_Product_Variation( $product_id );
|
976 |
+
}else{
|
977 |
+
$ld = $sitepress->get_element_language_details($item['id'], 'post_product');
|
978 |
+
$product_id = icl_object_id( $item['id'], 'product', true, $sitepress->get_default_language());
|
979 |
+
$_product = new WC_Product( $product_id );
|
980 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
981 |
|
982 |
+
// Process for non-default languages
|
983 |
+
if ($ld->language_code != $sitepress->get_default_language()) {
|
984 |
|
985 |
+
// Out of stock attribute
|
986 |
+
if ($_product->managing_stock() && !$_product->backorders_allowed() && $_product->get_total_stock()<=0){
|
987 |
+
$outofstock = 'outofstock';
|
988 |
+
}else{
|
989 |
+
$outofstock = false;
|
990 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
991 |
|
992 |
+
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
|
993 |
+
$stock = $_product->reduce_stock($item['qty']);
|
994 |
+
$total_sales = get_post_meta($_product->id, 'total_sales', true);
|
995 |
+
$total_sales += $item['qty'];
|
996 |
+
update_post_meta($product_id, 'total_sales', $total_sales);
|
997 |
+
}
|
998 |
+
}
|
999 |
+
}
|
1000 |
|
1001 |
}
|
1002 |
|
1064 |
|
1065 |
return $max_price;
|
1066 |
}
|
1067 |
+
|
1068 |
+
function sync_variations_for_duplicates($master_post_id, $lang, $postarr, $id) {
|
1069 |
+
$this->sync_variations($id, $postarr);
|
1070 |
+
}
|
1071 |
|
1072 |
function sync_variations($post_id, $post){
|
1073 |
global $wpdb, $pagenow, $sitepress;
|
1163 |
|
1164 |
if( ($pagenow == 'post.php' || $ajax_call ) && $post_type == 'product' && !empty($duplicated_post_id)){
|
1165 |
|
1166 |
+
$get_variation_term_id = $wpdb->get_var("SELECT term_id FROM $wpdb->terms WHERE name = 'variable'");
|
1167 |
+
$get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->term_relationships tr
|
1168 |
+
LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
1169 |
+
WHERE object_id = '$duplicated_post_id' AND taxonomy = 'product_type'");
|
1170 |
|
1171 |
+
$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_taxonomy_id'");
|
1172 |
if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
|
1173 |
|
1174 |
// synchronize term data, postmeta and post variations
|
1177 |
$get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
|
1178 |
WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
|
1179 |
|
1180 |
+
$duplicated_post_variation_ids = array();
|
1181 |
foreach($get_all_post_variations as $k => $post_data){
|
1182 |
$duplicated_post_variation_ids[] = $post_data->ID;
|
1183 |
}
|
1188 |
|
1189 |
if (!empty($variation_id)) {
|
1190 |
// Update variation
|
1191 |
+
wp_update_post(array(
|
1192 |
+
'ID' => $variation_id,
|
1193 |
'post_author' => $post_data->post_author,
|
1194 |
'post_date_gmt' => $post_data->post_date_gmt,
|
1195 |
'post_content' => $post_data->post_content,
|
1210 |
'post_type' => $post_data->post_type,
|
1211 |
'post_mime_type' => $post_data->post_mime_type,
|
1212 |
'comment_count' => $post_data->comment_count
|
1213 |
+
));
|
1214 |
} else {
|
1215 |
// Add new variation
|
1216 |
$guid = $post_data->guid;
|
1217 |
$replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
|
1218 |
$slug = $post_data->post_name;
|
1219 |
$replaced_slug = str_replace($duplicated_post_id, $post_id, $slug);
|
1220 |
+
$variation_id = wp_insert_post(array(
|
1221 |
'post_author' => $post_data->post_author,
|
1222 |
'post_date_gmt' => $post_data->post_date_gmt,
|
1223 |
'post_content' => $post_data->post_content,
|
1240 |
'post_mime_type' => $post_data->post_mime_type,
|
1241 |
'comment_count' => $post_data->comment_count
|
1242 |
));
|
|
|
1243 |
update_post_meta($variation_id, '_wcml_duplicate_of_variation', $post_data->ID);
|
1244 |
+
update_post_meta($variation_id, '_icl_duplicate_of', $post_data->ID);
|
1245 |
$trid = $sitepress->get_element_trid($post_data->ID, 'post_product_variation');
|
1246 |
$sitepress->set_element_language_details($variation_id, 'post_product_variation', $trid, $lang, $sitepress->get_default_language());
|
1247 |
}
|
1257 |
wp_delete_post($variation_id, true);
|
1258 |
}
|
1259 |
}
|
1260 |
+
|
1261 |
+
// custom fields to copy
|
1262 |
+
global $iclTranslationManagement;
|
1263 |
+
$cf = $iclTranslationManagement->settings['custom_fields_translation'];
|
1264 |
+
|
1265 |
+
// synchronize post variations post meta
|
1266 |
+
$current_post_variation_ids = array();
|
1267 |
+
foreach($get_current_post_variations as $k => $post_data){
|
1268 |
+
$current_post_variation_ids[] = $post_data->ID;
|
1269 |
+
}
|
1270 |
|
1271 |
+
$taxs = array();
|
1272 |
+
foreach($duplicated_post_variation_ids as $dp_key => $duplicated_post_variation_id){
|
1273 |
+
$get_all_post_meta = $wpdb->get_results("SELECT * FROM $wpdb->postmeta WHERE post_id = '$duplicated_post_variation_id'");
|
1274 |
+
|
1275 |
+
foreach($get_all_post_meta as $k => $post_meta){
|
1276 |
+
$meta_key = $post_meta->meta_key;
|
1277 |
+
$meta_value = $post_meta->meta_value;
|
1278 |
+
|
1279 |
+
// adjust the global attribute slug in the custom field
|
1280 |
+
$attid = null;
|
1281 |
+
if (substr($meta_key, 0, 10) == 'attribute_') {
|
1282 |
+
$tax = substr($meta_key, 10);
|
1283 |
+
if (taxonomy_exists($tax)) {
|
1284 |
+
$taxs[] = $tax;
|
1285 |
+
$attid = get_term_by('slug', $meta_value, $tax)->term_id;
|
1286 |
+
$attid = icl_object_id($attid, $tax, false, $lang);
|
1287 |
+
if (!$attid) {
|
1288 |
+
// if term not translated, skip
|
1289 |
+
continue;
|
1290 |
+
}
|
1291 |
+
$meta_value = get_term_by('id', $attid, $tax)->slug;
|
1292 |
+
} else {
|
1293 |
+
icl_register_string('woocommerce', $meta_value .'_attribute_name', $meta_value);
|
1294 |
+
}
|
1295 |
+
}
|
1296 |
+
// update current post variations meta
|
1297 |
+
if (!empty($attid) || in_array($meta_key, $cf) && $cf[$meta_key] == 1) {
|
1298 |
+
update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
|
1299 |
+
}
|
1300 |
+
}
|
1301 |
+
}
|
1302 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1303 |
// Sync terms
|
1304 |
+
$nontranslated = array();
|
1305 |
$taxs = array_unique($taxs);
|
1306 |
foreach ($taxs as $tax) {
|
1307 |
$terms = wp_get_object_terms($duplicated_post_id, $tax);
|
1308 |
$update = array();
|
1309 |
foreach ($terms as $term) {
|
1310 |
+
$term_id = intval(icl_object_id($term->term_id, $tax, false, $lang));
|
1311 |
+
if ($term_id > 0) {
|
1312 |
+
$update[] = $term_id;
|
1313 |
+
} else {
|
1314 |
+
// dont sync non-translated terms
|
1315 |
+
$nontranslated[] = $term;
|
1316 |
+
}
|
1317 |
}
|
1318 |
+
wp_set_object_terms($post_id, $update, $tax);
|
1319 |
}
|
1320 |
+
|
1321 |
}
|
1322 |
}
|
1323 |
}
|
1358 |
* Makes all new attributes translatable.
|
1359 |
*/
|
1360 |
function make_new_attributes_translatable(){
|
1361 |
+
global $sitepress;
|
1362 |
if(isset($_GET['page']) && $_GET['page'] == 'woocommerce_attributes'){
|
1363 |
|
1364 |
+
$wpml_settings = $sitepress->get_settings();
|
1365 |
|
1366 |
$get_all_taxonomies = get_taxonomies();
|
1367 |
|
1374 |
}
|
1375 |
}
|
1376 |
|
1377 |
+
$sitepress->save_settings($wpml_settings);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1378 |
}
|
1379 |
}
|
1380 |
|
wpml-config.xml
CHANGED
@@ -1,86 +1,54 @@
|
|
1 |
<wpml-config>
|
2 |
-
|
3 |
-
<custom-field action="copy">backorders</custom-field>
|
4 |
-
<custom-field action="copy">description</custom-field>
|
5 |
-
<custom-field action="copy">downloadable</custom-field>
|
6 |
-
<custom-field action="copy">featured</custom-field>
|
7 |
-
<custom-field action="copy">height</custom-field>
|
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>
|
14 |
-
<custom-field action="copy">sale_price_dates_to</custom-field>
|
15 |
-
<custom-field action="copy">seo_description</custom-field>
|
16 |
-
<custom-field action="copy">seo_follow</custom-field>
|
17 |
-
<custom-field action="copy">seo_keywords</custom-field>
|
18 |
-
<custom-field action="copy">sku</custom-field>
|
19 |
-
<custom-field action="copy">stock</custom-field>
|
20 |
-
<custom-field action="copy">stock_status</custom-field>
|
21 |
-
<custom-field action="copy">manage_stock</custom-field>
|
22 |
-
<custom-field action="copy">tax_class</custom-field>
|
23 |
-
<custom-field action="copy">tax_status</custom-field>
|
24 |
-
<custom-field action="copy">title</custom-field>
|
25 |
-
<custom-field action="copy">virtual</custom-field>
|
26 |
-
<custom-field action="copy">visibility</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">
|
|
|
32 |
<custom-field action="copy">_download_limit</custom-field>
|
|
|
33 |
<custom-field action="copy">_featured</custom-field>
|
34 |
<custom-field action="copy">_file_path</custom-field>
|
35 |
-
<custom-field action="copy">_height</custom-field>
|
36 |
-
<custom-field action="copy">_length</custom-field>
|
37 |
<custom-field action="copy">_manage_stock</custom-field>
|
38 |
-
<custom-field action="copy">
|
39 |
-
<custom-field action="copy">_max_variation_regular_price</custom-field>
|
40 |
-
<custom-field action="copy">_max_variation_sale_price</custom-field>
|
41 |
-
<custom-field action="copy">_min_variation_price</custom-field>
|
42 |
-
<custom-field action="copy">_min_variation_regular_price</custom-field>
|
43 |
-
<custom-field action="copy">_min_variation_sale_price</custom-field>
|
44 |
-
<custom-field action="copy">_price</custom-field>
|
45 |
<custom-field action="copy">_purchase_note</custom-field>
|
46 |
-
<custom-field action="copy">_regular_price</custom-field>
|
47 |
-
<custom-field action="copy">_sale_price</custom-field>
|
48 |
<custom-field action="copy">_sale_price_dates_from</custom-field>
|
49 |
<custom-field action="copy">_sale_price_dates_to</custom-field>
|
50 |
<custom-field action="copy">_sku</custom-field>
|
51 |
<custom-field action="copy">_stock</custom-field>
|
52 |
<custom-field action="copy">_stock_status</custom-field>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
<custom-field action="copy">_tax_class</custom-field>
|
54 |
<custom-field action="copy">_tax_status</custom-field>
|
55 |
-
<custom-field action="copy">
|
56 |
<custom-field action="copy">_virtual</custom-field>
|
57 |
<custom-field action="copy">_visibility</custom-field>
|
58 |
<custom-field action="copy">_weight</custom-field>
|
59 |
<custom-field action="copy">_width</custom-field>
|
|
|
|
|
60 |
<custom-field action="copy">_woocommerce_exclude_image</custom-field>
|
61 |
<custom-field action="copy">_wp_attached_file</custom-field>
|
62 |
-
<custom-field action="copy">
|
63 |
-
|
64 |
-
|
65 |
-
<custom-
|
66 |
-
<custom-field action="copy">_subscription_price</custom-field>
|
67 |
-
<custom-field action="copy">_subscription_trial_length</custom-field>
|
68 |
-
<custom-field action="copy">_subscription_sign_up_fee</custom-field>
|
69 |
-
<custom-field action="copy">_subscription_period</custom-field>
|
70 |
-
<custom-field action="copy">_subscription_period_interval</custom-field>
|
71 |
-
<custom-field action="copy">_subscription_length</custom-field>
|
72 |
-
<custom-field action="copy">_subscription_trial_period</custom-field>
|
73 |
-
</custom-fields>
|
74 |
-
<custom-types>
|
75 |
-
<custom-type translate="1">product</custom-type>
|
76 |
<custom-type translate="1">product_variation</custom-type>
|
77 |
<custom-type translate="0">shop_order</custom-type>
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
<taxonomy translate="0">shop_order_status</taxonomy>
|
83 |
<taxonomy translate="1">product_tag</taxonomy>
|
84 |
-
<taxonomy translate="
|
85 |
-
|
|
|
|
|
|
|
|
|
86 |
</wpml-config>
|
1 |
<wpml-config>
|
2 |
+
<custom-fields>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
<custom-field action="copy">_backorders</custom-field>
|
4 |
+
<custom-field action="copy">_crosssell_ids</custom-field>
|
5 |
+
<custom-field action="copy">_default_attributes</custom-field>
|
6 |
<custom-field action="copy">_download_limit</custom-field>
|
7 |
+
<custom-field action="copy">_downloadable</custom-field>
|
8 |
<custom-field action="copy">_featured</custom-field>
|
9 |
<custom-field action="copy">_file_path</custom-field>
|
|
|
|
|
10 |
<custom-field action="copy">_manage_stock</custom-field>
|
11 |
+
<custom-field action="copy">_product_attributes</custom-field>
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
<custom-field action="copy">_purchase_note</custom-field>
|
|
|
|
|
13 |
<custom-field action="copy">_sale_price_dates_from</custom-field>
|
14 |
<custom-field action="copy">_sale_price_dates_to</custom-field>
|
15 |
<custom-field action="copy">_sku</custom-field>
|
16 |
<custom-field action="copy">_stock</custom-field>
|
17 |
<custom-field action="copy">_stock_status</custom-field>
|
18 |
+
<custom-field action="copy">_subscription_length</custom-field>
|
19 |
+
<custom-field action="copy">_subscription_period</custom-field>
|
20 |
+
<custom-field action="copy">_subscription_period_interval</custom-field>
|
21 |
+
<custom-field action="copy">_subscription_price</custom-field>
|
22 |
+
<custom-field action="copy">_subscription_sign_up_fee</custom-field>
|
23 |
+
<custom-field action="copy">_subscription_trial_length</custom-field>
|
24 |
+
<custom-field action="copy">_subscription_trial_period</custom-field>
|
25 |
<custom-field action="copy">_tax_class</custom-field>
|
26 |
<custom-field action="copy">_tax_status</custom-field>
|
27 |
+
<custom-field action="copy">_upsell_ids</custom-field>
|
28 |
<custom-field action="copy">_virtual</custom-field>
|
29 |
<custom-field action="copy">_visibility</custom-field>
|
30 |
<custom-field action="copy">_weight</custom-field>
|
31 |
<custom-field action="copy">_width</custom-field>
|
32 |
+
<custom-field action="copy">_height</custom-field>
|
33 |
+
<custom-field action="copy">_length</custom-field>
|
34 |
<custom-field action="copy">_woocommerce_exclude_image</custom-field>
|
35 |
<custom-field action="copy">_wp_attached_file</custom-field>
|
36 |
+
<custom-field action="copy">total_sales</custom-field>
|
37 |
+
</custom-fields>
|
38 |
+
<custom-types>
|
39 |
+
<custom-type translate="1">product</custom-type>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
<custom-type translate="1">product_variation</custom-type>
|
41 |
<custom-type translate="0">shop_order</custom-type>
|
42 |
+
</custom-types>
|
43 |
+
<taxonomies>
|
44 |
+
<taxonomy translate="1">product_cat</taxonomy>
|
45 |
+
<taxonomy translate="0">product_type</taxonomy>
|
46 |
<taxonomy translate="0">shop_order_status</taxonomy>
|
47 |
<taxonomy translate="1">product_tag</taxonomy>
|
48 |
+
<taxonomy translate="0">product_shipping_class</taxonomy>
|
49 |
+
</taxonomies>
|
50 |
+
<admin-texts>
|
51 |
+
<key name="woocommerce_shop_page_title" />
|
52 |
+
<key name="woocommerce_email_footer_text" />
|
53 |
+
</admin-texts>
|
54 |
</wpml-config>
|
wpml-woocommerce.php
CHANGED
@@ -5,11 +5,11 @@
|
|
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.
|
9 |
*/
|
10 |
|
11 |
if(defined('WCML_VERSION')) return;
|
12 |
-
define('WCML_VERSION', '1.
|
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);
|
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.5
|
9 |
*/
|
10 |
|
11 |
if(defined('WCML_VERSION')) return;
|
12 |
+
define('WCML_VERSION', '1.5');
|
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);
|