WooCommerce Multilingual – run WooCommerce with WPML - Version 4.9.0

Version Description

  • Manual shipping prices in secondary currencies.
  • Fixed product attribute slug language not changed after changing value.
  • Fixed missing numeric attribute values after translation using ATE.
  • Fixed mini-cart total calculation when switching a currency.
  • Fixed out of stock variable products if "Show only products with custom prices in secondary currencies" option is enabled.
  • Fixed WC Tab Manager custom tab translation from ATE was not saved if the description is empty.
  • Fixed an error which some additional plugins may cause with WC_Email object.
  • Add a filter for WCML_WC_Gateways::get_current_gateway_language().
  • Fixed not synchronized WooCommerce Tab Manager global tabs while saving product translation via ATE.
  • Fixed not updated tax label after a change on settings page.
  • Fixed the value of a custom attribute translation is overwritten on saving the original product.
  • Fixed overwritten composite data title and description in translation after original product update.
  • Fixed js console error in languages_notice.js file.
  • Add language filtering for WooCommerce dashboard stock widgets.
  • Fixed creating of several memberships in WooCommerce Membership plugin.
Download this release

Release Info

Developer sergey.r
Plugin Icon 128x128 WooCommerce Multilingual – run WooCommerce with WPML
Version 4.9.0
Comparing to
See all releases

Code changes from version 4.8.0 to 4.9.0

Files changed (57) hide show
  1. changelog/4.4.0.md +0 -44
  2. changelog/4.6.0.md +2 -0
  3. changelog/4.9.0.md +20 -0
  4. classes/AdminDashboard/Hooks.php +55 -0
  5. classes/AdminNotices/Review.php +152 -0
  6. classes/Multicurrency/Shipping/AdminHooks.php +155 -0
  7. classes/Multicurrency/Shipping/DefaultConversion.php +25 -0
  8. classes/Multicurrency/Shipping/FlatRateShipping.php +12 -0
  9. classes/Multicurrency/Shipping/FreeShipping.php +76 -0
  10. classes/Multicurrency/Shipping/FrontEndHooks.php +93 -0
  11. classes/Multicurrency/Shipping/LocalPickup.php +12 -0
  12. classes/Multicurrency/Shipping/ShippingClasses.php +90 -0
  13. classes/Multicurrency/Shipping/ShippingClassesMode.php +22 -0
  14. classes/Multicurrency/Shipping/ShippingHooksFactory.php +57 -0
  15. classes/Multicurrency/Shipping/ShippingMode.php +75 -0
  16. classes/Multicurrency/Shipping/ShippingModeBase.php +14 -0
  17. classes/Multicurrency/Shipping/ShippingModeProvider.php +39 -0
  18. classes/Multicurrency/Shipping/UnsupportedShipping.php +41 -0
  19. classes/Multicurrency/Shipping/VariableCost.php +213 -0
  20. classes/Tax/Strings/Hooks.php +87 -0
  21. compatibility/class-wcml-composite-products.php +38 -74
  22. compatibility/class-wcml-gravityforms.php +2 -1
  23. compatibility/class-wcml-tab-manager.php +8 -1
  24. dist/js/multicurrencyShippingAdmin/app.js +1 -0
  25. inc/class-wcml-attributes.php +15 -7
  26. inc/class-wcml-emails.php +21 -5
  27. inc/class-wcml-orders.php +0 -1
  28. inc/class-wcml-url-translation.php +4 -3
  29. inc/class-wcml-wc-gateways.php +79 -23
  30. inc/class-wcml-wc-shipping.php +10 -26
  31. inc/currencies/class-wcml-custom-prices.php +31 -14
  32. inc/currencies/class-wcml-multi-currency-prices.php +8 -3
  33. inc/currencies/class-wcml-multi-currency-shipping.php +13 -9
  34. inc/wcml-core-functions.php +18 -0
  35. readme.txt +19 -45
  36. res/css/admin.css +1 -1
  37. res/css/management.css +1 -1
  38. res/css/wcml-prices.css +1 -1
  39. res/css/wcml-setup-wizard-notice.css +1 -1
  40. res/css/wcml-setup.css +1 -1
  41. res/images/bg-rating-notice.png +0 -0
  42. res/js/languages_notice.min.js +1 -1
  43. vendor/autoload.php +1 -1
  44. vendor/composer/autoload_classmap.php +17 -0
  45. vendor/composer/autoload_real.php +7 -7
  46. vendor/composer/autoload_static.php +21 -4
  47. vendor/otgs/installer/includes/class-installer-dependencies.php +6 -17
  48. vendor/otgs/installer/includes/class-wp-installer.php +68 -15
  49. vendor/otgs/installer/includes/functions-core.php +7 -0
  50. vendor/otgs/installer/includes/otgs-installer-autoload-classmap.php +3 -2
  51. vendor/otgs/installer/includes/rest/Push.php +41 -0
  52. vendor/otgs/installer/loader.php +6 -4
  53. vendor/otgs/installer/templates/channel-selector.php +2 -2
  54. vendor/otgs/installer/templates/repository-expired.php +1 -1
  55. vendor/otgs/installer/templates/repository-listing.php +1 -0
  56. vendor/otgs/installer/templates/repository-refunded.php +4 -2
  57. wpml-woocommerce.php +8 -4
changelog/4.4.0.md DELETED
@@ -1,44 +0,0 @@
1
- # Features
2
- * [wcml-436] Added the ability to associate BACS accounts with currencies
3
- * [wcml-2625] Hide reviews in other languages link, if there are no reviews in product
4
- * [wcml-2594] Update WCML Logo
5
- * [wcml-2375] Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
6
-
7
- # Fixes
8
- * [wcml-2647] Fix low_stock_amount not synchronized to translations
9
- * [wcml-2646] Fix custom attribute with number in name not appears to translation in Translation editor
10
- * [wcml-2644] Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
11
- * [wcml-2640] Fix translated custom field wrongly saved to translation if contains array of strings
12
- * [wcml-2639] Endless loop when using troubleshooting action to duplicate terms
13
- * [wcml-2634] Fixed an issue with Elementor PRO products block showing all categories in the translated page.
14
- * [wcml-2633] Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
15
- * [wcml-2630] Fixed compatibility issue with Flatsome theme
16
- * [wcml-2628] Fix issue with custom product attribute title when trying to upload translation with XLIFF file
17
- * [wcml-2627] Fixed cart validate for specific situations
18
- * [wcml-2618] Added filter for translated package rates
19
- * [wcml-2616] Added WPML switcher buttons library for Multi Currency in backend
20
- * [wcml-2614] Fix loading Jquery to any place in code and in header
21
- * [wcml-2608] Added fix for variation product "become" out-of-stock when translating using native screen
22
- * [wcml-2607] Removed backward compatibility filters for terms synchronization
23
- * [wcml-2605] Fixed attribute slug language always set to English
24
- * [wcml-2604] Wrong path in Bookings compatibility class
25
- * [wcml-2602] Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
26
- * [wcml-2600] Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
27
- * [wcml-2599] Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
28
- * [wcml-2592] Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
29
- * [wcml-2590] Fixed compatibility class name for wc product addons
30
- * [wcml-2589] Fixed manual order creation does not respect manual prices
31
- * [wcml-2587] Fix email language for the order as complete emails
32
- * [wcml-2585] Fixed Composite Products compatibility - Price not rounding to the nearest integer
33
- * [wcml-2576] Fixed missing custom attribute in XLIFF file / Pro Translation
34
- * [wcml-2575] Fix Endpoint error to prevent 404 in some cases
35
- * [wcml-2574] Fixed accepted arguments for terms_clause
36
- * [wcml-2572] Resolved an exception causing an error message in the cart in some setups
37
- * [wcml-2568] Fixed missed synchronization of 'outofstock' visibility term between product translations
38
- * [wcml-2566] Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
39
- * [wcml-2550] Custom attributes terms not copied to diplicated translation after update values in original
40
- * [wcml-2539] Added support for wpml endpoints
41
- * [wcml-2538] WP Fastest Cache compatibility - fixed currency switcher problem
42
- * [wcml-2532] Added ability to set custom prices for secondary currencies in WC Product Add-Ons
43
- * [wcml-2201] Update minimum requirements
44
- * [wcml-2011] Added ability to add custom payment methods for each currency
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
changelog/4.6.0.md CHANGED
@@ -8,4 +8,6 @@
8
  * [wcml-2755] Fix loading scripts on admin pages
9
  * [wcml-2754] Fix coupon discount when editing order from admin
10
  * [wcml-2726] Fix wrong product price after adding another product to existing order from admin
 
 
11
  * [wcml-2653] Fix my-account page endpoints in secondary language with pages set to "Display as translated"
8
  * [wcml-2755] Fix loading scripts on admin pages
9
  * [wcml-2754] Fix coupon discount when editing order from admin
10
  * [wcml-2726] Fix wrong product price after adding another product to existing order from admin
11
+
12
+ # Compatibility
13
  * [wcml-2653] Fix my-account page endpoints in secondary language with pages set to "Display as translated"
changelog/4.9.0.md ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Features
2
+ * [wcml-3] Manual shipping prices in secondary currencies.
3
+
4
+ # Fixes
5
+ * [wcml-3204] Fixed product attribute slug language not changed after changing value.
6
+ * [wcml-3196] Fixed missing numeric attribute values after translation using ATE.
7
+ * [wcml-3194] Fixed mini-cart total calculation when switching a currency.
8
+ * [wcml-3192] Fixed out of stock variable products if "Show only products with custom prices in secondary currencies" option is enabled.
9
+ * [wcml-3186] Fixed WC Tab Manager custom tab translation from ATE was not saved if the description is empty.
10
+ * [wcml-3177] Fixed an error which some additional plugins may cause with WC_Email object.
11
+ * [wcml-3176] Add a filter for WCML_WC_Gateways::get_current_gateway_language().
12
+ * [wcml-3171] Fixed not synchronized WooCommerce Tab Manager global tabs while saving product translation via ATE.
13
+ * [wcml-3160] Fixed not updated tax label after a change on settings page.
14
+ * [wcml-3151] Fixed the value of a custom attribute translation is overwritten on saving the original product.
15
+ * [wcml-3150] Fixed overwritten composite data title and description in translation after original product update.
16
+ * [wcml-3136] Fixed js console error in languages_notice.js file.
17
+ * [wcml-2932] Add language filtering for WooCommerce dashboard stock widgets.
18
+
19
+ # Compatibility
20
+ * [wcml-3140] Fixed creating of several memberships in WooCommerce Membership plugin.
classes/AdminDashboard/Hooks.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\AdminDashboard;
4
+
5
+ use SitePress;
6
+ use wpdb;
7
+ use IWPML_DIC_Action;
8
+ use IWPML_Backend_Action;
9
+
10
+ class Hooks implements IWPML_Backend_Action, IWPML_DIC_Action {
11
+
12
+ /** @var SitePress $sitepress */
13
+ private $sitepress;
14
+
15
+ /** @var wpdb $wpdb */
16
+ private $wpdb;
17
+
18
+ public function __construct( SitePress $sitepress, wpdb $wpdb ) {
19
+ $this->sitepress = $sitepress;
20
+ $this->wpdb = $wpdb;
21
+ }
22
+
23
+ public function add_hooks() {
24
+ add_action( 'wp_dashboard_setup', [ $this, 'clearStockTransients' ] );
25
+ add_filter( 'woocommerce_status_widget_low_in_stock_count_query', [ $this, 'addLanguageQuery' ] );
26
+ add_filter( 'woocommerce_status_widget_out_of_stock_count_query', [ $this, 'addLanguageQuery' ] );
27
+ }
28
+
29
+ public function clearStockTransients() {
30
+ delete_transient( 'wc_outofstock_count' );
31
+ delete_transient( 'wc_low_stock_count' );
32
+ }
33
+
34
+ /**
35
+ * @param string $query
36
+ *
37
+ * @return string
38
+ */
39
+ public function addLanguageQuery( $query ) {
40
+
41
+ $currentLanguage = $this->sitepress->get_current_language();
42
+
43
+ if ( $currentLanguage !== 'all' ) {
44
+ $languageQuery = $this->wpdb->prepare(
45
+ " INNER JOIN {$this->wpdb->prefix}icl_translations AS t
46
+ ON posts.ID = t.element_id AND t.element_type IN ( 'post_product', 'post_product_variation' )
47
+ WHERE t.language_code = %s AND ",
48
+ $currentLanguage );
49
+
50
+ return str_replace( 'WHERE', $languageQuery, $query );
51
+ }
52
+
53
+ return $query;
54
+ }
55
+ }
classes/AdminNotices/Review.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\AdminNotices;
4
+
5
+ use WPML_Notices;
6
+ use IWPML_Backend_Action;
7
+ use IWPML_Frontend_Action;
8
+ use IWPML_DIC_Action;
9
+ use wpdb;
10
+ use SitePress;
11
+
12
+ class Review implements IWPML_Backend_Action, IWPML_Frontend_Action, IWPML_DIC_Action {
13
+
14
+ const OPTION_NAME = 'wcml-rate-notice';
15
+
16
+ /** @var WPML_Notices $wpmlNotices */
17
+ private $wpmlNotices;
18
+
19
+ /** @var wpdb $wpdb */
20
+ private $wpdb;
21
+
22
+ /** @var SitePress $sitepress */
23
+ private $sitepress;
24
+
25
+ /**
26
+ * Review constructor.
27
+ *
28
+ * @param WPML_Notices $wpmlNotices
29
+ * @param wpdb $wpdb
30
+ * @param SitePress $sitepress
31
+ */
32
+ public function __construct( WPML_Notices $wpmlNotices, wpdb $wpdb, SitePress $sitepress ) {
33
+ $this->wpmlNotices = $wpmlNotices;
34
+ $this->wpdb = $wpdb;
35
+ $this->sitepress = $sitepress;
36
+ }
37
+
38
+ /**
39
+ * add hooks
40
+ */
41
+ public function add_hooks() {
42
+ add_action( 'admin_notices', [ $this, 'addNotice' ] );
43
+ add_action( 'woocommerce_after_order_object_save', [ $this, 'onNewOrder' ] );
44
+ }
45
+
46
+ /**
47
+ * add notice message
48
+ */
49
+ public function addNotice() {
50
+
51
+ if ( $this->shouldDisplayNotice() ) {
52
+ $notice = $this->wpmlNotices->get_new_notice( 'wcml-rate', $this->getNoticeText(), 'wcml-admin-notices' );
53
+
54
+ if ( $this->wpmlNotices->is_notice_dismissed( $notice ) ) {
55
+ return;
56
+ }
57
+
58
+ $notice->set_css_class_types( 'info' );
59
+ $notice->set_css_classes( [ 'otgs-notice-wcml-rating' ] );
60
+ $notice->set_dismissible( true );
61
+
62
+ $reviewLink = 'https://wordpress.org/support/plugin/woocommerce-multilingual/reviews/?filter=5#new-post';
63
+ $reviewButton = $this->wpmlNotices->get_new_notice_action( __( 'Review WooCommerce Multilingual', 'woocommerce-multilingual' ), $reviewLink, false, false, true );
64
+ $notice->add_action( $reviewButton );
65
+
66
+ $notice->set_restrict_to_screen_ids( $this->getRestrictedScreenIds() );
67
+ $notice->add_capability_check( [ 'manage_options', 'wpml_manage_woocommerce_multilingual' ] );
68
+ $this->wpmlNotices->add_notice( $notice );
69
+ }
70
+ }
71
+
72
+ /**
73
+ * get screen ids to display notice
74
+ *
75
+ * @return array
76
+ */
77
+ private function getRestrictedScreenIds() {
78
+ return [
79
+ 'dashboard',
80
+ 'woocommerce_page_wpml-wcml',
81
+ 'woocommerce_page_wc-admin',
82
+ 'woocommerce_page_wc-reports',
83
+ 'woocommerce_page_wc-settings',
84
+ 'woocommerce_page_wc-status',
85
+ 'woocommerce_page_wc-addons',
86
+ 'edit-shop_order',
87
+ 'edit-shop_coupon',
88
+ 'edit-product',
89
+ ];
90
+ }
91
+
92
+ /**
93
+ * get notice text
94
+ *
95
+ * @return string
96
+ */
97
+ private function getNoticeText() {
98
+ $text = '<h2>';
99
+ $text .= __( 'Congrats! You\'ve just earned some money using WooCommerce Multilingual.', 'woocommerce-multilingual' );
100
+ $text .= '</h2>';
101
+
102
+ $text .= '<p>';
103
+ $text .= __( 'How do you feel getting your very first order in foreign language or currency?', 'woocommerce-multilingual' );
104
+ $text .= '<br />';
105
+ $text .= __( 'We for sure are super thrilled about your success! Will you help WCML improve and grow?', 'woocommerce-multilingual' );
106
+ $text .= '</p>';
107
+
108
+ $text .= '<p><strong>';
109
+ $text .= __( 'Give us <span class="rating">5.0 <i class="otgs-ico-star"></i></span> review now.', 'woocommerce-multilingual' );
110
+ $text .= '</strong></p>';
111
+
112
+ return $text;
113
+ }
114
+
115
+ /**
116
+ * check if we should display notice
117
+ *
118
+ * @return bool
119
+ */
120
+ private function shouldDisplayNotice() {
121
+ return get_option( self::OPTION_NAME, false );
122
+ }
123
+
124
+ public function onNewOrder(){
125
+ if ( !$this->shouldDisplayNotice() ) {
126
+ $this->maybeAddOptionToShowNotice();
127
+ }
128
+ }
129
+
130
+ /**
131
+ * maybe add option to show notice
132
+ */
133
+ private function maybeAddOptionToShowNotice() {
134
+
135
+ $ordersCountInSecondLanguageOrCurrency = $this->wpdb->get_var(
136
+ $this->wpdb->prepare(
137
+ "SELECT COUNT(p.ID) FROM {$this->wpdb->postmeta} as pm
138
+ INNER JOIN {$this->wpdb->posts} as p ON pm.post_id = p.ID
139
+ WHERE p.post_type = 'shop_order' AND (
140
+ ( pm.meta_key = '_order_currency' AND pm.meta_value != %s )
141
+ OR
142
+ ( pm.meta_key = 'wpml_language' AND pm.meta_value != %s ) )",
143
+ wcml_get_woocommerce_currency_option(),
144
+ $this->sitepress->get_default_language() )
145
+ );
146
+
147
+ if ( $ordersCountInSecondLanguageOrCurrency ) {
148
+ add_option( self::OPTION_NAME, true );
149
+ }
150
+ }
151
+
152
+ }
classes/Multicurrency/Shipping/AdminHooks.php ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ use IWPML_Action;
6
+ use WCML_Multi_Currency;
7
+
8
+ class AdminHooks implements IWPML_Action {
9
+ const WCML_SHIPPING_COSTS = 'wcml_shipping_costs';
10
+
11
+ /** @var WCML_Multi_Currency */
12
+ private $wcmlMultiCurrency;
13
+
14
+ /**
15
+ * AdminHooks constructor.
16
+ *
17
+ * @param \WCML_Multi_Currency $wcmlMultiCurrency
18
+ */
19
+ public function __construct( \WCML_Multi_Currency $wcmlMultiCurrency ) {
20
+ $this->wcmlMultiCurrency = $wcmlMultiCurrency;
21
+ }
22
+
23
+ /**
24
+ * Registers hooks.
25
+ */
26
+ public function add_hooks() {
27
+ ShippingModeProvider::getAll()->each( function( ShippingMode $shippingMode ) {
28
+ add_filter(
29
+ 'woocommerce_shipping_instance_form_fields_' . $shippingMode->getMethodId(),
30
+ $this->addCurrencyShippingFields( $shippingMode ),
31
+ 10,
32
+ 1
33
+ );
34
+ }
35
+ );
36
+ add_action( 'admin_enqueue_scripts', [ $this, 'loadJs' ] );
37
+ }
38
+
39
+ public function addCurrencyShippingFields( ShippingMode $shippingMode ) {
40
+ return function( array $field ) use ( $shippingMode ) {
41
+ return $this->addCurrencyShippingFieldsToShippingMethodForm( $field, $shippingMode );
42
+ };
43
+ }
44
+
45
+ /**
46
+ * Adds fields to display screen for shipping method.
47
+ *
48
+ * Adds two kind of fields:
49
+ * - The select field to enable/disable shipping costs in other currencies.
50
+ * @see \AdminHooks::add_enable_field
51
+ * - The input field for each registered currency to provide shipping costs.
52
+ * @see \AdminHooks::add_currencies_fields
53
+ *
54
+ * @param array $field
55
+ *
56
+ * @return array
57
+ */
58
+ private function addCurrencyShippingFieldsToShippingMethodForm( array $field, ShippingMode $shippingMode ) {
59
+ $field = $this->addTitleField( $field );
60
+ $field = $this->addEnableField( $field );
61
+ $field = $this->addCurrenciesFields( $field, $shippingMode );
62
+ if ( $shippingMode instanceof ShippingClassesMode ) {
63
+ $field = ShippingClasses::addFields( $field, $this->wcmlMultiCurrency );
64
+ }
65
+ return $field;
66
+ }
67
+
68
+ private function addTitleField( $field ) {
69
+ $field[ 'wcml_shipping_costs_title' ] = [
70
+ 'title' => __( 'Costs and values in custom currencies', 'woocommerce-multilingual' ),
71
+ 'type' => 'title',
72
+ 'default' => '',
73
+ 'description' => __( 'Woocommerce Mulitlingual by default will multiply all your costs and values defined above by currency exchange rates. If you don\'t want this and you prefer static values instead, you can define them here.', 'woocommerce-multilingual' ),
74
+ ];
75
+ return $field;
76
+ }
77
+
78
+ /**
79
+ * Adds select field to enable/disable shipping costs in other currencies.
80
+ *
81
+ * @param array $field
82
+ *
83
+ * @return array
84
+ */
85
+ private function addEnableField( array $field ) {
86
+ $enable_field = [
87
+ 'title' => esc_html__( 'Enable costs in custom currencies', 'woocommerce-multilingual' ),
88
+ 'type' => 'select',
89
+ 'class' => 'wcml-enable-shipping-custom-currency',
90
+ 'default' => 'auto',
91
+ 'options' => [
92
+ 'auto' => esc_html__( 'Calculate shipping costs in other currencies automatically', 'woocommerce-multilingual' ),
93
+ 'manual' => esc_html__( 'Set shipping costs in other currencies manually', 'woocommerce-multilingual' )
94
+ ]
95
+ ];
96
+ $field[ self::WCML_SHIPPING_COSTS ] = $enable_field;
97
+
98
+ return $field;
99
+ }
100
+
101
+ /**
102
+ * Adds input field for each registered currency to provide shipping costs.
103
+ *
104
+ * @param array $field
105
+ *
106
+ * @return array
107
+ */
108
+ public function addCurrenciesFields( array $field, ShippingMode $shippingMode ) {
109
+ foreach ( $this->wcmlMultiCurrency->get_currency_codes() as $currencyCode ) {
110
+ if ( $this->wcmlMultiCurrency->get_default_currency() === $currencyCode ) {
111
+ continue;
112
+ }
113
+ $field = $this->getCurrencyField( $field, $currencyCode, $shippingMode );
114
+ }
115
+ return $field;
116
+ }
117
+
118
+ /**
119
+ * Adds one field for given currency.
120
+ *
121
+ * @param array $field
122
+ * @param string $currencyCode
123
+ *
124
+ * @return mixed
125
+ */
126
+ protected function getCurrencyField( $field, $currencyCode, ShippingMode $shippingMode ) {
127
+ $fieldKey = $shippingMode->getSettingsFormKey( $currencyCode );
128
+ if ( $fieldKey ) {
129
+ $fieldValue = [
130
+ 'title' => $shippingMode->getFieldTitle( $currencyCode ),
131
+ 'type' => 'text',
132
+ 'description' => $shippingMode->getFieldDescription( $currencyCode ),
133
+ 'default' => '0',
134
+ 'desc_tip' => true,
135
+ 'class' => 'wcml-shipping-cost-currency'
136
+ ];
137
+
138
+ $field[ $fieldKey] = $fieldValue;
139
+ }
140
+ return $field;
141
+ }
142
+
143
+ /**
144
+ * Enqueues script responsible for JS actions on shipping fields.
145
+ */
146
+ public function loadJs() {
147
+ wp_enqueue_script(
148
+ 'wcml-admin-shipping-currency-selector',
149
+ constant( 'WCML_PLUGIN_URL' ) . '/dist/js/multicurrencyShippingAdmin/app.js',
150
+ [],
151
+ constant( 'WCML_VERSION' ),
152
+ true
153
+ );
154
+ }
155
+ }
classes/Multicurrency/Shipping/DefaultConversion.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ trait DefaultConversion {
6
+ /**
7
+ * Try to get cost/amount from options array for default currency.
8
+ *
9
+ * @param float|int $cost Cost to filter.
10
+ * @param array $rateSettings Options array.
11
+ * @param string $costName Cost key with currency code appended.
12
+ * @param string $currencyCode Currency code.
13
+ *
14
+ * @return float|int
15
+ */
16
+ public function getValueFromDefaultCurrency( $cost, $rateSettings, $costName, $currencyCode ) {
17
+ if ( preg_match( '/(.*)_' . $currencyCode . '$/', $costName, $matches ) ) {
18
+ $defaultCostName = $matches[1];
19
+ if ( ! empty( $rateSettings[ $defaultCostName ] ) ) {
20
+ $cost = wcml_convert_price( $rateSettings[ $defaultCostName ], $currencyCode );
21
+ }
22
+ }
23
+ return $cost;
24
+ }
25
+ }
classes/Multicurrency/Shipping/FlatRateShipping.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class FlatRateShipping implements ShippingClassesMode {
6
+ use ShippingModeBase;
7
+ use VariableCost;
8
+
9
+ public function getMethodId() {
10
+ return 'flat_rate';
11
+ }
12
+ }
classes/Multicurrency/Shipping/FreeShipping.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class FreeShipping implements ShippingMode {
6
+ use ShippingModeBase;
7
+ use DefaultConversion;
8
+
9
+ public function getFieldTitle( $currencyCode ) {
10
+ if ( ! is_string( $currencyCode ) ) {
11
+ $currencyCode = '';
12
+ }
13
+ return sprintf( esc_html_x( 'Minimal order amount in %s',
14
+ 'The label for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
15
+ 'woocommerce-multilingual' ), $currencyCode );
16
+ }
17
+
18
+ public function getFieldDescription( $currencyCode ) {
19
+ if ( ! is_string( $currencyCode ) ) {
20
+ $currencyCode = '';
21
+ }
22
+ return sprintf( esc_html_x( 'The minimal order amount if customer choose %s as a purchase currency.',
23
+ 'The description for the field with minimal order amount in additional currency. The currency symbol will be added in place of %s specifier.',
24
+ 'woocommerce-multilingual' ), $currencyCode );
25
+ }
26
+
27
+ public function getMethodId() {
28
+ return 'free_shipping';
29
+ }
30
+
31
+ /**
32
+ * Returns minimal amount key for given currency.
33
+ *
34
+ * @param string $currencyCode Currency code.
35
+ *
36
+ * @return string
37
+ */
38
+ private function getMinimalOrderAmountKey( $currencyCode ) {
39
+ return sprintf( 'min_amount_%s', $currencyCode );
40
+ }
41
+
42
+ public function getSettingsFormKey( $currencyCode ) {
43
+ return $this->getMinimalOrderAmountKey( $currencyCode );
44
+ }
45
+
46
+ public function getMinimalOrderAmountValue( $amount, $shipping, $currency ) {
47
+ if ( $this->isManualPricingEnabled( $shipping ) ) {
48
+ $key = $this->getMinimalOrderAmountKey( $currency );
49
+ if ( ! empty( $shipping[ $key ] ) ) {
50
+ $amount = $shipping[ $key ];
51
+ } else {
52
+ $amount = $this->getValueFromDefaultCurrency( $amount, $shipping, $key, $currency );
53
+ }
54
+ }
55
+ return $amount;
56
+ }
57
+
58
+ /**
59
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getShippingCostValue
60
+ *
61
+ * @param array|object $rate
62
+ * @param string $currency
63
+ *
64
+ * @return int|mixed|string
65
+ */
66
+ public function getShippingCostValue( $rate, $currency ) {
67
+ if ( ! isset( $rate->cost ) ) {
68
+ $rate->cost = 0;
69
+ }
70
+ return $rate->cost;
71
+ }
72
+
73
+ public function isManualPricingEnabled( $instance ) {
74
+ return is_array( $instance ) && isset( $instance['wcml_shipping_costs'] ) && 'manual' === $instance['wcml_shipping_costs'];
75
+ }
76
+ }
classes/Multicurrency/Shipping/FrontEndHooks.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ use IWPML_Action;
6
+
7
+ class FrontEndHooks implements IWPML_Action {
8
+
9
+ private $multiCurrency;
10
+
11
+ public function __construct( $multiCurrency ) {
12
+ $this->multiCurrency = $multiCurrency;
13
+ }
14
+
15
+ public function add_hooks() {
16
+ ShippingModeProvider::getAll()->each( function( ShippingMode $shippingMode ) {
17
+ add_filter(
18
+ 'woocommerce_shipping_' . $shippingMode->getMethodId() . '_instance_option',
19
+ $this->getShippingCost( $shippingMode ),
20
+ 10,
21
+ 3
22
+ );
23
+ }
24
+ );
25
+ }
26
+
27
+ public function getShippingCost( ShippingMode $shippingMode ) {
28
+ return function( $rate, $key, $wcShippingMethod ) use ( $shippingMode ) {
29
+ if ( $shippingMode->isManualPricingEnabled( $wcShippingMethod ) ) {
30
+ if ( 'cost' === $key ) {
31
+ $rate = $shippingMode->getShippingCostValue( $wcShippingMethod, $this->getClientCurrency() );
32
+ } elseif ( $shippingMode instanceof ShippingClassesMode ) {
33
+ if ( $this->isShippingClass( $key ) ) {
34
+ $rate = $shippingMode->getShippingClassCostValue( $wcShippingMethod, $this->getClientCurrency(), $key );
35
+ } elseif ( $this->isNoShippingClass( $key ) ) {
36
+ $rate = $shippingMode->getNoShippingClassCostValue( $wcShippingMethod, $this->getClientCurrency() );
37
+ }
38
+ }
39
+ }
40
+ return $rate;
41
+ };
42
+ }
43
+
44
+ private function isShippingClass( $key ) {
45
+ return 'class_cost_' === substr( $key, 0, 11 );
46
+ }
47
+
48
+ private function isNoShippingClass( $key ) {
49
+ return 'no_class_cost' === substr( $key, 0, 13 );
50
+ }
51
+
52
+ /**
53
+ * Returns current client currency, respecting result of currency switcher widget actions.
54
+ *
55
+ * @return string
56
+ */
57
+ private function getClientCurrency() {
58
+ return $this->adjustCurrencyOnWidgetChange( $this->multiCurrency->get_client_currency() );
59
+ }
60
+
61
+ /**
62
+ * Checks if this is currency change triggered from WCML currency widget and updates currency code.
63
+ *
64
+ * @param string $currencyCode
65
+ *
66
+ * @return string Currency code.
67
+ */
68
+ private function adjustCurrencyOnWidgetChange( $currencyCode ) {
69
+ if ( ! isset( $_POST ) ) {
70
+ return $currencyCode;
71
+ }
72
+ $postData = wpml_collect( $_POST );
73
+ $currencyCodeInRequest = $postData->get( 'currency' );
74
+ if ( 'wcml_switch_currency' === $postData->get( 'action' )
75
+ && $currencyCodeInRequest
76
+ && $this->validateCurrencyCode( $currencyCodeInRequest ) ) {
77
+ return $currencyCodeInRequest;
78
+ }
79
+ return $currencyCode;
80
+ }
81
+
82
+ /**
83
+ * Checks if given currency code is one of currencies set in WCML.
84
+ *
85
+ * @param mixed $currencyCode
86
+ *
87
+ * @return bool
88
+ */
89
+ private function validateCurrencyCode( $currencyCode ) {
90
+ return in_array( $currencyCode, $this->multiCurrency->get_currency_codes() );
91
+ }
92
+
93
+ }
classes/Multicurrency/Shipping/LocalPickup.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class LocalPickup implements ShippingMode {
6
+ use ShippingModeBase;
7
+ use VariableCost;
8
+
9
+ public function getMethodId() {
10
+ return 'local_pickup';
11
+ }
12
+ }
classes/Multicurrency/Shipping/ShippingClasses.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class ShippingClasses {
6
+ /**
7
+ * Adds shipping classes for currencies fields to shipping method wp-admin GUI.
8
+ *
9
+ * @param array $field
10
+ * @param \WCML_Multi_Currency $wcmlMultiCurrency
11
+ *
12
+ * @return array
13
+ */
14
+ public static function addFields( array $field, \WCML_Multi_Currency $wcmlMultiCurrency ) {
15
+ $shippingClasses = WC()->shipping()->get_shipping_classes();
16
+ if ( ! empty( $shippingClasses ) ) {
17
+ foreach ( $wcmlMultiCurrency->get_currency_codes() as $currencyCode ) {
18
+ if ( $wcmlMultiCurrency->get_default_currency() === $currencyCode ) {
19
+ continue;
20
+ }
21
+ foreach ( $shippingClasses as $shippingClass ) {
22
+ $classSourceLanguageCode = self::getSourceLanguageCode( $shippingClass );
23
+ if ( $classSourceLanguageCode === null ) {
24
+ $field = self::addShippingClassField( $field, $shippingClass, $currencyCode );
25
+ } else {
26
+ $field = self::askToSwitchLanguage( $field, $shippingClass, $classSourceLanguageCode );
27
+ }
28
+ }
29
+ $field = self::addNoShippingClassField( $field, $currencyCode );
30
+ }
31
+ }
32
+ return $field;
33
+ }
34
+
35
+ /**
36
+ * Returns source language of the shipping class which was created originally.
37
+ *
38
+ * @param WP_Term $shippingClass
39
+ *
40
+ * @return string|null
41
+ */
42
+ protected static function getSourceLanguageCode( $shippingClass ) {
43
+ $classLanguageDetails = apply_filters( 'wpml_element_language_details', null, [
44
+ 'element_id' => $shippingClass->term_id,
45
+ 'element_type' => $shippingClass->taxonomy,
46
+ ] );
47
+ return isset( $classLanguageDetails->source_language_code ) ? $classLanguageDetails->source_language_code : null;
48
+ }
49
+
50
+ /**
51
+ * Adds field to the GUI which explains user should switch to the other language to provide the data.
52
+ *
53
+ * @param array $field
54
+ * @param WP_Tern $shippingClass
55
+ * @param string $classSourceLanguageCode
56
+ *
57
+ * @return array
58
+ */
59
+ protected static function askToSwitchLanguage( $field, $shippingClass, $classSourceLanguageCode ) {
60
+ $field[ 'wcml_ask_to_switch_language_' . $shippingClass->term_id ] = [
61
+ 'title' => '',
62
+ 'description' => sprintf( __( 'Your shipping class %s has been created in %s language. Please switch your language if you want to provide shipping costs in different currencies for this class.', 'woocommerce-multilingual' ),
63
+ $shippingClass->name,
64
+ $classSourceLanguageCode),
65
+ 'type' => 'title'
66
+ ];
67
+ return $field;
68
+ }
69
+
70
+ protected static function addShippingClassField( $field, $shippingClass, $currencyCode ) {
71
+ $field[ 'class_cost_' . $shippingClass->term_id . '_' . $currencyCode ] = [
72
+ 'title' => sprintf( __( '"%s" shipping class cost in %s', 'woocommerce-multilingual' ), esc_html( $shippingClass->name ), esc_html( $currencyCode ) ),
73
+ 'type' => 'text',
74
+ 'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
75
+ 'class' => 'wcml-shipping-cost-currency'
76
+ ];
77
+ return $field;
78
+ }
79
+
80
+ protected static function addNoShippingClassField( $field, $currencyCode ) {
81
+ $field[ 'no_class_cost_' . $currencyCode ] = [
82
+ 'title' => sprintf( __( 'No shipping class cost in %s', 'woocommerce-multilingual' ), esc_html( $currencyCode ) ),
83
+ 'type' => 'text',
84
+ 'placeholder' => __( 'N/A', 'woocommerce-multilingual' ),
85
+ 'default' => '',
86
+ 'class' => 'wcml-shipping-cost-currency'
87
+ ];
88
+ return $field;
89
+ }
90
+ }
classes/Multicurrency/Shipping/ShippingClassesMode.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ interface ShippingClassesMode extends ShippingMode {
6
+ /**
7
+ * @param array|object $rate
8
+ * @param string $currency
9
+ * @param string $shippingClassKey
10
+ *
11
+ * @return int|mixed|string Shipping class cost for given currency.
12
+ */
13
+ public function getShippingClassCostValue( $rate, $currency, $shippingClassKey );
14
+
15
+ /**
16
+ * @param array|object $rate
17
+ * @param string $currency
18
+ *
19
+ * @return int|mixed|string "No shipping class" cost for given currency.
20
+ */
21
+ public function getNoShippingClassCostValue( $rate, $currency );
22
+ }
classes/Multicurrency/Shipping/ShippingHooksFactory.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class ShippingHooksFactory implements \IWPML_Deferred_Action_Loader, \IWPML_Backend_Action_Loader, \IWPML_Frontend_Action_Loader {
6
+
7
+ public function get_load_action() {
8
+ return 'init';
9
+ }
10
+
11
+ public function create() {
12
+ /** @var \woocommerce_wpml $woocommerce_wpml */
13
+ global $woocommerce_wpml;
14
+ $hooks = [];
15
+
16
+ if ( wcml_is_multi_currency_on()
17
+ && $this->hasAdditionalCurrencyDefined()
18
+ ) {
19
+ if ( $this->isShippingPageRequest() || $this->isAjaxOnShippingPageRequest() ) {
20
+ $hooks[] = new AdminHooks( $woocommerce_wpml->get_multi_currency() );
21
+ } else {
22
+ $hooks[] = new FrontEndHooks( $woocommerce_wpml->get_multi_currency() );
23
+ }
24
+ }
25
+
26
+ return $hooks;
27
+ }
28
+
29
+ /**
30
+ * Does user defined at least one additional currency in WCML.
31
+ *
32
+ * @return bool
33
+ */
34
+ private function hasAdditionalCurrencyDefined() {
35
+ /** @var \woocommerce_wpml $woocommerce_wpml */
36
+ global $woocommerce_wpml;
37
+
38
+ $available_currencies = $woocommerce_wpml->get_multi_currency()->get_currency_codes();
39
+
40
+ return is_array( $available_currencies ) && count( $available_currencies ) > 1;
41
+ }
42
+
43
+ private function isShippingPageRequest() {
44
+ return isset( $_GET['page'], $_GET['tab'] ) && 'wc-settings' === $_GET['page'] && 'shipping' === $_GET['tab']
45
+ || isset( $_GET['action'] ) && 'woocommerce_shipping_zone_methods_save_settings' === $_GET['action'];
46
+ }
47
+
48
+ private function isAjaxOnShippingPageRequest() {
49
+ if ( ! isset( $_GET ) ) {
50
+ return false;
51
+ }
52
+ $getData = wpml_collect( $_GET );
53
+ $shippingActions = [ 'woocommerce_shipping_zone_add_method', 'woocommerce_shipping_zone_methods_save_changes' ];
54
+
55
+ return is_ajax() && wpml_collect( $shippingActions )->containsStrict( $getData->get( 'action' ) );
56
+ }
57
+ }
classes/Multicurrency/Shipping/ShippingMode.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ interface ShippingMode {
6
+ /**
7
+ * Returns shipping method id (shipping option key).
8
+ *
9
+ * @return string
10
+ */
11
+ public function getMethodId();
12
+
13
+ /**
14
+ * Returns field title.
15
+ *
16
+ * This value is visible on shipping method configuration screen, on the left.
17
+ *
18
+ * @param string $currencyCode
19
+ *
20
+ * @return string
21
+ */
22
+ public function getFieldTitle( $currencyCode );
23
+
24
+ /**
25
+ * Returns field description.
26
+ *
27
+ * This value is visible on shipping method configuration screen, when mouse over
28
+ * the question mark icon, next to field title.
29
+ *
30
+ * @param string $currencyCode
31
+ *
32
+ * @return string
33
+ */
34
+ public function getFieldDescription( $currencyCode );
35
+
36
+ /**
37
+ * Return the key which will be used in shipping method configuration form.
38
+ *
39
+ * @param string $currencyCode
40
+ *
41
+ * @return string|null
42
+ */
43
+ public function getSettingsFormKey( $currencyCode );
44
+
45
+ /**
46
+ * If shipping mode has minimal order amount, recalculate and return its value.
47
+ *
48
+ * @param integer|float|string $amount The value as saved for original language.
49
+ * @param array $shipping The shipping metadata.
50
+ * @param string $currency Currency code.
51
+ *
52
+ * @return integer|float|string
53
+ */
54
+ public function getMinimalOrderAmountValue( $amount, $shipping, $currency );
55
+
56
+ /**
57
+ * If shipping mode has custom cost, recalculate and return its value.
58
+ *
59
+ * @param array|object $rate Shipping rate metadata.
60
+ * @param string $currency Currency code.
61
+ *
62
+ * @return integer|float|string
63
+ */
64
+ public function getShippingCostValue( $rate, $currency );
65
+
66
+ /**
67
+ * Checks if the instance of the shipping method has enabled manual pricing.
68
+ *
69
+ * @param array|object $instance Currently processed instance of the shipping method.
70
+ *
71
+ * @return bool
72
+ */
73
+ public function isManualPricingEnabled( $instance );
74
+
75
+ }
classes/Multicurrency/Shipping/ShippingModeBase.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ trait ShippingModeBase {
6
+ /**
7
+ * @param array|object
8
+ *
9
+ * @return bool
10
+ */
11
+ public static function isEnabled( $rate_settings ) {
12
+ return isset( $rate_settings[ AdminHooks::WCML_SHIPPING_COSTS ] ) && 'manual' === $rate_settings[ AdminHooks::WCML_SHIPPING_COSTS ];
13
+ }
14
+ }
classes/Multicurrency/Shipping/ShippingModeProvider.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class ShippingModeProvider {
6
+
7
+ private static function getClasses() {
8
+ $collection = wpml_collect( [
9
+ 'flat_rate' => 'WCML\Multicurrency\Shipping\FlatRateShipping',
10
+ 'free_shipping' => 'WCML\Multicurrency\Shipping\FreeShipping',
11
+ 'local_pickup' => 'WCML\Multicurrency\Shipping\LocalPickup',
12
+ ] );
13
+ return $collection;
14
+ }
15
+
16
+ public static function getAll() {
17
+ return self::getClasses()->map( function( $className ) {
18
+ return self::make( $className );
19
+ } );
20
+ }
21
+
22
+ /**
23
+ * @param string $shippingMode
24
+ * @return ShippingMode
25
+ */
26
+ public static function get( $shippingMode ) {
27
+ return self::make(
28
+ self::getClasses()->get( $shippingMode, 'WCML\Multicurrency\Shipping\UnsupportedShipping' )
29
+ );
30
+ }
31
+
32
+ /**
33
+ * @param $className
34
+ * @return ShippingMode
35
+ */
36
+ private static function make( $className ) {
37
+ return \WPML\Container\make( $className );
38
+ }
39
+ }
classes/Multicurrency/Shipping/UnsupportedShipping.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ class UnsupportedShipping implements ShippingMode {
6
+
7
+ public function getMethodId() {
8
+ // TODO: Implement getMethodId() method.
9
+ }
10
+
11
+ public function getFieldTitle( $currencyCode ) {
12
+ // TODO: Implement getFieldTitle() method.
13
+ }
14
+
15
+ public function getFieldDescription( $currencyCode ) {
16
+ // TODO: Implement getFieldDescription() method.
17
+ }
18
+
19
+ public function getSettingsFormKey( $currencyCode ) {
20
+ return null;
21
+ }
22
+
23
+ public function getMinimalOrderAmountValue( $amount, $shipping, $currency ) {
24
+ return $amount;
25
+ }
26
+
27
+ public function isManualPricingEnabled( $instance = false ) {
28
+ return false;
29
+ }
30
+
31
+ public function getMinimalOrderAmountKey( $currencyCode ) {
32
+ // TODO: Implement getMinAmountKey() method.
33
+ }
34
+
35
+ public function getShippingCostValue( $rate, $currency ) {
36
+ if ( ! isset( $rate->cost ) ) {
37
+ $rate->cost = 0;
38
+ }
39
+ return $rate->cost;
40
+ }
41
+ }
classes/Multicurrency/Shipping/VariableCost.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Multicurrency\Shipping;
4
+
5
+ trait VariableCost {
6
+ use DefaultConversion;
7
+
8
+ /**
9
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getFieldTitle
10
+ *
11
+ * @param string $currencyCode
12
+ *
13
+ * return string
14
+ */
15
+ public function getFieldTitle( $currencyCode ) {
16
+ return sprintf( esc_html_x( 'Cost in %s',
17
+ 'The label for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
18
+ 'woocommerce-multilingual' ), $currencyCode );
19
+ }
20
+
21
+ private $wpOption = null;
22
+
23
+ /**
24
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getFieldDescription
25
+ *
26
+ * @param string $currencyCode
27
+ *
28
+ * @return string
29
+ */
30
+ public function getFieldDescription( $currencyCode ) {
31
+ return sprintf( esc_html_x( 'The shipping cost if customer choose %s as a purchase currency.',
32
+ 'The description for the field with shipping cost in additional currency. The currency symbol will be added in place of %s specifier.',
33
+ 'woocommerce-multilingual' ), $currencyCode );
34
+ }
35
+
36
+ /**
37
+ * Returns cost key for given currency.
38
+ *
39
+ * @param string $currencyCode Currency code.
40
+ *
41
+ * @return string
42
+ */
43
+ private function getCostKey( $currencyCode ) {
44
+ return sprintf( 'cost_%s', $currencyCode );
45
+ }
46
+
47
+ private function getShippingClassCostKey( $shippingClassKey, $currency ) {
48
+ return $this->replaceShippingClassId( $shippingClassKey ) . '_' . $currency;
49
+ }
50
+
51
+ private function getNoShippingClassCostKey( $currency ) {
52
+ return 'no_class_cost_' . $currency;
53
+ }
54
+
55
+ /**
56
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getSettingsFormKey
57
+ *
58
+ * @param string $currencyCode
59
+ *
60
+ * @return string
61
+ */
62
+ public function getSettingsFormKey( $currencyCode ) {
63
+ return $this->getCostKey( $currencyCode );
64
+ }
65
+
66
+ /**
67
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getMinimalOrderAmountValue
68
+ *
69
+ * @param integer|float|string $amount The value as saved for original language.
70
+ * @param array $shipping The shipping metadata.
71
+ * @param string $currency Currency code.
72
+ *
73
+ * @return mixed
74
+ */
75
+ public function getMinimalOrderAmountValue( $amount, $shipping, $currency ) {
76
+ return $amount;
77
+ }
78
+
79
+ /**
80
+ * @param array|object $rate
81
+ * @param string $currency
82
+ *
83
+ * @return int|mixed|string
84
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::getShippingCostValue
85
+ *
86
+ */
87
+ public function getShippingCostValue( $rate, $currency ) {
88
+ $costName = $this->getCostKey( $currency );
89
+ return $this->getCostValueForName( $rate, $currency, $costName, 'cost' );
90
+ }
91
+
92
+ /**
93
+ * @see \WCML\Multicurrency\Shipping\ShippingClassesMode::getShippingClassCostValue
94
+ *
95
+ * @param array|object $rate
96
+ * @param string $currency
97
+ * @param string $shippingClassKey
98
+ *
99
+ * @return int Shipping class cost for given currency.
100
+ */
101
+ public function getShippingClassCostValue( $rate, $currency, $shippingClassKey ) {
102
+ $costName = $this->getShippingClassCostKey( $shippingClassKey, $currency );
103
+ return $this->getCostValueForName( $rate, $currency, $costName, $shippingClassKey );
104
+ }
105
+
106
+ /**
107
+ * @see \WCML\Multicurrency\Shipping\ShippingClassesMode::getNoShippingClassCostValue
108
+ *
109
+ * @param array|object $rate
110
+ * @param string $currency
111
+ *
112
+ * @return int "No shipping class" cost for given currency.
113
+ */
114
+ public function getNoShippingClassCostValue( $rate, $currency ) {
115
+ $costName = $this->getNoShippingClassCostKey( $currency );
116
+ return $this->getCostValueForName( $rate, $currency, $costName, 'no_class_cost' );
117
+ }
118
+
119
+ private function getCostValueForName( $rate, $currency, $costName, $rateField ) {
120
+ if ( ! isset( $rate->$rateField ) ) {
121
+ $rate->$rateField = 0;
122
+ }
123
+ if ( isset( $rate->instance_id ) ) {
124
+ if ( $this->isManualPricingEnabled( $rate ) ) {
125
+ $rateSettings = $this->getWpOption( $this->getMethodId(), $rate->instance_id );
126
+ if ( ! empty( $rateSettings[ $costName ] ) ) {
127
+ $rate->$rateField = $rateSettings[ $costName ];
128
+ } else {
129
+ $rate->$rateField = $this->getValueFromDefaultCurrency( $rate->$rateField, $rateSettings, $costName, $currency );
130
+ }
131
+ }
132
+ }
133
+ return $rate->$rateField;
134
+ }
135
+
136
+ /**
137
+ * @see \WCML\Multicurrency\Shipping\ShippingMode::isManualPricingEnabled
138
+ *
139
+ * @param \WC_Shipping_Rate $instance
140
+ *
141
+ * @return mixed
142
+ */
143
+ public function isManualPricingEnabled( $instance ) {
144
+ return self::isEnabled( $this->getWpOption( $this->getMethodId(), $instance->instance_id ) );
145
+ }
146
+
147
+ /**
148
+ * Returns shipping data from wp_options table.
149
+ *
150
+ * @param string $methodId
151
+ * @param int $instanceId
152
+ *
153
+ * @return bool|mixed|void|null
154
+ */
155
+ private function getWpOption( $methodId, $instanceId ) {
156
+ if ( null === $this->wpOption ) {
157
+ $optionName = sprintf( 'woocommerce_%s_%d_settings', $methodId, $instanceId );
158
+ $this->wpOption = get_option( $optionName );
159
+ }
160
+ return $this->wpOption;
161
+ }
162
+
163
+ /**
164
+ * Extracts numeric shipping class ID from shipping class key.
165
+ *
166
+ * @param string $key
167
+ *
168
+ * @return false|string Class ID or false if not found.
169
+ */
170
+ private function getShippingClassTermId( $key ) {
171
+ if ( preg_match( '/^class_cost_(\d*)(_[A-Z]*)*$/', $key, $matches ) && isset( $matches[1] ) ) {
172
+ return $matches[1];
173
+ }
174
+ return false;
175
+ }
176
+ /**
177
+ * @param string $shippingClassKey
178
+ *
179
+ * @return string
180
+ */
181
+ private function replaceShippingClassId( $shippingClassKey ) {
182
+ $termId = $this->getShippingClassTermId( $shippingClassKey );
183
+ if ( $termId ) {
184
+ $termTrid = apply_filters( 'wpml_element_trid', null, $termId, 'tax_product_shipping_class' );
185
+ $termTranslations = apply_filters( 'wpml_get_element_translations', null, $termTrid, 'tax_product_shipping_class' );
186
+ if ( is_array( $termTranslations ) ) {
187
+ foreach ( $termTranslations as $languageCode => $translation ) {
188
+ if ( $translation->source_language_code === null ) {
189
+ $originalTermId = $translation->element_id;
190
+ break;
191
+ }
192
+ }
193
+ $shippingClassKey = str_replace( $termId, $originalTermId, $shippingClassKey );
194
+ }
195
+ }
196
+ return $shippingClassKey;
197
+ }
198
+
199
+
200
+ /**
201
+ * wrapper for getShippingClassTermId to avail testing private method.
202
+ *
203
+ * @param $key
204
+ *
205
+ * @return bool|false|string
206
+ */
207
+ public function _testGetShippingClassTermId( $key ) {
208
+ if ( ! isset( $_SERVER['SCRIPT_NAME'] ) || stristr( $_SERVER['SCRIPT_NAME'], 'phpunit' ) === false ) {
209
+ die( "don't run this method directly outside phpunit env" );
210
+ }
211
+ return $this->getShippingClassTermId( $key );
212
+ }
213
+ }
classes/Tax/Strings/Hooks.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace WCML\Tax\Strings;
4
+
5
+ use IWPML_Backend_Action;
6
+ use IWPML_Frontend_Action;
7
+
8
+ class Hooks implements IWPML_Backend_Action, IWPML_Frontend_Action {
9
+
10
+ const STRINGS_CONTEXT = 'admin_texts_woocommerce_tax';
11
+
12
+ public function add_hooks() {
13
+ add_action( 'woocommerce_tax_rate_added', [ $this, 'registerLabelString' ], 10, 2 );
14
+ add_action( 'woocommerce_tax_rate_updated', [ $this, 'registerLabelString' ], 10, 2 );
15
+ add_filter( 'woocommerce_rate_label', [ $this, 'translateLabelString' ], 10, 2 );
16
+ }
17
+
18
+ /**
19
+ * @param string $label
20
+ * @param int $taxId
21
+ *
22
+ * @return string
23
+ */
24
+ public function translateLabelString( $label, $taxId ) {
25
+
26
+ $stringId = icl_get_string_id( $label, self::STRINGS_CONTEXT, $this->getStringName( $taxId ) );
27
+
28
+ if ( ! $stringId ) {
29
+ $this->migrateStringToTaxIdName( $taxId, $label );
30
+ }
31
+
32
+ return icl_translate( self::STRINGS_CONTEXT, $this->getStringName( $taxId ), $label );
33
+ }
34
+
35
+ /**
36
+ * @param int $taxId
37
+ * @param array $taxRate
38
+ */
39
+ public function registerLabelString( $taxId, $taxRate ) {
40
+ if ( ! empty( $taxRate['tax_rate_name'] ) ) {
41
+ $this->registerString( $taxId, $taxRate['tax_rate_name'] );
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @param int $taxId
47
+ * @param string $label
48
+ *
49
+ * @return int
50
+ */
51
+ private function registerString( $taxId, $label ) {
52
+ return icl_register_string( self::STRINGS_CONTEXT, $this->getStringName( $taxId ), $label );
53
+ }
54
+
55
+ /**
56
+ * migration from WCML < 4.9.0
57
+ *
58
+ * @param int $taxId
59
+ * @param string $label
60
+ */
61
+ private function migrateStringToTaxIdName( $taxId, $label ) {
62
+ $newStringId = $this->registerString( $taxId, $label );
63
+
64
+ $oldStringId = icl_get_string_id( $label, 'woocommerce taxes', $label );
65
+
66
+ $oldStringTranslations = icl_get_string_translations_by_id( $oldStringId );
67
+
68
+ foreach ( $oldStringTranslations as $languageCode => $translation ) {
69
+ icl_add_string_translation(
70
+ $newStringId,
71
+ $languageCode,
72
+ $translation['value'],
73
+ ICL_STRING_TRANSLATION_COMPLETE
74
+ );
75
+ }
76
+ }
77
+
78
+ /**
79
+ * @param int $taxId
80
+ *
81
+ * @return string
82
+ */
83
+ private function getStringName( $taxId ) {
84
+ return 'tax_label_' . $taxId;
85
+ }
86
+
87
+ }
compatibility/class-wcml-composite-products.php CHANGED
@@ -35,13 +35,12 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
35
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
36
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
37
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
38
- add_action( 'wcml_before_sync_product', array( $this, 'sync_composite_data_across_translations'), 10, 2 );
39
  add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
40
- if( is_admin() ){
41
 
42
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
43
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
44
- add_action( 'wcml_before_sync_product_data', array( $this, 'components_update' ), 10, 3 );
45
  add_action( 'wcml_update_extra_fields', array( $this, 'update_component_strings' ), 10, 4 );
46
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
47
 
@@ -87,7 +86,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
87
 
88
  return $selected_value;
89
  }
90
-
91
  public function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
92
 
93
  if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
@@ -109,11 +108,12 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
109
  return $args;
110
  }
111
 
112
- public function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
113
 
114
  if( $this->get_product_type( $original_product_id ) == 'composite' ){
115
 
116
  $composite_data = $this->get_composite_data( $original_product_id );
 
117
 
118
  $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
119
  $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
@@ -151,12 +151,43 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
151
 
152
  }
153
 
 
 
 
 
 
 
 
 
154
  }
155
 
156
  update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
157
 
158
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
159
 
 
 
160
  }
161
  }
162
 
@@ -279,73 +310,6 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
279
  return $data;
280
  }
281
 
282
- public function components_update( $original_product_id, $product_id, $language ){
283
-
284
- $composite_data = $this->get_composite_data( $original_product_id );
285
-
286
- foreach( $composite_data as $component_id => $component ) {
287
-
288
- //sync product ids
289
- if( $component[ 'query_type' ] == 'product_ids' ){
290
- foreach( $component[ 'assigned_ids' ] as $key => $assigned_id ){
291
- $assigned_id_current_language = apply_filters( 'translate_object_id', $assigned_id, get_post_type( $assigned_id ), false, $language );
292
- if( $assigned_id_current_language ){
293
- $composite_data[ $component_id ][ 'assigned_ids' ][ $key ] = $assigned_id_current_language;
294
- }
295
- }
296
- }elseif( $component[ 'query_type' ] == 'category_ids' ){
297
- foreach( $component[ 'assigned_category_ids' ] as $key => $assigned_id ){
298
- $trsl_term_id = apply_filters( 'translate_object_id', $assigned_id, 'product_cat', false, $language );
299
- if( $trsl_term_id ){
300
- $composite_data[ $component_id ][ 'assigned_category_ids' ][ $key ] = $trsl_term_id;
301
- }
302
- }
303
- }
304
-
305
- //sync default
306
- if( $component[ 'default_id' ] ){
307
- $trnsl_default_id = apply_filters( 'translate_object_id', $component[ 'default_id' ], get_post_type( $component[ 'default_id' ] ), false, $language );
308
- if( $trnsl_default_id ){
309
- $composite_data[ $component_id ][ 'default_id' ] = $trnsl_default_id;
310
- }
311
- }
312
-
313
- }
314
-
315
- update_post_meta( $product_id, '_bto_data', $composite_data );
316
-
317
- $composite_scenarios_meta = $this->get_composite_scenarios_meta( $original_product_id );
318
- if( $composite_scenarios_meta ){
319
- foreach( $composite_scenarios_meta as $scenario_key => $scenario_meta ){
320
- //sync product ids
321
- foreach( $scenario_meta[ 'component_data' ] as $compon_id => $component_data ){
322
- if( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'product_ids' ){
323
- foreach( $component_data as $key => $assigned_prod_id ){
324
- $trnsl_assigned_prod_id = apply_filters( 'translate_object_id', $assigned_prod_id, get_post_type( $assigned_prod_id ), false, $language );
325
- if( $trnsl_assigned_prod_id ){
326
- $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trnsl_assigned_prod_id;
327
- }
328
- }
329
- }elseif( isset( $composite_data[ $compon_id ] ) && $composite_data[ $compon_id ][ 'query_type' ] == 'category_ids' ){
330
- foreach( $component_data as $key => $assigned_cat_id ){
331
- $trslt_assigned_cat_id = apply_filters( 'translate_object_id', $assigned_cat_id, 'product_cat', false, $language );
332
- if( $trslt_assigned_cat_id ){
333
- $composite_scenarios_meta[ $scenario_key ][ 'component_data' ][ $compon_id ][ $key ] = $trslt_assigned_cat_id;
334
- }
335
- }
336
- }
337
- }
338
- }
339
- }
340
-
341
- update_post_meta( $product_id, '_bto_scenario_data', $composite_scenarios_meta );
342
-
343
- return array(
344
- 'components' => $composite_data,
345
- 'scenarios' => $composite_scenarios_meta,
346
- );
347
- }
348
-
349
 
350
  public function update_component_strings( $original_product_id, $product_id, $data, $language ){
351
 
@@ -553,7 +517,7 @@ class WCML_Composite_Products extends WCML_Compatibility_Helper{
553
  $original_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
554
 
555
  $cost_status = get_post_meta( $original_id, '_wcml_custom_prices_status', true );
556
-
557
  $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
558
 
559
  if ( $currency === wcml_get_woocommerce_currency_option() ) {
35
  add_filter( 'woocommerce_composite_component_default_option', array($this, 'woocommerce_composite_component_default_option'), 10, 3 );
36
  add_filter( 'wcml_cart_contents', array($this, 'wpml_composites_compat'), 11, 4 );
37
  add_filter( 'woocommerce_composite_component_options_query_args', array($this, 'wpml_composites_transients_cache_per_language'), 10, 3 );
38
+ add_action( 'wcml_before_sync_product_data', array( $this, 'sync_composite_data_across_translations' ), 10, 2 );
39
  add_action( 'wpml_translation_job_saved', array( $this, 'save_composite_data_translation' ), 10, 3 );
40
+ if( is_admin() ){
41
 
42
  add_action( 'wcml_gui_additional_box_html', array( $this, 'custom_box_html' ), 10, 3 );
43
  add_filter( 'wcml_gui_additional_box_data', array( $this, 'custom_box_html_data' ), 10, 4 );
 
44
  add_action( 'wcml_update_extra_fields', array( $this, 'update_component_strings' ), 10, 4 );
45
  add_filter( 'woocommerce_json_search_found_products', array( $this, 'woocommerce_json_search_found_products' ) );
46
 
86
 
87
  return $selected_value;
88
  }
89
+
90
  public function wpml_composites_compat( $new_cart_data, $cart_contents, $key, $new_key ) {
91
 
92
  if ( isset( $cart_contents[ $key ][ 'composite_children' ] ) || isset( $cart_contents[ $key ][ 'composite_parent' ] ) ) {
108
  return $args;
109
  }
110
 
111
+ public function sync_composite_data_across_translations( $original_product_id, $current_product_id ){
112
 
113
  if( $this->get_product_type( $original_product_id ) == 'composite' ){
114
 
115
  $composite_data = $this->get_composite_data( $original_product_id );
116
+ $composite_scenarios_meta = $this->get_composite_scenarios_meta( $original_product_id );
117
 
118
  $product_trid = $this->sitepress->get_element_trid( $original_product_id, 'post_product' );
119
  $product_translations = $this->sitepress->get_element_translations( $product_trid, 'post_product' );
151
 
152
  }
153
 
154
+ //sync default
155
+ if ( isset( $component['default_id'] ) && $component['default_id'] ) {
156
+ $translated_default_id = apply_filters( 'translate_object_id', $component['default_id'], get_post_type( $component['default_id'] ), false, $product_translation->language_code );
157
+ if ( $translated_default_id ) {
158
+ $composite_data[ $component_id ]['default_id'] = $translated_default_id;
159
+ }
160
+ }
161
+
162
  }
163
 
164
  update_post_meta( $product_translation->element_id, '_bto_data', $composite_data );
165
 
166
+ if ( $composite_scenarios_meta ) {
167
+ foreach ( $composite_scenarios_meta as $scenario_key => $scenario_meta ) {
168
+ //sync product ids
169
+ foreach ( $scenario_meta['component_data'] as $component_id => $component_data ) {
170
+ if ( isset( $composite_data[ $component_id ] ) && $composite_data[ $component_id ]['query_type'] == 'product_ids' ) {
171
+ foreach ( $component_data as $key => $assigned_prod_id ) {
172
+ $translated_assigned_product_id = apply_filters( 'translate_object_id', $assigned_prod_id, get_post_type( $assigned_prod_id ), false, $product_translation->language_code );
173
+ if ( $translated_assigned_product_id ) {
174
+ $composite_scenarios_meta[ $scenario_key ]['component_data'][ $component_id ][ $key ] = $translated_assigned_product_id;
175
+ }
176
+ }
177
+ } elseif ( isset( $composite_data[ $component_id ] ) && $composite_data[ $component_id ]['query_type'] == 'category_ids' ) {
178
+ foreach ( $component_data as $key => $assigned_cat_id ) {
179
+ $translated_assigned_category_id = apply_filters( 'translate_object_id', $assigned_cat_id, 'product_cat', false, $product_translation->language_code );
180
+ if ( $translated_assigned_category_id ) {
181
+ $composite_scenarios_meta[ $scenario_key ]['component_data'][ $component_id ][ $key ] = $translated_assigned_category_id;
182
+ }
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
 
189
+ update_post_meta( $product_translation->element_id, '_bto_scenario_data', $composite_scenarios_meta );
190
+ }
191
  }
192
  }
193
 
310
  return $data;
311
  }
312
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
313
 
314
  public function update_component_strings( $original_product_id, $product_id, $data, $language ){
315
 
517
  $original_id = $this->woocommerce_wpml->products->get_original_product_id( $object_id );
518
 
519
  $cost_status = get_post_meta( $original_id, '_wcml_custom_prices_status', true );
520
+
521
  $currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
522
 
523
  if ( $currency === wcml_get_woocommerce_currency_option() ) {
compatibility/class-wcml-gravityforms.php CHANGED
@@ -34,7 +34,8 @@ class WCML_gravityforms {
34
 
35
 
36
  public function add_ajax_action( $actions ) {
37
- $actions[] = 'get_updated_price';
 
38
  return $actions;
39
  }
40
 
34
 
35
 
36
  public function add_ajax_action( $actions ) {
37
+ $actions[] = 'get_updated_price'; // Deprecated from 2.7.
38
+ $actions[] = 'gforms_get_updated_price';
39
  return $actions;
40
  }
41
 
compatibility/class-wcml-tab-manager.php CHANGED
@@ -547,7 +547,7 @@ class WCML_Tab_Manager {
547
  $new_wc_product_tab = [
548
  'post_type' => 'wp_product_tab',
549
  'post_title' => $value['title'],
550
- 'post_content' => $value['description'],
551
  'post_status' => 'publish',
552
  ];
553
 
@@ -603,6 +603,13 @@ class WCML_Tab_Manager {
603
  $translated_product_tabs_updated = true;
604
  }
605
 
 
 
 
 
 
 
 
606
  if ( true === $translated_product_tabs_updated && isset( $translated_product_tabs ) ) {
607
  update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
608
  }
547
  $new_wc_product_tab = [
548
  'post_type' => 'wp_product_tab',
549
  'post_title' => $value['title'],
550
+ 'post_content' => isset( $value['description'] ) ? $value['description'] : '',
551
  'post_status' => 'publish',
552
  ];
553
 
603
  $translated_product_tabs_updated = true;
604
  }
605
 
606
+ foreach ( $original_product_tabs as $original_product_tab ) {
607
+ if ( 'global' === $original_product_tab['type'] ) {
608
+ $translated_product_tabs = $this->set_global_tab( $original_product_tab, $translated_product_tabs, $job->language_code );
609
+ $translated_product_tabs_updated = true;
610
+ }
611
+ }
612
+
613
  if ( true === $translated_product_tabs_updated && isset( $translated_product_tabs ) ) {
614
  update_post_meta( $post_id, '_product_tabs', $translated_product_tabs );
615
  }
dist/js/multicurrencyShippingAdmin/app.js ADDED
@@ -0,0 +1 @@
 
1
+ !function(e){var t={};function n(r){if(t[r])return t[r].exports;var c=t[r]={i:r,l:!1,exports:{}};return e[r].call(c.exports,c,c.exports,n),c.l=!0,c.exports}n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=2)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(){var e=new MutationObserver(function(e){e.forEach(function(e){if("childList"===e.type){var t=document.querySelectorAll(".wcml-shipping-cost-currency");t.length>0&&(function(e){var t=document.querySelector('.select.wcml-enable-shipping-custom-currency option[selected="selected"]');e.forEach(function(e){e.closest("tr").hidden="auto"===t.value})}(t),function(e){var t=document.querySelector(".select.wcml-enable-shipping-custom-currency");t.addEventListener("change",function(n){e.forEach(function(e){e.closest("tr").hidden="manual"!==t.value})})}(t))}})}),t=document.querySelector(".woocommerce_page_wc-settings");e.observe(t,{attributes:!0,childList:!0,characterData:!0})}},function(e,t,n){"use strict";var r=function(e){return e&&e.__esModule?e:{default:e}}(n(0));document.addEventListener("DOMContentLoaded",r.default,!1)},function(e,t,n){e.exports=n(1)}]);
inc/class-wcml-attributes.php CHANGED
@@ -45,10 +45,10 @@ class WCML_Attributes {
45
  add_action( 'init', [ $this, 'init' ] );
46
 
47
  add_filter(
48
- 'wpml_translation_job_post_meta_value_translated',
49
  [
50
  $this,
51
- 'filter_product_attributes_for_translation',
52
  ],
53
  10,
54
  2
@@ -325,7 +325,7 @@ class WCML_Attributes {
325
  $orig_product_attrs = $this->get_product_attributes( $original_product_id );
326
  $trnsl_product_attrs = $this->get_product_attributes( $tr_product_id );
327
 
328
- $translated_labels = [];
329
 
330
  foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
331
  $sanitized_key = $this->filter_attribute_name( $orig_product_attr['name'], $original_product_id, true );
@@ -528,11 +528,19 @@ class WCML_Attributes {
528
  return $attribute;
529
  }
530
 
531
- public function filter_product_attributes_for_translation( $translated, $key ) {
532
- $translated = $translated
533
- ? preg_match( '#^(?!field-_product_attributes-(.+)-(.+)-(?!value|name))#', $key ) : 0;
 
 
 
 
 
 
 
 
534
 
535
- return $translated;
536
  }
537
 
538
  public function icl_custom_tax_sync_options() {
45
  add_action( 'init', [ $this, 'init' ] );
46
 
47
  add_filter(
48
+ 'wpml_tm_job_field_is_translatable',
49
  [
50
  $this,
51
+ 'set_custom_product_attributes_as_translatable_for_tm_job',
52
  ],
53
  10,
54
  2
325
  $orig_product_attrs = $this->get_product_attributes( $original_product_id );
326
  $trnsl_product_attrs = $this->get_product_attributes( $tr_product_id );
327
 
328
+ $translated_labels = $this->get_attr_label_translations( $tr_product_id );
329
 
330
  foreach ( $orig_product_attrs as $key => $orig_product_attr ) {
331
  $sanitized_key = $this->filter_attribute_name( $orig_product_attr['name'], $original_product_id, true );
528
  return $attribute;
529
  }
530
 
531
+ /**
532
+ * @param int|bool $translatable
533
+ * @param array $job_translate
534
+ *
535
+ * @return bool|int
536
+ */
537
+ public function set_custom_product_attributes_as_translatable_for_tm_job( $translatable, $job_translate ) {
538
+
539
+ if ( 'wc_attribute' === substr( $job_translate['field_type'], 0, 12 ) ) {
540
+ return true;
541
+ }
542
 
543
+ return $translatable;
544
  }
545
 
546
  public function icl_custom_tax_sync_options() {
inc/class-wcml-emails.php CHANGED
@@ -369,7 +369,7 @@ class WCML_Emails {
369
  ]);
370
 
371
  if ( $adminEmails->contains( $object->id ) ) {
372
- $language = $this->get_admin_language_by_email( $object->recipient, $object->object->get_id() );
373
  }
374
 
375
  $translated_value = $this->get_email_translated_string( $key, $object, $language );
@@ -385,14 +385,30 @@ class WCML_Emails {
385
  *
386
  * @return string
387
  */
388
- public function get_email_translated_string( $key,
389
- $object, $language)
390
- {
391
 
392
  $context = 'admin_texts_woocommerce_' . $object->id . '_settings';
393
  $name = '[woocommerce_' . $object->id . '_settings]' . $key;
394
 
395
- return $this->wcml_get_translated_email_string( $context, $name, $object->object->get_id(), $language );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
396
  }
397
 
398
  public function new_order_admin_email( $order_id ) {
369
  ]);
370
 
371
  if ( $adminEmails->contains( $object->id ) ) {
372
+ $language = $this->get_admin_language_by_email( $object->recipient, $this->get_order_id_from_email_object( $object ) );
373
  }
374
 
375
  $translated_value = $this->get_email_translated_string( $key, $object, $language );
385
  *
386
  * @return string
387
  */
388
+ public function get_email_translated_string( $key, $object, $language ) {
 
 
389
 
390
  $context = 'admin_texts_woocommerce_' . $object->id . '_settings';
391
  $name = '[woocommerce_' . $object->id . '_settings]' . $key;
392
 
393
+ return $this->wcml_get_translated_email_string( $context, $name, $this->get_order_id_from_email_object( $object ), $language );
394
+ }
395
+
396
+ /**
397
+ * @param WC_Email $object
398
+ *
399
+ * @return bool|string|int
400
+ */
401
+ private function get_order_id_from_email_object( $object ) {
402
+
403
+ if ( method_exists( $object->object, 'get_id' ) ) {
404
+ return $object->object->get_id();
405
+ }
406
+
407
+ if ( is_array( $object->object ) && isset( $object->object['ID'] ) ) {
408
+ return $object->object['ID'];
409
+ }
410
+
411
+ return false;
412
  }
413
 
414
  public function new_order_admin_email( $order_id ) {
inc/class-wcml-orders.php CHANGED
@@ -400,7 +400,6 @@ class WCML_Orders {
400
  if ( isset( $_POST['wcml_shop_order_language'] ) ) {
401
  update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
402
  }
403
-
404
  }
405
 
406
  public function filter_downloadable_product_items( $files, $item, $object ) {
400
  if ( isset( $_POST['wcml_shop_order_language'] ) ) {
401
  update_post_meta( $post_id, 'wpml_language', filter_input( INPUT_POST, 'wcml_shop_order_language', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
402
  }
 
403
  }
404
 
405
  public function filter_downloadable_product_items( $files, $item, $object ) {
inc/class-wcml-url-translation.php CHANGED
@@ -273,15 +273,16 @@ class WCML_Url_Translation {
273
 
274
  if ( isset( $permalink_options['attribute_base'] ) && $permalink_options['attribute_base'] ) {
275
  $attr_base = trim( $permalink_options['attribute_base'], '/' );
 
276
 
277
- $string_language = $this->woocommerce_wpml->strings->get_string_language( $attr_base, $this->url_strings_context(), $name );
278
  if ( is_null( $string_language ) ) {
279
  $string_language = '';
280
  }
281
- do_action( 'wpml_register_single_string', $this->url_strings_context(), $this->url_string_name( 'attribute' ), $attr_base, false, $string_language );
282
 
283
  if ( isset( $_POST['attribute_base_language'] ) ) {
284
- $this->woocommerce_wpml->strings->set_string_language( $attr_base, $this->url_strings_context(), $this->url_string_name( 'attribute' ), $_POST['attribute_base_language'] );
285
  }
286
  }
287
 
273
 
274
  if ( isset( $permalink_options['attribute_base'] ) && $permalink_options['attribute_base'] ) {
275
  $attr_base = trim( $permalink_options['attribute_base'], '/' );
276
+ $attr_string_name = $this->url_string_name( 'attribute' );
277
 
278
+ $string_language = $this->woocommerce_wpml->strings->get_string_language( $attr_base, $this->url_strings_context(), $attr_string_name );
279
  if ( is_null( $string_language ) ) {
280
  $string_language = '';
281
  }
282
+ do_action( 'wpml_register_single_string', $this->url_strings_context(), $attr_string_name, $attr_base, false, $string_language );
283
 
284
  if ( isset( $_POST['attribute_base_language'] ) ) {
285
+ $this->woocommerce_wpml->strings->set_string_language( $attr_base, $this->url_strings_context(), $attr_string_name, $_POST['attribute_base_language'] );
286
  }
287
  }
288
 
inc/class-wcml-wc-gateways.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class WCML_WC_Gateways {
4
 
5
  const WCML_BACS_ACCOUNTS_CURRENCIES_OPTION = 'wcml_bacs_accounts_currencies';
@@ -144,45 +146,99 @@ class WCML_WC_Gateways {
144
 
145
  $postData = wpml_collect( $_POST );
146
  if ( $postData->isNotEmpty() ) {
147
-
148
- $is_user_order_note = 'woocommerce_add_order_note' === $postData->get( 'action' ) && 'customer' === $postData->get( 'note_type' );
149
- if ( $is_user_order_note ) {
150
- return get_post_meta( $postData->get( 'post_id' ), 'wpml_language', true );
 
 
151
  }
 
 
 
152
 
153
- $is_refund_line_item = 'woocommerce_refund_line_items' === $postData->get( 'action' );
154
- if ( $is_refund_line_item ) {
155
- return get_post_meta( $postData->get( 'order_id' ), 'wpml_language', true );
156
- }
 
 
 
 
 
157
 
158
- if ( $postData->get( 'post_ID' ) ) {
159
- $is_saving_new_order = wpml_collect( [ 'auto-draft', 'draft' ] )->contains( $postData->get( 'post_status' ) )
160
- && 'editpost' === $postData->get( 'action' )
161
- && $postData->get( 'save' );
162
- if ( $is_saving_new_order && isset( $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ] ) ) {
163
- return $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ];
164
- }
 
 
 
 
 
 
 
 
 
 
165
 
166
- $is_order_emails_status = wpml_collect( [ 'wc-completed', 'wc-processing', 'wc-refunded', 'wc-on-hold' ] )->contains( $postData->get( 'order_status' ) );
167
- $is_send_order_details_action = 'send_order_details' === $postData->get( 'wc_order_action' );
168
- if ( $is_order_emails_status || $is_send_order_details_action ) {
169
- return get_post_meta( $postData->get( 'post_ID' ), 'wpml_language', true );
170
- }
171
 
172
- return $this->current_language;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  }
174
  }
175
 
 
 
 
 
 
 
 
 
176
  $getData = wpml_collect( $_GET );
177
  if ( $getData->isNotEmpty() ) {
178
- $is_order_ajax_action = 'woocommerce_mark_order_status' === $getData->get( 'action' ) && wpml_collect( [ 'completed', 'processing' ] )->contains( $getData->get( 'status' ) );
 
 
 
179
  if ( $is_order_ajax_action && $getData->get( 'order_id' ) ) {
180
  return get_post_meta( $getData->get( 'order_id' ), 'wpml_language', true );
181
  }
182
  }
183
 
184
  return $this->current_language;
185
- }
186
 
187
  public function show_language_links_for_gateways() {
188
 
1
  <?php
2
 
3
+ use WPML\Collect\Support\Collection;
4
+
5
  class WCML_WC_Gateways {
6
 
7
  const WCML_BACS_ACCOUNTS_CURRENCIES_OPTION = 'wcml_bacs_accounts_currencies';
146
 
147
  $postData = wpml_collect( $_POST );
148
  if ( $postData->isNotEmpty() ) {
149
+ if ( $this->is_user_order_note( $postData ) ) {
150
+ $current_gateway_language = get_post_meta( $postData->get( 'post_id' ), 'wpml_language', true );
151
+ } elseif ( $this->is_refund_line_item( $postData ) ) {
152
+ $current_gateway_language = get_post_meta( $postData->get( 'order_id' ), 'wpml_language', true );
153
+ } else {
154
+ $current_gateway_language = $this->get_order_action_gateway_language( $postData );
155
  }
156
+ } else {
157
+ $current_gateway_language = $this->get_order_ajax_action_gateway_language();
158
+ }
159
 
160
+ /**
161
+ * Filters the current gateway language
162
+ *
163
+ * @since 4.9.0
164
+ *
165
+ * @param string $current_gateway_language
166
+ */
167
+ return apply_filters( 'wcml_current_gateway_language', $current_gateway_language );
168
+ }
169
 
170
+ /**
171
+ * @param Collection $postData
172
+ *
173
+ * @return bool
174
+ */
175
+ private function is_user_order_note( Collection $postData ) {
176
+ return 'woocommerce_add_order_note' === $postData->get( 'action' ) && 'customer' === $postData->get( 'note_type' );
177
+ }
178
+
179
+ /**
180
+ * @param Collection $postData
181
+ *
182
+ * @return bool
183
+ */
184
+ private function is_refund_line_item( Collection $postData ){
185
+ return 'woocommerce_refund_line_items' === $postData->get( 'action' );
186
+ }
187
 
 
 
 
 
 
188
 
189
+ /**
190
+ * @param Collection $postData
191
+ *
192
+ * @return string
193
+ */
194
+ private function get_order_action_gateway_language( Collection $postData ) {
195
+
196
+ if ( $postData->get( 'post_ID' ) ) {
197
+
198
+ $is_saving_new_order = wpml_collect( [
199
+ 'auto-draft',
200
+ 'draft'
201
+ ] )->contains( $postData->get( 'post_status' ) )
202
+ && 'editpost' === $postData->get( 'action' )
203
+ && $postData->get( 'save' );
204
+ if ( $is_saving_new_order && isset( $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ] ) ) {
205
+ return $_COOKIE[ WCML_Orders::DASHBOARD_COOKIE_NAME ];
206
+ }
207
+
208
+ $is_order_emails_status = wpml_collect( [
209
+ 'wc-completed',
210
+ 'wc-processing',
211
+ 'wc-refunded',
212
+ 'wc-on-hold'
213
+ ] )->contains( $postData->get( 'order_status' ) );
214
+
215
+ $is_send_order_details_action = 'send_order_details' === $postData->get( 'wc_order_action' );
216
+ if ( $is_order_emails_status || $is_send_order_details_action ) {
217
+ return get_post_meta( $postData->get( 'post_ID' ), 'wpml_language', true );
218
  }
219
  }
220
 
221
+ return $this->current_language;
222
+ }
223
+
224
+ /**
225
+ * @return string
226
+ */
227
+ private function get_order_ajax_action_gateway_language(){
228
+
229
  $getData = wpml_collect( $_GET );
230
  if ( $getData->isNotEmpty() ) {
231
+ $is_order_ajax_action = 'woocommerce_mark_order_status' === $getData->get( 'action' ) && wpml_collect( [
232
+ 'completed',
233
+ 'processing'
234
+ ] )->contains( $getData->get( 'status' ) );
235
  if ( $is_order_ajax_action && $getData->get( 'order_id' ) ) {
236
  return get_post_meta( $getData->get( 'order_id' ), 'wpml_language', true );
237
  }
238
  }
239
 
240
  return $this->current_language;
241
+ }
242
 
243
  public function show_language_links_for_gateways() {
244
 
inc/class-wcml-wc-shipping.php CHANGED
@@ -29,14 +29,11 @@ class WCML_WC_Shipping {
29
  }
30
 
31
  public function add_hooks() {
32
-
33
- add_action( 'woocommerce_tax_rate_added', [ $this, 'register_tax_rate_label_string' ], 10, 2 );
34
  add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', [ $this, 'save_shipping_zone_method_from_ajax' ], 9 );
35
  add_action( 'icl_save_term_translation', [ $this, 'sync_class_costs_for_new_shipping_classes' ], 100, 2 );
36
  add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs_from_ajax' ], 9 );
37
 
38
  add_filter( 'woocommerce_package_rates', [ $this, 'translate_shipping_methods_in_package' ] );
39
- add_filter( 'woocommerce_rate_label', [ $this, 'translate_woocommerce_rate_label' ] );
40
  add_filter( 'pre_update_option_woocommerce_flat_rate_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs' ] );
41
  add_filter( 'pre_update_option_woocommerce_international_delivery_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs' ] );
42
  add_filter( 'woocommerce_shipping_flat_rate_instance_option', [ $this, 'get_original_shipping_class_rate' ], 10, 3 );
@@ -167,21 +164,6 @@ class WCML_WC_Shipping {
167
  return $title;
168
  }
169
 
170
- public function translate_woocommerce_rate_label( $label ) {
171
-
172
- $label = apply_filters( 'wpml_translate_single_string', $label, 'woocommerce taxes', $label );
173
-
174
- return $label;
175
- }
176
-
177
- public function register_tax_rate_label_string( $id, $tax_rate ) {
178
-
179
- if ( ! empty( $tax_rate['tax_rate_name'] ) ) {
180
- do_action( 'wpml_register_single_string', 'woocommerce taxes', $tax_rate['tax_rate_name'], $tax_rate['tax_rate_name'] );
181
- }
182
-
183
- }
184
-
185
  public function sync_class_costs_for_new_shipping_classes( $original_tax, $result ) {
186
  // update flat rate options for shipping classes.
187
  if ( $original_tax->taxonomy == 'product_shipping_class' ) {
@@ -211,18 +193,20 @@ class WCML_WC_Shipping {
211
  } else {
212
  $shipp_class = get_term_by( 'slug', $shipp_class_key, 'product_shipping_class' );
213
  }
214
- $trid = $this->sitepress->get_element_trid( $shipp_class->term_taxonomy_id, 'tax_product_shipping_class' );
 
215
 
216
- $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_shipping_class' );
217
 
218
- foreach ( $translations as $translation ) {
219
 
220
- $tr_shipp_class = get_term_by( 'term_taxonomy_id', $translation->element_id, 'product_shipping_class' );
221
 
222
- if ( is_numeric( $shipp_class_key ) ) {
223
- $settings[ 'class_cost_' . $tr_shipp_class->term_id ] = $value;
224
- } else {
225
- $settings[ 'class_cost_' . $tr_shipp_class->slug ] = $value;
 
226
  }
227
  }
228
  }
29
  }
30
 
31
  public function add_hooks() {
 
 
32
  add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', [ $this, 'save_shipping_zone_method_from_ajax' ], 9 );
33
  add_action( 'icl_save_term_translation', [ $this, 'sync_class_costs_for_new_shipping_classes' ], 100, 2 );
34
  add_action( 'wp_ajax_woocommerce_shipping_zone_methods_save_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs_from_ajax' ], 9 );
35
 
36
  add_filter( 'woocommerce_package_rates', [ $this, 'translate_shipping_methods_in_package' ] );
 
37
  add_filter( 'pre_update_option_woocommerce_flat_rate_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs' ] );
38
  add_filter( 'pre_update_option_woocommerce_international_delivery_settings', [ $this, 'update_woocommerce_shipping_settings_for_class_costs' ] );
39
  add_filter( 'woocommerce_shipping_flat_rate_instance_option', [ $this, 'get_original_shipping_class_rate' ], 10, 3 );
164
  return $title;
165
  }
166
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  public function sync_class_costs_for_new_shipping_classes( $original_tax, $result ) {
168
  // update flat rate options for shipping classes.
169
  if ( $original_tax->taxonomy == 'product_shipping_class' ) {
193
  } else {
194
  $shipp_class = get_term_by( 'slug', $shipp_class_key, 'product_shipping_class' );
195
  }
196
+ if ( isset( $shipp_class->term_taxonomy_id ) ) {
197
+ $trid = $this->sitepress->get_element_trid( $shipp_class->term_taxonomy_id, 'tax_product_shipping_class' );
198
 
199
+ $translations = $this->sitepress->get_element_translations( $trid, 'tax_product_shipping_class' );
200
 
201
+ foreach ( $translations as $translation ) {
202
 
203
+ $tr_shipp_class = get_term_by( 'term_taxonomy_id', $translation->element_id, 'product_shipping_class' );
204
 
205
+ if ( is_numeric( $shipp_class_key ) ) {
206
+ $settings[ 'class_cost_' . $tr_shipp_class->term_id ] = $value;
207
+ } else {
208
+ $settings[ 'class_cost_' . $tr_shipp_class->slug ] = $value;
209
+ }
210
  }
211
  }
212
  }
inc/currencies/class-wcml-custom-prices.php CHANGED
@@ -31,6 +31,7 @@ class WCML_Custom_Prices {
31
  add_action( 'woocommerce_variation_is_visible', [ $this, 'filter_product_variations_with_custom_prices' ], 10, 2 );
32
 
33
  add_filter( 'loop_shop_post_in', [ $this, 'filter_products_with_custom_prices' ], 100 );
 
34
 
35
  }
36
 
@@ -307,13 +308,23 @@ class WCML_Custom_Prices {
307
 
308
  }
309
 
310
- // set variations without custom prices to not visible when "Show only products with custom prices in secondary currencies" is enabled.
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  public function filter_product_variations_with_custom_prices( $is_visible, $variation_id ) {
312
 
313
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
314
- isset( $this->woocommerce_wpml->settings['display_custom_prices'] ) &&
315
- $this->woocommerce_wpml->settings['display_custom_prices'] &&
316
- is_product() ) {
317
 
318
  $orig_child_id = $this->woocommerce_wpml->products->get_original_product_id( $variation_id );
319
 
@@ -328,16 +339,8 @@ class WCML_Custom_Prices {
328
  // display products with custom prices only if enabled "Show only products with custom prices in secondary currencies" option on settings page.
329
  public function filter_products_with_custom_prices( $filtered_posts ) {
330
 
331
- if ( $this->woocommerce_wpml->settings['enable_multi_currency'] == WCML_MULTI_CURRENCIES_INDEPENDENT &&
332
- isset( $this->woocommerce_wpml->settings['display_custom_prices'] ) &&
333
- $this->woocommerce_wpml->settings['display_custom_prices'] ) {
334
-
335
- $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
336
- $woocommerce_currency = wcml_get_woocommerce_currency_option();
337
 
338
- if ( $client_currency == $woocommerce_currency ) {
339
- return $filtered_posts;
340
- }
341
  $matched_products = [];
342
  $matched_products_query = $this->wpdb->get_results(
343
  "
@@ -349,6 +352,9 @@ class WCML_Custom_Prices {
349
  );
350
 
351
  if ( $matched_products_query ) {
 
 
 
352
  remove_filter( 'get_post_metadata', [ $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ], 10, 4 );
353
  foreach ( $matched_products_query as $product ) {
354
  if ( ! get_post_meta( $product->ID, '_price_' . $client_currency, true ) ) {
@@ -377,6 +383,17 @@ class WCML_Custom_Prices {
377
  return $filtered_posts;
378
  }
379
 
 
 
 
 
 
 
 
 
 
 
 
380
  public function save_custom_prices( $post_id ) {
381
  $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
382
 
31
  add_action( 'woocommerce_variation_is_visible', [ $this, 'filter_product_variations_with_custom_prices' ], 10, 2 );
32
 
33
  add_filter( 'loop_shop_post_in', [ $this, 'filter_products_with_custom_prices' ], 100 );
34
+ add_filter( 'woocommerce_is_purchasable', [ $this, 'check_product_with_custom_prices' ], 10, 2 );
35
 
36
  }
37
 
308
 
309
  }
310
 
311
+ public function check_product_with_custom_prices( $is_purchasable, WC_Product $product ) {
312
+
313
+ if ( $this->is_filtering_products_with_custom_prices_enabled() && is_product() ) {
314
+
315
+ $original_id = $this->woocommerce_wpml->products->get_original_product_id( $product->get_id() );
316
+
317
+ if ( ! get_post_meta( $original_id, '_wcml_custom_prices_status', true ) ) {
318
+ return false;
319
+ }
320
+ }
321
+
322
+ return $is_purchasable;
323
+ }
324
+
325
  public function filter_product_variations_with_custom_prices( $is_visible, $variation_id ) {
326
 
327
+ if ( $this->is_filtering_products_with_custom_prices_enabled() && is_product() ) {
 
 
 
328
 
329
  $orig_child_id = $this->woocommerce_wpml->products->get_original_product_id( $variation_id );
330
 
339
  // display products with custom prices only if enabled "Show only products with custom prices in secondary currencies" option on settings page.
340
  public function filter_products_with_custom_prices( $filtered_posts ) {
341
 
342
+ if ( $this->is_filtering_products_with_custom_prices_enabled() ) {
 
 
 
 
 
343
 
 
 
 
344
  $matched_products = [];
345
  $matched_products_query = $this->wpdb->get_results(
346
  "
352
  );
353
 
354
  if ( $matched_products_query ) {
355
+
356
+ $client_currency = $this->woocommerce_wpml->multi_currency->get_client_currency();
357
+
358
  remove_filter( 'get_post_metadata', [ $this->woocommerce_wpml->multi_currency->prices, 'product_price_filter' ], 10, 4 );
359
  foreach ( $matched_products_query as $product ) {
360
  if ( ! get_post_meta( $product->ID, '_price_' . $client_currency, true ) ) {
383
  return $filtered_posts;
384
  }
385
 
386
+ /**
387
+ * @return bool
388
+ */
389
+ private function is_filtering_products_with_custom_prices_enabled() {
390
+
391
+ return wcml_is_multi_currency_on() &&
392
+ isset( $this->woocommerce_wpml->settings['display_custom_prices'] ) &&
393
+ $this->woocommerce_wpml->settings['display_custom_prices'] &&
394
+ $this->woocommerce_wpml->multi_currency->get_client_currency() !== wcml_get_woocommerce_currency_option();
395
+ }
396
+
397
  public function save_custom_prices( $post_id ) {
398
  $nonce = filter_input( INPUT_POST, '_wcml_custom_prices_nonce', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
399
 
inc/currencies/class-wcml-multi-currency-prices.php CHANGED
@@ -78,6 +78,8 @@ class WCML_Multi_Currency_Prices {
78
  add_filter( 'wc_price_args', [ $this, 'filter_wc_price_args' ] );
79
  }
80
 
 
 
81
  // formatting options.
82
  add_filter( 'option_woocommerce_price_thousand_sep', [ $this, 'filter_currency_thousand_sep_option' ] );
83
  add_filter( 'option_woocommerce_price_decimal_sep', [ $this, 'filter_currency_decimal_sep_option' ] );
@@ -569,7 +571,6 @@ class WCML_Multi_Currency_Prices {
569
  }
570
 
571
  public function filter_woocommerce_cart_contents_total( $cart_contents_total ) {
572
- global $woocommerce;
573
  remove_filter(
574
  'woocommerce_cart_contents_total',
575
  [
@@ -578,13 +579,17 @@ class WCML_Multi_Currency_Prices {
578
  ],
579
  100
580
  );
581
- $woocommerce->cart->calculate_totals();
582
- $cart_contents_total = $woocommerce->cart->get_cart_total();
583
  add_filter( 'woocommerce_cart_contents_total', [ $this, 'filter_woocommerce_cart_contents_total' ], 100 );
584
 
585
  return $cart_contents_total;
586
  }
587
 
 
 
 
 
588
  public function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart_object ) {
589
 
590
  remove_filter( 'woocommerce_cart_subtotal', [ $this, 'filter_woocommerce_cart_subtotal' ], 100, 3 );
78
  add_filter( 'wc_price_args', [ $this, 'filter_wc_price_args' ] );
79
  }
80
 
81
+ add_action( 'woocommerce_cart_loaded_from_session', [ $this, 'recalculate_totals' ] );
82
+
83
  // formatting options.
84
  add_filter( 'option_woocommerce_price_thousand_sep', [ $this, 'filter_currency_thousand_sep_option' ] );
85
  add_filter( 'option_woocommerce_price_decimal_sep', [ $this, 'filter_currency_decimal_sep_option' ] );
571
  }
572
 
573
  public function filter_woocommerce_cart_contents_total( $cart_contents_total ) {
 
574
  remove_filter(
575
  'woocommerce_cart_contents_total',
576
  [
579
  ],
580
  100
581
  );
582
+ $this->recalculate_totals();
583
+ $cart_contents_total = WC()->cart->get_cart_total();
584
  add_filter( 'woocommerce_cart_contents_total', [ $this, 'filter_woocommerce_cart_contents_total' ], 100 );
585
 
586
  return $cart_contents_total;
587
  }
588
 
589
+ public function recalculate_totals() {
590
+ WC()->cart->calculate_totals();
591
+ }
592
+
593
  public function filter_woocommerce_cart_subtotal( $cart_subtotal, $compound, $cart_object ) {
594
 
595
  remove_filter( 'woocommerce_cart_subtotal', [ $this, 'filter_woocommerce_cart_subtotal' ], 100, 3 );
inc/currencies/class-wcml-multi-currency-shipping.php CHANGED
@@ -1,5 +1,7 @@
1
  <?php
2
 
 
 
3
  class WCML_Multi_Currency_Shipping {
4
 
5
  /** @var WCML_Multi_Currency */
@@ -27,7 +29,7 @@ class WCML_Multi_Currency_Shipping {
27
 
28
  // Used for table rate shipping compatibility class.
29
  add_filter( 'wcml_shipping_price_amount', [ $this, 'shipping_price_filter' ] ); // WCML filters.
30
- add_filter( 'wcml_shipping_free_min_amount', [ $this, 'shipping_free_min_amount' ] ); // WCML filters.
31
 
32
  add_filter( 'woocommerce_evaluate_shipping_cost_args', [ $this, 'woocommerce_evaluate_shipping_cost_args' ] );
33
 
@@ -49,7 +51,9 @@ class WCML_Multi_Currency_Shipping {
49
  if ( $cached_converted_shipping_cost ) {
50
  $rate->cost = $cached_converted_shipping_cost;
51
  } elseif ( isset( $rate->cost ) && $rate->cost ) {
52
- $rate->cost = $this->multi_currency->prices->raw_price_filter( $rate->cost, $client_currency );
 
 
53
  wp_cache_set( $cache_key, $rate->cost, $cache_group );
54
  }
55
  }
@@ -84,7 +88,7 @@ class WCML_Multi_Currency_Shipping {
84
  $settings['requires'] === 'either' ||
85
  ( $settings['requires'] === 'both' && $has_free_shipping_coupon )
86
  ) {
87
- $settings['min_amount'] = apply_filters( 'wcml_shipping_free_min_amount', $settings['min_amount'] );
88
  }
89
  }
90
 
@@ -132,13 +136,13 @@ class WCML_Multi_Currency_Shipping {
132
 
133
  }
134
 
135
- public function shipping_free_min_amount( $price ) {
136
-
137
- $price = $this->multi_currency->prices->raw_price_filter( $price, $this->multi_currency->get_client_currency() );
138
-
 
 
139
  return $price;
140
 
141
  }
142
-
143
-
144
  }
1
  <?php
2
 
3
+ use \WCML\Multicurrency\Shipping\ShippingModeProvider as ManualCost;
4
+
5
  class WCML_Multi_Currency_Shipping {
6
 
7
  /** @var WCML_Multi_Currency */
29
 
30
  // Used for table rate shipping compatibility class.
31
  add_filter( 'wcml_shipping_price_amount', [ $this, 'shipping_price_filter' ] ); // WCML filters.
32
+ add_filter( 'wcml_shipping_free_min_amount', [ $this, 'shipping_free_min_amount' ], 10, 2 ); // WCML filters.
33
 
34
  add_filter( 'woocommerce_evaluate_shipping_cost_args', [ $this, 'woocommerce_evaluate_shipping_cost_args' ] );
35
 
51
  if ( $cached_converted_shipping_cost ) {
52
  $rate->cost = $cached_converted_shipping_cost;
53
  } elseif ( isset( $rate->cost ) && $rate->cost ) {
54
+ if ( ! ManualCost::get( $rate->method_id )->isManualPricingEnabled( $rate ) ) {
55
+ $rate->cost = $this->multi_currency->prices->raw_price_filter( $rate->cost, $client_currency );
56
+ }
57
  wp_cache_set( $cache_key, $rate->cost, $cache_group );
58
  }
59
  }
88
  $settings['requires'] === 'either' ||
89
  ( $settings['requires'] === 'both' && $has_free_shipping_coupon )
90
  ) {
91
+ $settings['min_amount'] = apply_filters( 'wcml_shipping_free_min_amount', $settings['min_amount'], $settings );
92
  }
93
  }
94
 
136
 
137
  }
138
 
139
+ public function shipping_free_min_amount( $price, $settings ) {
140
+ if ( ManualCost::get( 'free_shipping' )->isManualPricingEnabled( $settings ) ) {
141
+ $price = ManualCost::get( 'free_shipping' )->getMinimalOrderAmountValue( $price, $settings, $this->multi_currency->get_client_currency() );
142
+ } else {
143
+ $price = $this->multi_currency->prices->raw_price_filter( $price, $this->multi_currency->get_client_currency() );
144
+ }
145
  return $price;
146
 
147
  }
 
 
148
  }
inc/wcml-core-functions.php CHANGED
@@ -92,3 +92,21 @@ if ( ! function_exists( 'wcml_product_data_store_cpt' ) ) {
92
  return new WCML_Product_Data_Store_CPT();
93
  }
94
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  return new WCML_Product_Data_Store_CPT();
93
  }
94
  }
95
+
96
+ if ( ! function_exists( 'wcml_convert_price' ) ) {
97
+
98
+ /**
99
+ * @since 4.9.0
100
+ *
101
+ * @param float|int $price
102
+ * @param bool|string $currency_code
103
+ *
104
+ * @return float|int
105
+ */
106
+ function wcml_convert_price( $price, $currency_code = false ) {
107
+ /** @var woocommerce_wpml $woocommerce_wpml */
108
+ global $woocommerce_wpml;
109
+
110
+ return $woocommerce_wpml->multi_currency->prices->raw_price_filter( $price, $currency_code );
111
+ }
112
+ }
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: 4.7
7
- Tested up to: 5.4
8
- Stable tag: 4.8.0
9
  Requires PHP: 5.6
10
 
11
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
@@ -137,6 +137,23 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
137
 
138
  == Changelog ==
139
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
  = 4.8.0 =
141
  * Fixed JS SyntaxError on Products listing page.
142
  * Fixed not registered 'Additional Content' emails setting text after first saving.
@@ -224,46 +241,3 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
224
  * WooCommerce Variation Swatches and Photos compatibility to translate attributes
225
  * Fix related product displays in all languages
226
  * Added compatibility with Yikes Custom Product Tabs
227
-
228
- = 4.4.0 =
229
- * Added the ability to associate BACS accounts with currencies
230
- * Hide reviews in other languages link, if there are no reviews in product
231
- * Update WCML Logo
232
- * Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
233
- * Fix low_stock_amount not synchronized to translations
234
- * Fix custom attribute with number in name not appears to translation in Translation editor
235
- * Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
236
- * Fix translated custom field wrongly saved to translation if contains array of strings
237
- * Endless loop when using troubleshooting action to duplicate terms
238
- * Fixed an issue with Elementor PRO products block showing all categories in the translated page.
239
- * Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
240
- * Fixed compatibility issue with Flatsome theme
241
- * Fix issue with custom product attribute title when trying to upload translation with XLIFF file
242
- * Fixed cart validate for specific situations
243
- * Added filter for translated package rates
244
- * Added WPML switcher buttons library for Multi Currency in backend
245
- * Fix loading Jquery to any place in code and in header
246
- * Added fix for variation product "become" out-of-stock when translating using native screen
247
- * Removed backward compatibility filters for terms synchronization
248
- * Fixed attribute slug language always set to English
249
- * Wrong path in Bookings compatibility class
250
- * Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
251
- * Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
252
- * Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
253
- * Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
254
- * Fixed compatibility class name for wc product addons
255
- * Fixed manual order creation does not respect manual prices
256
- * Fix email language for the order as complete emails
257
- * Fixed Composite Products compatibility - Price not rounding to the nearest integer
258
- * Fixed missing custom attribute in XLIFF file / Pro Translation
259
- * Fix Endpoint error to prevent 404 in some cases
260
- * Fixed accepted arguments for terms_clause
261
- * Resolved an exception causing an error message in the cart in some setups
262
- * Fixed missed synchronization of 'outofstock' visibility term between product translations
263
- * Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
264
- * Custom attributes terms not copied to diplicated translation after update values in original
265
- * Added support for wpml endpoints
266
- * WP Fastest Cache compatibility - fixed currency switcher problem
267
- * Added ability to set custom prices for secondary currencies in WC Product Add-Ons
268
- * Update minimum requirements
269
- * Added ability to add custom payment methods for each currency
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 4.7
7
+ Tested up to: 5.4.1
8
+ Stable tag: 4.9.0
9
  Requires PHP: 5.6
10
 
11
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
137
 
138
  == Changelog ==
139
 
140
+ = 4.9.0 =
141
+ * Manual shipping prices in secondary currencies.
142
+ * Fixed product attribute slug language not changed after changing value.
143
+ * Fixed missing numeric attribute values after translation using ATE.
144
+ * Fixed mini-cart total calculation when switching a currency.
145
+ * Fixed out of stock variable products if "Show only products with custom prices in secondary currencies" option is enabled.
146
+ * Fixed WC Tab Manager custom tab translation from ATE was not saved if the description is empty.
147
+ * Fixed an error which some additional plugins may cause with WC_Email object.
148
+ * Add a filter for WCML_WC_Gateways::get_current_gateway_language().
149
+ * Fixed not synchronized WooCommerce Tab Manager global tabs while saving product translation via ATE.
150
+ * Fixed not updated tax label after a change on settings page.
151
+ * Fixed the value of a custom attribute translation is overwritten on saving the original product.
152
+ * Fixed overwritten composite data title and description in translation after original product update.
153
+ * Fixed js console error in languages_notice.js file.
154
+ * Add language filtering for WooCommerce dashboard stock widgets.
155
+ * Fixed creating of several memberships in WooCommerce Membership plugin.
156
+
157
  = 4.8.0 =
158
  * Fixed JS SyntaxError on Products listing page.
159
  * Fixed not registered 'Additional Content' emails setting text after first saving.
241
  * WooCommerce Variation Swatches and Photos compatibility to translate attributes
242
  * Fix related product displays in all languages
243
  * Added compatibility with Yikes Custom Product Tabs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
res/css/admin.css CHANGED
@@ -1 +1 @@
1
- .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0}.otgs-ico-ok:before{content:"\63"}.wcml-wrap .mouse-hovered{display:none;width:auto;max-width:350px;height:auto;max-height:250px;position:absolute;z-index:10;border:solid 4px #999;background:#fff}.wp-list-table.fixed .column-icl_translations{width:12%}
1
+ .wcml-menu-warn{display:inline-block;color:#d54e21;line-height:15px;margin:1px 0 0 2px;z-index:26}a.wcml-external-link{padding-right:15px}a.wcml-external-link:after{content:"\f504";display:inline-block;width:15px;margin-right:-15px;font-size:14px;line-height:18px;font-family:dashicons;text-decoration:none;font-weight:normal;font-style:normal;vertical-align:top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.wcml-pointer-inner .wcml-information-paragraph{padding-right:30px}.wcml-pointer-inner .wp-pointer-buttons{padding:0}.wcml-pointer-inner.wp-pointer-bottom .wp-pointer-arrow{left:auto;right:50px}.wcml-message-icon.wcml-table-cell,.wcml-message-content.wcml-table-cell{height:100px}.wcml-pointer-link{position:relative;text-decoration:none;padding:10px}.wcml-cart-dialog button{text-transform:capitalize}div[data-selector="woocommerce_table_rate_title"] a,div[data-selector="wpbody-content .woocommerce h2"] a{padding:10px 0 0 0}#shipping_rates .shipping_label .wcml-pointer-link{padding:0}.otgs-ico-ok:before{content:"\63"}.wcml-wrap .mouse-hovered{display:none;width:auto;max-width:350px;height:auto;max-height:250px;position:absolute;z-index:10;border:solid 4px #999;background:#fff}.wp-list-table.fixed .column-icl_translations{width:12%}.otgs-notice-wcml-rating{border:none !important;background:url(../images/bg-rating-notice.png) no-repeat 100% 50%,linear-gradient(84.39deg, #2782AD 0%, #27AD95 99.36%) !important;color:#fff;padding-bottom:20px !important;border-radius:5px}.otgs-notice-wcml-rating h2{color:#fff}.otgs-notice-wcml-rating p{line-height:1.6}.otgs-notice-wcml-rating p span.rating{display:inline-block;padding:5px 8px 5px 12px;margin:0 5px;border-radius:20px;background:rgba(255,255,255,0.5)}.otgs-notice-wcml-rating .otgs-notice-actions .notice-action{border:none;-webkit-box-shadow:none;box-shadow:none;background:#fff;border-radius:5px;padding:0 15px;line-height:34px;height:34px}.otgs-notice-wcml-rating .otgs-notice-actions .notice-action:hover{color:#fff;background:#db552b}.otgs-notice-wcml-rating .notice-dismiss{opacity:0.5}.otgs-notice-wcml-rating .notice-dismiss:before{color:#fff}.otgs-notice-wcml-rating .notice-dismiss:hover{opacity:1}
res/css/management.css CHANGED
@@ -1 +1 @@
1
- .wcml-wrap{border:1px solid #CCCCCC;padding:15px;background-color:#ffffff}.wcml-wrap:before,.wcml-wrap:after{content:" ";display:table}.wcml-wrap:after{clear:both}.dis_base{opacity:0.5}.display-block{display:block}.wcml-wrap{margin-bottom:20px}.wcml-wrap .wpml-tabs{margin-top:0}.wcml-wrap .otgs-ico-yes,.wcml-wrap .otgs-ico-ok{color:#51a351}.wcml-wrap .otgs-ico-no,.wcml-wrap .otgs-ico-warning,.wcml-wrap .otgs-ico-delete{color:#9d261d}.wcml-wrap .otgs-ico-edit{color:#3a87ad}.wcml-wrap .otgs-ico-in-progress{color:#ffb800}@media (max-width: 1199px){.wcml-wrap .tablenav.top{height:auto}.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignright,.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignleft{float:none;margin-bottom:5px}}[class*="otgs-ico"]:before{font-size:16px}.wcml-tabs:before,.wcml-tabs:after{content:" ";display:table}.wcml-tabs:after{clear:both}.wcml-tabs .nav-tab [class*="otgs-ico"]:before{font-size:18px}.wcml-tabs .nav-tab-active{background:#fff;border-bottom:none}.wcml-section{clear:both;padding:0 0 15px 0;margin:0 0 15px 0;border-bottom:1px solid #ededed}.wcml-section:after{content:'';display:table;clear:both}.wcml-section:last-of-type{border:none;margin:0}@media (max-width: 480px){.wcml-section .button{max-width:100%;white-space:normal;line-height:1.3;padding-top:7px;padding-bottom:8px;height:auto}}.explanation-text{color:#999}h4+.explanation-text{margin-top:-1.1em;margin-bottom:1.33em}.wcml-section-content .wcml-section-content-inner:not(:last-child){margin:0 0 20px 0;padding:0 0 10px 0;border-bottom:1px solid #ededed}.wcml-section-header h3{font-weight:normal;font-size:1.4em;margin-top:0.7em}.wcml-section-header h3 .wcml-tip:before{vertical-align:top}@media (min-width: 1200px){.wcml-section-header{width:310px;float:left}.rtl .wcml-section-header{float:right}.wcml-section-content{float:left;width:600px;max-width:100%;margin-left:30px}.rtl .wcml-section-content{float:right}.wcml-section-content-wide{width:calc(100% - 360px)}}.wcml_products{margin:20px 0;position:relative}.button-wrap,.widefat td .button-wrap{text-align:right;margin:10px 0}.currency_action_update{display:inline-block}.wcml-co-dialog.hidden{display:none}.wcml-co-dialog .wpml-form-row label,.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{margin:3px 15px}.wcml-co-dialog .wpml-form-row label{width:215px;text-align:start}.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{width:145px}.wcml-co-dialog .currency_code label{width:100px;vertical-align:top}.wcml-co-dialog .currency_code select{width:auto;max-width:calc(100% - 165px)}.wcml-co-dialog .wcml-co-exchange-rate label{width:100px;vertical-align:top}.wcml-co-dialog .wcml-co-exchange-rate input{margin:0 !important;width:75px}.wcml-co-dialog .wcml-co-exchange-rate .wcml-co-set-rate{display:inline-block;padding:4px 15px 7px 15px;max-width:265px}.wcml-co-dialog .wcml-co-exchange-rate small{display:block;margin-top:5px}.wcml-co-dialog .wcml-co-help-link{margin-top:7px}.wcml-co-dialog .wcml-co-preview label{width:120px;vertical-align:middle}.wcml-co-dialog .wcml-co-preview .wcml-co-preview-value{display:inline-block;padding:7px 15px;border:1px solid #555;font-size:1.4em;font-weight:bold;vertical-align:middle;margin:15px 0}.wcml-co-dialog .label-header{margin:20px 15px 7px 15px;display:block}.wcml-co-dialog .wcml-gateways-switcher{margin:7px 15px 30px}.wcml-co-dialog .wcml-gateways-switcher .otgs-toggle-group{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-margin-end:15px;margin-inline-end:15px}.wcml-co-dialog .wcml-gateways{margin-bottom:30px}.wcml-co-dialog .wcml-gateways .wpml-form-row label{width:130px}.wcml-co-dialog .wcml-gateways .wpml-form-row input,.wcml-co-dialog .wcml-gateways .wpml-form-row select{width:auto}.wcml-co-dialog .wcml-gateways .wpml-form-row input+.wcml-tip,.wcml-co-dialog .wcml-gateways .wpml-form-row select+.wcml-tip{-webkit-margin-start:-12px;margin-inline-start:-12px}.wcml-co-dialog .wcml-gateways .explanation-text{display:block;margin:0 15px}table.widefat.currency_table{float:left;width:255px;border-right:none}@media (max-width: 782px){table.widefat.currency_table{width:120px}}table.widefat.currency_table td.wcml-col-currency,table.widefat.currency_table td.wcml-col-rate{padding-top:7px;padding-bottom:0;vertical-align:top}table.widefat.currency_table td.wcml-col-currency .truncate{max-width:100px;display:block}table.widefat.currency_table td.wcml-col-currency small{display:block}table.widefat.currency_table td.wcml-col-edit a{position:relative;top:-3px}table.widefat.currency_table td.wcml-col-rate{font-size:.85em;-webkit-padding-start:3px;padding-inline-start:3px}table.widefat.currency_table td.wcml-col-rate .truncate{max-width:75px;display:block}@media (max-width: 782px){table.widefat.currency_table .wcml-col-rate{display:none}}table.widefat.currency_settings_table{float:left;width:80px;border-left:none;clear:none}table.widefat.currency_settings_table td.wcml-col-delete,table.widefat.currency_settings_table td.wcml-col-edit{vertical-align:middle;text-align:center}table.widefat.currency_settings_table td.wcml-col-delete:first-child,table.widefat.currency_settings_table td.wcml-col-edit:first-child{border-left:1px solid #e5e5e5}.currency_value .wcml-error,.wcml-error{font-size:10px;color:#f00;display:inline-block}.trbl_variables_products{padding:10px;border:1px solid #8cceea;background-color:#eff8fc;border-radius:5px}.trbl_variables_products label span{font-weight:bold}.wcml_trbl_warning{padding:10px;margin-bottom:10px;border:1px solid #f00;background-color:#ffb7b7;border-radius:5px 5px}#wcml_sync_variations{background-color:#21759b;background-image:-webkit-gradient(linear, left top, left bottom, from(#2a95c5), to(#21759b));background-image:linear-gradient(to bottom, #2a95c5, #21759b);border-color:#21759b;border-bottom-color:#1e6a8d;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,0.1)}.wcml_duplicate_product_notice td{border-bottom:none !important}.wcml_product_status_text,.prod_parent_text{font-style:italic;color:#9A9A9A}.wcml_no_found_text{text-align:center}.currency_languages{position:relative;text-align:center}.currency_languages:first-child{border-left:1px solid #e5e5e5}.currency_languages ul{margin:0;text-align:center}.currency_languages ul li{margin:0;display:none}.currency_languages ul li.on{display:inline-block}.currencies-table-content{display:inline-block;min-width:291px}@media (min-width: 1200px){.currencies-table-content{min-width:600px}}.currencies-table-content::after{display:table;clear:both;content:''}table.widefat.currency_lang_table{border-left:none;border-right:none}table.widefat.currency_lang_table thead .currency-lang-flags{height:23px}table.widefat.currency_lang_table thead tr{height:45px}table.widefat.currency_lang_table thead td{border-bottom:0;text-align:center;padding:3px 10px 1px 0;font-size:1em}table.widefat.currency_lang_table thead th{padding-top:0;padding-bottom:0;text-align:center}.currency_wrap{width:100%;max-width:calc(100% - 255px - 80px);min-width:70px;float:left;margin-bottom:10px;position:relative}.currency_wrap::after{content:'';position:absolute;top:1px;bottom:1px;right:0;width:15px;background:-webkit-gradient(linear, left top, right top, from(transparent), to(#fff));background:linear-gradient(to right, transparent, #fff)}@media (max-width: 782px){.currency_wrap{max-width:calc(100% - 121px - 80px)}}.currency_inner{overflow-x:auto;overflow-y:visible}.currency_table,.currency_lang_table,.currency_settings_table{clear:none}.currency_table thead tr,.currency_lang_table thead tr,.currency_settings_table thead tr{height:68px}.currency_table tr,.currency_lang_table tr,.currency_settings_table tr{height:50px}@media (max-width: 782px){.currency_table .default_currency,.currency_lang_table .default_currency,.currency_settings_table .default_currency{height:55px}}.currency_lang_table th{text-align:center}.currency_lang_table td{vertical-align:middle}.currency_lang_table.widefat td{padding-right:0;padding-left:0}@media (max-width: 782px){#wpbody .currency_lang_table select{font-size:10px}.currency_lang_table [class*='otgs-ico']::before{font-size:27px}}.default_currency select{font-size:9px;height:24px;margin:0;margin-right:2px;padding:2px 0}.default_currency td{border-top:1px solid #e5e5e5}.default_currency .inf_message{font-size:10px;font-style:italic;color:#9A9A9A}#wcml_currencies_order{display:block;overflow:hidden;width:100%}#wcml_currencies_order li{float:left;margin:2px 4px 2px 0;padding:2px 8px;border:1px solid #DFDFDF;border-radius:2px;background:-webkit-gradient(linear, left bottom, left top, from(#ECECEC), to(#F9F9F9)) repeat scroll 0 0 #F1F1F1;background:linear-gradient(to top, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;cursor:move}.wcml_currencies_order_ajx_resp{font-weight:500;margin:0 5px;padding:1px 4px 2px;border-radius:3px;white-space:nowrap;color:#46b450;background-color:rgba(92,255,102,0.15)}.wcml-cs-list{font-size:inherit;width:100%;border-collapse:collapse;border:lightgrey 1px solid;vertical-align:middle}.wcml-cs-list thead tr{border:lightgrey 1px solid}.wcml-cs-list th,.wcml-cs-list td{text-align:center;padding:5px}.wcml-cs-list .wcml-cs-cell-preview{text-align:start}.wcml-cs-list .wcml-cs-actions{width:60px}.wcml-cs-list .wcml-cs-actions a{display:inline-block;width:20px;cursor:pointer}@media (max-width: 480px){.wcml-cs-list{display:block}.wcml-cs-list thead{display:none}.wcml-cs-list tbody,.wcml-cs-list tr:not(.wcml-cs-empty-row),.wcml-cs-list td{display:block !important;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-cs-list tr::after{display:table;content:'';clear:both}.wcml-cs-list tr+tr{margin-top:30px}.wcml-cs-list .wcml-cs-cell-preview{width:100%}.wcml-cs-list .wcml-cs-widget-name,.wcml-cs-list .wcml-cs-actions{width:50%;float:left}.wcml-cs-list .wcml-cs-widget-name{text-align:start}.wcml-cs-list .wcml-cs-actions{text-align:end}}.wcml-currency-preview-wrapper{background-color:#fff;padding:15px 10px 10px;border:1px solid #ccc;width:100%;min-width:150px;min-height:120px;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wcml-currency-preview-wrapper .wcml-currency-preview-label{position:absolute;top:5px;left:10px;z-index:101;display:inline-block;padding:2px;background:rgba(255,255,255,0.9)}.wcml-currency-preview-wrapper .spinner{position:absolute;bottom:5px;right:0;z-index:101}.wcml-cs-dialog .wcml-currency-switcher-options-form input{max-width:100%}@media (min-width: 1000px){.wcml-cs-dialog .wcml-currency-switcher-options-form{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options{width:60%;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options>h4:first-child{margin-top:0}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{width:40%;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper>div{display:block}}@media (max-width: 999px){.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{margin:-17px -15px 30px -15px;width:calc(100% + 2 * 15px);border-left:0;border-right:0;z-index:10}}.wcml-cs-panel-colors table{width:100%;max-width:600px;font-size:inherit}.wcml-cs-panel-colors table th{text-align:start}.wcml-cs-panel-colors table td{vertical-align:top}.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{padding-left:50px;position:relative}@media screen and (max-width: 782px){.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{height:22px}}.wcml-cs-panel-colors .wp-color-result:after,.wcml-cs-panel-colors .wp-color-result.button:after{background:transparent;border-radius:0;border-left:0;padding:0;right:0;left:0;position:absolute;content:''}.wcml-cs-panel-colors .wp-color-result.wp-picker-open:after,.wcml-cs-panel-colors .wp-color-result.button.wp-picker-open:after{content:''}.wcml-cs-panel-colors .wp-color-result:not(.wp-picker-open):after,.wcml-cs-panel-colors .wp-color-result.button:not(.wp-picker-open):after{font-family:otgs-icons;content:'\69';color:#333;text-shadow:1px 1px 2px rgba(255,255,255,0.4);font-size:16px;min-width:0}.wcml-cs-panel-colors .wp-color-result.button .wp-color-result-text{display:none !important}.wcml-cs-panel-colors .wp-color-result.button:after{top:-2px}.wcml-cs-panel-colors .wp-picker-container input[type="text"].wp-color-picker{display:inline !important;margin-right:6px}.wcml_product_name{line-height:20px}.wcml_prod_filters{float:left}.wcml_miss_lang p:first-child{float:left}#display_custom_prices_select{display:inline-block;width:100%}.edit_slug_input,.edit_slug_hide_link{display:none}.wcml-tip{cursor:help;color:#555}.wcml-products a{cursor:pointer}@media (max-width: 782px){.column-product_cat,.column-product_tag,.column-product_type{display:none}}.wcml-link-troubleshooting{margin-top:7px}.wcml-status-list li{padding-left:25px;margin-bottom:30px}.wcml-status-list li ul li{margin-bottom:3.5px}.wcml-status-list.wcml-tax-translation-list li{margin-bottom:5px;line-height:26px}.wcml-status-list.wcml-plugins-status-list li{margin-bottom:10px}.wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:-25px;margin-right:5px;vertical-align:baseline}.rtl .wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:5px;margin-right:-25px}.wcml-status-list .button-secondary{vertical-align:middle}.wcml-status-list small{display:block}.wcml-lang-list{margin:7px 0}.wcml-lang-list .wpml-title-flag{margin-left:-25px;margin-right:5px}.rtl .wcml-lang-list .wpml-title-flag{margin-left:5px;margin-right:0}.wcml-dismiss-warning{position:relative;float:right;padding:0;text-decoration:none;outline:none}.wcml-dismiss-warning:active{outline:none}.wcml-notice{background:#fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);margin:5px 0 15px;padding:1px 12px;position:relative}.wcml-notice p{margin:.5em 0;padding:2px}.otgs-is-dismissible{position:relative;padding-right:38px}.otgs-is-dismissible .notice-dismiss{text-decoration:none}.otgs-is-dismissible p [class*="button-"]{margin:-5px 5px}.wcml_tt_spinner{margin-right:15px;display:none}.wcml-product-attributes-selector{text-align:center;margin-bottom:25px}@media (max-width: 1280px){.wcml-product-attributes-selector{margin-left:.2em}}.wcml-product-attributes-selector select{min-width:200px}.wcml-product-custom-taxonomies-selector{text-align:center;margin-bottom:25px}.wcml_attributes_wrap #wpml_tt_taxonomy_translation_wrap>label,.wcml_custom_taxonomies_wrap #wpml_tt_taxonomy_translation_wrap>label{display:none}
1
+ .wcml-wrap{border:1px solid #CCCCCC;padding:15px;background-color:#ffffff}.wcml-wrap:before,.wcml-wrap:after{content:" ";display:table}.wcml-wrap:after{clear:both}.dis_base{opacity:0.5}.display-block{display:block}.wcml-wrap{margin-bottom:20px}.wcml-wrap .wpml-tabs{margin-top:0}.wcml-wrap .otgs-ico-yes,.wcml-wrap .otgs-ico-ok{color:#51a351}.wcml-wrap .otgs-ico-no,.wcml-wrap .otgs-ico-warning,.wcml-wrap .otgs-ico-delete{color:#9d261d}.wcml-wrap .otgs-ico-edit{color:#3a87ad}.wcml-wrap .otgs-ico-in-progress{color:#ffb800}@media (max-width: 1199px){.wcml-wrap .tablenav.top{height:auto}.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignright,.wcml-wrap .tablenav.top.wcml-product-translation-filtering .alignleft{float:none;margin-bottom:5px}}[class*="otgs-ico"]:before{font-size:16px}.wcml-tabs:before,.wcml-tabs:after{content:" ";display:table}.wcml-tabs:after{clear:both}.wcml-tabs .nav-tab [class*="otgs-ico"]:before{font-size:18px}.wcml-tabs .nav-tab-active{background:#fff;border-bottom:none}.wcml-section{clear:both;padding:0 0 15px 0;margin:0 0 15px 0;border-bottom:1px solid #ededed}.wcml-section:after{content:'';display:table;clear:both}.wcml-section:last-of-type{border:none;margin:0}@media (max-width: 480px){.wcml-section .button{max-width:100%;white-space:normal;line-height:1.3;padding-top:7px;padding-bottom:8px;height:auto}}.explanation-text{color:#999}h4+.explanation-text{margin-top:-1.1em;margin-bottom:1.33em}.wcml-section-content .wcml-section-content-inner:not(:last-child){margin:0 0 20px 0;padding:0 0 10px 0;border-bottom:1px solid #ededed}.wcml-section-header h3{font-weight:normal;font-size:1.4em;margin-top:0.7em}.wcml-section-header h3 .wcml-tip:before{vertical-align:top}@media (min-width: 1200px){.wcml-section-header{width:310px;float:left}.rtl .wcml-section-header{float:right}.wcml-section-content{float:left;width:600px;max-width:100%;margin-left:30px}.rtl .wcml-section-content{float:right}.wcml-section-content-wide{width:calc(100% - 360px)}}.wcml_products{margin:20px 0;position:relative}.button-wrap,.widefat td .button-wrap{text-align:right;margin:10px 0}.currency_action_update{display:inline-block}.wcml-co-dialog.hidden{display:none}.wcml-co-dialog .wpml-form-row label,.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{margin:3px 15px}.wcml-co-dialog .wpml-form-row label{width:215px;text-align:start}.wcml-co-dialog .wpml-form-row input,.wcml-co-dialog .wpml-form-row select{width:145px}.wcml-co-dialog .currency_code label{width:100px;vertical-align:top}.wcml-co-dialog .currency_code select{width:auto;max-width:calc(100% - 165px)}.wcml-co-dialog .wcml-co-exchange-rate label{width:100px;vertical-align:top}.wcml-co-dialog .wcml-co-exchange-rate input{margin:0 !important;width:75px}.wcml-co-dialog .wcml-co-exchange-rate .wcml-co-set-rate{display:inline-block;padding:4px 15px 7px 15px;max-width:265px}.wcml-co-dialog .wcml-co-exchange-rate small{display:block;margin-top:5px}.wcml-co-dialog .wcml-co-help-link{margin-top:7px}.wcml-co-dialog .wcml-co-preview label{width:120px;vertical-align:middle}.wcml-co-dialog .wcml-co-preview .wcml-co-preview-value{display:inline-block;padding:7px 15px;border:1px solid #555;font-size:1.4em;font-weight:bold;vertical-align:middle;margin:15px 0}.wcml-co-dialog .label-header{margin:20px 15px 7px 15px;display:block}.wcml-co-dialog .wcml-gateways-switcher{margin:7px 15px 30px}.wcml-co-dialog .wcml-gateways-switcher .otgs-toggle-group{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-margin-end:15px;margin-inline-end:15px}.wcml-co-dialog .wcml-gateways{margin-bottom:30px}.wcml-co-dialog .wcml-gateways .wpml-form-row label{width:130px}.wcml-co-dialog .wcml-gateways .wpml-form-row input,.wcml-co-dialog .wcml-gateways .wpml-form-row select{width:auto}.wcml-co-dialog .wcml-gateways .wpml-form-row input+.wcml-tip,.wcml-co-dialog .wcml-gateways .wpml-form-row select+.wcml-tip{-webkit-margin-start:-12px;margin-inline-start:-12px}.wcml-co-dialog .wcml-gateways .explanation-text{display:block;margin:0 15px}table.widefat.currency_table{float:left;width:255px;border-right:none}@media (max-width: 782px){table.widefat.currency_table{width:120px}}table.widefat.currency_table td.wcml-col-currency,table.widefat.currency_table td.wcml-col-rate{padding-top:7px;padding-bottom:0;vertical-align:top}table.widefat.currency_table td.wcml-col-currency .truncate{max-width:100px;display:block}table.widefat.currency_table td.wcml-col-currency small{display:block}table.widefat.currency_table td.wcml-col-edit a{position:relative;top:-3px}table.widefat.currency_table td.wcml-col-rate{font-size:.85em;-webkit-padding-start:3px;padding-inline-start:3px}table.widefat.currency_table td.wcml-col-rate .truncate{max-width:75px;display:block}@media (max-width: 782px){table.widefat.currency_table .wcml-col-rate{display:none}}table.widefat.currency_settings_table{float:left;width:80px;border-left:none;clear:none}table.widefat.currency_settings_table td.wcml-col-delete,table.widefat.currency_settings_table td.wcml-col-edit{vertical-align:middle;text-align:center}table.widefat.currency_settings_table td.wcml-col-delete:first-child,table.widefat.currency_settings_table td.wcml-col-edit:first-child{border-left:1px solid #e5e5e5}.currency_value .wcml-error,.wcml-error{font-size:10px;color:#f00;display:inline-block}.trbl_variables_products{padding:10px;border:1px solid #8cceea;background-color:#eff8fc;border-radius:5px}.trbl_variables_products label span{font-weight:bold}.wcml_trbl_warning{padding:10px;margin-bottom:10px;border:1px solid #f00;background-color:#ffb7b7;border-radius:5px 5px}#wcml_sync_variations{background-color:#21759b;background-image:-webkit-gradient(linear, left top, left bottom, from(#2a95c5), to(#21759b));background-image:linear-gradient(to bottom, #2a95c5, #21759b);border-color:#21759b;border-bottom-color:#1e6a8d;-webkit-box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);box-shadow:inset 0 1px 0 rgba(120,200,230,0.5);color:#fff;text-decoration:none;text-shadow:0 1px 0 rgba(0,0,0,0.1)}.wcml_duplicate_product_notice td{border-bottom:none !important}.wcml_product_status_text,.prod_parent_text{font-style:italic;color:#9A9A9A}.wcml_no_found_text{text-align:center}.currency_languages{position:relative;text-align:center}.currency_languages:first-child{border-left:1px solid #e5e5e5}.currency_languages ul{margin:0;text-align:center}.currency_languages ul li{margin:0;display:none}.currency_languages ul li.on{display:inline-block}.currencies-table-content{display:inline-block;min-width:291px}@media (min-width: 1200px){.currencies-table-content{min-width:600px}}.currencies-table-content::after{display:table;clear:both;content:''}table.widefat.currency_lang_table{border-left:none;border-right:none}table.widefat.currency_lang_table thead .currency-lang-flags{height:23px}table.widefat.currency_lang_table thead tr{height:45px}table.widefat.currency_lang_table thead td{border-bottom:0;text-align:center;padding:3px 10px 1px 0;font-size:1em}table.widefat.currency_lang_table thead th{padding-top:0;padding-bottom:0;text-align:center}.currency_wrap{width:100%;max-width:calc(100% - 255px - 80px);min-width:70px;float:left;margin-bottom:10px;position:relative}.currency_wrap::after{content:'';position:absolute;top:1px;bottom:1px;right:0;width:15px;background:-webkit-gradient(linear, left top, right top, from(transparent), to(#fff));background:linear-gradient(to right, transparent, #fff)}@media (max-width: 782px){.currency_wrap{max-width:calc(100% - 121px - 80px)}}.currency_inner{overflow-x:auto;overflow-y:visible}.currency_table,.currency_lang_table,.currency_settings_table{clear:none}.currency_table thead tr,.currency_lang_table thead tr,.currency_settings_table thead tr{height:68px}.currency_table tr,.currency_lang_table tr,.currency_settings_table tr{height:50px}@media (max-width: 782px){.currency_table .default_currency,.currency_lang_table .default_currency,.currency_settings_table .default_currency{height:55px}}.currency_lang_table th{text-align:center}.currency_lang_table td{vertical-align:middle}.currency_lang_table.widefat td{padding-right:0;padding-left:0}@media (max-width: 782px){#wpbody .currency_lang_table select{font-size:10px}.currency_lang_table [class*='otgs-ico']::before{font-size:27px}}.default_currency select{font-size:12px;height:24px;margin:0;margin-right:2px}.default_currency td{border-top:1px solid #e5e5e5}.default_currency .inf_message{font-size:10px;font-style:italic;color:#9A9A9A}#wcml_currencies_order{display:block;overflow:hidden;width:100%}#wcml_currencies_order li{float:left;margin:2px 4px 2px 0;padding:2px 8px;border:1px solid #DFDFDF;border-radius:2px;background:-webkit-gradient(linear, left bottom, left top, from(#ECECEC), to(#F9F9F9)) repeat scroll 0 0 #F1F1F1;background:linear-gradient(to top, #ECECEC, #F9F9F9) repeat scroll 0 0 #F1F1F1;cursor:move}.wcml_currencies_order_ajx_resp{font-weight:500;margin:0 5px;padding:1px 4px 2px;border-radius:3px;white-space:nowrap;color:#46b450;background-color:rgba(92,255,102,0.15)}.wcml-cs-list{font-size:inherit;width:100%;border-collapse:collapse;border:lightgrey 1px solid;vertical-align:middle}.wcml-cs-list thead tr{border:lightgrey 1px solid}.wcml-cs-list th,.wcml-cs-list td{text-align:center;padding:5px}.wcml-cs-list .wcml-cs-cell-preview{text-align:start}.wcml-cs-list .wcml-cs-actions{width:60px}.wcml-cs-list .wcml-cs-actions a{display:inline-block;width:20px;cursor:pointer}@media (max-width: 480px){.wcml-cs-list{display:block}.wcml-cs-list thead{display:none}.wcml-cs-list tbody,.wcml-cs-list tr:not(.wcml-cs-empty-row),.wcml-cs-list td{display:block !important;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-cs-list tr::after{display:table;content:'';clear:both}.wcml-cs-list tr+tr{margin-top:30px}.wcml-cs-list .wcml-cs-cell-preview{width:100%}.wcml-cs-list .wcml-cs-widget-name,.wcml-cs-list .wcml-cs-actions{width:50%;float:left}.wcml-cs-list .wcml-cs-widget-name{text-align:start}.wcml-cs-list .wcml-cs-actions{text-align:end}}.wcml-currency-preview-wrapper{background-color:#fff;padding:15px 10px 10px;border:1px solid #ccc;width:100%;min-width:150px;min-height:120px;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:-webkit-box !important;display:-ms-flexbox !important;display:flex !important;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.wcml-currency-preview-wrapper .wcml-currency-preview-label{position:absolute;top:5px;left:10px;z-index:101;display:inline-block;padding:2px;background:rgba(255,255,255,0.9)}.wcml-currency-preview-wrapper .spinner{position:absolute;bottom:5px;right:0;z-index:101}.wcml-cs-dialog .wcml-currency-switcher-options-form input{max-width:100%}@media (min-width: 1000px){.wcml-cs-dialog .wcml-currency-switcher-options-form{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options{width:60%;-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-switcher-options>h4:first-child{margin-top:0}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{width:40%;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper>div{display:block}}@media (max-width: 999px){.wcml-cs-dialog .wcml-currency-switcher-options-form .wcml-currency-preview-wrapper{margin:-17px -15px 30px -15px;width:calc(100% + 2 * 15px);border-left:0;border-right:0;z-index:10}}.wcml-cs-panel-colors table{width:100%;max-width:600px;font-size:inherit}.wcml-cs-panel-colors table th{text-align:start}.wcml-cs-panel-colors table td{vertical-align:top}.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{padding-left:50px;position:relative}@media screen and (max-width: 782px){.wcml-cs-panel-colors .wp-color-result,.wcml-cs-panel-colors .wp-color-result.button{height:22px}}.wcml-cs-panel-colors .wp-color-result:after,.wcml-cs-panel-colors .wp-color-result.button:after{background:transparent;border-radius:0;border-left:0;padding:0;right:0;left:0;position:absolute;content:''}.wcml-cs-panel-colors .wp-color-result.wp-picker-open:after,.wcml-cs-panel-colors .wp-color-result.button.wp-picker-open:after{content:''}.wcml-cs-panel-colors .wp-color-result:not(.wp-picker-open):after,.wcml-cs-panel-colors .wp-color-result.button:not(.wp-picker-open):after{font-family:otgs-icons;content:'\69';color:#333;text-shadow:1px 1px 2px rgba(255,255,255,0.4);font-size:16px;min-width:0}.wcml-cs-panel-colors .wp-color-result.button .wp-color-result-text{display:none !important}.wcml-cs-panel-colors .wp-color-result.button:after{top:-2px}.wcml-cs-panel-colors .wp-picker-container input[type="text"].wp-color-picker{display:inline !important;margin-right:6px}.wcml_product_name{line-height:20px}.wcml_prod_filters{float:left}.wcml_miss_lang p:first-child{float:left}#display_custom_prices_select{display:inline-block;width:100%}.edit_slug_input,.edit_slug_hide_link{display:none}.wcml-tip{cursor:help;color:#555}.wcml-products a{cursor:pointer}@media (max-width: 782px){.column-product_cat,.column-product_tag,.column-product_type{display:none}}.wcml-link-troubleshooting{margin-top:7px}.wcml-status-list li{padding-left:25px;margin-bottom:30px}.wcml-status-list li ul li{margin-bottom:3.5px}.wcml-status-list.wcml-tax-translation-list li{margin-bottom:5px;line-height:26px}.wcml-status-list.wcml-plugins-status-list li{margin-bottom:10px}.wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:-25px;margin-right:5px;vertical-align:baseline}.rtl .wcml-status-list [class*="otgs-ico"]:not(.otgs-ico-help){margin-left:5px;margin-right:-25px}.wcml-status-list .button-secondary{vertical-align:middle}.wcml-status-list small{display:block}.wcml-lang-list{margin:7px 0}.wcml-lang-list .wpml-title-flag{margin-left:-25px;margin-right:5px}.rtl .wcml-lang-list .wpml-title-flag{margin-left:5px;margin-right:0}.wcml-dismiss-warning{position:relative;float:right;padding:0;text-decoration:none;outline:none}.wcml-dismiss-warning:active{outline:none}.wcml-notice{background:#fff;-webkit-box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);box-shadow:0 1px 1px 0 rgba(0,0,0,0.1);margin:5px 0 15px;padding:1px 12px;position:relative}.wcml-notice p{margin:.5em 0;padding:2px}.otgs-is-dismissible{position:relative;padding-right:38px}.otgs-is-dismissible .notice-dismiss{text-decoration:none}.otgs-is-dismissible p [class*="button-"]{margin:-5px 5px}.wcml_tt_spinner{margin-right:15px;display:none}.wcml-product-attributes-selector{text-align:center;margin-bottom:25px}@media (max-width: 1280px){.wcml-product-attributes-selector{margin-left:.2em}}.wcml-product-attributes-selector select{min-width:200px}.wcml-product-custom-taxonomies-selector{text-align:center;margin-bottom:25px}.wcml_attributes_wrap #wpml_tt_taxonomy_translation_wrap>label,.wcml_custom_taxonomies_wrap #wpml_tt_taxonomy_translation_wrap>label{display:none}
res/css/wcml-prices.css CHANGED
@@ -1 +1 @@
1
- .wcml_custom_prices_block:after,.wcml_schedule_dates:after{content:'';display:block;clear:both}.wcml_custom_prices_block{margin:10px}.wcml_custom_prices_block input[type="text"]{float:none}.wcml_custom_prices_options_block label,.wcml_schedule_options label{display:block;float:none;width:auto;margin:0}.wcml_custom_prices_options_block input[type="radio"],.wcml_schedule_options input[type="radio"]{float:none}.wcml_custom_prices_options_block,.custom_prices_message_block{display:block}.wcml_custom_prices_manually_block_control{padding-left:10px}.currency_blck:not(:last-child){margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #eee}.custom_prices_message_block label{color:#9d261d}.wcml_custom_prices_manually_block,.wcml_automaticaly_prices_block,.wcml_schedule_dates{display:none;padding-left:20px;margin-top:10px}.wcml_custom_prices_manually_block p,.wcml_automaticaly_prices_block p{margin:0}.currency_blck>label,.wcml_automaticaly_prices_block>label{display:block;font-weight:bold;margin:0 0 5px 0;width:auto;float:none}.wcml_schedule_manually_block_hide,.block_actions,.wcml_custom_prices_auto_block_hide{display:none}.wcml_custom_prices_manually_block_show,.wcml_custom_prices_manually_block_hide{display:none;padding-left:10px}.wcml_no_price_message{font-style:italic;font-size:12px}.woocommerce_options_panel .wcml_schedule_dates input.short{width:100px}.woocommerce_variation .currency_blck p,.woocommerce_variation .wcml_automaticaly_prices_block p,.wcml_schedule{padding:5px 20px 5px 162px !important}.woocommerce_variation .currency_blck p>label,.woocommerce_variation .wcml_automaticaly_prices_block p>label,.wcml_schedule>label{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_variation .currency_blck p .wcml_schedule_dates input,.woocommerce_variation .wcml_automaticaly_prices_block p .wcml_schedule_dates input,.wcml_schedule .wcml_schedule_dates input{float:left}.wcml_price_error{display:none;max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:.5em 1px 0 -1em;z-index:9999999;color:#fff;font-size:.8em;text-align:center;border-radius:3px;padding:.618em 1em;box-shadow:0 1px 3px rgba(0,0,0,0.2)}.wcml_price_error:after{content:'';display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}
1
+ .wcml_custom_prices_block:after,.wcml_schedule_dates:after{content:'';display:block;clear:both}.wcml_custom_prices_block{margin:10px}.wcml_custom_prices_block input[type="text"]{float:none}.wcml_custom_prices_options_block label,.wcml_schedule_options label{display:block;float:none;width:auto;margin:0}.wcml_custom_prices_options_block input[type="radio"],.wcml_schedule_options input[type="radio"]{float:none}.wcml_custom_prices_options_block,.custom_prices_message_block{display:block}.wcml_custom_prices_manually_block_control{padding-left:10px}.currency_blck:not(:last-child){margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #eee}.custom_prices_message_block label{color:#9d261d}.wcml_custom_prices_manually_block,.wcml_automaticaly_prices_block,.wcml_schedule_dates{display:none;padding-left:20px;margin-top:10px}.wcml_custom_prices_manually_block p,.wcml_automaticaly_prices_block p{margin:0}.currency_blck>label,.wcml_automaticaly_prices_block>label{display:block;font-weight:bold;margin:0 0 5px 0;width:auto;float:none}.wcml_schedule_manually_block_hide,.block_actions,.wcml_custom_prices_auto_block_hide{display:none}.wcml_custom_prices_manually_block_show,.wcml_custom_prices_manually_block_hide{display:none;padding-left:10px}.wcml_no_price_message{font-style:italic;font-size:12px}.woocommerce_options_panel .wcml_schedule_dates input.short{width:100px}.woocommerce_variation .currency_blck p,.woocommerce_variation .wcml_automaticaly_prices_block p,.wcml_schedule{padding:5px 20px 5px 162px !important}.woocommerce_variation .currency_blck p>label,.woocommerce_variation .wcml_automaticaly_prices_block p>label,.wcml_schedule>label{float:left;width:150px;padding:0;margin:0 0 0 -150px}.woocommerce_variation .currency_blck p .wcml_schedule_dates input,.woocommerce_variation .wcml_automaticaly_prices_block p .wcml_schedule_dates input,.wcml_schedule .wcml_schedule_dates input{float:left}.wcml_price_error{display:none;max-width:20em;line-height:1.8em;position:absolute;white-space:normal;background:#d82223;margin:.5em 1px 0 -1em;z-index:9999999;color:#fff;font-size:.8em;text-align:center;border-radius:3px;padding:.618em 1em;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.2);box-shadow:0 1px 3px rgba(0,0,0,0.2)}.wcml_price_error:after{content:'';display:block;border:8px solid #d82223;border-right-color:transparent;border-left-color:transparent;border-top-color:transparent;position:absolute;top:-3px;left:50%;margin:-1em 0 0 -3px}
res/css/wcml-setup-wizard-notice.css CHANGED
@@ -1 +1 @@
1
- div.wpml-message .button-primary{background:#21759b;border-color:#1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}div.wpml-message .button-primary:hover,div.wpml-message .button-primary:focus,div.wpml-message .button-primary:active{background:#1d688a;border-color:#1d6586}div.wpml-message{border-left-color:#21759b}.wcml-notice-list{list-style-type:disc;padding:0 2em;margin:.5em 0}.wcml-notice-list li{margin:0}
1
+ div.wpml-message .button-primary{background:#21759b;border-color:#1d6586;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}div.wpml-message .button-primary:hover,div.wpml-message .button-primary:focus,div.wpml-message .button-primary:active{background:#1d688a;border-color:#1d6586}div.wpml-message{border-left-color:#21759b}.wcml-notice-list{list-style-type:disc;padding:0 2em;margin:.5em 0}.wcml-notice-list li{margin:0}
res/css/wcml-setup.css CHANGED
@@ -1 +1 @@
1
- .wcml-setup .wcml-setup-actions .button-primary{background:#21759b;border-color:#1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}.wcml-setup .wcml-setup-actions .button-primary:hover,.wcml-setup .wcml-setup-actions .button-primary:focus,.wcml-setup .wcml-setup-actions .button-primary:active{background:#1d688a;border-color:#1d6586}body{margin:100px auto 24px;box-shadow:none;background:#f1f1f1;padding:0}#wcml-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wcml-logo img{max-width:50%}.wcml-setup-content{box-shadow:0 1px 3px rgba(0,0,0,0.13);padding:24px 24px 0;background:#fff;overflow:hidden;zoom:1}.wcml-setup-content p,.wcml-setup-content li,.wcml-setup-content table{font-size:1em;line-height:1.75em;color:#666}.wcml-setup-content h1,.wcml-setup-content h2,.wcml-setup-content h3,.wcml-setup-content table{margin:0 0 24px;border:0;padding:0;color:#666;clear:none}.wcml-setup-content p{margin:0 0 24px}.wcml-setup-content a{color:#21759b}.wcml-setup-content a:focus,.wcml-setup-content a:hover{color:#111}.wcml-setup-content .wcml-setup-pages{width:100%;border-top:1px solid #eee}.wcml-setup-content .wcml-setup-pages thead th{display:none}.wcml-setup-content .wcml-setup-pages .page-name{width:30%;font-weight:700}.wcml-setup-content .wcml-setup-pages td,.wcml-setup-content .wcml-setup-pages th{padding:14px 0;border-bottom:1px solid #eee}.wcml-setup-content .wcml-setup-pages td:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages th{padding-top:0}.wcml-setup-content .wcml-setup-pages th:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages .page-options p{color:#777;margin:6px 0 0 24px;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p input{vertical-align:middle;margin:1px 0 0;height:1.75em;width:1.75em;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p label{line-height:1}.wcml-setup-content .wcml-setup-next-steps{overflow:hidden;margin:0 0 24px}.wcml-setup-content .wcml-setup-next-steps h2{margin-bottom:12px}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-first{float:left;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-last{float:right;width:50%;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps ul{padding:0 2em 0 0;list-style:none;margin:0 0 -0.75em}.wcml-setup-content .wcml-setup-next-steps ul li a{display:block;padding:0 0 0.75em}.wcml-setup-content .wcml-setup-next-steps ul .setup-product a{background-color:#21759b;border-color:#21759b;box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 0 rgba(0,0,0,0.15);font-size:1em;height:auto;line-height:1.75em;margin:0 0 .75em;opacity:1;padding:1em;text-align:center;text-shadow:0 -1px 1px #4A4A4A,1px 0 1px #4A4A4A,0 1px 1px #4A4A4A,-1px 0 1px #4A4A4A}.wcml-setup-content .wcml-setup-next-steps ul li a:before{color:#82878c;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none !important;vertical-align:top}.wcml-setup-content .wcml-setup-next-steps ul .learn-more a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .video-walkthrough a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .sidekick a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .newsletter a:before{content:""}.wcml-setup-content .updated{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.wcml-setup-content .updated p{padding:0;margin:0 0 12px}.wcml-setup-content .updated p:last-child{margin:0 0 24px}.wcml-setup-content .wcml-status-list{list-style:none}.wcml-setup-content .wcml-status-list ul li{list-style:none}.wcml-setup-content .wcml-section-header h3{display:none}.wcml-setup-content .no-bullets li{list-style:none}.wcml-setup-content .otgs-ico-no,.wcml-setup-content .otgs-ico-warning,.wcml-setup-content.otgs-ico-delete{color:#9d261d}.wcml-setup-content .otgs-ico-yes,.wcml-setup-content .otgs-ico-ok{color:#51a351}.wcml-setup-content [class*="otgs-ico"]::before{line-height:1.3em !important}@media screen and (max-width: 782px){.wcml-setup-content .form-table tbody th{width:auto}}.wcml-setup-steps{padding:0 0 24px;margin:0;list-style:none;overflow:hidden;color:#ccc;width:100%;display:inline-flex}.wcml-setup-steps li{width:25%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.wcml-setup-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.wcml-setup-steps li.active{border-color:#21759b;color:#21759b}.wcml-setup-steps li.active:before{border-color:#21759b}.wcml-setup-steps li.done{border-color:#21759b;color:#21759b}.wcml-setup-steps li.done:before{border-color:#21759b;background:#21759b}.wcml-setup .wcml-setup-actions:after{content:'';display:table;clear:both}.wcml-setup .wcml-setup-actions .button{float:right;font-size:1.25em;padding:.5em 1em;line-height:1em;margin-right:.5em;height:auto}.wcml-setup .wcml-setup-actions .button-primary{float:right;margin:0;opacity:1}
1
+ .wcml-setup .wcml-setup-actions .button-primary{background:#21759b;border-color:#1d6586;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;box-shadow:inset 0 1px 0 rgba(255,255,255,0.25),0 1px 0 #1d6586;color:#fff;text-shadow:0 -1px 1px #1d6586,1px 0 1px #1d6586,0 1px 1px #1d6586,-1px 0 1px #1d6586}.wcml-setup .wcml-setup-actions .button-primary:hover,.wcml-setup .wcml-setup-actions .button-primary:focus,.wcml-setup .wcml-setup-actions .button-primary:active{background:#1d688a;border-color:#1d6586}body{margin:100px auto 24px;-webkit-box-shadow:none;box-shadow:none;background:#f1f1f1;padding:0}#wcml-logo{border:0;margin:0 0 24px;padding:0;text-align:center}#wcml-logo img{max-width:50%}.wcml-setup-content{-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.13);box-shadow:0 1px 3px rgba(0,0,0,0.13);padding:24px 24px 0;background:#fff;overflow:hidden;zoom:1}.wcml-setup-content p,.wcml-setup-content li,.wcml-setup-content table{font-size:1em;line-height:1.75em;color:#666}.wcml-setup-content h1,.wcml-setup-content h2,.wcml-setup-content h3,.wcml-setup-content table{margin:0 0 24px;border:0;padding:0;color:#666;clear:none}.wcml-setup-content p{margin:0 0 24px}.wcml-setup-content a{color:#21759b}.wcml-setup-content a:focus,.wcml-setup-content a:hover{color:#111}.wcml-setup-content .wcml-setup-pages{width:100%;border-top:1px solid #eee}.wcml-setup-content .wcml-setup-pages thead th{display:none}.wcml-setup-content .wcml-setup-pages .page-name{width:30%;font-weight:700}.wcml-setup-content .wcml-setup-pages td,.wcml-setup-content .wcml-setup-pages th{padding:14px 0;border-bottom:1px solid #eee}.wcml-setup-content .wcml-setup-pages td:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages th{padding-top:0}.wcml-setup-content .wcml-setup-pages th:first-child{padding-right:9px}.wcml-setup-content .wcml-setup-pages .page-options p{color:#777;margin:6px 0 0 24px;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p input{vertical-align:middle;margin:1px 0 0;height:1.75em;width:1.75em;line-height:1.75em}.wcml-setup-content .wcml-setup-pages .page-options p label{line-height:1}.wcml-setup-content .wcml-setup-next-steps{overflow:hidden;margin:0 0 24px}.wcml-setup-content .wcml-setup-next-steps h2{margin-bottom:12px}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-first{float:left;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps .wcml-setup-next-steps-last{float:right;width:50%;-webkit-box-sizing:border-box;box-sizing:border-box}.wcml-setup-content .wcml-setup-next-steps ul{padding:0 2em 0 0;list-style:none;margin:0 0 -0.75em}.wcml-setup-content .wcml-setup-next-steps ul li a{display:block;padding:0 0 0.75em}.wcml-setup-content .wcml-setup-next-steps ul .setup-product a{background-color:#21759b;border-color:#21759b;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 1px 0 rgba(255,255,255,0.2),0 1px 0 rgba(0,0,0,0.15);font-size:1em;height:auto;line-height:1.75em;margin:0 0 .75em;opacity:1;padding:1em;text-align:center;text-shadow:0 -1px 1px #4A4A4A,1px 0 1px #4A4A4A,0 1px 1px #4A4A4A,-1px 0 1px #4A4A4A}.wcml-setup-content .wcml-setup-next-steps ul li a:before{color:#82878c;font:400 20px/1 dashicons;speak:none;display:inline-block;padding:0 10px 0 0;top:1px;position:relative;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-decoration:none !important;vertical-align:top}.wcml-setup-content .wcml-setup-next-steps ul .learn-more a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .video-walkthrough a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .sidekick a:before{content:""}.wcml-setup-content .wcml-setup-next-steps ul .newsletter a:before{content:""}.wcml-setup-content .updated{padding:24px 24px 0;margin:0 0 24px;overflow:hidden;background:#f5f5f5}.wcml-setup-content .updated p{padding:0;margin:0 0 12px}.wcml-setup-content .updated p:last-child{margin:0 0 24px}.wcml-setup-content .wcml-status-list{list-style:none}.wcml-setup-content .wcml-status-list ul li{list-style:none}.wcml-setup-content .wcml-section-header h3{display:none}.wcml-setup-content .no-bullets li{list-style:none}.wcml-setup-content .otgs-ico-no,.wcml-setup-content .otgs-ico-warning,.wcml-setup-content.otgs-ico-delete{color:#9d261d}.wcml-setup-content .otgs-ico-yes,.wcml-setup-content .otgs-ico-ok{color:#51a351}.wcml-setup-content [class*="otgs-ico"]::before{line-height:1.3em !important}@media screen and (max-width: 782px){.wcml-setup-content .form-table tbody th{width:auto}}.wcml-setup-steps{padding:0 0 24px;margin:0;list-style:none;overflow:hidden;color:#ccc;width:100%;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex}.wcml-setup-steps li{width:25%;float:left;padding:0 0 .8em;margin:0;text-align:center;position:relative;border-bottom:4px solid #ccc;line-height:1.4em}.wcml-setup-steps li:before{content:"";border:4px solid #ccc;border-radius:100%;width:4px;height:4px;position:absolute;bottom:0;left:50%;margin-left:-6px;margin-bottom:-8px;background:#fff}.wcml-setup-steps li.active{border-color:#21759b;color:#21759b}.wcml-setup-steps li.active:before{border-color:#21759b}.wcml-setup-steps li.done{border-color:#21759b;color:#21759b}.wcml-setup-steps li.done:before{border-color:#21759b;background:#21759b}.wcml-setup .wcml-setup-actions:after{content:'';display:table;clear:both}.wcml-setup .wcml-setup-actions .button{float:right;font-size:1.25em;padding:.5em 1em;line-height:1em;margin-right:.5em;height:auto}.wcml-setup .wcml-setup-actions .button-primary{float:right;margin:0;opacity:1}
res/images/bg-rating-notice.png ADDED
Binary file
res/js/languages_notice.min.js CHANGED
@@ -1 +1 @@
1
- jQuery(document).ready(function(){jQuery(document).on("click","#wcml_translations_message",function(a){a.preventDefault(),jQuery.ajax({type:"post",url:ajaxurl,data:{action:"hide_wcml_translations_message",wcml_nonce:jQuery("#wcml_hide_languages_notice").val()},success:function(a){jQuery("#wcml_translations_message").remove()}})}),jQuery(document).on("click","#icl_save_language_selection",function(){jQuery("#icl_avail_languages_picker li input").each(function(){if(jQuery(this).is(":checked"))return jQuery('<p class="icl_ajx_response" style="display: block">'+wcml_settings.warn+"</p>").insertBefore("#icl_ajx_response"),!1})})});
1
+ jQuery(document).ready(function(){jQuery(document).on("click","#wcml_translations_message",function(e){e.preventDefault();jQuery.ajax({type:"post",url:ajaxurl,data:{action:"hide_wcml_translations_message",wcml_nonce:jQuery("#wcml_hide_languages_notice").val()},success:function(response){jQuery("#wcml_translations_message").remove()}})});jQuery(document).on("click","#icl_save_language_selection",function(){jQuery("#icl_avail_languages_picker li input").each(function(){if(jQuery(this).is(":checked")){jQuery('<p class="icl_ajx_response" style="display: block">'+wcml_language_upgrade_notices.dont_close+"</p>").insertBefore("#icl_ajx_response");return false}})})});
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInit4be6ab1b4378bf1f9c11125f815eddfc::getLoader();
vendor/composer/autoload_classmap.php CHANGED
@@ -6,6 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
 
9
  'WCML\\Block\\Convert\\ConverterProvider' => $baseDir . '/classes/Block/Convert/ConverterProvider.php',
10
  'WCML\\Block\\Convert\\Converter\\ProductsByAttributes' => $baseDir . '/classes/Block/Convert/Converter/ProductsByAttributes.php',
11
  'WCML\\Block\\Convert\\Hooks' => $baseDir . '/classes/Block/Convert/Hooks.php',
@@ -16,8 +18,23 @@ return array(
16
  'WCML\\Media\\Wrapper\\IMedia' => $baseDir . '/classes/media/Wrapper/IMedia.php',
17
  'WCML\\Media\\Wrapper\\NonTranslatable' => $baseDir . '/classes/media/Wrapper/NonTranslatable.php',
18
  'WCML\\Media\\Wrapper\\Translatable' => $baseDir . '/classes/media/Wrapper/Translatable.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  'WCML\\Rest\\Frontend\\Language' => $baseDir . '/classes/Rest/Frontend/Language.php',
20
  'WCML\\RewriteRules\\Hooks' => $baseDir . '/classes/RewriteRules/Hooks.php',
 
21
  'WCML_ATE_Activate_Synchronization' => $baseDir . '/classes/ate/class-wcml-ate-activate-synchronization.php',
22
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
23
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'WCML\\AdminDashboard\\Hooks' => $baseDir . '/classes/AdminDashboard/Hooks.php',
10
+ 'WCML\\AdminNotices\\Review' => $baseDir . '/classes/AdminNotices/Review.php',
11
  'WCML\\Block\\Convert\\ConverterProvider' => $baseDir . '/classes/Block/Convert/ConverterProvider.php',
12
  'WCML\\Block\\Convert\\Converter\\ProductsByAttributes' => $baseDir . '/classes/Block/Convert/Converter/ProductsByAttributes.php',
13
  'WCML\\Block\\Convert\\Hooks' => $baseDir . '/classes/Block/Convert/Hooks.php',
18
  'WCML\\Media\\Wrapper\\IMedia' => $baseDir . '/classes/media/Wrapper/IMedia.php',
19
  'WCML\\Media\\Wrapper\\NonTranslatable' => $baseDir . '/classes/media/Wrapper/NonTranslatable.php',
20
  'WCML\\Media\\Wrapper\\Translatable' => $baseDir . '/classes/media/Wrapper/Translatable.php',
21
+ 'WCML\\Multicurrency\\Shipping\\AdminHooks' => $baseDir . '/classes/Multicurrency/Shipping/AdminHooks.php',
22
+ 'WCML\\Multicurrency\\Shipping\\DefaultConversion' => $baseDir . '/classes/Multicurrency/Shipping/DefaultConversion.php',
23
+ 'WCML\\Multicurrency\\Shipping\\FlatRateShipping' => $baseDir . '/classes/Multicurrency/Shipping/FlatRateShipping.php',
24
+ 'WCML\\Multicurrency\\Shipping\\FreeShipping' => $baseDir . '/classes/Multicurrency/Shipping/FreeShipping.php',
25
+ 'WCML\\Multicurrency\\Shipping\\FrontEndHooks' => $baseDir . '/classes/Multicurrency/Shipping/FrontEndHooks.php',
26
+ 'WCML\\Multicurrency\\Shipping\\LocalPickup' => $baseDir . '/classes/Multicurrency/Shipping/LocalPickup.php',
27
+ 'WCML\\Multicurrency\\Shipping\\ShippingClasses' => $baseDir . '/classes/Multicurrency/Shipping/ShippingClasses.php',
28
+ 'WCML\\Multicurrency\\Shipping\\ShippingClassesMode' => $baseDir . '/classes/Multicurrency/Shipping/ShippingClassesMode.php',
29
+ 'WCML\\Multicurrency\\Shipping\\ShippingHooksFactory' => $baseDir . '/classes/Multicurrency/Shipping/ShippingHooksFactory.php',
30
+ 'WCML\\Multicurrency\\Shipping\\ShippingMode' => $baseDir . '/classes/Multicurrency/Shipping/ShippingMode.php',
31
+ 'WCML\\Multicurrency\\Shipping\\ShippingModeBase' => $baseDir . '/classes/Multicurrency/Shipping/ShippingModeBase.php',
32
+ 'WCML\\Multicurrency\\Shipping\\ShippingModeProvider' => $baseDir . '/classes/Multicurrency/Shipping/ShippingModeProvider.php',
33
+ 'WCML\\Multicurrency\\Shipping\\UnsupportedShipping' => $baseDir . '/classes/Multicurrency/Shipping/UnsupportedShipping.php',
34
+ 'WCML\\Multicurrency\\Shipping\\VariableCost' => $baseDir . '/classes/Multicurrency/Shipping/VariableCost.php',
35
  'WCML\\Rest\\Frontend\\Language' => $baseDir . '/classes/Rest/Frontend/Language.php',
36
  'WCML\\RewriteRules\\Hooks' => $baseDir . '/classes/RewriteRules/Hooks.php',
37
+ 'WCML\\Tax\\Strings\\Hooks' => $baseDir . '/classes/Tax/Strings/Hooks.php',
38
  'WCML_ATE_Activate_Synchronization' => $baseDir . '/classes/ate/class-wcml-ate-activate-synchronization.php',
39
  'WCML_Accommodation_Bookings' => $baseDir . '/compatibility/class-wcml-accommodation-bookings.php',
40
  'WCML_Admin_Cookie' => $baseDir . '/classes/class-wcml-admin-cookie.php',
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1
6
  {
7
  private static $loader;
8
 
@@ -22,15 +22,15 @@ class ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1
22
  return self::$loader;
23
  }
24
 
25
- spl_autoload_register(array('ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
- spl_autoload_unregister(array('ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
- call_user_func(\Composer\Autoload\ComposerStaticInit2b24f5ddc335620015ade0eba62103e1::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
@@ -51,19 +51,19 @@ class ComposerAutoloaderInit2b24f5ddc335620015ade0eba62103e1
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
- $includeFiles = Composer\Autoload\ComposerStaticInit2b24f5ddc335620015ade0eba62103e1::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
- composerRequire2b24f5ddc335620015ade0eba62103e1($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
- function composerRequire2b24f5ddc335620015ade0eba62103e1($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInit4be6ab1b4378bf1f9c11125f815eddfc
6
  {
7
  private static $loader;
8
 
22
  return self::$loader;
23
  }
24
 
25
+ spl_autoload_register(array('ComposerAutoloaderInit4be6ab1b4378bf1f9c11125f815eddfc', 'loadClassLoader'), true, true);
26
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
27
+ spl_autoload_unregister(array('ComposerAutoloaderInit4be6ab1b4378bf1f9c11125f815eddfc', 'loadClassLoader'));
28
 
29
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
30
  if ($useStaticLoader) {
31
  require_once __DIR__ . '/autoload_static.php';
32
 
33
+ call_user_func(\Composer\Autoload\ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc::getInitializer($loader));
34
  } else {
35
  $map = require __DIR__ . '/autoload_namespaces.php';
36
  foreach ($map as $namespace => $path) {
51
  $loader->register(true);
52
 
53
  if ($useStaticLoader) {
54
+ $includeFiles = Composer\Autoload\ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc::$files;
55
  } else {
56
  $includeFiles = require __DIR__ . '/autoload_files.php';
57
  }
58
  foreach ($includeFiles as $fileIdentifier => $file) {
59
+ composerRequire4be6ab1b4378bf1f9c11125f815eddfc($fileIdentifier, $file);
60
  }
61
 
62
  return $loader;
63
  }
64
  }
65
 
66
+ function composerRequire4be6ab1b4378bf1f9c11125f815eddfc($fileIdentifier, $file)
67
  {
68
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
69
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit2b24f5ddc335620015ade0eba62103e1
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
@@ -25,6 +25,8 @@ class ComposerStaticInit2b24f5ddc335620015ade0eba62103e1
25
  );
26
 
27
  public static $classMap = array (
 
 
28
  'WCML\\Block\\Convert\\ConverterProvider' => __DIR__ . '/../..' . '/classes/Block/Convert/ConverterProvider.php',
29
  'WCML\\Block\\Convert\\Converter\\ProductsByAttributes' => __DIR__ . '/../..' . '/classes/Block/Convert/Converter/ProductsByAttributes.php',
30
  'WCML\\Block\\Convert\\Hooks' => __DIR__ . '/../..' . '/classes/Block/Convert/Hooks.php',
@@ -35,8 +37,23 @@ class ComposerStaticInit2b24f5ddc335620015ade0eba62103e1
35
  'WCML\\Media\\Wrapper\\IMedia' => __DIR__ . '/../..' . '/classes/media/Wrapper/IMedia.php',
36
  'WCML\\Media\\Wrapper\\NonTranslatable' => __DIR__ . '/../..' . '/classes/media/Wrapper/NonTranslatable.php',
37
  'WCML\\Media\\Wrapper\\Translatable' => __DIR__ . '/../..' . '/classes/media/Wrapper/Translatable.php',
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  'WCML\\Rest\\Frontend\\Language' => __DIR__ . '/../..' . '/classes/Rest/Frontend/Language.php',
39
  'WCML\\RewriteRules\\Hooks' => __DIR__ . '/../..' . '/classes/RewriteRules/Hooks.php',
 
40
  'WCML_ATE_Activate_Synchronization' => __DIR__ . '/../..' . '/classes/ate/class-wcml-ate-activate-synchronization.php',
41
  'WCML_Accommodation_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-accommodation-bookings.php',
42
  'WCML_Admin_Cookie' => __DIR__ . '/../..' . '/classes/class-wcml-admin-cookie.php',
@@ -238,9 +255,9 @@ class ComposerStaticInit2b24f5ddc335620015ade0eba62103e1
238
  public static function getInitializer(ClassLoader $loader)
239
  {
240
  return \Closure::bind(function () use ($loader) {
241
- $loader->prefixLengthsPsr4 = ComposerStaticInit2b24f5ddc335620015ade0eba62103e1::$prefixLengthsPsr4;
242
- $loader->prefixDirsPsr4 = ComposerStaticInit2b24f5ddc335620015ade0eba62103e1::$prefixDirsPsr4;
243
- $loader->classMap = ComposerStaticInit2b24f5ddc335620015ade0eba62103e1::$classMap;
244
 
245
  }, null, ClassLoader::class);
246
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
25
  );
26
 
27
  public static $classMap = array (
28
+ 'WCML\\AdminDashboard\\Hooks' => __DIR__ . '/../..' . '/classes/AdminDashboard/Hooks.php',
29
+ 'WCML\\AdminNotices\\Review' => __DIR__ . '/../..' . '/classes/AdminNotices/Review.php',
30
  'WCML\\Block\\Convert\\ConverterProvider' => __DIR__ . '/../..' . '/classes/Block/Convert/ConverterProvider.php',
31
  'WCML\\Block\\Convert\\Converter\\ProductsByAttributes' => __DIR__ . '/../..' . '/classes/Block/Convert/Converter/ProductsByAttributes.php',
32
  'WCML\\Block\\Convert\\Hooks' => __DIR__ . '/../..' . '/classes/Block/Convert/Hooks.php',
37
  'WCML\\Media\\Wrapper\\IMedia' => __DIR__ . '/../..' . '/classes/media/Wrapper/IMedia.php',
38
  'WCML\\Media\\Wrapper\\NonTranslatable' => __DIR__ . '/../..' . '/classes/media/Wrapper/NonTranslatable.php',
39
  'WCML\\Media\\Wrapper\\Translatable' => __DIR__ . '/../..' . '/classes/media/Wrapper/Translatable.php',
40
+ 'WCML\\Multicurrency\\Shipping\\AdminHooks' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/AdminHooks.php',
41
+ 'WCML\\Multicurrency\\Shipping\\DefaultConversion' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/DefaultConversion.php',
42
+ 'WCML\\Multicurrency\\Shipping\\FlatRateShipping' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/FlatRateShipping.php',
43
+ 'WCML\\Multicurrency\\Shipping\\FreeShipping' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/FreeShipping.php',
44
+ 'WCML\\Multicurrency\\Shipping\\FrontEndHooks' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/FrontEndHooks.php',
45
+ 'WCML\\Multicurrency\\Shipping\\LocalPickup' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/LocalPickup.php',
46
+ 'WCML\\Multicurrency\\Shipping\\ShippingClasses' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingClasses.php',
47
+ 'WCML\\Multicurrency\\Shipping\\ShippingClassesMode' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingClassesMode.php',
48
+ 'WCML\\Multicurrency\\Shipping\\ShippingHooksFactory' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingHooksFactory.php',
49
+ 'WCML\\Multicurrency\\Shipping\\ShippingMode' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingMode.php',
50
+ 'WCML\\Multicurrency\\Shipping\\ShippingModeBase' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingModeBase.php',
51
+ 'WCML\\Multicurrency\\Shipping\\ShippingModeProvider' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/ShippingModeProvider.php',
52
+ 'WCML\\Multicurrency\\Shipping\\UnsupportedShipping' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/UnsupportedShipping.php',
53
+ 'WCML\\Multicurrency\\Shipping\\VariableCost' => __DIR__ . '/../..' . '/classes/Multicurrency/Shipping/VariableCost.php',
54
  'WCML\\Rest\\Frontend\\Language' => __DIR__ . '/../..' . '/classes/Rest/Frontend/Language.php',
55
  'WCML\\RewriteRules\\Hooks' => __DIR__ . '/../..' . '/classes/RewriteRules/Hooks.php',
56
+ 'WCML\\Tax\\Strings\\Hooks' => __DIR__ . '/../..' . '/classes/Tax/Strings/Hooks.php',
57
  'WCML_ATE_Activate_Synchronization' => __DIR__ . '/../..' . '/classes/ate/class-wcml-ate-activate-synchronization.php',
58
  'WCML_Accommodation_Bookings' => __DIR__ . '/../..' . '/compatibility/class-wcml-accommodation-bookings.php',
59
  'WCML_Admin_Cookie' => __DIR__ . '/../..' . '/classes/class-wcml-admin-cookie.php',
255
  public static function getInitializer(ClassLoader $loader)
256
  {
257
  return \Closure::bind(function () use ($loader) {
258
+ $loader->prefixLengthsPsr4 = ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc::$prefixLengthsPsr4;
259
+ $loader->prefixDirsPsr4 = ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc::$prefixDirsPsr4;
260
+ $loader->classMap = ComposerStaticInit4be6ab1b4378bf1f9c11125f815eddfc::$classMap;
261
 
262
  }, null, ClassLoader::class);
263
  }
vendor/otgs/installer/includes/class-installer-dependencies.php CHANGED
@@ -34,12 +34,9 @@ class Installer_Dependencies {
34
  }
35
 
36
  public function is_win_paths_exception( $repository_id ) {
37
-
38
  if ( ! isset( $this->is_win_paths_exception[ $repository_id ] ) ) {
39
-
40
  $this->is_win_paths_exception[ $repository_id ] = false;
41
-
42
- if ( strtoupper( substr( PHP_OS, 0, 3 ) ) === 'WIN' ) {
43
 
44
  $windows_max_path_length = 256;
45
  $longest_path['wpml'] = 109;
@@ -50,29 +47,21 @@ class Installer_Dependencies {
50
  $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
51
 
52
  $installer_settings = WP_Installer()->settings;
53
-
54
- if ( isset($installer_settings['repositories'][$repository_id]['data']) && is_array( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] ) ) {
55
- $a_plugin = current( $installer_settings['repositories'][$repository_id]['data']['downloads']['plugins'] );
56
- $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
57
- $tmpfname = wp_tempnam( $url );
58
-
59
  $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
 
60
 
61
  if ( $upgrade_path_length + $tmpname_length + $longest_path[ $repository_id ] + $margin > $windows_max_path_length ) {
62
-
63
  $this->is_win_paths_exception[ $repository_id ] = true;
64
-
65
  }
66
-
67
  }
68
-
69
-
70
  }
71
-
72
  }
73
 
74
  return $this->is_win_paths_exception[ $repository_id ];
75
-
76
  }
77
 
78
  public function is_uploading_allowed() {
34
  }
35
 
36
  public function is_win_paths_exception( $repository_id ) {
 
37
  if ( ! isset( $this->is_win_paths_exception[ $repository_id ] ) ) {
 
38
  $this->is_win_paths_exception[ $repository_id ] = false;
39
+ if ( strtoupper( substr( constant('PHP_OS'), 0, 3 ) ) === 'WIN' ) {
 
40
 
41
  $windows_max_path_length = 256;
42
  $longest_path['wpml'] = 109;
47
  $upgrade_path_length = strlen( WP_CONTENT_DIR . '/upgrade' );
48
 
49
  $installer_settings = WP_Installer()->settings;
50
+ if ( isset( $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'] ) ) {
51
+ $a_plugin = current( $installer_settings['repositories'][ $repository_id ]['data']['downloads']['plugins'] );
52
+ $url = WP_Installer()->append_site_key_to_download_url( $a_plugin['url'], 'xxxxxx', $repository_id );
53
+ $tmpfname = wp_tempnam( $url );
 
 
54
  $tmpname_length = strlen( basename( $tmpfname ) ) - 4; // -.tmp
55
+ wp_delete_file( $tmpfname );
56
 
57
  if ( $upgrade_path_length + $tmpname_length + $longest_path[ $repository_id ] + $margin > $windows_max_path_length ) {
 
58
  $this->is_win_paths_exception[ $repository_id ] = true;
 
59
  }
 
60
  }
 
 
61
  }
 
62
  }
63
 
64
  return $this->is_win_paths_exception[ $repository_id ];
 
65
  }
66
 
67
  public function is_uploading_allowed() {
vendor/otgs/installer/includes/class-wp-installer.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  use OTGS\Installer\Collection;
 
4
 
5
  class WP_Installer {
6
 
@@ -131,7 +132,12 @@ class WP_Installer {
131
  || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
132
  ) {
133
  $this->refresh_repositories_data();
134
- $this->refresh_subscriptions_data();
 
 
 
 
 
135
  }
136
 
137
  if ( empty( $this->settings['_pre_1_0_clean_up'] ) ) {
@@ -212,9 +218,19 @@ class WP_Installer {
212
  $this->package_source = json_decode( $wp_filesystem->get_contents( $package_source_file ) );
213
  }
214
 
 
 
215
  do_action( 'otgs_installer_initialized' );
216
  }
217
 
 
 
 
 
 
 
 
 
218
  /**
219
  * @return OTGS_Products_Manager|null
220
  */
@@ -303,10 +319,16 @@ class WP_Installer {
303
 
304
  if ( is_multisite() && ! is_network_admin() ) {
305
  $this->menu_multisite_redirect();
306
- add_options_page( __( 'Installer', 'installer' ), __( 'Installer', 'installer' ), 'manage_options', 'installer', array(
307
- $this,
308
- 'show_products'
309
- ) );
 
 
 
 
 
 
310
  } else {
311
  if ( $this->config['plugins_install_tab'] && is_admin() && $pagenow === 'plugin-install.php' ) {
312
  // Default GUI, under Plugins -> Install
@@ -314,7 +336,6 @@ class WP_Installer {
314
  add_action( 'install_plugins_commercial', array( $this, 'show_products' ) );
315
  }
316
  }
317
-
318
  }
319
 
320
  public static function menu_url() {
@@ -906,13 +927,12 @@ class WP_Installer {
906
 
907
  }
908
 
909
- private function refresh_subscriptions_data() {
910
  $require_saving_settings = false;
911
  foreach ( $this->repositories as $repository_id => $data ) {
912
- $subscription = $this->get_subscription( $repository_id );
913
  $site_key = $this->get_site_key( $repository_id );
914
 
915
- if ( $subscription->is_valid() || ! $site_key ) {
916
  continue;
917
  }
918
 
@@ -950,7 +970,8 @@ class WP_Installer {
950
  $this->log_subscription_update(
951
  "Subscriptions updated successfully."
952
  );
953
- $this->save_settings();
 
954
  }
955
  }
956
 
@@ -1066,10 +1087,14 @@ class WP_Installer {
1066
  }
1067
 
1068
  public function show_products( $args = array() ) {
 
 
 
 
1069
 
1070
  $screen = get_current_screen();
1071
 
1072
- if ( $screen->base == 'settings_page_installer' ) { // settings page
1073
  echo '<div class="wrap">';
1074
  echo '<h2>' . __( 'Installer', 'installer' ) . '</h2>';
1075
  }
@@ -1091,9 +1116,9 @@ class WP_Installer {
1091
 
1092
  foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
1093
 
1094
- if ( $args['template'] == 'compact' ) {
1095
 
1096
- if ( isset( $args['repository'] ) && $args['repository'] == $repository_id ) {
1097
  include $this->plugin_path() . '/templates/products-compact.php';
1098
  }
1099
 
@@ -1104,7 +1129,6 @@ class WP_Installer {
1104
  }
1105
 
1106
  unset( $site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable );
1107
-
1108
  }
1109
 
1110
  } else {
@@ -1113,7 +1137,7 @@ class WP_Installer {
1113
 
1114
  }
1115
 
1116
- if ( $screen->base == 'settings_page_installer' ) { // settings page
1117
  echo '</div>';
1118
  }
1119
 
@@ -1634,6 +1658,35 @@ class WP_Installer {
1634
  return $this->get_subscription( $repository_id )->is_refunded();
1635
  }
1636
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1637
  public function repository_has_subscription( $repository_id ) {
1638
  $key = false;
1639
  if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription']['key'] ) ) {
1
  <?php
2
 
3
  use OTGS\Installer\Collection;
4
+ use OTGS\Installer\Rest\Push;
5
 
6
  class WP_Installer {
7
 
132
  || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
133
  ) {
134
  $this->refresh_repositories_data();
135
+ }
136
+
137
+ if ( time() - $this->get_last_subscriptions_refresh() > DAY_IN_SECONDS
138
+ || ( isset( $_GET['force-check'] ) && $_GET['force-check'] == 1 )
139
+ ) {
140
+ $this->refresh_subscriptions_data();
141
  }
142
 
143
  if ( empty( $this->settings['_pre_1_0_clean_up'] ) ) {
218
  $this->package_source = json_decode( $wp_filesystem->get_contents( $package_source_file ) );
219
  }
220
 
221
+ add_action( 'rest_api_init', Push::class . '::register_routes' );
222
+
223
  do_action( 'otgs_installer_initialized' );
224
  }
225
 
226
+ public function get_last_subscriptions_refresh() {
227
+ if ( isset( $this->settings['last_subscriptions_update'] ) ) {
228
+ return $this->settings['last_subscriptions_update'];
229
+ }
230
+
231
+ return 0;
232
+ }
233
+
234
  /**
235
  * @return OTGS_Products_Manager|null
236
  */
319
 
320
  if ( is_multisite() && ! is_network_admin() ) {
321
  $this->menu_multisite_redirect();
322
+ add_options_page(
323
+ __( 'Installer', 'installer' ),
324
+ __( 'Installer', 'installer' ),
325
+ 'install_plugins',
326
+ 'installer',
327
+ array(
328
+ $this,
329
+ 'show_products',
330
+ )
331
+ );
332
  } else {
333
  if ( $this->config['plugins_install_tab'] && is_admin() && $pagenow === 'plugin-install.php' ) {
334
  // Default GUI, under Plugins -> Install
336
  add_action( 'install_plugins_commercial', array( $this, 'show_products' ) );
337
  }
338
  }
 
339
  }
340
 
341
  public static function menu_url() {
927
 
928
  }
929
 
930
+ public function refresh_subscriptions_data() {
931
  $require_saving_settings = false;
932
  foreach ( $this->repositories as $repository_id => $data ) {
 
933
  $site_key = $this->get_site_key( $repository_id );
934
 
935
+ if ( ! $site_key ) {
936
  continue;
937
  }
938
 
970
  $this->log_subscription_update(
971
  "Subscriptions updated successfully."
972
  );
973
+ $this->settings['last_subscriptions_update'] = time();
974
+ $this->save_settings();
975
  }
976
  }
977
 
1087
  }
1088
 
1089
  public function show_products( $args = array() ) {
1090
+ if ( ! current_user_can( 'install_plugins' ) ) {
1091
+ wp_die( __('Sorry, you are not allowed to manage Installer for this site.', 'installer' ));
1092
+ return;
1093
+ }
1094
 
1095
  $screen = get_current_screen();
1096
 
1097
+ if ( $screen->base === 'settings_page_installer' ) { // settings page
1098
  echo '<div class="wrap">';
1099
  echo '<h2>' . __( 'Installer', 'installer' ) . '</h2>';
1100
  }
1116
 
1117
  foreach ( $this->settings['repositories'] as $repository_id => $repository ) {
1118
 
1119
+ if ( $args['template'] === 'compact' ) {
1120
 
1121
+ if ( isset( $args['repository'] ) && $args['repository'] === $repository_id ) {
1122
  include $this->plugin_path() . '/templates/products-compact.php';
1123
  }
1124
 
1129
  }
1130
 
1131
  unset( $site_key, $subscription_type, $expired, $upgrade_options, $products_avaliable );
 
1132
  }
1133
 
1134
  } else {
1137
 
1138
  }
1139
 
1140
+ if ( $screen->base === 'settings_page_installer' ) { // settings page
1141
  echo '</div>';
1142
  }
1143
 
1658
  return $this->get_subscription( $repository_id )->is_refunded();
1659
  }
1660
 
1661
+ /**
1662
+ * @return bool
1663
+ */
1664
+ public function should_display_unregister_link_on_refund_notice() {
1665
+ $hide_till_date = $this->get_hide_unregister_link_on_refund_notice_till_date();
1666
+
1667
+ return time() > (int) $hide_till_date;
1668
+ }
1669
+
1670
+ private function get_hide_unregister_link_on_refund_notice_till_date() {
1671
+ if ( defined( 'OTGS_INSTALLER_OVERRIDE_HIDE_UNREGISTERED_TILL' ) ) {
1672
+ return constant( 'OTGS_INSTALLER_OVERRIDE_HIDE_UNREGISTERED_TILL' );
1673
+ }
1674
+
1675
+ if ( isset( $this->settings['hide_unregister_link_on_refund_notice_till'] ) ) {
1676
+ return $this->settings['hide_unregister_link_on_refund_notice_till'];
1677
+ }
1678
+
1679
+ $hide_till_date = time() + WEEK_IN_SECONDS;
1680
+ $this->set_hide_unregister_link_on_refund_notice_date( $hide_till_date );
1681
+
1682
+ return $hide_till_date;
1683
+ }
1684
+
1685
+ public function set_hide_unregister_link_on_refund_notice_date( $hide_till_date ) {
1686
+ $this->settings['hide_unregister_link_on_refund_notice_till'] = $hide_till_date;
1687
+ $this->save_settings();
1688
+ }
1689
+
1690
  public function repository_has_subscription( $repository_id ) {
1691
  $key = false;
1692
  if ( ! empty( $this->settings['repositories'][ $repository_id ]['subscription']['key'] ) ) {
vendor/otgs/installer/includes/functions-core.php CHANGED
@@ -1,8 +1,15 @@
1
  <?php
 
 
 
2
  function WP_Installer(){
3
  return WP_Installer::instance();
4
  }
5
 
 
 
 
 
6
  function WP_Installer_Channels(){
7
  return WP_Installer_Channels::instance();
8
  }
1
  <?php
2
+ /**
3
+ * @deprecated
4
+ */
5
  function WP_Installer(){
6
  return WP_Installer::instance();
7
  }
8
 
9
+ function OTGS_Installer(){
10
+ return WP_Installer::instance();
11
+ }
12
+
13
  function WP_Installer_Channels(){
14
  return WP_Installer_Channels::instance();
15
  }
vendor/otgs/installer/includes/otgs-installer-autoload-classmap.php CHANGED
@@ -1,7 +1,7 @@
1
  <?php
2
  $baseDir = dirname( dirname( __FILE__ ) );
3
 
4
- return array(
5
  'Installer_Dependencies' => $baseDir . '/includes/class-installer-dependencies.php',
6
  'Installer_Theme_Class' => $baseDir . '/includes/class-installer-theme.php',
7
  'Installer_Upgrader_Skins' => $baseDir . '/includes/class-installer-upgrader-skins.php',
@@ -93,4 +93,5 @@ return array(
93
  'OTGS\Installer\Templates\Repository\Refunded' => $baseDir . '/templates/repository-refunded.php',
94
  'OTGS\Installer\Templates\Repository\Registered' => $baseDir . '/templates/repository-registered.php',
95
  'OTGS\Installer\Templates\Repository\RegisteredButtons' => $baseDir . '/templates/repository-registered-buttons.php',
96
- );
 
1
  <?php
2
  $baseDir = dirname( dirname( __FILE__ ) );
3
 
4
+ return [
5
  'Installer_Dependencies' => $baseDir . '/includes/class-installer-dependencies.php',
6
  'Installer_Theme_Class' => $baseDir . '/includes/class-installer-theme.php',
7
  'Installer_Upgrader_Skins' => $baseDir . '/includes/class-installer-upgrader-skins.php',
93
  'OTGS\Installer\Templates\Repository\Refunded' => $baseDir . '/templates/repository-refunded.php',
94
  'OTGS\Installer\Templates\Repository\Registered' => $baseDir . '/templates/repository-registered.php',
95
  'OTGS\Installer\Templates\Repository\RegisteredButtons' => $baseDir . '/templates/repository-registered-buttons.php',
96
+ 'OTGS\Installer\Rest\Push' => $baseDir . '/includes/rest/Push.php',
97
+ ];
vendor/otgs/installer/includes/rest/Push.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace OTGS\Installer\Rest;
4
+
5
+ use \WP_REST_Response;
6
+
7
+ class Push {
8
+
9
+ const REFRESH_INTERVAL = 7200; //2 hours
10
+
11
+ const REST_NAMESPACE = 'otgs/installer/v1';
12
+
13
+ public static function register_routes() {
14
+ register_rest_route(
15
+ self::REST_NAMESPACE,
16
+ 'push/fetch-subscription',
17
+ [
18
+ 'methods' => 'GET',
19
+ 'callback' => self::class . '::fetch_subscription',
20
+ ]
21
+ );
22
+ }
23
+
24
+ public static function fetch_subscription() {
25
+ $installer = OTGS_Installer();
26
+ $last_refresh = $installer->get_last_subscriptions_refresh();
27
+
28
+ if ( defined( 'OTGS_INSTALLER_OVERRIDE_SUB_LAST_REFRESH' ) ) {
29
+ $last_refresh = constant( 'OTGS_INSTALLER_OVERRIDE_SUB_LAST_REFRESH' );
30
+ }
31
+
32
+ if ( time() - $last_refresh > self::REFRESH_INTERVAL
33
+ ) {
34
+ $installer->refresh_subscriptions_data();
35
+
36
+ return new WP_REST_Response( [ 'message' => 'OK' ], 200 );
37
+ }
38
+
39
+ return new WP_REST_Response( [ 'message' => 'OK' ], 403 );
40
+ }
41
+ }
vendor/otgs/installer/loader.php CHANGED
@@ -51,7 +51,7 @@ $wp_installer_instance = dirname( __FILE__ ) . '/installer.php';
51
  global $wp_installer_instances;
52
  $wp_installer_instances[ $wp_installer_instance ] = array(
53
  'bootfile' => $wp_installer_instance,
54
- 'version' => '2.2.7'
55
  );
56
 
57
 
@@ -124,17 +124,19 @@ if ( ! function_exists( 'wpml_installer_instance_delegator' ) ) {
124
  function wpml_installer_instance_delegator() {
125
  global $wp_installer_instances;
126
 
 
127
  // version based election.
128
  foreach ( $wp_installer_instances as $instance_key => $instance ) {
129
  $wp_installer_instances[ $instance_key ]['delegated'] = false;
130
 
131
  if ( ! isset( $delegate ) || version_compare( $instance['version'], $delegate['version'], '>' ) ) {
132
- $delegate = $instance;
133
-
134
- $wp_installer_instances[ $instance_key ]['delegated'] = true;
135
  }
136
  }
137
 
 
 
138
  // priority based election.
139
  $highest_priority = null;
140
  foreach ( $wp_installer_instances as $instance ) {
51
  global $wp_installer_instances;
52
  $wp_installer_instances[ $wp_installer_instance ] = array(
53
  'bootfile' => $wp_installer_instance,
54
+ 'version' => '2.4.0'
55
  );
56
 
57
 
124
  function wpml_installer_instance_delegator() {
125
  global $wp_installer_instances;
126
 
127
+ $delegated_instance_key = null;
128
  // version based election.
129
  foreach ( $wp_installer_instances as $instance_key => $instance ) {
130
  $wp_installer_instances[ $instance_key ]['delegated'] = false;
131
 
132
  if ( ! isset( $delegate ) || version_compare( $instance['version'], $delegate['version'], '>' ) ) {
133
+ $delegate = $instance;
134
+ $delegated_instance_key = $instance_key;
 
135
  }
136
  }
137
 
138
+ $wp_installer_instances[ $delegated_instance_key ]['delegated'] = true;
139
+
140
  // priority based election.
141
  $highest_priority = null;
142
  foreach ( $wp_installer_instances as $instance ) {
vendor/otgs/installer/templates/channel-selector.php CHANGED
@@ -19,8 +19,8 @@
19
  '%CHANNEL%', WP_Installer()->get_generic_product_name( $repository_id ) ) ) ?>">
20
  </span>
21
  <span class="installer-channel-update-fail" data-text-unstable="<?php
22
- $support_url = $repository_id ==='toolset' ? 'https://wp-types.com/forums/forum/support-2/' : 'https://wpml.org/forums/forum/english-support/';
23
- $download_url = $repository_id ==='toolset' ? 'https://wp-types.com/account/downloads/' : 'https://wpml.org/account/downloads/';
24
  echo esc_attr( sprintf(
25
  __( "Something went wrong and we could not install all updates from the %s channel. Click here to %stry again%s. If the errors persist, please switch back to the Production channel and contact the %s%s support%s.", 'installer' ),
26
  '%CHANNEL%',
19
  '%CHANNEL%', WP_Installer()->get_generic_product_name( $repository_id ) ) ) ?>">
20
  </span>
21
  <span class="installer-channel-update-fail" data-text-unstable="<?php
22
+ $support_url = $repository_id ==='toolset' ? 'https://toolset.com/forums/forum/professional-support/' : 'https://wpml.org/forums/forum/english-support/';
23
+ $download_url = $repository_id ==='toolset' ? 'https://toolset.com/account/downloads/' : 'https://wpml.org/account/downloads/';
24
  echo esc_attr( sprintf(
25
  __( "Something went wrong and we could not install all updates from the %s channel. Click here to %stry again%s. If the errors persist, please switch back to the Production channel and contact the %s%s support%s.", 'installer' ),
26
  '%CHANNEL%',
vendor/otgs/installer/templates/repository-expired.php CHANGED
@@ -28,7 +28,7 @@ class Expired {
28
 
29
  ?>
30
  <div class="otgs-installer-registered otgs-installer-expired clearfix">
31
- <div class="notice inline otgs-installer-notice otgs-installer-notice-expired otgs-installer-notice-<?php echo $model->repoId; ?>">
32
  <div class="otgs-installer-notice-content">
33
  <h2><?php echo esc_html( $title ); ?>
34
  <a class="update_site_key_js"
28
 
29
  ?>
30
  <div class="otgs-installer-registered otgs-installer-expired clearfix">
31
+ <div class="notice inline otgs-installer-notice otgs-installer-notice-expired">
32
  <div class="otgs-installer-notice-content">
33
  <h2><?php echo esc_html( $title ); ?>
34
  <a class="update_site_key_js"
vendor/otgs/installer/templates/repository-listing.php CHANGED
@@ -39,6 +39,7 @@ $model = (object) [
39
  \OTGS\Installer\Templates\Repository\Expired::render( $model );
40
  } else if ( $this->repository_has_refunded_subscription( $repository_id ) ) {
41
  $model->expired = true;
 
42
  \OTGS\Installer\Templates\Repository\Refunded::render( $model );
43
  } else {
44
  $this->show_subscription_renew_warning( $repository_id, $subscription_type );
39
  \OTGS\Installer\Templates\Repository\Expired::render( $model );
40
  } else if ( $this->repository_has_refunded_subscription( $repository_id ) ) {
41
  $model->expired = true;
42
+ $model->shouldDisplayUnregisterLink = $this->should_display_unregister_link_on_refund_notice();
43
  \OTGS\Installer\Templates\Repository\Refunded::render( $model );
44
  } else {
45
  $this->show_subscription_renew_warning( $repository_id, $subscription_type );
vendor/otgs/installer/templates/repository-refunded.php CHANGED
@@ -11,7 +11,7 @@ class Refunded {
11
  $buyButton = __( 'Check my order status', 'installer' );
12
  ?>
13
  <div class="otgs-installer-registered clearfix">
14
- <div class="notice inline otgs-installer-notice otgs-installer-notice-refund otgs-installer-notice-<?php echo $model->repoId; ?>">
15
  <div class="otgs-installer-notice-content">
16
  <h2><?php echo esc_html( $title ); ?></h2>
17
  <p><?php echo esc_html( $into ); ?></p>
@@ -26,7 +26,9 @@ class Refunded {
26
  </a>
27
 
28
  <?php
29
- \OTGS\Installer\Templates\Repository\RegisteredButtons::render( $model );
 
 
30
  ?>
31
  </div>
32
  </div>
11
  $buyButton = __( 'Check my order status', 'installer' );
12
  ?>
13
  <div class="otgs-installer-registered clearfix">
14
+ <div class="notice inline otgs-installer-notice otgs-installer-notice-refund">
15
  <div class="otgs-installer-notice-content">
16
  <h2><?php echo esc_html( $title ); ?></h2>
17
  <p><?php echo esc_html( $into ); ?></p>
26
  </a>
27
 
28
  <?php
29
+ if( $model->shouldDisplayUnregisterLink ) {
30
+ \OTGS\Installer\Templates\Repository\RegisteredButtons::render( $model );
31
+ }
32
  ?>
33
  </div>
34
  </div>
wpml-woocommerce.php CHANGED
@@ -7,11 +7,11 @@
7
  * Author URI: http://www.onthegosystems.com/
8
  * Text Domain: woocommerce-multilingual
9
  * Requires at least: 4.7
10
- * Tested up to: 5.4
11
- * Version: 4.8.0
12
  * Plugin Slug: woocommerce-multilingual
13
  * WC requires at least: 3.3.0
14
- * WC tested up to: 4.0.1
15
  *
16
  * @package WCML
17
  * @author OnTheGoSystems
@@ -33,7 +33,7 @@ if ( ! $wpml_php_version_check->is_ok() ) {
33
  return;
34
  }
35
 
36
- define( 'WCML_VERSION', '4.8.0' );
37
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
38
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
39
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
@@ -83,6 +83,10 @@ function wcml_loader() {
83
  \WCML\Email\Settings\Hooks::class,
84
  \WCML\Block\Convert\Hooks::class,
85
  \WCML\MO\Hooks::class,
 
 
 
 
86
  ];
87
 
88
  if (
7
  * Author URI: http://www.onthegosystems.com/
8
  * Text Domain: woocommerce-multilingual
9
  * Requires at least: 4.7
10
+ * Tested up to: 5.4.1
11
+ * Version: 4.9.0
12
  * Plugin Slug: woocommerce-multilingual
13
  * WC requires at least: 3.3.0
14
+ * WC tested up to: 3.8.0
15
  *
16
  * @package WCML
17
  * @author OnTheGoSystems
33
  return;
34
  }
35
 
36
+ define( 'WCML_VERSION', '4.9.0' );
37
  define( 'WCML_PLUGIN_PATH', dirname( __FILE__ ) );
38
  define( 'WCML_PLUGIN_FOLDER', basename( WCML_PLUGIN_PATH ) );
39
  define( 'WCML_LOCALE_PATH', WCML_PLUGIN_PATH . '/locale' );
83
  \WCML\Email\Settings\Hooks::class,
84
  \WCML\Block\Convert\Hooks::class,
85
  \WCML\MO\Hooks::class,
86
+ \WCML\Multicurrency\Shipping\ShippingHooksFactory::class,
87
+ \WCML\Tax\Strings\Hooks::class,
88
+ \WCML\AdminDashboard\Hooks::class,
89
+ \WCML\AdminNotices\Review::class,
90
  ];
91
 
92
  if (