WooCommerce Multilingual – run WooCommerce with WPML - Version 3.7.3

Version Description

  • Added support for translating custom attributes (for variations) via the professional translation
  • Added support for translating products tab information (WooCommerce Tab Manager) via the professional translation
  • Added support for translating persons and resources (WooCommerce Bookings) via the professional translation
  • Added support for translating products bundle data (WooCommerce Product Bundles) via the professional translation
  • Added extended compatibility and support for professional translation for WooCommerce Composite Products
  • Bug fix: it was not possible to set a product translation as draft when the original was published
  • Bug fix: in some cases the product categories hierarchy (and count) was not sycned across translations
  • Bug fix: the custom title and description of a bundle of a translated product was removed after updating the original product
  • Bug fix: custom fields that did not have any translation preference were wrongfully copied across translations
  • Bug fix: multi-currency was not working properly for product variations when the "Show only products with custom prices in secondary currencies" option was on
  • Fixed an important compatibility issue with Yoast SEO (fatal error when using Yoast SEO 3.0+)
  • Bug fix: wcml_check_on_duplicate_products_in_cart was incorrectly duplicated specific items in the cart
Download this release

Release Info

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

Code changes from version 3.7.2 to 3.7.3

Files changed (32) hide show
  1. assets/css/management.css +7 -1
  2. compatibility/{wc_ajax_layered_nav_widget.class.php → class-wcml-ajax-layered-nav-widget.php} +0 -0
  3. compatibility/{wc_bookings.class.php → class-wcml-bookings.php} +219 -23
  4. compatibility/{wc_bulk_stock_management.class.php → class-wcml-bulk-stock-management.php} +0 -0
  5. compatibility/{wc_checkout_addons.class.php → class-wcml-checkout-addons.php} +0 -0
  6. compatibility/{wc_checkout_field_editor.class.php → class-wcml-checkout-field-editor.php} +0 -0
  7. compatibility/class-wcml-compatibility-helper.php +19 -0
  8. compatibility/class-wcml-composite-products.php +314 -0
  9. compatibility/{wc_dynamic_pricing.class.php → class-wcml-dynamic-pricing.php} +81 -81
  10. compatibility/{wc_extra_product_options.class.php → class-wcml-extra-product-options.php} +122 -122
  11. compatibility/{gravityforms.class.php → class-wcml-gravityforms.php} +0 -9
  12. compatibility/{wc_per_product_shipping.class.php → class-wcml-per-product-shipping.php} +30 -30
  13. compatibility/{wc_product_addons.class.php → class-wcml-product-addons.php} +76 -83
  14. compatibility/{wc_product_bundles.class.php → class-wcml-product-bundles.php} +132 -11
  15. compatibility/{wc_sensei.class.php → class-wcml-sensei.php} +231 -231
  16. compatibility/class-wcml-tab-manager.php +485 -0
  17. compatibility/{wc_table_rate_shipping.class.php → class-wcml-table-rate-shipping.php} +24 -24
  18. compatibility/{wc_variation_swatches_photos.class.php → class-wcml-variation-swatches-and-photos.php} +0 -0
  19. compatibility/{wc_subscriptions.class.php → class-wcml-wc-subscriptions.php} +36 -36
  20. compatibility/{wc_exporter.class.php → class-wcml-wcexporter.php} +70 -70
  21. compatibility/templates/wc_tab_manager_custom_box_html.php +2 -2
  22. compatibility/templates/woocommerce-composite-products.php +35 -0
  23. compatibility/wc_composite_products.class.php +0 -51
  24. compatibility/wc_tab_manager.class.php +0 -279
  25. inc/class-wcml-tp-support.php +177 -0
  26. inc/compatibility.class.php +18 -17
  27. inc/multi-currency-support.class.php +38 -4
  28. inc/products.class.php +233 -202
  29. inc/upgrade.class.php +27 -1
  30. menu/management.php +1 -1
  31. readme.txt +16 -2
  32. wpml-woocommerce.php +3 -2
assets/css/management.css CHANGED
@@ -972,6 +972,12 @@ input[name="wcml_curr_template"]{
972
  width: 100%;
973
  }
974
  .edit_slug_input,
975
- .edit_slug_hide_link{
976
  display: none;
 
 
 
 
 
 
977
  }
972
  width: 100%;
973
  }
974
  .edit_slug_input,
975
+ .edit_slug_hide_link {
976
  display: none;
977
+ }
978
+
979
+ .wcml-wrap .nav-tab{
980
+ float: none;
981
+ font-size: 12px;
982
+ line-height: 26px;
983
  }
compatibility/{wc_ajax_layered_nav_widget.class.php → class-wcml-ajax-layered-nav-widget.php} RENAMED
File without changes
compatibility/{wc_bookings.class.php → class-wcml-bookings.php} RENAMED
@@ -2,6 +2,8 @@
2
 
3
  class WCML_Bookings{
4
 
 
 
5
  function __construct(){
6
 
7
  add_action( 'woocommerce_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
@@ -57,11 +59,21 @@ class WCML_Bookings{
57
  }
58
 
59
  add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
60
- add_filter('wcml_exception_duplicate_products_in_cart', array($this, 'check_on_bookable_product_in_cart'), 10, 2 );
61
  add_filter('woocommerce_bookings_in_date_range_query', array($this, 'bookings_in_date_range_query'));
62
  add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
63
  add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
64
 
 
 
 
 
 
 
 
 
 
 
 
65
  $this->clear_transient_fields();
66
 
67
  }
@@ -120,7 +132,6 @@ class WCML_Bookings{
120
 
121
  }
122
 
123
-
124
  function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
125
  global $woocommerce_wpml;
126
 
@@ -257,15 +268,15 @@ class WCML_Bookings{
257
 
258
  echo '<div class="wcml_custom_costs">';
259
 
260
- echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
261
- echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
262
 
263
- $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
264
 
265
- echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
266
- echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
267
 
268
- wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
269
 
270
  echo '</div>';
271
  }
@@ -464,7 +475,6 @@ class WCML_Bookings{
464
 
465
  }
466
 
467
-
468
  function duplicate_resource( $tr_product_id, $resource, $lang_code){
469
  global $sitepress, $wpdb, $iclTranslationManagement;
470
 
@@ -557,7 +567,6 @@ class WCML_Bookings{
557
 
558
  }
559
 
560
-
561
  function duplicate_person( $tr_product_id, $person_id, $lang_code ){
562
  global $sitepress, $wpdb, $iclTranslationManagement;
563
 
@@ -889,7 +898,6 @@ class WCML_Bookings{
889
 
890
  }
891
 
892
-
893
  function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ){
894
  return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
895
  }
@@ -957,7 +965,6 @@ class WCML_Bookings{
957
 
958
  }
959
 
960
-
961
  function wcml_multi_currency_is_ajax( $actions ){
962
 
963
  $actions[] = 'wc_bookings_calculate_costs';
@@ -1564,7 +1571,6 @@ class WCML_Bookings{
1564
  return $translated_bookings;
1565
  }
1566
 
1567
-
1568
  public function booking_filters_query( $query ) {
1569
  global $typenow, $sitepress, $wpdb;
1570
 
@@ -1585,16 +1591,6 @@ class WCML_Bookings{
1585
  }
1586
  }
1587
 
1588
- function check_on_bookable_product_in_cart( $flag, $cart_item ){
1589
-
1590
- if( $cart_item[ 'data' ] instanceof WC_Product_Booking ) {
1591
- return true;
1592
- }
1593
-
1594
- return false;
1595
-
1596
- }
1597
-
1598
  function bookings_in_date_range_query($booking_ids){
1599
  global $sitepress;
1600
 
@@ -1684,4 +1680,204 @@ class WCML_Bookings{
1684
 
1685
  }
1686
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1687
  }
2
 
3
  class WCML_Bookings{
4
 
5
+ public $tp;
6
+
7
  function __construct(){
8
 
9
  add_action( 'woocommerce_bookings_after_booking_base_cost' , array( $this, 'wcml_price_field_after_booking_base_cost' ) );
59
  }
60
 
61
  add_filter( 'parse_query', array( $this, 'booking_filters_query' ) );
 
62
  add_filter('woocommerce_bookings_in_date_range_query', array($this, 'bookings_in_date_range_query'));
63
  add_action( 'before_delete_post', array( $this, 'delete_bookings' ) );
64
  add_action( 'wp_trash_post', array( $this, 'trash_bookings' ) );
65
 
66
+ if( is_admin() ){
67
+
68
+ $this->tp = new WPML_Element_Translation_Package;
69
+
70
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_persons_to_translation_package' ), 10, 2 );
71
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_person_translation' ), 10, 3 );
72
+
73
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_resources_to_translation_package' ), 10, 2 );
74
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_resource_translation' ), 10, 3 );
75
+ }
76
+
77
  $this->clear_transient_fields();
78
 
79
  }
132
 
133
  }
134
 
 
135
  function echo_wcml_price_field( $post_id, $field, $pricing = false, $check = true, $resource_id = false ){
136
  global $woocommerce_wpml;
137
 
268
 
269
  echo '<div class="wcml_custom_costs">';
270
 
271
+ echo '<input type="radio" name="_wcml_custom_costs" id="wcml_custom_costs_auto" value="0" class="wcml_custom_costs_input" '. $checked .' />';
272
+ echo '<label for="wcml_custom_costs_auto">'. __('Calculate costs in other currencies automatically', 'woocommerce-multilingual') .'</label>';
273
 
274
+ $checked = $custom_costs_status == 1 ? 'checked="checked"' : ' ';
275
 
276
+ echo '<input type="radio" name="_wcml_custom_costs" value="1" id="wcml_custom_costs_manually" class="wcml_custom_costs_input" '. $checked .' />';
277
+ echo '<label for="wcml_custom_costs_manually">'. __('Set costs in other currencies manually', 'woocommerce-multilingual') .'</label>';
278
 
279
+ wp_nonce_field( 'wcml_save_custom_costs', '_wcml_custom_costs_nonce' );
280
 
281
  echo '</div>';
282
  }
475
 
476
  }
477
 
 
478
  function duplicate_resource( $tr_product_id, $resource, $lang_code){
479
  global $sitepress, $wpdb, $iclTranslationManagement;
480
 
567
 
568
  }
569
 
 
570
  function duplicate_person( $tr_product_id, $person_id, $lang_code ){
571
  global $sitepress, $wpdb, $iclTranslationManagement;
572
 
898
 
899
  }
900
 
 
901
  function wc_bookings_process_cost_rules_cost( $cost, $fields, $key ){
902
  return $this->filter_pricing_cost( $cost, $fields, 'cost_', $key );
903
  }
965
 
966
  }
967
 
 
968
  function wcml_multi_currency_is_ajax( $actions ){
969
 
970
  $actions[] = 'wc_bookings_calculate_costs';
1571
  return $translated_bookings;
1572
  }
1573
 
 
1574
  public function booking_filters_query( $query ) {
1575
  global $typenow, $sitepress, $wpdb;
1576
 
1591
  }
1592
  }
1593
 
 
 
 
 
 
 
 
 
 
 
1594
  function bookings_in_date_range_query($booking_ids){
1595
  global $sitepress;
1596
 
1680
 
1681
  }
1682
 
1683
+ function append_persons_to_translation_package( $package, $post ){
1684
+
1685
+ if( $post->post_type == 'product' ){
1686
+ $product = wc_get_product( $post->ID );
1687
+
1688
+ if( $product->get_type() == 'booking' ){
1689
+
1690
+ $bookable_product = new WC_Product_Booking( $post->ID );
1691
+
1692
+ $person_types = $bookable_product->get_person_types();
1693
+
1694
+ foreach( $person_types as $person_type ) {
1695
+
1696
+ $package['contents']['wc_bookings:person:' . $person_type->ID . ':name'] = array(
1697
+ 'translate' => 1,
1698
+ 'data' => $this->tp->encode_field_data( $person_type->post_title, 'base64' ),
1699
+ 'format' => 'base64'
1700
+ );
1701
+
1702
+ $package['contents']['wc_bookings:person:' . $person_type->ID . ':description'] = array(
1703
+ 'translate' => 1,
1704
+ 'data' => $this->tp->encode_field_data( $person_type->post_excerpt, 'base64' ),
1705
+ 'format' => 'base64'
1706
+ );
1707
+
1708
+ }
1709
+
1710
+ }
1711
+
1712
+ }
1713
+
1714
+ return $package;
1715
+
1716
+ }
1717
+
1718
+ function save_person_translation($post_id, $data, $job ){
1719
+ global $sitepress;
1720
+
1721
+ $person_translations = array();
1722
+
1723
+ foreach($data as $value){
1724
+
1725
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:person:' ) === 0 ) {
1726
+
1727
+ $exp = explode( ':', $value['field_type'] );
1728
+
1729
+ $person_id = $exp[2];
1730
+ $field = $exp[3];
1731
+
1732
+ $person_translations[$person_id][$field] = $value['data'];
1733
+
1734
+ }
1735
+
1736
+ }
1737
+
1738
+ if( $person_translations ){
1739
+
1740
+ foreach( $person_translations as $person_id => $pt ){
1741
+
1742
+ $person_trid = $sitepress->get_element_trid( $person_id, 'post_bookable_person');
1743
+
1744
+
1745
+ $person_id_translated = apply_filters( 'translate_object_id', $person_id, 'bookable_person', false, $job->language_code );
1746
+
1747
+ if( empty($person_id_translated) ) {
1748
+
1749
+ $person_post = array(
1750
+
1751
+ 'post_type' => 'bookable_person',
1752
+ 'post_status' => 'publish',
1753
+ 'post_title' => $pt['name'],
1754
+ 'post_parent' => $post_id,
1755
+ 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1756
+
1757
+ );
1758
+
1759
+ $person_id_translated = wp_insert_post( $person_post );
1760
+
1761
+ $sitepress->set_element_language_details( $person_id_translated, 'post_bookable_person', $person_trid, $job->language_code );
1762
+
1763
+ } else {
1764
+
1765
+ $person_post = array(
1766
+ 'ID' => $person_id_translated,
1767
+ 'post_title' => $pt['name'],
1768
+ 'post_excerpt' => isset($pt['description']) ? $pt['description'] : ''
1769
+ );
1770
+
1771
+ wp_update_post( $person_post );
1772
+
1773
+ }
1774
+
1775
+ }
1776
+
1777
+ }
1778
+
1779
+ }
1780
+
1781
+ function append_resources_to_translation_package( $package, $post ){
1782
+
1783
+ if( $post->post_type == 'product' ){
1784
+ $product = wc_get_product( $post->ID );
1785
+
1786
+ if( $product->get_type() == 'booking' && $product->has_resources() ){
1787
+
1788
+
1789
+
1790
+ $resources = $product->get_resources();
1791
+
1792
+
1793
+ foreach( $resources as $resource ) {
1794
+
1795
+ $package['contents']['wc_bookings:resource:' . $resource->ID . ':name'] = array(
1796
+ 'translate' => 1,
1797
+ 'data' => $this->tp->encode_field_data( $resource->post_title, 'base64' ),
1798
+ 'format' => 'base64'
1799
+ );
1800
+
1801
+ }
1802
+
1803
+ }
1804
+
1805
+ }
1806
+
1807
+ return $package;
1808
+
1809
+ }
1810
+
1811
+ function save_resource_translation( $post_id, $data, $job ){
1812
+ global $sitepress, $wpdb;
1813
+
1814
+ $resource_translations = array();
1815
+
1816
+ foreach($data as $value){
1817
+
1818
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_bookings:resource:' ) === 0 ) {
1819
+
1820
+ $exp = explode( ':', $value['field_type'] );
1821
+
1822
+ $resource_id = $exp[2];
1823
+ $field = $exp[3];
1824
+
1825
+ $resource_translations[$resource_id][$field] = $value['data'];
1826
+
1827
+ }
1828
+
1829
+ }
1830
+
1831
+ if( $resource_translations ){
1832
+
1833
+ foreach( $resource_translations as $resource_id => $rt ){
1834
+
1835
+ $resource_trid = $sitepress->get_element_trid( $resource_id, 'post_bookable_person');
1836
+
1837
+ $resource_id_translated = apply_filters( 'translate_object_id', $resource_id, 'bookable_resource', false, $job->language_code );
1838
+
1839
+ if( empty($resource_id_translated) ) {
1840
+
1841
+ $resource_post = array(
1842
+
1843
+ 'post_type' => 'bookable_resource',
1844
+ 'post_status' => 'publish',
1845
+ 'post_title' => $rt['name'],
1846
+ 'post_parent' => $post_id
1847
+ );
1848
+
1849
+ $resource_id_translated = wp_insert_post( $resource_post );
1850
+
1851
+ $sitepress->set_element_language_details( $resource_id_translated, 'post_bookable_person', $resource_trid, $job->language_code );
1852
+
1853
+ $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1854
+ $relationship = array(
1855
+ 'product_id' => $post_id,
1856
+ 'resource_id' => $resource_id_translated,
1857
+ 'sort_order' => $sort_order
1858
+ );
1859
+ $wpdb->insert( $wpdb->prefix . 'wc_booking_relationships', $relationship);
1860
+
1861
+ } else {
1862
+
1863
+ $resource_post = array(
1864
+ 'ID' => $resource_id_translated,
1865
+ 'post_title' => $rt['name']
1866
+ );
1867
+
1868
+ wp_update_post( $resource_post );
1869
+
1870
+ $sort_order = $wpdb->get_var( $wpdb->prepare( "SELECT sort_order FROM {$wpdb->prefix}wc_booking_relationships WHERE resource_id=%d", $resource_id ) );
1871
+ $wpdb->update( $wpdb->prefix . 'wc_booking_relationships', array( 'sort_order' => $sort_order ),
1872
+ array ( 'product_id' => $post_id, 'resource_id' => $resource_id_translated) );
1873
+
1874
+
1875
+ }
1876
+
1877
+
1878
+ }
1879
+
1880
+ }
1881
+
1882
+ }
1883
  }
compatibility/{wc_bulk_stock_management.class.php → class-wcml-bulk-stock-management.php} RENAMED
File without changes
compatibility/{wc_checkout_addons.class.php → class-wcml-checkout-addons.php} RENAMED
File without changes
compatibility/{wc_checkout_field_editor.class.php → class-wcml-checkout-field-editor.php} RENAMED
File without changes
compatibility/class-wcml-compatibility-helper.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Compatibility_Helper{
4
+
5
+ function get_product_type($product_id){
6
+
7
+ if ( $terms = wp_get_object_terms( $product_id, 'product_type' ) ) {
8
+ $product_type = sanitize_title( current( $terms )->name );
9
+ } else {
10
+ $product_type = apply_filters( 'default_product_type', 'simple' );
11
+ }
12
+
13
+ return $product_type;
14
+
15
+ }
16
+
17
+ }
18
+
19
+ ?>
compatibility/class-wcml-composite-products.php ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class WCML_Composite_Products extends WCML_Compatibility_Helper{
5
+
6
+ private $tp;
7
+
8
+ function __construct() {
9
+ add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
10
+ add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
11
+ add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
12
+
13
+ if( is_admin() ){
14
+ add_action( 'save_post', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
15
+
16
+ add_filter( 'wcml_gui_additional_box', array( $this, 'custom_box_html'), 10, 3 );
17
+ add_action('wcml_extra_titles',array($this,'product_editor_title'),10,1);
18
+ add_action('wcml_update_extra_fields',array($this,'components_update'),10,2);
19
+
20
+ $this->tp = new WPML_Element_Translation_Package();
21
+
22
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_composite_data_translation_package' ), 10, 2 );
23
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
24
+
25
+ }
26
+ }
27
+
28
+ function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
29
+
30
+ if( !empty( $selected_value ) )
31
+ $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
32
+
33
+
34
+ return $selected_value;
35
+ }
36
+
37
+ function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
38
+
39
+ if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
40
+
41
+ $buff = $new_cart_data[ $new_key ];
42
+
43
+ unset( $new_cart_data[ $new_key ] );
44
+
45
+ $new_cart_data[ $key ] = $buff;
46
+ }
47
+
48
+ return $new_cart_data;
49
+ }
50
+
51
+ function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
52
+
53
+ $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
54
+
55
+ return $args;
56
+ }
57
+
58
+ function sync_composite_data_across_translations( $product_id, $post = null ){
59
+ global $sitepress, $woocommerce_wpml;
60
+
61
+ if( is_null( $post ) ){
62
+ $post = get_post( $product_id );
63
+ }
64
+
65
+ // skip auto-drafts // skip autosave
66
+ if ( $post->post_status == 'auto-draft' || isset( $_POST[ 'autosave' ] ) ) {
67
+ return;
68
+ }
69
+
70
+ if( $post->post_type == 'product' ) {
71
+
72
+ if( $this->get_product_type( $product_id ) == 'composite' ) {
73
+
74
+ if ( $woocommerce_wpml->products->is_original_product( $product_id ) ) {
75
+
76
+ $original_product_id = $product_id;
77
+
78
+ } else {
79
+
80
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $product_id );
81
+ $original_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $original_product_language );
82
+
83
+ }
84
+
85
+ $product = new WC_Product_Composite( $original_product_id );
86
+
87
+ $product_trid = $sitepress->get_element_trid( $original_product_id, 'post_product' );
88
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
89
+
90
+ $composite_data = $product->get_composite_data();
91
+
92
+ foreach ( $product_translations as $product_translation ) {
93
+
94
+ if ( empty($product_translation->original) ) {
95
+
96
+ $translated_product = new WC_Product_Composite( $product_translation->element_id );
97
+ $translated_composite_data = $translated_product->get_composite_data();
98
+
99
+ foreach ( $composite_data as $component_id => $component ) {
100
+
101
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
102
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
103
+ }
104
+
105
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
106
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
107
+ }
108
+
109
+ if ( $component['query_type'] == 'product_ids' ) {
110
+
111
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
112
+ $composite_data[$component_id]['assigned_ids'][$idx] =
113
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $product_translation->language_code );
114
+ }
115
+
116
+ } elseif( $component['query_type'] == 'category_ids' ){
117
+
118
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
119
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
120
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $product_translation->language_code );
121
+
122
+ }
123
+
124
+ }
125
+
126
+ }
127
+
128
+ update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
129
+
130
+ }
131
+
132
+ }
133
+
134
+ }
135
+
136
+ }
137
+
138
+ }
139
+
140
+ function custom_box_html($product_id,$lang, $is_duplicate_product = false){
141
+ global $woocommerce_wpml, $sitepress;
142
+
143
+ $original_product_language = $woocommerce_wpml->products->get_original_product_language( $product_id );
144
+
145
+ if( $this->get_product_type( $product_id ) == 'composite' ){
146
+
147
+ $product = new WC_Product_Composite( $product_id );
148
+ $composite_data = $product->get_composite_data();
149
+
150
+ if( $original_product_language != $lang ){
151
+ $product_trid = $sitepress->get_element_trid( $product_id, 'post_product' );
152
+ $product_translations = $sitepress->get_element_translations( $product_trid, 'post_product' );
153
+ if( isset($product_translations[$lang]) ){
154
+ $translated_product = new WC_Product_Composite( $product_translations[$lang]->element_id );
155
+ $translated_composite_data = $translated_product->get_composite_data();
156
+ }
157
+
158
+ foreach( $composite_data as $component_id => $component ){
159
+
160
+ $template_data['wc_composite_components']['components'][$component_id]['title'] =
161
+ isset( $translated_composite_data[$component_id]['title'] ) ? $translated_composite_data[$component_id]['title'] : '';
162
+
163
+ $template_data['wc_composite_components']['components'][$component_id]['description'] =
164
+ isset( $translated_composite_data[$component_id]['description'] ) ? $translated_composite_data[$component_id]['description'] : '';
165
+
166
+ }
167
+
168
+ }else{
169
+
170
+ foreach( $composite_data as $component_id => $component ) {
171
+
172
+ $template_data['wc_composite_components']['components'][$component_id]['title'] =
173
+ isset( $composite_data[$component_id]['title'] ) ? $composite_data[$component_id]['title'] : '';
174
+
175
+ $template_data['wc_composite_components']['components'][$component_id]['description'] =
176
+ isset( $composite_data[$component_id]['description'] ) ? $composite_data[$component_id]['description'] : '';
177
+
178
+ }
179
+
180
+ }
181
+
182
+ $template_data['wc_composite_components']['_is_original'] = $original_product_language == $lang;
183
+
184
+ include WCML_PLUGIN_PATH . '/compatibility/templates/woocommerce-composite-products.php';
185
+ }
186
+
187
+ }
188
+
189
+ function product_editor_title( $product_id ){
190
+
191
+ if( $this->get_product_type( $product_id ) == 'composite' ) {
192
+ printf( '<th scope="col">%s</h>', __( 'Components', 'woocommerce-multilingual' ) );
193
+ }
194
+
195
+ }
196
+
197
+ function components_update( $product_id, $data ){
198
+
199
+ $this->sync_composite_data_across_translations( $product_id );
200
+
201
+ $product = new WC_Product_Composite( $product_id );
202
+
203
+ $composite_data = $product->get_composite_data();
204
+
205
+ if(!empty($data['wc_composite_component'])){
206
+ foreach($data['wc_composite_component'] as $component_id => $component){
207
+
208
+ if(!empty($component['title'])){
209
+ $composite_data[$component_id]['title'] = $component['title'];
210
+ }
211
+
212
+ if(!empty($component['description'])) {
213
+ $composite_data[$component_id]['description'] = $component['description'];
214
+ }
215
+
216
+
217
+ }
218
+
219
+ update_post_meta( $product_id, '_bto_data', $composite_data );
220
+
221
+ }
222
+ }
223
+
224
+ function append_composite_data_translation_package( $package, $post ){
225
+
226
+ if( $post->post_type == 'product' ) {
227
+
228
+ $composite_data = get_post_meta( $post->ID, '_bto_data', true );
229
+
230
+ if( $composite_data ){
231
+
232
+ $fields = array( 'title', 'description' );
233
+
234
+ foreach( $composite_data as $component_id => $component ){
235
+
236
+ foreach( $fields as $field ) {
237
+ if ( !empty($component[$field]) ) {
238
+
239
+ $package['contents']['wc_composite:' . $component_id . ':' . $field] = array(
240
+ 'translate' => 1,
241
+ 'data' => $this->tp->encode_field_data( $component[$field], 'base64' ),
242
+ 'format' => 'base64'
243
+ );
244
+
245
+ }
246
+ }
247
+
248
+ }
249
+
250
+ }
251
+
252
+ }
253
+
254
+ return $package;
255
+
256
+ }
257
+
258
+ function save_composite_data_translation( $post_id, $data, $job ){
259
+
260
+
261
+ $translated_composite_data = array();
262
+ foreach( $data as $value){
263
+
264
+ if( preg_match( '/wc_composite:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
265
+
266
+ $component_id = $matches[1];
267
+ $field = $matches[2];
268
+
269
+ $translated_composite_data[$component_id][$field] = $value['data'];
270
+
271
+ }
272
+
273
+ }
274
+
275
+ if( $translated_composite_data ){
276
+
277
+ $composite_data = get_post_meta( $job->original_doc_id, '_bto_data', true );
278
+
279
+
280
+ foreach ( $composite_data as $component_id => $component ) {
281
+
282
+ if( isset( $translated_composite_data[$component_id]['title'] ) ){
283
+ $composite_data[$component_id]['title'] = $translated_composite_data[$component_id]['title'];
284
+ }
285
+
286
+ if( isset( $translated_composite_data[$component_id]['description'] ) ){
287
+ $composite_data[$component_id]['description'] = $translated_composite_data[$component_id]['description'];
288
+ }
289
+
290
+ if ( $component['query_type'] == 'product_ids' ) {
291
+
292
+ foreach ( $component['assigned_ids'] as $idx => $assigned_id ) {
293
+ $composite_data[$component_id]['assigned_ids'][$idx] =
294
+ apply_filters( 'translate_object_id', $assigned_id, 'product', true, $job->language_code );
295
+ }
296
+
297
+ } elseif( $component['query_type'] == 'category_ids' ){
298
+
299
+ foreach ( $component['assigned_category_ids'] as $idx => $assigned_id ) {
300
+ $composite_data[$component_id]['assigned_category_ids'][$idx] =
301
+ apply_filters( 'translate_object_id', $assigned_id, 'product_cat', true, $job->language_code );
302
+
303
+ }
304
+
305
+ }
306
+
307
+ }
308
+
309
+ }
310
+
311
+ update_post_meta( $post_id, '_bto_data', $composite_data );
312
+
313
+ }
314
+ }
compatibility/{wc_dynamic_pricing.class.php → class-wcml-dynamic-pricing.php} RENAMED
@@ -1,81 +1,81 @@
1
- <?php
2
-
3
- class WCML_Dynamic_Pricing{
4
-
5
- function __construct(){
6
- if(!is_admin()){
7
- add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
- add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
- add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
- add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
- add_filter('translate_cart_subtotal_exception',array($this,'translate_cart_subtotal_exception'),10,2);
12
-
13
- }
14
- }
15
-
16
- function filter_price($modules){
17
-
18
- foreach($modules as $mod_key=>$module){
19
- if(isset($module->available_rulesets)){
20
- $available_rulesets = $module->available_rulesets;
21
- foreach($available_rulesets as $rule_key=>$available_ruleset){
22
- $rules = $available_ruleset['rules'];
23
-
24
- if($rules){
25
- foreach($rules as $r_key=>$rule){
26
- if($rule['type'] == 'fixed_product'){
27
- $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
- }
29
- }
30
- $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
31
-
32
- }
33
- }
34
-
35
- }
36
- }
37
-
38
- return $modules;
39
- }
40
-
41
-
42
- function woocommerce_dynamic_pricing_is_applied_to($process_discounts, $_product, $module_id, $obj,$cat_id){
43
- if($cat_id && isset($obj->available_rulesets) && count($obj->available_rulesets) > 0){
44
- global $sitepress;
45
- $cat_id = apply_filters( 'translate_object_id',$cat_id,'product_cat',true,$sitepress->get_current_language());
46
- $process_discounts = is_object_in_term($_product->id, 'product_cat', $cat_id);
47
- }
48
-
49
- return $process_discounts;
50
- }
51
-
52
-
53
- function woocommerce_dynamic_pricing_get_rule_amount($amount, $rule, $cart_item, $obj){
54
-
55
- if($rule['type'] == 'price_discount' || $rule['type'] == 'fixed_price'){
56
- $amount = apply_filters('wcml_raw_price_amount',$amount);
57
- }
58
-
59
- return $amount;
60
-
61
- }
62
-
63
-
64
- function dynamic_pricing_product_rules($rules){
65
- if(is_array($rules)){
66
- foreach($rules as $r_key=>$rule){
67
- foreach($rule['rules'] as $key=>$product_rule){
68
- if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
69
- $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
70
- }
71
- }
72
- }
73
- }
74
- return $rules;
75
- }
76
-
77
- function translate_cart_subtotal_exception( $value, $cart ){
78
- return true;
79
- }
80
-
81
- }
1
+ <?php
2
+
3
+ class WCML_Dynamic_Pricing{
4
+
5
+ function __construct(){
6
+ if(!is_admin()){
7
+ add_filter('wc_dynamic_pricing_load_modules', array($this, 'filter_price'));
8
+ add_filter('woocommerce_dynamic_pricing_is_applied_to', array($this, 'woocommerce_dynamic_pricing_is_applied_to'),10,5);
9
+ add_filter('woocommerce_dynamic_pricing_get_rule_amount',array($this,'woocommerce_dynamic_pricing_get_rule_amount'),10,4);
10
+ add_filter('dynamic_pricing_product_rules',array($this,'dynamic_pricing_product_rules'));
11
+ add_filter('translate_cart_subtotal_exception',array($this,'translate_cart_subtotal_exception'),10,2);
12
+
13
+ }
14
+ }
15
+
16
+ function filter_price($modules){
17
+
18
+ foreach($modules as $mod_key=>$module){
19
+ if(isset($module->available_rulesets)){
20
+ $available_rulesets = $module->available_rulesets;
21
+ foreach($available_rulesets as $rule_key=>$available_ruleset){
22
+ $rules = $available_ruleset['rules'];
23
+
24
+ if($rules){
25
+ foreach($rules as $r_key=>$rule){
26
+ if($rule['type'] == 'fixed_product'){
27
+ $rules[$r_key]['amount'] = apply_filters('wcml_raw_price_amount', $rule['amount']);
28
+ }
29
+ }
30
+ $modules[$mod_key]->available_rulesets[$rule_key]['rules'] = $rules;
31
+
32
+ }
33
+ }
34
+
35
+ }
36
+ }
37
+
38
+ return $modules;
39
+ }
40
+
41
+
42
+ function woocommerce_dynamic_pricing_is_applied_to($process_discounts, $_product, $module_id, $obj,$cat_id){
43
+ if($cat_id && isset($obj->available_rulesets) && count($obj->available_rulesets) > 0){
44
+ global $sitepress;
45
+ $cat_id = apply_filters( 'translate_object_id',$cat_id,'product_cat',true,$sitepress->get_current_language());
46
+ $process_discounts = is_object_in_term($_product->id, 'product_cat', $cat_id);
47
+ }
48
+
49
+ return $process_discounts;
50
+ }
51
+
52
+
53
+ function woocommerce_dynamic_pricing_get_rule_amount($amount, $rule, $cart_item, $obj){
54
+
55
+ if($rule['type'] == 'price_discount' || $rule['type'] == 'fixed_price'){
56
+ $amount = apply_filters('wcml_raw_price_amount',$amount);
57
+ }
58
+
59
+ return $amount;
60
+
61
+ }
62
+
63
+
64
+ function dynamic_pricing_product_rules($rules){
65
+ if(is_array($rules)){
66
+ foreach($rules as $r_key=>$rule){
67
+ foreach($rule['rules'] as $key=>$product_rule){
68
+ if($product_rule['type'] == 'price_discount' || $product_rule['type'] == 'fixed_price'){
69
+ $rules[$r_key]['rules'][$key]['amount'] = apply_filters('wcml_raw_price_amount', $product_rule['amount']);
70
+ }
71
+ }
72
+ }
73
+ }
74
+ return $rules;
75
+ }
76
+
77
+ function translate_cart_subtotal_exception( $value, $cart ){
78
+ return true;
79
+ }
80
+
81
+ }
compatibility/{wc_extra_product_options.class.php → class-wcml-extra-product-options.php} RENAMED
@@ -1,122 +1,122 @@
1
- <?php
2
-
3
- class WCML_Extra_Product_Options{
4
-
5
- function __construct(){
6
-
7
- add_filter( 'get_tm_product_terms', array( $this, 'filter_product_terms' ) );
8
-
9
- add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
10
-
11
- add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
12
-
13
- add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
14
- add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
15
- }
16
-
17
- function register_options_strings( $meta_id, $id, $meta_key, $options ){
18
- if( $meta_key != 'tm_meta' )
19
- return false;
20
-
21
- $this->filter_options( $options, $id, 'register' );
22
-
23
- }
24
-
25
- function product_options_filter( $null, $object_id, $meta_key, $single ){
26
- static $no_filter = false;
27
-
28
- if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
29
- $no_filter = true;
30
-
31
- $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
32
-
33
- $options = $this->filter_options( $options, $object_id, 'translate' );
34
-
35
- $no_filter = false;
36
- }
37
-
38
- return isset( $options ) ? array( $options ) : $null;
39
- }
40
-
41
- function filter_options( $options, $id, $action ){
42
-
43
- if( !isset( $options[ 'tmfbuilder' ] ) ){
44
- return $options;
45
- }
46
-
47
- global $sitepress,$woocommerce_wpml;
48
- $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
49
-
50
- $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
51
-
52
- foreach( $options[ 'tmfbuilder' ] as $key => $values ){
53
- foreach( $keys_to_translate as $key_text ){
54
- if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
55
- foreach( $values as $value_key => $value ){
56
- if( $value ){
57
- if( $action == 'register'){
58
- do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
59
- }else{
60
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
61
- }
62
- }
63
-
64
- }
65
- }
66
- }
67
-
68
- //convert prices
69
- if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
70
- foreach( $values as $value_key => $value ){
71
- if( $value ){
72
- if( is_array( $value ) ){
73
- foreach( $value as $key_price => $price ){
74
- $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
75
- }
76
- }else{
77
- $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
78
- }
79
- }
80
- }
81
- }
82
-
83
- }
84
-
85
- return $options;
86
- }
87
-
88
-
89
- function filter_product_terms( $product_terms ){
90
- global $sitepress,$wpdb;
91
-
92
- $translated_terms = array();
93
-
94
- foreach($product_terms as $key => $product_term){
95
- $tr_id = apply_filters( 'translate_object_id', $key, 'product_cat', true, $sitepress->get_default_language() );
96
-
97
- $translated_terms[$tr_id] = $wpdb->get_row( $wpdb->prepare("
98
- SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $tr_id, 'product_cat' ) );
99
-
100
- }
101
-
102
-
103
- return $translated_terms;
104
- }
105
-
106
- function inf_translate_strings(){
107
- if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
108
- $this->inf_message( 'Options Form' );
109
- }
110
-
111
- function inf_translate_product_page_strings(){
112
- $this->inf_message( 'Product' );
113
- }
114
-
115
- function inf_message( $text ){
116
- $message = '<div><p class="icl_cyan_box">';
117
- $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
118
- $message .= '</p></div>';
119
-
120
- echo $message;
121
- }
122
- }
1
+ <?php
2
+
3
+ class WCML_Extra_Product_Options{
4
+
5
+ function __construct(){
6
+
7
+ add_filter( 'get_tm_product_terms', array( $this, 'filter_product_terms' ) );
8
+
9
+ add_filter( 'get_post_metadata', array( $this, 'product_options_filter'), 100, 4 );
10
+
11
+ add_action( 'updated_post_meta', array( $this, 'register_options_strings' ), 10, 4 );
12
+
13
+ add_action( 'tm_before_extra_product_options', array( $this, 'inf_translate_product_page_strings' ) );
14
+ add_action( 'tm_before_price_rules', array( $this, 'inf_translate_strings' ) );
15
+ }
16
+
17
+ function register_options_strings( $meta_id, $id, $meta_key, $options ){
18
+ if( $meta_key != 'tm_meta' )
19
+ return false;
20
+
21
+ $this->filter_options( $options, $id, 'register' );
22
+
23
+ }
24
+
25
+ function product_options_filter( $null, $object_id, $meta_key, $single ){
26
+ static $no_filter = false;
27
+
28
+ if( empty($no_filter) && $meta_key == 'tm_meta' && !is_admin() ){
29
+ $no_filter = true;
30
+
31
+ $options = maybe_unserialize( get_post_meta( $object_id, $meta_key, $single ) );
32
+
33
+ $options = $this->filter_options( $options, $object_id, 'translate' );
34
+
35
+ $no_filter = false;
36
+ }
37
+
38
+ return isset( $options ) ? array( $options ) : $null;
39
+ }
40
+
41
+ function filter_options( $options, $id, $action ){
42
+
43
+ if( !isset( $options[ 'tmfbuilder' ] ) ){
44
+ return $options;
45
+ }
46
+
47
+ global $sitepress,$woocommerce_wpml;
48
+ $keys_to_translate = array( 'header_title', 'header_subtitle', 'text_after_price', 'placeholder' );
49
+
50
+ $id = apply_filters( 'translate_object_id', $id, get_post_type( $id ), true, $woocommerce_wpml->products->get_original_product_language( $id ) );
51
+
52
+ foreach( $options[ 'tmfbuilder' ] as $key => $values ){
53
+ foreach( $keys_to_translate as $key_text ){
54
+ if ( preg_match('/.*'.$key_text.'$/', $key ) ) {
55
+ foreach( $values as $value_key => $value ){
56
+ if( $value ){
57
+ if( $action == 'register'){
58
+ do_action('wpml_register_single_string', 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key, $value );
59
+ }else{
60
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wpml_translate_single_string', $value, 'wc_extra_product_options', $id.'_option_'.$value_key.'_'.$key);
61
+ }
62
+ }
63
+
64
+ }
65
+ }
66
+ }
67
+
68
+ //convert prices
69
+ if( $action == 'translate' && preg_match('/.*price$/', $key ) && !preg_match('/.*text_after_price/', $key )){
70
+ foreach( $values as $value_key => $value ){
71
+ if( $value ){
72
+ if( is_array( $value ) ){
73
+ foreach( $value as $key_price => $price ){
74
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ][ $key_price ] = apply_filters( 'wcml_raw_price_amount', $price );
75
+ }
76
+ }else{
77
+ $options[ 'tmfbuilder' ][ $key ][ $value_key ] = apply_filters( 'wcml_raw_price_amount', $value );
78
+ }
79
+ }
80
+ }
81
+ }
82
+
83
+ }
84
+
85
+ return $options;
86
+ }
87
+
88
+
89
+ function filter_product_terms( $product_terms ){
90
+ global $sitepress,$wpdb;
91
+
92
+ $translated_terms = array();
93
+
94
+ foreach($product_terms as $key => $product_term){
95
+ $tr_id = apply_filters( 'translate_object_id', $key, 'product_cat', true, $sitepress->get_default_language() );
96
+
97
+ $translated_terms[$tr_id] = $wpdb->get_row( $wpdb->prepare("
98
+ SELECT * FROM {$wpdb->terms} t JOIN {$wpdb->term_taxonomy} x ON x.term_id = t.term_id WHERE t.term_id = %d AND x.taxonomy = %s", $tr_id, 'product_cat' ) );
99
+
100
+ }
101
+
102
+
103
+ return $translated_terms;
104
+ }
105
+
106
+ function inf_translate_strings(){
107
+ if( isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] == 'tm-global-epo' )
108
+ $this->inf_message( 'Options Form' );
109
+ }
110
+
111
+ function inf_translate_product_page_strings(){
112
+ $this->inf_message( 'Product' );
113
+ }
114
+
115
+ function inf_message( $text ){
116
+ $message = '<div><p class="icl_cyan_box">';
117
+ $message .= sprintf(__('To translate Extra Options strings please save %s and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), $text, admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_extra_product_options'));
118
+ $message .= '</p></div>';
119
+
120
+ echo $message;
121
+ }
122
+ }
compatibility/{gravityforms.class.php → class-wcml-gravityforms.php} RENAMED
@@ -6,8 +6,6 @@ class WCML_gravityforms{
6
  add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
  add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
 
9
- add_filter('wcml_exception_duplicate_products_in_cart', array($this, 'addons_duplicate_exception'),10,2);
10
-
11
  add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
12
  }
13
 
@@ -25,13 +23,6 @@ class WCML_gravityforms{
25
  return $actions;
26
  }
27
 
28
- function addons_duplicate_exception( $exclude, $cart_item ) {
29
- if ( isset( $cart_item[ '_gravity_form_data' ] ) ) {
30
- $exclude = true;
31
- }
32
- return $exclude;
33
- }
34
-
35
  function sync_gf_data($original_product_id, $trnsl_product_id, $data){
36
  $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
37
  $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
6
  add_filter('gform_formatted_money',array($this,'wcml_convert_price'),10,2);
7
  add_filter('wcml_multi_currency_is_ajax',array($this,'add_ajax_action'));
8
 
 
 
9
  add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_gf_data'), 10, 3 );
10
  }
11
 
23
  return $actions;
24
  }
25
 
 
 
 
 
 
 
 
26
  function sync_gf_data($original_product_id, $trnsl_product_id, $data){
27
  $orig_gf = maybe_unserialize( get_post_meta( $original_product_id, '_gravity_form_data' , true ) );
28
  $trnsl_gf = maybe_unserialize( get_post_meta( $trnsl_product_id, '_gravity_form_data' , true ) );
compatibility/{wc_per_product_shipping.class.php → class-wcml-per-product-shipping.php} RENAMED
@@ -1,30 +1,30 @@
1
- <?php
2
-
3
- class WCML_Per_Product_Shipping{
4
-
5
- function __construct(){
6
-
7
- if(!is_admin()){
8
-
9
- add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
-
11
- }
12
-
13
-
14
- }
15
-
16
- function original_product_id( $product_id ){
17
- global $sitepress;
18
-
19
- $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
- $translations = $sitepress->get_element_translations($trid, 'post_product');
21
- foreach($translations as $language_code =>$translation){
22
- if($translation->original){
23
- $product_id = $translation->element_id;
24
- }
25
- }
26
-
27
- return $product_id;
28
- }
29
-
30
- }
1
+ <?php
2
+
3
+ class WCML_Per_Product_Shipping{
4
+
5
+ function __construct(){
6
+
7
+ if(!is_admin()){
8
+
9
+ add_filter('woocommerce_per_product_shipping_get_matching_rule_product_id', array( $this, 'original_product_id' ) );
10
+
11
+ }
12
+
13
+
14
+ }
15
+
16
+ function original_product_id( $product_id ){
17
+ global $sitepress;
18
+
19
+ $trid = $sitepress->get_element_trid($product_id, 'post_product');
20
+ $translations = $sitepress->get_element_translations($trid, 'post_product');
21
+ foreach($translations as $language_code =>$translation){
22
+ if($translation->original){
23
+ $product_id = $translation->element_id;
24
+ }
25
+ }
26
+
27
+ return $product_id;
28
+ }
29
+
30
+ }
compatibility/{wc_product_addons.class.php → class-wcml-product-addons.php} RENAMED
@@ -1,83 +1,76 @@
1
- <?php
2
-
3
- class WCML_Product_Addons{
4
-
5
- function __construct(){
6
-
7
- add_filter('get_product_addons_product_terms',array($this,'addons_product_terms'));
8
- add_filter('get_product_addons_fields',array($this,'product_addons_filter'),10,2);
9
-
10
- add_action('updated_post_meta',array($this,'register_addons_strings'),10,4);
11
-
12
- global $pagenow;
13
- if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
14
- add_action('admin_notices', array($this, 'inf_translate_strings'));
15
- }
16
-
17
- add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
18
- add_filter('wcml_exception_duplicate_products_in_cart', array($this, 'addons_duplicate_exception'),10,2);
19
- }
20
-
21
- function register_addons_strings( $meta_id, $id, $meta_key, $addons){
22
- if( $meta_key != '_product_addons' )
23
- return false;
24
-
25
- foreach($addons as $addon){
26
- //register name
27
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name', $addon['name']);
28
- //register description
29
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description', $addon['description']);
30
- //register options labels
31
- foreach($addon['options'] as $key=>$option){
32
- do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key, $option['label']);
33
- }
34
- }
35
- }
36
-
37
- function product_addons_filter($addons, $object_id){
38
- global $sitepress;
39
-
40
- $addon_type = get_post_type($object_id);
41
- if( $addon_type != 'global_product_addon' )
42
- $object_id = $sitepress->get_original_element_id( $object_id , 'post_'.$addon_type );
43
-
44
- foreach($addons as $add_id => $addon){
45
- $addons[$add_id]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name' );
46
- $addons[$add_id]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description');
47
- foreach($addon['options'] as $key=>$option){
48
- $addons[$add_id]['options'][$key]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key);
49
-
50
- //price filter
51
- $addons[$add_id]['options'][$key]['price'] = apply_filters('wcml_raw_price_amount', $option['price']);
52
- }
53
- }
54
-
55
- return $addons;
56
- }
57
-
58
-
59
- function addons_product_terms($product_terms){
60
- global $sitepress;
61
-
62
- foreach($product_terms as $key => $product_term){
63
- $product_terms[$key] = apply_filters( 'translate_object_id',$product_term,'product_cat',true,$sitepress->get_default_language());
64
- }
65
-
66
- return $product_terms;
67
- }
68
-
69
- function inf_translate_strings(){
70
- $message = '<div><p class="icl_cyan_box">';
71
- $message .= sprintf(__('To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings'));
72
- $message .= '</p></div>';
73
-
74
- echo $message;
75
- }
76
-
77
- function addons_duplicate_exception( $exclude, $cart_item ) {
78
- if ( isset( $cart_item[ 'addons' ] ) ) {
79
- $exclude = true;
80
- }
81
- return $exclude;
82
- }
83
- }
1
+ <?php
2
+
3
+ class WCML_Product_Addons{
4
+
5
+ function __construct(){
6
+
7
+ add_filter('get_product_addons_product_terms',array($this,'addons_product_terms'));
8
+ add_filter('get_product_addons_fields',array($this,'product_addons_filter'),10,2);
9
+
10
+ add_action('updated_post_meta',array($this,'register_addons_strings'),10,4);
11
+
12
+ global $pagenow;
13
+ if($pagenow == 'edit.php' && isset($_GET['post_type']) && $_GET['post_type']=='product' && isset($_GET['page']) && $_GET['page']=='global_addons' && !isset($_GET['edit'])){
14
+ add_action('admin_notices', array($this, 'inf_translate_strings'));
15
+ }
16
+
17
+ add_action( 'addons_panel_start', array( $this, 'inf_translate_strings' ) );
18
+ }
19
+
20
+ function register_addons_strings( $meta_id, $id, $meta_key, $addons){
21
+ if( $meta_key != '_product_addons' )
22
+ return false;
23
+
24
+ foreach($addons as $addon){
25
+ //register name
26
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name', $addon['name']);
27
+ //register description
28
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description', $addon['description']);
29
+ //register options labels
30
+ foreach($addon['options'] as $key=>$option){
31
+ do_action('wpml_register_single_string', 'wc_product_addons_strings', $id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key, $option['label']);
32
+ }
33
+ }
34
+ }
35
+
36
+ function product_addons_filter($addons, $object_id){
37
+ global $sitepress;
38
+
39
+ $addon_type = get_post_type($object_id);
40
+ if( $addon_type != 'global_product_addon' )
41
+ $object_id = $sitepress->get_original_element_id( $object_id , 'post_'.$addon_type );
42
+
43
+ foreach($addons as $add_id => $addon){
44
+ $addons[$add_id]['name'] = apply_filters( 'wpml_translate_single_string', $addon['name'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_name' );
45
+ $addons[$add_id]['description'] = apply_filters( 'wpml_translate_single_string', $addon['description'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_description');
46
+ foreach($addon['options'] as $key=>$option){
47
+ $addons[$add_id]['options'][$key]['label'] = apply_filters( 'wpml_translate_single_string', $option['label'], 'wc_product_addons_strings', $object_id.'_addon_'.$addon['type'].'_'.$addon['position'].'_option_label_'.$key);
48
+
49
+ //price filter
50
+ $addons[$add_id]['options'][$key]['price'] = apply_filters('wcml_raw_price_amount', $option['price']);
51
+ }
52
+ }
53
+
54
+ return $addons;
55
+ }
56
+
57
+
58
+ function addons_product_terms($product_terms){
59
+ global $sitepress;
60
+
61
+ foreach($product_terms as $key => $product_term){
62
+ $product_terms[$key] = apply_filters( 'translate_object_id',$product_term,'product_cat',true,$sitepress->get_default_language());
63
+ }
64
+
65
+ return $product_terms;
66
+ }
67
+
68
+ function inf_translate_strings(){
69
+ $message = '<div><p class="icl_cyan_box">';
70
+ $message .= sprintf(__('To translate Add-ons strings please save Add-ons and go to the <b><a href="%s">String Translation interface</a></b>', 'woocommerce-multilingual'), admin_url('admin.php?page='.WPML_ST_FOLDER.'/menu/string-translation.php&context=wc_product_addons_strings'));
71
+ $message .= '</p></div>';
72
+
73
+ echo $message;
74
+ }
75
+
76
+ }
 
 
 
 
 
 
 
compatibility/{wc_product_bundles.class.php → class-wcml-product-bundles.php} RENAMED
@@ -1,20 +1,48 @@
1
  <?php
2
  class WCML_Product_Bundles{
 
 
 
3
  function __construct(){
 
4
  add_action('wcml_gui_additional_box',array($this,'product_bundles_box'),10,3);
5
  add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
6
  add_action('wcml_extra_titles',array($this,'product_bundles_title'),10,1);
7
  add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,2);
8
  add_action('woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle'),5,3);
9
  add_filter('woocommerce_cart_loaded_from_session', array($this, 'resync_bundle_clean'),10);
10
- add_filter('wcml_exception_duplicate_products_in_cart', array($this, 'bundles_duplicate_exception'),10,2);
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
 
 
 
 
 
 
 
 
 
 
 
12
  // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
13
  function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
14
  global $sitepress;
15
  $atts = maybe_unserialize(get_post_meta($original_product_id, '_bundle_data', true));
16
  if( $atts ){
17
  $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
 
18
  $tr_ids = array();
19
  $i = 2;
20
  foreach($atts as $id=>$bundle_data){
@@ -28,8 +56,8 @@ class WCML_Product_Bundles{
28
  $tr_bundle[$bundle_key] = $bundle_data;
29
  $tr_bundle[$bundle_key]['product_id'] = $tr_id;
30
  if(isset($bundle_data['product_title'])){
31
- if($bundle_data['override_title']=='yes'){
32
- $tr_bundle[$bundle_key]['product_title'] = '';
33
  }else{
34
  $tr_title= get_the_title($tr_id);
35
  $tr_bundle[$bundle_key]['product_title'] = $tr_title;
@@ -37,7 +65,7 @@ class WCML_Product_Bundles{
37
  }
38
  if(isset($bundle_data['product_description'])){
39
  if($bundle_data['override_description']=='yes'){
40
- $tr_bundle[$bundle_key]['product_description'] = '';
41
  }else{
42
  $tr_prod = get_post($tr_id);
43
  $tr_desc = $tr_prod->post_excerpt;
@@ -76,6 +104,7 @@ class WCML_Product_Bundles{
76
  update_post_meta($trnsl_product_id,'_bundle_data',$tr_bundle);
77
  }
78
  }
 
79
  // Update Bundled products title and descritpion after saving the translation
80
  function bundle_update($tr_id, $data){
81
  global $sitepress;
@@ -92,13 +121,15 @@ class WCML_Product_Bundles{
92
  $tr_bundle_data = array();
93
  }
94
  }
 
95
  // Add 'Product Bundles' title to the WCML Product GUI if the current product is a bundled product
96
  function product_bundles_title($product_id){
97
  $bundle_data = maybe_unserialize(get_post_meta($product_id,'_bundle_data', true));
98
  if(!empty($bundle_data) && $bundle_data!=false){ ?>
99
- <th scope="col"><?php _e('Product Bundles', 'wcml_product_bundles'); ?></th>
100
  <?php }
101
  }
 
102
  // Add Bundles Box to WCML Translation GUI
103
  function product_bundles_box($product_id,$lang, $is_duplicate_product = false ) {
104
  global $sitepress, $woocommerce_wpml;
@@ -168,6 +199,7 @@ class WCML_Product_Bundles{
168
  }
169
  include WCML_PLUGIN_PATH . '/compatibility/templates/bundles_box.php';
170
  }
 
171
  function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
172
  if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
173
  $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
@@ -206,6 +238,7 @@ class WCML_Product_Bundles{
206
  }
207
  return $cart_item;
208
  }
 
209
  function resync_bundle_clean( $cart ) {
210
  foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
211
  if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
@@ -215,10 +248,98 @@ class WCML_Product_Bundles{
215
  }
216
  }
217
  }
218
- function bundles_duplicate_exception( $exclude, $cart_item ) {
219
- if ( isset( $cart_item[ 'bundled_items' ] ) || isset( $cart_item[ 'bundled_by' ] ) ) {
220
- $exclude = true;
221
- }
222
- return $exclude;
223
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
  }
1
  <?php
2
  class WCML_Product_Bundles{
3
+
4
+ var $tp;
5
+
6
  function __construct(){
7
+
8
  add_action('wcml_gui_additional_box',array($this,'product_bundles_box'),10,3);
9
  add_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
10
  add_action('wcml_extra_titles',array($this,'product_bundles_title'),10,1);
11
  add_action('wcml_update_extra_fields',array($this,'bundle_update'),10,2);
12
  add_action('woocommerce_get_cart_item_from_session', array( $this, 'resync_bundle'),5,3);
13
  add_filter('woocommerce_cart_loaded_from_session', array($this, 'resync_bundle_clean'),10);
14
+
15
+ if( version_compare( WCML_VERSION, '3.7.2', '>') ){
16
+ add_filter( 'option_wpml_config_files_arr', array($this, 'make__bundle_data_not_translatable_by_default'), 0 );
17
+ }
18
+
19
+ if( is_admin() ){
20
+ $this->tp = new WPML_Element_Translation_Package();
21
+
22
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_bundle_data_translation_package' ), 10, 2 );
23
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_bundle_data_translation' ), 10, 3 );
24
+
25
+ }
26
+
27
  }
28
+
29
+ function make__bundle_data_not_translatable_by_default($wpml_config_array){
30
+
31
+ if( isset( $wpml_config_array->plugins['WooCommerce Product Bundles'] ) ){
32
+ $wpml_config_array->plugins['WooCommerce Product Bundles'] =
33
+ str_replace('<custom-field action="translate">_bundle_data</custom-field>', '<custom-field action="nothing">_bundle_data</custom-field>', $wpml_config_array->plugins['WooCommerce Product Bundles']);
34
+ }
35
+
36
+ return $wpml_config_array;
37
+ }
38
+
39
  // Sync Bundled product '_bundle_data' with translated values when the product is duplicated
40
  function sync_bundled_ids($original_product_id, $trnsl_product_id, $data = false){
41
  global $sitepress;
42
  $atts = maybe_unserialize(get_post_meta($original_product_id, '_bundle_data', true));
43
  if( $atts ){
44
  $lang = $sitepress->get_language_for_element($trnsl_product_id,'post_product');
45
+ $tr_bundle_meta = maybe_unserialize(get_post_meta($trnsl_product_id, '_bundle_data', true));
46
  $tr_ids = array();
47
  $i = 2;
48
  foreach($atts as $id=>$bundle_data){
56
  $tr_bundle[$bundle_key] = $bundle_data;
57
  $tr_bundle[$bundle_key]['product_id'] = $tr_id;
58
  if(isset($bundle_data['product_title'])){
59
+ if($bundle_data['override_title'] == 'yes'){
60
+ $tr_bundle[$bundle_key]['product_title'] = isset( $tr_bundle_meta[$bundle_key]['product_title'] ) ? $tr_bundle_meta[$bundle_key]['product_title'] : '';
61
  }else{
62
  $tr_title= get_the_title($tr_id);
63
  $tr_bundle[$bundle_key]['product_title'] = $tr_title;
65
  }
66
  if(isset($bundle_data['product_description'])){
67
  if($bundle_data['override_description']=='yes'){
68
+ $tr_bundle[$bundle_key]['product_description'] = isset( $tr_bundle_meta[$bundle_key]['product_description'] ) ? $tr_bundle_meta[$bundle_key]['product_description'] : '';
69
  }else{
70
  $tr_prod = get_post($tr_id);
71
  $tr_desc = $tr_prod->post_excerpt;
104
  update_post_meta($trnsl_product_id,'_bundle_data',$tr_bundle);
105
  }
106
  }
107
+
108
  // Update Bundled products title and descritpion after saving the translation
109
  function bundle_update($tr_id, $data){
110
  global $sitepress;
121
  $tr_bundle_data = array();
122
  }
123
  }
124
+
125
  // Add 'Product Bundles' title to the WCML Product GUI if the current product is a bundled product
126
  function product_bundles_title($product_id){
127
  $bundle_data = maybe_unserialize(get_post_meta($product_id,'_bundle_data', true));
128
  if(!empty($bundle_data) && $bundle_data!=false){ ?>
129
+ <th scope="col"><?php _e('Product Bundles', 'woocommerce-multilingual'); ?></th>
130
  <?php }
131
  }
132
+
133
  // Add Bundles Box to WCML Translation GUI
134
  function product_bundles_box($product_id,$lang, $is_duplicate_product = false ) {
135
  global $sitepress, $woocommerce_wpml;
199
  }
200
  include WCML_PLUGIN_PATH . '/compatibility/templates/bundles_box.php';
201
  }
202
+
203
  function resync_bundle( $cart_item, $session_values, $cart_item_key ) {
204
  if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
205
  $current_bundle_id = apply_filters( 'translate_object_id', $cart_item[ 'product_id' ], 'product', true );
238
  }
239
  return $cart_item;
240
  }
241
+
242
  function resync_bundle_clean( $cart ) {
243
  foreach ( $cart->cart_contents as $cart_item_key => $cart_item ) {
244
  if ( isset( $cart_item[ 'bundled_items' ] ) && $cart_item[ 'data' ]->product_type === 'bundle' ) {
248
  }
249
  }
250
  }
251
+
252
+ function append_bundle_data_translation_package( $package, $post ){
253
+
254
+ if( $post->post_type == 'product' ) {
255
+
256
+ $bundle_data = get_post_meta( $post->ID, '_bundle_data', true );
257
+
258
+ if( $bundle_data ){
259
+
260
+ $fields = array( 'title', 'description' );
261
+
262
+ foreach( $bundle_data as $product ){
263
+
264
+ foreach( $fields as $field ) {
265
+ if ( $product['override_' . $field] == 'yes' && !empty($product['product_' . $field]) ) {
266
+
267
+ $package['contents']['product_bundles:' . $product['product_id'] . ':' . $field] = array(
268
+ 'translate' => 1,
269
+ 'data' => $this->tp->encode_field_data( $product['product_' . $field], 'base64' ),
270
+ 'format' => 'base64'
271
+ );
272
+
273
+ }
274
+ }
275
+
276
+ }
277
+
278
+ }
279
+
280
+ }
281
+
282
+ return $package;
283
+
284
+ }
285
+
286
+ function save_bundle_data_translation( $post_id, $data, $job ){
287
+
288
+ remove_action('wcml_after_duplicate_product_post_meta',array($this,'sync_bundled_ids'),10,3);
289
+
290
+ $bundle_data = get_post_meta( $post_id, '_bundle_data', true );
291
+
292
+ $bundle_data_original = get_post_meta($job->original_doc_id , '_bundle_data', true);
293
+
294
+ $translated_bundle_pieces = array();
295
+
296
+ foreach( $data as $value){
297
+
298
+ if( preg_match( '/product_bundles:([0-9]+):(.+)/', $value['field_type'], $matches ) ){
299
+
300
+ $product_id = $matches[1];
301
+ $field = $matches[2];
302
+
303
+ $translated_product_id = apply_filters( 'translate_object_id', $product_id, 'product', true, $job->language_code );
304
+
305
+ $products_translation_map[$translated_product_id] = $product_id;
306
+
307
+ if( $translated_product_id ){
308
+
309
+ $translated_bundle_pieces[$translated_product_id][$field] = $value['data'];
310
+
311
+ }
312
+
313
+ }
314
+
315
+ }
316
+
317
+ if( $translated_bundle_pieces ){
318
+ foreach( $translated_bundle_pieces as $product_id => $piece ){
319
+
320
+ if( isset($products_translation_map[$product_id]) ) {
321
+
322
+ $bundle_data[$product_id] = array(
323
+
324
+ 'product_id' => $product_id,
325
+ 'hide_thumbnail' => $bundle_data_original[$products_translation_map[$product_id]]['hide_thumbnail'],
326
+ 'override_title' => $bundle_data_original[$products_translation_map[$product_id]]['override_title'],
327
+ 'product_title' => isset( $piece['title'] ) ? $piece['title'] : '',
328
+ 'override_description' => $bundle_data_original[$products_translation_map[$product_id]]['override_description'],
329
+ 'product_description' => isset( $piece['description'] ) ? $piece['description'] : '',
330
+ 'optional' => $bundle_data_original[$products_translation_map[$product_id]]['optional'],
331
+ 'bundle_quantity' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity'],
332
+ 'bundle_quantity_max' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_quantity_max'],
333
+ 'bundle_discount' => $bundle_data_original[$products_translation_map[$product_id]]['bundle_discount'],
334
+ 'visibility' => $bundle_data_original[$products_translation_map[$product_id]]['visibility'],
335
+
336
+ );
337
+ }
338
+
339
+ }
340
+ }
341
+
342
+ update_post_meta( $post_id, '_bundle_data', $bundle_data );
343
+
344
+ }
345
  }
compatibility/{wc_sensei.class.php → class-wcml-sensei.php} RENAMED
@@ -1,231 +1,231 @@
1
- <?php
2
-
3
- class WCML_sensei{
4
-
5
- function __construct(){
6
- global $sitepress;
7
- add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
- add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
-
10
- add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
- add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
- add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
- add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
-
15
- add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
-
17
- if( is_admin() &&
18
- (
19
- ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
- ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
- ) ){
22
- remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
- }
24
-
25
- }
26
-
27
- function save_post_actions( $post_id, $post ){
28
- global $sitepress;
29
-
30
- // skip not related post types
31
- if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
- return;
33
- }
34
- // skip auto-drafts
35
- if ( $post->post_status == 'auto-draft' ) {
36
- return;
37
- }
38
- // skip autosave
39
- if ( isset( $_POST[ 'autosave' ] ) ) {
40
- return;
41
- }
42
-
43
- if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
- $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
- }
46
-
47
-
48
- // sync fields from original
49
- $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
- $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
-
52
- if ( !empty( $translations ) ) {
53
- $original_post_id = false;
54
- foreach ( $translations as $t ) {
55
- if ( $t->original ) {
56
- $original_post_id = $t->element_id;
57
- break;
58
- }
59
- }
60
-
61
- if ( $post_id != $original_post_id ) {
62
- $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
- } else {
64
- foreach ( $translations as $t ) {
65
- if ( $original_post_id != $t->element_id ) {
66
- $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
- }
68
- }
69
- }
70
- }
71
-
72
- }
73
-
74
-
75
- function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
- global $sitepress;
77
-
78
- $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
- if( $post_type == 'quiz' ){
80
-
81
- //sync quiz lesson
82
- $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
-
84
- if( $lesson_id ){
85
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
-
87
- if( !is_null( $tr_lesson_id ) ){
88
- update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
- }
90
- }else{
91
- delete_post_meta( $post_id, '_quiz_lesson' );
92
- }
93
-
94
- } elseif( $post_type == 'lesson' ){
95
- //sync lesson course
96
- $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
-
98
- if( $course_id ){
99
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
-
101
- if( !is_null( $tr_course_id ) ){
102
- update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
- }
104
- }else{
105
- delete_post_meta( $post_id, '_lesson_course' );
106
- }
107
-
108
- //sync lesson prerequisite
109
- $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
-
111
- if( $lesson_id ){
112
- $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
-
114
- if( !is_null( $tr_lesson_id ) ){
115
- update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
- }
117
- }else{
118
- delete_post_meta( $post_id, '_lesson_prerequisite' );
119
- }
120
-
121
- }else{
122
-
123
- //sync course woocommerce_product
124
- $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
-
126
- if( $product_id ){
127
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
-
129
- if( !is_null( $tr_product_id ) ){
130
- update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
- }
132
- }else{
133
- delete_post_meta( $post_id, '_course_woocommerce_product' );
134
- }
135
-
136
- //sync course prerequisite
137
- $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
-
139
- if( $course_id ){
140
- $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
-
142
- if( !is_null( $tr_course_id ) ){
143
- update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
- }
145
- }else{
146
- delete_post_meta( $post_id, '_course_prerequisite' );
147
- }
148
-
149
- }
150
-
151
- }
152
-
153
- function log_activity_after ( $args, $data, $comment_id = false ){
154
- global $sitepress;
155
-
156
- if( !$comment_id ){
157
- return false;
158
- }
159
-
160
- $comment_post_id = $data['comment_post_ID'];
161
- $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
- $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
-
164
- foreach($translations as $translation){
165
-
166
- if( $comment_post_id != $translation->element_id ){
167
- $data['comment_post_ID'] = $translation->element_id;
168
-
169
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
-
171
- $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
- if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
- $data['comment_ID'] = $tr_comment_id;
174
- $tr_comment_id = wp_update_comment( $data );
175
- }else{
176
- $tr_comment_id = wp_insert_comment( $data );
177
- $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
- }
179
- }
180
-
181
- }
182
-
183
- }
184
-
185
- function filter_bought_product_id( $product_id, $order ){
186
-
187
- $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
-
189
- $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
-
191
- if( !is_null( $tr_product_id ) ){
192
- return $tr_product_id;
193
- }else{
194
- return $product_id;
195
- }
196
- }
197
-
198
- function delete_user_activity ( $comment_id ){
199
- global $sitepress;
200
-
201
- $comment_type = get_comment_type( $comment_id );
202
-
203
- if( strstr( $comment_type, "sensei" ) ){
204
-
205
- $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
- $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
-
208
- remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
- foreach ( $translations as $translation ){
210
- if( $comment_id != $translation->element_id ){
211
- wp_delete_comment( $translation->element_id, true );
212
- }
213
- }
214
-
215
- }
216
-
217
-
218
- }
219
-
220
- function pre_get_comments($obj){
221
- global $sitepress;
222
-
223
- if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
-
225
- remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
-
227
- }
228
-
229
- }
230
-
231
- }
1
+ <?php
2
+
3
+ class WCML_sensei{
4
+
5
+ function __construct(){
6
+ global $sitepress;
7
+ add_action( 'manage_edit-lesson_columns', array( $sitepress, 'add_posts_management_column' ) );
8
+ add_action( 'manage_edit-course_columns', array( $sitepress, 'add_posts_management_column' ) );
9
+
10
+ add_action( 'save_post', array( $this, 'save_post_actions' ), 100, 2 );
11
+ add_action( 'sensei_log_activity_after', array( $this, 'log_activity_after' ), 10, 3 );
12
+ add_filter( 'sensei_bought_product_id', array( $this, 'filter_bought_product_id' ), 10, 2 );
13
+ add_action( 'delete_comment', array( $this, 'delete_user_activity' ) );
14
+
15
+ add_action( 'pre_get_comments', array( $this, 'pre_get_comments') );
16
+
17
+ if( is_admin() &&
18
+ (
19
+ ( isset($_GET['post_type']) && $_GET['post_type'] == 'sensei_message' ) ||
20
+ ( isset($_GET['page']) && $_GET['page'] == 'sensei_grading' )
21
+ ) ){
22
+ remove_action( 'wp_before_admin_bar_render', array($sitepress, 'admin_language_switcher') );
23
+ }
24
+
25
+ }
26
+
27
+ function save_post_actions( $post_id, $post ){
28
+ global $sitepress;
29
+
30
+ // skip not related post types
31
+ if ( !in_array( $post->post_type , array( 'lesson', 'course', 'quiz' ) ) ) {
32
+ return;
33
+ }
34
+ // skip auto-drafts
35
+ if ( $post->post_status == 'auto-draft' ) {
36
+ return;
37
+ }
38
+ // skip autosave
39
+ if ( isset( $_POST[ 'autosave' ] ) ) {
40
+ return;
41
+ }
42
+
43
+ if( $post->post_type == 'quiz' && isset( $_POST[ 'ID' ] ) ){
44
+ $this->save_post_actions( $_POST[ 'ID' ], get_post( $_POST[ 'ID' ] ) );
45
+ }
46
+
47
+
48
+ // sync fields from original
49
+ $trid = $sitepress->get_element_trid( $post_id, 'post_' . $post->post_type );
50
+ $translations = $sitepress->get_element_translations( $trid, 'post_' . $post->post_type );
51
+
52
+ if ( !empty( $translations ) ) {
53
+ $original_post_id = false;
54
+ foreach ( $translations as $t ) {
55
+ if ( $t->original ) {
56
+ $original_post_id = $t->element_id;
57
+ break;
58
+ }
59
+ }
60
+
61
+ if ( $post_id != $original_post_id ) {
62
+ $this->sync_custom_fields( $original_post_id, $post_id, $post->post_type );
63
+ } else {
64
+ foreach ( $translations as $t ) {
65
+ if ( $original_post_id != $t->element_id ) {
66
+ $this->sync_custom_fields( $original_post_id, $t->element_id, $post->post_type );
67
+ }
68
+ }
69
+ }
70
+ }
71
+
72
+ }
73
+
74
+
75
+ function sync_custom_fields ( $original_post_id, $post_id, $post_type ){
76
+ global $sitepress;
77
+
78
+ $language = $sitepress->get_language_for_element( $post_id, 'post_'.$post_type );
79
+ if( $post_type == 'quiz' ){
80
+
81
+ //sync quiz lesson
82
+ $lesson_id = get_post_meta( $original_post_id, '_quiz_lesson', true );
83
+
84
+ if( $lesson_id ){
85
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
86
+
87
+ if( !is_null( $tr_lesson_id ) ){
88
+ update_post_meta( $post_id, '_quiz_lesson', $tr_lesson_id );
89
+ }
90
+ }else{
91
+ delete_post_meta( $post_id, '_quiz_lesson' );
92
+ }
93
+
94
+ } elseif( $post_type == 'lesson' ){
95
+ //sync lesson course
96
+ $course_id = get_post_meta( $original_post_id, '_lesson_course', true );
97
+
98
+ if( $course_id ){
99
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
100
+
101
+ if( !is_null( $tr_course_id ) ){
102
+ update_post_meta( $post_id, '_lesson_course', $tr_course_id );
103
+ }
104
+ }else{
105
+ delete_post_meta( $post_id, '_lesson_course' );
106
+ }
107
+
108
+ //sync lesson prerequisite
109
+ $lesson_id = get_post_meta( $original_post_id, '_lesson_prerequisite', true );
110
+
111
+ if( $lesson_id ){
112
+ $tr_lesson_id = apply_filters( 'translate_object_id', $lesson_id, 'lesson', false, $language );
113
+
114
+ if( !is_null( $tr_lesson_id ) ){
115
+ update_post_meta( $post_id, '_lesson_prerequisite', $tr_lesson_id );
116
+ }
117
+ }else{
118
+ delete_post_meta( $post_id, '_lesson_prerequisite' );
119
+ }
120
+
121
+ }else{
122
+
123
+ //sync course woocommerce_product
124
+ $product_id = get_post_meta( $original_post_id, '_course_woocommerce_product', true );
125
+
126
+ if( $product_id ){
127
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $language );
128
+
129
+ if( !is_null( $tr_product_id ) ){
130
+ update_post_meta( $post_id, '_course_woocommerce_product', $tr_product_id );
131
+ }
132
+ }else{
133
+ delete_post_meta( $post_id, '_course_woocommerce_product' );
134
+ }
135
+
136
+ //sync course prerequisite
137
+ $course_id = get_post_meta( $original_post_id, '_course_prerequisite', true );
138
+
139
+ if( $course_id ){
140
+ $tr_course_id = apply_filters( 'translate_object_id', $course_id, 'course', false, $language );
141
+
142
+ if( !is_null( $tr_course_id ) ){
143
+ update_post_meta( $post_id, '_course_prerequisite', $tr_course_id );
144
+ }
145
+ }else{
146
+ delete_post_meta( $post_id, '_course_prerequisite' );
147
+ }
148
+
149
+ }
150
+
151
+ }
152
+
153
+ function log_activity_after ( $args, $data, $comment_id = false ){
154
+ global $sitepress;
155
+
156
+ if( !$comment_id ){
157
+ return false;
158
+ }
159
+
160
+ $comment_post_id = $data['comment_post_ID'];
161
+ $trid = $sitepress->get_element_trid( $comment_post_id, 'post_'.get_post_type( $comment_post_id ) );
162
+ $translations = $sitepress->get_element_translations( $trid, 'post_'.get_post_type( $comment_post_id ) );
163
+
164
+ foreach($translations as $translation){
165
+
166
+ if( $comment_post_id != $translation->element_id ){
167
+ $data['comment_post_ID'] = $translation->element_id;
168
+
169
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
170
+
171
+ $tr_comment_id = apply_filters( 'translate_object_id', $comment_id, 'comment', false, $translation->language_code );
172
+ if ( isset( $args['action'] ) && 'update' == $args['action'] && !is_null( $tr_comment_id ) && get_comment( $tr_comment_id ) ) {
173
+ $data['comment_ID'] = $tr_comment_id;
174
+ $tr_comment_id = wp_update_comment( $data );
175
+ }else{
176
+ $tr_comment_id = wp_insert_comment( $data );
177
+ $sitepress->set_element_language_details( $tr_comment_id, 'comment', $trid, $translation->language_code );
178
+ }
179
+ }
180
+
181
+ }
182
+
183
+ }
184
+
185
+ function filter_bought_product_id( $product_id, $order ){
186
+
187
+ $order_language = get_post_meta( $order->id, 'wpml_language', true );
188
+
189
+ $tr_product_id = apply_filters( 'translate_object_id', $product_id, get_post_type( $product_id ), false, $order_language );
190
+
191
+ if( !is_null( $tr_product_id ) ){
192
+ return $tr_product_id;
193
+ }else{
194
+ return $product_id;
195
+ }
196
+ }
197
+
198
+ function delete_user_activity ( $comment_id ){
199
+ global $sitepress;
200
+
201
+ $comment_type = get_comment_type( $comment_id );
202
+
203
+ if( strstr( $comment_type, "sensei" ) ){
204
+
205
+ $trid = $sitepress->get_element_trid( $comment_id, 'comment' );
206
+ $translations = $sitepress->get_element_translations( $trid, 'comment' );
207
+
208
+ remove_action( 'delete_comment', array ( $this, 'delete_user_activity' ) );
209
+ foreach ( $translations as $translation ){
210
+ if( $comment_id != $translation->element_id ){
211
+ wp_delete_comment( $translation->element_id, true );
212
+ }
213
+ }
214
+
215
+ }
216
+
217
+
218
+ }
219
+
220
+ function pre_get_comments($obj){
221
+ global $sitepress;
222
+
223
+ if( $obj->query_vars[ 'type' ] == 'sensei_course_start' ){
224
+
225
+ remove_filter( 'comments_clauses', array( $sitepress, 'comments_clauses' ), 10, 2 );
226
+
227
+ }
228
+
229
+ }
230
+
231
+ }
compatibility/class-wcml-tab-manager.php ADDED
@@ -0,0 +1,485 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_Tab_Manager{
4
+
5
+ public $tp;
6
+
7
+ function __construct(){
8
+ add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_tabs' ), 10, 3 );
9
+ add_filter( 'wcml_product_content_exception', array( $this, 'is_have_custom_product_tab' ), 10, 3 );
10
+ add_filter( 'wcml_custom_box_html', array( $this, 'custom_box_html'), 10, 3 );
11
+ add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
12
+ add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs') , 10, 2 );
13
+
14
+ if( version_compare( WCML_VERSION, '3.7.2', '>') ){
15
+ add_filter( 'option_wpml_config_files_arr', array($this, 'make__product_tabs_not_translatable_by_default'), 0 );
16
+ }
17
+
18
+ if( is_admin() ){
19
+
20
+ $this->tp = new WPML_Element_Translation_Package;
21
+
22
+ add_action( 'save_post', array($this, 'force_set_language_information_on_product_tabs'), 10, 2);
23
+
24
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_tabs_to_translation_package' ), 10, 2 );
25
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_tabs_translation' ), 10, 3 );
26
+
27
+ }
28
+
29
+ }
30
+
31
+ function make__product_tabs_not_translatable_by_default($wpml_config_array){
32
+
33
+ if( isset( $wpml_config_array->plugins['WooCommerce Tab Manager'] ) ){
34
+ $wpml_config_array->plugins['WooCommerce Tab Manager'] =
35
+ str_replace('<custom-field action="translate">_product_tabs</custom-field>',
36
+ '<custom-field action="nothing">_product_tabs</custom-field>',
37
+ $wpml_config_array->plugins['WooCommerce Tab Manager'] );
38
+ }
39
+
40
+ return $wpml_config_array;
41
+
42
+ }
43
+
44
+ function sync_tabs( $original_product_id, $trnsl_product_id, $data = false ){
45
+ global $wc_tab_manager, $sitepress, $woocommerce, $woocommerce_wpml;
46
+
47
+ $lang = $sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
48
+
49
+ //check if "duplicate" product
50
+ if( ( isset( $_POST['icl_ajx_action'] ) && ( $_POST['icl_ajx_action'] == 'make_duplicates' ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ){
51
+ $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
52
+ }
53
+
54
+ if( !isset( $data[ '_product_tabs_'.$lang ] ) ){
55
+ return;
56
+ }
57
+
58
+ $orig_prod_tabs = $wc_tab_manager->get_product_tabs( $original_product_id );
59
+
60
+ if( $orig_prod_tabs ){
61
+ $trnsl_product_tabs = array();
62
+ $i = 0;
63
+ foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
64
+ switch( $orig_prod_tab[ 'type' ] ){
65
+ case 'core':
66
+ $default_language = $woocommerce_wpml->products->get_original_product_language( $original_product_id );
67
+ $current_language = $sitepress->get_current_language();
68
+ $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
69
+ if( isset( $data[ '_product_tabs_'.$lang ] ) ){
70
+ $title = $data[ '_product_tabs_'.$lang ][ 'core_title' ][ $orig_prod_tab[ 'id' ] ];
71
+ $heading = $data[ '_product_tabs_'.$lang ][ 'core_heading' ][ $orig_prod_tab[ 'id' ] ];
72
+ }
73
+
74
+ if( $default_language != $lang ){
75
+ $this->refresh_text_domain( $lang );
76
+ if( !$title ) $title = $orig_prod_tabs[ $key ][ 'title' ];
77
+ $title = __( $title, 'woocommerce' );
78
+ if( !isset( $heading ) ){
79
+ $heading = '';
80
+ }elseif( !$heading && isset( $orig_prod_tabs[ $key ][ 'heading' ] ) ){
81
+ $heading = $orig_prod_tabs[ $key ][ 'heading' ];
82
+ }
83
+ $heading = __( $heading, 'woocommerce' );
84
+ $this->refresh_text_domain( $current_language );
85
+ }
86
+
87
+ $trnsl_product_tabs[ $key ][ 'title' ] = $title;
88
+ $trnsl_product_tabs[ $key ][ 'heading' ] = $heading;
89
+ break;
90
+ case 'global':
91
+ $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
92
+ break;
93
+ case 'product':
94
+ $tab_id = false;
95
+ if( isset( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) ){
96
+ if( get_post_type( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) == 'wc_product_tab' ){
97
+ $tab_id = $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ];
98
+ }
99
+ $title = $data[ '_product_tabs_'.$lang ][ 'title' ][ $i ];
100
+ $content = $data[ '_product_tabs_'.$lang ][ 'content' ][ $i ];
101
+ }
102
+
103
+ $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
104
+
105
+ $i++;
106
+ break;
107
+ }
108
+ }
109
+ update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
110
+ }
111
+ }
112
+
113
+ function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ){
114
+ global $sitepress;
115
+ $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
116
+ $prod_tabs = array();
117
+ foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
118
+ switch( $orig_prod_tab[ 'type' ] ){
119
+ case 'core':
120
+ $prod_tabs[ $key ] = $orig_prod_tab;
121
+ $this->refresh_text_domain( $lang );
122
+ $prod_tabs[ $key ][ 'title' ] = __( $orig_prod_tab[ 'title' ], 'woocommerce' );
123
+ if( isset( $orig_prod_tab[ 'heading' ] ) )
124
+ $prod_tabs[ $key ][ 'heading' ] = __( $orig_prod_tab[ 'heading' ], 'woocommerce' );
125
+ $orig_lang = $sitepress->get_language_for_element( $original_product_id, 'post_product' );
126
+ $this->refresh_text_domain( $orig_lang );
127
+ break;
128
+ case 'global':
129
+ $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
130
+ break;
131
+ case 'product':
132
+ $original_tab = get_post( $orig_prod_tab[ 'id' ] );
133
+ $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
134
+ break;
135
+ }
136
+ }
137
+
138
+ update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
139
+ }
140
+
141
+ function refresh_text_domain( $lang ){
142
+ global $sitepress, $woocommerce;
143
+
144
+ unload_textdomain( 'woocommerce' );
145
+ $sitepress->switch_lang( $lang );
146
+ $woocommerce->load_plugin_textdomain();
147
+ }
148
+
149
+ function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ){
150
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', true, $lang );
151
+ $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tr_tab_id ] = array(
152
+ 'position' => $orig_prod_tab[ 'position' ],
153
+ 'type' => $orig_prod_tab[ 'type' ],
154
+ 'id' => $tr_tab_id,
155
+ 'name' => get_post( $tr_tab_id )->post_name
156
+ );
157
+ return $trnsl_product_tabs;
158
+ }
159
+
160
+ function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ){
161
+ global $wpdb, $sitepress;
162
+
163
+ if( !$tab_id ){
164
+ $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', false, $lang );
165
+
166
+ if( !is_null( $tr_tab_id ) ){
167
+ $tab_id = $tr_tab_id;
168
+ }
169
+ }
170
+
171
+ if( $tab_id ){
172
+ //update existing tab
173
+ $args = array();
174
+ $args[ 'post_title' ] = $title;
175
+ $args[ 'post_content' ] = $content;
176
+ $wpdb->update( $wpdb->posts, $args, array( 'ID' => $tab_id ) );
177
+ }else{
178
+ //tab not exist creating new
179
+ $args = array();
180
+ $args[ 'post_title' ] = $title;
181
+ $args[ 'post_content' ] = $content;
182
+ $args[ 'post_author' ] = get_current_user_id();
183
+ $args[ 'post_name' ] = sanitize_title( $title );
184
+ $args[ 'post_type' ] = 'wc_product_tab';
185
+ $args[ 'post_parent' ] = $trnsl_product_id;
186
+ $args[ 'post_status' ] = 'publish';
187
+ $wpdb->insert( $wpdb->posts, $args );
188
+
189
+ $tab_id = $wpdb->insert_id;
190
+ $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
191
+ if( !$tab_trid ){
192
+ $sitepress->set_element_language_details( $orig_prod_tab[ 'id' ], 'post_wc_product_tab', false, $sitepress->get_default_language() );
193
+ $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
194
+ }
195
+ $sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
196
+ }
197
+
198
+ $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tab_id ] = array(
199
+ 'position' => $orig_prod_tab[ 'position' ],
200
+ 'type' => $orig_prod_tab[ 'type' ],
201
+ 'id' => $tab_id,
202
+ 'name' => get_post( $tab_id )->post_name
203
+ );
204
+
205
+ return $trnsl_product_tabs;
206
+ }
207
+
208
+ function duplicate_custom_fields_exceptions( $exceptions ){
209
+ $exceptions[] = '_product_tabs';
210
+ return $exceptions;
211
+ }
212
+
213
+ function is_have_custom_product_tab( $exception, $product_id, $meta_key ){
214
+
215
+ if( $meta_key == '_product_tabs'){
216
+ $exception = get_post_meta( $product_id, '_override_tab_layout', true) != 'yes';
217
+ }
218
+
219
+ return $exception;
220
+ }
221
+
222
+ function custom_box_html($html, $template_data, $lang){
223
+
224
+ if( $template_data['product_content'] == '_product_tabs' ){
225
+ global $wc_tab_manager;
226
+
227
+ $orig_prod_tabs = $wc_tab_manager->get_product_tabs($template_data['product_id']);
228
+ if(!$orig_prod_tabs) return '';
229
+ if($template_data['tr_product_id']){
230
+ $tr_prod_tabs = $wc_tab_manager->get_product_tabs($template_data['tr_product_id']);
231
+
232
+ if(!is_array($tr_prod_tabs)){
233
+ return __('Please update original product', 'woocommerce-multilingual');
234
+ }
235
+
236
+ foreach($tr_prod_tabs as $key=>$prod_tab){
237
+ if(in_array($prod_tab['type'],array('product','core'))){
238
+ if($prod_tab['type'] == 'core'){
239
+ $template_data['tr_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
240
+ $template_data['tr_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
241
+ $template_data['tr_tabs'][$prod_tab['id']]['title'] = $prod_tab['title'];
242
+ $template_data['tr_tabs'][$prod_tab['id']]['heading'] = isset ($prod_tab['heading']) ? $prod_tab['heading'] : '';
243
+ }else{
244
+ $template_data['tr_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
245
+ $template_data['tr_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
246
+ }
247
+ }
248
+ }
249
+ }else{
250
+ global $sitepress,$woocommerce;
251
+ $current_language = $sitepress->get_current_language();
252
+ foreach($orig_prod_tabs as $key=>$prod_tab){
253
+ if($prod_tab['type'] == 'core'){
254
+ unload_textdomain('woocommerce');
255
+ $sitepress->switch_lang($lang);
256
+ $woocommerce->load_plugin_textdomain();
257
+ $title = __( $prod_tab['title'], 'woocommerce' );
258
+ if($prod_tab['title'] != $title){
259
+ $template_data['tr_tabs'][$prod_tab['id']]['title'] = $title;
260
+
261
+ }
262
+
263
+ if(!isset($prod_tab['heading'])){
264
+ $template_data['tr_tabs'][$prod_tab['id']]['heading'] = '';
265
+ }else{
266
+ $heading = __( $prod_tab['heading'], 'woocommerce' );
267
+ if($prod_tab['heading'] != $heading){
268
+ $template_data['tr_tabs'][$prod_tab['id']]['heading'] = $heading;
269
+ }
270
+ }
271
+
272
+ unload_textdomain('woocommerce');
273
+ $sitepress->switch_lang($current_language);
274
+ $woocommerce->load_plugin_textdomain();
275
+ }
276
+ }
277
+ }
278
+
279
+ foreach($orig_prod_tabs as $key=>$prod_tab){
280
+ if(in_array($prod_tab['type'],array('product','core'))){
281
+ if($prod_tab['type'] == 'core'){
282
+ $template_data['orig_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
283
+ $template_data['orig_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
284
+ }else{
285
+ $template_data['orig_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
286
+ $template_data['orig_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
287
+ }
288
+
289
+ }
290
+ }
291
+
292
+ return include WCML_PLUGIN_PATH . '/compatibility/templates/wc_tab_manager_custom_box_html.php';
293
+ }
294
+
295
+ return $html;
296
+ }
297
+
298
+ function duplicate_product_tabs( $new_id, $original_post ){
299
+
300
+ wc_tab_manager_duplicate_product( $new_id, $original_post );
301
+
302
+ }
303
+
304
+ function force_set_language_information_on_product_tabs($post_id, $post){
305
+ global $sitepress;
306
+
307
+ if( $post->post_type == 'wc_product_tab' ){
308
+
309
+ $language = $sitepress->get_language_for_element($post->ID, 'post_wc_product_tab');
310
+ if( empty ($language) && $post->post_parent ) {
311
+ $parent_language = $sitepress->get_language_for_element($post->post_parent, 'post_product');
312
+ if( $parent_language ){
313
+ $sitepress->set_element_language_details($post->ID, 'post_wc_product_tab', null, $parent_language);
314
+ }
315
+ }
316
+
317
+ }
318
+
319
+ }
320
+
321
+ function append_custom_tabs_to_translation_package($package, $post){
322
+
323
+ if( $post->post_type == 'product' ) {
324
+
325
+ $override_tab_layout = get_post_meta( $post->ID , '_override_tab_layout', true);
326
+
327
+ if( $override_tab_layout == 'yes' ){
328
+
329
+ $meta = get_post_meta( $post->ID, '_product_tabs', true );
330
+
331
+ foreach ( (array)$meta as $key => $value ) {
332
+
333
+ if ( preg_match( '/product_tab_([0-9]+)/', $key, $matches ) ) {
334
+
335
+ $wc_product_tab_id = $matches[1];
336
+ $wc_product_tab = get_post( $wc_product_tab_id );
337
+
338
+ $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':title'] = array(
339
+ 'translate' => 1,
340
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_title, 'base64' ),
341
+ 'format' => 'base64'
342
+ );
343
+
344
+ $package['contents']['product_tabs:product_tab:' . $wc_product_tab_id . ':description'] = array(
345
+ 'translate' => 1,
346
+ 'data' => $this->tp->encode_field_data( $wc_product_tab->post_content, 'base64' ),
347
+ 'format' => 'base64'
348
+ );
349
+
350
+
351
+ } elseif ( preg_match( '/^core_tab_(.+)$/', $key, $matches ) ){
352
+
353
+ $package['contents']['product_tabs:core_tab_title:' . $matches[1]] = array(
354
+ 'translate' => 1,
355
+ 'data' => $this->tp->encode_field_data( $value['title'], 'base64' ),
356
+ 'format' => 'base64'
357
+ );
358
+
359
+ if(isset( $value['heading'] )) {
360
+ $package['contents']['product_tabs:core_tab_heading:' . $matches[1]] = array(
361
+ 'translate' => 1,
362
+ 'data' => $this->tp->encode_field_data( $value['heading'], 'base64' ),
363
+ 'format' => 'base64'
364
+ );
365
+ }
366
+
367
+
368
+ }
369
+
370
+ }
371
+ }
372
+
373
+
374
+ }
375
+
376
+ return $package;
377
+ }
378
+
379
+ function save_custom_tabs_translation( $post_id, $data, $job ){
380
+ global $sitepress;
381
+
382
+
383
+ $translated_product_tabs_updated = false;
384
+
385
+ $original_product_tabs = get_post_meta($job->original_doc_id, '_product_tabs', true);
386
+
387
+ if( $original_product_tabs ) {
388
+
389
+ // custom tabs
390
+ $product_tab_translations = array();
391
+
392
+ foreach ( $data as $value ) {
393
+
394
+ if ( preg_match( '/product_tabs:product_tab:([0-9]+):(.+)/', $value['field_type'], $matches ) ) {
395
+
396
+ $wc_product_tab_id = $matches[1];
397
+ $field = $matches[2];
398
+
399
+ $product_tab_translations[$wc_product_tab_id][$field] = $value['data'];
400
+ }
401
+
402
+ }
403
+
404
+ if ( $product_tab_translations ) {
405
+
406
+ $translated_product_tabs = get_post_meta( $post_id, '_product_tabs', true );
407
+
408
+ foreach ( $product_tab_translations as $wc_product_tab_id => $value ) {
409
+
410
+ $new_wc_product_tab = array(
411
+ 'post_type' => 'wp_product_tab',
412
+ 'post_title' => $value['title'],
413
+ 'post_content' => $value['description'],
414
+ 'post_status' => 'publish'
415
+ );
416
+
417
+ $wc_product_tab_id_translated = wp_insert_post( $new_wc_product_tab );
418
+
419
+ if ( $wc_product_tab_id_translated ) {
420
+
421
+ $wc_product_tab_trid = $sitepress->get_element_trid( $wc_product_tab_id, 'post_wc_product_tab' );
422
+ $sitepress->set_element_language_details( $wc_product_tab_id_translated, 'post_wc_product_tab', $wc_product_tab_trid, $job->language_code );
423
+
424
+ $wc_product_tab_translated = get_post( $wc_product_tab_id_translated );
425
+
426
+ $translated_product_tabs['product_tab_' . $wc_product_tab_id_translated] = array(
427
+
428
+ 'position' => $original_product_tabs['product_tab_' . $wc_product_tab_id]['position'],
429
+ 'type' => 'product',
430
+ 'id' => $wc_product_tab_id_translated,
431
+ 'name' => $wc_product_tab_translated->post_name
432
+
433
+ );
434
+
435
+ }
436
+
437
+ }
438
+
439
+
440
+ $translated_product_tabs_updated = true;
441
+ }
442
+
443
+ // the other tabs
444
+ $product_tab_translations = array();
445
+
446
+ foreach ( $data as $value ) {
447
+
448
+ if ( preg_match( '/product_tabs:core_tab_(.+):(.+)/', $value['field_type'], $matches ) ) {
449
+
450
+ $tab_field = $matches[1];
451
+ $tab_id = $matches[2];
452
+
453
+ $product_tab_translations[$tab_id][$tab_field] = $value['data'];
454
+
455
+ }
456
+
457
+ }
458
+
459
+ if( $product_tab_translations){
460
+ foreach( $product_tab_translations as $id => $tab ){
461
+
462
+ $translated_product_tabs['core_tab_' . $id] = array(
463
+ 'type' => 'core',
464
+ 'position' => $original_product_tabs['core_tab_' . $id]['position'],
465
+ 'id' => $id,
466
+ 'title' => $tab['title']
467
+ );
468
+
469
+ if( isset( $tab['heading'] ) ){
470
+ $translated_product_tabs['core_tab_' . $id]['heading'] = $tab['heading'];
471
+ }
472
+
473
+ }
474
+
475
+ $translated_product_tabs_updated = true;
476
+ }
477
+
478
+ if ( $translated_product_tabs_updated ) {
479
+ update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
480
+ }
481
+
482
+ }
483
+ }
484
+
485
+ }
compatibility/{wc_table_rate_shipping.class.php → class-wcml-table-rate-shipping.php} RENAMED
@@ -1,24 +1,24 @@
1
- <?php
2
-
3
- class WCML_Table_Rate_Shipping{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
- }
9
-
10
- function init(){
11
- global $pagenow;
12
-
13
- //register shipping label
14
- if($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page']=='shipping_zones' && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] )){
15
- do_action('wpml_register_single_string', 'woocommerce', $_POST['woocommerce_table_rate_title'] .'_shipping_method_title', $_POST['woocommerce_table_rate_title']);
16
- $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
17
- foreach($shipping_labels as $shipping_label){
18
- do_action('wpml_register_single_string', 'woocommerce', $shipping_label .'_shipping_method_title', $shipping_label);
19
- }
20
- }
21
-
22
- }
23
-
24
- }
1
+ <?php
2
+
3
+ class WCML_Table_Rate_Shipping{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'),9);
8
+ }
9
+
10
+ function init(){
11
+ global $pagenow;
12
+
13
+ //register shipping label
14
+ if($pagenow == 'admin.php' && isset($_GET['page']) && $_GET['page']=='shipping_zones' && isset( $_POST['shipping_label'] ) && isset( $_POST['woocommerce_table_rate_title'] )){
15
+ do_action('wpml_register_single_string', 'woocommerce', $_POST['woocommerce_table_rate_title'] .'_shipping_method_title', $_POST['woocommerce_table_rate_title']);
16
+ $shipping_labels = array_map( 'woocommerce_clean', $_POST['shipping_label'] );
17
+ foreach($shipping_labels as $shipping_label){
18
+ do_action('wpml_register_single_string', 'woocommerce', $shipping_label .'_shipping_method_title', $shipping_label);
19
+ }
20
+ }
21
+
22
+ }
23
+
24
+ }
compatibility/{wc_variation_swatches_photos.class.php → class-wcml-variation-swatches-and-photos.php} RENAMED
File without changes
compatibility/{wc_subscriptions.class.php → class-wcml-wc-subscriptions.php} RENAMED
@@ -1,36 +1,36 @@
1
- <?php
2
-
3
- class WCML_WC_Subscriptions{
4
-
5
- function __construct(){
6
-
7
- add_action('init', array($this, 'init'),9);
8
- add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
9
-
10
- }
11
-
12
- function init(){
13
- if(!is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.1', '<' )){
14
- add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
15
- }
16
- }
17
-
18
- function product_price_filter($subscription_sign_up_fee, $product){
19
-
20
- $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
21
-
22
- return $subscription_sign_up_fee;
23
- }
24
-
25
- function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
26
- global $wpdb;
27
- $get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'");
28
-
29
- if(!empty($get_variation_term_taxonomy_id)){
30
- $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
31
- }
32
-
33
- return $get_variation_term_taxonomy_ids;
34
- }
35
-
36
- }
1
+ <?php
2
+
3
+ class WCML_WC_Subscriptions{
4
+
5
+ function __construct(){
6
+
7
+ add_action('init', array($this, 'init'),9);
8
+ add_filter('wcml_variation_term_taxonomy_ids',array($this,'wcml_variation_term_taxonomy_ids'));
9
+
10
+ }
11
+
12
+ function init(){
13
+ if(!is_admin() && version_compare( WOOCOMMERCE_VERSION, '2.1', '<' )){
14
+ add_filter('woocommerce_subscriptions_product_sign_up_fee', array($this, 'product_price_filter'), 10, 2);
15
+ }
16
+ }
17
+
18
+ function product_price_filter($subscription_sign_up_fee, $product){
19
+
20
+ $subscription_sign_up_fee = apply_filters('wcml_raw_price_amount', $subscription_sign_up_fee );
21
+
22
+ return $subscription_sign_up_fee;
23
+ }
24
+
25
+ function wcml_variation_term_taxonomy_ids($get_variation_term_taxonomy_ids){
26
+ global $wpdb;
27
+ $get_variation_term_taxonomy_id = $wpdb->get_var("SELECT tt.term_taxonomy_id FROM $wpdb->terms AS t LEFT JOIN $wpdb->term_taxonomy AS tt ON t.term_id = tt.term_id WHERE t.slug = 'variable-subscription'");
28
+
29
+ if(!empty($get_variation_term_taxonomy_id)){
30
+ $get_variation_term_taxonomy_ids[] = $get_variation_term_taxonomy_id;
31
+ }
32
+
33
+ return $get_variation_term_taxonomy_ids;
34
+ }
35
+
36
+ }
compatibility/{wc_exporter.class.php → class-wcml-wcexporter.php} RENAMED
@@ -1,70 +1,70 @@
1
- <?php
2
-
3
- class WCML_wcExporter{
4
-
5
- function __construct(){
6
-
7
- add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
- add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
- add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
- add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
- add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
- add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
- add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
-
15
- }
16
-
17
- function woo_ce_fields($fields){
18
- $fields[] = array(
19
- 'name' => 'language',
20
- 'label' => __( 'Language', 'woo_ce' ),
21
- 'default' => 1
22
- );
23
- $fields[] = array(
24
- 'name' => 'translation_of',
25
- 'label' => __( 'Translation of', 'woo_ce' ),
26
- 'default' => 1
27
- );
28
- return $fields;
29
- }
30
-
31
- function woo_ce_order_fields($fields){
32
- $fields[] = array(
33
- 'name' => 'language',
34
- 'label' => __( 'Language', 'woo_ce' ),
35
- 'default' => 1
36
- );
37
-
38
- return $fields;
39
- }
40
-
41
- function woo_ce_product_item($data, $product_id){
42
- global $sitepress,$woocommerce_wpml;
43
-
44
- $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
- $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
-
47
- return $data;
48
- }
49
-
50
- function woo_ce_category_item($data){
51
- global $sitepress;
52
-
53
- $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
- $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
-
56
- return $data;
57
- }
58
-
59
- function woo_ce_tags($tags){
60
- global $sitepress;
61
-
62
- foreach($tags as $key=>$tag){
63
- $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
- $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
- }
66
-
67
- return $tags;
68
- }
69
-
70
- }
1
+ <?php
2
+
3
+ class WCML_wcExporter{
4
+
5
+ function __construct(){
6
+
7
+ add_filter('woo_ce_product_fields',array($this,'woo_ce_fields'));
8
+ add_filter('woo_ce_category_fields',array($this,'woo_ce_fields'));
9
+ add_filter('woo_ce_tag_fields',array($this,'woo_ce_fields'));
10
+ add_filter('woo_ce_order_fields',array($this,'woo_ce_order_fields'));
11
+ add_filter('woo_ce_product_item',array($this,'woo_ce_product_item'),10,2);
12
+ add_filter('woo_ce_category_item',array($this,'woo_ce_category_item'),10);
13
+ add_filter('woo_ce_tags',array($this,'woo_ce_tags'),10);
14
+
15
+ }
16
+
17
+ function woo_ce_fields($fields){
18
+ $fields[] = array(
19
+ 'name' => 'language',
20
+ 'label' => __( 'Language', 'woo_ce' ),
21
+ 'default' => 1
22
+ );
23
+ $fields[] = array(
24
+ 'name' => 'translation_of',
25
+ 'label' => __( 'Translation of', 'woo_ce' ),
26
+ 'default' => 1
27
+ );
28
+ return $fields;
29
+ }
30
+
31
+ function woo_ce_order_fields($fields){
32
+ $fields[] = array(
33
+ 'name' => 'language',
34
+ 'label' => __( 'Language', 'woo_ce' ),
35
+ 'default' => 1
36
+ );
37
+
38
+ return $fields;
39
+ }
40
+
41
+ function woo_ce_product_item($data, $product_id){
42
+ global $sitepress,$woocommerce_wpml;
43
+
44
+ $data->language = $sitepress->get_language_for_element($product_id,'post_'.get_post_type($product_id));
45
+ $data->translation_of = apply_filters( 'translate_object_id',$product_id,get_post_type($product_id),true, $woocommerce_wpml->products->get_original_product_language( $product_id ) );
46
+
47
+ return $data;
48
+ }
49
+
50
+ function woo_ce_category_item($data){
51
+ global $sitepress;
52
+
53
+ $data->language = $sitepress->get_language_for_element($data->term_taxonomy_id,'tax_product_cat');
54
+ $data->translation_of = apply_filters( 'translate_object_id',$data->term_taxonomy_id,'tax_product_cat',true,$sitepress->get_default_language());
55
+
56
+ return $data;
57
+ }
58
+
59
+ function woo_ce_tags($tags){
60
+ global $sitepress;
61
+
62
+ foreach($tags as $key=>$tag){
63
+ $tags[$key]->language = $sitepress->get_language_for_element($tag->term_taxonomy_id,'tax_product_tag');
64
+ $tags[$key]->translation_of = apply_filters( 'translate_object_id',$tag->term_taxonomy_id,'tax_product_tag',true,$sitepress->get_default_language());
65
+ }
66
+
67
+ return $tags;
68
+ }
69
+
70
+ }
compatibility/templates/wc_tab_manager_custom_box_html.php CHANGED
@@ -11,12 +11,12 @@
11
  <?php endif;?>
12
  <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[title][]'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo $template_data['original']?get_the_title($orig_tab_id):get_the_title($trnsl_tab_id); ?></textarea>
13
  <?php else: ?>
14
- <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_title]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo $template_data['tr_tabs'][$key]['title']; ?></textarea>
15
  <?php endif; ?>
16
  </td>
17
  <td>
18
  <?php if($values['type'] == 'core'): ?>
19
- <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_heading]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo $template_data['tr_tabs'][$key]['heading']; ?></textarea>
20
  <?php else: ?>
21
  <?php if($template_data['original']): ?>
22
  <button type="button" class="button-secondary wcml_edit_content origin_content"><?php _e('Show content', 'woocommerce-multilingual') ?></button>
11
  <?php endif;?>
12
  <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[title][]'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo $template_data['original']?get_the_title($orig_tab_id):get_the_title($trnsl_tab_id); ?></textarea>
13
  <?php else: ?>
14
+ <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_title]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo isset($template_data['tr_tabs'][$key]['title']) ? $template_data['tr_tabs'][$key]['title'] : ''; ?></textarea>
15
  <?php endif; ?>
16
  </td>
17
  <td>
18
  <?php if($values['type'] == 'core'): ?>
19
+ <textarea rows="1" <?php if(!$template_data['original']): ?>name="<?php echo $template_data['product_content'].'_'.$template_data['lang'].'[core_heading]['.$key.']'; ?>"<?php endif;?> <?php if($template_data['original']): ?> disabled="disabled"<?php endif;?>><?php echo isset($template_data['tr_tabs'][$key]['heading']) ? $template_data['tr_tabs'][$key]['heading'] : ''; ?></textarea>
20
  <?php else: ?>
21
  <?php if($template_data['original']): ?>
22
  <button type="button" class="button-secondary wcml_edit_content origin_content"><?php _e('Show content', 'woocommerce-multilingual') ?></button>
compatibility/templates/woocommerce-composite-products.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <td>
2
+ <button id="wc_composite_link_<?php echo $lang ?>" class="button-secondary js-table-toggle wc_composite_link<?php if($is_duplicate_product): ?> js-dup-disabled<?php endif;?>" data-text-opened="<?php _e('Collapse', 'woocommerce-multilingual'); ?>" data-text-closed="<?php _e('Expand', 'woocommerce-multilingual'); ?>"<?php if($is_duplicate_product): ?> disabled="disabled"<?php endif;?>>
3
+ <span><?php _e('Expand', 'woocommerce-multilingual'); ?></span>
4
+ <i class="icon-caret-down"></i>
5
+ </button>
6
+
7
+ <table id="prod_wc_composite_<?php echo $lang ?>" class="widefat prod_variations js-table">
8
+
9
+ <tbody>
10
+
11
+ <?php $disabled = $template_data['wc_composite_components']['_is_original'] ? ' disabled="disabled"' : ''; ?>
12
+ <?php foreach($template_data['wc_composite_components']['components'] as $key => $component): ?>
13
+ <tr>
14
+ <td>
15
+ <label><?php _e('Title', 'woocommerce-multilingual'); ?>&nbsp;
16
+ <textarea rows="1" name="wc_composite_component[<?php echo $key ?>][title]"<?php echo $disabled ?>><?php echo esc_attr( $component['title'] ) ?></textarea>
17
+ </label>
18
+ </td>
19
+ <td>
20
+ <label><?php _e('Description', 'woocommerce-multilingual'); ?>&nbsp;
21
+ <textarea rows="1" name="wc_composite_component[<?php echo $key ?>][description]"<?php echo $disabled ?>><?php echo esc_attr( $component['description'] ) ?></textarea>
22
+ </label>
23
+ </td>
24
+ </tr>
25
+ <?php endforeach ?>
26
+
27
+ </tbody>
28
+
29
+ </table>
30
+
31
+ </td>
32
+
33
+
34
+
35
+
compatibility/wc_composite_products.class.php DELETED
@@ -1,51 +0,0 @@
1
- <?php
2
-
3
-
4
- class WCML_Composite_Products {
5
- function __construct() {
6
- add_filter('woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3);
7
- add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
8
- add_filter( 'wcml_exception_duplicate_products_in_cart', array($this, 'wpml_composites_dupicate_exception'), 10, 2 );
9
- add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
10
- }
11
-
12
- function woocommerce_composite_component_default_option($selected_value, $component_id, $object) {
13
-
14
- if( !empty( $selected_value ) )
15
- $selected_value = apply_filters( 'wpml_object_id', $selected_value, 'product', true );
16
-
17
-
18
- return $selected_value;
19
- }
20
-
21
- function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
22
-
23
- if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
24
-
25
- $buff = $new_cart_data[ $new_key ];
26
-
27
- unset( $new_cart_data[ $new_key ] );
28
-
29
- $new_cart_data[ $key ] = $buff;
30
- }
31
-
32
- return $new_cart_data;
33
- }
34
-
35
- function wpml_composites_dupicate_exception( $exclude, $cart_item ) {
36
-
37
- if ( isset( $cart_item[ 'composite_parent' ] ) || isset( $cart_item[ 'composite_children' ] ) ) {
38
- $exclude = true;
39
- }
40
-
41
- return $exclude;
42
- }
43
-
44
- function wpml_composites_transients_cache_per_language( $args, $query_args, $component_data ) {
45
-
46
- $args[ 'wpml_lang' ] = apply_filters( 'wpml_current_language', NULL );
47
-
48
- return $args;
49
- }
50
-
51
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
compatibility/wc_tab_manager.class.php DELETED
@@ -1,279 +0,0 @@
1
- <?php
2
-
3
- class WCML_Tab_Manager{
4
-
5
- function __construct(){
6
- add_action( 'wcml_after_duplicate_product_post_meta', array( $this, 'sync_tabs' ), 10, 3 );
7
- add_filter( 'wcml_product_content_exception', array( $this, 'is_have_custom_product_tab' ), 10, 3 );
8
- add_filter( 'wcml_custom_box_html', array( $this, 'custom_box_html'), 10, 3 );
9
- add_filter( 'wpml_duplicate_custom_fields_exceptions', array( $this, 'duplicate_custom_fields_exceptions' ) );
10
- add_action( 'wcml_after_duplicate_product', array( $this, 'duplicate_product_tabs') , 10, 2 );
11
- }
12
-
13
- function sync_tabs( $original_product_id, $trnsl_product_id, $data = false ){
14
- global $wc_tab_manager, $sitepress, $woocommerce, $woocommerce_wpml;
15
-
16
- $lang = $sitepress->get_language_for_element( $trnsl_product_id, 'post_product' );
17
-
18
- //check if "duplicate" product
19
- if( ( isset( $_POST['icl_ajx_action'] ) && ( $_POST['icl_ajx_action'] == 'make_duplicates' ) ) || ( get_post_meta( $trnsl_product_id , '_icl_lang_duplicate_of', true ) ) ){
20
- $this->duplicate_tabs( $original_product_id, $trnsl_product_id, $lang );
21
- }
22
-
23
- if( !isset( $data[ '_product_tabs_'.$lang ] ) ){
24
- return;
25
- }
26
-
27
- $orig_prod_tabs = $wc_tab_manager->get_product_tabs( $original_product_id );
28
-
29
- if( $orig_prod_tabs ){
30
- $trnsl_product_tabs = array();
31
- $i = 0;
32
- foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
33
- switch( $orig_prod_tab[ 'type' ] ){
34
- case 'core':
35
- $default_language = $woocommerce_wpml->products->get_original_product_language( $original_product_id );
36
- $current_language = $sitepress->get_current_language();
37
- $trnsl_product_tabs[ $key ] = $orig_prod_tabs[ $key ];
38
- if( isset( $data[ '_product_tabs_'.$lang ] ) ){
39
- $title = $data[ '_product_tabs_'.$lang ][ 'core_title' ][ $orig_prod_tab[ 'id' ] ];
40
- $heading = $data[ '_product_tabs_'.$lang ][ 'core_heading' ][ $orig_prod_tab[ 'id' ] ];
41
- }
42
-
43
- if( $default_language != $lang ){
44
- $this->refresh_text_domain( $lang );
45
- if( !$title ) $title = $orig_prod_tabs[ $key ][ 'title' ];
46
- $title = __( $title, 'woocommerce' );
47
- if( !isset( $heading ) ){
48
- $heading = '';
49
- }elseif( !$heading && isset( $orig_prod_tabs[ $key ][ 'heading' ] ) ){
50
- $heading = $orig_prod_tabs[ $key ][ 'heading' ];
51
- }
52
- $heading = __( $heading, 'woocommerce' );
53
- $this->refresh_text_domain( $current_language );
54
- }
55
-
56
- $trnsl_product_tabs[ $key ][ 'title' ] = $title;
57
- $trnsl_product_tabs[ $key ][ 'heading' ] = $heading;
58
- break;
59
- case 'global':
60
- $trnsl_product_tabs = $this->set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang );
61
- break;
62
- case 'product':
63
- $tab_id = false;
64
- if( isset( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) ){
65
- if( get_post_type( $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ] ) == 'wc_product_tab' ){
66
- $tab_id = $data[ '_product_tabs_'.$lang ][ 'id' ][ $i ];
67
- }
68
- $title = $data[ '_product_tabs_'.$lang ][ 'title' ][ $i ];
69
- $content = $data[ '_product_tabs_'.$lang ][ 'content' ][ $i ];
70
- }
71
-
72
- $trnsl_product_tabs = $this->set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content );
73
-
74
- $i++;
75
- break;
76
- }
77
- }
78
- update_post_meta( $trnsl_product_id, '_product_tabs', $trnsl_product_tabs );
79
- }
80
- }
81
-
82
- function duplicate_tabs( $original_product_id, $trnsl_product_id, $lang ){
83
- global $sitepress;
84
- $orig_prod_tabs = maybe_unserialize( get_post_meta( $original_product_id, '_product_tabs', true ) );
85
- $prod_tabs = array();
86
- foreach( $orig_prod_tabs as $key => $orig_prod_tab ){
87
- switch( $orig_prod_tab[ 'type' ] ){
88
- case 'core':
89
- $prod_tabs[ $key ] = $orig_prod_tab;
90
- $this->refresh_text_domain( $lang );
91
- $prod_tabs[ $key ][ 'title' ] = __( $orig_prod_tab[ 'title' ], 'woocommerce' );
92
- if( isset( $orig_prod_tab[ 'heading' ] ) )
93
- $prod_tabs[ $key ][ 'heading' ] = __( $orig_prod_tab[ 'heading' ], 'woocommerce' );
94
- $orig_lang = $sitepress->get_language_for_element( $original_product_id, 'post_product' );
95
- $this->refresh_text_domain( $orig_lang );
96
- break;
97
- case 'global':
98
- $prod_tabs = $this->set_global_tab( $orig_prod_tab, $prod_tabs, $lang );
99
- break;
100
- case 'product':
101
- $original_tab = get_post( $orig_prod_tab[ 'id' ] );
102
- $prod_tabs = $this->set_product_tab( $orig_prod_tab, $prod_tabs, $lang, $trnsl_product_id, false, $original_tab->post_title , $original_tab->post_content );
103
- break;
104
- }
105
- }
106
-
107
- update_post_meta( $trnsl_product_id, '_product_tabs', $prod_tabs );
108
- }
109
-
110
- function refresh_text_domain( $lang ){
111
- global $sitepress, $woocommerce;
112
-
113
- unload_textdomain( 'woocommerce' );
114
- $sitepress->switch_lang( $lang );
115
- $woocommerce->load_plugin_textdomain();
116
- }
117
-
118
- function set_global_tab( $orig_prod_tab, $trnsl_product_tabs, $lang ){
119
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', true, $lang );
120
- $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tr_tab_id ] = array(
121
- 'position' => $orig_prod_tab[ 'position' ],
122
- 'type' => $orig_prod_tab[ 'type' ],
123
- 'id' => $tr_tab_id,
124
- 'name' => get_post( $tr_tab_id )->post_name
125
- );
126
- return $trnsl_product_tabs;
127
- }
128
-
129
- function set_product_tab( $orig_prod_tab, $trnsl_product_tabs, $lang, $trnsl_product_id, $tab_id, $title, $content ){
130
- global $wpdb, $sitepress;
131
-
132
- if( !$tab_id ){
133
- $tr_tab_id = apply_filters( 'translate_object_id', $orig_prod_tab[ 'id' ], 'wc_product_tab', false, $lang );
134
-
135
- if( !is_null( $tr_tab_id ) ){
136
- $tab_id = $tr_tab_id;
137
- }
138
- }
139
-
140
- if( $tab_id ){
141
- //update existing tab
142
- $args = array();
143
- $args[ 'post_title' ] = $title;
144
- $args[ 'post_content' ] = $content;
145
- $wpdb->update( $wpdb->posts, $args, array( 'ID' => $tab_id ) );
146
- }else{
147
- //tab not exist creating new
148
- $args = array();
149
- $args[ 'post_title' ] = $title;
150
- $args[ 'post_content' ] = $content;
151
- $args[ 'post_author' ] = get_current_user_id();
152
- $args[ 'post_name' ] = sanitize_title( $title );
153
- $args[ 'post_type' ] = 'wc_product_tab';
154
- $args[ 'post_parent' ] = $trnsl_product_id;
155
- $args[ 'post_status' ] = 'publish';
156
- $wpdb->insert( $wpdb->posts, $args );
157
-
158
- $tab_id = $wpdb->insert_id;
159
- $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
160
- if( !$tab_trid ){
161
- $sitepress->set_element_language_details( $orig_prod_tab[ 'id' ], 'post_wc_product_tab', false, $sitepress->get_default_language() );
162
- $tab_trid = $sitepress->get_element_trid( $orig_prod_tab[ 'id' ], 'post_wc_product_tab' );
163
- }
164
- $sitepress->set_element_language_details( $tab_id, 'post_wc_product_tab', $tab_trid, $lang );
165
- }
166
-
167
- $trnsl_product_tabs[ $orig_prod_tab[ 'type' ].'_tab_'.$tab_id ] = array(
168
- 'position' => $orig_prod_tab[ 'position' ],
169
- 'type' => $orig_prod_tab[ 'type' ],
170
- 'id' => $tab_id,
171
- 'name' => get_post( $tab_id )->post_name
172
- );
173
-
174
- return $trnsl_product_tabs;
175
- }
176
-
177
- function duplicate_custom_fields_exceptions( $exceptions ){
178
- $exceptions[] = '_product_tabs';
179
- return $exceptions;
180
- }
181
-
182
- function is_have_custom_product_tab($exception,$product_id,$meta_key){
183
- if( $meta_key == '_product_tabs'){
184
- $prod_tabs = maybe_unserialize(get_post_meta($product_id,'_product_tabs',true));
185
- foreach($prod_tabs as $prod_tab){
186
- if(in_array($prod_tab['type'],array('product','core'))){
187
- $exception = false;
188
- break;
189
- }
190
- }
191
- }
192
-
193
- return $exception;
194
- }
195
-
196
-
197
- function custom_box_html($html,$template_data,$lang){
198
- if($template_data['product_content'] == '_product_tabs'){
199
- global $wc_tab_manager;
200
- $orig_prod_tabs = $wc_tab_manager->get_product_tabs($template_data['product_id']);
201
- if(!$orig_prod_tabs) return '';
202
- if($template_data['tr_product_id']){
203
- $tr_prod_tabs = $wc_tab_manager->get_product_tabs($template_data['tr_product_id']);
204
-
205
- if(!is_array($tr_prod_tabs)){
206
- return __('Please update original product', 'woocommerce-multilingual');
207
- }
208
-
209
- foreach($tr_prod_tabs as $key=>$prod_tab){
210
- if(in_array($prod_tab['type'],array('product','core'))){
211
- if($prod_tab['type'] == 'core'){
212
- $template_data['tr_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
213
- $template_data['tr_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
214
- $template_data['tr_tabs'][$prod_tab['id']]['title'] = $prod_tab['title'];
215
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = isset ($prod_tab['heading']) ? $prod_tab['heading'] : '';
216
- }else{
217
- $template_data['tr_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
218
- $template_data['tr_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
219
- }
220
- }
221
- }
222
- }else{
223
- global $sitepress,$woocommerce;
224
- $current_language = $sitepress->get_current_language();
225
- foreach($orig_prod_tabs as $key=>$prod_tab){
226
- if($prod_tab['type'] == 'core'){
227
- unload_textdomain('woocommerce');
228
- $sitepress->switch_lang($lang);
229
- $woocommerce->load_plugin_textdomain();
230
- $title = __( $prod_tab['title'], 'woocommerce' );
231
- if($prod_tab['title'] != $title){
232
- $template_data['tr_tabs'][$prod_tab['id']]['title'] = $title;
233
-
234
- }
235
-
236
- if(!isset($prod_tab['heading'])){
237
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = '';
238
- }else{
239
- $heading = __( $prod_tab['heading'], 'woocommerce' );
240
- if($prod_tab['heading'] != $heading){
241
- $template_data['tr_tabs'][$prod_tab['id']]['heading'] = $heading;
242
- }
243
- }
244
-
245
- unload_textdomain('woocommerce');
246
- $sitepress->switch_lang($current_language);
247
- $woocommerce->load_plugin_textdomain();
248
- }
249
- }
250
- }
251
-
252
- foreach($orig_prod_tabs as $key=>$prod_tab){
253
- if(in_array($prod_tab['type'],array('product','core'))){
254
- if($prod_tab['type'] == 'core'){
255
- $template_data['orig_tabs'][$prod_tab['id']]['id'] = $prod_tab['id'];
256
- $template_data['orig_tabs'][$prod_tab['id']]['type'] = $prod_tab['type'];
257
- }else{
258
- $template_data['orig_tabs'][$prod_tab['position']]['id'] = $prod_tab['id'];
259
- $template_data['orig_tabs'][$prod_tab['position']]['type'] = $prod_tab['type'];
260
- }
261
-
262
- }
263
- }
264
-
265
-
266
-
267
- return include WCML_PLUGIN_PATH . '/compatibility/templates/wc_tab_manager_custom_box_html.php';
268
- }
269
-
270
- return $html;
271
- }
272
-
273
- function duplicate_product_tabs( $new_id, $original_post ){
274
-
275
- wc_tab_manager_duplicate_product( $new_id, $original_post );
276
-
277
- }
278
-
279
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
inc/class-wcml-tp-support.php ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class WCML_TP_Support{
4
+
5
+ public $tp;
6
+
7
+ function __construct(){
8
+
9
+ $this->tp = new WPML_Element_Translation_Package;
10
+
11
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_custom_attributes_to_translation_package' ), 10, 2 );
12
+ add_action( 'wpml_translation_job_saved', array( $this, 'save_custom_attribute_translations' ), 10, 2 );
13
+
14
+ add_filter( 'wpml_tm_translation_job_data', array( $this, 'append_variation_descriptions_translation_package' ), 10, 2 );
15
+ add_action( 'wpml_pro_translation_completed', array( $this, 'save_variation_descriptions_translations' ), 20, 3 ); //after WCML_Products
16
+ }
17
+
18
+
19
+ function append_custom_attributes_to_translation_package( $package, $post ){
20
+
21
+ $product = wc_get_product( $post->ID );
22
+
23
+ if( !empty($product) && $product->get_type() == 'variable' ){
24
+
25
+ $attributes = $product->get_attributes();
26
+
27
+ foreach( $attributes as $attribute_key => $attribute ){
28
+ if( !$attribute['is_taxonomy'] ){
29
+
30
+ $package['contents']['wc_attribute_name:' . $attribute_key] = array(
31
+ 'translate' => 1,
32
+ 'data' => $this->tp->encode_field_data( $attribute['name'], 'base64' ),
33
+ 'format' => 'base64'
34
+ );
35
+
36
+ $values = explode( '|', $attribute['value'] );
37
+ $values = array_map('trim', $values);
38
+
39
+ foreach( $values as $value_key => $value ){
40
+
41
+ $package['contents']['wc_attribute_value:' . $value_key . ':' . $attribute_key] = array(
42
+ 'translate' => 1,
43
+ 'data' => $this->tp->encode_field_data( $value, 'base64' ),
44
+ 'format' => 'base64'
45
+ );
46
+
47
+ }
48
+
49
+ }
50
+ }
51
+
52
+ }
53
+
54
+ return $package;
55
+ }
56
+
57
+ function save_custom_attribute_translations($post_id, $data){
58
+ global $woocommerce_wpml;
59
+
60
+ $translated_attributes = array();
61
+
62
+ foreach( $data as $data_key => $value){
63
+
64
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_attribute_' ) === 0 ){
65
+
66
+ if( strpos( $value['field_type'], 'wc_attribute_name:' ) === 0 ){
67
+
68
+ $exp = explode( ':', $value['field_type'], 2 );
69
+ $attribute_key = $exp[1];
70
+
71
+ $translated_attributes[$attribute_key]['name'] = $value['data'];
72
+
73
+ } else if( strpos( $value['field_type'], 'wc_attribute_value:' ) === 0 ){
74
+
75
+ $exp = explode( ':', $value['field_type'], 3 );
76
+ $value_key = $exp[1];
77
+ $attribute_key = $exp[2];
78
+
79
+ $translated_attributes[$attribute_key]['values'][$value_key] = $value['data'];
80
+
81
+ }
82
+
83
+ }
84
+
85
+ }
86
+
87
+ if( $translated_attributes ) {
88
+
89
+ $product_attributes = get_post_meta( $post_id, '_product_attributes', true );
90
+
91
+ $original_post_language = $woocommerce_wpml->products->get_original_product_language( $post_id );
92
+ $original_post_id = apply_filters( 'translate_object_id', $post_id, 'product', false, $original_post_language );
93
+
94
+ $original_attributes = get_post_meta( $original_post_id, '_product_attributes', true );
95
+
96
+ foreach ( $translated_attributes as $attribute_key => $attribute ) {
97
+
98
+ $product_attributes[$attribute_key] = array(
99
+ 'name' => $attribute['name'],
100
+ 'value' => join( ' | ', $attribute['values'] ),
101
+ 'is_taxonomy' => 0,
102
+ 'is_visible' => $original_attributes[$attribute_key]['is_visible'],
103
+ 'position' => $original_attributes[$attribute_key]['position']
104
+ );
105
+
106
+
107
+ }
108
+
109
+ update_post_meta( $post_id, '_product_attributes', $product_attributes );
110
+
111
+ }
112
+
113
+ }
114
+
115
+ function append_variation_descriptions_translation_package($package, $post){
116
+
117
+ $product = wc_get_product( $post->ID );
118
+
119
+ if( !empty($product) && $product->get_type() == 'variable' ) {
120
+
121
+ $variations = $product->get_available_variations();
122
+
123
+ foreach( $variations as $variation ){
124
+
125
+ if( !empty($variation['variation_description']) ){
126
+
127
+ $package['contents']['wc_variation_description:' . $variation['variation_id']] = array(
128
+ 'translate' => 1,
129
+ 'data' => $this->tp->encode_field_data( $variation['variation_description'], 'base64' ),
130
+ 'format' => 'base64'
131
+ );
132
+
133
+ }
134
+
135
+ }
136
+
137
+
138
+ }
139
+
140
+ return $package;
141
+
142
+ }
143
+
144
+ function save_variation_descriptions_translations($post_id, $data, $job){
145
+
146
+ $language = $job->language_code;
147
+
148
+ foreach( $data as $data_key => $value){
149
+
150
+ if( $value['finished'] && strpos( $value['field_type'], 'wc_variation_description:' ) === 0 ){
151
+
152
+ $variation_id = substr( $value['field_type'], strpos($value['field_type'], ':') + 1 );
153
+
154
+ if( is_post_type_translated( 'product_variation' ) ){
155
+
156
+ $translated_variation_id = apply_filters( 'translate_object_id', $variation_id, 'product_variation', false, $language );
157
+
158
+ }else{
159
+ global $sitepress;
160
+ $trid = $sitepress->get_element_trid($variation_id, 'post_product_variation');
161
+ $translations = $sitepress->get_element_translations($trid, 'post_product_variation', true, true, true);
162
+
163
+ $translated_variation_id = isset( $translations[$language] ) ? $translations[$language]->element_id : false;
164
+
165
+ }
166
+
167
+ if($translated_variation_id){
168
+ update_post_meta($translated_variation_id, '_variation_description', $value['data'] );
169
+ }
170
+
171
+
172
+ }
173
+
174
+ }
175
+
176
+ }
177
+ }
inc/compatibility.class.php CHANGED
@@ -4,98 +4,88 @@ class WCML_Compatibility {
4
 
5
  function __construct(){
6
 
 
 
 
 
7
  $this->init();
8
 
9
  }
10
 
11
  function init(){
 
12
  //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
13
 
14
  //WooCommerce Tab Manager plugin
15
  if(class_exists('WC_Tab_Manager')){
16
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_tab_manager.class.php';
17
  $this->tab_manager = new WCML_Tab_Manager();
18
  }
19
 
20
  //WooCommerce Table Rate Shipping plugin
21
  if(defined('TABLE_RATE_SHIPPING_VERSION')){
22
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_table_rate_shipping.class.php';
23
  $this->table_rate_shipping = new WCML_Table_Rate_Shipping();
24
  }
25
 
26
  //WooCommerce Subscriptions
27
  if(class_exists('WC_Subscriptions')){
28
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_subscriptions.class.php';
29
  $this->wp_subscriptions = new WCML_WC_Subscriptions();
30
  }
31
 
32
  //Product Bundle
33
  if(class_exists('WC_Product_Bundle')){
34
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_product_bundles.class.php';
35
  $this->product_bundles = new WCML_Product_Bundles();
36
  }
37
 
38
  // WooCommerce Variation Swatches and Photos
39
  if(class_exists('WC_SwatchesPlugin')){
40
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_variation_swatches_photos.class.php';
41
  $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
42
  }
43
 
44
  // Product Add-ons
45
  if(class_exists( 'Product_Addon_Display' )){
46
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_product_addons.class.php';
47
  $this->product_addons = new WCML_Product_Addons();
48
  }
49
 
50
  // Product Per Product Shipping
51
  if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
52
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_per_product_shipping.class.php';
53
  new WCML_Per_Product_Shipping();
54
  }
55
  //Store Exporter plugin
56
  if(defined('WOO_CE_PATH')){
57
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_exporter.class.php';
58
  $this->wc_exporter = new WCML_wcExporter();
59
  }
60
 
61
  //Gravity Forms
62
  if(class_exists('GFForms')){
63
- require_once WCML_PLUGIN_PATH . '/compatibility/gravityforms.class.php';
64
  $this->gravityforms = new WCML_gravityforms();
65
  }
66
 
67
  //Sensei WooThemes
68
  if(class_exists('WooThemes_Sensei')){
69
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_sensei.class.php';
70
  $this->sensei = new WCML_sensei();
71
  }
72
 
73
  //Extra Product Options
74
  if(class_exists('TM_Extra_Product_Options')){
75
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_extra_product_options.class.php';
76
  $this->extra_product_options = new WCML_Extra_Product_Options();
77
  }
78
 
79
  // Dynamic Pricing
80
  if(class_exists( 'WC_Dynamic_Pricing' )){
81
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_dynamic_pricing.class.php';
82
  $this->dynamic_pricing = new WCML_Dynamic_Pricing();
83
  }
84
 
85
  // WooCommerce Bookings
86
  if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
87
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_bookings.class.php';
88
  $this->bookings = new WCML_Bookings();
89
  }
90
 
91
  // WooCommerce Checkout Field Editor
92
  if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
93
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_checkout_field_editor.class.php';
94
  $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
95
  }
96
 
97
  if (class_exists('WC_Bulk_Stock_Management')) {
98
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_bulk_stock_management.class.php';
99
  $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
100
  }
101
 
@@ -108,16 +98,27 @@ class WCML_Compatibility {
108
 
109
  // woocommerce composite products
110
  if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
111
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_composite_products.class.php';
112
  $this->wc_composite_products = new WCML_Composite_Products();
113
  }
114
 
115
  // woocommerce checkout addons
116
  if (function_exists('init_woocommerce_checkout_add_ons')) {
117
- require_once WCML_PLUGIN_PATH . '/compatibility/wc_checkout_addons.class.php';
118
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
119
  }
120
 
121
  }
122
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
4
 
5
  function __construct(){
6
 
7
+ spl_autoload_register( array( $this, 'autoload' ) );
8
+
9
+ $this->include_path = WCML_PLUGIN_PATH . '/compatibility/';
10
+
11
  $this->init();
12
 
13
  }
14
 
15
  function init(){
16
+
17
  //hardcoded list of extensions and check which ones the user has and then include the corresponding file from the ‘compatibility’ folder
18
 
19
  //WooCommerce Tab Manager plugin
20
  if(class_exists('WC_Tab_Manager')){
 
21
  $this->tab_manager = new WCML_Tab_Manager();
22
  }
23
 
24
  //WooCommerce Table Rate Shipping plugin
25
  if(defined('TABLE_RATE_SHIPPING_VERSION')){
 
26
  $this->table_rate_shipping = new WCML_Table_Rate_Shipping();
27
  }
28
 
29
  //WooCommerce Subscriptions
30
  if(class_exists('WC_Subscriptions')){
 
31
  $this->wp_subscriptions = new WCML_WC_Subscriptions();
32
  }
33
 
34
  //Product Bundle
35
  if(class_exists('WC_Product_Bundle')){
 
36
  $this->product_bundles = new WCML_Product_Bundles();
37
  }
38
 
39
  // WooCommerce Variation Swatches and Photos
40
  if(class_exists('WC_SwatchesPlugin')){
 
41
  $this->variation_sp = new WCML_Variation_Swatches_and_Photos();
42
  }
43
 
44
  // Product Add-ons
45
  if(class_exists( 'Product_Addon_Display' )){
 
46
  $this->product_addons = new WCML_Product_Addons();
47
  }
48
 
49
  // Product Per Product Shipping
50
  if(defined( 'PER_PRODUCT_SHIPPING_VERSION' )){
 
51
  new WCML_Per_Product_Shipping();
52
  }
53
  //Store Exporter plugin
54
  if(defined('WOO_CE_PATH')){
 
55
  $this->wc_exporter = new WCML_wcExporter();
56
  }
57
 
58
  //Gravity Forms
59
  if(class_exists('GFForms')){
 
60
  $this->gravityforms = new WCML_gravityforms();
61
  }
62
 
63
  //Sensei WooThemes
64
  if(class_exists('WooThemes_Sensei')){
 
65
  $this->sensei = new WCML_sensei();
66
  }
67
 
68
  //Extra Product Options
69
  if(class_exists('TM_Extra_Product_Options')){
 
70
  $this->extra_product_options = new WCML_Extra_Product_Options();
71
  }
72
 
73
  // Dynamic Pricing
74
  if(class_exists( 'WC_Dynamic_Pricing' )){
 
75
  $this->dynamic_pricing = new WCML_Dynamic_Pricing();
76
  }
77
 
78
  // WooCommerce Bookings
79
  if(defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.7.8', '>=') ){
 
80
  $this->bookings = new WCML_Bookings();
81
  }
82
 
83
  // WooCommerce Checkout Field Editor
84
  if ( function_exists( 'woocommerce_init_checkout_field_editor' ) ) {
 
85
  $this->checkout_field_editor = new WCML_Checkout_Field_Editor();
86
  }
87
 
88
  if (class_exists('WC_Bulk_Stock_Management')) {
 
89
  $this->wc_bulk_stock_management = new WCML_Bulk_Stock_Management();
90
  }
91
 
98
 
99
  // woocommerce composite products
100
  if ( isset( $GLOBALS[ 'woocommerce_composite_products' ] ) ) {
 
101
  $this->wc_composite_products = new WCML_Composite_Products();
102
  }
103
 
104
  // woocommerce checkout addons
105
  if (function_exists('init_woocommerce_checkout_add_ons')) {
 
106
  $this->wc_checkout_addons = new WCML_Checkout_Addons();
107
  }
108
 
109
  }
110
 
111
+ function autoload( $class ){
112
+
113
+ $class = strtolower( $class );
114
+ $file = 'class-' . str_replace( '_', '-', $class ) . '.php';
115
+ $path = $this->include_path . $file;
116
+
117
+ if ( $path && is_readable( $path ) ) {
118
+ include_once( $path );
119
+ return true;
120
+ }
121
+
122
+ }
123
+
124
  }
inc/multi-currency-support.class.php CHANGED
@@ -45,8 +45,6 @@ class WCML_Multi_Currency_Support{
45
 
46
  add_action( 'update_option_woocommerce_currency', array( $this, 'set_default_currencies_languages' ), 10, 2 );
47
 
48
-
49
-
50
  }
51
 
52
  function _load_filters(){
@@ -125,6 +123,8 @@ class WCML_Multi_Currency_Support{
125
  }
126
 
127
  if(!is_admin()) $this->load_inline_js();
 
 
128
 
129
  }
130
 
@@ -1091,10 +1091,23 @@ class WCML_Multi_Currency_Support{
1091
  isset($woocommerce_wpml->settings['display_custom_prices']) &&
1092
  $woocommerce_wpml->settings['display_custom_prices'] ){
1093
 
1094
- $current_product_id = wc_get_product()->id;
 
1095
  $original_product_language = $woocommerce_wpml->products->get_original_product_language( $current_product_id );
 
1096
 
1097
- if( !get_post_meta( apply_filters( 'translate_object_id', $current_product_id , get_post_type( $current_product_id ), true, $original_product_language ), '_wcml_custom_prices_status', true ) ){
 
 
 
 
 
 
 
 
 
 
 
1098
  $this->client_currency = get_option('woocommerce_currency');
1099
  }
1100
 
@@ -1424,6 +1437,27 @@ class WCML_Multi_Currency_Support{
1424
 
1425
  return $cart_subtotal;
1426
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1427
 
1428
  }
1429
 
45
 
46
  add_action( 'update_option_woocommerce_currency', array( $this, 'set_default_currencies_languages' ), 10, 2 );
47
 
 
 
48
  }
49
 
50
  function _load_filters(){
123
  }
124
 
125
  if(!is_admin()) $this->load_inline_js();
126
+
127
+ add_action( 'woocommerce_get_children', array( $this, 'filter_product_variations_with_custom_prices' ), 10 );
128
 
129
  }
130
 
1091
  isset($woocommerce_wpml->settings['display_custom_prices']) &&
1092
  $woocommerce_wpml->settings['display_custom_prices'] ){
1093
 
1094
+ $product_obj = wc_get_product();
1095
+ $current_product_id = $product_obj->id;
1096
  $original_product_language = $woocommerce_wpml->products->get_original_product_language( $current_product_id );
1097
+ $default = false;
1098
 
1099
+ if( $product_obj->is_type( 'variable' ) ){
1100
+ foreach( $product_obj->get_children() as $child ){
1101
+ if( !get_post_meta( apply_filters( 'translate_object_id', $child , get_post_type( $child ), true, $original_product_language ), '_wcml_custom_prices_status', true ) ){
1102
+ $default = true;
1103
+ break;
1104
+ }
1105
+ }
1106
+ }elseif( !get_post_meta( apply_filters( 'translate_object_id', $current_product_id , get_post_type( $current_product_id ), true, $original_product_language ), '_wcml_custom_prices_status', true ) ){
1107
+ $default = true;
1108
+ }
1109
+
1110
+ if( $default ){
1111
  $this->client_currency = get_option('woocommerce_currency');
1112
  }
1113
 
1437
 
1438
  return $cart_subtotal;
1439
  }
1440
+
1441
+ //display variations with custom prices when "Show only products with custom prices in secondary currencies" enabled
1442
+ function filter_product_variations_with_custom_prices( $children ){
1443
+ global $woocommerce_wpml;
1444
+
1445
+ if( is_product() && $woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
1446
+ isset($woocommerce_wpml->settings['display_custom_prices']) &&
1447
+ $woocommerce_wpml->settings['display_custom_prices'] ){
1448
+
1449
+ foreach( $children as $key => $child ){
1450
+ if( !get_post_meta( $child, '_wcml_custom_prices_status', true ) ){
1451
+ unset( $children[ $key ] );
1452
+ }
1453
+ }
1454
+
1455
+
1456
+ }
1457
+
1458
+ return $children;
1459
+
1460
+ }
1461
 
1462
  }
1463
 
inc/products.class.php CHANGED
@@ -6,15 +6,18 @@ class WCML_Products{
6
  private $tinymce_plugins_for_rtl = '';
7
  private $yoast_seo_fields = array( '_yoast_wpseo_focuskw', '_yoast_wpseo_title', '_yoast_wpseo_metadesc' );
8
 
 
 
9
  function __construct(){
10
 
11
  add_action( 'init', array( $this, 'init' ) );
12
- add_action( 'init', array( $this, 'wc_cart_widget_actions' ) );
13
 
14
  //add action for coupons data from WC_Coupon construct
15
  add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
16
 
17
  add_action( 'init', array( $this, 'set_prices_config' ), 9999 ); // After TM
 
18
  }
19
 
20
  function init(){
@@ -46,9 +49,9 @@ class WCML_Products{
46
 
47
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
48
  add_filter( 'tiny_mce_before_init', array( $this, '_mce_set_plugins' ), 9 );
49
-
50
  add_action( 'admin_head', array( $this, 'hide_multilingual_content_setup_box' ) );
51
-
52
  add_action( 'woocommerce_duplicate_product', array( $this, 'woocommerce_duplicate_product' ), 10, 2 );
53
 
54
  add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
@@ -58,6 +61,9 @@ class WCML_Products{
58
  add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
59
 
60
  add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
 
 
 
61
  }else{
62
  add_filter('woocommerce_json_search_found_products', array($this, 'filter_found_products_by_language'));
63
  add_filter( 'loop_shop_post_in', array( $this, 'filter_products_with_custom_prices' ), 100 );
@@ -68,7 +74,7 @@ class WCML_Products{
68
  add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
69
  add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
70
  add_filter( 'wpml_link_to_translation', array( $this, '_filter_link_to_translation' ), 100 );
71
-
72
  add_filter( 'woocommerce_upsell_crosssell_search_products', array( $this, 'filter_woocommerce_upsell_crosssell_posts_by_language' ) );
73
 
74
  add_filter( 'icl_post_alternative_languages', array( $this, 'hide_post_translation_links' ) );
@@ -108,7 +114,11 @@ class WCML_Products{
108
  add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
109
 
110
  if(defined('WPSEO_VERSION') && defined('WPSEO_PATH') && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'products'){
111
- require_once WPSEO_PATH . 'admin/class-metabox.php';
 
 
 
 
112
  }
113
 
114
  // Override cached widget id
@@ -194,7 +204,7 @@ class WCML_Products{
194
  $top_level_products[] = $product->ID;
195
  }else{
196
  $children_products[$product->post_parent][] = $product->ID;
197
- }
198
  }
199
 
200
  $count = 0;
@@ -322,7 +332,7 @@ class WCML_Products{
322
  $sql = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->posts AS p";
323
 
324
  if($category){
325
- $sql .= " LEFT JOIN $wpdb->term_relationships AS tx ON tx.object_id = p.id";
326
  }
327
 
328
  $sql .= " LEFT JOIN {$wpdb->prefix}icl_translations AS t ON t.element_id = p.id";
@@ -344,7 +354,7 @@ class WCML_Products{
344
 
345
  $sql .= " LEFT JOIN {$wpdb->prefix}icl_translation_status iclts_{$tbl_alias_suffix}
346
  ON iclts_{$tbl_alias_suffix}.translation_id=iclt_{$tbl_alias_suffix}.translation_id\n";
347
- }
348
  }
349
 
350
  $sql .= " WHERE p.post_title LIKE '%s' AND p.post_type = 'product' AND t.element_type = 'post_product' AND t.source_language_code IS NULL";
@@ -469,7 +479,11 @@ class WCML_Products{
469
  $args['comment_status'] = $orig_product->comment_status;
470
  $product_parent = apply_filters( 'translate_object_id',$orig_product->post_parent, 'product', false, $language);
471
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
 
 
472
  $_POST['to_lang'] = $language;
 
 
473
 
474
  if($woocommerce_wpml->settings['products_sync_date']){
475
  $args['post_date'] = $orig_product->post_date;
@@ -525,7 +539,9 @@ class WCML_Products{
525
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
526
  $_POST['to_lang'] = $language;
527
 
 
528
  wp_update_post($args);
 
529
 
530
  $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM {$wpdb->posts} WHERE ID=%d", $tr_product_id ));
531
  if(isset( $data['post_name_' . $language]) && $post_name != $data['post_name_' . $language]){
@@ -544,6 +560,9 @@ class WCML_Products{
544
 
545
  }
546
 
 
 
 
547
  do_action( 'wcml_update_extra_fields', $tr_product_id, $data, $language );
548
 
549
  do_action( 'wcml_before_sync_product_data', $original_product_id, $tr_product_id, $language );
@@ -564,9 +583,6 @@ class WCML_Products{
564
  $this->sync_product_gallery($original_product_id);
565
  }
566
 
567
- //sync taxonomies
568
- $this->sync_product_taxonomies($original_product_id, $tr_product_id, $language);
569
-
570
  // synchronize post variations
571
  $this->sync_product_variations($original_product_id, $tr_product_id, $language, $data);
572
 
@@ -611,7 +627,7 @@ class WCML_Products{
611
  ob_start();
612
  $this->product_variations_box($tr_product_id,$language);
613
  $return['variations'][$language] = ob_get_clean();
614
- }
615
 
616
  // no longer a duplicate
617
  if(!empty($data['end_duplication'][$original_product_id][$language])){
@@ -631,6 +647,7 @@ class WCML_Products{
631
  //get "_product_attributes" from original product
632
  $orig_product_attrs = $this->get_product_atributes( $original_product_id );
633
  $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
 
634
  $trnsl_labels = get_post_meta( $tr_product_id, 'attr_label_translations', true );
635
 
636
  foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
@@ -654,7 +671,12 @@ class WCML_Products{
654
  $orig_product_attrs[ $key_to_save ][ 'value' ] = '';
655
  }
656
  }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
657
- $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
 
 
 
 
 
658
  }
659
 
660
  }
@@ -745,7 +767,9 @@ class WCML_Products{
745
  $terms_array = array_unique( array_map( 'intval', $terms_array ) );
746
  }
747
 
 
748
  wp_set_post_terms($tr_product_id, $terms_array, $taxonomy);
 
749
 
750
  }
751
  }
@@ -774,7 +798,7 @@ class WCML_Products{
774
  }
775
 
776
  foreach ($all_meta as $key => $meta) {
777
- if(isset($settings['translation-management']['custom_fields_translation'][$key]) && $settings['translation-management']['custom_fields_translation'][$key] == 0){
778
  continue;
779
  }
780
  foreach ($meta as $meta_value) {
@@ -803,47 +827,47 @@ class WCML_Products{
803
  }
804
 
805
  if(isset($data['regular_price_'.$lang]) && isset($data['sale_price_'.$lang]) && $product_type == 'variable'){
806
- switch($key){
807
- case '_min_variation_sale_price':
808
- $meta_value = count(array_filter($data['sale_price_'.$lang]))?min(array_filter($data['sale_price_'.$lang])):'';
809
- break;
810
- case '_max_variation_sale_price':
811
- $meta_value = count(array_filter($data['sale_price_'.$lang]))?max(array_filter($data['sale_price_'.$lang])):'';
812
- break;
813
- case '_min_variation_regular_price':
814
- $meta_value = count(array_filter($data['regular_price_'.$lang]))?min(array_filter($data['regular_price_'.$lang])):'';
815
- break;
816
- case '_max_variation_regular_price':
817
- $meta_value = count(array_filter($data['regular_price_'.$lang]))?max(array_filter($data['regular_price_'.$lang])):'';
818
- break;
819
- case '_min_variation_price':
820
- if(count(array_filter($data['sale_price_'.$lang])) && min(array_filter($data['sale_price_'.$lang]))<min(array_filter($data['regular_price_'.$lang]))){
821
- $meta_value = min(array_filter($data['sale_price_'.$lang]));
822
- }elseif(count(array_filter($data['regular_price_'.$lang]))){
823
- $meta_value = min(array_filter($data['regular_price_'.$lang]));
824
- }else{
825
- $meta_value = '';
826
- }
827
- break;
828
- case '_max_variation_price':
829
- if(count(array_filter($data['sale_price_'.$lang])) && max(array_filter($data['sale_price_'.$lang]))>max(array_filter($data['regular_price_'.$lang]))){
830
- $meta_value = max(array_filter($data['sale_price_'.$lang]));
831
- }elseif(count(array_filter($data['regular_price_'.$lang]))){
832
- $meta_value = max(array_filter($data['regular_price_'.$lang]));
833
- }else{
834
- $meta_value = '';
835
- }
836
- break;
837
- case '_price':
838
- if(count(array_filter($data['sale_price_'.$lang])) && min(array_filter($data['sale_price_'.$lang]))<min(array_filter($data['regular_price_'.$lang]))){
839
- $meta_value = min(array_filter($data['sale_price_'.$lang]));
840
- }elseif(count(array_filter($data['regular_price_'.$lang]))){
841
- $meta_value = min(array_filter($data['regular_price_'.$lang]));
842
- }else{
843
- $meta_value = '';
844
- }
845
- break;
846
- }
847
 
848
  }else{
849
  if($key == '_price' && isset($data['sale_price_'.$lang]) && isset($data['regular_price_'.$lang])){
@@ -929,19 +953,19 @@ class WCML_Products{
929
 
930
  if (isset($product_translations[$language['code']])) {
931
  $tr_status = $wpdb->get_row($wpdb->prepare("SELECT status,needs_update FROM " . $wpdb->prefix . "icl_translation_status WHERE translation_id = %d", $product_translations[$language['code']]->translation_id));
932
- if(!$tr_status){
933
- $alt = __('Not translated', 'woocommerce-multilingual');
934
- echo '<i title="'. $alt .'" class="stat_img icon-warning-sign"></i>';
935
- }elseif($tr_status->needs_update){
936
- $alt = __('Not translated - needs update', 'woocommerce-multilingual');
937
- echo '<i title="'. $alt .'" class="stat_img icon-repeat"></i>';
938
- }elseif($tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE) {
939
- $alt = __('In progress', 'woocommerce-multilingual');
940
- echo '<i title="'. $alt .'" class="stat_img icon-spinner"></i>';
941
- }elseif($tr_status->status == ICL_TM_COMPLETE || $tr_status->status == ICL_TM_DUPLICATE){
942
- $alt = __('Complete', 'woocommerce-multilingual');
943
- echo '<i title="'. $alt .'" class="stat_img icon-ok"></i>';
944
- }
945
  } else {
946
  $alt = __('Not translated', 'woocommerce-multilingual');
947
  echo '<i title="'. $alt .'" class="stat_img icon-warning-sign"></i>';
@@ -1039,7 +1063,7 @@ class WCML_Products{
1039
  'post_type' => $post_data->post_type,
1040
  'post_mime_type' => $post_data->post_mime_type,
1041
  'comment_count' => $post_data->comment_count
1042
- ));
1043
  add_post_meta($variation_id, '_wcml_duplicate_of_variation', $post_data->ID);
1044
 
1045
  $sitepress->set_element_language_details($variation_id, 'post_product_variation', $trid, $lang);
@@ -1242,9 +1266,9 @@ class WCML_Products{
1242
  $original_cross_sells = maybe_unserialize( get_post_meta( $product_id, '_crosssell_ids', true ) );
1243
  $trnsl_cross_sells = array();
1244
  if( $original_cross_sells )
1245
- foreach( $original_cross_sells as $original_cross_sell_product ){
1246
- $trnsl_cross_sells[] = apply_filters( 'translate_object_id', $original_cross_sell_product, get_post_type( $original_cross_sell_product ), false, $lang );
1247
- }
1248
  update_post_meta( $tr_product_id, '_crosssell_ids', $trnsl_cross_sells );
1249
 
1250
  //sync grouped products
@@ -1345,7 +1369,7 @@ class WCML_Products{
1345
  $message .= '</p></div>';
1346
 
1347
  echo $message;
1348
- }
1349
 
1350
  //product quickedit
1351
  function filter_product_actions( $actions, $post ){
@@ -1480,17 +1504,17 @@ class WCML_Products{
1480
 
1481
  $_product = wc_get_product($translation->element_id);
1482
 
1483
- if ( $_product && $_product->exists() && $_product->managing_stock() ) {
1484
 
1485
- $total_sales = get_post_meta($_product->id, 'total_sales', true);
1486
 
1487
- if( $action == 'reduce'){
1488
- $stock = $_product->reduce_stock($item['qty']);
1489
- $total_sales += $item['qty'];
1490
- }else{
1491
- $stock = $_product->increase_stock( $item['qty'] );
1492
- $total_sales -= $item['qty'];
1493
- }
1494
  update_post_meta($translation->element_id, 'total_sales', $total_sales);
1495
  }
1496
  }
@@ -1502,10 +1526,10 @@ class WCML_Products{
1502
 
1503
  function sanitize_cpa_values($values) {
1504
  // Text based, separate by pipe
1505
- $values = explode('|', esc_html(stripslashes($values)));
1506
- $values = array_map('trim', $values);
1507
- $values = implode('|', $values);
1508
- return $values;
1509
  }
1510
 
1511
  /**
@@ -1561,7 +1585,7 @@ class WCML_Products{
1561
  if (!$woocommerce_wpml->settings['trnsl_interface'] && $original_language != $current_language ) {
1562
 
1563
  if( !isset( $_POST[ 'wp-preview' ] ) || empty( $_POST[ 'wp-preview' ] ) ){
1564
- $this->sync_status_and_parent( $duplicated_post_id, $post_id, $current_language );
1565
  $this->sync_product_data( $duplicated_post_id, $post_id, $current_language );
1566
  }
1567
 
@@ -1606,7 +1630,7 @@ class WCML_Products{
1606
  $this->sync_thumbnail_id( $duplicated_post_id, $post_id, $lang );
1607
  }
1608
 
1609
- $this->sync_status_and_parent( $duplicated_post_id, $post_id, $lang );
1610
 
1611
  $this->sync_product_taxonomies( $duplicated_post_id, $post_id, $lang );
1612
 
@@ -1709,16 +1733,15 @@ class WCML_Products{
1709
  }
1710
 
1711
  //sync product parent & post_status
1712
- function sync_status_and_parent( $duplicated_post_id, $post_id, $lang ){
1713
  global $wpdb,$woocommerce_wpml;
1714
 
1715
  $tr_parent_id = apply_filters( 'translate_object_id', wp_get_post_parent_id( $duplicated_post_id ), 'product', false, $lang );
1716
 
1717
  $orig_product = get_post( $duplicated_post_id );
 
1718
  $args = array();
1719
  $args[ 'post_parent' ] = is_null( $tr_parent_id )? 0 : $tr_parent_id;
1720
- $args[ 'post_status' ] = $orig_product->post_status;
1721
- $args[ 'comment_status' ] = $orig_product->comment_status;
1722
 
1723
  //sync product date
1724
  if( $woocommerce_wpml->settings[ 'products_sync_date' ] ){
@@ -1992,38 +2015,52 @@ class WCML_Products{
1992
 
1993
  global $sitepress,$wpseo_metabox;
1994
  $settings = $sitepress->get_settings();
1995
- foreach(get_post_custom_keys($product_id) as $meta_key){
 
 
 
 
 
 
1996
  if(isset($settings['translation-management']['custom_fields_translation'][$meta_key]) && $settings['translation-management']['custom_fields_translation'][$meta_key] == 2){
1997
- if(in_array($meta_key,$this->not_display_fields_for_variables_product)){
1998
- continue;
1999
- }
2000
 
2001
- if($this->check_custom_field_is_single_value($product_id,$meta_key)){
2002
- if(defined('WPSEO_VERSION')){
2003
- if(!is_null($wpseo_metabox) && in_array($meta_key,$this->yoast_seo_fields)){
2004
- $wpseo_metabox_values = $wpseo_metabox->get_meta_boxes('product');
2005
- $contents[] = $wpseo_metabox_values[str_replace('_yoast_wpseo_','',$meta_key)]['title'];
2006
- continue;
2007
- }
2008
- }
2009
- }else{
2010
- $exception = apply_filters('wcml_product_content_exception',true,$product_id,$meta_key);
2011
- if($exception){
 
 
2012
  continue;
2013
  }
2014
-
2015
  }
2016
-
2017
- $custom_key_label = apply_filters( 'wcml_product_content_label', $meta_key, $product_id );
2018
- if( $custom_key_label != $meta_key ){
2019
- $contents[] = $custom_key_label;
2020
  continue;
2021
  }
2022
 
2023
- $custom_key_label = str_replace('_',' ',$meta_key);
2024
- $contents[] = trim($custom_key_label[0]) ? ucfirst($custom_key_label) : ucfirst(substr($custom_key_label,1));
2025
 
 
 
 
 
2026
  }
 
 
 
 
 
2027
  }
2028
 
2029
  return apply_filters('wcml_product_content_fields_label', $contents, $product_id);
@@ -2031,7 +2068,7 @@ class WCML_Products{
2031
 
2032
  function check_custom_field_is_single_value($product_id,$meta_key){
2033
 
2034
- $meta_value = maybe_unserialize( get_post_meta( $product_id, $meta_key, true ) );
2035
  if(is_array($meta_value)){
2036
  return false;
2037
  }else{
@@ -2203,7 +2240,7 @@ class WCML_Products{
2203
  $is_product_has_variations = $wpdb->get_var($wpdb->prepare("SELECT count(id) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation'",$product_id));
2204
 
2205
  foreach ($template_data['all_file_paths'] as $key => $price) {
2206
- $template_data['all_variations_ids'][] = $key;
2207
  }
2208
 
2209
  if (!$is_product_has_variations){
@@ -2261,7 +2298,8 @@ class WCML_Products{
2261
  include WCML_PLUGIN_PATH . '/menu/sub/images-box.php';
2262
  }
2263
 
2264
- function custom_box($product_id,$product_content,$trn_contents,$lang,$lang_name,$is_duplicate_product){
 
2265
  global $sitepress;
2266
  $original_language = $sitepress->get_language_for_element($product_id,'post_product');
2267
  $tr_product_id = apply_filters( 'translate_object_id',$product_id, 'product', false, $lang);
@@ -2404,14 +2442,14 @@ class WCML_Products{
2404
  $variations = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value = %s",'attribute_'.$taxonomy,$original_slug));
2405
 
2406
  foreach($variations as $variation){
2407
- //update taxonomy in translation of variation
2408
- $trnsl_variation_id = apply_filters( 'translate_object_id',$variation->post_id,'product_variation',false,$language);
2409
- if(!is_null($trnsl_variation_id)){
2410
- if(!$slug){
2411
- $slug = sanitize_title($name);
2412
- }
2413
  update_post_meta($trnsl_variation_id,'attribute_'.$taxonomy,$slug);
2414
- }
2415
  }
2416
  }
2417
 
@@ -2534,7 +2572,7 @@ class WCML_Products{
2534
  if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
2535
  && ( ( !$parent && $sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
2536
  || ( $parent && $sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
2537
- )
2538
  ||
2539
  ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
2540
  && ( ( !$parent && $this->is_original_product($post) )
@@ -2621,9 +2659,9 @@ class WCML_Products{
2621
  $taxonomy = substr($attr_key, 10, strlen($attr_key)-1 );
2622
  }
2623
  $cart->cart_contents[$key]['variation'][$attr_key] = $this->get_cart_attribute_translation($taxonomy,$attribute,$cart_item['product_id'],$tr_product_id,$current_language);
 
2624
  }
2625
  }
2626
- }
2627
  }else{
2628
  if(!is_null($tr_product_id)){
2629
  $cart->cart_contents[$key]['product_id'] = intval($tr_product_id);
@@ -2663,14 +2701,7 @@ class WCML_Products{
2663
  continue;
2664
  }
2665
 
2666
- if( empty( $cart_content[ 'variation_id' ] ) ){
2667
- $search_key = $cart_content[ 'product_id' ];
2668
- }else{
2669
- $search_key = $cart_content[ 'product_id' ].'_'.$cart_content['variation_id'];
2670
- foreach( $cart_content['variation'] as $var_key => $value ){
2671
- $search_key .= '_'.$var_key.'-'.$value;
2672
- }
2673
- }
2674
 
2675
  if( array_key_exists( $search_key, $exists_products ) ){
2676
  unset( $cart_contents[ $key ] );
@@ -2721,7 +2752,7 @@ class WCML_Products{
2721
  $unserialized_orig_product_attributes = maybe_unserialize($orig_product_attributes);
2722
  foreach($unserialized_orig_product_attributes as $orig_attr_key => $orig_product_attribute){
2723
  $orig_attr_key = urldecode($orig_attr_key);
2724
- if( strtolower($taxonomy) == $orig_attr_key){
2725
  $values = explode('|',$orig_product_attribute['value']);
2726
  foreach($values as $key_id => $value){
2727
  if(trim($value," ") == $attribute){
@@ -2736,7 +2767,7 @@ class WCML_Products{
2736
  $taxonomy = sanitize_title($taxonomy);
2737
  $trnsl_attr_values = explode('|',$unserialized_trnsl_product_attributes[$taxonomy]['value']);
2738
 
2739
- if(isset($attr_key_id) && isset($trnsl_attr_values[$attr_key_id])){
2740
  return trim($trnsl_attr_values[$attr_key_id]);
2741
  }
2742
 
@@ -2796,86 +2827,86 @@ class WCML_Products{
2796
  }
2797
 
2798
 
2799
- function set_taxonomies_config( $config_all ) {
2800
  global $woocommerce_wpml;
2801
 
2802
  $all_products_taxonomies = get_taxonomies( array( 'object_type' => array( 'product' ) ), 'objects' );
2803
 
2804
- foreach($all_products_taxonomies as $tax_key => $tax) {
2805
- if($tax_key == 'product_type' ) continue;
2806
-
2807
- $found = false;
2808
 
2809
- foreach( $config_all['wpml-config']['taxonomies']['taxonomy'] as $key => $taxonomy ){
2810
 
2811
- if( $tax_key == $taxonomy['value'] ){
2812
- $config_all['wpml-config']['taxonomies']['taxonomy'][$key]['attr']['translate'] = 1;
2813
- $found = true;
2814
- }
2815
 
 
 
 
2816
  }
2817
 
2818
- if( !$found ){
2819
- $config_all['wpml-config']['taxonomies']['taxonomy'][] = array( 'value' => $tax_key, 'attr' => array( 'translate' => 1 ) );
2820
- }
 
 
2821
 
2822
  }
2823
 
2824
- return $config_all;
2825
- }
2826
 
2827
 
2828
- function set_prices_config(){
2829
- global $sitepress, $iclTranslationManagement, $sitepress_settings, $woocommerce_wpml;
2830
 
2831
- $wpml_settings = $sitepress->get_settings();
2832
 
2833
- if (!isset($wpml_settings['translation-management']) || !isset($iclTranslationManagement) || !( $iclTranslationManagement instanceof TranslationManagement) ) {
2834
- return;
2835
- }
2836
 
2837
- $keys = array(
2838
- '_regular_price',
2839
- '_sale_price',
2840
- '_price',
2841
- '_min_variation_regular_price',
2842
- '_min_variation_sale_price',
2843
- '_min_variation_price',
2844
- '_max_variation_regular_price',
2845
- '_max_variation_sale_price',
2846
- '_max_variation_price',
2847
- '_sale_price_dates_from',
2848
- '_sale_price_dates_to',
2849
- '_wcml_schedule'
2850
- );
2851
 
2852
- $save = false;
2853
 
2854
- foreach ($keys as $key) {
2855
- $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $key;
2856
- if (!isset($sitepress_settings['translation-management']['custom_fields_translation'][$key]) ||
2857
- $wpml_settings['translation-management']['custom_fields_translation'][$key] != 1) {
2858
- $wpml_settings['translation-management']['custom_fields_translation'][$key] = 1;
2859
- $save = true;
2860
- }
2861
 
2862
- if(!empty($woocommerce_wpml->multi_currency_support)){
2863
- foreach($woocommerce_wpml->multi_currency_support->get_currency_codes() as $code){
2864
- $new_key = $key.'_'.$code;
2865
- $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $new_key;
2866
- if (!isset($sitepress_settings['translation-management']['custom_fields_translation'][$new_key]) ||
2867
- $wpml_settings['translation-management']['custom_fields_translation'][$new_key] != 0) {
2868
- $wpml_settings['translation-management']['custom_fields_translation'][$new_key] = 0;
2869
- $save = true;
2870
- }
2871
- }
2872
- }
2873
 
2874
- }
2875
 
2876
- if ($save) {
2877
- $sitepress->save_settings($wpml_settings);
2878
- }
2879
  }
2880
 
2881
  function woocommerce_duplicate_product($new_id, $post){
@@ -2967,7 +2998,7 @@ class WCML_Products{
2967
  }
2968
 
2969
  return $widget_id;
2970
- }
2971
 
2972
 
2973
  //update menu_order fro translations after ordering original products
@@ -3000,9 +3031,9 @@ class WCML_Products{
3000
  $menu_order = $wpdb->get_var($wpdb->prepare("SELECT menu_order FROM $wpdb->posts WHERE ID = %d", $product_id ) );
3001
 
3002
  $trid = $sitepress->get_element_trid($product_id, 'post_product');
3003
- $translations = $sitepress->get_element_translations($trid, 'post_product');
3004
 
3005
- foreach ($translations as $translation) {
3006
 
3007
  if ($translation->element_id != $product_id) {
3008
  $wpdb->update( $wpdb->posts, array('menu_order' => $menu_order), array('ID' => $translation->element_id));
@@ -3020,20 +3051,20 @@ class WCML_Products{
3020
  $elements[ 'excerpt' ] ['editor_type'] = 'editor';
3021
  }
3022
 
3023
- if ( function_exists( 'format_for_editor' ) ) {
3024
- // WordPress 4.3 uses format_for_editor
3025
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(format_for_editor($elements[ 'excerpt' ] ['value'], $_POST[ 'excerpt_type']));
3026
  } else {
3027
- // Backwards compatible for WordPress < 4.3
3028
  if($_POST[ 'excerpt_type'] == 'rich'){
3029
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(wp_richedit_pre($elements[ 'excerpt' ] ['value']));
3030
  }else{
3031
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(wp_htmledit_pre($elements[ 'excerpt' ] ['value']));
3032
  }
3033
  }
3034
-
3035
- return $elements;
3036
- }
3037
 
3038
 
3039
  function product_data_html(){
6
  private $tinymce_plugins_for_rtl = '';
7
  private $yoast_seo_fields = array( '_yoast_wpseo_focuskw', '_yoast_wpseo_title', '_yoast_wpseo_metadesc' );
8
 
9
+ public $tp_support;
10
+
11
  function __construct(){
12
 
13
  add_action( 'init', array( $this, 'init' ) );
14
+ add_action( 'init', array( $this, 'wc_cart_widget_actions' ) );
15
 
16
  //add action for coupons data from WC_Coupon construct
17
  add_action( 'woocommerce_coupon_loaded', array( $this, 'wcml_coupon_loaded' ) );
18
 
19
  add_action( 'init', array( $this, 'set_prices_config' ), 9999 ); // After TM
20
+
21
  }
22
 
23
  function init(){
49
 
50
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
51
  add_filter( 'tiny_mce_before_init', array( $this, '_mce_set_plugins' ), 9 );
52
+
53
  add_action( 'admin_head', array( $this, 'hide_multilingual_content_setup_box' ) );
54
+
55
  add_action( 'woocommerce_duplicate_product', array( $this, 'woocommerce_duplicate_product' ), 10, 2 );
56
 
57
  add_filter( 'post_row_actions', array( $this, 'filter_product_actions' ), 10, 2 );
61
  add_filter( 'wpml_translation_job_post_meta_value_translated', array($this, 'filter_product_attributes_for_translation'), 10, 2 );
62
 
63
  add_action( 'wp_ajax_woocommerce_feature_product' , array( $this, 'sync_feature_product_meta' ), 9 );
64
+
65
+ $this->tp_support = new WCML_TP_Support();
66
+
67
  }else{
68
  add_filter('woocommerce_json_search_found_products', array($this, 'filter_found_products_by_language'));
69
  add_filter( 'loop_shop_post_in', array( $this, 'filter_products_with_custom_prices' ), 100 );
74
  add_action( 'wp_ajax_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
75
  add_action( 'wp_ajax_nopriv_woocommerce_update_shipping_method', array( $this, 'wcml_refresh_text_domain' ), 9 );
76
  add_filter( 'wpml_link_to_translation', array( $this, '_filter_link_to_translation' ), 100 );
77
+
78
  add_filter( 'woocommerce_upsell_crosssell_search_products', array( $this, 'filter_woocommerce_upsell_crosssell_posts_by_language' ) );
79
 
80
  add_filter( 'icl_post_alternative_languages', array( $this, 'hide_post_translation_links' ) );
114
  add_action( 'woocommerce_before_checkout_process', array( $this, 'wcml_refresh_cart_total' ) );
115
 
116
  if(defined('WPSEO_VERSION') && defined('WPSEO_PATH') && isset($_GET['page']) && $_GET['page'] == 'wpml-wcml' && isset($_GET['tab']) && $_GET['tab'] == 'products'){
117
+ if(version_compare(WPSEO_VERSION, '3', '<' )) {
118
+ require_once WPSEO_PATH . 'admin/class-metabox.php';
119
+ } elseif( file_exists( WPSEO_PATH . 'admin/metabox/class-metabox.php' ) ) {
120
+ require_once WPSEO_PATH . 'admin/metabox/class-metabox.php';
121
+ }
122
  }
123
 
124
  // Override cached widget id
204
  $top_level_products[] = $product->ID;
205
  }else{
206
  $children_products[$product->post_parent][] = $product->ID;
207
+ }
208
  }
209
 
210
  $count = 0;
332
  $sql = "SELECT SQL_CALC_FOUND_ROWS * FROM $wpdb->posts AS p";
333
 
334
  if($category){
335
+ $sql .= " LEFT JOIN $wpdb->term_relationships AS tx ON tx.object_id = p.id";
336
  }
337
 
338
  $sql .= " LEFT JOIN {$wpdb->prefix}icl_translations AS t ON t.element_id = p.id";
354
 
355
  $sql .= " LEFT JOIN {$wpdb->prefix}icl_translation_status iclts_{$tbl_alias_suffix}
356
  ON iclts_{$tbl_alias_suffix}.translation_id=iclt_{$tbl_alias_suffix}.translation_id\n";
357
+ }
358
  }
359
 
360
  $sql .= " WHERE p.post_title LIKE '%s' AND p.post_type = 'product' AND t.element_type = 'post_product' AND t.source_language_code IS NULL";
479
  $args['comment_status'] = $orig_product->comment_status;
480
  $product_parent = apply_filters( 'translate_object_id',$orig_product->post_parent, 'product', false, $language);
481
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
482
+
483
+ //TODO: remove after change required WPML version > 3.3
484
  $_POST['to_lang'] = $language;
485
+ // for WPML > 3.3
486
+ $_POST['icl_post_language'] = $language;
487
 
488
  if($woocommerce_wpml->settings['products_sync_date']){
489
  $args['post_date'] = $orig_product->post_date;
539
  $args['post_parent'] = is_null($product_parent) ? 0 : $product_parent;
540
  $_POST['to_lang'] = $language;
541
 
542
+ $sitepress->switch_lang( $language );
543
  wp_update_post($args);
544
+ $sitepress->switch_lang();
545
 
546
  $post_name = $wpdb->get_var( $wpdb->prepare( "SELECT post_name FROM {$wpdb->posts} WHERE ID=%d", $tr_product_id ));
547
  if(isset( $data['post_name_' . $language]) && $post_name != $data['post_name_' . $language]){
560
 
561
  }
562
 
563
+ //sync taxonomies
564
+ $this->sync_product_taxonomies($original_product_id, $tr_product_id, $language);
565
+
566
  do_action( 'wcml_update_extra_fields', $tr_product_id, $data, $language );
567
 
568
  do_action( 'wcml_before_sync_product_data', $original_product_id, $tr_product_id, $language );
583
  $this->sync_product_gallery($original_product_id);
584
  }
585
 
 
 
 
586
  // synchronize post variations
587
  $this->sync_product_variations($original_product_id, $tr_product_id, $language, $data);
588
 
627
  ob_start();
628
  $this->product_variations_box($tr_product_id,$language);
629
  $return['variations'][$language] = ob_get_clean();
630
+ }
631
 
632
  // no longer a duplicate
633
  if(!empty($data['end_duplication'][$original_product_id][$language])){
647
  //get "_product_attributes" from original product
648
  $orig_product_attrs = $this->get_product_atributes( $original_product_id );
649
  $trnsl_product_attrs = $this->get_product_atributes( $tr_product_id );
650
+
651
  $trnsl_labels = get_post_meta( $tr_product_id, 'attr_label_translations', true );
652
 
653
  foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
671
  $orig_product_attrs[ $key_to_save ][ 'value' ] = '';
672
  }
673
  }elseif( !$orig_product_attr[ 'is_taxonomy' ] ){
674
+
675
+ if( isset( $trnsl_product_attrs[ $key ] ) ){
676
+ $orig_product_attrs[ $key_to_save ][ 'value' ] = $trnsl_product_attrs[ $key ][ 'value' ];
677
+ }else{
678
+ unset ( $orig_product_attrs[ $key_to_save ] );
679
+ }
680
  }
681
 
682
  }
767
  $terms_array = array_unique( array_map( 'intval', $terms_array ) );
768
  }
769
 
770
+ $sitepress->switch_lang( $lang );
771
  wp_set_post_terms($tr_product_id, $terms_array, $taxonomy);
772
+ $sitepress->switch_lang();
773
 
774
  }
775
  }
798
  }
799
 
800
  foreach ($all_meta as $key => $meta) {
801
+ if( !isset($settings['translation-management']['custom_fields_translation'][$key]) || $settings['translation-management']['custom_fields_translation'][$key] == 0 ){
802
  continue;
803
  }
804
  foreach ($meta as $meta_value) {
827
  }
828
 
829
  if(isset($data['regular_price_'.$lang]) && isset($data['sale_price_'.$lang]) && $product_type == 'variable'){
830
+ switch($key){
831
+ case '_min_variation_sale_price':
832
+ $meta_value = count(array_filter($data['sale_price_'.$lang]))?min(array_filter($data['sale_price_'.$lang])):'';
833
+ break;
834
+ case '_max_variation_sale_price':
835
+ $meta_value = count(array_filter($data['sale_price_'.$lang]))?max(array_filter($data['sale_price_'.$lang])):'';
836
+ break;
837
+ case '_min_variation_regular_price':
838
+ $meta_value = count(array_filter($data['regular_price_'.$lang]))?min(array_filter($data['regular_price_'.$lang])):'';
839
+ break;
840
+ case '_max_variation_regular_price':
841
+ $meta_value = count(array_filter($data['regular_price_'.$lang]))?max(array_filter($data['regular_price_'.$lang])):'';
842
+ break;
843
+ case '_min_variation_price':
844
+ if(count(array_filter($data['sale_price_'.$lang])) && min(array_filter($data['sale_price_'.$lang]))<min(array_filter($data['regular_price_'.$lang]))){
845
+ $meta_value = min(array_filter($data['sale_price_'.$lang]));
846
+ }elseif(count(array_filter($data['regular_price_'.$lang]))){
847
+ $meta_value = min(array_filter($data['regular_price_'.$lang]));
848
+ }else{
849
+ $meta_value = '';
850
+ }
851
+ break;
852
+ case '_max_variation_price':
853
+ if(count(array_filter($data['sale_price_'.$lang])) && max(array_filter($data['sale_price_'.$lang]))>max(array_filter($data['regular_price_'.$lang]))){
854
+ $meta_value = max(array_filter($data['sale_price_'.$lang]));
855
+ }elseif(count(array_filter($data['regular_price_'.$lang]))){
856
+ $meta_value = max(array_filter($data['regular_price_'.$lang]));
857
+ }else{
858
+ $meta_value = '';
859
+ }
860
+ break;
861
+ case '_price':
862
+ if(count(array_filter($data['sale_price_'.$lang])) && min(array_filter($data['sale_price_'.$lang]))<min(array_filter($data['regular_price_'.$lang]))){
863
+ $meta_value = min(array_filter($data['sale_price_'.$lang]));
864
+ }elseif(count(array_filter($data['regular_price_'.$lang]))){
865
+ $meta_value = min(array_filter($data['regular_price_'.$lang]));
866
+ }else{
867
+ $meta_value = '';
868
+ }
869
+ break;
870
+ }
871
 
872
  }else{
873
  if($key == '_price' && isset($data['sale_price_'.$lang]) && isset($data['regular_price_'.$lang])){
953
 
954
  if (isset($product_translations[$language['code']])) {
955
  $tr_status = $wpdb->get_row($wpdb->prepare("SELECT status,needs_update FROM " . $wpdb->prefix . "icl_translation_status WHERE translation_id = %d", $product_translations[$language['code']]->translation_id));
956
+ if(!$tr_status){
957
+ $alt = __('Not translated', 'woocommerce-multilingual');
958
+ echo '<i title="'. $alt .'" class="stat_img icon-warning-sign"></i>';
959
+ }elseif($tr_status->needs_update){
960
+ $alt = __('Not translated - needs update', 'woocommerce-multilingual');
961
+ echo '<i title="'. $alt .'" class="stat_img icon-repeat"></i>';
962
+ }elseif($tr_status->status != ICL_TM_COMPLETE && $tr_status->status != ICL_TM_DUPLICATE) {
963
+ $alt = __('In progress', 'woocommerce-multilingual');
964
+ echo '<i title="'. $alt .'" class="stat_img icon-spinner"></i>';
965
+ }elseif($tr_status->status == ICL_TM_COMPLETE || $tr_status->status == ICL_TM_DUPLICATE){
966
+ $alt = __('Complete', 'woocommerce-multilingual');
967
+ echo '<i title="'. $alt .'" class="stat_img icon-ok"></i>';
968
+ }
969
  } else {
970
  $alt = __('Not translated', 'woocommerce-multilingual');
971
  echo '<i title="'. $alt .'" class="stat_img icon-warning-sign"></i>';
1063
  'post_type' => $post_data->post_type,
1064
  'post_mime_type' => $post_data->post_mime_type,
1065
  'comment_count' => $post_data->comment_count
1066
+ ));
1067
  add_post_meta($variation_id, '_wcml_duplicate_of_variation', $post_data->ID);
1068
 
1069
  $sitepress->set_element_language_details($variation_id, 'post_product_variation', $trid, $lang);
1266
  $original_cross_sells = maybe_unserialize( get_post_meta( $product_id, '_crosssell_ids', true ) );
1267
  $trnsl_cross_sells = array();
1268
  if( $original_cross_sells )
1269
+ foreach( $original_cross_sells as $original_cross_sell_product ){
1270
+ $trnsl_cross_sells[] = apply_filters( 'translate_object_id', $original_cross_sell_product, get_post_type( $original_cross_sell_product ), false, $lang );
1271
+ }
1272
  update_post_meta( $tr_product_id, '_crosssell_ids', $trnsl_cross_sells );
1273
 
1274
  //sync grouped products
1369
  $message .= '</p></div>';
1370
 
1371
  echo $message;
1372
+ }
1373
 
1374
  //product quickedit
1375
  function filter_product_actions( $actions, $post ){
1504
 
1505
  $_product = wc_get_product($translation->element_id);
1506
 
1507
+ if ( $_product && $_product->exists() && $_product->managing_stock() ) {
1508
 
1509
+ $total_sales = get_post_meta($_product->id, 'total_sales', true);
1510
 
1511
+ if( $action == 'reduce'){
1512
+ $stock = $_product->reduce_stock($item['qty']);
1513
+ $total_sales += $item['qty'];
1514
+ }else{
1515
+ $stock = $_product->increase_stock( $item['qty'] );
1516
+ $total_sales -= $item['qty'];
1517
+ }
1518
  update_post_meta($translation->element_id, 'total_sales', $total_sales);
1519
  }
1520
  }
1526
 
1527
  function sanitize_cpa_values($values) {
1528
  // Text based, separate by pipe
1529
+ $values = explode('|', esc_html(stripslashes($values)));
1530
+ $values = array_map('trim', $values);
1531
+ $values = implode('|', $values);
1532
+ return $values;
1533
  }
1534
 
1535
  /**
1585
  if (!$woocommerce_wpml->settings['trnsl_interface'] && $original_language != $current_language ) {
1586
 
1587
  if( !isset( $_POST[ 'wp-preview' ] ) || empty( $_POST[ 'wp-preview' ] ) ){
1588
+ $this->sync_date_and_parent( $duplicated_post_id, $post_id, $current_language );
1589
  $this->sync_product_data( $duplicated_post_id, $post_id, $current_language );
1590
  }
1591
 
1630
  $this->sync_thumbnail_id( $duplicated_post_id, $post_id, $lang );
1631
  }
1632
 
1633
+ $this->sync_date_and_parent( $duplicated_post_id, $post_id, $lang );
1634
 
1635
  $this->sync_product_taxonomies( $duplicated_post_id, $post_id, $lang );
1636
 
1733
  }
1734
 
1735
  //sync product parent & post_status
1736
+ function sync_date_and_parent( $duplicated_post_id, $post_id, $lang ){
1737
  global $wpdb,$woocommerce_wpml;
1738
 
1739
  $tr_parent_id = apply_filters( 'translate_object_id', wp_get_post_parent_id( $duplicated_post_id ), 'product', false, $lang );
1740
 
1741
  $orig_product = get_post( $duplicated_post_id );
1742
+
1743
  $args = array();
1744
  $args[ 'post_parent' ] = is_null( $tr_parent_id )? 0 : $tr_parent_id;
 
 
1745
 
1746
  //sync product date
1747
  if( $woocommerce_wpml->settings[ 'products_sync_date' ] ){
2015
 
2016
  global $sitepress,$wpseo_metabox;
2017
  $settings = $sitepress->get_settings();
2018
+
2019
+
2020
+ $all_post_custom_keys = get_post_custom_keys($product_id) ;
2021
+
2022
+ // filter out not translatable custom fields
2023
+ $post_custom_keys = array();
2024
+ foreach( $all_post_custom_keys as $meta_key ){
2025
  if(isset($settings['translation-management']['custom_fields_translation'][$meta_key]) && $settings['translation-management']['custom_fields_translation'][$meta_key] == 2){
2026
+ $post_custom_keys[] = $meta_key;
2027
+ }
2028
+ }
2029
 
2030
+ $post_custom_keys = apply_filters ( 'wcml_translatable_custom_fields', $post_custom_keys );
2031
+
2032
+ foreach( $post_custom_keys as $meta_key ){
2033
+
2034
+ if(in_array($meta_key,$this->not_display_fields_for_variables_product)){
2035
+ continue;
2036
+ }
2037
+
2038
+ if($this->check_custom_field_is_single_value($product_id,$meta_key)){
2039
+ if(defined('WPSEO_VERSION')){
2040
+ if(!is_null($wpseo_metabox) && in_array($meta_key,$this->yoast_seo_fields)){
2041
+ $wpseo_metabox_values = $wpseo_metabox->get_meta_boxes('product');
2042
+ $contents[] = $wpseo_metabox_values[str_replace('_yoast_wpseo_','',$meta_key)]['title'];
2043
  continue;
2044
  }
 
2045
  }
2046
+ }else{
2047
+ $exception = apply_filters('wcml_product_content_exception',true,$product_id,$meta_key);
2048
+ if($exception){
 
2049
  continue;
2050
  }
2051
 
2052
+ }
 
2053
 
2054
+ $custom_key_label = apply_filters( 'wcml_product_content_label', $meta_key, $product_id );
2055
+ if( $custom_key_label != $meta_key ){
2056
+ $contents[] = $custom_key_label;
2057
+ continue;
2058
  }
2059
+
2060
+ $custom_key_label = str_replace('_',' ',$meta_key);
2061
+ $contents[] = trim($custom_key_label[0]) ? ucfirst($custom_key_label) : ucfirst(substr($custom_key_label,1));
2062
+
2063
+
2064
  }
2065
 
2066
  return apply_filters('wcml_product_content_fields_label', $contents, $product_id);
2068
 
2069
  function check_custom_field_is_single_value($product_id,$meta_key){
2070
 
2071
+ $meta_value = maybe_unserialize( get_post_meta( $product_id, $meta_key, true ) );
2072
  if(is_array($meta_value)){
2073
  return false;
2074
  }else{
2240
  $is_product_has_variations = $wpdb->get_var($wpdb->prepare("SELECT count(id) FROM $wpdb->posts WHERE post_parent = %d AND post_type = 'product_variation'",$product_id));
2241
 
2242
  foreach ($template_data['all_file_paths'] as $key => $price) {
2243
+ $template_data['all_variations_ids'][] = $key;
2244
  }
2245
 
2246
  if (!$is_product_has_variations){
2298
  include WCML_PLUGIN_PATH . '/menu/sub/images-box.php';
2299
  }
2300
 
2301
+ function custom_box( $product_id, $product_content, $trn_contents, $lang, $lang_name, $is_duplicate_product ){
2302
+
2303
  global $sitepress;
2304
  $original_language = $sitepress->get_language_for_element($product_id,'post_product');
2305
  $tr_product_id = apply_filters( 'translate_object_id',$product_id, 'product', false, $lang);
2442
  $variations = $wpdb->get_results($wpdb->prepare("SELECT post_id FROM $wpdb->postmeta WHERE meta_key=%s AND meta_value = %s",'attribute_'.$taxonomy,$original_slug));
2443
 
2444
  foreach($variations as $variation){
2445
+ //update taxonomy in translation of variation
2446
+ $trnsl_variation_id = apply_filters( 'translate_object_id',$variation->post_id,'product_variation',false,$language);
2447
+ if(!is_null($trnsl_variation_id)){
2448
+ if(!$slug){
2449
+ $slug = sanitize_title($name);
2450
+ }
2451
  update_post_meta($trnsl_variation_id,'attribute_'.$taxonomy,$slug);
2452
+ }
2453
  }
2454
  }
2455
 
2572
  if( ( isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
2573
  && ( ( !$parent && $sitepress->get_language_for_element( $post, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] )
2574
  || ( $parent && $sitepress->get_language_for_element( $parent, 'post_product') == $_COOKIE [ '_wcml_dashboard_order_language' ] ) )
2575
+ )
2576
  ||
2577
  ( ! isset( $_COOKIE [ '_wcml_dashboard_order_language' ] )
2578
  && ( ( !$parent && $this->is_original_product($post) )
2659
  $taxonomy = substr($attr_key, 10, strlen($attr_key)-1 );
2660
  }
2661
  $cart->cart_contents[$key]['variation'][$attr_key] = $this->get_cart_attribute_translation($taxonomy,$attribute,$cart_item['product_id'],$tr_product_id,$current_language);
2662
+ }
2663
  }
2664
  }
 
2665
  }else{
2666
  if(!is_null($tr_product_id)){
2667
  $cart->cart_contents[$key]['product_id'] = intval($tr_product_id);
2701
  continue;
2702
  }
2703
 
2704
+ $search_key = md5(serialize($cart_content));
 
 
 
 
 
 
 
2705
 
2706
  if( array_key_exists( $search_key, $exists_products ) ){
2707
  unset( $cart_contents[ $key ] );
2752
  $unserialized_orig_product_attributes = maybe_unserialize($orig_product_attributes);
2753
  foreach($unserialized_orig_product_attributes as $orig_attr_key => $orig_product_attribute){
2754
  $orig_attr_key = urldecode($orig_attr_key);
2755
+ if( strtolower($taxonomy) == $orig_attr_key){
2756
  $values = explode('|',$orig_product_attribute['value']);
2757
  foreach($values as $key_id => $value){
2758
  if(trim($value," ") == $attribute){
2767
  $taxonomy = sanitize_title($taxonomy);
2768
  $trnsl_attr_values = explode('|',$unserialized_trnsl_product_attributes[$taxonomy]['value']);
2769
 
2770
+ if(isset($attr_key_id) && isset($trnsl_attr_values[$attr_key_id])){
2771
  return trim($trnsl_attr_values[$attr_key_id]);
2772
  }
2773
 
2827
  }
2828
 
2829
 
2830
+ function set_taxonomies_config( $config_all ) {
2831
  global $woocommerce_wpml;
2832
 
2833
  $all_products_taxonomies = get_taxonomies( array( 'object_type' => array( 'product' ) ), 'objects' );
2834
 
2835
+ foreach($all_products_taxonomies as $tax_key => $tax) {
2836
+ if($tax_key == 'product_type' ) continue;
 
 
2837
 
2838
+ $found = false;
2839
 
2840
+ foreach( $config_all['wpml-config']['taxonomies']['taxonomy'] as $key => $taxonomy ){
 
 
 
2841
 
2842
+ if( $tax_key == $taxonomy['value'] ){
2843
+ $config_all['wpml-config']['taxonomies']['taxonomy'][$key]['attr']['translate'] = 1;
2844
+ $found = true;
2845
  }
2846
 
2847
+ }
2848
+
2849
+ if( !$found ){
2850
+ $config_all['wpml-config']['taxonomies']['taxonomy'][] = array( 'value' => $tax_key, 'attr' => array( 'translate' => 1 ) );
2851
+ }
2852
 
2853
  }
2854
 
2855
+ return $config_all;
2856
+ }
2857
 
2858
 
2859
+ function set_prices_config(){
2860
+ global $sitepress, $iclTranslationManagement, $sitepress_settings, $woocommerce_wpml;
2861
 
2862
+ $wpml_settings = $sitepress->get_settings();
2863
 
2864
+ if (!isset($wpml_settings['translation-management']) || !isset($iclTranslationManagement) || !( $iclTranslationManagement instanceof TranslationManagement) ) {
2865
+ return;
2866
+ }
2867
 
2868
+ $keys = array(
2869
+ '_regular_price',
2870
+ '_sale_price',
2871
+ '_price',
2872
+ '_min_variation_regular_price',
2873
+ '_min_variation_sale_price',
2874
+ '_min_variation_price',
2875
+ '_max_variation_regular_price',
2876
+ '_max_variation_sale_price',
2877
+ '_max_variation_price',
2878
+ '_sale_price_dates_from',
2879
+ '_sale_price_dates_to',
2880
+ '_wcml_schedule'
2881
+ );
2882
 
2883
+ $save = false;
2884
 
2885
+ foreach ($keys as $key) {
2886
+ $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $key;
2887
+ if (!isset($sitepress_settings['translation-management']['custom_fields_translation'][$key]) ||
2888
+ $wpml_settings['translation-management']['custom_fields_translation'][$key] != 1) {
2889
+ $wpml_settings['translation-management']['custom_fields_translation'][$key] = 1;
2890
+ $save = true;
2891
+ }
2892
 
2893
+ if(!empty($woocommerce_wpml->multi_currency_support)){
2894
+ foreach($woocommerce_wpml->multi_currency_support->get_currency_codes() as $code){
2895
+ $new_key = $key.'_'.$code;
2896
+ $iclTranslationManagement->settings['custom_fields_readonly_config'][] = $new_key;
2897
+ if (!isset($sitepress_settings['translation-management']['custom_fields_translation'][$new_key]) ||
2898
+ $wpml_settings['translation-management']['custom_fields_translation'][$new_key] != 0) {
2899
+ $wpml_settings['translation-management']['custom_fields_translation'][$new_key] = 0;
2900
+ $save = true;
2901
+ }
2902
+ }
2903
+ }
2904
 
2905
+ }
2906
 
2907
+ if ($save) {
2908
+ $sitepress->save_settings($wpml_settings);
2909
+ }
2910
  }
2911
 
2912
  function woocommerce_duplicate_product($new_id, $post){
2998
  }
2999
 
3000
  return $widget_id;
3001
+ }
3002
 
3003
 
3004
  //update menu_order fro translations after ordering original products
3031
  $menu_order = $wpdb->get_var($wpdb->prepare("SELECT menu_order FROM $wpdb->posts WHERE ID = %d", $product_id ) );
3032
 
3033
  $trid = $sitepress->get_element_trid($product_id, 'post_product');
3034
+ $translations = $sitepress->get_element_translations($trid, 'post_product');
3035
 
3036
+ foreach ($translations as $translation) {
3037
 
3038
  if ($translation->element_id != $product_id) {
3039
  $wpdb->update( $wpdb->posts, array('menu_order' => $menu_order), array('ID' => $translation->element_id));
3051
  $elements[ 'excerpt' ] ['editor_type'] = 'editor';
3052
  }
3053
 
3054
+ if ( function_exists( 'format_for_editor' ) ) {
3055
+ // WordPress 4.3 uses format_for_editor
3056
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(format_for_editor($elements[ 'excerpt' ] ['value'], $_POST[ 'excerpt_type']));
3057
  } else {
3058
+ // Backwards compatible for WordPress < 4.3
3059
  if($_POST[ 'excerpt_type'] == 'rich'){
3060
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(wp_richedit_pre($elements[ 'excerpt' ] ['value']));
3061
  }else{
3062
  $elements[ 'excerpt' ] ['value'] = htmlspecialchars_decode(wp_htmledit_pre($elements[ 'excerpt' ] ['value']));
3063
  }
3064
  }
3065
+
3066
+ return $elements;
3067
+ }
3068
 
3069
 
3070
  function product_data_html(){
inc/upgrade.class.php CHANGED
@@ -11,7 +11,8 @@ class WCML_Upgrade{
11
  '3.5',
12
  '3.5.4',
13
  '3.6',
14
- '3.7'
 
15
 
16
  );
17
 
@@ -378,4 +379,29 @@ class WCML_Upgrade{
378
 
379
  }
380
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
381
  }
11
  '3.5',
12
  '3.5.4',
13
  '3.6',
14
+ '3.7',
15
+ '3.7.3'
16
 
17
  );
18
 
379
 
380
  }
381
 
382
+ function upgrade_3_7_3()
383
+ {
384
+ global $sitepress;
385
+
386
+ $active_languages = $sitepress->get_active_languages();
387
+ $current_language = $sitepress->get_current_language();
388
+
389
+ foreach( $active_languages as $lang ){
390
+
391
+ $sitepress->switch_lang( $lang['code'] );
392
+
393
+ $product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
394
+
395
+ _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
396
+
397
+ $product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
398
+
399
+ _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
400
+
401
+ }
402
+
403
+ $sitepress->switch_lang( $current_language );
404
+
405
+ }
406
+
407
  }
menu/management.php CHANGED
@@ -29,7 +29,7 @@ if(isset($_GET['tab'])){
29
 
30
  ?>
31
 
32
- <div class="wrap">
33
  <div id="icon-wpml" class="icon32"><br /></div>
34
  <h2><?php _e('WooCommerce Multilingual', 'woocommerce-multilingual') ?></h2>
35
 
29
 
30
  ?>
31
 
32
+ <div class="wrap wcml-wrap">
33
  <div id="icon-wpml" class="icon32"><br /></div>
34
  <h2><?php _e('WooCommerce Multilingual', 'woocommerce-multilingual') ?></h2>
35
 
readme.txt CHANGED
@@ -4,8 +4,8 @@ Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilin
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.0
7
- Tested up to: 4.3
8
- Stable tag: 3.7.2
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -78,6 +78,20 @@ In order for the checkout and store pages to appear translated, you need to crea
78
 
79
  == Changelog ==
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  = 3.7.2 =
82
  * Added synchronization for the 'featured' flag (star) for products across translations
83
  * Fixed one compatibility problem with WooCommerce Bookings: bookings were not filtered by language on the front end
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 3.0
7
+ Tested up to: 4.3.1
8
+ Stable tag: 3.7.3
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
78
 
79
  == Changelog ==
80
 
81
+ = 3.7.3 =
82
+ * Added support for translating custom attributes (for variations) via the professional translation
83
+ * Added support for translating products tab information (WooCommerce Tab Manager) via the professional translation
84
+ * Added support for translating persons and resources (WooCommerce Bookings) via the professional translation
85
+ * Added support for translating products bundle data (WooCommerce Product Bundles) via the professional translation
86
+ * Added extended compatibility and support for professional translation for WooCommerce Composite Products
87
+ * Bug fix: it was not possible to set a product translation as draft when the original was published
88
+ * Bug fix: in some cases the product categories hierarchy (and count) was not sycned across translations
89
+ * Bug fix: the custom title and description of a bundle of a translated product was removed after updating the original product
90
+ * Bug fix: custom fields that did not have any translation preference were wrongfully copied across translations
91
+ * Bug fix: multi-currency was not working properly for product variations when the "Show only products with custom prices in secondary currencies" option was on
92
+ * Fixed an important compatibility issue with Yoast SEO (fatal error when using Yoast SEO 3.0+)
93
+ * Bug fix: wcml_check_on_duplicate_products_in_cart was incorrectly duplicated specific items in the cart
94
+
95
  = 3.7.2 =
96
  * Added synchronization for the 'featured' flag (star) for products across translations
97
  * Fixed one compatibility problem with WooCommerce Bookings: bookings were not filtered by language on the front end
wpml-woocommerce.php CHANGED
@@ -6,12 +6,12 @@
6
  Author: OnTheGoSystems
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
- Version: 3.7.2
10
  */
11
 
12
 
13
  if(defined('WCML_VERSION')) return;
14
- define('WCML_VERSION', '3.7.2');
15
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
16
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
17
  define('WCML_LOCALE_PATH',WCML_PLUGIN_PATH.'/locale');
@@ -39,6 +39,7 @@ require WCML_PLUGIN_PATH . '/inc/endpoints.class.php';
39
  require WCML_PLUGIN_PATH . '/inc/currency-switcher.class.php';
40
  require WCML_PLUGIN_PATH . '/inc/xdomain-data.class.php';
41
  require WCML_PLUGIN_PATH . '/inc/url-translation.class.php';
 
42
 
43
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
44
 
6
  Author: OnTheGoSystems
7
  Author URI: http://www.onthegosystems.com/
8
  Text Domain: woocommerce-multilingual
9
+ Version: 3.7.3
10
  */
11
 
12
 
13
  if(defined('WCML_VERSION')) return;
14
+ define('WCML_VERSION', '3.7.3');
15
  define('WCML_PLUGIN_PATH', dirname(__FILE__));
16
  define('WCML_PLUGIN_FOLDER', basename(WCML_PLUGIN_PATH));
17
  define('WCML_LOCALE_PATH',WCML_PLUGIN_PATH.'/locale');
39
  require WCML_PLUGIN_PATH . '/inc/currency-switcher.class.php';
40
  require WCML_PLUGIN_PATH . '/inc/xdomain-data.class.php';
41
  require WCML_PLUGIN_PATH . '/inc/url-translation.class.php';
42
+ require WCML_PLUGIN_PATH . '/inc/class-wcml-tp-support.php';
43
 
44
  require WCML_PLUGIN_PATH . '/woocommerce_wpml.class.php';
45