WooCommerce Multilingual – run WooCommerce with WPML - Version 4.2.5

Version Description

  • Cannot update Purchase note (any other custom field) once the job is completed
  • New order admin emails have un-translated heading and subject when admin language is different of default
  • Product in cart not adjusted to correct language when switching languages
  • WooCommerce Subscriptions -> Product with free trial has no payment method
  • Strings for subject and title are not translating for Refund emails
  • Page builder strings does not translate in a product when WCML is enabled
  • Fixed small glitch with no payment methods in free product with extra shipping cost
  • Fix an issue that caused fatal error in WooCommerce Store Exporter plugin
  • Fixed wrong output when using multiple categories in shortcodes
  • Fixed compatibility issue in WC Membership with wrong product url
  • Un-trashing product results of redirect to post listing in WCML
  • Fix a bug that the price calculation is not correct in combination with WC Bookings and WC Deposit plugin
  • MaxStore Pro theme compatibility for mini cart
  • Product price was doubled on cart in combination with Booking and Product Addons
  • Added 'wcml_hide_cart_alert_dialog' filter to support hide cart alert switching dialog
Download this release

Release Info

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

Code changes from version 4.2.4 to 4.2.5

changelog/4.2.5.md ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Fixes
2
+ * [wcml-2196] Cannot update Purchase note (any other custom field) once the job is completed
3
+ * [wcml-2189] New order admin emails have un-translated heading and subject when admin language is different of default
4
+ * [wcml-2188] Product in cart not adjusted to correct language when switching languages
5
+ * [wcml-2187] WooCommerce Subscriptions -> Product with free trial has no payment method
6
+ * [wcml-2184] Strings for subject and title are not translating for Refund emails
7
+ * [wcml-2179] Page builder strings does not translate in a product when WCML is enabled
8
+ * [wcml-2177] Fixed small glitch with no payment methods in free product with extra shipping cost
9
+ * [wcml-2175] Fix an issue that caused fatal error in WooCommerce Store Exporter plugin
10
+ * [wcml-2171] Fixed wrong output when using multiple categories in shortcodes
11
+ * [wcml-2166] Fixed compatibility issue in WC Membership with wrong product url
12
+ * [wcml-2165] Un-trashing product results of redirect to post listing in WCML
13
+ * [wcml-2161] Fix a bug that the price calculation is not correct in combination with WC Bookings and WC Deposit plugin
14
+ * [wcml-2149] MaxStore Pro theme compatibility for mini cart
15
+ * [wcml-2127] Product price was doubled on cart in combination with Booking and Product Addons
16
+ # New filters
17
+ * [wcml-2091] Added 'wcml_hide_cart_alert_dialog' filter to support hide cart alert switching dialog
classes/shortcodes/class-wcml-wc-shortcode-product-category.php CHANGED
@@ -33,32 +33,38 @@ class WCML_WC_Shortcode_Product_Category {
33
  */
34
  public function translate_category( $args, $atts ) {
35
 
36
- if ( isset( $args['product_cat'] ) ) {
37
- $args = $this->translate_categories_using_simple_tax_query( $args );
38
- } elseif ( isset( $atts['category'] ) ) {
39
 
40
- // Get translated category slugs, we need to remove WPML filter.
41
- $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
42
- $categories = get_terms( array( 'slug' => $atts['category'], 'taxonomy' => 'product_cat' ) );
43
 
44
- if ( $filter_exists ) {
45
- add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
46
- }
 
47
 
48
- // Replace slugs in query arguments.
49
- $terms = wp_list_pluck( $categories, 'slug' );
50
- foreach ( $args['tax_query'] as $i => $tax_query ) {
51
- $args['tax_query'][ $i ] = array();
52
- if ( ! is_int( key( $tax_query ) ) ) {
53
- $tax_query = array( $tax_query );
54
  }
55
- foreach ( $tax_query as $j => $condition ) {
56
- if ( 'product_cat' === $condition['taxonomy'] ) {
57
- $condition['terms'] = $terms;
 
 
 
 
 
 
 
 
 
 
 
58
  }
59
- $args['tax_query'][ $i ][] = $condition;
60
  }
61
  }
 
62
  }
63
 
64
  return $args;
33
  */
34
  public function translate_category( $args, $atts ) {
35
 
36
+ if( $this->sitepress->get_default_language() !== $this->sitepress->get_current_language() ) {
 
 
37
 
38
+ if ( isset( $args['product_cat'] ) ) {
39
+ $args = $this->translate_categories_using_simple_tax_query( $args );
40
+ } elseif ( isset( $atts['category'] ) ) {
41
 
42
+ // Get translated category slugs, we need to remove WPML filter.
43
+ $filter_exists = remove_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10 );
44
+ $slugs = array_filter( explode(',', $atts['category'] ), 'trim' ) ;
45
+ $categories = get_terms( array( 'slug' => $slugs, 'taxonomy' => 'product_cat' ) );
46
 
47
+ if ( $filter_exists ) {
48
+ add_filter( 'terms_clauses', array( $this->sitepress, 'terms_clauses' ), 10, 4 );
 
 
 
 
49
  }
50
+
51
+ // Replace slugs in query arguments.
52
+ $terms = wp_list_pluck( $categories, 'slug' );
53
+
54
+ foreach ( $args['tax_query'] as $i => $tax_query ) {
55
+ $args['tax_query'][ $i ] = array();
56
+ if ( ! is_int( key( $tax_query ) ) ) {
57
+ $tax_query = array( $tax_query );
58
+ }
59
+ foreach ( $tax_query as $j => $condition ) {
60
+ if ( 'product_cat' === $condition['taxonomy'] ) {
61
+ $condition['terms'] = $terms;
62
+ }
63
+ $args['tax_query'][ $i ][] = $condition;
64
  }
 
65
  }
66
  }
67
+
68
  }
69
 
70
  return $args;
compatibility/class-wcml-maxstore.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_MaxStore{
4
+
5
+ function add_hooks(){
6
+
7
+ add_filter( 'wcml_force_reset_cart_fragments', array( $this, 'wcml_force_reset_cart_fragments' ) );
8
+
9
+ }
10
+
11
+ public function wcml_force_reset_cart_fragments(){
12
+
13
+ return 1;
14
+
15
+ }
16
+
17
+ }
compatibility/class-wcml-product-addons.php CHANGED
@@ -9,13 +9,19 @@ class WCML_Product_Addons {
9
  * @var SitePress
10
  */
11
  public $sitepress;
 
 
 
 
12
 
13
  /**
14
  * WCML_Product_Addons constructor.
15
  * @param SitePress $sitepress
 
16
  */
17
- function __construct( $sitepress ){
18
- $this->sitepress = $sitepress;
 
19
  }
20
 
21
  public function add_hooks(){
@@ -282,7 +288,10 @@ class WCML_Product_Addons {
282
  // special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
283
  public function filter_booking_addon_product_in_cart_contents( $cart_item ) {
284
 
285
- if ( $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] ) ) {
 
 
 
286
  $cost = $cart_item['data']->get_price();
287
 
288
  foreach( $cart_item['addons'] as $addon ){
9
  * @var SitePress
10
  */
11
  public $sitepress;
12
+ /**
13
+ * @var int
14
+ */
15
+ private $enable_multi_currency_setting;
16
 
17
  /**
18
  * WCML_Product_Addons constructor.
19
  * @param SitePress $sitepress
20
+ * @param int $enable_multi_currency_setting
21
  */
22
+ function __construct( SitePress $sitepress, $enable_multi_currency_setting ){
23
+ $this->sitepress = $sitepress;
24
+ $this->enable_multi_currency_setting = $enable_multi_currency_setting;
25
  }
26
 
27
  public function add_hooks(){
288
  // special case for WC Bookings plugin - need add addon cost after re-calculating booking costs #wcml-1877
289
  public function filter_booking_addon_product_in_cart_contents( $cart_item ) {
290
 
291
+ $is_multi_currency_on = $this->enable_multi_currency_setting == WCML_MULTI_CURRENCIES_INDEPENDENT;
292
+ $is_booking_product_with_addons = $cart_item['data'] instanceof WC_Product_Booking && isset( $cart_item['addons'] );
293
+
294
+ if ( $is_multi_currency_on && $is_booking_product_with_addons ) {
295
  $cost = $cart_item['data']->get_price();
296
 
297
  foreach( $cart_item['addons'] as $addon ){
compatibility/class-wcml-wc-memberships.php CHANGED
@@ -1,84 +1,95 @@
1
  <?php
2
 
3
- class WCML_WC_Memberships{
4
 
5
- public function add_hooks(){
 
 
 
6
 
7
- add_filter( 'parse_request', array( $this, 'adjust_query_vars' ) );
8
- add_filter( 'wcml_register_endpoints_query_vars', array( $this, 'register_endpoints_query_vars' ), 10, 3 );
9
- add_filter( 'wcml_endpoint_permalink_filter', array( $this, 'endpoint_permalink_filter' ), 10, 2 );
10
- add_filter( 'wc_memberships_members_area_my-memberships_actions', array( $this, 'filter_actions_links' ) );
11
 
12
- add_action( 'wp_enqueue_scripts', array( $this, 'load_assets' ) );
13
- }
14
 
15
- public function register_endpoints_query_vars( $query_vars, $wc_vars, $object ){
16
- $query_vars[ 'members_area' ] = $this->get_translated_endpoint( $object );
 
 
17
 
18
- return $query_vars;
19
- }
20
 
21
- public function get_translated_endpoint( $object ){
 
22
 
23
- $translation = $object->get_endpoint_translation(
24
- 'members_area',
25
- get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' )
26
- );
27
 
28
- return $translation;
29
- }
30
 
31
- public function adjust_query_vars( $q ){
 
 
 
32
 
33
- if( !isset( $q->query_vars['members-area'] ) && isset( $q->query_vars[ 'members_area' ] ) ){
34
- $q->query_vars['members-area'] = $q->query_vars[ 'members_area' ];
35
- }
36
 
37
- return $q;
38
- }
39
 
40
- public function endpoint_permalink_filter( $endpoint, $key ){
 
 
41
 
42
- if( 'members_area' === $key ){
43
- $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
44
- }
45
 
46
- return $endpoint;
47
- }
48
 
49
- public function filter_actions_links( $actions ){
 
 
50
 
51
- foreach ( $actions as $key => $action ){
52
- if( 'view' === $key ){
53
- $membership_endpoints = $this->get_membership_endpoints();
54
- $actions[ $key ][ 'url' ] = str_replace( $membership_endpoints[ 'original' ], $membership_endpoints[ 'translated' ], $action[ 'url' ] );
55
- }
56
- }
57
 
58
- return $actions;
59
- }
60
 
61
- public function load_assets( ) {
62
- global $post;
 
 
 
 
63
 
64
- if( isset( $post->ID ) && wc_get_page_id( 'myaccount' ) == $post->ID ){
65
- wp_register_script( 'wcml-members-js', WCML_PLUGIN_URL . '/compatibility/res/js/wcml-members.js', array( 'jquery' ), WCML_VERSION );
66
- wp_enqueue_script( 'wcml-members-js' );
67
- wp_localize_script( 'wcml-members-js', 'endpoints', $this->get_membership_endpoints() );
68
- }
69
 
70
- }
 
71
 
72
- public function get_membership_endpoints(){
 
 
 
 
 
 
73
 
74
- $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
75
- $translated_endpoint = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', 'members_area' );
76
 
77
- return array(
78
- 'original' => $endpoint,
79
- 'translated' => $translated_endpoint
80
- );
81
- }
 
 
 
 
 
82
 
83
 
84
  }
1
  <?php
2
 
3
+ class WCML_WC_Memberships {
4
 
5
+ /**
6
+ * @var WPML_WP_API
7
+ */
8
+ private $wp_api;
9
 
10
+ public function __construct( WPML_WP_API $wp_api ) {
11
+ $this->wp_api = $wp_api;
12
+ }
 
13
 
14
+ public function add_hooks() {
 
15
 
16
+ add_filter( 'parse_request', array( $this, 'adjust_query_vars' ) );
17
+ add_filter( 'wcml_register_endpoints_query_vars', array( $this, 'register_endpoints_query_vars' ), 10, 3 );
18
+ add_filter( 'wcml_endpoint_permalink_filter', array( $this, 'endpoint_permalink_filter' ), 10, 2 );
19
+ add_filter( 'wc_memberships_members_area_my-memberships_actions', array( $this, 'filter_actions_links' ) );
20
 
21
+ add_action( 'wp_enqueue_scripts', array( $this, 'load_assets' ) );
22
+ }
23
 
24
+ public function register_endpoints_query_vars( $query_vars, $wc_vars, $object ) {
25
+ $query_vars['members_area'] = $this->get_translated_endpoint( $object );
26
 
27
+ return $query_vars;
28
+ }
 
 
29
 
30
+ public function get_translated_endpoint( $object ) {
 
31
 
32
+ $translation = $object->get_endpoint_translation(
33
+ 'members_area',
34
+ get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' )
35
+ );
36
 
37
+ return $translation;
38
+ }
 
39
 
40
+ public function adjust_query_vars( $q ) {
 
41
 
42
+ if ( ! isset( $q->query_vars['members-area'] ) && isset( $q->query_vars['members_area'] ) ) {
43
+ $q->query_vars['members-area'] = $q->query_vars['members_area'];
44
+ }
45
 
46
+ return $q;
47
+ }
 
48
 
49
+ public function endpoint_permalink_filter( $endpoint, $key ) {
 
50
 
51
+ if ( 'members_area' === $key ) {
52
+ $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
53
+ }
54
 
55
+ return $endpoint;
56
+ }
 
 
 
 
57
 
58
+ public function filter_actions_links( $actions ) {
 
59
 
60
+ foreach ( $actions as $key => $action ) {
61
+ if ( 'view' === $key ) {
62
+ $membership_endpoints = $this->get_members_area_endpoint();
63
+ $actions[ $key ]['url'] = str_replace( $membership_endpoints['original'], $membership_endpoints['translated'], $action['url'] );
64
+ }
65
+ }
66
 
67
+ return $actions;
68
+ }
 
 
 
69
 
70
+ public function load_assets() {
71
+ global $post;
72
 
73
+ if ( isset( $post->ID ) && wc_get_page_id( 'myaccount' ) == $post->ID ) {
74
+ $wcml_plugin_url = $this->wp_api->constant( 'WCML_PLUGIN_URL' );
75
+ $wcml_version = $this->wp_api->constant( 'WCML_VERSION' );
76
+ wp_register_script( 'wcml-members-js', $wcml_plugin_url . '/compatibility/res/js/wcml-members.js', array( 'jquery' ), $wcml_version );
77
+ wp_enqueue_script( 'wcml-members-js' );
78
+ wp_localize_script( 'wcml-members-js', 'wc_memberships_memebers_area_endpoint', $this->get_members_area_endpoint() );
79
+ }
80
 
81
+ }
 
82
 
83
+ public function get_members_area_endpoint() {
84
+
85
+ $endpoint = get_option( 'woocommerce_myaccount_members_area_endpoint', 'members-area' );
86
+ $translated_endpoint = apply_filters( 'wpml_translate_single_string', $endpoint, 'WooCommerce Endpoints', 'members_area' );
87
+
88
+ return array(
89
+ 'original' => $endpoint,
90
+ 'translated' => $translated_endpoint
91
+ );
92
+ }
93
 
94
 
95
  }
compatibility/class-wcml-wcexporter.php CHANGED
@@ -1,70 +1,88 @@
1
  <?php
2
 
3
- class WCML_wcExporter{
4
-
5
- function __construct(){
6
-
7
- add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
- add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
- add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
- add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
- add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
- add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
- add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
-
15
- }
16
-
17
- function woo_ce_fields($fields){
18
- $fields[] = array(
19
- 'name' => 'language',
20
- 'label' => __( 'Language', 'woo_ce' ),
21
- 'default' => 1
22
- );
23
- $fields[] = array(
24
- 'name' => 'translation_of',
25
- 'label' => __( 'Translation of', 'woo_ce' ),
26
- 'default' => 1
27
- );
28
- return $fields;
29
- }
30
-
31
- function woo_ce_order_fields($fields){
32
- $fields[] = array(
33
- 'name' => 'language',
34
- 'label' => __( 'Language', 'woo_ce' ),
35
- 'default' => 1
36
- );
37
-
38
- return $fields;
39
- }
40
-
41
- function woo_ce_product_item($data, $product_id){
42
- global $sitepress,$woocommerce_wpml;
43
-
44
- $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
- $data->translation_of = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
46
-
47
- return $data;
48
- }
49
-
50
- function woo_ce_category_item($data){
51
- global $sitepress;
52
-
53
- $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
- $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
-
56
- return $data;
57
- }
58
-
59
- function woo_ce_tags($tags){
60
- global $sitepress;
61
-
62
- foreach($tags as $key=>$tag){
63
- $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
- $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
- }
66
-
67
- return $tags;
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  }
1
  <?php
2
 
3
+ class WCML_wcExporter {
4
+
5
+ /**
6
+ * @var SitePress
7
+ */
8
+ private $sitepress;
9
+ /**
10
+ * @var woocommerce_wpml
11
+ */
12
+ private $woocommerce_wpml;
13
+
14
+ /**
15
+ * WCML_wcExporter constructor.
16
+ *
17
+ * @param SitePress $sitepress
18
+ * @param woocommerce_wpml $woocommerce_wpml
19
+ */
20
+ function __construct( SitePress $sitepress, woocommerce_wpml $woocommerce_wpml ) {
21
+ $this->sitepress = $sitepress;
22
+ $this->woocommerce_wpml = $woocommerce_wpml;
23
+ }
24
+
25
+ function add_hooks() {
26
+
27
+ add_filter( 'woo_ce_product_fields', array( $this, 'woo_ce_fields' ) );
28
+ add_filter( 'woo_ce_category_fields', array( $this, 'woo_ce_fields' ) );
29
+ add_filter( 'woo_ce_tag_fields', array( $this, 'woo_ce_fields' ) );
30
+ add_filter( 'woo_ce_order_fields', array( $this, 'woo_ce_order_fields' ) );
31
+ add_filter( 'woo_ce_product_item', array( $this, 'woo_ce_product_item' ), 10, 2 );
32
+ add_filter( 'woo_ce_category_item', array( $this, 'woo_ce_category_item' ), 10 );
33
+ add_filter( 'woo_ce_tags', array( $this, 'woo_ce_tags' ), 10 );
34
+
35
+ }
36
+
37
+ function woo_ce_fields( $fields ) {
38
+ $fields[] = array(
39
+ 'name' => 'language',
40
+ 'label' => __( 'Language', 'woo_ce' ),
41
+ 'default' => 1
42
+ );
43
+ $fields[] = array(
44
+ 'name' => 'translation_of',
45
+ 'label' => __( 'Translation of', 'woo_ce' ),
46
+ 'default' => 1
47
+ );
48
+
49
+ return $fields;
50
+ }
51
+
52
+ function woo_ce_order_fields( $fields ) {
53
+ $fields[] = array(
54
+ 'name' => 'language',
55
+ 'label' => __( 'Language', 'woo_ce' ),
56
+ 'default' => 1
57
+ );
58
+
59
+ return $fields;
60
+ }
61
+
62
+ function woo_ce_product_item( $data, $product_id ) {
63
+
64
+ $data->language = $this->sitepress->get_language_for_element( $product_id, 'post_' . get_post_type( $product_id ) );
65
+ $data->translation_of = $this->woocommerce_wpml->products->get_original_product_id( $product_id );
66
+
67
+ return $data;
68
+ }
69
+
70
+ function woo_ce_category_item( $data ) {
71
+
72
+ $data->language = $this->sitepress->get_language_for_element( $data->term_taxonomy_id, 'tax_product_cat' );
73
+ $data->translation_of = apply_filters( 'translate_object_id', $data->term_taxonomy_id, 'tax_product_cat', true, $this->sitepress->get_default_language() );
74
+
75
+ return $data;
76
+ }
77
+
78
+ function woo_ce_tags( $tags ) {
79
+
80
+ foreach ( $tags as $key => $tag ) {
81
+ $tags[ $key ]->language = $this->sitepress->get_language_for_element( $tag->term_taxonomy_id, 'tax_product_tag' );
82
+ $tags[ $key ]->translation_of = apply_filters( 'translate_object_id', $tag->term_taxonomy_id, 'tax_product_tag', true, $this->sitepress->get_default_language() );
83
+ }
84
+
85
+ return $tags;
86
+ }
87
 
88
  }
compatibility/res/js/wcml-members.js CHANGED
@@ -1,19 +1,18 @@
1
- jQuery( document ).ready( function( $ ){
2
 
3
- if( typeof endpoints != 'undefined' ){
4
 
5
- var tabs = [ 'my-membership-content', 'my-membership-products', 'my-membership-discounts', 'my-membership-notes'];
6
 
7
- for ( i = 0; i < tabs.length; i++ ) {
8
- var link = $('.'+tabs[i]+' a'),
9
- link_href = link.attr('href');
10
- if ( link_href ){
11
- link.attr('href', link_href.replace( endpoints.original, endpoints.translated ));
12
- }
 
13
  }
14
- }
15
-
16
- });
17
-
18
 
 
19
 
 
1
+ jQuery(document).ready(function ($) {
2
 
3
+ if (typeof wc_memberships_memebers_area_endpoint != 'undefined') {
4
 
5
+ var tabs = ['my-membership-content', 'my-membership-products', 'my-membership-discounts', 'my-membership-notes'];
6
 
7
+ for (var i = 0; i < tabs.length; i++) {
8
+ $('.' + tabs[i] + ' a').each(function () {
9
+ var href = $(this).attr('href');
10
+ if (href) {
11
+ $(this).attr('href', href.replace(wc_memberships_memebers_area_endpoint.original, wc_memberships_memebers_area_endpoint.translated));
12
+ }
13
+ });
14
  }
 
 
 
 
15
 
16
+ }
17
 
18
+ });
compatibility/res/js/wcml-members.min.js ADDED
@@ -0,0 +1 @@
 
1
+ jQuery(document).ready(function(c){if(typeof wc_memberships_memebers_area_endpoint!="undefined"){var b=["my-membership-content","my-membership-products","my-membership-discounts","my-membership-notes"];for(var a=0;a<b.length;a++){c("."+b[a]+" a").each(function(){var d=c(this).attr("href");if(d){c(this).attr("href",d.replace(wc_memberships_memebers_area_endpoint.original,wc_memberships_memebers_area_endpoint.translated))}})}}});
inc/admin-menus/class-wcml-admin-menus.php CHANGED
@@ -2,14 +2,17 @@
2
 
3
  class WCML_Admin_Menus{
4
 
 
5
  private static $woocommerce_wpml;
 
6
  private static $sitepress;
 
7
  private static $wpdb;
8
 
9
- public static function set_up_menus( &$woocommerce_wpml, &$sitepress, &$wpdb, $check_dependencies ){
10
- self::$woocommerce_wpml =& $woocommerce_wpml;
11
- self::$sitepress =& $sitepress;
12
- self::$wpdb =& $wpdb;
13
 
14
  if( self::is_page_without_admin_language_switcher() ){
15
  self::remove_wpml_admin_language_switcher();
@@ -179,60 +182,35 @@ class WCML_Admin_Menus{
179
  }
180
 
181
  public static function restrict_admin_with_redirect() {
182
- global $pagenow;
183
 
184
- $default_lang = self::$sitepress->get_default_language();
185
- $current_lang = self::$sitepress->get_current_language();
186
 
187
- if(
188
- ( $pagenow == 'post.php' && isset( $_GET[ 'post' ] ) ) ||
189
- ( $pagenow == 'admin.php' &&
190
- isset( $_GET[ 'action' ] ) &&
191
- $_GET[ 'action'] == 'duplicate_product' &&
192
- isset( $_GET[ 'post' ] )
193
- )
194
- ){
195
- $prod_lang = self::$sitepress->get_language_for_element( $_GET[ 'post' ], 'post_product' );
196
- }
197
 
198
- if(
199
- !self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
200
- $pagenow == 'post.php' &&
201
- isset( $_GET[ 'post' ] )&&
202
- get_post_type( $_GET[ 'post' ] ) == 'product' &&
203
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) )
204
- {
205
- add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
206
- }
207
 
208
- if(
209
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
210
- $pagenow == 'post.php' &&
211
- !is_ajax() &&
212
- isset( $_GET[ 'post' ] ) &&
213
- !self::$woocommerce_wpml->products->is_original_product( $_GET[ 'post' ] ) &&
214
- get_post_type( $_GET[ 'post' ] ) == 'product'
215
- ) {
216
- if(
217
- !isset( $_GET[ 'action' ] ) ||
218
- ( isset( $_GET[ 'action' ] ) && !in_array( $_GET[ 'action' ], array( 'trash', 'delete' ) ) )
219
- ) {
220
- $prid = (int)$_GET[ 'post' ];
221
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products&prid='.$prid ) );
222
- exit;
223
- }
224
- }
 
 
225
 
226
- if(
227
- self::$woocommerce_wpml->settings[ 'trnsl_interface' ] &&
228
- $pagenow == 'admin.php' &&
229
- isset( $_GET[ 'action' ] ) &&
230
- $_GET[ 'action' ] == 'duplicate_product' &&
231
- $default_lang != $prod_lang )
232
- {
233
- wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
234
- exit;
235
- }
236
  }
237
 
238
  public static function inf_editing_product_in_non_default_lang(){
2
 
3
  class WCML_Admin_Menus{
4
 
5
+ /** @var woocommerce_wpml */
6
  private static $woocommerce_wpml;
7
+ /** @var SitePress */
8
  private static $sitepress;
9
+ /** @var SitePress */
10
  private static $wpdb;
11
 
12
+ public static function set_up_menus( woocommerce_wpml $woocommerce_wpml, $sitepress, wpdb $wpdb, $check_dependencies ){
13
+ self::$woocommerce_wpml = $woocommerce_wpml;
14
+ self::$sitepress = $sitepress;
15
+ self::$wpdb = $wpdb;
16
 
17
  if( self::is_page_without_admin_language_switcher() ){
18
  self::remove_wpml_admin_language_switcher();
182
  }
183
 
184
  public static function restrict_admin_with_redirect() {
185
+ global $pagenow;
186
 
187
+ $is_post_product_translation = isset( $_GET['post'] ) && 'product' === get_post_type( $_GET['post'] ) && ! self::$woocommerce_wpml->products->is_original_product( $_GET['post'] );
 
188
 
189
+ if ( self::$woocommerce_wpml->settings['trnsl_interface'] ) {
 
 
 
 
 
 
 
 
 
190
 
191
+ $is_admin_duplicate_page_action = 'admin.php' === $pagenow && isset( $_GET['action'] ) && 'duplicate_product' === $_GET['action'];
192
+ $is_post_action_needs_redirect = ! isset( $_GET['action'] ) || ( isset( $_GET['action'] ) && ! in_array( $_GET['action'], array( 'trash', 'delete', 'untrash' ) ) );
 
 
 
 
 
 
 
193
 
194
+ if (
195
+ 'post.php' === $pagenow &&
196
+ ! is_ajax() &&
197
+ $is_post_product_translation &&
198
+ $is_post_action_needs_redirect
199
+ ) {
200
+ $prid = (int) $_GET['post'];
201
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products&prid=' . $prid ) );
202
+ exit;
203
+
204
+ } elseif ( $is_admin_duplicate_page_action && $is_post_product_translation ) {
205
+
206
+ wp_redirect( admin_url( 'admin.php?page=wpml-wcml&tab=products' ) );
207
+ exit;
208
+ }
209
+
210
+ } elseif ( 'post.php' === $pagenow && $is_post_product_translation ) {
211
+ add_action( 'admin_notices', array( __CLASS__, 'inf_editing_product_in_non_default_lang' ) );
212
+ }
213
 
 
 
 
 
 
 
 
 
 
 
214
  }
215
 
216
  public static function inf_editing_product_in_non_default_lang(){
inc/class-wcml-cart.php CHANGED
@@ -1,169 +1,186 @@
1
  <?php
2
- class WCML_Cart
3
- {
4
- /** @var woocommerce_wpml */
5
- private $woocommerce_wpml;
6
- /** @var Sitepress */
7
- private $sitepress;
8
- /** @var WooCommerce */
9
- private $woocommerce;
10
-
11
- /**
12
- * WCML_Cart constructor.
13
- *
14
- * @param woocommerce_wpml $woocommerce_wpml
15
- * @param SitePress $sitepress
16
- * @param WooCommerce $woocommerce
17
- */
18
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WooCommerce $woocommerce )
19
- {
20
- $this->woocommerce_wpml = $woocommerce_wpml;
21
- $this->sitepress = $sitepress;
22
- $this->woocommerce = $woocommerce;
23
- }
24
-
25
- public function add_hooks(){
26
-
27
- if( $this->is_clean_cart_enabled() ){
28
-
29
- $this->enqueue_dialog_ui();
30
-
31
- add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
32
- add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
33
- add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
34
-
35
- add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 4 );
36
- add_action( 'wcml_before_switch_currency', array( $this, 'switching_currency_empty_cart_if_needed' ), 10, 2 );
37
- }else{
38
- //cart widget
39
- add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
40
- add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
41
- add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
42
- add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
43
-
44
- //cart
45
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
46
- add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ) );
47
- add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
48
- add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
49
-
50
- add_filter('woocommerce_paypal_args', array($this, 'filter_paypal_args'));
51
- add_filter( 'woocommerce_add_to_cart_sold_individually_quantity', array( $this, 'add_to_cart_sold_individually_exception' ), 10, 5 );
52
-
53
- $this->localize_flat_rates_shipping_classes();
54
- }
55
-
56
- add_filter( 'woocommerce_cart_needs_payment', array( $this, 'use_cart_contents_total_for_needs_payment' ), 10, 2 );
57
-
58
- }
59
-
60
- public function is_clean_cart_enabled(){
61
-
62
- $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
63
-
64
- if(
65
- $cart_sync_settings[ 'currency_switch' ] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) ||
66
- $cart_sync_settings[ 'lang_switch' ] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' )
67
- ){
68
- return true;
69
- }
70
-
71
- return false;
72
- }
73
-
74
- public function enqueue_dialog_ui(){
75
-
76
- wp_enqueue_script( 'jquery-ui-dialog' );
77
- wp_enqueue_style( 'wp-jquery-ui-dialog' );
78
-
79
- }
80
-
81
- public function wcml_removed_cart_items_widget( $args = array() ){
82
-
83
- if( !empty( $this->woocommerce->session ) ){
84
- $removed_cart_items = new WCML_Removed_Cart_Items_UI( $args, $this->woocommerce_wpml, $this->sitepress, $this->woocommerce );
85
- $preview = $removed_cart_items->get_view();
86
-
87
- if ( !isset($args['echo']) || $args['echo'] ) {
88
- echo $preview;
89
- } else {
90
- return $preview;
91
- }
92
- }
93
-
94
- }
95
-
96
- public function switching_currency_empty_cart_if_needed( $currency, $force_switch ){
97
- if( $force_switch && $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_CLEAR ) {
98
- $this->empty_cart_if_needed('currency_switch');
99
- $this->woocommerce->session->set('wcml_switched_type', 'currency');
100
- }
101
- }
102
-
103
- public function empty_cart_if_needed( $switching_type ){
104
 
105
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ $switching_type ] == WCML_CART_CLEAR ){
106
- $removed_products = $this->woocommerce->session->get( 'wcml_removed_items' ) ? maybe_unserialize( $this->woocommerce->session->get( 'wcml_removed_items' ) ) : array();
 
 
 
 
 
107
 
108
- foreach( WC()->cart->get_cart_for_session() as $item_key => $cart ){
109
- if( !in_array( $cart[ 'product_id' ], $removed_products ) ){
110
- $removed_products[] = $cart[ 'product_id' ];
111
- }
112
- WC()->cart->remove_cart_item( $item_key );
113
- }
114
-
115
- if( !empty( $this->woocommerce->session ) ){
116
- $this->woocommerce->session->set( 'wcml_removed_items', serialize( $removed_products ) );
117
- }
118
- }
119
- }
120
-
121
- public function wcml_cart_clear_removed_items( ){
122
-
123
- $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
124
- if(!$nonce || !wp_verify_nonce($nonce, 'wcml_clear_removed_items')){
125
- die('Invalid nonce');
126
- }
127
-
128
- $this->woocommerce->session->__unset( 'wcml_removed_items' );
129
- $this->woocommerce->session->__unset( 'wcml_switched_type' );
130
- }
131
-
132
- public function cart_switching_currency( $exc, $current_currency, $new_currency, $return = false ){
133
-
134
- $cart_for_session = WC()->cart->get_cart_for_session();
135
- if( $this->woocommerce_wpml->settings[ 'cart_sync' ][ 'currency_switch' ] == WCML_CART_SYNC || empty( $cart_for_session ) ){
136
- return $exc;
137
- }
138
-
139
- $dialog_title = __( 'Switching currency?', 'woocommerce-multilingual');
140
- $confirmation_message = __( 'Your cart is not empty! After you switched the currency, all items from the cart will be removed and you have to add them again.', 'woocommerce-multilingual');
141
- $stay_in = sprintf( __( 'Keep using %s', 'woocommerce-multilingual'), $current_currency );
142
- $switch_to = __( 'Proceed', 'woocommerce-multilingual');
143
-
144
- ob_start();
145
- $this->cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $new_currency, $current_currency );
146
- $html = ob_get_contents();
147
- ob_end_clean();
148
-
149
- if( $return ){
150
- return array( 'prevent_switching' => $html );
151
- }else{
152
- echo json_encode( array( 'prevent_switching' => $html ) );
153
- }
154
-
155
- return true;
156
- }
157
-
158
- public function cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $switch_to_value, $stay_in_value = false, $language_switch = false ){
159
- ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  <div id="wcml-cart-dialog-confirm" title="<?php echo esc_attr( $dialog_title ) ?>">
161
  <p><?php echo esc_html( $confirmation_message ); ?></p>
162
  </div>
163
 
164
  <script type="text/javascript">
165
- jQuery( document).ready( function(){
166
- jQuery( "#wcml-cart-dialog-confirm" ).dialog({
167
  resizable: false,
168
  draggable: false,
169
  height: "auto",
@@ -171,359 +188,362 @@ class WCML_Cart
171
  modal: true,
172
  closeOnEscape: false,
173
  dialogClass: "wcml-cart-dialog",
174
- create: function(){
175
  jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
176
  },
177
- open: function(event, ui) {
178
  jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
179
  },
180
- close: function(event, ui){
181
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
182
  },
183
  buttons: {
184
- "<?php echo $switch_to; ?>": function() {
185
- jQuery( this ).dialog( "close" );
186
- <?php if( $language_switch ): ?>
187
- window.location = '<?php echo esc_url( $switch_to_value, null, 'redirect' ); ?>';
188
- <?php else: ?>
189
- jQuery('.wcml_currency_switcher').parent().find('img').remove();
190
- wcml_load_currency( "<?php echo esc_js( $switch_to_value ); ?>", true );
191
- <?php endif; ?>
192
 
193
  },
194
- "<?php echo $stay_in; ?>": function() {
195
- jQuery( this ).dialog( "close" );
196
- <?php if( $language_switch ): ?>
197
- window.location = '<?php echo esc_url( $stay_in_value, null, 'redirect' ); ?>';
198
- <?php else: ?>
199
- jQuery('.wcml_currency_switcher').parent().find('img').remove();
200
- jQuery('.wcml_currency_switcher').removeAttr('disabled');
201
- jQuery('.wcml_currency_switcher').val( '<?php echo esc_js ( $stay_in_value ); ?>' );
202
- <?php endif; ?>
203
  }
204
  }
205
  });
206
  });
207
  </script>
208
- <?php
209
- }
210
-
211
- public function wcml_refresh_fragments(){
212
- WC()->cart->calculate_totals();
213
- $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
214
- }
215
-
216
- /*
217
- * Update cart and cart session when switch language
218
- */
219
- public function woocommerce_calculate_totals( $cart, $currency = false ){
220
-
221
- $current_language = $this->sitepress->get_current_language();
222
- $new_cart_data = array();
223
-
224
- foreach( $cart->cart_contents as $key => $cart_item ){
225
- $tr_product_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', false, $current_language );
226
- //translate custom attr labels in cart object
227
-
228
- if( version_compare( WC_VERSION , '3.0.0', '<' ) && isset( $cart_item[ 'data' ]->product_attributes ) ){
229
- foreach( $cart_item[ 'data' ]->product_attributes as $attr_key => $product_attribute ){
230
- if( isset( $product_attribute[ 'is_taxonomy' ]) && !$product_attribute[ 'is_taxonomy' ] ){
231
- $cart->cart_contents[ $key ][ 'data' ]->product_attributes[ $attr_key ][ 'name' ] = $this->woocommerce_wpml->strings->translated_attribute_label(
232
- $product_attribute[ 'name' ],
233
- $product_attribute[ 'name' ],
234
- $tr_product_id );
235
- }
236
- }
237
- }
238
-
239
- //translate custom attr value in cart object
240
- if( isset( $cart_item[ 'variation' ] ) && is_array( $cart_item[ 'variation' ] ) ){
241
- foreach( $cart_item[ 'variation' ] as $attr_key => $attribute ){
242
- $cart->cart_contents[ $key ][ 'variation' ][ $attr_key ] = $this->get_cart_attribute_translation(
243
- $attr_key,
244
- $attribute,
245
- $cart_item[ 'variation_id' ],
246
- $current_language,
247
- $cart_item[ 'product_id' ],
248
- $tr_product_id
249
- );
250
- }
251
- }
252
-
253
- if( $currency !== false ){
254
- $cart->cart_contents[ $key ][ 'data' ]->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
255
- }
256
-
257
- if( $cart_item[ 'product_id' ] == $tr_product_id ){
258
- $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[$key], $key, $current_language );
259
- continue;
260
- }
261
-
262
- if( isset( $cart->cart_contents[ $key ][ 'variation_id' ] ) && $cart->cart_contents[ $key ][ 'variation_id' ] ){
263
- $tr_variation_id = apply_filters( 'translate_object_id', $cart_item[ 'variation_id' ], 'product_variation', false, $current_language );
264
- if( !is_null( $tr_variation_id ) ){
265
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
266
- $cart->cart_contents[ $key ][ 'variation_id' ] = intval( $tr_variation_id );
267
- if( defined('WC_VERSION') && version_compare( WC_VERSION , '2.7', '<' ) ){
268
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
269
- }else{
270
- $cart->cart_contents[ $key ][ 'data' ]->set_id( intval( $tr_product_id ) );
271
- }
272
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
273
- }
274
- }else{
275
- if( !is_null( $tr_product_id ) ){
276
- $cart->cart_contents[ $key ][ 'product_id' ] = intval( $tr_product_id );
277
- if( defined('WC_VERSION') && version_compare( WC_VERSION , '2.7', '<' ) ){
278
- $cart->cart_contents[ $key ][ 'data' ]->id = intval( $tr_product_id );
279
- }else{
280
- $cart->cart_contents[ $key ][ 'data' ]->set_id( intval( $tr_product_id ) );
281
- }
282
- $cart->cart_contents[ $key ][ 'data' ]->post = get_post( $tr_product_id );
283
- }
284
- }
285
-
286
- if( !is_null( $tr_product_id ) ){
287
-
288
- $new_key = $this->wcml_generate_cart_key( $cart->cart_contents, $key );
289
- $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
290
- $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
291
-
292
- $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
293
- }
294
- }
295
-
296
- $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
297
- $this->woocommerce->session->cart = $cart->cart_contents;
298
- return $cart->cart_contents;
299
- }
300
-
301
- public function wcml_check_on_duplicate_products_in_cart( $cart_contents ){
302
-
303
- $exists_products = array();
304
- remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
305
-
306
- foreach( $cart_contents as $key => $cart_content ){
307
- $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
308
- if( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ){
309
- continue;
310
- }
311
-
312
- $quantity = $cart_content['quantity'];
313
-
314
- $search_key = $this->wcml_generate_cart_key( $cart_contents, $key );
315
- if( array_key_exists( $search_key, $exists_products ) ){
316
- unset( $cart_contents[ $key ] );
317
- $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] = $cart_contents[ $exists_products[ $search_key ] ][ 'quantity' ] + $quantity;
318
- $this->woocommerce->cart->calculate_totals();
319
- }else{
320
- $exists_products[ $search_key ] = $key;
321
- }
322
- }
323
-
324
- add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
325
- return $cart_contents;
326
- }
327
-
328
- public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ){
329
-
330
- $attr_translation = $attribute;
331
-
332
- if( !empty( $attribute ) ){
333
- //delete 'attribute_' at the beginning
334
- $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
335
-
336
- if( taxonomy_exists( $taxonomy ) ){
337
- if( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
338
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
339
- $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
340
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
341
- $attr_translation = $term->slug;
342
- }
343
- }else{
344
-
345
- $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
346
-
347
- if( $trnsl_attr ){
348
- $attr_translation = $trnsl_attr;
349
- }else{
350
- $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
351
- }
352
- }
353
- }
354
-
355
- return $attr_translation;
356
- }
357
-
358
- public function wcml_generate_cart_key( $cart_contents, $key ){
359
- $cart_item_data = $this->get_cart_item_data_from_cart( $cart_contents[ $key ] );
360
-
361
- return $this->woocommerce->cart->generate_cart_id(
362
- $cart_contents[ $key ][ 'product_id' ],
363
- $cart_contents[ $key ][ 'variation_id' ],
364
- $cart_contents[ $key ][ 'variation' ],
365
- $cart_item_data
366
- );
367
- }
368
-
369
- //get cart_item_data from existing cart array ( from session )
370
- public function get_cart_item_data_from_cart( $cart_contents ){
371
- unset( $cart_contents[ 'product_id' ] );
372
- unset( $cart_contents[ 'variation_id' ] );
373
- unset( $cart_contents[ 'variation' ] );
374
- unset( $cart_contents[ 'quantity' ] );
375
- unset( $cart_contents[ 'line_total' ] );
376
- unset( $cart_contents[ 'line_subtotal' ] );
377
- unset( $cart_contents[ 'line_tax' ] );
378
- unset( $cart_contents[ 'line_subtotal_tax' ] );
379
- unset( $cart_contents[ 'line_tax_data' ] );
380
- unset( $cart_contents[ 'data' ] );
381
-
382
- return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
383
- }
384
-
385
- public function translate_cart_contents( $item ) {
386
-
387
- // translate the product id and product data
388
- $item[ 'product_id' ] = apply_filters( 'translate_object_id', $item[ 'product_id' ], 'product', true );
389
- if( $item[ 'variation_id' ] ) {
390
- $item[ 'variation_id' ] = apply_filters( 'translate_object_id', $item[ 'variation_id' ], 'product_variation', true );
391
- }
392
-
393
- $item_product_title = $item[ 'variation_id' ] ? get_the_title( $item[ 'variation_id' ] ) : get_the_title( $item[ 'product_id' ] );
394
-
395
- if( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '>=' ) ) {
396
- $item[ 'data' ]->set_name( $item_product_title );
397
- } else {
398
- $item[ 'data' ]->post->post_title = $item_product_title;
399
- }
400
-
401
- return $item;
402
- }
403
-
404
- public function translate_cart_subtotal( $cart ) {
405
-
406
- if( isset( $_SERVER['REQUEST_URI'] ) ){
407
- //special case: check if attachment loading
408
- $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
409
-
410
- foreach( $attachments as $attachment ){
411
- $match = preg_match( '/\.'.$attachment.'$/', $_SERVER['REQUEST_URI'] );
412
- if( !empty( $match ) ){
413
- return false;
414
- }
415
- }
416
- }
417
-
418
- if( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ){
419
- $cart->calculate_totals();
420
- }
421
-
422
- }
423
-
424
- // refresh cart total to return correct price from WC object
425
- public function wcml_refresh_cart_total() {
426
- WC()->cart->calculate_totals();
427
- }
428
-
429
-
430
- public function localize_flat_rates_shipping_classes(){
431
-
432
- if(is_ajax() && isset($_POST['action']) && $_POST['action'] == 'woocommerce_update_order_review'){
433
- $this->woocommerce->shipping->load_shipping_methods();
434
- $shipping_methods = $this->woocommerce->shipping->get_shipping_methods();
435
- foreach($shipping_methods as $method){
436
- if(isset($method->flat_rate_option)){
437
- add_filter('option_' . $method->flat_rate_option, array($this, 'translate_shipping_class'));
438
- }
439
- }
440
-
441
- }
442
- }
443
-
444
- public function translate_shipping_class($rates){
445
-
446
- if(is_array($rates)){
447
- foreach($rates as $shipping_class => $value){
448
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug('product_shipping_class', $shipping_class );
449
-
450
- if($term_id && !is_wp_error($term_id)){
451
- $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true);
452
- if($translated_term_id != $term_id){
453
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
454
- unset($rates[$shipping_class]);
455
- $rates[$term->slug] = $value;
456
 
457
- }
458
- }
459
- }
460
- }
461
- return $rates;
462
- }
463
 
464
- public function filter_paypal_args( $args ) {
465
- $args['lc'] = $this->sitepress->get_current_language();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
466
 
467
- //filter URL when default permalinks uses
468
- $wpml_settings = $this->sitepress->get_settings();
469
- if( $wpml_settings[ 'language_negotiation_type' ] == 3 ){
470
- $args[ 'notify_url' ] = str_replace( '%2F&', '&', $args[ 'notify_url' ] );
471
- }
472
 
473
- return $args;
474
- }
475
 
476
- public function add_to_cart_sold_individually_exception( $qt, $quantity, $product_id, $variation_id, $cart_item_data ) {
477
 
478
- $post_id = $product_id;
479
- if ( $variation_id ) {
480
- $post_id = $variation_id;
481
- }
482
 
483
- //check if product already added to cart in another language
484
- foreach ( WC()->cart->cart_contents as $cart_item ) {
 
 
 
485
 
486
- if ( $this->sold_individually_product( $cart_item, $cart_item_data, $post_id, $quantity ) ) {
487
 
488
- $this->sold_individually_exception( $post_id );
 
 
 
 
 
 
 
 
489
 
490
- }
491
- }
492
 
493
- return $qt;
494
- }
 
 
495
 
496
- public function sold_individually_product( $cart_item, $cart_item_data, $post_id, $quantity ){
497
 
498
- $current_product_trid = $this->sitepress->get_element_trid( $post_id, 'post_' . get_post_type( $post_id ) );
 
 
499
 
500
- if ( $cart_item['variation_id'] ) {
501
- $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['variation_id'], 'post_product_variation' );
502
- } else {
503
- $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['product_id'], 'post_product' );
504
- }
 
 
 
505
 
506
- if ( apply_filters( 'wcml_add_to_cart_sold_individually', true, $cart_item_data, $post_id, $quantity ) &&
507
- $current_product_trid == $cart_element_trid &&
508
- $cart_item['quantity'] > 0
509
- ) {
510
- return true;
511
- } else {
512
- return false;
513
- }
514
- }
515
 
516
- public function sold_individually_exception( $post_id ){
 
517
 
518
- $wc_cart_url = esc_url( wc_get_cart_url() );
519
- $message_title = sprintf( esc_html__( 'You cannot add another &quot;%s&quot; to your cart.', 'woocommerce' ), get_the_title( $post_id ) );
520
 
521
- $message = '<a href="' . $wc_cart_url . '" class="button wc-forward">' . esc_html__( 'View Cart', 'woocommerce' ) . '</a>';
522
- $message .= ' ' . $message_title;
 
 
 
 
 
523
 
524
- throw new Exception( $message );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
 
526
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
527
 
528
  /**
529
  * @param bool $needs
@@ -531,11 +551,30 @@ class WCML_Cart
531
  *
532
  * @return bool
533
  */
534
- public function use_cart_contents_total_for_needs_payment( $needs, $cart ){
535
- if( isset( $cart->cart_contents_total ) && version_compare( WC()->version,'3.2', '<' ) ){
536
- $needs = $cart->cart_contents_total > 0;
 
 
 
537
  }
 
538
  return $needs;
539
  }
540
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
  }
1
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
+ class WCML_Cart {
4
+ /** @var woocommerce_wpml */
5
+ private $woocommerce_wpml;
6
+ /** @var Sitepress */
7
+ private $sitepress;
8
+ /** @var WooCommerce */
9
+ private $woocommerce;
10
 
11
+ /**
12
+ * WCML_Cart constructor.
13
+ *
14
+ * @param woocommerce_wpml $woocommerce_wpml
15
+ * @param SitePress $sitepress
16
+ * @param WooCommerce $woocommerce
17
+ */
18
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress, WooCommerce $woocommerce ) {
19
+ $this->woocommerce_wpml = $woocommerce_wpml;
20
+ $this->sitepress = $sitepress;
21
+ $this->woocommerce = $woocommerce;
22
+ }
23
+
24
+ public function add_hooks() {
25
+
26
+ if ( $this->is_clean_cart_enabled() ) {
27
+
28
+ $this->enqueue_dialog_ui();
29
+
30
+ add_action( 'wcml_removed_cart_items', array( $this, 'wcml_removed_cart_items_widget' ) );
31
+ add_action( 'wp_ajax_wcml_cart_clear_removed_items', array( $this, 'wcml_cart_clear_removed_items' ) );
32
+ add_action( 'wp_ajax_nopriv_wcml_cart_clear_removed_items', array(
33
+ $this,
34
+ 'wcml_cart_clear_removed_items'
35
+ ) );
36
+
37
+ add_filter( 'wcml_switch_currency_exception', array( $this, 'cart_switching_currency' ), 10, 4 );
38
+ add_action( 'wcml_before_switch_currency', array(
39
+ $this,
40
+ 'switching_currency_empty_cart_if_needed'
41
+ ), 10, 2 );
42
+ } else {
43
+ //cart widget
44
+ add_action( 'wp_ajax_woocommerce_get_refreshed_fragments', array( $this, 'wcml_refresh_fragments' ), 0 );
45
+ add_action( 'wp_ajax_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
46
+ add_action( 'wp_ajax_nopriv_woocommerce_get_refreshed_fragments', array(
47
+ $this,
48
+ 'wcml_refresh_fragments'
49
+ ), 0 );
50
+ add_action( 'wp_ajax_nopriv_woocommerce_add_to_cart', array( $this, 'wcml_refresh_fragments' ), 0 );
51
+
52
+ //cart
53
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
54
+ add_action( 'woocommerce_get_cart_item_from_session', array( $this, 'translate_cart_contents' ) );
55
+ add_action( 'woocommerce_cart_loaded_from_session', array( $this, 'translate_cart_subtotal' ) );
56
+ add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
57
+
58
+ add_filter( 'woocommerce_cart_item_permalink', array( $this, 'cart_item_permalink' ), 10, 2 );
59
+ add_filter( 'woocommerce_paypal_args', array( $this, 'filter_paypal_args' ) );
60
+ add_filter( 'woocommerce_add_to_cart_sold_individually_quantity', array(
61
+ $this,
62
+ 'add_to_cart_sold_individually_exception'
63
+ ), 10, 5 );
64
+
65
+ $this->localize_flat_rates_shipping_classes();
66
+ }
67
+
68
+ add_filter( 'woocommerce_cart_needs_payment', array(
69
+ $this,
70
+ 'use_cart_contents_total_for_needs_payment'
71
+ ), 10, 2 );
72
+
73
+ }
74
+
75
+ public function is_clean_cart_enabled() {
76
+
77
+ $cart_sync_settings = $this->woocommerce_wpml->settings['cart_sync'];
78
+ $wpml_cookies_enabled = $this->sitepress->get_setting( $this->sitepress->get_wp_api()->constant( 'WPML_Cookie_Setting::COOKIE_SETTING_FIELD' ) );
79
+
80
+ if (
81
+ $wpml_cookies_enabled &&
82
+ ( $cart_sync_settings['currency_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) ||
83
+ $cart_sync_settings['lang_switch'] === $this->sitepress->get_wp_api()->constant( 'WCML_CART_CLEAR' ) )
84
+ ) {
85
+ return true;
86
+ }
87
+
88
+ return false;
89
+ }
90
+
91
+ public function enqueue_dialog_ui() {
92
+
93
+ wp_enqueue_script( 'jquery-ui-dialog' );
94
+ wp_enqueue_style( 'wp-jquery-ui-dialog' );
95
+
96
+ }
97
+
98
+ public function wcml_removed_cart_items_widget( $args = array() ) {
99
+
100
+ if ( ! empty( $this->woocommerce->session ) ) {
101
+ $removed_cart_items = new WCML_Removed_Cart_Items_UI( $args, $this->woocommerce_wpml, $this->sitepress, $this->woocommerce );
102
+ $preview = $removed_cart_items->get_view();
103
+
104
+ if ( ! isset( $args['echo'] ) || $args['echo'] ) {
105
+ echo $preview;
106
+ } else {
107
+ return $preview;
108
+ }
109
+ }
110
+
111
+ }
112
+
113
+ public function switching_currency_empty_cart_if_needed( $currency, $force_switch ) {
114
+ if ( $force_switch && $this->woocommerce_wpml->settings['cart_sync']['currency_switch'] == WCML_CART_CLEAR ) {
115
+ $this->empty_cart_if_needed( 'currency_switch' );
116
+ $this->woocommerce->session->set( 'wcml_switched_type', 'currency' );
117
+ }
118
+ }
119
+
120
+ public function empty_cart_if_needed( $switching_type ) {
121
+
122
+ if ( $this->woocommerce_wpml->settings['cart_sync'][ $switching_type ] == WCML_CART_CLEAR ) {
123
+ $removed_products = $this->woocommerce->session->get( 'wcml_removed_items' ) ? maybe_unserialize( $this->woocommerce->session->get( 'wcml_removed_items' ) ) : array();
124
+
125
+ foreach ( WC()->cart->get_cart_for_session() as $item_key => $cart ) {
126
+ if ( ! in_array( $cart['product_id'], $removed_products ) ) {
127
+ $removed_products[] = $cart['product_id'];
128
+ }
129
+ WC()->cart->remove_cart_item( $item_key );
130
+ }
131
+
132
+ if ( ! empty( $this->woocommerce->session ) ) {
133
+ $this->woocommerce->session->set( 'wcml_removed_items', serialize( $removed_products ) );
134
+ }
135
+ }
136
+ }
137
+
138
+ public function wcml_cart_clear_removed_items() {
139
+
140
+ $nonce = filter_input( INPUT_POST, 'wcml_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
141
+ if ( ! $nonce || ! wp_verify_nonce( $nonce, 'wcml_clear_removed_items' ) ) {
142
+ die( 'Invalid nonce' );
143
+ }
144
+
145
+ $this->woocommerce->session->__unset( 'wcml_removed_items' );
146
+ $this->woocommerce->session->__unset( 'wcml_switched_type' );
147
+ }
148
+
149
+ public function cart_switching_currency( $exc, $current_currency, $new_currency, $return = false ) {
150
+
151
+ $cart_for_session = WC()->cart->get_cart_for_session();
152
+ if ( $this->woocommerce_wpml->settings['cart_sync']['currency_switch'] == WCML_CART_SYNC || empty( $cart_for_session ) ) {
153
+ return $exc;
154
+ }
155
+
156
+ $dialog_title = __( 'Switching currency?', 'woocommerce-multilingual' );
157
+ $confirmation_message = __( 'Your cart is not empty! After you switched the currency, all items from the cart will be removed and you have to add them again.', 'woocommerce-multilingual' );
158
+ $stay_in = sprintf( __( 'Keep using %s', 'woocommerce-multilingual' ), $current_currency );
159
+ $switch_to = __( 'Proceed', 'woocommerce-multilingual' );
160
+
161
+ ob_start();
162
+ $this->cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $new_currency, $current_currency );
163
+ $html = ob_get_contents();
164
+ ob_end_clean();
165
+
166
+ if ( $return ) {
167
+ return array( 'prevent_switching' => $html );
168
+ } else {
169
+ echo json_encode( array( 'prevent_switching' => $html ) );
170
+ }
171
+
172
+ return true;
173
+ }
174
+
175
+ public function cart_alert( $dialog_title, $confirmation_message, $switch_to, $stay_in, $switch_to_value, $stay_in_value = false, $language_switch = false ) {
176
+ ?>
177
  <div id="wcml-cart-dialog-confirm" title="<?php echo esc_attr( $dialog_title ) ?>">
178
  <p><?php echo esc_html( $confirmation_message ); ?></p>
179
  </div>
180
 
181
  <script type="text/javascript">
182
+ jQuery(document).ready(function () {
183
+ jQuery("#wcml-cart-dialog-confirm").dialog({
184
  resizable: false,
185
  draggable: false,
186
  height: "auto",
188
  modal: true,
189
  closeOnEscape: false,
190
  dialogClass: "wcml-cart-dialog",
191
+ create: function () {
192
  jQuery('#jquery-ui-style-css').attr('disabled', 'disabled');
193
  },
194
+ open: function (event, ui) {
195
  jQuery(".ui-dialog-titlebar-close", ui.dialog | ui).hide();
196
  },
197
+ close: function (event, ui) {
198
  jQuery('#jquery-ui-style-css').removeAttr('disabled');
199
  },
200
  buttons: {
201
+ "<?php echo $switch_to; ?>": function () {
202
+ jQuery(this).dialog("close");
203
+ <?php if( $language_switch ): ?>
204
+ window.location = '<?php echo esc_url( $switch_to_value, null, 'redirect' ); ?>';
205
+ <?php else: ?>
206
+ jQuery('.wcml_currency_switcher').parent().find('img').remove();
207
+ wcml_load_currency("<?php echo esc_js( $switch_to_value ); ?>", true);
208
+ <?php endif; ?>
209
 
210
  },
211
+ "<?php echo $stay_in; ?>": function () {
212
+ jQuery(this).dialog("close");
213
+ <?php if( $language_switch ): ?>
214
+ window.location = '<?php echo esc_url( $stay_in_value, null, 'redirect' ); ?>';
215
+ <?php else: ?>
216
+ jQuery('.wcml_currency_switcher').parent().find('img').remove();
217
+ jQuery('.wcml_currency_switcher').removeAttr('disabled');
218
+ jQuery('.wcml_currency_switcher').val('<?php echo esc_js( $stay_in_value ); ?>');
219
+ <?php endif; ?>
220
  }
221
  }
222
  });
223
  });
224
  </script>
225
+ <?php
226
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
227
 
228
+ public function wcml_refresh_fragments() {
229
+ WC()->cart->calculate_totals();
230
+ $this->woocommerce_wpml->locale->wcml_refresh_text_domain();
231
+ }
 
 
232
 
233
+ /*
234
+ * Update cart and cart session when switch language
235
+ */
236
+ public function woocommerce_calculate_totals( $cart, $currency = false ) {
237
+
238
+ $current_language = $this->sitepress->get_current_language();
239
+ $new_cart_data = array();
240
+
241
+ foreach ( $cart->cart_contents as $key => $cart_item ) {
242
+ $tr_product_id = apply_filters( 'translate_object_id', $cart_item['product_id'], 'product', false, $current_language );
243
+ //translate custom attr labels in cart object
244
+
245
+ if ( version_compare( WC_VERSION, '3.0.0', '<' ) && isset( $cart_item['data']->product_attributes ) ) {
246
+ foreach ( $cart_item['data']->product_attributes as $attr_key => $product_attribute ) {
247
+ if ( isset( $product_attribute['is_taxonomy'] ) && ! $product_attribute['is_taxonomy'] ) {
248
+ $cart->cart_contents[ $key ]['data']->product_attributes[ $attr_key ]['name'] = $this->woocommerce_wpml->strings->translated_attribute_label(
249
+ $product_attribute['name'],
250
+ $product_attribute['name'],
251
+ $tr_product_id );
252
+ }
253
+ }
254
+ }
255
+
256
+ //translate custom attr value in cart object
257
+ if ( isset( $cart_item['variation'] ) && is_array( $cart_item['variation'] ) ) {
258
+ foreach ( $cart_item['variation'] as $attr_key => $attribute ) {
259
+ $cart->cart_contents[ $key ]['variation'][ $attr_key ] = $this->get_cart_attribute_translation(
260
+ $attr_key,
261
+ $attribute,
262
+ $cart_item['variation_id'],
263
+ $current_language,
264
+ $cart_item['product_id'],
265
+ $tr_product_id
266
+ );
267
+ }
268
+ }
269
+
270
+ if ( $currency !== false ) {
271
+ $cart->cart_contents[ $key ]['data']->price = get_post_meta( $cart_item['product_id'], '_price', 1 );
272
+ }
273
+
274
+ if ( $cart_item['product_id'] == $tr_product_id ) {
275
+ $new_cart_data[ $key ] = apply_filters( 'wcml_cart_contents_not_changed', $cart->cart_contents[ $key ], $key, $current_language );
276
+ continue;
277
+ }
278
+
279
+ if ( isset( $cart->cart_contents[ $key ]['variation_id'] ) && $cart->cart_contents[ $key ]['variation_id'] ) {
280
+ $tr_variation_id = apply_filters( 'translate_object_id', $cart_item['variation_id'], 'product_variation', false, $current_language );
281
+ if ( ! is_null( $tr_variation_id ) ) {
282
+ $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
283
+ $cart->cart_contents[ $key ]['variation_id'] = intval( $tr_variation_id );
284
+ if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '2.7', '<' ) ) {
285
+ $cart->cart_contents[ $key ]['data']->id = intval( $tr_product_id );
286
+ } else {
287
+ $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
288
+ }
289
+ $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
290
+ }
291
+ } else {
292
+ if ( ! is_null( $tr_product_id ) ) {
293
+ $cart->cart_contents[ $key ]['product_id'] = intval( $tr_product_id );
294
+ if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '2.7', '<' ) ) {
295
+ $cart->cart_contents[ $key ]['data']->id = intval( $tr_product_id );
296
+ } else {
297
+ $cart->cart_contents[ $key ]['data']->set_id( intval( $tr_product_id ) );
298
+ }
299
+ $cart->cart_contents[ $key ]['data']->post = get_post( $tr_product_id );
300
+ }
301
+ }
302
+
303
+ if ( ! is_null( $tr_product_id ) ) {
304
+
305
+ $new_key = $this->wcml_generate_cart_key( $cart->cart_contents, $key );
306
+ $cart->cart_contents = apply_filters( 'wcml_update_cart_contents_lang_switch', $cart->cart_contents, $key, $new_key, $current_language );
307
+ $new_cart_data[ $new_key ] = $cart->cart_contents[ $key ];
308
+
309
+ $new_cart_data = apply_filters( 'wcml_cart_contents', $new_cart_data, $cart->cart_contents, $key, $new_key );
310
+ }
311
+ }
312
 
313
+ $cart->cart_contents = $this->wcml_check_on_duplicate_products_in_cart( $new_cart_data );
314
+ $this->woocommerce->session->cart = $cart->cart_contents;
 
 
 
315
 
316
+ return $cart->cart_contents;
317
+ }
318
 
319
+ public function wcml_check_on_duplicate_products_in_cart( $cart_contents ) {
320
 
321
+ $exists_products = array();
322
+ remove_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
 
 
323
 
324
+ foreach ( $cart_contents as $key => $cart_content ) {
325
+ $cart_contents = apply_filters( 'wcml_check_on_duplicated_products_in_cart', $cart_contents, $key, $cart_content );
326
+ if ( apply_filters( 'wcml_exception_duplicate_products_in_cart', false, $cart_content ) ) {
327
+ continue;
328
+ }
329
 
330
+ $quantity = $cart_content['quantity'];
331
 
332
+ $search_key = $this->wcml_generate_cart_key( $cart_contents, $key );
333
+ if ( array_key_exists( $search_key, $exists_products ) ) {
334
+ unset( $cart_contents[ $key ] );
335
+ $cart_contents[ $exists_products[ $search_key ] ]['quantity'] = $cart_contents[ $exists_products[ $search_key ] ]['quantity'] + $quantity;
336
+ $this->woocommerce->cart->calculate_totals();
337
+ } else {
338
+ $exists_products[ $search_key ] = $key;
339
+ }
340
+ }
341
 
342
+ add_action( 'woocommerce_before_calculate_totals', array( $this, 'woocommerce_calculate_totals' ), 100 );
 
343
 
344
+ return $cart_contents;
345
+ }
346
+
347
+ public function get_cart_attribute_translation( $attr_key, $attribute, $variation_id, $current_language, $product_id, $tr_product_id ) {
348
 
349
+ $attr_translation = $attribute;
350
 
351
+ if ( ! empty( $attribute ) ) {
352
+ //delete 'attribute_' at the beginning
353
+ $taxonomy = substr( $attr_key, 10, strlen( $attr_key ) - 1 );
354
 
355
+ if ( taxonomy_exists( $taxonomy ) ) {
356
+ if ( $this->woocommerce_wpml->attributes->is_translatable_attribute( $taxonomy ) ) {
357
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $taxonomy, $attribute );
358
+ $trnsl_term_id = apply_filters( 'translate_object_id', $term_id, $taxonomy, true, $current_language );
359
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $trnsl_term_id, $taxonomy );
360
+ $attr_translation = $term->slug;
361
+ }
362
+ } else {
363
 
364
+ $trnsl_attr = get_post_meta( $variation_id, $attr_key, true );
365
+
366
+ if ( $trnsl_attr ) {
367
+ $attr_translation = $trnsl_attr;
368
+ } else {
369
+ $attr_translation = $this->woocommerce_wpml->attributes->get_custom_attr_translation( $product_id, $tr_product_id, $taxonomy, $attribute );
370
+ }
371
+ }
372
+ }
373
 
374
+ return $attr_translation;
375
+ }
376
 
377
+ public function wcml_generate_cart_key( $cart_contents, $key ) {
378
+ $cart_item_data = $this->get_cart_item_data_from_cart( $cart_contents[ $key ] );
379
 
380
+ return $this->woocommerce->cart->generate_cart_id(
381
+ $cart_contents[ $key ]['product_id'],
382
+ $cart_contents[ $key ]['variation_id'],
383
+ $cart_contents[ $key ]['variation'],
384
+ $cart_item_data
385
+ );
386
+ }
387
 
388
+ //get cart_item_data from existing cart array ( from session )
389
+ public function get_cart_item_data_from_cart( $cart_contents ) {
390
+ unset( $cart_contents['product_id'] );
391
+ unset( $cart_contents['variation_id'] );
392
+ unset( $cart_contents['variation'] );
393
+ unset( $cart_contents['quantity'] );
394
+ unset( $cart_contents['line_total'] );
395
+ unset( $cart_contents['line_subtotal'] );
396
+ unset( $cart_contents['line_tax'] );
397
+ unset( $cart_contents['line_subtotal_tax'] );
398
+ unset( $cart_contents['line_tax_data'] );
399
+ unset( $cart_contents['data'] );
400
+
401
+ return apply_filters( 'wcml_filter_cart_item_data', $cart_contents );
402
+ }
403
 
404
+ public function translate_cart_contents( $item ) {
405
+
406
+ // translate the product id and product data
407
+ $item['product_id'] = apply_filters( 'translate_object_id', $item['product_id'], 'product', true );
408
+ if ( $item['variation_id'] ) {
409
+ $item['variation_id'] = apply_filters( 'translate_object_id', $item['variation_id'], 'product_variation', true );
410
+ }
411
+
412
+ $item_product_title = $item['variation_id'] ? get_the_title( $item['variation_id'] ) : get_the_title( $item['product_id'] );
413
+
414
+ if ( $this->sitepress->get_wp_api()->version_compare( $this->sitepress->get_wp_api()->constant( 'WC_VERSION' ), '3.0.0', '>=' ) ) {
415
+ $item['data']->set_name( $item_product_title );
416
+ } else {
417
+ $item['data']->post->post_title = $item_product_title;
418
+ }
419
+
420
+ return $item;
421
+ }
422
+
423
+ public function translate_cart_subtotal( $cart ) {
424
+
425
+ if ( isset( $_SERVER['REQUEST_URI'] ) ) {
426
+ //special case: check if attachment loading
427
+ $attachments = array( 'png', 'jpg', 'jpeg', 'gif', 'js', 'css' );
428
+
429
+ foreach ( $attachments as $attachment ) {
430
+ $match = preg_match( '/\.' . $attachment . '$/', $_SERVER['REQUEST_URI'] );
431
+ if ( ! empty( $match ) ) {
432
+ return false;
433
+ }
434
+ }
435
+ }
436
+
437
+ if ( apply_filters( 'wcml_calculate_totals_exception', true, $cart ) ) {
438
+ $cart->calculate_totals();
439
+ }
440
+
441
+ }
442
+
443
+ // refresh cart total to return correct price from WC object
444
+ public function wcml_refresh_cart_total() {
445
+ WC()->cart->calculate_totals();
446
+ }
447
+
448
+
449
+ public function localize_flat_rates_shipping_classes() {
450
+
451
+ if ( is_ajax() && isset( $_POST['action'] ) && $_POST['action'] == 'woocommerce_update_order_review' ) {
452
+ $this->woocommerce->shipping->load_shipping_methods();
453
+ $shipping_methods = $this->woocommerce->shipping->get_shipping_methods();
454
+ foreach ( $shipping_methods as $method ) {
455
+ if ( isset( $method->flat_rate_option ) ) {
456
+ add_filter( 'option_' . $method->flat_rate_option, array( $this, 'translate_shipping_class' ) );
457
+ }
458
+ }
459
+
460
+ }
461
+ }
462
+
463
+ public function translate_shipping_class( $rates ) {
464
+
465
+ if ( is_array( $rates ) ) {
466
+ foreach ( $rates as $shipping_class => $value ) {
467
+ $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( 'product_shipping_class', $shipping_class );
468
+
469
+ if ( $term_id && ! is_wp_error( $term_id ) ) {
470
+ $translated_term_id = apply_filters( 'translate_object_id', $term_id, 'product_shipping_class', true );
471
+ if ( $translated_term_id != $term_id ) {
472
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $translated_term_id, 'product_shipping_class' );
473
+ unset( $rates[ $shipping_class ] );
474
+ $rates[ $term->slug ] = $value;
475
+
476
+ }
477
+ }
478
+ }
479
+ }
480
+
481
+ return $rates;
482
+ }
483
+
484
+ public function filter_paypal_args( $args ) {
485
+ $args['lc'] = $this->sitepress->get_current_language();
486
+
487
+ //filter URL when default permalinks uses
488
+ $wpml_settings = $this->sitepress->get_settings();
489
+ if ( $wpml_settings['language_negotiation_type'] == 3 ) {
490
+ $args['notify_url'] = str_replace( '%2F&', '&', $args['notify_url'] );
491
+ }
492
+
493
+ return $args;
494
+ }
495
+
496
+ public function add_to_cart_sold_individually_exception( $qt, $quantity, $product_id, $variation_id, $cart_item_data ) {
497
+
498
+ $post_id = $product_id;
499
+ if ( $variation_id ) {
500
+ $post_id = $variation_id;
501
+ }
502
+
503
+ //check if product already added to cart in another language
504
+ foreach ( WC()->cart->cart_contents as $cart_item ) {
505
+
506
+ if ( $this->sold_individually_product( $cart_item, $cart_item_data, $post_id, $quantity ) ) {
507
+
508
+ $this->sold_individually_exception( $post_id );
509
+
510
+ }
511
+ }
512
+
513
+ return $qt;
514
+ }
515
+
516
+ public function sold_individually_product( $cart_item, $cart_item_data, $post_id, $quantity ) {
517
+
518
+ $current_product_trid = $this->sitepress->get_element_trid( $post_id, 'post_' . get_post_type( $post_id ) );
519
+
520
+ if ( $cart_item['variation_id'] ) {
521
+ $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['variation_id'], 'post_product_variation' );
522
+ } else {
523
+ $cart_element_trid = $this->sitepress->get_element_trid( $cart_item['product_id'], 'post_product' );
524
+ }
525
+
526
+ if ( apply_filters( 'wcml_add_to_cart_sold_individually', true, $cart_item_data, $post_id, $quantity ) &&
527
+ $current_product_trid == $cart_element_trid &&
528
+ $cart_item['quantity'] > 0
529
+ ) {
530
+ return true;
531
+ } else {
532
+ return false;
533
+ }
534
+ }
535
+
536
+ public function sold_individually_exception( $post_id ) {
537
+
538
+ $wc_cart_url = esc_url( wc_get_cart_url() );
539
+ $message_title = sprintf( esc_html__( 'You cannot add another &quot;%s&quot; to your cart.', 'woocommerce' ), get_the_title( $post_id ) );
540
+
541
+ $message = '<a href="' . $wc_cart_url . '" class="button wc-forward">' . esc_html__( 'View Cart', 'woocommerce' ) . '</a>';
542
+ $message .= ' ' . $message_title;
543
+
544
+ throw new Exception( $message );
545
+
546
+ }
547
 
548
  /**
549
  * @param bool $needs
551
  *
552
  * @return bool
553
  */
554
+ public function use_cart_contents_total_for_needs_payment( $needs, $cart ) {
555
+
556
+ if ( version_compare( WC()->version, '3.2', '<' ) ) {
557
+ $needs = ( isset( $cart->cart_contents_total ) && $cart->cart_contents_total > 0 )
558
+ || ( isset( $cart->total ) && $cart->total > 0 )
559
+ || isset( $cart->recurring_carts );
560
  }
561
+
562
  return $needs;
563
  }
564
 
565
+ /**
566
+ * @param string $permalink
567
+ * @param array $cart_item
568
+ *
569
+ * @return string
570
+ */
571
+ public function cart_item_permalink( $permalink, $cart_item ) {
572
+
573
+ if ( ! $this->sitepress->get_setting( 'auto_adjust_ids' ) ) {
574
+ $permalink = get_permalink( $cart_item['product_id'] );
575
+ }
576
+
577
+ return $permalink;
578
+ }
579
+
580
  }
inc/class-wcml-compatibility.php CHANGED
@@ -79,7 +79,7 @@ class WCML_Compatibility {
79
 
80
  // Product Add-ons
81
  if ( class_exists( 'Product_Addon_Display' ) ) {
82
- $this->product_addons = new WCML_Product_Addons( $this->sitepress );
83
  $this->product_addons->add_hooks();
84
  }
85
 
@@ -89,7 +89,8 @@ class WCML_Compatibility {
89
  }
90
  //Store Exporter plugin
91
  if ( defined( 'WOO_CE_PATH' ) ) {
92
- $this->wc_exporter = new WCML_wcExporter();
 
93
  }
94
 
95
  //Gravity Forms
@@ -218,10 +219,15 @@ class WCML_Compatibility {
218
 
219
  // Woocommerce Memberships
220
  if ( class_exists( 'WC_Memberships' ) ) {
221
- $this->wc_memberships = new WCML_WC_Memberships();
222
  $this->wc_memberships->add_hooks();
223
  }
224
 
 
 
 
 
 
225
 
226
  }
227
 
79
 
80
  // Product Add-ons
81
  if ( class_exists( 'Product_Addon_Display' ) ) {
82
+ $this->product_addons = new WCML_Product_Addons( $this->sitepress, $this->woocommerce_wpml->settings['enable_multi_currency'] );
83
  $this->product_addons->add_hooks();
84
  }
85
 
89
  }
90
  //Store Exporter plugin
91
  if ( defined( 'WOO_CE_PATH' ) ) {
92
+ $this->wc_exporter = new WCML_wcExporter( $this->sitepress, $this->woocommerce_wpml );
93
+ $this->wc_exporter->add_hooks();
94
  }
95
 
96
  //Gravity Forms
219
 
220
  // Woocommerce Memberships
221
  if ( class_exists( 'WC_Memberships' ) ) {
222
+ $this->wc_memberships = new WCML_WC_Memberships( $this->sitepress->get_wp_api() );
223
  $this->wc_memberships->add_hooks();
224
  }
225
 
226
+ // MaxStore-Pro Theme
227
+ if ( function_exists( 'maxstore_pro_setup' ) ) {
228
+ $this->maxstore = new WCML_MaxStore();
229
+ $this->maxstore->add_hooks();
230
+ }
231
 
232
  }
233
 
inc/class-wcml-coupons.php CHANGED
@@ -1,125 +1,127 @@
1
  <?php
2
 
3
- class WCML_Coupons{
4
-
5
- /** @var woocommerce_wpml */
6
- private $woocommerce_wpml;
7
- /** @var Sitepress */
8
- private $sitepress;
9
-
10
- public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress ) {
11
- $this->woocommerce_wpml = $woocommerce_wpml;
12
- $this->sitepress = $sitepress;
13
- }
14
-
15
- public function add_hooks(){
16
-
17
- add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
18
- add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
19
-
20
- add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
21
- }
22
-
23
- public function wcml_coupon_loaded( $coupons_data ){
24
-
25
- $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
26
-
27
- $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
28
- $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
29
- $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
30
- $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
31
-
32
- $product_ids = array();
33
- $exclude_product_ids = array();
34
- $product_categories_ids = array();
35
- $exclude_product_categories_ids = array();
36
-
37
- foreach( $coupon_product_ids as $prod_id ){
38
- $post_type = get_post_field( 'post_type', $prod_id );
39
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
40
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
41
- foreach( $translations as $translation ){
42
- $product_ids[] = $translation->element_id;
43
- }
44
- }
45
- foreach( $coupon_excluded_product_ids as $prod_id ){
46
- $post_type = get_post_field( 'post_type', $prod_id );
47
- $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
48
- $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
49
- foreach( $translations as $translation ){
50
- $exclude_product_ids[] = $translation->element_id;
51
- }
52
- }
53
-
54
- foreach( $coupon_product_categories as $cat_id ){
55
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
56
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
57
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
58
-
59
- foreach( $translations as $translation ){
60
- $product_categories_ids[] = $translation->term_id;
61
- }
62
- }
63
-
64
- foreach( $coupon_excluded_product_categories as $cat_id ){
65
- $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id,'product_cat' );
66
- $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
67
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
68
- foreach( $translations as $translation ){
69
- $exclude_product_categories_ids[] = $translation->term_id;
70
- }
71
- }
72
-
73
- if( $wc_27_coupons ){
74
- $coupons_data->set_product_ids( $product_ids );
75
- $coupons_data->set_excluded_product_ids( $exclude_product_ids );
76
- $coupons_data->set_product_categories( $product_categories_ids );
77
- $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
78
- } else {
79
- $coupons_data->product_ids = $product_ids;
80
- $coupons_data->exclude_product_ids = $exclude_product_ids;
81
- $coupons_data->product_categories = $product_categories_ids;
82
- $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
83
- }
84
-
85
- return $coupons_data;
86
- }
87
-
88
- public function icl_adjust_terms_filtering(){
89
- if( is_admin() && isset( $_GET[ 'action' ] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ){
90
- global $icl_adjust_id_url_filter_off;
91
- $icl_adjust_id_url_filter_off = true;
92
- }
93
- }
94
-
95
-
96
- /**
97
- * @param bool $valid
98
- * @param WC_Product $product
99
- * @param WC_Coupon $object
100
- * @param array $values
101
- *
102
- * @return bool
103
- */
104
- public function is_valid_for_product( $valid, $product, $object, $values )
105
- {
106
-
107
- $product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
108
-
109
- $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $this->sitepress->get_current_language() );
110
-
111
- if ( $product_id !== $translated_product_id ) {
112
-
113
- remove_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
114
-
115
- $valid = $object->is_valid_for_product( wc_get_product( $translated_product_id ), $values );
116
-
117
- add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
118
-
119
- }
120
-
121
- return $valid;
122
-
123
- }
 
 
124
 
125
  }
1
  <?php
2
 
3
+ class WCML_Coupons {
4
+
5
+ /** @var woocommerce_wpml */
6
+ private $woocommerce_wpml;
7
+ /** @var Sitepress */
8
+ private $sitepress;
9
+
10
+ public function __construct( woocommerce_wpml $woocommerce_wpml, SitePress $sitepress ) {
11
+ $this->woocommerce_wpml = $woocommerce_wpml;
12
+ $this->sitepress = $sitepress;
13
+ }
14
+
15
+ public function add_hooks() {
16
+
17
+ add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
18
+ add_action( 'admin_init', array( $this, 'icl_adjust_terms_filtering' ) );
19
+
20
+ add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
21
+ }
22
+
23
+ public function wcml_coupon_loaded( $coupons_data ) {
24
+
25
+ $wc_27_coupons = method_exists( 'WC_Coupon', 'get_amount' );
26
+
27
+ $coupon_product_ids = $wc_27_coupons ? $coupons_data->get_product_ids() : $coupons_data->product_ids;
28
+ $coupon_excluded_product_ids = $wc_27_coupons ? $coupons_data->get_excluded_product_ids() : $coupons_data->exclude_product_ids;
29
+ $coupon_product_categories = $wc_27_coupons ? $coupons_data->get_product_categories() : $coupons_data->product_categories;
30
+ $coupon_excluded_product_categories = $wc_27_coupons ? $coupons_data->get_excluded_product_categories() : $coupons_data->exclude_product_categories;
31
+
32
+ $product_ids = array();
33
+ $exclude_product_ids = array();
34
+ $product_categories_ids = array();
35
+ $exclude_product_categories_ids = array();
36
+
37
+ foreach ( $coupon_product_ids as $prod_id ) {
38
+ $post_type = get_post_field( 'post_type', $prod_id );
39
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
40
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
41
+ foreach ( $translations as $translation ) {
42
+ $product_ids[] = $translation->element_id;
43
+ }
44
+ }
45
+ foreach ( $coupon_excluded_product_ids as $prod_id ) {
46
+ $post_type = get_post_field( 'post_type', $prod_id );
47
+ $trid = $this->sitepress->get_element_trid( $prod_id, 'post_' . $post_type );
48
+ $translations = $this->sitepress->get_element_translations( $trid, 'post_' . $post_type );
49
+ foreach ( $translations as $translation ) {
50
+ $exclude_product_ids[] = $translation->element_id;
51
+ }
52
+ }
53
+
54
+ foreach ( $coupon_product_categories as $cat_id ) {
55
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
56
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
57
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
58
+
59
+ foreach ( $translations as $translation ) {
60
+ $product_categories_ids[] = $translation->term_id;
61
+ }
62
+ }
63
+
64
+ foreach ( $coupon_excluded_product_categories as $cat_id ) {
65
+ $term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $cat_id, 'product_cat' );
66
+ $trid = $this->sitepress->get_element_trid( $term->term_taxonomy_id, 'tax_product_cat' );
67
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_cat' );
68
+ foreach ( $translations as $translation ) {
69
+ $exclude_product_categories_ids[] = $translation->term_id;
70
+ }
71
+ }
72
+
73
+ if ( $wc_27_coupons ) {
74
+ $coupons_data->set_product_ids( $product_ids );
75
+ $coupons_data->set_excluded_product_ids( $exclude_product_ids );
76
+ $coupons_data->set_product_categories( $product_categories_ids );
77
+ $coupons_data->set_excluded_product_categories( $exclude_product_categories_ids );
78
+ } else {
79
+ $coupons_data->product_ids = $product_ids;
80
+ $coupons_data->exclude_product_ids = $exclude_product_ids;
81
+ $coupons_data->product_categories = $product_categories_ids;
82
+ $coupons_data->exclude_product_categories = $exclude_product_categories_ids;
83
+ }
84
+
85
+ return $coupons_data;
86
+ }
87
+
88
+ public function icl_adjust_terms_filtering() {
89
+ if ( is_admin() && isset( $_GET['action'] ) && $_GET['action'] == 'woocommerce_json_search_products_and_variations' ) {
90
+ global $icl_adjust_id_url_filter_off;
91
+ $icl_adjust_id_url_filter_off = true;
92
+ }
93
+ }
94
+
95
+ /**
96
+ * @param bool $valid
97
+ * @param WC_Product $product
98
+ * @param WC_Coupon $object
99
+ * @param array $values
100
+ *
101
+ * @return bool
102
+ */
103
+ public function is_valid_for_product( $valid, $product, $object, $values ) {
104
+
105
+ if ( version_compare( WC()->version, '3.0', '<' ) ) {
106
+ $product_id = $product->is_type( 'variation' ) ? $product->parent->id : $product->id;
107
+ } else {
108
+ $product_id = $product->is_type( 'variation' ) ? $product->get_parent_id() : $product->get_id();
109
+ }
110
+
111
+ $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', false, $this->sitepress->get_current_language() );
112
+
113
+ if ( $product_id !== $translated_product_id ) {
114
+
115
+ remove_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
116
+
117
+ $valid = $object->is_valid_for_product( wc_get_product( $translated_product_id ), $values );
118
+
119
+ add_filter( 'woocommerce_coupon_is_valid_for_product', array( $this, 'is_valid_for_product' ), 10, 4 );
120
+
121
+ }
122
+
123
+ return $valid;
124
+
125
+ }
126
 
127
  }
inc/class-wcml-emails.php CHANGED
@@ -59,10 +59,6 @@ class WCML_Emails{
59
  ), 9 );
60
  add_action( 'woocommerce_new_customer_note', array( $this, 'refresh_email_lang' ), 9 );
61
 
62
-
63
- add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'email_heading_refund' ), 9 );
64
- add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
65
-
66
  //new order admins email
67
  add_action( 'woocommerce_order_status_pending_to_processing_notification', array(
68
  $this,
@@ -120,6 +116,10 @@ class WCML_Emails{
120
  'send_queued_transactional_email'
121
  ), 10, 3 );
122
 
 
 
 
 
123
  add_filter( 'woocommerce_email_setup_locale', '__return_false' );
124
  add_filter( 'woocommerce_email_restore_locale', '__return_false' );
125
  }
@@ -239,25 +239,21 @@ class WCML_Emails{
239
  }
240
  }
241
 
242
- function email_heading_refund( $order_id, $refund_id = null ){
243
 
244
- if( class_exists( 'WC_Email_Customer_Refunded_Order' ) && isset( $this->woocommerce->mailer()->emails[ 'WC_Email_Customer_Refunded_Order' ] ) ){
 
 
245
 
246
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->heading =
247
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
248
- '[woocommerce_customer_refunded_order_settings]heading_partial', $order_id );
249
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->subject =
250
- $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
251
- '[woocommerce_customer_refunded_order_settings]subject_partial', $order_id );
252
 
253
- $enabled = $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled;
254
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = false;
255
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->trigger($order_id, true, $refund_id);
256
- $this->woocommerce->mailer()->emails['WC_Email_Customer_Refunded_Order']->enabled = $enabled;
257
 
258
- }
259
- }
260
 
 
261
 
262
  function new_order_admin_email($order_id){
263
 
@@ -273,9 +269,9 @@ class WCML_Emails{
273
 
274
  $this->change_email_language( $user_lang );
275
 
276
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading', $order_id );
277
 
278
- $this->woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject', $order_id );
279
 
280
  $this->woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
281
 
@@ -352,11 +348,9 @@ class WCML_Emails{
352
  return $value;
353
  }
354
 
355
- function wcml_get_translated_email_string( $context, $name, $order_id = false ){
356
 
357
- $language_code = null;
358
-
359
- if( $order_id ){
360
  $order_language = get_post_meta( $order_id, 'wpml_language', true );
361
  if( $order_language ){
362
  $language_code = $order_language;
59
  ), 9 );
60
  add_action( 'woocommerce_new_customer_note', array( $this, 'refresh_email_lang' ), 9 );
61
 
 
 
 
 
62
  //new order admins email
63
  add_action( 'woocommerce_order_status_pending_to_processing_notification', array(
64
  $this,
116
  'send_queued_transactional_email'
117
  ), 10, 3 );
118
 
119
+ add_action( 'woocommerce_order_partially_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
120
+ add_action( 'woocommerce_order_fully_refunded_notification', array( $this, 'refresh_email_lang' ), 9 );
121
+ add_filter( 'woocommerce_email_get_option', array( $this, 'filter_refund_emails_strings' ), 10, 4 );
122
+
123
  add_filter( 'woocommerce_email_setup_locale', '__return_false' );
124
  add_filter( 'woocommerce_email_restore_locale', '__return_false' );
125
  }
239
  }
240
  }
241
 
242
+ public function filter_refund_emails_strings( $value, $object , $old_value, $key ){
243
 
244
+ if( in_array( $key, array( 'subject_partial', 'subject_full', 'heading_partial', 'heading_full' ) ) && $object->object ){
245
+ $translated_value = $this->get_refund_email_translated_string( $key, $object );
246
+ }
247
 
248
+ return !empty( $translated_value ) ? $translated_value : $value;
249
+ }
 
 
 
 
250
 
251
+ public function get_refund_email_translated_string( $key, $object){
 
 
 
252
 
253
+ return $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_customer_refunded_order_settings',
254
+ '[woocommerce_customer_refunded_order_settings]'.$key, $object->object->get_id() );
255
 
256
+ }
257
 
258
  function new_order_admin_email($order_id){
259
 
269
 
270
  $this->change_email_language( $user_lang );
271
 
272
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->heading = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]heading', $order_id, $user_lang );
273
 
274
+ $this->woocommerce->mailer()->emails['WC_Email_New_Order']->subject = $this->wcml_get_translated_email_string( 'admin_texts_woocommerce_new_order_settings', '[woocommerce_new_order_settings]subject', $order_id, $user_lang );
275
 
276
  $this->woocommerce->mailer()->emails['WC_Email_New_Order']->recipient = $recipient;
277
 
348
  return $value;
349
  }
350
 
351
+ function wcml_get_translated_email_string( $context, $name, $order_id = false, $language_code = null ){
352
 
353
+ if( $order_id && !$language_code ){
 
 
354
  $order_language = get_post_meta( $order_id, 'wpml_language', true );
355
  if( $order_language ){
356
  $language_code = $order_language;
inc/class-wcml-orders.php CHANGED
@@ -174,31 +174,17 @@ class WCML_Orders{
174
  }
175
 
176
  $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
 
177
  if( !is_null( $tr_product_id ) ){
178
  $item->set_product_id( $tr_product_id );
179
  $item->set_name( get_post( $tr_product_id )->post_title );
180
  }
181
- $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
182
- if( !is_null( $tr_variation_id ) ){
183
- $item->set_variation_id( $tr_variation_id );
184
- }
185
 
186
- $meta_data = array();
187
- foreach( $item->get_meta_data() as $data ){
188
-
189
- if( substr( $data->key, 0, 3) == 'pa_' ){
190
- $term_id = $this->woocommerce_wpml->terms->wcml_get_term_id_by_slug( $data->key, $data->value );
191
- $tr_id = apply_filters( 'translate_object_id', $term_id, $data->key, false, $language_to_filter );
192
-
193
- if(!is_null($tr_id)){
194
- $translated_term = $this->woocommerce_wpml->terms->wcml_get_term_by_id( $tr_id, $data->key);
195
- $data->value = $translated_term->slug;
196
- }
197
- }
198
-
199
- $meta_data[] = $data;
200
-
201
- }
202
  }
203
  }elseif( $item instanceof WC_Order_Item_Shipping ){
204
  if( $item->get_method_id() ){
174
  }
175
 
176
  $tr_product_id = apply_filters( 'translate_object_id', $item_product_id, 'product', false, $language_to_filter );
177
+
178
  if( !is_null( $tr_product_id ) ){
179
  $item->set_product_id( $tr_product_id );
180
  $item->set_name( get_post( $tr_product_id )->post_title );
181
  }
 
 
 
 
182
 
183
+ $tr_variation_id = apply_filters( 'translate_object_id', $item->get_variation_id(), 'product_variation', false, $language_to_filter );
184
+ if ( ! is_null( $tr_variation_id ) ) {
185
+ $item->set_variation_id( $tr_variation_id );
186
+ $item->set_name( wc_get_product( $tr_variation_id )->get_name() );
187
+ }
 
 
 
 
 
 
 
 
 
 
 
188
  }
189
  }elseif( $item instanceof WC_Order_Item_Shipping ){
190
  if( $item->get_method_id() ){
inc/class-wcml-requests.php CHANGED
@@ -39,8 +39,10 @@ class WCML_Requests{
39
 
40
  $woocommerce_wpml->settings['file_path_sync'] = $wcml_file_path_sync;
41
 
42
- $woocommerce_wpml->settings['cart_sync']['lang_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT ) );
43
- $woocommerce_wpml->settings['cart_sync']['currency_switch'] = intval( filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT ) );
 
 
44
 
45
  $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
46
  $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
39
 
40
  $woocommerce_wpml->settings['file_path_sync'] = $wcml_file_path_sync;
41
 
42
+ if ( isset( $_POST['cart_sync_lang'] ) && isset( $_POST['cart_sync_currencies'] ) ) {
43
+ $woocommerce_wpml->settings['cart_sync']['lang_switch'] = (int) filter_input( INPUT_POST, 'cart_sync_lang', FILTER_SANITIZE_NUMBER_INT );
44
+ $woocommerce_wpml->settings['cart_sync']['currency_switch'] = (int) filter_input( INPUT_POST, 'cart_sync_currencies', FILTER_SANITIZE_NUMBER_INT );
45
+ }
46
 
47
  $new_value = $wcml_file_path_sync == 0 ? 2 :$wcml_file_path_sync;
48
  $sitepress_settings['translation-management']['custom_fields_translation']['_downloadable_files'] = $new_value;
inc/class-wcml-resources.php CHANGED
@@ -142,6 +142,7 @@ class WCML_Resources {
142
  wp_localize_script( 'cart-widget', 'actions', array(
143
  'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
144
  'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0,
 
145
  'cart_fragment' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) ) ),
146
  ) );
147
  } elseif( is_admin() ) {
142
  wp_localize_script( 'cart-widget', 'actions', array(
143
  'is_lang_switched' => self::$sitepress->get_language_from_url( $referer ) != self::$sitepress->get_current_language() ? 1 : 0,
144
  'is_currency_switched' => isset( $_GET[ 'wcmlc' ] ) ? 1 : 0,
145
+ 'force_reset' => apply_filters( 'wcml_force_reset_cart_fragments', 0 ),
146
  'cart_fragment' => apply_filters( 'woocommerce_cart_fragment_name', 'wc_fragments_' . md5( get_current_blog_id() . '_' . get_site_url( get_current_blog_id(), '/' ) ) ),
147
  ) );
148
  } elseif( is_admin() ) {
inc/class-wcml-store-pages.php CHANGED
@@ -332,7 +332,7 @@ class WCML_Store_Pages{
332
  foreach ($miss_lang['codes'] as $mis_lang) {
333
  $args = array();
334
 
335
- $this->woocommerce_wpml->locale->switch_locale( $mis_lang );
336
 
337
  foreach ($check_pages as $page) {
338
  $orig_id = get_option($page);
@@ -384,10 +384,25 @@ class WCML_Store_Pages{
384
  $this->sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
385
  }
386
  }
387
- $this->woocommerce_wpml->locale->switch_locale();
388
  }
389
  }
390
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
391
 
392
  /**
393
  * get missing pages
332
  foreach ($miss_lang['codes'] as $mis_lang) {
333
  $args = array();
334
 
335
+ $this->switch_lang( $mis_lang );
336
 
337
  foreach ($check_pages as $page) {
338
  $orig_id = get_option($page);
384
  $this->sitepress->set_element_language_details($new_page_id, 'post_page', $trid, $mis_lang);
385
  }
386
  }
387
+ $this->switch_lang();
388
  }
389
  }
390
  }
391
+
392
+ private function switch_lang( $lang_code = false ){
393
+
394
+ $st_prior_2_6 = version_compare( $this->sitepress->get_wp_api()->constant( 'WPML_ST_VERSION' ), '2.6.0', '<' );
395
+
396
+ if( !$st_prior_2_6 ){
397
+ $is_mo_loading_disabled = WPML_Theme_Localization_Type::USE_ST_AND_NO_MO_FILES === $this->sitepress->get_setting('theme_localization_type' );
398
+ }
399
+
400
+ if( $st_prior_2_6 || !isset($is_mo_loading_disabled) ){
401
+ $this->woocommerce_wpml->locale->switch_locale( $lang_code );
402
+ }else{
403
+ $this->sitepress->switch_lang( $lang_code );
404
+ }
405
+ }
406
 
407
  /**
408
  * get missing pages
inc/class-woocommerce-wpml.php CHANGED
@@ -159,6 +159,7 @@ class woocommerce_wpml {
159
  );
160
 
161
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
 
162
 
163
  if ( $this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
164
  || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && isset( $_GET['tab'] ) && $_GET['tab'] == 'multi-currency' )
@@ -206,8 +207,6 @@ class woocommerce_wpml {
206
  $this->url_translation->set_up();
207
  $this->endpoints = new WCML_Endpoints( $this );
208
  $this->requests = new WCML_Requests;
209
- $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
210
- $this->cart->add_hooks();
211
  $this->coupons = new WCML_Coupons( $this, $sitepress );
212
  $this->coupons->add_hooks();
213
  $this->locale = new WCML_Locale( $this, $sitepress );
159
  );
160
 
161
  $this->cart = new WCML_Cart( $this, $sitepress, $woocommerce );
162
+ $this->cart->add_hooks();
163
 
164
  if ( $this->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT
165
  || ( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && isset( $_GET['tab'] ) && $_GET['tab'] == 'multi-currency' )
207
  $this->url_translation->set_up();
208
  $this->endpoints = new WCML_Endpoints( $this );
209
  $this->requests = new WCML_Requests;
 
 
210
  $this->coupons = new WCML_Coupons( $this, $sitepress );
211
  $this->coupons->add_hooks();
212
  $this->locale = new WCML_Locale( $this, $sitepress );
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -200,7 +200,7 @@ class WCML_Multi_Currency_Prices {
200
  } else {
201
  // 2. automatic conversion
202
  $price = get_post_meta( $object_id, $meta_key, $single );
203
- if( $price ){
204
  $price = apply_filters( 'wcml_raw_price_amount', $price );
205
  }
206
  }
200
  } else {
201
  // 2. automatic conversion
202
  $price = get_post_meta( $object_id, $meta_key, $single );
203
+ if( is_numeric( $price ) ){
204
  $price = apply_filters( 'wcml_raw_price_amount', $price );
205
  }
206
  }
inc/translation-editor/class-wcml-page-builders.php CHANGED
@@ -1,107 +1,104 @@
1
  <?php
2
 
3
- class WCML_Page_Builders{
4
 
5
- /**
6
- * @var SitePress
7
- */
8
- private $sitepress;
9
 
10
- function __construct( &$sitepress )
11
- {
12
- $this->sitepress = $sitepress;
13
 
14
- }
15
 
16
- public function get_page_builders_string_packages( $product_id ){
17
- return apply_filters( 'wpml_st_get_post_string_packages', false, $product_id );
18
- }
19
 
20
- public function get_page_builders_strings( $product_id, $target_language ){
21
 
22
- $string_packages = $this->get_page_builders_string_packages( $product_id );
23
- $translation_package = array();
24
 
25
- if ( $string_packages ) {
26
 
27
- foreach ( $string_packages as $package_id => $string_package ) {
28
 
29
- $translation_package[ $package_id ] = array(
30
- 'title' => $string_package->title
31
- );
32
 
33
- $strings = $string_package->get_package_strings();
34
 
35
- $translated_strings = $string_package->get_translated_strings( array() );
36
 
37
- foreach ( $strings as $string ) {
38
 
39
- if( isset( $translated_strings[ $string->name ][ $target_language ] ) ){
40
- $string->translated_value = $translated_strings[ $string->name ][ $target_language ][ 'value' ];
41
- }
42
 
43
- $string->name = WPML_TM_Page_Builders_Field_Wrapper::generate_field_slug( $package_id, $string->id );
 
 
 
44
 
45
- $translation_package[ $package_id ][ 'strings' ][] = $string;
46
- }
47
- }
48
- }
49
 
50
- return $translation_package;
51
 
52
- }
53
 
54
- public function get_page_builders_strings_section( $data, $product_id, $target_language ){
 
55
 
56
- $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
57
- $strings_section = false;
58
 
59
- foreach ( $string_packages as $string_package ){
60
- $strings_section = new WPML_Editor_UI_Field_Section( $string_package[ 'title' ] );
 
 
 
61
 
62
- foreach ( $string_package[ 'strings' ] as $string ) {
63
- $field_label = apply_filters( 'wpml_string_title_from_id', false, $string->id );
64
- $strings_section->add_field( new WCML_Editor_UI_WYSIWYG_Field( $string->name, $field_label, $data, true ) );
65
- }
66
- }
67
 
68
- return $strings_section;
69
- }
70
 
71
- public function page_builders_data( $element_data, $product_id, $target_language ){
72
 
73
- $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
74
 
75
- foreach ( $string_packages as $string_package ){
 
 
 
 
 
 
76
 
77
- foreach ( $string_package[ 'strings' ] as $string ) {
78
- $element_data[ $string->name ] = array( 'original' => $string->value );
79
- if( isset( $string->translated_value ) ){
80
- $element_data[ $string->name ][ 'translation' ] = $string->translated_value;
81
- }
82
- }
83
- }
84
 
85
- return $element_data;
86
- }
87
 
88
- public function save_page_builders_strings( $translations, $product_id, $target_language ){
89
 
90
- $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
91
 
92
- foreach ( $string_packages as $string_package ){
93
 
94
- foreach ( $string_package[ 'strings' ] as $string ) {
 
 
 
 
 
 
95
 
96
- do_action(
97
- 'wpml_add_string_translation',
98
- $string->id,
99
- $target_language,
100
- $translations[ md5( $string->name ) ],
101
- $this->sitepress->get_wp_api()->constant( 'ICL_TM_COMPLETE' )
102
- );
103
-
104
- }
105
- }
106
- }
107
  }
1
  <?php
2
 
3
+ class WCML_Page_Builders {
4
 
5
+ /**
6
+ * @var SitePress
7
+ */
8
+ private $sitepress;
9
 
10
+ function __construct( &$sitepress ) {
11
+ $this->sitepress = $sitepress;
 
12
 
13
+ }
14
 
15
+ public function get_page_builders_string_packages( $product_id ) {
16
+ return apply_filters( 'wpml_st_get_post_string_packages', false, $product_id );
17
+ }
18
 
19
+ public function get_page_builders_strings( $product_id, $target_language ) {
20
 
21
+ $string_packages = $this->get_page_builders_string_packages( $product_id );
22
+ $translation_package = array();
23
 
24
+ if ( $string_packages ) {
25
 
26
+ foreach ( $string_packages as $package_id => $string_package ) {
27
 
28
+ $translation_package[ $package_id ] = array(
29
+ 'title' => $string_package->title
30
+ );
31
 
32
+ $strings = $string_package->get_package_strings();
33
 
34
+ $translated_strings = $string_package->get_translated_strings( array() );
35
 
36
+ foreach ( $strings as $string ) {
37
 
38
+ if ( isset( $translated_strings[ $string->name ][ $target_language ] ) ) {
39
+ $string->translated_value = $translated_strings[ $string->name ][ $target_language ]['value'];
40
+ }
41
 
42
+ $translation_package[ $package_id ]['strings'][] = $string;
43
+ }
44
+ }
45
+ }
46
 
47
+ return $translation_package;
 
 
 
48
 
49
+ }
50
 
51
+ public function get_page_builders_strings_section( $data, $product_id, $target_language ) {
52
 
53
+ $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
54
+ $strings_section = false;
55
 
56
+ foreach ( $string_packages as $string_package ) {
57
+ $strings_section = new WPML_Editor_UI_Field_Section( $string_package['title'] );
58
 
59
+ foreach ( $string_package['strings'] as $string ) {
60
+ $field_label = apply_filters( 'wpml_string_title_from_id', false, $string->id );
61
+ $strings_section->add_field( new WCML_Editor_UI_WYSIWYG_Field( $string->name, $field_label, $data, true ) );
62
+ }
63
+ }
64
 
65
+ return $strings_section;
66
+ }
 
 
 
67
 
68
+ public function page_builders_data( $element_data, $product_id, $target_language ) {
 
69
 
70
+ $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
71
 
72
+ foreach ( $string_packages as $string_package ) {
73
 
74
+ foreach ( $string_package['strings'] as $string ) {
75
+ $element_data[ $string->name ] = array( 'original' => $string->value );
76
+ if ( isset( $string->translated_value ) ) {
77
+ $element_data[ $string->name ]['translation'] = $string->translated_value;
78
+ }
79
+ }
80
+ }
81
 
82
+ return $element_data;
83
+ }
 
 
 
 
 
84
 
85
+ public function save_page_builders_strings( $translations, $product_id, $target_language ) {
 
86
 
87
+ $string_packages = $this->get_page_builders_strings( $product_id, $target_language );
88
 
89
+ foreach ( $string_packages as $string_package ) {
90
 
91
+ foreach ( $string_package['strings'] as $string ) {
92
 
93
+ do_action(
94
+ 'wpml_add_string_translation',
95
+ $string->id,
96
+ $target_language,
97
+ $translations[ md5( $string->name ) ],
98
+ $this->sitepress->get_wp_api()->constant( 'ICL_TM_COMPLETE' )
99
+ );
100
 
101
+ }
102
+ }
103
+ }
 
 
 
 
 
 
 
 
104
  }
inc/translation-editor/class-wcml-synchronize-product-data.php CHANGED
@@ -465,23 +465,26 @@ class WCML_Synchronize_Product_Data{
465
  public function duplicate_product_post_meta( $original_product_id, $trnsl_product_id, $data = false ){
466
  global $iclTranslationManagement;
467
 
468
- if( $this->check_if_product_fields_sync_needed( $original_product_id, $trnsl_product_id, 'postmeta_fields' ) ){
469
- $settings = $iclTranslationManagement->settings[ 'custom_fields_translation' ];
470
  $all_meta = get_post_custom( $original_product_id );
471
  $post_fields = null;
472
 
 
473
  unset( $all_meta[ '_thumbnail_id' ] );
474
 
475
  foreach ( $all_meta as $key => $meta ) {
476
- if ( !isset( $settings[ $key ] ) || $settings[ $key ] == WPML_IGNORE_CUSTOM_FIELD ) {
 
 
 
477
  continue;
478
  }
 
479
  foreach ( $meta as $meta_value ) {
480
  if( $key == '_downloadable_files' ){
481
  $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $trnsl_product_id, $data );
482
  }elseif ( $data ) {
483
- if ( isset( $settings[ $key ] ) && $settings[ $key ] == WPML_TRANSLATE_CUSTOM_FIELD ) {
484
-
485
  $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields, $original_product_id );
486
  }
487
  }
465
  public function duplicate_product_post_meta( $original_product_id, $trnsl_product_id, $data = false ){
466
  global $iclTranslationManagement;
467
 
468
+ if( $this->check_if_product_fields_sync_needed( $original_product_id, $trnsl_product_id, 'postmeta_fields' ) || $data ){
 
469
  $all_meta = get_post_custom( $original_product_id );
470
  $post_fields = null;
471
 
472
+ $settings_factory = new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement );
473
  unset( $all_meta[ '_thumbnail_id' ] );
474
 
475
  foreach ( $all_meta as $key => $meta ) {
476
+
477
+ $setting = $settings_factory->post_meta_setting( $key );
478
+
479
+ if ( WPML_IGNORE_CUSTOM_FIELD === $setting->status() ) {
480
  continue;
481
  }
482
+
483
  foreach ( $meta as $meta_value ) {
484
  if( $key == '_downloadable_files' ){
485
  $this->woocommerce_wpml->downloadable->sync_files_to_translations( $original_product_id, $trnsl_product_id, $data );
486
  }elseif ( $data ) {
487
+ if ( WPML_TRANSLATE_CUSTOM_FIELD === $setting->status() ) {
 
488
  $post_fields = $this->sync_custom_field_value( $key, $data, $trnsl_product_id, $post_fields, $original_product_id );
489
  }
490
  }
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.9
7
  Tested up to: 4.8.1
8
- Stable tag: 4.2.4
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -142,6 +142,23 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
142
 
143
  == Changelog ==
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  = 4.2.4 =
146
  * Allow translating categories used in shortcodes when the simple tax query is used
147
  * Switching language/currency reset cart feature redirect to random product page after reset cart
5
  License: GPLv2
6
  Requires at least: 3.9
7
  Tested up to: 4.8.1
8
+ Stable tag: 4.2.5
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
142
 
143
  == Changelog ==
144
 
145
+ = 4.2.5 =
146
+ * Cannot update Purchase note (any other custom field) once the job is completed
147
+ * New order admin emails have un-translated heading and subject when admin language is different of default
148
+ * Product in cart not adjusted to correct language when switching languages
149
+ * WooCommerce Subscriptions -> Product with free trial has no payment method
150
+ * Strings for subject and title are not translating for Refund emails
151
+ * Page builder strings does not translate in a product when WCML is enabled
152
+ * Fixed small glitch with no payment methods in free product with extra shipping cost
153
+ * Fix an issue that caused fatal error in WooCommerce Store Exporter plugin
154
+ * Fixed wrong output when using multiple categories in shortcodes
155
+ * Fixed compatibility issue in WC Membership with wrong product url
156
+ * Un-trashing product results of redirect to post listing in WCML
157
+ * Fix a bug that the price calculation is not correct in combination with WC Bookings and WC Deposit plugin
158
+ * MaxStore Pro theme compatibility for mini cart
159
+ * Product price was doubled on cart in combination with Booking and Product Addons
160
+ * Added 'wcml_hide_cart_alert_dialog' filter to support hide cart alert switching dialog
161
+
162
  = 4.2.4 =
163
  * Allow translating categories used in shortcodes when the simple tax query is used
164
  * Switching language/currency reset cart feature redirect to random product page after reset cart
res/css/admin.css CHANGED
@@ -1 +1,4 @@
1
- .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0}
 
 
 
1
+ .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0} .otgs-ico-ok:before {content: "\63";}
2
+
3
+
4
+
res/js/cart_widget.js CHANGED
@@ -2,7 +2,7 @@ jQuery(document).ready(function($){
2
  try {
3
  var cart_hash_key = wc_cart_fragments_params.ajax_url.toString() + '-wc_cart_hash';
4
 
5
- if (sessionStorage.getItem( 'woocommerce_cart_hash' ) == '' || actions.is_lang_switched == 1 || actions.is_currency_switched == 1 ) {
6
  sessionStorage.removeItem( actions.cart_fragment );
7
 
8
  //backward compatibility for WC < 3.0
2
  try {
3
  var cart_hash_key = wc_cart_fragments_params.ajax_url.toString() + '-wc_cart_hash';
4
 
5
+ if (sessionStorage.getItem( 'woocommerce_cart_hash' ) == '' || actions.is_lang_switched == 1 || actions.is_currency_switched == 1 || actions.force_reset == 1 ) {
6
  sessionStorage.removeItem( actions.cart_fragment );
7
 
8
  //backward compatibility for WC < 3.0
res/js/cart_widget.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function($){try{var cart_hash_key=wc_cart_fragments_params.ajax_url.toString()+"-wc_cart_hash";if(sessionStorage.getItem("woocommerce_cart_hash")==""||actions.is_lang_switched==1||actions.is_currency_switched==1){sessionStorage.removeItem(actions.cart_fragment);sessionStorage.removeItem("wc_fragments")}}catch(err){}});
1
+ jQuery(document).ready(function($){try{var cart_hash_key=wc_cart_fragments_params.ajax_url.toString()+"-wc_cart_hash";if(sessionStorage.getItem("woocommerce_cart_hash")==""||actions.is_lang_switched==1||actions.is_currency_switched==1||actions.force_reset==1){sessionStorage.removeItem(actions.cart_fragment);sessionStorage.removeItem("wc_fragments")}}catch(err){}});
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit55764b6d2d88b7d4a989a95374d49eb9::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit0f07622f9161d526755751a06b94b887::getLoader();
vendor/autoload_52.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
- return ComposerAutoloaderInit2cba9b05618d6fd29d7253c699fac21d::getLoader();
4
 
5
  require_once dirname(__FILE__) . '/composer'.'/autoload_real_52.php';
6
 
7
+ return ComposerAutoloaderInit7bcc7875eb86a79d191a7fd61af603ef::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -348,6 +348,7 @@ return array(
348
  'WCML_Languages_Upgrader' => $baseDir . '/inc/class-wcml-languages-upgrader.php',
349
  'WCML_Links' => $baseDir . '/inc/admin-menus/class-wcml-links.php',
350
  'WCML_Locale' => $baseDir . '/inc/class-wcml-locale.php',
 
351
  'WCML_Media' => $baseDir . '/inc/class-wcml-media.php',
352
  'WCML_Menus_Wrap' => $baseDir . '/inc/template-classes/class-wcml-menus-wrap.php',
353
  'WCML_Mix_and_Match_Products' => $baseDir . '/compatibility/class-wcml-mix-and-match-products.php',
348
  'WCML_Languages_Upgrader' => $baseDir . '/inc/class-wcml-languages-upgrader.php',
349
  'WCML_Links' => $baseDir . '/inc/admin-menus/class-wcml-links.php',
350
  'WCML_Locale' => $baseDir . '/inc/class-wcml-locale.php',
351
+ 'WCML_MaxStore' => $baseDir . '/compatibility/class-wcml-maxstore.php',
352
  'WCML_Media' => $baseDir . '/inc/class-wcml-media.php',
353
  'WCML_Menus_Wrap' => $baseDir . '/inc/template-classes/class-wcml-menus-wrap.php',
354
  'WCML_Mix_and_Match_Products' => $baseDir . '/compatibility/class-wcml-mix-and-match-products.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit55764b6d2d88b7d4a989a95374d49eb9
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit55764b6d2d88b7d4a989a95374d49eb9
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit55764b6d2d88b7d4a989a95374d49eb9', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit55764b6d2d88b7d4a989a95374d49eb9', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit0f07622f9161d526755751a06b94b887
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit0f07622f9161d526755751a06b94b887', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit0f07622f9161d526755751a06b94b887', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit0f07622f9161d526755751a06b94b887::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
vendor/composer/autoload_real_52.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
- class ComposerAutoloaderInit2cba9b05618d6fd29d7253c699fac21d {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
@@ -19,9 +19,9 @@ class ComposerAutoloaderInit2cba9b05618d6fd29d7253c699fac21d {
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit2cba9b05618d6fd29d7253c699fac21d', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit2cba9b05618d6fd29d7253c699fac21d', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
2
 
3
  // autoload_real_52.php generated by xrstf/composer-php52
4
 
5
+ class ComposerAutoloaderInit7bcc7875eb86a79d191a7fd61af603ef {
6
  private static $loader;
7
 
8
  public static function loadClassLoader($class) {
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInit7bcc7875eb86a79d191a7fd61af603ef', 'loadClassLoader'), true /*, true */);
23
  self::$loader = $loader = new xrstf_Composer52_ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit7bcc7875eb86a79d191a7fd61af603ef', 'loadClassLoader'));
25
 
26
  $vendorDir = dirname(dirname(__FILE__));
27
  $baseDir = dirname($vendorDir);
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'C' =>
@@ -380,6 +380,7 @@ class ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9
380
  'WCML_Languages_Upgrader' => __DIR__ . '/../..' . '/inc/class-wcml-languages-upgrader.php',
381
  'WCML_Links' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-links.php',
382
  'WCML_Locale' => __DIR__ . '/../..' . '/inc/class-wcml-locale.php',
 
383
  'WCML_Media' => __DIR__ . '/../..' . '/inc/class-wcml-media.php',
384
  'WCML_Menus_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-menus-wrap.php',
385
  'WCML_Mix_and_Match_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-mix-and-match-products.php',
@@ -480,10 +481,10 @@ class ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9
480
  public static function getInitializer(ClassLoader $loader)
481
  {
482
  return \Closure::bind(function () use ($loader) {
483
- $loader->prefixLengthsPsr4 = ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9::$prefixLengthsPsr4;
484
- $loader->prefixDirsPsr4 = ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9::$prefixDirsPsr4;
485
- $loader->prefixesPsr0 = ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9::$prefixesPsr0;
486
- $loader->classMap = ComposerStaticInit55764b6d2d88b7d4a989a95374d49eb9::$classMap;
487
 
488
  }, null, ClassLoader::class);
489
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit0f07622f9161d526755751a06b94b887
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
  'C' =>
380
  'WCML_Languages_Upgrader' => __DIR__ . '/../..' . '/inc/class-wcml-languages-upgrader.php',
381
  'WCML_Links' => __DIR__ . '/../..' . '/inc/admin-menus/class-wcml-links.php',
382
  'WCML_Locale' => __DIR__ . '/../..' . '/inc/class-wcml-locale.php',
383
+ 'WCML_MaxStore' => __DIR__ . '/../..' . '/compatibility/class-wcml-maxstore.php',
384
  'WCML_Media' => __DIR__ . '/../..' . '/inc/class-wcml-media.php',
385
  'WCML_Menus_Wrap' => __DIR__ . '/../..' . '/inc/template-classes/class-wcml-menus-wrap.php',
386
  'WCML_Mix_and_Match_Products' => __DIR__ . '/../..' . '/compatibility/class-wcml-mix-and-match-products.php',
481
  public static function getInitializer(ClassLoader $loader)
482
  {
483
  return \Closure::bind(function () use ($loader) {
484
+ $loader->prefixLengthsPsr4 = ComposerStaticInit0f07622f9161d526755751a06b94b887::$prefixLengthsPsr4;
485
+ $loader->prefixDirsPsr4 = ComposerStaticInit0f07622f9161d526755751a06b94b887::$prefixDirsPsr4;
486
+ $loader->prefixesPsr0 = ComposerStaticInit0f07622f9161d526755751a06b94b887::$prefixesPsr0;
487
+ $loader->classMap = ComposerStaticInit0f07622f9161d526755751a06b94b887::$classMap;
488
 
489
  }, null, ClassLoader::class);
490
  }
wpml-woocommerce.php CHANGED
@@ -8,14 +8,16 @@
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
  Tested up to: 4.8.1
11
- Version: 4.2.4
 
 
12
  */
13
 
14
  if ( defined( 'WCML_VERSION' ) ) {
15
  return;
16
  }
17
 
18
- define( 'WCML_VERSION', '4.2.4' );
19
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
20
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
21
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
8
  Text Domain: woocommerce-multilingual
9
  Requires at least: 3.9
10
  Tested up to: 4.8.1
11
+ Version: 4.2.5
12
+ WC requires at least: 2.1.0
13
+ WC tested up to: 3.2.1
14
  */
15
 
16
  if ( defined( 'WCML_VERSION' ) ) {
17
  return;
18
  }
19
 
20
+ define( 'WCML_VERSION', '4.2.5' );
21
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
22
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
23
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );