Version Description
- Fix variation sync to more than one language
- Fix custom field sync for new variations
- Fix rounding of amounts in PayPal
- Adjust product stock sync to WC 2.x
- Add automatic id translation of logout page
- Adjust permalink warnings to WC 2.x
- Clean up code
Download this release
Release Info
Developer | dgwatkins |
Plugin | WooCommerce Multilingual – run WooCommerce with WPML |
Version | 2.0 |
Comparing to | |
See all releases |
Code changes from version 1.5 to 2.0
- readme.txt +24 -4
- woocommerce_wpml.class.php +367 -363
- wpml-config.xml +0 -1
- wpml-woocommerce.php +2 -2
readme.txt
CHANGED
@@ -5,7 +5,7 @@ Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multili
|
|
5 |
License: GPLv2
|
6 |
Requires at least: 3.0
|
7 |
Tested up to: 3.5
|
8 |
-
Stable tag:
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
@@ -13,7 +13,7 @@ Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
|
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 |
-
>>
|
17 |
|
18 |
= Features =
|
19 |
|
@@ -36,9 +36,9 @@ When you need help, go to [WPML technical support forum](http://wpml.org/forums/
|
|
36 |
|
37 |
= Downloads =
|
38 |
|
39 |
-
This version of WooCommerce Multilingual works with WooCommerce
|
40 |
|
41 |
-
You will also need [WPML](http://wpml.org), together with the String Translation
|
42 |
|
43 |
== Installation ==
|
44 |
|
@@ -68,6 +68,23 @@ In order for the checkout and store pages to appear translated, you need to crea
|
|
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.
|
@@ -133,6 +150,9 @@ In order for the checkout and store pages to appear translated, you need to crea
|
|
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 |
|
5 |
License: GPLv2
|
6 |
Requires at least: 3.0
|
7 |
Tested up to: 3.5
|
8 |
+
Stable tag: 2.0
|
9 |
|
10 |
Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
|
11 |
|
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 |
+
>> This version of WooCommerce Multilingual has been updated to work with WooCommerce 2.x. We are keeping backward compatibility with WooCommerce 1.x.
|
17 |
|
18 |
= Features =
|
19 |
|
36 |
|
37 |
= Downloads =
|
38 |
|
39 |
+
This version of WooCommerce Multilingual works with WooCommerce 2.x. It has been tested with [WooCommerce 2.0.3](http://downloads.wordpress.org/plugin/woocommerce.2.0.3.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 and the Translation Management modules, which are part of the [Multilingual CMS](http://wpml.org/purchase/) package.
|
42 |
|
43 |
== Installation ==
|
44 |
|
68 |
|
69 |
== Changelog ==
|
70 |
|
71 |
+
= 2.1 =
|
72 |
+
* Add admin notices for required plugins
|
73 |
+
* Add support for 'Review Order' and 'Lost Password' pages
|
74 |
+
* Fix rounding issues in currency conversion
|
75 |
+
* Variations: pick translated terms using 'trid' gives better results
|
76 |
+
* Variations: sync to all languages when there are more than 2 languages
|
77 |
+
* Improvement: load JS/CSS only when needed
|
78 |
+
|
79 |
+
= 2.0 =
|
80 |
+
* Fix variation sync to more than one language
|
81 |
+
* Fix custom field sync for new variations
|
82 |
+
* Fix rounding of amounts in PayPal
|
83 |
+
* Adjust product stock sync to WC 2.x
|
84 |
+
* Add automatic id translation of logout page
|
85 |
+
* Adjust permalink warnings to WC 2.x
|
86 |
+
* Clean up code
|
87 |
+
|
88 |
= 1.5 =
|
89 |
* Fixed manually setting prices in translated products.
|
90 |
* Take advantage of WPML's new slug translation feature.
|
150 |
|
151 |
== Upgrade Notice ==
|
152 |
|
153 |
+
= 2.0 =
|
154 |
+
More variation fixes and compatibility with WooCommerce 2.x
|
155 |
+
|
156 |
= 1.5 =
|
157 |
Variation translation works a lot better now. This version runs best with WooCommerce 1.6.6.
|
158 |
|
woocommerce_wpml.class.php
CHANGED
@@ -1,8 +1,9 @@
|
|
1 |
<?php
|
2 |
class woocommerce_wpml {
|
3 |
-
|
4 |
var $currencies;
|
5 |
-
|
|
|
6 |
function __construct(){
|
7 |
add_action('plugins_loaded', array($this, 'init'), 2);
|
8 |
$this->currencies = array(
|
@@ -17,22 +18,41 @@ class woocommerce_wpml {
|
|
17 |
'GBP' => '£'
|
18 |
);
|
19 |
}
|
20 |
-
|
21 |
function init(){
|
22 |
global $sitepress;
|
23 |
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
|
37 |
if(get_option('icl_is_wcml_installed') !== 'yes'){
|
38 |
$this->wcml_install();
|
@@ -40,17 +60,7 @@ class woocommerce_wpml {
|
|
40 |
|
41 |
add_action('admin_notices', array($this, 'check_for_incompatible_permalinks'));
|
42 |
|
43 |
-
add_filter('woocommerce_get_checkout_url', array($this, '
|
44 |
-
add_filter('woocommerce_get_checkout_page_id', array($this, 'checkout_page_id'));
|
45 |
-
add_filter('woocommerce_get_cart_page_id', array($this, 'get_cart_page_id'));
|
46 |
-
add_filter('woocommerce_get_myaccount_page_id', array($this, 'get_myaccount_page_id'));
|
47 |
-
add_filter('woocommerce_get_edit_address_page_id', array($this, 'get_edit_address_page_id'));
|
48 |
-
add_filter('woocommerce_get_view_order_page_id', array($this, 'get_view_order_page_id'));
|
49 |
-
add_filter('woocommerce_get_change_password_page_id', array($this, 'get_change_password_page_id'));
|
50 |
-
add_filter('woocommerce_get_thanks_page_id', array($this, 'get_thanks_page_id'));
|
51 |
-
add_filter('woocommerce_get_shop_page_id', array($this, 'shop_page_id'));
|
52 |
-
add_filter('woocommerce_get_terms_page_id', array($this, 'terms_page_id'));
|
53 |
-
add_filter('woocommerce_get_pay_page_id', array($this, 'pay_page_id'));
|
54 |
add_filter('woocommerce_get_checkout_payment_url', array($this, 'do_redirect'));
|
55 |
add_filter('woocommerce_get_cancel_order_url', array($this, 'do_redirect'));
|
56 |
add_filter('woocommerce_get_return_url', array($this, 'do_redirect'));
|
@@ -67,24 +77,26 @@ class woocommerce_wpml {
|
|
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 |
-
|
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
|
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'));
|
80 |
add_filter('option_woocommerce_cart_page_id', array($this, 'translate_pages_in_settings'));
|
81 |
add_filter('option_woocommerce_checkout_page_id', array($this, 'translate_pages_in_settings'));
|
|
|
82 |
add_filter('option_woocommerce_pay_page_id', array($this, 'translate_pages_in_settings'));
|
83 |
add_filter('option_woocommerce_thanks_page_id', array($this, 'translate_pages_in_settings'));
|
|
|
84 |
add_filter('option_woocommerce_myaccount_page_id', array($this, 'translate_pages_in_settings'));
|
85 |
add_filter('option_woocommerce_edit_address_page_id', array($this, 'translate_pages_in_settings'));
|
86 |
add_filter('option_woocommerce_view_order_page_id', array($this, 'translate_pages_in_settings'));
|
87 |
add_filter('option_woocommerce_change_password_page_id', array($this, 'translate_pages_in_settings'));
|
|
|
88 |
|
89 |
if(get_option('icl_enable_multi_currency') == 'yes'){
|
90 |
if(get_option('currency_converting_option') == '1'){
|
@@ -113,7 +125,6 @@ class woocommerce_wpml {
|
|
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'));
|
119 |
|
@@ -291,28 +302,12 @@ class woocommerce_wpml {
|
|
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){
|
305 |
-
|
306 |
-
icl_register_string('woocommerce', $method->label .'_shipping_method_title', $method->label);
|
307 |
-
}
|
308 |
-
|
309 |
-
if(function_exists('icl_t')){
|
310 |
-
$method->label = icl_t('woocommerce', $method->label .'_shipping_method_title', $method->label);
|
311 |
-
}
|
312 |
}
|
313 |
-
|
314 |
-
return $available_methods;
|
315 |
|
|
|
316 |
}
|
317 |
|
318 |
function tax_rates($rates){
|
@@ -383,35 +378,37 @@ class woocommerce_wpml {
|
|
383 |
return $languages;
|
384 |
}
|
385 |
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
|
404 |
-
|
|
|
|
|
405 |
|
406 |
-
|
407 |
-
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
|
416 |
/**
|
417 |
* Install the plugin.
|
@@ -444,9 +441,45 @@ class woocommerce_wpml {
|
|
444 |
function check_for_incompatible_permalinks() {
|
445 |
global $sitepress, $sitepress_settings;
|
446 |
|
447 |
-
|
448 |
-
|
449 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
}
|
451 |
|
452 |
// Check if slug translation is enabled
|
@@ -457,29 +490,6 @@ class woocommerce_wpml {
|
|
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 |
?>
|
@@ -489,8 +499,7 @@ class woocommerce_wpml {
|
|
489 |
}
|
490 |
if (!$compatible) {
|
491 |
?>
|
492 |
-
<div class="message error"><p><?php
|
493 |
-
'admin.php?page=woocommerce_settings&tab=pages'); ?></p></div>
|
494 |
<?php
|
495 |
}
|
496 |
}
|
@@ -508,30 +517,25 @@ class woocommerce_wpml {
|
|
508 |
}
|
509 |
|
510 |
/**
|
511 |
-
|
512 |
-
|
513 |
function search_products($found_products){
|
514 |
global $wpdb, $sitepress;
|
515 |
|
516 |
$current_page_language = $sitepress->get_current_language();
|
517 |
|
518 |
-
|
519 |
-
|
520 |
$product_language = $post_data->language_code;
|
521 |
|
522 |
if($product_language !== $current_page_language){
|
523 |
unset($found_products[$product_id]);
|
524 |
-
|
525 |
-
|
526 |
|
527 |
return $found_products;
|
528 |
}
|
529 |
-
|
530 |
-
// Return the correct amount in a second language.
|
531 |
-
function paypal_amount($amount){
|
532 |
-
return $amount;
|
533 |
-
}
|
534 |
-
|
535 |
// Set multilingual currency.
|
536 |
function set_ml_currency($currency){
|
537 |
global $wpdb, $sitepress;
|
@@ -565,92 +569,9 @@ class woocommerce_wpml {
|
|
565 |
/**
|
566 |
* Filters WooCommerce checkout link.
|
567 |
*/
|
568 |
-
function
|
569 |
return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
|
570 |
}
|
571 |
-
|
572 |
-
/**
|
573 |
-
* Filters WooCommerce checkout page id.
|
574 |
-
*/
|
575 |
-
function checkout_page_id(){
|
576 |
-
return icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true);
|
577 |
-
}
|
578 |
-
|
579 |
-
/**
|
580 |
-
* Filters WooCommerce cart link.
|
581 |
-
*/
|
582 |
-
function get_cart_page_id() {
|
583 |
-
return icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
|
584 |
-
}
|
585 |
-
|
586 |
-
/**
|
587 |
-
* Filters WooCommerce my account link.
|
588 |
-
*/
|
589 |
-
function get_myaccount_page_id(){
|
590 |
-
return icl_object_id(get_option('woocommerce_myaccount_page_id'), 'page', true);
|
591 |
-
}
|
592 |
-
|
593 |
-
/**
|
594 |
-
* Filters WooCommerce my account edit address link.
|
595 |
-
*/
|
596 |
-
function get_edit_address_page_id(){
|
597 |
-
return icl_object_id(get_option('woocommerce_edit_address_page_id'), 'page', true);
|
598 |
-
}
|
599 |
-
|
600 |
-
/**
|
601 |
-
* Filters WooCommerce view order link.
|
602 |
-
*/
|
603 |
-
function get_view_order_page_id(){
|
604 |
-
// avoid redirect to the my account page
|
605 |
-
if(get_option('woocommerce_view_order_page_id') !== get_option('woocommerce_checkout_page_id')){
|
606 |
-
$return = icl_object_id(get_option('woocommerce_view_order_page_id'), 'page', true);
|
607 |
-
} else {
|
608 |
-
$return = false;
|
609 |
-
}
|
610 |
-
|
611 |
-
return $return;
|
612 |
-
}
|
613 |
-
|
614 |
-
/**
|
615 |
-
* Filters WooCommerce my account change password link.
|
616 |
-
*/
|
617 |
-
function get_change_password_page_id(){
|
618 |
-
return icl_object_id(get_option('woocommerce_change_password_page_id'), 'page', true);
|
619 |
-
}
|
620 |
-
|
621 |
-
/**
|
622 |
-
* Filters WooCommerce thanks link.
|
623 |
-
*/
|
624 |
-
function get_thanks_page_id(){
|
625 |
-
return icl_object_id(get_option('woocommerce_thanks_page_id'), 'page', true);
|
626 |
-
}
|
627 |
-
|
628 |
-
/**
|
629 |
-
* Filters WooCommerce shop link.
|
630 |
-
*/
|
631 |
-
function shop_page_id(){
|
632 |
-
return icl_object_id(get_option('woocommerce_shop_page_id'), 'page', false);
|
633 |
-
}
|
634 |
-
|
635 |
-
/**
|
636 |
-
* Filters WooCommerce terms link.
|
637 |
-
*/
|
638 |
-
function terms_page_id(){
|
639 |
-
return icl_object_id(get_option('woocommerce_terms_page_id'), 'page', false);
|
640 |
-
}
|
641 |
-
|
642 |
-
/**
|
643 |
-
* Filters WooCommerce pay page id
|
644 |
-
*/
|
645 |
-
function pay_page_id(){
|
646 |
-
$is_cart_page = icl_object_id(get_option('woocommerce_cart_page_id'), 'page', true);
|
647 |
-
|
648 |
-
if(is_page($is_cart_page)){
|
649 |
-
//return
|
650 |
-
} else {
|
651 |
-
return icl_object_id(get_option('woocommerce_pay_page_id'), 'page', true);
|
652 |
-
}
|
653 |
-
}
|
654 |
|
655 |
/**
|
656 |
* After email translation switch language to default.
|
@@ -788,7 +709,7 @@ class woocommerce_wpml {
|
|
788 |
global $post;
|
789 |
|
790 |
$post_type = get_post_type($post->ID);
|
791 |
-
$checkout_page_id =
|
792 |
|
793 |
if($post_type == 'product' || is_page($checkout_page_id)){
|
794 |
$output = '';
|
@@ -807,6 +728,7 @@ class woocommerce_wpml {
|
|
807 |
}
|
808 |
|
809 |
function attribute_terms($terms){
|
|
|
810 |
// remove autop
|
811 |
$terms = str_replace('<p>', '', $terms);
|
812 |
$terms = str_replace('</p>', '', $terms);
|
@@ -816,7 +738,12 @@ class woocommerce_wpml {
|
|
816 |
$out = array();
|
817 |
foreach ($terms as $term) {
|
818 |
$term = trim($term);
|
819 |
-
|
|
|
|
|
|
|
|
|
|
|
820 |
}
|
821 |
|
822 |
return wpautop(wptexturize(implode(", ", $out)));
|
@@ -908,15 +835,16 @@ class woocommerce_wpml {
|
|
908 |
function woocommerce_price($price){
|
909 |
global $sitepress, $wpdb;
|
910 |
|
911 |
-
|
912 |
-
|
913 |
-
|
914 |
-
|
915 |
-
|
916 |
-
|
917 |
-
|
918 |
-
|
919 |
-
|
|
|
920 |
|
921 |
return $price;
|
922 |
}
|
@@ -931,10 +859,7 @@ class woocommerce_wpml {
|
|
931 |
function email_header() {
|
932 |
global $sitepress, $order_id;
|
933 |
|
934 |
-
$lang =
|
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'])){
|
@@ -959,16 +884,51 @@ class woocommerce_wpml {
|
|
959 |
$sitepress->switch_lang();
|
960 |
}
|
961 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
962 |
/*
|
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
|
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());
|
@@ -1000,6 +960,41 @@ class woocommerce_wpml {
|
|
1000 |
|
1001 |
}
|
1002 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1003 |
/**
|
1004 |
* Adds language to order post type.
|
1005 |
*
|
@@ -1033,7 +1028,7 @@ class woocommerce_wpml {
|
|
1033 |
if($currency){
|
1034 |
$exchange_rate = $currency[0]->value;
|
1035 |
$min_price = $min_price / $exchange_rate;
|
1036 |
-
$min_price = round($min_price);
|
1037 |
}
|
1038 |
}
|
1039 |
|
@@ -1058,51 +1053,71 @@ class woocommerce_wpml {
|
|
1058 |
if($currency){
|
1059 |
$exchange_rate = $currency[0]->value;
|
1060 |
$max_price = $max_price / $exchange_rate;
|
1061 |
-
$max_price = round($max_price);
|
1062 |
}
|
1063 |
}
|
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 |
-
|
1073 |
-
|
|
|
|
|
|
|
1074 |
|
|
|
1075 |
$post_type = get_post_type($post_id);
|
1076 |
-
|
1077 |
-
|
|
|
1078 |
|
1079 |
// exceptions
|
|
|
|
|
1080 |
if (empty($duplicated_post_id) || isset($_POST['autosave'])) {
|
1081 |
return;
|
1082 |
}
|
1083 |
-
|
|
|
|
|
|
|
1084 |
// get language code
|
1085 |
$language_details = $sitepress->get_element_language_details($post_id, 'post_product');
|
1086 |
if (empty($language_details)) {
|
1087 |
return;
|
1088 |
}
|
1089 |
-
$lang = $language_details->language_code;
|
1090 |
-
|
1091 |
-
if ($lang == $sitepress->get_default_language()) {
|
1092 |
-
return;
|
1093 |
-
}
|
1094 |
|
1095 |
-
//
|
1096 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1097 |
|
|
|
1098 |
$original_product_upsell_ids = get_post_meta($duplicated_post_id, '_upsell_ids', TRUE);
|
1099 |
if(!empty($original_product_upsell_ids)){
|
1100 |
$unserialized_upsell_ids = maybe_unserialize($original_product_upsell_ids);
|
1101 |
-
|
1102 |
foreach($unserialized_upsell_ids as $k => $product_id){
|
1103 |
// get the correct language
|
1104 |
$upsell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
|
1105 |
-
|
1106 |
if($upsell_product_translation_id){
|
1107 |
$unserialized_upsell_ids[$k] = $upsell_product_translation_id;
|
1108 |
// if it isn't translated - unset it
|
@@ -1110,20 +1125,20 @@ class woocommerce_wpml {
|
|
1110 |
unset($unserialized_upsell_ids[$k]);
|
1111 |
}
|
1112 |
}
|
1113 |
-
|
1114 |
$data = array('meta_value' => maybe_serialize($unserialized_upsell_ids));
|
1115 |
$where = array('post_id' => $post_id, 'meta_key' => '_upsell_ids');
|
1116 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1117 |
}
|
1118 |
-
|
1119 |
$original_product_crosssell_ids = get_post_meta($duplicated_post_id, '_crosssell_ids', TRUE);
|
1120 |
if(!empty($original_product_crosssell_ids)){
|
1121 |
$unserialized_crosssell_ids = maybe_unserialize($original_product_crosssell_ids);
|
1122 |
-
|
1123 |
foreach($unserialized_crosssell_ids as $k => $product_id){
|
1124 |
// get the correct language
|
1125 |
$crosssell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
|
1126 |
-
|
1127 |
if($crosssell_product_translation_id){
|
1128 |
$unserialized_crosssell_ids[$k] = $crosssell_product_translation_id;
|
1129 |
// if it isn't translated - unset it
|
@@ -1131,12 +1146,12 @@ class woocommerce_wpml {
|
|
1131 |
unset($unserialized_crosssell_ids[$k]);
|
1132 |
}
|
1133 |
}
|
1134 |
-
|
1135 |
$data = array('meta_value' => maybe_serialize($unserialized_crosssell_ids));
|
1136 |
$where = array('post_id' => $post_id, 'meta_key' => '_crosssell_ids');
|
1137 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1138 |
}
|
1139 |
-
|
1140 |
$original_default_attributes = get_post_meta($duplicated_post_id, '_default_attributes', TRUE);
|
1141 |
if(!empty($original_default_attributes)){
|
1142 |
$unserialized_default_attributes = maybe_unserialize($original_default_attributes);
|
@@ -1153,114 +1168,110 @@ class woocommerce_wpml {
|
|
1153 |
unset($unserialized_default_attributes[$attribute]);
|
1154 |
}
|
1155 |
}
|
1156 |
-
|
1157 |
$data = array('meta_value' => maybe_serialize($unserialized_default_attributes));
|
1158 |
$where = array('post_id' => $post_id, 'meta_key' => '_default_attributes');
|
1159 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1160 |
}
|
1161 |
|
1162 |
-
|
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 |
-
|
1172 |
-
|
1173 |
|
1174 |
-
|
1175 |
-
|
1176 |
-
|
1177 |
-
|
1178 |
-
|
1179 |
|
1180 |
-
|
1181 |
-
|
1182 |
-
|
1183 |
-
|
1184 |
|
1185 |
-
|
1186 |
-
|
1187 |
-
|
1188 |
-
|
1189 |
-
|
1190 |
-
|
1191 |
-
|
1192 |
-
|
1193 |
-
|
1194 |
-
|
1195 |
-
|
1196 |
-
|
1197 |
-
|
1198 |
-
|
1199 |
-
|
1200 |
-
|
1201 |
-
|
1202 |
-
|
1203 |
-
|
1204 |
-
|
1205 |
-
|
1206 |
-
|
1207 |
-
|
1208 |
-
|
1209 |
-
|
1210 |
-
|
1211 |
-
|
1212 |
-
|
1213 |
-
|
1214 |
-
|
1215 |
-
|
1216 |
-
|
1217 |
-
|
1218 |
-
|
1219 |
-
|
1220 |
-
|
1221 |
-
|
1222 |
-
|
1223 |
-
|
1224 |
-
|
1225 |
-
|
1226 |
-
|
1227 |
-
|
1228 |
-
|
1229 |
-
|
1230 |
-
|
1231 |
-
|
1232 |
-
|
1233 |
-
|
1234 |
-
|
1235 |
-
|
1236 |
-
|
1237 |
-
|
1238 |
-
|
1239 |
-
|
1240 |
-
|
1241 |
-
|
1242 |
-
|
1243 |
-
|
1244 |
-
|
1245 |
-
|
1246 |
-
|
1247 |
-
|
1248 |
-
|
|
|
1249 |
|
1250 |
-
|
1251 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1252 |
|
1253 |
-
// Delete variations that no longer exist
|
1254 |
-
foreach ($get_current_post_variations as $post_data) {
|
1255 |
-
$variation_id = get_post_meta($post_data->ID, '_wcml_duplicate_of_variation', true);
|
1256 |
-
if (!in_array($variation_id, $duplicated_post_variation_ids)) {
|
1257 |
-
wp_delete_post($variation_id, true);
|
1258 |
-
}
|
1259 |
-
}
|
1260 |
-
|
1261 |
// custom fields to copy
|
1262 |
-
|
1263 |
-
$cf = $iclTranslationManagement->settings['custom_fields_translation'];
|
1264 |
|
1265 |
// synchronize post variations post meta
|
1266 |
$current_post_variation_ids = array();
|
@@ -1282,45 +1293,43 @@ class woocommerce_wpml {
|
|
1282 |
$tax = substr($meta_key, 10);
|
1283 |
if (taxonomy_exists($tax)) {
|
1284 |
$taxs[] = $tax;
|
1285 |
-
$attid = get_term_by('slug', $meta_value, $tax)->
|
1286 |
-
$
|
1287 |
-
if (
|
1288 |
-
|
1289 |
-
|
|
|
|
|
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 (
|
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 |
-
$
|
1311 |
-
|
1312 |
-
|
1313 |
-
|
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 |
-
|
|
|
|
|
1324 |
|
1325 |
/**
|
1326 |
* Creates WCML page.
|
@@ -1343,15 +1352,10 @@ class woocommerce_wpml {
|
|
1343 |
* Adds additional CSS and JS.
|
1344 |
*/
|
1345 |
function load_css_and_js() {
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
plugin_dir_url(__FILE__) . '/assets/js/jquery.validate.min.js',
|
1351 |
-
array('jquery'),
|
1352 |
-
'1.8.1',
|
1353 |
-
true
|
1354 |
-
);
|
1355 |
}
|
1356 |
|
1357 |
/**
|
1 |
<?php
|
2 |
class woocommerce_wpml {
|
3 |
+
|
4 |
var $currencies;
|
5 |
+
var $missing;
|
6 |
+
|
7 |
function __construct(){
|
8 |
add_action('plugins_loaded', array($this, 'init'), 2);
|
9 |
$this->currencies = array(
|
18 |
'GBP' => '£'
|
19 |
);
|
20 |
}
|
21 |
+
|
22 |
function init(){
|
23 |
global $sitepress;
|
24 |
|
25 |
+
$allok = true;
|
26 |
+
$this->missing = array();
|
27 |
+
if(!defined('ICL_SITEPRESS_VERSION') || ICL_PLUGIN_INACTIVE){
|
28 |
+
if(!function_exists('is_multisite') || !is_multisite()) {
|
29 |
+
$this->missing['WPML'] = 'http://wpml.org';
|
30 |
+
$allok = false;
|
31 |
+
}
|
32 |
+
} else if(version_compare(ICL_SITEPRESS_VERSION, '2.0.5', '<')){
|
33 |
+
add_action('admin_notices', array($this, 'old_wpml_warning'));
|
34 |
+
$allok = false;
|
35 |
+
}
|
36 |
+
|
37 |
+
if(!class_exists('woocommerce')){
|
38 |
+
$this->missing['WooCommerce'] = 'http://www.woothemes.com/woocommerce/';
|
39 |
+
$allok = false;
|
40 |
+
}
|
41 |
+
|
42 |
+
if(!defined('WPML_TM_VERSION')){
|
43 |
+
$this->missing['WPML Translation Management'] = 'http://wpml.org';
|
44 |
+
$allok = false;
|
45 |
+
}
|
46 |
+
|
47 |
+
if(!defined('WPML_ST_VERSION')){
|
48 |
+
$this->missing['WPML String Translation'] = 'http://wpml.org';
|
49 |
+
$allok = false;
|
50 |
+
}
|
51 |
+
|
52 |
+
if (!$allok) {
|
53 |
+
add_action('admin_notices', array($this, 'missing_plugins_warning'));
|
54 |
+
return false;
|
55 |
+
}
|
56 |
|
57 |
if(get_option('icl_is_wcml_installed') !== 'yes'){
|
58 |
$this->wcml_install();
|
60 |
|
61 |
add_action('admin_notices', array($this, 'check_for_incompatible_permalinks'));
|
62 |
|
63 |
+
add_filter('woocommerce_get_checkout_url', array($this, 'get_checkout_page_url'));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
add_filter('woocommerce_get_checkout_payment_url', array($this, 'do_redirect'));
|
65 |
add_filter('woocommerce_get_cancel_order_url', array($this, 'do_redirect'));
|
66 |
add_filter('woocommerce_get_return_url', array($this, 'do_redirect'));
|
77 |
add_filter('woocommerce_gateway_description', array($this, 'gateway_description'), 10, 2);
|
78 |
add_filter('woocommerce_json_search_found_products', array($this, 'search_products'));
|
79 |
add_filter('woocommerce_currency', array($this, 'set_ml_currency'));
|
80 |
+
add_action('admin_print_scripts', array($this,'js_scripts_setup'), 11);
|
|
|
81 |
add_action('init', array($this, 'translate_email_notifications'));
|
82 |
|
83 |
+
// Slug translation
|
84 |
add_filter('gettext_with_context', array($this, 'default_slug_translation'), 0, 4);
|
|
|
85 |
|
86 |
+
// Translate shop page ids
|
87 |
add_filter('option_woocommerce_shop_page_id', array($this, 'translate_pages_in_settings'));
|
88 |
add_filter('option_woocommerce_terms_page_id', array($this, 'translate_pages_in_settings'));
|
89 |
add_filter('option_woocommerce_cart_page_id', array($this, 'translate_pages_in_settings'));
|
90 |
add_filter('option_woocommerce_checkout_page_id', array($this, 'translate_pages_in_settings'));
|
91 |
+
add_filter('option_woocommerce_review_order_page_id', array($this, 'translate_pages_in_settings'));
|
92 |
add_filter('option_woocommerce_pay_page_id', array($this, 'translate_pages_in_settings'));
|
93 |
add_filter('option_woocommerce_thanks_page_id', array($this, 'translate_pages_in_settings'));
|
94 |
+
add_filter('option_woocommerce_lost_password_page_id', array($this, 'translate_pages_in_settings'));
|
95 |
add_filter('option_woocommerce_myaccount_page_id', array($this, 'translate_pages_in_settings'));
|
96 |
add_filter('option_woocommerce_edit_address_page_id', array($this, 'translate_pages_in_settings'));
|
97 |
add_filter('option_woocommerce_view_order_page_id', array($this, 'translate_pages_in_settings'));
|
98 |
add_filter('option_woocommerce_change_password_page_id', array($this, 'translate_pages_in_settings'));
|
99 |
+
add_filter('option_woocommerce_logout_page_id', array($this, 'translate_pages_in_settings'));
|
100 |
|
101 |
if(get_option('icl_enable_multi_currency') == 'yes'){
|
102 |
if(get_option('currency_converting_option') == '1'){
|
125 |
add_action('save_post', array($this, 'sync_variations'), 11, 2); // After WPML
|
126 |
add_filter('icl_make_duplicate', array($this, 'sync_variations_for_duplicates'), 11, 4);
|
127 |
|
|
|
128 |
add_action('admin_menu', array($this, 'menu'));
|
129 |
add_action('init', array($this, 'load_css_and_js'));
|
130 |
|
302 |
return $terms;
|
303 |
}
|
304 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
305 |
function register_shipping_methods($available_methods){
|
|
|
306 |
foreach($available_methods as $method){
|
307 |
+
$method->label = icl_translate('woocommerce', $method->label .'_shipping_method_title', $method->label);
|
|
|
|
|
|
|
|
|
|
|
|
|
308 |
}
|
|
|
|
|
309 |
|
310 |
+
return $available_methods;
|
311 |
}
|
312 |
|
313 |
function tax_rates($rates){
|
378 |
return $languages;
|
379 |
}
|
380 |
|
381 |
+
/**
|
382 |
+
* Adds admin notice.
|
383 |
+
*/
|
384 |
+
function missing_plugins_warning(){
|
385 |
+
$missing = '';
|
386 |
+
$counter = 0;
|
387 |
+
foreach ($this->missing as $title => $url) {
|
388 |
+
$counter ++;
|
389 |
+
if ($counter == sizeof($this->missing)) {
|
390 |
+
$sep = '';
|
391 |
+
} elseif ($counter == sizeof($this->missing) - 1) {
|
392 |
+
$sep = ' ' . __('and', 'plugin woocommerce') . ' ';
|
393 |
+
} else {
|
394 |
+
$sep = ', ';
|
395 |
+
}
|
396 |
+
$missing .= '<a href="' . $url . '">' . $title . '</a>' . $sep;
|
397 |
+
}
|
398 |
+
?>
|
399 |
+
<div class="message error"><p><?php printf(__('WooCommerce Multilingual is enabled but not effective. It requires %s in order to work.', 'plugin woocommerce'), $missing); ?></p></div>
|
400 |
+
<?php
|
401 |
+
}
|
402 |
|
403 |
+
/**
|
404 |
+
* Adds admin notice.
|
405 |
+
*/
|
406 |
+
function old_wpml_warning(){
|
407 |
+
?>
|
408 |
+
<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'),
|
409 |
+
'http://wpml.org/'); ?></p></div>
|
410 |
+
<?php
|
411 |
+
}
|
412 |
|
413 |
/**
|
414 |
* Install the plugin.
|
441 |
function check_for_incompatible_permalinks() {
|
442 |
global $sitepress, $sitepress_settings;
|
443 |
|
444 |
+
if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
|
445 |
+
// WooCommerce 2.x specific checks
|
446 |
+
$permalinks = get_option('woocommerce_permalinks', array('product_base' => ''));
|
447 |
+
if (empty($permalinks['product_base'])) {
|
448 |
+
return;
|
449 |
+
}
|
450 |
+
$message = sprintf(__('If you want to translate product slugs, you need to keep the default permalink structure for products in <a href="%s">Permalink Settings</a>', 'plugin woocommerce'), 'options-permalink.php');
|
451 |
+
} else {
|
452 |
+
// WooCommerce 1.x specific checks
|
453 |
+
if (get_option('woocommerce_prepend_shop_page_to_products', 'yes') != "yes") {
|
454 |
+
return;
|
455 |
+
}
|
456 |
+
$message = sprintf(__('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'), 'admin.php?page=woocommerce_settings&tab=pages');
|
457 |
+
}
|
458 |
+
|
459 |
+
// Check if translated shop pages have the same slug (only 1.x)
|
460 |
+
$allsame = true;
|
461 |
+
if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
|
462 |
+
} else {
|
463 |
+
$shop_page_id = get_option('woocommerce_shop_page_id', false);
|
464 |
+
if (!empty($shop_page_id)) {
|
465 |
+
$slug = @get_page($shop_page_id)->post_name;
|
466 |
+
$languages = icl_get_languages('skip_missing=0');
|
467 |
+
if (sizeof($languages) < 2) {
|
468 |
+
return;
|
469 |
+
}
|
470 |
+
foreach ($languages as $language) {
|
471 |
+
if ($language['language_code'] != $sitepress->get_default_language()) {
|
472 |
+
$translated_shop_page_id = icl_object_id($shop_page_id, 'page', false, $language['language_code']);
|
473 |
+
if (!empty($translated_shop_page_id)) {
|
474 |
+
$translated_slug = get_page($translated_shop_page_id)->post_name;
|
475 |
+
if (!empty($translated_slug) && $translated_slug != $slug) {
|
476 |
+
$allsame = false;
|
477 |
+
break;
|
478 |
+
}
|
479 |
+
}
|
480 |
+
}
|
481 |
+
}
|
482 |
+
}
|
483 |
}
|
484 |
|
485 |
// Check if slug translation is enabled
|
490 |
$compatible = false;
|
491 |
}
|
492 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
493 |
// display messages
|
494 |
if (!$allsame) {
|
495 |
?>
|
499 |
}
|
500 |
if (!$compatible) {
|
501 |
?>
|
502 |
+
<div class="message error"><p><?php echo $message; ?></p></div>
|
|
|
503 |
<?php
|
504 |
}
|
505 |
}
|
517 |
}
|
518 |
|
519 |
/**
|
520 |
+
* Filters upsell/crosell products in the correct language.
|
521 |
+
*/
|
522 |
function search_products($found_products){
|
523 |
global $wpdb, $sitepress;
|
524 |
|
525 |
$current_page_language = $sitepress->get_current_language();
|
526 |
|
527 |
+
foreach($found_products as $product_id => $output_v){
|
528 |
+
$post_data = $wpdb->get_row("SELECT * FROM ". $wpdb->prefix ."icl_translations WHERE element_id = '$product_id'");
|
529 |
$product_language = $post_data->language_code;
|
530 |
|
531 |
if($product_language !== $current_page_language){
|
532 |
unset($found_products[$product_id]);
|
533 |
+
}
|
534 |
+
}
|
535 |
|
536 |
return $found_products;
|
537 |
}
|
538 |
+
|
|
|
|
|
|
|
|
|
|
|
539 |
// Set multilingual currency.
|
540 |
function set_ml_currency($currency){
|
541 |
global $wpdb, $sitepress;
|
569 |
/**
|
570 |
* Filters WooCommerce checkout link.
|
571 |
*/
|
572 |
+
function get_checkout_page_url(){
|
573 |
return get_permalink(icl_object_id(get_option('woocommerce_checkout_page_id'), 'page', true));
|
574 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
575 |
|
576 |
/**
|
577 |
* After email translation switch language to default.
|
709 |
global $post;
|
710 |
|
711 |
$post_type = get_post_type($post->ID);
|
712 |
+
$checkout_page_id = get_option('woocommerce_checkout_page_id');
|
713 |
|
714 |
if($post_type == 'product' || is_page($checkout_page_id)){
|
715 |
$output = '';
|
728 |
}
|
729 |
|
730 |
function attribute_terms($terms){
|
731 |
+
global $sitepress;
|
732 |
// remove autop
|
733 |
$terms = str_replace('<p>', '', $terms);
|
734 |
$terms = str_replace('</p>', '', $terms);
|
738 |
$out = array();
|
739 |
foreach ($terms as $term) {
|
740 |
$term = trim($term);
|
741 |
+
if ($sitepress->get_default_language() == $sitepress->get_current_language()) {
|
742 |
+
$term = icl_translate('woocommerce', $term .'_attribute_name', $term);
|
743 |
+
} else {
|
744 |
+
$term = icl_t('woocommerce', $term .'_attribute_name', $term);
|
745 |
+
}
|
746 |
+
$out[] = $term;
|
747 |
}
|
748 |
|
749 |
return wpautop(wptexturize(implode(", ", $out)));
|
835 |
function woocommerce_price($price){
|
836 |
global $sitepress, $wpdb;
|
837 |
|
838 |
+
if (get_option('icl_enable_multi_currency') != 'yes') {
|
839 |
+
$sql = "SELECT value FROM ". $wpdb->prefix ."icl_currencies WHERE language_code = '". $sitepress->get_current_language() ."'";
|
840 |
+
$currency = $wpdb->get_results($sql, OBJECT);
|
841 |
+
|
842 |
+
if($currency){
|
843 |
+
$exchange_rate = $currency[0]->value;
|
844 |
+
$price = round($price * $exchange_rate, (int) get_option( 'woocommerce_price_num_decimals' ));
|
845 |
+
$price = apply_filters('woocommerce_multilingual_price', $price);
|
846 |
+
}
|
847 |
+
}
|
848 |
|
849 |
return $price;
|
850 |
}
|
859 |
function email_header() {
|
860 |
global $sitepress, $order_id;
|
861 |
|
862 |
+
$lang = get_post_meta($order_id, 'wpml_language', TRUE);
|
|
|
|
|
|
|
863 |
|
864 |
if(empty($lang)){
|
865 |
if(isset($_SESSION['wpml_globalcart_language'])){
|
884 |
$sitepress->switch_lang();
|
885 |
}
|
886 |
|
887 |
+
/*
|
888 |
+
* WC compat layer: get product id
|
889 |
+
*/
|
890 |
+
|
891 |
+
function get_product_id_from_order_item($item) {
|
892 |
+
if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
|
893 |
+
// WC 2.0
|
894 |
+
return isset($item['product_id']) ? $item['product_id'] : false;
|
895 |
+
} else {
|
896 |
+
return isset($item['product_id']) ? $item['product_id'] : false;
|
897 |
+
}
|
898 |
+
}
|
899 |
+
|
900 |
+
|
901 |
+
/*
|
902 |
+
* WC compat layer: get product
|
903 |
+
*/
|
904 |
+
|
905 |
+
function wcml_get_product($product_id) {
|
906 |
+
if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
|
907 |
+
// WC 2.0
|
908 |
+
return get_product( $product_id);
|
909 |
+
} else {
|
910 |
+
return new WC_Product($product_id);
|
911 |
+
}
|
912 |
+
}
|
913 |
+
|
914 |
+
function sync_product_stocks($order) {
|
915 |
+
if ( version_compare( WOOCOMMERCE_VERSION, "2.0.0" ) >= 0 ) {
|
916 |
+
// WC 2.0
|
917 |
+
return $this->sync_product_stocks20($order);
|
918 |
+
} else {
|
919 |
+
return $this->sync_product_stocks16($order);
|
920 |
+
}
|
921 |
+
}
|
922 |
+
|
923 |
/*
|
924 |
Only when translated products are ordered, force adjusting stock information for all translations
|
925 |
When a product in the default language is ordered stocks are adjusted automatically
|
926 |
*/
|
927 |
+
function sync_product_stocks16($order){
|
928 |
global $sitepress;
|
929 |
$order_id = $order->id;
|
930 |
|
931 |
foreach ( $order->get_items() as $item ) {
|
|
|
932 |
if (isset($item['variation_id']) && $item['variation_id']>0){
|
933 |
$ld = $sitepress->get_element_language_details($item['variation_id'], 'post_product_variation');
|
934 |
$product_id = icl_object_id( $item['variation_id'], 'product_variation', true, $sitepress->get_default_language());
|
960 |
|
961 |
}
|
962 |
|
963 |
+
function sync_product_stocks20($order){
|
964 |
+
global $sitepress;
|
965 |
+
$order_id = $order->id;
|
966 |
+
|
967 |
+
foreach ( $order->get_items() as $item ) {
|
968 |
+
if (isset($item['variation_id']) && $item['variation_id']>0){
|
969 |
+
$ld = $sitepress->get_element_language_details($item['variation_id'], 'post_product_variation');
|
970 |
+
$product_id = icl_object_id( $item['variation_id'], 'product_variation', true, $sitepress->get_default_language());
|
971 |
+
$_product = get_product($product_id);
|
972 |
+
}else{
|
973 |
+
$ld = $sitepress->get_element_language_details($item['product_id'], 'post_product');
|
974 |
+
$product_id = icl_object_id( $item['product_id'], 'product', true, $sitepress->get_default_language());
|
975 |
+
$_product = get_product($product_id);
|
976 |
+
}
|
977 |
+
|
978 |
+
// Process for non-default languages
|
979 |
+
if ($ld->language_code != $sitepress->get_default_language()) {
|
980 |
+
|
981 |
+
// Out of stock attribute
|
982 |
+
if ($_product->managing_stock() && !$_product->backorders_allowed() && $_product->get_total_stock()<=0){
|
983 |
+
$outofstock = 'outofstock';
|
984 |
+
}else{
|
985 |
+
$outofstock = false;
|
986 |
+
}
|
987 |
+
|
988 |
+
if ( $_product && $_product->exists() && $_product->managing_stock() ) {
|
989 |
+
$stock = $_product->reduce_stock($item['qty']);
|
990 |
+
$total_sales = get_post_meta($_product->id, 'total_sales', true);
|
991 |
+
$total_sales += $item['qty'];
|
992 |
+
update_post_meta($product_id, 'total_sales', $total_sales);
|
993 |
+
}
|
994 |
+
}
|
995 |
+
}
|
996 |
+
|
997 |
+
}
|
998 |
/**
|
999 |
* Adds language to order post type.
|
1000 |
*
|
1028 |
if($currency){
|
1029 |
$exchange_rate = $currency[0]->value;
|
1030 |
$min_price = $min_price / $exchange_rate;
|
1031 |
+
$min_price = round($min_price,(int) get_option( 'woocommerce_price_num_decimals' ));
|
1032 |
}
|
1033 |
}
|
1034 |
|
1053 |
if($currency){
|
1054 |
$exchange_rate = $currency[0]->value;
|
1055 |
$max_price = $max_price / $exchange_rate;
|
1056 |
+
$max_price = round($max_price,(int) get_option( 'woocommerce_price_num_decimals' ));
|
1057 |
}
|
1058 |
}
|
1059 |
|
1060 |
return $max_price;
|
1061 |
}
|
1062 |
+
|
1063 |
+
/**
|
1064 |
+
* This function synchronizes variations when we first create a duplicate
|
1065 |
+
*/
|
1066 |
function sync_variations_for_duplicates($master_post_id, $lang, $postarr, $id) {
|
1067 |
$this->sync_variations($id, $postarr);
|
1068 |
}
|
1069 |
|
1070 |
+
/**
|
1071 |
+
* This function takes care of synchronizing variations from original to translations
|
1072 |
+
*/
|
1073 |
+
function sync_variations($post_id, $post){
|
1074 |
+
global $wpdb, $pagenow, $sitepress, $sitepress_settings;
|
1075 |
|
1076 |
+
// check its a product
|
1077 |
$post_type = get_post_type($post_id);
|
1078 |
+
if ($post_type != 'product') {
|
1079 |
+
return;
|
1080 |
+
}
|
1081 |
|
1082 |
// exceptions
|
1083 |
+
$ajax_call = (!empty($_POST['icl_ajx_action']) && $_POST['icl_ajx_action'] == 'make_duplicates');
|
1084 |
+
$duplicated_post_id = icl_object_id($post_id, 'product', false, $sitepress->get_default_language());
|
1085 |
if (empty($duplicated_post_id) || isset($_POST['autosave'])) {
|
1086 |
return;
|
1087 |
}
|
1088 |
+
if($pagenow != 'post.php' && $pagenow != 'post-new.php' && !$ajax_call){
|
1089 |
+
return;
|
1090 |
+
}
|
1091 |
+
|
1092 |
// get language code
|
1093 |
$language_details = $sitepress->get_element_language_details($post_id, 'post_product');
|
1094 |
if (empty($language_details)) {
|
1095 |
return;
|
1096 |
}
|
|
|
|
|
|
|
|
|
|
|
1097 |
|
1098 |
+
// pick posts to sync
|
1099 |
+
$posts = array();
|
1100 |
+
$translations = $sitepress->get_element_translations($language_details->trid, 'post_product');
|
1101 |
+
foreach ($translations as $translation) {
|
1102 |
+
if ($translation->original) {
|
1103 |
+
$duplicated_post_id = $translation->element_id;
|
1104 |
+
} else {
|
1105 |
+
$posts[$translation->element_id] = $translation;
|
1106 |
+
}
|
1107 |
+
}
|
1108 |
+
|
1109 |
+
foreach ($posts as $post_id => $translation) {
|
1110 |
+
$lang = $translation->language_code;
|
1111 |
|
1112 |
+
// Filter upsell products, crosell products and default attributes for translations
|
1113 |
$original_product_upsell_ids = get_post_meta($duplicated_post_id, '_upsell_ids', TRUE);
|
1114 |
if(!empty($original_product_upsell_ids)){
|
1115 |
$unserialized_upsell_ids = maybe_unserialize($original_product_upsell_ids);
|
1116 |
+
|
1117 |
foreach($unserialized_upsell_ids as $k => $product_id){
|
1118 |
// get the correct language
|
1119 |
$upsell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
|
1120 |
+
|
1121 |
if($upsell_product_translation_id){
|
1122 |
$unserialized_upsell_ids[$k] = $upsell_product_translation_id;
|
1123 |
// if it isn't translated - unset it
|
1125 |
unset($unserialized_upsell_ids[$k]);
|
1126 |
}
|
1127 |
}
|
1128 |
+
|
1129 |
$data = array('meta_value' => maybe_serialize($unserialized_upsell_ids));
|
1130 |
$where = array('post_id' => $post_id, 'meta_key' => '_upsell_ids');
|
1131 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1132 |
}
|
1133 |
+
|
1134 |
$original_product_crosssell_ids = get_post_meta($duplicated_post_id, '_crosssell_ids', TRUE);
|
1135 |
if(!empty($original_product_crosssell_ids)){
|
1136 |
$unserialized_crosssell_ids = maybe_unserialize($original_product_crosssell_ids);
|
1137 |
+
|
1138 |
foreach($unserialized_crosssell_ids as $k => $product_id){
|
1139 |
// get the correct language
|
1140 |
$crosssell_product_translation_id = icl_object_id($product_id, 'product', false, $lang);
|
1141 |
+
|
1142 |
if($crosssell_product_translation_id){
|
1143 |
$unserialized_crosssell_ids[$k] = $crosssell_product_translation_id;
|
1144 |
// if it isn't translated - unset it
|
1146 |
unset($unserialized_crosssell_ids[$k]);
|
1147 |
}
|
1148 |
}
|
1149 |
+
|
1150 |
$data = array('meta_value' => maybe_serialize($unserialized_crosssell_ids));
|
1151 |
$where = array('post_id' => $post_id, 'meta_key' => '_crosssell_ids');
|
1152 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1153 |
}
|
1154 |
+
|
1155 |
$original_default_attributes = get_post_meta($duplicated_post_id, '_default_attributes', TRUE);
|
1156 |
if(!empty($original_default_attributes)){
|
1157 |
$unserialized_default_attributes = maybe_unserialize($original_default_attributes);
|
1168 |
unset($unserialized_default_attributes[$attribute]);
|
1169 |
}
|
1170 |
}
|
1171 |
+
|
1172 |
$data = array('meta_value' => maybe_serialize($unserialized_default_attributes));
|
1173 |
$where = array('post_id' => $post_id, 'meta_key' => '_default_attributes');
|
1174 |
$wpdb->update($wpdb->postmeta, $data, $where);
|
1175 |
}
|
1176 |
|
1177 |
+
$get_variation_term_id = $wpdb->get_var("SELECT term_id FROM $wpdb->terms WHERE name = 'variable'");
|
1178 |
+
$get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->term_relationships tr
|
|
|
|
|
|
|
|
|
1179 |
LEFT JOIN $wpdb->term_taxonomy tt ON tt.term_taxonomy_id = tr.term_taxonomy_id
|
1180 |
WHERE object_id = '$duplicated_post_id' AND taxonomy = 'product_type'");
|
1181 |
|
1182 |
+
$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'");
|
1183 |
+
if(!empty($is_post_has_variations)) $is_post_has_variations = TRUE;
|
1184 |
|
1185 |
+
// synchronize term data, postmeta and post variations
|
1186 |
+
if($is_post_has_variations){
|
1187 |
+
// synchronize post variations
|
1188 |
+
$get_all_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
|
1189 |
+
WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$duplicated_post_id'");
|
1190 |
|
1191 |
+
$duplicated_post_variation_ids = array();
|
1192 |
+
foreach($get_all_post_variations as $k => $post_data){
|
1193 |
+
$duplicated_post_variation_ids[] = $post_data->ID;
|
1194 |
+
}
|
1195 |
|
1196 |
+
foreach($get_all_post_variations as $k => $post_data){
|
1197 |
+
// Find if this has already been duplicated
|
1198 |
+
$variation_id = $wpdb->get_var("SELECT post_id FROM $wpdb->postmeta
|
1199 |
+
JOIN {$wpdb->prefix}icl_translations ON element_id = post_id AND element_type = 'post_product_variation' AND language_code = '$lang'
|
1200 |
+
WHERE meta_key = '_wcml_duplicate_of_variation' AND meta_value = '$post_data->ID'");
|
1201 |
+
if (!empty($variation_id)) {
|
1202 |
+
// Update variation
|
1203 |
+
wp_update_post(array(
|
1204 |
+
'ID' => $variation_id,
|
1205 |
+
'post_author' => $post_data->post_author,
|
1206 |
+
'post_date_gmt' => $post_data->post_date_gmt,
|
1207 |
+
'post_content' => $post_data->post_content,
|
1208 |
+
'post_title' => $post_data->post_title,
|
1209 |
+
'post_excerpt' => $post_data->post_excerpt,
|
1210 |
+
'post_status' => $post_data->post_status,
|
1211 |
+
'comment_status' => $post_data->comment_status,
|
1212 |
+
'ping_status' => $post_data->ping_status,
|
1213 |
+
'post_password' => $post_data->post_password,
|
1214 |
+
'post_name' => $post_data->post_name,
|
1215 |
+
'to_ping' => $post_data->to_ping,
|
1216 |
+
'pinged' => $post_data->pinged,
|
1217 |
+
'post_modified' => $post_data->post_modified,
|
1218 |
+
'post_modified_gmt' => $post_data->post_modified_gmt,
|
1219 |
+
'post_content_filtered' => $post_data->post_content_filtered,
|
1220 |
+
'post_parent' => $post_id, // current post ID
|
1221 |
+
'menu_order' => $post_data->menu_order,
|
1222 |
+
'post_type' => $post_data->post_type,
|
1223 |
+
'post_mime_type' => $post_data->post_mime_type,
|
1224 |
+
'comment_count' => $post_data->comment_count
|
1225 |
+
));
|
1226 |
+
} else {
|
1227 |
+
// Add new variation
|
1228 |
+
$guid = $post_data->guid;
|
1229 |
+
$replaced_guid = str_replace($duplicated_post_id, $post_id, $guid);
|
1230 |
+
$slug = $post_data->post_name;
|
1231 |
+
$replaced_slug = str_replace($duplicated_post_id, $post_id, $slug);
|
1232 |
+
$variation_id = wp_insert_post(array(
|
1233 |
+
'post_author' => $post_data->post_author,
|
1234 |
+
'post_date_gmt' => $post_data->post_date_gmt,
|
1235 |
+
'post_content' => $post_data->post_content,
|
1236 |
+
'post_title' => $post_data->post_title,
|
1237 |
+
'post_excerpt' => $post_data->post_excerpt,
|
1238 |
+
'post_status' => $post_data->post_status,
|
1239 |
+
'comment_status' => $post_data->comment_status,
|
1240 |
+
'ping_status' => $post_data->ping_status,
|
1241 |
+
'post_password' => $post_data->post_password,
|
1242 |
+
'post_name' => $replaced_slug,
|
1243 |
+
'to_ping' => $post_data->to_ping,
|
1244 |
+
'pinged' => $post_data->pinged,
|
1245 |
+
'post_modified' => $post_data->post_modified,
|
1246 |
+
'post_modified_gmt' => $post_data->post_modified_gmt,
|
1247 |
+
'post_content_filtered' => $post_data->post_content_filtered,
|
1248 |
+
'post_parent' => $post_id, // current post ID
|
1249 |
+
'guid' => $replaced_guid,
|
1250 |
+
'menu_order' => $post_data->menu_order,
|
1251 |
+
'post_type' => $post_data->post_type,
|
1252 |
+
'post_mime_type' => $post_data->post_mime_type,
|
1253 |
+
'comment_count' => $post_data->comment_count
|
1254 |
+
));
|
1255 |
+
update_post_meta($variation_id, '_wcml_duplicate_of_variation', $post_data->ID);
|
1256 |
+
update_post_meta($variation_id, '_icl_duplicate_of', $post_data->ID);
|
1257 |
+
$trid = $sitepress->get_element_trid($post_data->ID, 'post_product_variation');
|
1258 |
+
$sitepress->set_element_language_details($variation_id, 'post_product_variation', $trid, $lang, $sitepress->get_default_language());
|
1259 |
+
}
|
1260 |
+
}
|
1261 |
|
1262 |
+
$get_current_post_variations = $wpdb->get_results("SELECT * FROM $wpdb->posts
|
1263 |
+
WHERE post_status = 'publish' AND post_type = 'product_variation' AND post_parent = '$post_id'");
|
1264 |
+
|
1265 |
+
// Delete variations that no longer exist
|
1266 |
+
foreach ($get_current_post_variations as $post_data) {
|
1267 |
+
$variation_id = get_post_meta($post_data->ID, '_wcml_duplicate_of_variation', true);
|
1268 |
+
if (!in_array($variation_id, $duplicated_post_variation_ids)) {
|
1269 |
+
wp_delete_post($variation_id, true);
|
1270 |
+
}
|
1271 |
+
}
|
1272 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1273 |
// custom fields to copy
|
1274 |
+
$cf = (array)$sitepress_settings['translation-management']['custom_fields_translation'];
|
|
|
1275 |
|
1276 |
// synchronize post variations post meta
|
1277 |
$current_post_variation_ids = array();
|
1293 |
$tax = substr($meta_key, 10);
|
1294 |
if (taxonomy_exists($tax)) {
|
1295 |
$taxs[] = $tax;
|
1296 |
+
$attid = get_term_by('slug', $meta_value, $tax)->term_taxonomy_id;
|
1297 |
+
$trid = $sitepress->get_element_trid($attid, 'tax_' . $tax);
|
1298 |
+
if ($trid) {
|
1299 |
+
$translations = $sitepress->get_element_translations($trid,'tax_' . $tax);
|
1300 |
+
if (isset($translations[$lang])) {
|
1301 |
+
$meta_value = get_term_by('id', $translations[$lang]->term_id, $tax)->slug;
|
1302 |
+
}
|
1303 |
}
|
|
|
|
|
|
|
1304 |
}
|
1305 |
}
|
1306 |
// update current post variations meta
|
1307 |
+
if ((substr($meta_key, 0, 10) == 'attribute_' || isset($cf[$meta_key]) && $cf[$meta_key] == 1)) {
|
1308 |
update_post_meta($current_post_variation_ids[$dp_key], $meta_key, $meta_value);
|
1309 |
}
|
1310 |
}
|
1311 |
}
|
1312 |
|
1313 |
// Sync terms
|
|
|
1314 |
$taxs = array_unique($taxs);
|
1315 |
foreach ($taxs as $tax) {
|
1316 |
$terms = wp_get_object_terms($duplicated_post_id, $tax);
|
1317 |
$update = array();
|
1318 |
foreach ($terms as $term) {
|
1319 |
+
$trid = $sitepress->get_element_trid($term->term_taxonomy_id, 'tax_' . $tax);
|
1320 |
+
$translations = $sitepress->get_element_translations($trid,'tax_' . $tax);
|
1321 |
+
if (isset($translations[$lang])) {
|
1322 |
+
$update[] = intval($translations[$lang]->term_id);
|
|
|
|
|
1323 |
}
|
1324 |
}
|
1325 |
wp_set_object_terms($post_id, $update, $tax);
|
1326 |
}
|
1327 |
|
1328 |
+
}
|
1329 |
+
|
1330 |
+
}
|
1331 |
+
|
1332 |
+
}
|
1333 |
|
1334 |
/**
|
1335 |
* Creates WCML page.
|
1352 |
* Adds additional CSS and JS.
|
1353 |
*/
|
1354 |
function load_css_and_js() {
|
1355 |
+
if(isset($_GET['page']) && $_GET['page'] == 'wpml-wcml') {
|
1356 |
+
wp_enqueue_style('wpml-wcml', WCML_PLUGIN_URL . '/assets/css/management.css', array(), WCML_VERSION);
|
1357 |
+
wp_enqueue_script('jquery-validate', plugin_dir_url(__FILE__) . '/assets/js/jquery.validate.min.js', array('jquery'), '1.8.1', true);
|
1358 |
+
}
|
|
|
|
|
|
|
|
|
|
|
1359 |
}
|
1360 |
|
1361 |
/**
|
wpml-config.xml
CHANGED
@@ -32,7 +32,6 @@
|
|
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>
|
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">total_sales</custom-field>
|
36 |
</custom-fields>
|
37 |
<custom-types>
|
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:
|
9 |
*/
|
10 |
|
11 |
if(defined('WCML_VERSION')) return;
|
12 |
-
define('WCML_VERSION', '
|
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: 2.0
|
9 |
*/
|
10 |
|
11 |
if(defined('WCML_VERSION')) return;
|
12 |
+
define('WCML_VERSION', '2.0');
|
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);
|