WooCommerce Multilingual – run WooCommerce with WPML - Version 4.7.3

Version Description

  • Fixed PHP Fatal error: Uncaught LogicException: A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.
  • Fixed wrong language for some string on WooCommerce shipping settings page when switching admin language using language switcher.
Download this release

Release Info

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

Code changes from version 4.7.2 to 4.7.3

changelog/4.7.2.md DELETED
@@ -1,6 +0,0 @@
1
- # Fixes
2
- * [wcml-2982] Fixed a fatal error that sometimes happened when updating WPML 4.1.0 to WPML 4.3.0.
3
- * [wcml-2979] Fixed an error that happened when updating a product using the WooCommerce version older than 3.6.0.
4
-
5
- # Performances
6
- * [wcml-2980] Replaced the "wp_" cookie prefix with "wp-".
 
 
 
 
 
 
changelog/4.7.3.md ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ # Fixes
2
+ * [wcml-2987] Fixed PHP Fatal error: Uncaught LogicException: A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.
3
+ * [wcml-2982] Fixed a fatal error that sometimes happened when updating WPML 4.1.0 to WPML 4.3.0.
inc/class-wcml-terms.php CHANGED
@@ -681,21 +681,20 @@ class WCML_Terms{
681
  return $terms;
682
  }
683
 
684
- function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
685
 
686
  $on_wc_settings_page = isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] === 'wc-settings';
687
  $on_shipping_tab = isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] === 'shipping';
688
  $on_classes_section = isset( $_GET[ 'section' ] ) && $_GET[ 'section' ] === 'classes';
689
 
690
- if( is_admin() && in_array( 'product_shipping_class', (array) $taxonomies ) && $on_wc_settings_page && $on_shipping_tab && !$on_classes_section ){
691
- remove_filter('get_terms',array($this,'filter_shipping_classes_terms'));
692
- $current_language = $this->sitepress->get_current_language();
693
- $this->sitepress->switch_lang($this->sitepress->get_default_language());
694
- add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
695
- $terms = get_terms( $taxonomies, $args );
696
- remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
697
  add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
698
- $this->sitepress->switch_lang($current_language);
699
  }
700
 
701
  return $terms;
681
  return $terms;
682
  }
683
 
684
+ public function filter_shipping_classes_terms( $terms, $taxonomies, $args ){
685
 
686
  $on_wc_settings_page = isset( $_GET[ 'page' ] ) && $_GET[ 'page' ] === 'wc-settings';
687
  $on_shipping_tab = isset( $_GET[ 'tab' ] ) && $_GET[ 'tab' ] === 'shipping';
688
  $on_classes_section = isset( $_GET[ 'section' ] ) && $_GET[ 'section' ] === 'classes';
689
 
690
+ if( is_admin() && in_array( 'product_shipping_class', $taxonomies ) && $on_wc_settings_page && $on_shipping_tab && !$on_classes_section ){
691
+ remove_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ) );
692
+ remove_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
693
+ $this->sitepress->switch_lang( $this->sitepress->get_default_language() );
694
+ $terms = get_terms( $args );
695
+ add_filter( 'get_terms', array( 'WPML_Terms_Translations', 'get_terms_filter' ), 10, 2 );
 
696
  add_filter( 'get_terms', array( $this, 'filter_shipping_classes_terms' ), 10, 3 );
697
+ $this->sitepress->switch_lang();
698
  }
699
 
700
  return $terms;
inc/class-wcml-upgrade.php CHANGED
@@ -1,654 +1,639 @@
1
  <?php
2
 
3
- class WCML_Upgrade{
4
-
5
- private $versions = array(
6
-
7
- '2.9.9.1',
8
- '3.1',
9
- '3.2',
10
- '3.3',
11
- '3.5',
12
- '3.5.4',
13
- '3.6',
14
- '3.7',
15
- '3.7.3',
16
- '3.7.11',
17
- '3.8',
18
- '3.9',
19
- '3.9.1',
20
- '4.0',
21
- '4.1.0',
22
- '4.2.0',
23
- '4.2.2',
24
- '4.2.7',
25
- '4.2.10',
26
- '4.2.11',
27
- '4.3.0',
28
- '4.3.4',
29
- '4.3.5',
30
- '4.4.1',
31
- '4.4.3',
32
- '4.6.8',
33
- );
34
-
35
- function __construct(){
36
-
37
- add_action('init', array($this, 'run'));
38
- add_action('init', array($this, 'setup_upgrade_notices'));
39
- add_action('admin_notices', array($this, 'show_upgrade_notices'));
40
-
41
- add_action('wp_ajax_wcml_hide_notice', array($this, 'hide_upgrade_notice'));
42
-
43
- }
44
-
45
- function setup_upgrade_notices(){
46
-
47
- $wcml_settings = get_option('_wcml_settings');
48
- $version_in_db = get_option('_wcml_version');
49
-
50
- if(!empty($version_in_db) && version_compare($version_in_db, '2.9.9.1', '<')){
51
- $n = 'varimages';
52
- $wcml_settings['notifications'][$n] =
53
- array(
54
- 'show' => 1,
55
- 'text' => __( 'Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?', 'woocommerce-multilingual' ).
56
- '<br /><strong>' .
57
- ' <a href="' . admin_url('admin.php?page=wpml-wcml&tab=troubleshooting') . '">' . __( 'Yes, go to the troubleshooting page', 'woocommerce-multilingual' ) . '</a> |' .
58
- ' <a href="#" onclick="jQuery.ajax({type:\'POST\',url: ajaxurl,data:\'action=wcml_hide_notice&notice='.$n.'\',success:function(){jQuery(\'#' . $n . '\').fadeOut()}});return false;">' . __( 'No - dismiss', 'woocommerce-multilingual' ) . '</a>' .
59
- '</strong>'
60
- );
61
- update_option('_wcml_settings', $wcml_settings);
62
- }
63
-
64
- }
65
-
66
- function show_upgrade_notices(){
67
- $wcml_settings = get_option('_wcml_settings');
68
- if(!empty($wcml_settings['notifications'])){
69
- foreach($wcml_settings['notifications'] as $k => $notification){
70
-
71
- // exceptions
72
- if(isset($_GET['tab']) && $_GET['tab'] == 'troubleshooting' && $k == 'varimages') continue;
73
-
74
- if($notification['show']){
75
- ?>
76
- <div id="<?php echo $k ?>" class="updated">
77
- <p><?php echo $notification['text'] ?></p>
78
- </div>
79
- <?php
80
- }
81
- }
82
- }
83
- }
84
-
85
- function hide_upgrade_notice($k){
86
-
87
- if(empty($k)){
88
- $k = $_POST['notice'];
89
- }
90
-
91
- $wcml_settings = get_option('_wcml_settings');
92
- if(isset($wcml_settings['notifications'][$k])){
93
- $wcml_settings['notifications'][$k]['show'] = 0;
94
- update_option('_wcml_settings', $wcml_settings);
95
- }
96
- }
97
-
98
- function run(){
99
-
100
- $version_in_db = get_option('_wcml_version');
101
-
102
- // exception - starting in 2.3.2
103
- if(empty($version_in_db) && get_option('icl_is_wcml_installed')){
104
- $version_in_db = '2.3.2';
105
- }
106
-
107
- $migration_ran = false;
108
-
109
- if ( $version_in_db && version_compare( $version_in_db, WCML_VERSION, '<' ) ) {
110
-
111
- foreach ( $this->versions as $version ) {
112
-
113
- if ( version_compare( $version, $version_in_db, '>' ) ) {
114
-
115
- $upgrade_method = 'upgrade_' . str_replace( '.', '_', $version );
116
-
117
- if ( method_exists( $this, $upgrade_method ) ) {
118
- $this->$upgrade_method();
119
- $migration_ran = true;
120
- }
121
-
122
- }
123
-
124
- }
125
-
126
- }
127
-
128
- if($migration_ran || empty($version_in_db)){
129
- update_option('_wcml_version', WCML_VERSION);
130
- }
131
-
132
- if( get_option( '_wcml_4_1_0_migration_required' ) && class_exists( 'woocommerce' ) ){
133
- $this->upgrade_4_1_0();
134
- delete_option('_wcml_4_1_0_migration_required' );
135
- }
136
- }
137
-
138
- function upgrade_2_9_9_1(){
139
- global $wpdb;
140
-
141
- //migrate exists currencies
142
- $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
143
- foreach($currencies as $currency){
144
- if(isset($currency->language_code)){
145
- $wpdb->insert($wpdb->prefix .'icl_languages_currencies', array(
146
- 'language_code' => $currency->language_code,
147
- 'currency_id' => $currency->id
148
- )
149
- );
150
- }
151
- }
152
-
153
- $cols = $wpdb->get_col("SHOW COLUMNS FROM {$wpdb->prefix}icl_currencies");
154
- if(in_array('language_code', $cols)){
155
- $wpdb->query("ALTER TABLE {$wpdb->prefix}icl_currencies DROP COLUMN language_code");
156
- }
157
-
158
- // migrate settings
159
- $new_settings = array(
160
- 'is_term_order_synced' => get_option('icl_is_wcml_term_order_synched'),
161
- 'file_path_sync' => get_option('wcml_file_path_sync'),
162
- 'is_installed' => get_option('icl_is_wpcml_installed'),
163
- 'dismiss_doc_main' => get_option('wpml_dismiss_doc_main'),
164
- 'enable_multi_currency' => get_option('icl_enable_multi_currency'),
165
- 'currency_converting_option' => get_option('currency_converting_option')
166
- );
167
-
168
- if(!get_option('_wcml_settings')){
169
- add_option('_wcml_settings', $new_settings, false, true);
170
- }
171
-
172
- delete_option('icl_is_wcml_term_order_synced');
173
- delete_option('wcml_file_path_sync');
174
- delete_option('icl_is_wpcml_installed');
175
- delete_option('wpml_dismiss_doc_main');
176
- delete_option('icl_enable_multi_currency');
177
- delete_option('currency_converting_option');
178
-
179
-
180
- }
181
-
182
- function upgrade_3_1(){
183
- global $wpdb,$sitepress;
184
- $wcml_settings = get_option('_wcml_settings');
185
-
186
- if(isset($wcml_settings['enable_multi_currency']) && $wcml_settings['enable_multi_currency'] == 'yes'){
187
- $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_INDEPENDENT;
188
- }else{
189
- $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_DISABLED;
190
- }
191
-
192
- $wcml_settings['products_sync_date'] = 1;
193
-
194
-
195
- update_option('_wcml_settings', $wcml_settings);
196
-
197
- // multi-currency migration
198
- if($wcml_settings['enable_multi_currency'] == 'yes' && $wcml_settings['currency_converting_option'] == 2){
199
-
200
- // get currencies exchange rates
201
- $results = $wpdb->get_results("SELECT code, value FROM {$wpdb->prefix}icl_currencies");
202
- foreach($results as $row){
203
- $exchange_rates[$row->code] = $row->value;
204
- }
205
-
206
- // get languages currencies map
207
- $results = $wpdb->get_results("SELECT l.language_code, c.code FROM {$wpdb->prefix}icl_languages_currencies l JOIN {$wpdb->prefix}icl_currencies c ON l.currency_id = c.id");
208
- foreach($results as $row){
209
- $language_currencies[$row->language_code] = $row->code;
210
- }
211
-
212
-
213
- $results = $wpdb->get_results($wpdb->prepare("
214
  SELECT p.ID, t.trid, t.element_type
215
  FROM {$wpdb->posts} p JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
216
  WHERE
217
  p.post_type in ('product', 'product_variation') AND t.language_code = %s
218
 
219
- ", $sitepress->get_default_language()));
220
-
221
- // set custom conversion rates
222
- foreach($results as $row){
223
- $translations = $sitepress->get_element_translations($row->trid, $row->element_type);
224
- $meta = get_post_meta($row->ID);
225
- $original_prices['_price'] = !empty($meta['_price']) ? $meta['_price'][0] : 0;
226
- $original_prices['_regular_price'] = !empty($meta['_regular_price']) ? $meta['_regular_price'][0] : 0;
227
- $original_prices['_sale_price'] = !empty($meta['_sale_price']) ? $meta['_sale_price'][0] : 0;
228
-
229
-
230
- $ccr = array();
231
-
232
- foreach($translations as $translation){
233
- if($translation->element_id != $row->ID){
234
-
235
- $meta = get_post_meta($translation->element_id);
236
- $translated_prices['_price'] = $meta['_price'][0];
237
- $translated_prices['_regular_price'] = $meta['_regular_price'][0];
238
- $translated_prices['_sale_price'] = $meta['_sale_price'][0];
239
-
240
- if(!empty($translated_prices['_price']) && !empty($original_prices['_price']) && $translated_prices['_price'] != $original_prices['_price']){
241
-
242
- $ccr['_price'][$language_currencies[$translation->language_code]] = $translated_prices['_price'] / $original_prices['_price'];
243
-
244
- }
245
- if(!empty($translated_prices['_regular_price']) && !empty($original_prices['_regular_price']) && $translated_prices['_regular_price'] != $original_prices['_regular_price']){
246
-
247
- $ccr['_regular_price'][$language_currencies[$translation->language_code]] = $translated_prices['_regular_price'] / $original_prices['_regular_price'];
248
-
249
- }
250
- if(!empty($translated_prices['_sale_price']) && !empty($original_prices['_sale_price']) && $translated_prices['_sale_price'] != $original_prices['_sale_price']){
251
-
252
- $ccr['_sale_price'][$language_currencies[$translation->language_code]] = $translated_prices['_sale_price'] / $original_prices['_sale_price'] ;
253
-
254
- }
255
-
256
-
257
- }
258
- }
259
-
260
- if($ccr){
261
- update_post_meta($row->ID, '_custom_conversion_rate', $ccr);
262
- }
263
-
264
-
265
- }
266
-
267
-
268
- }
269
-
270
- }
271
-
272
- function upgrade_3_2(){
273
-
274
- WCML_Capabilities::set_up_capabilities();
275
-
276
- //delete not existing currencies in WC
277
- global $wpdb;
278
- $currencies = $wpdb->get_results("SELECT id,code FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` DESC");
279
- $wc_currencies = get_woocommerce_currencies();
280
- foreach ($currencies as $currency){
281
- if(!array_key_exists($currency->code,$wc_currencies)){
282
- $wpdb->delete( $wpdb->prefix . 'icl_currencies', array( 'ID' => $currency->id ) );
283
- }
284
- }
285
-
286
- }
287
-
288
- function upgrade_3_3(){
289
- global $wpdb, $woocommerce_wpml;
290
-
291
- WCML_Capabilities::set_up_capabilities();
292
-
293
- $currencies = $wpdb->get_results("SELECT * FROM " . $wpdb->prefix . "icl_currencies ORDER BY `id` ASC", OBJECT);
294
- if($currencies)
295
- foreach($this->currencies as $currency){
296
-
297
- $woocommerce_wpml->settings['currency_options'][$currency->code]['rate'] = $currency->value;
298
- $woocommerce_wpml->settings['currency_options'][$currency->code]['updated'] = $currency->changed;
299
- $woocommerce_wpml->settings['currency_options'][$currency->code]['position'] = 'left';
300
- $woocommerce_wpml->settings['currency_options'][$currency->code]['languages'] = $woocommerce_wpml->settings['currencies_languages'];
301
- unset($woocommerce_wpml->settings['currencies_languages']);
302
-
303
- $woocommerce_wpml->update_settings();
304
-
305
- }
306
-
307
- $wpdb->query("DROP TABLE `{$wpdb->prefix}icl_currencies`");
308
-
309
- }
310
-
311
- function upgrade_3_5()
312
- {
313
- global $wpdb;
314
- $wcml_settings = get_option('_wcml_settings');
315
-
316
- $wcml_settings['products_sync_order'] = 1;
317
-
318
- update_option('_wcml_settings', $wcml_settings);
319
- }
320
-
321
- function upgrade_3_5_4()
322
- {
323
- flush_rewrite_rules( );
324
- }
325
-
326
- function upgrade_3_6()
327
- {
328
- $wcml_settings = get_option('_wcml_settings');
329
-
330
- $wcml_settings['display_custom_prices'] = 0;
331
- $wcml_settings['currency_switcher_product_visibility'] = 1;
332
-
333
- update_option('_wcml_settings', $wcml_settings);
334
- }
335
-
336
- function upgrade_3_7(){
337
- global $woocommerce_wpml,$wpdb;
338
-
339
- $woocommerce_permalinks = maybe_unserialize( get_option('woocommerce_permalinks') );
340
-
341
- if( is_array( $woocommerce_permalinks ) ) {
342
- foreach ( $woocommerce_permalinks as $base_key => $base ) {
343
-
344
- $base_key = trim( $base_key, '/' );
345
-
346
- if ( $base ) {
347
- $taxonomy = false;
348
-
349
- switch ( $base_key ) {
350
- case 'category_base':
351
- $taxonomy = 'product_cat';
352
- break;
353
- case 'tag_base':
354
- $taxonomy = 'product_tag';
355
- break;
356
- case 'attribute_base':
357
- $taxonomy = 'attribute';
358
- break;
359
- }
360
-
361
- if ( $taxonomy ) {
362
- $wpdb->update(
363
- $wpdb->prefix . 'icl_strings',
364
- array(
365
- 'context' => 'WordPress',
366
- 'name' => sprintf( 'URL %s tax slug', $taxonomy )
367
- ),
368
- array(
369
- 'context' => sprintf( 'URL %s slugs - %s', $taxonomy, $base ),
370
- 'name' => sprintf( 'Url %s slug: %s', $taxonomy, $base )
371
- )
372
- );
373
-
374
- }
375
- }
376
-
377
- }
378
- }
379
-
380
- $endpoint_keys = array( 'order-pay', 'order-received', 'view-order', 'edit-account', 'edit-address', 'lost-password', 'customer-logout', 'add-payment-method' );
381
-
382
- foreach( $endpoint_keys as $endpoint_key ){
383
-
384
- $wpdb->query(
385
- $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
386
- SET context = 'WooCommerce Endpoints', name = %s
387
- WHERE context = 'WordPress' AND name = %s",
388
- $endpoint_key, 'Endpoint slug: '. $endpoint_key )
389
- );
390
 
391
- // update domain_name_context_md5 value
392
- $string_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = 'WooCommerce Endpoints' AND name = %s", $endpoint_key ) );
 
 
 
 
 
393
 
394
- if( $string_id ){
395
- $wpdb->query(
396
- $wpdb->prepare( "UPDATE {$wpdb->prefix}icl_strings
397
- SET domain_name_context_md5 = %s
398
- WHERE id = %d",
399
- md5( $endpoint_key,'WooCommerce Endpoints' ), $string_id )
400
- );
401
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
402
 
403
- }
 
404
 
405
- if( !isset($woocommerce_wpml->terms) ){
406
- global $sitepress;
407
- $woocommerce_wpml->terms = new WCML_Terms( $woocommerce_wpml, $sitepress, $wpdb );
408
- }
409
- $woocommerce_wpml->terms->check_if_sync_terms_needed();
410
 
411
- $wcml_settings = get_option('_wcml_settings');
412
 
413
- $wcml_settings['sync_taxonomies_checked'] = 1;
 
414
 
415
- update_option('_wcml_settings', $wcml_settings);
 
 
416
 
 
 
417
 
418
- //update custom fields for bookings
419
- $bookable_resources = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_resource' AND source_language_code IS NOT NULL");
420
 
421
- foreach( $bookable_resources AS $bookable_resource ){
422
- update_post_meta( $bookable_resource->element_id, 'wcml_is_translated', true );
423
- }
424
 
425
- $bookable_persons = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_person' AND source_language_code IS NOT NULL");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
426
 
427
- foreach( $bookable_persons AS $bookable_person ){
428
- update_post_meta( $bookable_person->element_id, 'wcml_is_translated', true );
429
- }
 
 
430
 
431
- }
432
 
433
- function upgrade_3_7_3()
434
- {
435
- global $sitepress;
436
 
437
- $active_languages = $sitepress->get_active_languages();
438
- $current_language = $sitepress->get_current_language();
439
 
440
- foreach( $active_languages as $lang ){
 
441
 
442
- $sitepress->switch_lang( $lang['code'] );
 
 
443
 
444
- $product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
445
 
446
- _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
 
 
 
447
 
448
- $product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
 
449
 
450
- _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
 
451
 
452
- }
 
453
 
454
- $sitepress->switch_lang( $current_language );
 
 
 
 
 
 
455
 
456
- }
457
 
458
- function upgrade_3_7_11(){
 
 
 
 
 
 
459
 
460
- $wcml_settings = get_option('_wcml_settings');
461
- $wcml_settings['dismiss_doc_main'] = 1;
462
- update_option('_wcml_settings', $wcml_settings);
463
- }
464
 
465
- function upgrade_3_8(){
 
466
 
467
- $wcml_settings = get_option('_wcml_settings');
468
- $wcml_settings['set_up_wizard_run'] = 1;
 
 
 
469
 
470
- if( isset($wcml_settings[ 'attributes_settings' ]) ) {
471
- $attributes_settings = $wcml_settings['attributes_settings'];
472
- foreach ( $attributes_settings as $name => $value ) {
473
- if ( substr( $name, 0, 3 ) != 'pa_' ) {
474
- unset( $wcml_settings['attributes_settings'] [$name] );
475
- $wcml_settings['attributes_settings'] ['pa_' . $name] = $value;
476
- }
477
- }
478
- }
479
 
480
- update_option('_wcml_settings', $wcml_settings);
 
 
 
 
 
 
 
 
481
 
482
- }
 
483
 
484
- function upgrade_3_9(){
485
- global $wpdb;
486
 
487
- $meta_keys_to_fix = array(
488
- '_price',
489
- '_regular_price',
490
- '_sale_price',
491
- '_sku'
492
- );
493
 
494
- $sql = "
495
  UPDATE {$wpdb->postmeta}
496
  SET meta_value = ''
497
- WHERE meta_key IN('" . join("','", $meta_keys_to_fix) . "')
498
  AND meta_value IS NULL";
499
 
500
- $wpdb->query( $sql );
501
-
502
- }
503
 
504
- function upgrade_3_9_1(){
505
- global $wpdb, $sitepress;
506
 
507
- $results = $wpdb->get_results("
 
508
  SELECT p.ID, t.trid, t.element_type
509
  FROM {$wpdb->posts} p
510
  JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
511
  WHERE p.post_type in ('product', 'product_variation') AND t.source_language_code IS NULL
512
- ");
513
-
514
- foreach( $results as $product ){
515
-
516
- if( get_post_meta( $product->ID, '_manage_stock', true ) === 'yes' ){
517
-
518
- $translations = $sitepress->get_element_translations( $product->trid, $product->element_type );
519
 
520
- $min_stock = false;
 
 
521
 
522
- //collect min stock
523
- foreach( $translations as $translation ){
524
- $stock = get_post_meta( $translation->element_id, '_stock', true );
525
- if( !$min_stock || $stock < $min_stock ){
526
- $min_stock = $stock;
527
- }
528
- }
529
 
530
- //update stock value
531
- foreach( $translations as $translation ){
532
- update_post_meta( $translation->element_id, '_stock', $min_stock );
533
- }
534
- }
535
- }
536
- }
537
 
538
- function upgrade_4_0(){
539
- $wcml_settings = get_option( '_wcml_settings' );
540
- $wcml_settings[ 'dismiss_tm_warning' ] = 0;
541
- $wcml_settings['cart_sync']['lang_switch'] = WCML_CART_SYNC;
542
- $wcml_settings['cart_sync']['currency_switch'] = WCML_CART_SYNC;
 
 
543
 
544
- update_option('_wcml_settings', $wcml_settings);
 
 
 
 
545
 
546
- }
547
 
548
- function upgrade_4_1_0(){
549
- global $wpdb;
550
 
551
- if( !class_exists( 'WooCommerce' ) ){
552
- update_option( '_wcml_4_1_0_migration_required', true );
553
- }else{
554
 
555
- $results = $wpdb->get_results( "
 
 
 
 
556
  SELECT *
557
  FROM {$wpdb->postmeta}
558
  WHERE meta_key LIKE '\\_price\\_%' OR meta_key LIKE '\\_regular_price\\_%' OR ( meta_key LIKE '\\_sale_price\\_%' AND meta_key NOT LIKE '\\_sale\\_price\\_dates%' )
559
- ");
560
-
561
- foreach( $results as $price ){
562
- $formatted_price = wc_format_decimal( $price->meta_value );
563
- update_post_meta( $price->post_id, $price->meta_key, $formatted_price );
564
-
565
- if( get_post_type( $price->post_id ) == 'product_variation' ){
566
- delete_transient( 'wc_var_prices_'.wp_get_post_parent_id( $price->post_id ) );
567
- }
568
-
569
- }
570
-
571
- $wcml_settings = get_option( '_wcml_settings' );
572
-
573
- if(
574
- isset( $wcml_settings[ 'currency_switcher_style' ] ) &&
575
- $wcml_settings[ 'currency_switcher_style' ] == 'list'
576
- ){
577
- if( $wcml_settings[ 'wcml_curr_sel_orientation' ] == 'horizontal' ){
578
- $switcher_style = 'wcml-horizontal-list';
579
- }else{
580
- $switcher_style = 'wcml-vertical-list';
581
- }
582
- }else{
583
- $switcher_style = 'wcml-dropdown';
584
- }
585
-
586
- $wcml_settings[ 'currency_switchers' ][ 'product' ] = array(
587
- 'switcher_style' => $switcher_style,
588
- 'template' => isset( $wcml_settings[ 'wcml_curr_template' ] ) ? $wcml_settings[ 'wcml_curr_template' ] : '',
589
- 'widget_title' => '',
590
- 'color_scheme' => array(
591
- 'font_current_normal' => '',
592
- 'font_current_hover' => '',
593
- 'background_current_normal' => '',
594
- 'background_current_hover' => '',
595
- 'font_other_normal' => '',
596
- 'font_other_hover' => '',
597
- 'background_other_normal' => '',
598
- 'background_other_hover' => '',
599
- 'border_normal' => ''
600
- )
601
- );
602
-
603
- $wcml_settings[ 'currency_switcher_additional_css' ] = '';
604
- update_option('_wcml_settings', $wcml_settings );
605
- }
606
- }
607
-
608
- function upgrade_4_2_0(){
609
-
610
- $wcml_settings = get_option( '_wcml_settings' );
611
- $wcml_settings[ 'dismiss_cart_warning' ] = 0;
612
-
613
- update_option( '_wcml_settings', $wcml_settings );
614
- }
615
-
616
- private function upgrade_4_2_2(){
617
 
 
618
  // #wcml-2128
619
  $user = new WP_User( 'admin' );
620
- if( $user->exists() && ! is_super_admin( $user->ID ) ) {
621
  $user->remove_cap( 'wpml_manage_woocommerce_multilingual' );
622
- if( ! in_array( 'shop_manager', $user->roles, true ) ){
623
  $user->remove_cap( 'wpml_operate_woocommerce_multilingual' );
624
  }
625
  }
626
-
627
  }
628
 
629
- private function upgrade_4_2_7(){
630
-
631
  // #wcml-2242
632
  $wcml_settings = get_option( '_wcml_settings' );
633
- if( 'yahoo' === $wcml_settings['multi_currency']['exchange_rates']['service'] ){
634
  $wcml_settings['multi_currency']['exchange_rates']['service'] = 'fixerio';
635
  update_option( '_wcml_settings', $wcml_settings );
636
  }
637
-
638
  }
639
 
640
- private function upgrade_4_2_10(){
641
-
642
  // #wcml-2307
643
  global $wpdb;
644
 
645
- if ( defined( 'WC_BOOKINGS_VERSION' ) && version_compare(WC_BOOKINGS_VERSION, '1.10.9', '>=' ) ) {
646
-
647
- $results = $wpdb->get_results( "
648
  SELECT *
649
  FROM {$wpdb->postmeta}
650
  WHERE meta_key LIKE '\\_wc_booking_base_cost\\_%' )
651
- " );
 
652
 
653
  foreach ( $results as $price ) {
654
  $base_cost_price = $price->meta_value;
@@ -656,24 +641,24 @@ class WCML_Upgrade{
656
  update_post_meta( $price->post_id, $block_cost_field_key, $base_cost_price );
657
  }
658
  }
659
-
660
  }
661
 
662
- private function upgrade_4_2_11(){
663
- global $wpdb;
664
 
665
- $wpdb->query( "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta
 
666
  SET meta_key = '_wcml_converted_subtotal'
667
  WHERE meta_key = 'wcml_converted_subtotal'"
668
  );
669
 
670
- $wpdb->query( "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta
 
671
  SET meta_key = '_wcml_converted_total'
672
  WHERE meta_key = 'wcml_converted_total'"
673
  );
674
 
675
  WCML_Install::insert_default_categories();
676
-
677
  }
678
 
679
  private function upgrade_4_3_0() {
@@ -693,60 +678,57 @@ class WCML_Upgrade{
693
  $fixerio_name = '<strong>Fixer.io</strong>';
694
  $mc_settings_link = '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ) . '">' . __( 'multi-currency settings page', 'woocommerce-multilingual' ) . '</a>';
695
 
696
- $message = sprintf( __( 'Your site uses %s to automatically calculate prices in the secondary currency. There is an %s effective June 1st, 2018.', 'woocommerce-multilingual' ), $fixerio_name, $announcement_link );
 
 
697
  $message .= '<br />';
698
- $message .= sprintf( __( 'Please go to the %s and fill in your %s.', 'woocommerce-multilingual' ), $mc_settings_link, $fixer_api_key_link );
 
699
 
700
  $notice = new WPML_Notice( 'wcml-fixerio-api-key-required', $message, 'wcml-save-multi-currency-options' );
701
  $notice->set_css_class_types( 'warning' );
702
  $notice->set_dismissible( true );
703
  $wpml_admin_notices = wpml_get_admin_notices();
704
  $wpml_admin_notices->add_notice( $notice );
705
-
706
  }
707
  }
708
 
709
  private function upgrade_4_3_4() {
710
  global $wpdb;
711
 
712
- //delete wrong duplicated attachments
713
  $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_translations WHERE `element_id` IN ( SELECT ID FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%' ) " );
714
  $wpdb->query( "DELETE FROM {$wpdb->prefix}postmeta WHERE `post_id` IN ( SELECT ID FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%' ) " );
715
  $wpdb->query( "DELETE FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%'" );
716
-
717
  }
718
 
719
  private function upgrade_4_3_5() {
720
-
721
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
722
-
723
  global $wpdb;
724
- //delete wrong bundle items
725
  $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_itemmeta WHERE `meta_key` LIKE 'translation_item_id_of_%' AND `meta_value` IN ( SELECT bundled_item_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE `product_id` = 0 AND `bundle_id` = 0 ) " );
726
  $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_items WHERE `product_id` = 0 AND `bundle_id` = 0 " );
727
  $not_existing_items = $wpdb->get_col( "SELECT m.`meta_id` FROM {$wpdb->prefix}woocommerce_bundled_itemmeta AS m LEFT JOIN {$wpdb->prefix}woocommerce_bundled_items as i ON m.meta_value = i.bundled_item_id WHERE m.`meta_key` LIKE 'translation_item_id_of_%' AND i.`bundled_item_id` IS NULL" );
728
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_itemmeta WHERE `meta_id` IN ( %s )", join( ',', $not_existing_items ) ) );
729
  }
730
-
731
  }
732
 
733
  private function upgrade_4_4_1() {
734
- global $sitepress,$woocommerce_wpml;
735
-
736
- if( !$woocommerce_wpml->is_wpml_prior_4_2() ){
737
 
738
- $wcml_settings = get_option( '_wcml_settings' );
739
- $tm_settings = $sitepress->get_setting( 'translation-management', array() );
 
740
 
741
- if( $wcml_settings['trnsl_interface'] ){
742
- $tm_settings[ WPML_TM_Post_Edit_TM_Editor_Mode::TM_KEY_FOR_POST_TYPE_USE_NATIVE ][ 'product' ] = false;
743
- }else{
744
- $tm_settings[ WPML_TM_Post_Edit_TM_Editor_Mode::TM_KEY_FOR_POST_TYPE_USE_NATIVE ][ 'product' ] = true;
745
- }
746
-
747
- $sitepress->set_setting( 'translation-management', $tm_settings, true );
748
- }
749
 
 
 
750
  }
751
 
752
 
@@ -754,17 +736,18 @@ class WCML_Upgrade{
754
  if ( class_exists( 'WC_SwatchesPlugin' ) ) {
755
  global $wpdb, $sitepress, $wpml_post_translations;
756
 
757
- $variation_sp = new WCML_Variation_Swatches_And_Photos( $sitepress );
758
- $original_products = $wpdb->get_results( "
 
759
  SELECT element_id
760
  FROM {$wpdb->prefix}icl_translations
761
- WHERE element_type = 'post_product' AND source_language_code IS NULL" );
 
762
 
763
  $current_language = $sitepress->get_current_language();
764
 
765
  foreach ( $original_products as $product ) {
766
-
767
- $sitepress->switch_lang( $wpml_post_translations->get_element_lang_code( $product->element_id ) );
768
 
769
  $translations = $wpml_post_translations->get_element_translations( $product->element_id, false, true );
770
  foreach ( $translations as $translation ) {
@@ -779,21 +762,27 @@ class WCML_Upgrade{
779
  private function upgrade_4_6_8() {
780
  global $wpdb;
781
 
782
- $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
 
783
  SET `context` = 'admin_texts_woocommerce_gateways',
784
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
785
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_title'"
786
  );
787
- $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
 
788
  SET `context` = 'admin_texts_woocommerce_gateways',
789
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
790
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_description'"
791
  );
792
- $wpdb->query( "UPDATE {$wpdb->prefix}icl_strings
 
793
  SET `context` = 'admin_texts_woocommerce_gateways',
794
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
795
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_instructions'"
796
  );
797
  }
798
 
799
- }
 
 
 
1
  <?php
2
 
3
+ class WCML_Upgrade {
4
+
5
+ /** @var array */
6
+ private $versions = [
7
+ '2.9.9.1',
8
+ '3.1',
9
+ '3.2',
10
+ '3.3',
11
+ '3.5',
12
+ '3.5.4',
13
+ '3.6',
14
+ '3.7',
15
+ '3.7.3',
16
+ '3.7.11',
17
+ '3.8',
18
+ '3.9',
19
+ '3.9.1',
20
+ '4.0',
21
+ '4.1.0',
22
+ '4.2.0',
23
+ '4.2.2',
24
+ '4.2.7',
25
+ '4.2.10',
26
+ '4.2.11',
27
+ '4.3.0',
28
+ '4.3.4',
29
+ '4.3.5',
30
+ '4.4.1',
31
+ '4.4.3',
32
+ '4.6.8',
33
+ '4.7.3',
34
+ ];
35
+
36
+ public function __construct() {
37
+ add_action( 'init', [ $this, 'run' ] );
38
+ add_action( 'init', [ $this, 'setup_upgrade_notices' ] );
39
+ add_action( 'admin_notices', [ $this, 'show_upgrade_notices' ] );
40
+
41
+ add_action( 'wp_ajax_wcml_hide_notice', [ $this, 'hide_upgrade_notice' ] );
42
+ }
43
+
44
+ public function setup_upgrade_notices() {
45
+ $wcml_settings = get_option( '_wcml_settings' );
46
+ $version_in_db = get_option( '_wcml_version' );
47
+
48
+ if ( ! empty( $version_in_db ) && version_compare( $version_in_db, '2.9.9.1', '<' ) ) {
49
+ $n = 'varimages';
50
+ $wcml_settings['notifications'][ $n ] =
51
+ [
52
+ 'show' => 1,
53
+ 'text' => __( 'Looks like you are upgrading from a previous version of WooCommerce Multilingual. Would you like to automatically create translated variations and images?', 'woocommerce-multilingual' ) .
54
+ '<br /><strong>' .
55
+ ' <a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=troubleshooting' ) . '">' . __( 'Yes, go to the troubleshooting page', 'woocommerce-multilingual' ) . '</a> |' .
56
+ ' <a href="#" onclick="jQuery.ajax({type:\'POST\',url: ajaxurl,data:\'action=wcml_hide_notice&notice=' . $n . '\',success:function(){jQuery(\'#' . $n . '\').fadeOut()}});return false;">' . __( 'No - dismiss', 'woocommerce-multilingual' ) . '</a>' .
57
+ '</strong>',
58
+ ];
59
+ update_option( '_wcml_settings', $wcml_settings );
60
+ }
61
+ }
62
+
63
+ public function show_upgrade_notices() {
64
+ $wcml_settings = get_option( '_wcml_settings' );
65
+ if ( ! empty( $wcml_settings['notifications'] ) ) {
66
+ foreach ( $wcml_settings['notifications'] as $k => $notification ) {
67
+
68
+ // Exceptions.
69
+ if ( isset( $_GET['tab'] ) && 'troubleshooting' === $_GET['tab'] && 'varimages' === $k ) {
70
+ continue;
71
+ }
72
+
73
+ if ( $notification['show'] ) {
74
+ ?>
75
+ <div id="<?php echo $k; ?>" class="updated">
76
+ <p><?php echo $notification['text']; ?></p>
77
+ </div>
78
+ <?php
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ public function hide_upgrade_notice( $k ) {
85
+ if ( empty( $k ) ) {
86
+ $k = $_POST['notice'];
87
+ }
88
+
89
+ $wcml_settings = get_option( '_wcml_settings' );
90
+ if ( isset( $wcml_settings['notifications'][ $k ] ) ) {
91
+ $wcml_settings['notifications'][ $k ]['show'] = 0;
92
+ update_option( '_wcml_settings', $wcml_settings );
93
+ }
94
+ }
95
+
96
+ public function run() {
97
+ $version_in_db = get_option( '_wcml_version' );
98
+
99
+ // Exception - starting in 2.3.2.
100
+ if ( empty( $version_in_db ) && get_option( 'icl_is_wcml_installed' ) ) {
101
+ $version_in_db = '2.3.2';
102
+ }
103
+
104
+ $migration_ran = false;
105
+
106
+ if ( $version_in_db && version_compare( $version_in_db, WCML_VERSION, '<' ) ) {
107
+ foreach ( $this->versions as $version ) {
108
+ if ( version_compare( $version, $version_in_db, '>' ) ) {
109
+ $upgrade_method = 'upgrade_' . str_replace( '.', '_', $version );
110
+
111
+ if ( method_exists( $this, $upgrade_method ) ) {
112
+ $this->$upgrade_method();
113
+ $migration_ran = true;
114
+ }
115
+ }
116
+ }
117
+ }
118
+
119
+ if ( $migration_ran || empty( $version_in_db ) ) {
120
+ update_option( '_wcml_version', WCML_VERSION );
121
+ }
122
+
123
+ if ( get_option( '_wcml_4_1_0_migration_required' ) && class_exists( 'woocommerce' ) ) {
124
+ $this->upgrade_4_1_0();
125
+ delete_option( '_wcml_4_1_0_migration_required' );
126
+ }
127
+ }
128
+
129
+ public function upgrade_2_9_9_1() {
130
+ global $wpdb;
131
+
132
+ // Migrate existing currencies.
133
+ $currencies = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'icl_currencies ORDER BY `id` DESC' );
134
+ foreach ( $currencies as $currency ) {
135
+ if ( isset( $currency->language_code ) ) {
136
+ $wpdb->insert(
137
+ $wpdb->prefix . 'icl_languages_currencies',
138
+ [
139
+ 'language_code' => $currency->language_code,
140
+ 'currency_id' => $currency->id,
141
+ ]
142
+ );
143
+ }
144
+ }
145
+
146
+ $cols = $wpdb->get_col( "SHOW COLUMNS FROM {$wpdb->prefix}icl_currencies" );
147
+ if ( in_array( 'language_code', $cols ) ) {
148
+ $wpdb->query( "ALTER TABLE {$wpdb->prefix}icl_currencies DROP COLUMN language_code" );
149
+ }
150
+
151
+ // Migrate settings.
152
+ $new_settings = [
153
+ 'is_term_order_synced' => get_option( 'icl_is_wcml_term_order_synched' ),
154
+ 'file_path_sync' => get_option( 'wcml_file_path_sync' ),
155
+ 'is_installed' => get_option( 'icl_is_wpcml_installed' ),
156
+ 'dismiss_doc_main' => get_option( 'wpml_dismiss_doc_main' ),
157
+ 'enable_multi_currency' => get_option( 'icl_enable_multi_currency' ),
158
+ 'currency_converting_option' => get_option( 'currency_converting_option' ),
159
+ ];
160
+
161
+ if ( ! get_option( '_wcml_settings' ) ) {
162
+ add_option( '_wcml_settings', $new_settings, '', true );
163
+ }
164
+
165
+ delete_option( 'icl_is_wcml_term_order_synced' );
166
+ delete_option( 'wcml_file_path_sync' );
167
+ delete_option( 'icl_is_wpcml_installed' );
168
+ delete_option( 'wpml_dismiss_doc_main' );
169
+ delete_option( 'icl_enable_multi_currency' );
170
+ delete_option( 'currency_converting_option' );
171
+
172
+ }
173
+
174
+ public function upgrade_3_1() {
175
+ global $wpdb, $sitepress;
176
+ $wcml_settings = get_option( '_wcml_settings' );
177
+
178
+ if ( isset( $wcml_settings['enable_multi_currency'] ) && 'yes' === $wcml_settings['enable_multi_currency'] ) {
179
+ $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_INDEPENDENT;
180
+ } else {
181
+ $wcml_settings['enable_multi_currency'] = WCML_MULTI_CURRENCIES_DISABLED;
182
+ }
183
+
184
+ $wcml_settings['products_sync_date'] = 1;
185
+
186
+ update_option( '_wcml_settings', $wcml_settings );
187
+
188
+ // Multi-currency migration.
189
+ if ( 'yes' === $wcml_settings['enable_multi_currency'] && 2 === (int) $wcml_settings['currency_converting_option'] ) {
190
+
191
+ // Get currencies exchange rates.
192
+ $results = $wpdb->get_results( "SELECT code, value FROM {$wpdb->prefix}icl_currencies" );
193
+ foreach ( $results as $row ) {
194
+ $exchange_rates[ $row->code ] = $row->value;
195
+ }
196
+
197
+ // Get languages currencies map.
198
+ $results = $wpdb->get_results( "SELECT l.language_code, c.code FROM {$wpdb->prefix}icl_languages_currencies l JOIN {$wpdb->prefix}icl_currencies c ON l.currency_id = c.id" );
199
+ foreach ( $results as $row ) {
200
+ $language_currencies[ $row->language_code ] = $row->code;
201
+ }
202
+
203
+ $results = $wpdb->get_results(
204
+ $wpdb->prepare(
205
+ "
 
 
 
 
 
 
 
 
206
  SELECT p.ID, t.trid, t.element_type
207
  FROM {$wpdb->posts} p JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
208
  WHERE
209
  p.post_type in ('product', 'product_variation') AND t.language_code = %s
210
 
211
+ ",
212
+ $sitepress->get_default_language()
213
+ )
214
+ );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
 
216
+ // Set custom conversion rates.
217
+ foreach ( $results as $row ) {
218
+ $translations = $sitepress->get_element_translations( $row->trid, $row->element_type );
219
+ $meta = get_post_meta( $row->ID );
220
+ $original_prices['_price'] = ! empty( $meta['_price'] ) ? $meta['_price'][0] : 0;
221
+ $original_prices['_regular_price'] = ! empty( $meta['_regular_price'] ) ? $meta['_regular_price'][0] : 0;
222
+ $original_prices['_sale_price'] = ! empty( $meta['_sale_price'] ) ? $meta['_sale_price'][0] : 0;
223
 
224
+ $ccr = [];
225
+
226
+ foreach ( $translations as $translation ) {
227
+ if ( $translation->element_id != $row->ID ) {
228
+ $meta = get_post_meta( $translation->element_id );
229
+ $translated_prices['_price'] = $meta['_price'][0];
230
+ $translated_prices['_regular_price'] = $meta['_regular_price'][0];
231
+ $translated_prices['_sale_price'] = $meta['_sale_price'][0];
232
+
233
+ if ( ! empty( $translated_prices['_price'] ) && ! empty( $original_prices['_price'] ) && $translated_prices['_price'] != $original_prices['_price'] ) {
234
+ $ccr['_price'][ $language_currencies[ $translation->language_code ] ] = $translated_prices['_price'] / $original_prices['_price'];
235
+ }
236
+
237
+ if ( ! empty( $translated_prices['_regular_price'] ) && ! empty( $original_prices['_regular_price'] ) && $translated_prices['_regular_price'] != $original_prices['_regular_price'] ) {
238
+ $ccr['_regular_price'][ $language_currencies[ $translation->language_code ] ] = $translated_prices['_regular_price'] / $original_prices['_regular_price'];
239
+ }
240
+
241
+ if ( ! empty( $translated_prices['_sale_price'] ) && ! empty( $original_prices['_sale_price'] ) && $translated_prices['_sale_price'] != $original_prices['_sale_price'] ) {
242
+ $ccr['_sale_price'][ $language_currencies[ $translation->language_code ] ] = $translated_prices['_sale_price'] / $original_prices['_sale_price'];
243
+ }
244
+ }
245
+ }
246
+
247
+ if ( $ccr ) {
248
+ update_post_meta( $row->ID, '_custom_conversion_rate', $ccr );
249
+ }
250
+ }
251
+ }
252
+
253
+ }
254
+
255
+ public function upgrade_3_2() {
256
+ WCML_Capabilities::set_up_capabilities();
257
+
258
+ // Delete not existing currencies in WC.
259
+ global $wpdb;
260
+ $currencies = $wpdb->get_results( 'SELECT id,code FROM ' . $wpdb->prefix . 'icl_currencies ORDER BY `id` DESC' );
261
+ $wc_currencies = get_woocommerce_currencies();
262
+ foreach ( $currencies as $currency ) {
263
+ if ( ! array_key_exists( $currency->code, $wc_currencies ) ) {
264
+ $wpdb->delete( $wpdb->prefix . 'icl_currencies', [ 'ID' => $currency->id ] );
265
+ }
266
+ }
267
+ }
268
+
269
+ public function upgrade_3_3() {
270
+ global $wpdb, $woocommerce_wpml;
271
+
272
+ WCML_Capabilities::set_up_capabilities();
273
+
274
+ $currencies = $wpdb->get_results( 'SELECT * FROM ' . $wpdb->prefix . 'icl_currencies ORDER BY `id` ASC', OBJECT );
275
+ if ( $currencies ) {
276
+ foreach ( $this->currencies as $currency ) {
277
+ $woocommerce_wpml->settings['currency_options'][ $currency->code ]['rate'] = $currency->value;
278
+ $woocommerce_wpml->settings['currency_options'][ $currency->code ]['updated'] = $currency->changed;
279
+ $woocommerce_wpml->settings['currency_options'][ $currency->code ]['position'] = 'left';
280
+ $woocommerce_wpml->settings['currency_options'][ $currency->code ]['languages'] = $woocommerce_wpml->settings['currencies_languages'];
281
+ unset( $woocommerce_wpml->settings['currencies_languages'] );
282
+
283
+ $woocommerce_wpml->update_settings();
284
+ }
285
+ }
286
 
287
+ $wpdb->query( "DROP TABLE `{$wpdb->prefix}icl_currencies`" );
288
+ }
289
 
290
+ public function upgrade_3_5() {
291
+ global $wpdb;
292
+ $wcml_settings = get_option( '_wcml_settings' );
 
 
293
 
294
+ $wcml_settings['products_sync_order'] = 1;
295
 
296
+ update_option( '_wcml_settings', $wcml_settings );
297
+ }
298
 
299
+ public function upgrade_3_5_4() {
300
+ flush_rewrite_rules();
301
+ }
302
 
303
+ public function upgrade_3_6() {
304
+ $wcml_settings = get_option( '_wcml_settings' );
305
 
306
+ $wcml_settings['display_custom_prices'] = 0;
307
+ $wcml_settings['currency_switcher_product_visibility'] = 1;
308
 
309
+ update_option( '_wcml_settings', $wcml_settings );
310
+ }
 
311
 
312
+ public function upgrade_3_7() {
313
+ global $woocommerce_wpml, $wpdb;
314
+
315
+ $woocommerce_permalinks = maybe_unserialize( get_option( 'woocommerce_permalinks' ) );
316
+
317
+ if ( is_array( $woocommerce_permalinks ) ) {
318
+ foreach ( $woocommerce_permalinks as $base_key => $base ) {
319
+
320
+ $base_key = trim( $base_key, '/' );
321
+
322
+ if ( $base ) {
323
+ $taxonomy = false;
324
+
325
+ switch ( $base_key ) {
326
+ case 'category_base':
327
+ $taxonomy = 'product_cat';
328
+ break;
329
+ case 'tag_base':
330
+ $taxonomy = 'product_tag';
331
+ break;
332
+ case 'attribute_base':
333
+ $taxonomy = 'attribute';
334
+ break;
335
+ }
336
+
337
+ if ( $taxonomy ) {
338
+ $wpdb->update(
339
+ $wpdb->prefix . 'icl_strings',
340
+ [
341
+ 'context' => 'WordPress',
342
+ 'name' => sprintf( 'URL %s tax slug', $taxonomy ),
343
+ ],
344
+ [
345
+ 'context' => sprintf( 'URL %s slugs - %s', $taxonomy, $base ),
346
+ 'name' => sprintf( 'Url %s slug: %s', $taxonomy, $base ),
347
+ ]
348
+ );
349
+
350
+ }
351
+ }
352
+ }
353
+ }
354
+
355
+ $endpoint_keys = [
356
+ 'order-pay',
357
+ 'order-received',
358
+ 'view-order',
359
+ 'edit-account',
360
+ 'edit-address',
361
+ 'lost-password',
362
+ 'customer-logout',
363
+ 'add-payment-method',
364
+ ];
365
+
366
+ foreach ( $endpoint_keys as $endpoint_key ) {
367
+ $wpdb->query(
368
+ $wpdb->prepare(
369
+ "UPDATE {$wpdb->prefix}icl_strings
370
+ SET context = 'WooCommerce Endpoints', name = %s
371
+ WHERE context = 'WordPress' AND name = %s",
372
+ $endpoint_key,
373
+ 'Endpoint slug: ' . $endpoint_key
374
+ )
375
+ );
376
+
377
+ // Update domain_name_context_md5 value.
378
+ $string_id = $wpdb->get_var( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}icl_strings WHERE context = 'WooCommerce Endpoints' AND name = %s", $endpoint_key ) );
379
+
380
+ if ( $string_id ) {
381
+ $wpdb->query(
382
+ $wpdb->prepare(
383
+ "UPDATE {$wpdb->prefix}icl_strings
384
+ SET domain_name_context_md5 = %s
385
+ WHERE id = %d",
386
+ md5( $endpoint_key, 'WooCommerce Endpoints' ),
387
+ $string_id
388
+ )
389
+ );
390
+ }
391
+ }
392
 
393
+ if ( ! isset( $woocommerce_wpml->terms ) ) {
394
+ global $sitepress;
395
+ $woocommerce_wpml->terms = new WCML_Terms( $woocommerce_wpml, $sitepress, $wpdb );
396
+ }
397
+ $woocommerce_wpml->terms->check_if_sync_terms_needed();
398
 
399
+ $wcml_settings = get_option( '_wcml_settings' );
400
 
401
+ $wcml_settings['sync_taxonomies_checked'] = 1;
 
 
402
 
403
+ update_option( '_wcml_settings', $wcml_settings );
 
404
 
405
+ // Update custom fields for bookings.
406
+ $bookable_resources = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_resource' AND source_language_code IS NOT NULL" );
407
 
408
+ foreach ( $bookable_resources as $bookable_resource ) {
409
+ update_post_meta( $bookable_resource->element_id, 'wcml_is_translated', true );
410
+ }
411
 
412
+ $bookable_persons = $wpdb->get_results( "SELECT element_id FROM {$wpdb->prefix}icl_translations WHERE element_type = 'post_bookable_person' AND source_language_code IS NOT NULL" );
413
 
414
+ foreach ( $bookable_persons as $bookable_person ) {
415
+ update_post_meta( $bookable_person->element_id, 'wcml_is_translated', true );
416
+ }
417
+ }
418
 
419
+ public function upgrade_3_7_3() {
420
+ global $sitepress;
421
 
422
+ $active_languages = $sitepress->get_active_languages();
423
+ $current_language = $sitepress->get_current_language();
424
 
425
+ foreach ( $active_languages as $lang ) {
426
+ $sitepress->switch_lang( $lang['code'] );
427
 
428
+ $product_cats = get_terms(
429
+ 'product_cat',
430
+ [
431
+ 'hide_empty' => false,
432
+ 'fields' => 'id=>parent',
433
+ ]
434
+ );
435
 
436
+ _wc_term_recount( $product_cats, get_taxonomy( 'product_cat' ), true, false );
437
 
438
+ $product_tags = get_terms(
439
+ 'product_tag',
440
+ [
441
+ 'hide_empty' => false,
442
+ 'fields' => 'id=>parent',
443
+ ]
444
+ );
445
 
446
+ _wc_term_recount( $product_tags, get_taxonomy( 'product_tag' ), true, false );
447
+ }
 
 
448
 
449
+ $sitepress->switch_lang( $current_language );
450
+ }
451
 
452
+ public function upgrade_3_7_11() {
453
+ $wcml_settings = get_option( '_wcml_settings' );
454
+ $wcml_settings['dismiss_doc_main'] = 1;
455
+ update_option( '_wcml_settings', $wcml_settings );
456
+ }
457
 
458
+ public function upgrade_3_8() {
459
+ $wcml_settings = get_option( '_wcml_settings' );
460
+ $wcml_settings['set_up_wizard_run'] = 1;
 
 
 
 
 
 
461
 
462
+ if ( isset( $wcml_settings['attributes_settings'] ) ) {
463
+ $attributes_settings = $wcml_settings['attributes_settings'];
464
+ foreach ( $attributes_settings as $name => $value ) {
465
+ if ( substr( $name, 0, 3 ) != 'pa_' ) {
466
+ unset( $wcml_settings['attributes_settings'] [ $name ] );
467
+ $wcml_settings['attributes_settings'] [ 'pa_' . $name ] = $value;
468
+ }
469
+ }
470
+ }
471
 
472
+ update_option( '_wcml_settings', $wcml_settings );
473
+ }
474
 
475
+ public function upgrade_3_9() {
476
+ global $wpdb;
477
 
478
+ $meta_keys_to_fix = [
479
+ '_price',
480
+ '_regular_price',
481
+ '_sale_price',
482
+ '_sku',
483
+ ];
484
 
485
+ $sql = "
486
  UPDATE {$wpdb->postmeta}
487
  SET meta_value = ''
488
+ WHERE meta_key IN('" . join( "','", $meta_keys_to_fix ) . "')
489
  AND meta_value IS NULL";
490
 
491
+ $wpdb->query( $sql );
492
+ }
 
493
 
494
+ public function upgrade_3_9_1() {
495
+ global $wpdb, $sitepress;
496
 
497
+ $results = $wpdb->get_results(
498
+ "
499
  SELECT p.ID, t.trid, t.element_type
500
  FROM {$wpdb->posts} p
501
  JOIN {$wpdb->prefix}icl_translations t ON t.element_id = p.ID AND t.element_type IN ('post_product', 'post_product_variation')
502
  WHERE p.post_type in ('product', 'product_variation') AND t.source_language_code IS NULL
503
+ "
504
+ );
 
 
 
 
 
505
 
506
+ foreach ( $results as $product ) {
507
+ if ( get_post_meta( $product->ID, '_manage_stock', true ) === 'yes' ) {
508
+ $translations = $sitepress->get_element_translations( $product->trid, $product->element_type );
509
 
510
+ $min_stock = false;
 
 
 
 
 
 
511
 
512
+ // Collect min stock.
513
+ foreach ( $translations as $translation ) {
514
+ $stock = get_post_meta( $translation->element_id, '_stock', true );
515
+ if ( ! $min_stock || $stock < $min_stock ) {
516
+ $min_stock = $stock;
517
+ }
518
+ }
519
 
520
+ // Update stock value.
521
+ foreach ( $translations as $translation ) {
522
+ update_post_meta( $translation->element_id, '_stock', $min_stock );
523
+ }
524
+ }
525
+ }
526
+ }
527
 
528
+ public function upgrade_4_0() {
529
+ $wcml_settings = get_option( '_wcml_settings' );
530
+ $wcml_settings['dismiss_tm_warning'] = 0;
531
+ $wcml_settings['cart_sync']['lang_switch'] = WCML_CART_SYNC;
532
+ $wcml_settings['cart_sync']['currency_switch'] = WCML_CART_SYNC;
533
 
534
+ update_option( '_wcml_settings', $wcml_settings );
535
 
536
+ }
 
537
 
538
+ public function upgrade_4_1_0() {
539
+ global $wpdb;
 
540
 
541
+ if ( ! class_exists( 'WooCommerce' ) ) {
542
+ update_option( '_wcml_4_1_0_migration_required', true );
543
+ } else {
544
+ $results = $wpdb->get_results(
545
+ "
546
  SELECT *
547
  FROM {$wpdb->postmeta}
548
  WHERE meta_key LIKE '\\_price\\_%' OR meta_key LIKE '\\_regular_price\\_%' OR ( meta_key LIKE '\\_sale_price\\_%' AND meta_key NOT LIKE '\\_sale\\_price\\_dates%' )
549
+ "
550
+ );
551
+
552
+ foreach ( $results as $price ) {
553
+ $formatted_price = wc_format_decimal( $price->meta_value );
554
+ update_post_meta( $price->post_id, $price->meta_key, $formatted_price );
555
+
556
+ if ( 'product_variation' === get_post_type( $price->post_id ) ) {
557
+ delete_transient( 'wc_var_prices_' . wp_get_post_parent_id( $price->post_id ) );
558
+ }
559
+ }
560
+
561
+ $wcml_settings = get_option( '_wcml_settings' );
562
+
563
+ if (
564
+ isset( $wcml_settings['currency_switcher_style'] ) &&
565
+ 'list' === $wcml_settings['currency_switcher_style']
566
+ ) {
567
+ if ( 'horizontal' === $wcml_settings['wcml_curr_sel_orientation'] ) {
568
+ $switcher_style = 'wcml-horizontal-list';
569
+ } else {
570
+ $switcher_style = 'wcml-vertical-list';
571
+ }
572
+ } else {
573
+ $switcher_style = 'wcml-dropdown';
574
+ }
575
+
576
+ $wcml_settings['currency_switchers']['product'] = [
577
+ 'switcher_style' => $switcher_style,
578
+ 'template' => isset( $wcml_settings['wcml_curr_template'] ) ? $wcml_settings['wcml_curr_template'] : '',
579
+ 'widget_title' => '',
580
+ 'color_scheme' => [
581
+ 'font_current_normal' => '',
582
+ 'font_current_hover' => '',
583
+ 'background_current_normal' => '',
584
+ 'background_current_hover' => '',
585
+ 'font_other_normal' => '',
586
+ 'font_other_hover' => '',
587
+ 'background_other_normal' => '',
588
+ 'background_other_hover' => '',
589
+ 'border_normal' => '',
590
+ ],
591
+ ];
592
+
593
+ $wcml_settings['currency_switcher_additional_css'] = '';
594
+ update_option( '_wcml_settings', $wcml_settings );
595
+ }
596
+ }
597
+
598
+ public function upgrade_4_2_0() {
599
+ $wcml_settings = get_option( '_wcml_settings' );
600
+ $wcml_settings['dismiss_cart_warning'] = 0;
601
+
602
+ update_option( '_wcml_settings', $wcml_settings );
603
+ }
 
 
 
604
 
605
+ private function upgrade_4_2_2() {
606
  // #wcml-2128
607
  $user = new WP_User( 'admin' );
608
+ if ( $user->exists() && ! is_super_admin( $user->ID ) ) {
609
  $user->remove_cap( 'wpml_manage_woocommerce_multilingual' );
610
+ if ( ! in_array( 'shop_manager', $user->roles, true ) ) {
611
  $user->remove_cap( 'wpml_operate_woocommerce_multilingual' );
612
  }
613
  }
 
614
  }
615
 
616
+ private function upgrade_4_2_7() {
 
617
  // #wcml-2242
618
  $wcml_settings = get_option( '_wcml_settings' );
619
+ if ( 'yahoo' === $wcml_settings['multi_currency']['exchange_rates']['service'] ) {
620
  $wcml_settings['multi_currency']['exchange_rates']['service'] = 'fixerio';
621
  update_option( '_wcml_settings', $wcml_settings );
622
  }
 
623
  }
624
 
625
+ private function upgrade_4_2_10() {
 
626
  // #wcml-2307
627
  global $wpdb;
628
 
629
+ if ( defined( 'WC_BOOKINGS_VERSION' ) && version_compare( WC_BOOKINGS_VERSION, '1.10.9', '>=' ) ) {
630
+ $results = $wpdb->get_results(
631
+ "
632
  SELECT *
633
  FROM {$wpdb->postmeta}
634
  WHERE meta_key LIKE '\\_wc_booking_base_cost\\_%' )
635
+ "
636
+ );
637
 
638
  foreach ( $results as $price ) {
639
  $base_cost_price = $price->meta_value;
641
  update_post_meta( $price->post_id, $block_cost_field_key, $base_cost_price );
642
  }
643
  }
 
644
  }
645
 
646
+ private function upgrade_4_2_11() {
647
+ global $wpdb;
648
 
649
+ $wpdb->query(
650
+ "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta
651
  SET meta_key = '_wcml_converted_subtotal'
652
  WHERE meta_key = 'wcml_converted_subtotal'"
653
  );
654
 
655
+ $wpdb->query(
656
+ "UPDATE {$wpdb->prefix}woocommerce_order_itemmeta
657
  SET meta_key = '_wcml_converted_total'
658
  WHERE meta_key = 'wcml_converted_total'"
659
  );
660
 
661
  WCML_Install::insert_default_categories();
 
662
  }
663
 
664
  private function upgrade_4_3_0() {
678
  $fixerio_name = '<strong>Fixer.io</strong>';
679
  $mc_settings_link = '<a href="' . admin_url( 'admin.php?page=wpml-wcml&tab=multi-currency' ) . '">' . __( 'multi-currency settings page', 'woocommerce-multilingual' ) . '</a>';
680
 
681
+ // translators: 1: Fixer.io, 2: Announcement link.
682
+ $message = sprintf( __( 'Your site uses %1$s to automatically calculate prices in the secondary currency. There is an %2$s effective June 1st, 2018.', 'woocommerce-multilingual' ), $fixerio_name, $announcement_link );
683
+
684
  $message .= '<br />';
685
+ // translators: 1: Mulicurrency tab link, 2: Fixer.io API key.
686
+ $message .= sprintf( __( 'Please go to the %1$s and fill in your %2$s.', 'woocommerce-multilingual' ), $mc_settings_link, $fixer_api_key_link );
687
 
688
  $notice = new WPML_Notice( 'wcml-fixerio-api-key-required', $message, 'wcml-save-multi-currency-options' );
689
  $notice->set_css_class_types( 'warning' );
690
  $notice->set_dismissible( true );
691
  $wpml_admin_notices = wpml_get_admin_notices();
692
  $wpml_admin_notices->add_notice( $notice );
 
693
  }
694
  }
695
 
696
  private function upgrade_4_3_4() {
697
  global $wpdb;
698
 
699
+ // Delete wrongly duplicated attachments.
700
  $wpdb->query( "DELETE FROM {$wpdb->prefix}icl_translations WHERE `element_id` IN ( SELECT ID FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%' ) " );
701
  $wpdb->query( "DELETE FROM {$wpdb->prefix}postmeta WHERE `post_id` IN ( SELECT ID FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%' ) " );
702
  $wpdb->query( "DELETE FROM {$wpdb->prefix}posts WHERE `guid` LIKE '%attachment_id%'" );
 
703
  }
704
 
705
  private function upgrade_4_3_5() {
 
706
  if ( class_exists( 'WC_Product_Bundle' ) && function_exists( 'WC_PB' ) ) {
 
707
  global $wpdb;
708
+ // Delete wrongly bundled items.
709
  $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_itemmeta WHERE `meta_key` LIKE 'translation_item_id_of_%' AND `meta_value` IN ( SELECT bundled_item_id FROM {$wpdb->prefix}woocommerce_bundled_items WHERE `product_id` = 0 AND `bundle_id` = 0 ) " );
710
  $wpdb->query( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_items WHERE `product_id` = 0 AND `bundle_id` = 0 " );
711
  $not_existing_items = $wpdb->get_col( "SELECT m.`meta_id` FROM {$wpdb->prefix}woocommerce_bundled_itemmeta AS m LEFT JOIN {$wpdb->prefix}woocommerce_bundled_items as i ON m.meta_value = i.bundled_item_id WHERE m.`meta_key` LIKE 'translation_item_id_of_%' AND i.`bundled_item_id` IS NULL" );
712
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_bundled_itemmeta WHERE `meta_id` IN ( %s )", join( ',', $not_existing_items ) ) );
713
  }
 
714
  }
715
 
716
  private function upgrade_4_4_1() {
717
+ /** @var woocommerce_wpml $woocommerce_wpml */
718
+ global $sitepress, $woocommerce_wpml;
 
719
 
720
+ if ( ! $woocommerce_wpml->is_wpml_prior_4_2() ) {
721
+ $wcml_settings = get_option( '_wcml_settings' );
722
+ $tm_settings = $sitepress->get_setting( 'translation-management', [] );
723
 
724
+ if ( $wcml_settings['trnsl_interface'] ) {
725
+ $tm_settings[ WPML_TM_Post_Edit_TM_Editor_Mode::TM_KEY_FOR_POST_TYPE_USE_NATIVE ]['product'] = false;
726
+ } else {
727
+ $tm_settings[ WPML_TM_Post_Edit_TM_Editor_Mode::TM_KEY_FOR_POST_TYPE_USE_NATIVE ]['product'] = true;
728
+ }
 
 
 
729
 
730
+ $sitepress->set_setting( 'translation-management', $tm_settings, true );
731
+ }
732
  }
733
 
734
 
736
  if ( class_exists( 'WC_SwatchesPlugin' ) ) {
737
  global $wpdb, $sitepress, $wpml_post_translations;
738
 
739
+ $variation_sp = new WCML_Variation_Swatches_And_Photos( $sitepress );
740
+ $original_products = $wpdb->get_results(
741
+ "
742
  SELECT element_id
743
  FROM {$wpdb->prefix}icl_translations
744
+ WHERE element_type = 'post_product' AND source_language_code IS NULL"
745
+ );
746
 
747
  $current_language = $sitepress->get_current_language();
748
 
749
  foreach ( $original_products as $product ) {
750
+ $sitepress->switch_lang( $wpml_post_translations->get_element_lang_code( $product->element_id ) );
 
751
 
752
  $translations = $wpml_post_translations->get_element_translations( $product->element_id, false, true );
753
  foreach ( $translations as $translation ) {
762
  private function upgrade_4_6_8() {
763
  global $wpdb;
764
 
765
+ $wpdb->query(
766
+ "UPDATE {$wpdb->prefix}icl_strings
767
  SET `context` = 'admin_texts_woocommerce_gateways',
768
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
769
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_title'"
770
  );
771
+ $wpdb->query(
772
+ "UPDATE {$wpdb->prefix}icl_strings
773
  SET `context` = 'admin_texts_woocommerce_gateways',
774
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
775
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_description'"
776
  );
777
+ $wpdb->query(
778
+ "UPDATE {$wpdb->prefix}icl_strings
779
  SET `context` = 'admin_texts_woocommerce_gateways',
780
  `domain_name_context_md5` = MD5( CONCAT( 'admin_texts_woocommerce_gateways', `name`, `gettext_context` ) )
781
  WHERE `context` = 'woocommerce' AND `name` LIKE '%_gateway_instructions'"
782
  );
783
  }
784
 
785
+ private function upgrade_4_7_3() {
786
+ delete_option( 'wcml_currency_switcher_template_objects' );
787
+ }
788
+ }
inc/currencies/currency-switcher/class-wcml-currency-switcher-templates.php CHANGED
@@ -1,179 +1,182 @@
1
  <?php
2
 
3
  class WCML_Currency_Switcher_Templates {
4
-
5
  const CONFIG_FILE = 'config.json';
6
  const OPTION_NAME = 'wcml_currency_switcher_template_objects';
7
 
8
- /**
9
- * @var woocommerce_wpml
10
- */
11
- private $woocommerce_wpml;
12
 
13
- /**
14
- * @var WPML_WP_API $wp_api
15
- */
16
- private $wp_api;
17
 
18
- /**
19
- * @var string $uploads_path
20
- */
21
- private $uploads_path;
22
 
23
- /**
24
- * @var WPML_File
25
- */
26
- private $wpml_file;
27
 
28
- /**
29
- * @var array $templates Collection of WCML_CS_Template
30
- */
31
- private $templates = false;
32
 
33
  /**
34
  * @var array $enqueued_templates
35
  */
36
  private $enqueued_templates = array();
37
 
38
- /**
39
- * @var string $ds
40
- */
41
- private $ds = DIRECTORY_SEPARATOR;
42
-
43
- public function __construct( woocommerce_wpml $woocommerce_wpml, WPML_WP_API $wp_api, WCML_File $wpml_file = null ) {
44
-
45
- $this->woocommerce_wpml = $woocommerce_wpml;
46
- $this->wp_api = $wp_api;
47
-
48
- if ( ! $wpml_file ) {
49
- //TODO: use WPML_FILE class instead after changing requirements for WPML >= 3.6.0
50
- $wpml_file = new WCML_File();
51
- }
52
-
53
- $this->wpml_file = $wpml_file;
54
- }
55
-
56
- public function init_hooks() {
57
-
58
- add_action( 'after_setup_theme', array( $this, 'after_setup_theme_action' ) );
59
- add_action( 'admin_head', array( $this, 'admin_enqueue_template_resources' ) );
60
-
61
- //enqueue front resources only when MC enabled
62
- $wcml_settings = $this->woocommerce_wpml->get_settings();
63
- if( $wcml_settings['enable_multi_currency'] === $this->wp_api->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' ) ){
64
- add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_template_resources' ) );
65
- }
66
- }
67
-
68
- public function after_setup_theme_action() {
69
- $this->init_available_templates();
70
- }
71
-
72
- /**
73
- * @param string $template_slug
74
- *
75
- * @return WCML_CS_Template
76
- */
77
- public function get_template( $template_slug ) {
78
- $ret = false;
79
- if ( array_key_exists( $template_slug, $this->templates ) ) {
80
- $ret = $this->templates[ $template_slug ];
81
- }
82
-
83
- return $ret;
84
- }
85
-
86
- /**
87
- * @return array of active WCML_CS_Templates
88
- */
89
- public function get_active_templates( $load_default = false ) {
90
-
91
- $templates = array();
92
- $wcml_settings = $this->woocommerce_wpml->get_settings();
93
-
94
- if ( isset( $wcml_settings['currency_switchers'] ) ) {
95
- foreach ( $wcml_settings['currency_switchers'] as $switcher_id => $switcher ) {
96
- if ( ! $this->woocommerce_wpml->cs_properties->is_currency_switcher_active( $switcher_id, $wcml_settings ) ) {
97
- continue;
98
- }
99
-
100
- foreach ( $this->templates as $key => $template ) {
101
- if ( $switcher['switcher_style'] === $key && ! isset( $templates[ $key ] ) ) {
102
- $templates[ $key ] = $template;
103
- }
104
- }
105
- }
106
- }
107
-
108
- if( !$templates && $load_default ){
109
- //set default template to active
110
- $templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
111
- }
112
-
113
- return $templates;
114
- }
115
-
116
- /**
117
- * @return array of template data
118
- */
119
- public function get_templates() {
120
-
121
- $templates = array();
122
-
123
- foreach( $this->templates as $key => $template ){
124
-
125
- $template_data = $template->get_template_data();
126
-
127
- if( isset( $template_data['is_core'] ) && $template_data['is_core'] ){
128
- $templates[ 'core' ][ $key ] = $template_data;
129
- }else{
130
- $templates[ 'custom' ][ $key ] = $template_data;
131
- }
132
- }
133
-
134
- return $templates;
135
- }
136
-
137
- /**
138
- * @return null|string
139
- */
140
- private function get_uploads_path() {
141
- if ( ! $this->uploads_path ) {
142
- $uploads = wp_upload_dir( null, false );
143
-
144
- if ( isset( $uploads['basedir'] ) ) {
145
- $this->uploads_path = $uploads['basedir'];
146
- }
147
- }
148
-
149
- return $this->uploads_path;
150
- }
151
-
152
- /**
153
- * @param string $template_path
154
- *
155
- * @return array
156
- */
157
- private function parse_template_config( $template_path ) {
158
- $config = array();
159
- $configuration_file = $template_path . $this->ds . self::CONFIG_FILE;
160
- if ( file_exists( $configuration_file ) ) {
161
- $json_content = file_get_contents( $configuration_file );
162
- $config = json_decode( $json_content, true );
163
- }
164
-
165
- return $config;
166
- }
167
 
168
- private function init_available_templates() {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
170
  $is_admin_ui_page = isset( $_GET['page'] ) && 'wpml-wcml' === $_GET['page'] && isset( $_GET['tab'] ) && 'multi-currency' === $_GET['tab'];
171
 
172
  if ( ! $is_admin_ui_page ) {
173
  $this->templates = $this->get_templates_from_transient();
174
  }
175
 
176
- if ( $this->templates === false ) {
177
  $templates = array();
178
  $dirs_to_scan = array();
179
 
@@ -221,7 +224,6 @@ class WCML_Currency_Switcher_Templates {
221
 
222
  $this->set_templates( $templates );
223
  }
224
-
225
  }
226
 
227
  private function get_templates_from_transient() {
@@ -247,184 +249,180 @@ class WCML_Currency_Switcher_Templates {
247
  return $paths_are_valid;
248
  }
249
 
250
- /**
251
- * @param array $dirs_to_scan
252
- *
253
- * @return array
254
- */
255
- private function scan_template_paths( $dirs_to_scan ) {
256
- $templates_paths = array();
257
-
258
- foreach ( $dirs_to_scan as $dir ) {
259
- if ( !is_dir( $dir ) ) {
260
- continue;
261
- }
262
- $files = scandir( $dir );
263
- $files = array_diff( $files, array( '..', '.' ) );
264
- if ( count( $files ) > 0 ) {
265
- foreach ( $files as $file ) {
266
- $template_path = $dir . '/' . $file;
267
- if ( is_dir( $template_path )
268
- && file_exists( $template_path . $this->ds . WCML_Currency_Switcher_Template::FILENAME )
269
- && file_exists( $template_path . $this->ds . self::CONFIG_FILE )
270
- ) {
271
- $templates_paths[] = $template_path;
272
- }
273
- }
274
- }
275
- }
276
-
277
- return $templates_paths;
278
- }
279
-
280
-
281
- /**
282
- * @param string $ext
283
- * @param string $template_path
284
- * @param array $config
285
- *
286
- * @return array|null
287
- */
288
- private function get_files( $ext, $template_path, $config ) {
289
- $resources = array();
290
-
291
- if( isset( $config[ $ext ] ) ) {
292
- $config[ $ext ] = is_array( $config[ $ext ] ) ? $config[ $ext ] : array( $config[ $ext ] );
293
- foreach ( $config[ $ext ] as $file ) {
294
- $file = untrailingslashit( $template_path ) .$this->ds . $file;
295
- $resources[] = $this->wpml_file->get_uri_from_path( $file );
296
- }
297
- } else {
298
- $search_path = $template_path . $this->ds . '*.' . $ext;
299
- if ( glob( $search_path ) ) {
300
- foreach ( glob( $search_path ) as $file ) {
301
- $resources[] = $this->wpml_file->get_uri_from_path( $file );
302
- }
303
- }
304
- }
305
-
306
- return $resources;
307
- }
308
-
309
- /**
310
- * @param string $path
311
- *
312
- * @return bool
313
- */
314
- private function is_core_template( $path ) {
315
- return strpos( $path, WCML_PLUGIN_PATH ) === 0;
316
- }
317
-
318
- /**
319
- * @param mixed|string|null $name
320
- * @param string $path
321
- *
322
- * @return string
323
- */
324
- private function get_unique_name( $name, $path ) {
325
- if ( is_null( $name ) ) {
326
- $name = basename( $path );
327
- }
328
-
329
- if ( strpos( $path, $this->wpml_file->fix_dir_separator( get_template_directory() ) ) === 0 ) {
330
- $theme = wp_get_theme();
331
- $name = $theme . ' - ' . $name;
332
- } elseif ( strpos( $path, $this->wpml_file->fix_dir_separator( $this->get_uploads_path() ) ) === 0 ) {
333
- $name = __( 'Uploads', 'woocommerce-multilingual' ) . ' - ' . $name;
334
- } elseif (
335
- strpos( $path, $this->wpml_file->fix_dir_separator( WP_PLUGIN_DIR ) ) === 0
336
- && ! $this->is_core_template( $path )
337
- ) {
338
- $plugin_dir = $this->wpml_file->fix_dir_separator( WP_PLUGIN_DIR );
339
- $plugin_dir = preg_replace( '#' . preg_quote( $plugin_dir ) . '#' , '', $path, 1 );
340
- $plugin_dir = ltrim( $plugin_dir, $this->ds );
341
- $plugin_dir = explode( $this->ds, $plugin_dir );
342
-
343
- if ( isset( $plugin_dir[0] ) ) {
344
- $require = ABSPATH . 'wp-admin' . $this->ds . 'includes' . $this->ds . 'plugin.php';
345
- require_once( $require );
346
- foreach ( get_plugins() as $slug => $plugin ) {
347
- if ( strpos( $slug, $plugin_dir[0] ) === 0 ) {
348
- $name = $plugin['Name'] . ' - ' . $name;
349
- break;
350
- }
351
- }
352
- } else {
353
- $name = substr( md5( $path ), 0, 8 ) . ' - ' . $name;
354
- }
355
- }
356
-
357
- return $name;
358
- }
359
-
360
- public function enqueue_template_resources( $templates = false ) {
361
-
362
- if( !$templates ){
363
- $templates = $this->get_active_templates( true );
364
- }
365
-
366
- $wcml_settings = $this->woocommerce_wpml->get_settings();
367
-
368
- foreach ( $templates as $slug => $template ) {
369
-
370
- $this->enqueue_template_assets( $slug, $template );
371
-
372
- if ( $template->has_styles() ) {
373
- $style_handler = $template->get_inline_style_handler();
374
- }
375
- }
376
-
377
- if( $templates ){
378
- if( isset( $wcml_settings[ 'currency_switchers' ] ) ){
379
- foreach( $wcml_settings[ 'currency_switchers' ] as $key => $switcher_data ){
380
-
381
- $switcher_template = $switcher_data['switcher_style'];
382
-
383
- if ( ! isset( $templates[ $switcher_template ] ) ) {
384
- continue;
385
- }
386
-
387
- $css = $this->get_color_picket_css( $key, $switcher_data );
388
- $template = $templates[ $switcher_template ];
389
-
390
- if ( $template->has_styles() ) {
391
- wp_add_inline_style( $template->get_inline_style_handler(), $css );
392
- }else{
393
- echo $this->get_inline_style( $key, $switcher_template, $css );
394
- }
395
- }
396
- }
397
-
398
- if ( ! empty( $wcml_settings['currency_switcher_additional_css'] ) ) {
399
- $additional_css = $this->sanitize_css( $wcml_settings['currency_switcher_additional_css'] );
400
-
401
- if( !empty( $style_handler ) ){
402
- wp_add_inline_style( $style_handler, $additional_css );
403
- }else{
404
- echo $this->get_inline_style( 'currency_switcher', 'additional_css', $additional_css );
405
- }
406
- }
407
- }
408
- }
409
 
410
  /**
411
- * @param string $slug
412
- * @param WCML_Currency_Switcher_Template $template
 
413
  *
 
414
  */
415
- public function enqueue_template_assets( $slug, $template ){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
416
 
417
- $this->enqueued_templates[] = $slug;
 
418
 
419
- foreach ( $template->get_scripts() as $k => $url ) {
420
- wp_enqueue_script( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION, true );
421
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
422
 
423
- foreach ( $template->get_styles() as $k => $url ) {
424
- wp_enqueue_style( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION );
425
- }
426
 
427
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
 
429
 
430
  /**
@@ -438,93 +436,90 @@ class WCML_Currency_Switcher_Templates {
438
  }
439
 
440
 
441
- /**
442
- * @param string $css
443
- *
444
- * @return string
445
- */
446
- private function sanitize_css( $css ) {
447
- $css = wp_strip_all_tags( $css );
448
- $css = preg_replace('/\s+/S', " ", trim( $css ) );
449
- return $css;
450
- }
451
-
452
- public function admin_enqueue_template_resources(){
453
- if( isset( $_GET['page'] ) && $_GET['page'] == 'wpml-wcml' && isset( $_GET['tab'] ) && $_GET['tab'] == 'multi-currency' ){
454
- $this->enqueue_template_resources( $this->templates );
455
- }
456
- }
457
-
458
- public function get_color_picket_css( $switcher_id, $switcher_data ){
459
-
460
- $css = '';
461
- $wrapper_class = '.'.$switcher_id.'.'.$switcher_data[ 'switcher_style' ];
462
-
463
- if ( $switcher_data[ 'color_scheme' ][ 'border_normal' ] ) {
464
- $css .= "$wrapper_class, $wrapper_class li, $wrapper_class li li{";
465
- $css .= "border-color:". $switcher_data[ 'color_scheme' ][ 'border_normal' ] ." ;";
466
- $css .= "}";
467
- }
468
-
469
- if ( $switcher_data[ 'color_scheme' ][ 'font_other_normal' ] || $switcher_data[ 'color_scheme' ][ 'background_other_normal' ] ) {
470
- $css .= "$wrapper_class li>a {";
471
- $css .= $switcher_data[ 'color_scheme' ][ 'font_other_normal' ] ? "color:". $switcher_data[ 'color_scheme' ][ 'font_other_normal' ] .";" : '';
472
- $css .= $switcher_data[ 'color_scheme' ][ 'background_other_normal' ] ? "background-color:". $switcher_data[ 'color_scheme' ][ 'background_other_normal' ] .";" : '';
473
- $css .= "}";
474
- }
475
-
476
- if ( $switcher_data[ 'color_scheme' ][ 'font_other_hover' ] || $switcher_data[ 'color_scheme' ][ 'background_other_hover' ] ) {
477
- $css .= "$wrapper_class li:hover>a, $wrapper_class li:focus>a {";
478
- $css .= $switcher_data[ 'color_scheme' ][ 'font_other_hover' ] ? "color:". $switcher_data[ 'color_scheme' ][ 'font_other_hover' ] .";" : '';
479
- $css .= $switcher_data[ 'color_scheme' ][ 'background_other_hover' ] ? "background-color:". $switcher_data[ 'color_scheme' ][ 'background_other_hover' ] .";" : '';
480
- $css .= "}";
481
- }
482
-
483
- if ( $switcher_data[ 'color_scheme' ][ 'font_current_normal' ] || $switcher_data[ 'color_scheme' ][ 'background_current_normal' ] ) {
484
- $css .= "$wrapper_class .wcml-cs-active-currency>a {";
485
- $css .= $switcher_data[ 'color_scheme' ][ 'font_current_normal' ] ? "color:". $switcher_data[ 'color_scheme' ][ 'font_current_normal' ] .";" : '';
486
- $css .= $switcher_data[ 'color_scheme' ][ 'background_current_normal' ] ? "background-color:". $switcher_data[ 'color_scheme' ][ 'background_current_normal' ] .";" : '';
487
- $css .= "}";
488
- }
489
-
490
- if ( $switcher_data[ 'color_scheme' ][ 'font_current_hover' ]|| $switcher_data[ 'color_scheme' ][ 'background_current_hover' ] ) {
491
- $css .= "$wrapper_class .wcml-cs-active-currency:hover>a, $wrapper_class .wcml-cs-active-currency:focus>a {";
492
- $css .= $switcher_data[ 'color_scheme' ][ 'font_current_hover' ] ? "color:". $switcher_data[ 'color_scheme' ][ 'font_current_hover' ] .";" : '';
493
- $css .= $switcher_data[ 'color_scheme' ][ 'background_current_hover' ] ? "background-color:". $switcher_data[ 'color_scheme' ][ 'background_current_hover' ] .";" : '';
494
- $css .= "}";
495
- }
496
-
497
- return $css;
498
- }
499
-
500
-
501
- public function get_inline_style( $switcher_id, $switcher_template, $css ) {
502
- $style_id = 'wcml-cs-inline-styles-' . $switcher_id.'-'.$switcher_template;
503
- return '<style type="text/css" id="' . $style_id . '">' . $css . '</style>' . PHP_EOL;
504
- }
505
 
506
- public function set_templates( $templates ) {
507
- $this->templates = $templates;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
508
  }
509
 
510
- public function check_is_active( $template ){
511
- $is_active = false;
512
 
513
- $active_templates = $this->get_active_templates( true );
 
 
 
 
 
 
 
514
 
515
- foreach( $active_templates as $template_key => $active_template ){
516
- if ( $template === $template_key ){
517
- $is_active = true;
518
- break;
519
- }
520
- }
521
 
522
- return $is_active;
523
 
524
- }
 
 
 
 
 
525
 
526
- public function get_first_active( ){
527
- return current( array_keys( $this->get_active_templates( true ) ) );
528
 
529
- }
 
 
530
  }
1
  <?php
2
 
3
  class WCML_Currency_Switcher_Templates {
 
4
  const CONFIG_FILE = 'config.json';
5
  const OPTION_NAME = 'wcml_currency_switcher_template_objects';
6
 
7
+ /**
8
+ * @var woocommerce_wpml
9
+ */
10
+ private $woocommerce_wpml;
11
 
12
+ /**
13
+ * @var WPML_WP_API $wp_api
14
+ */
15
+ private $wp_api;
16
 
17
+ /**
18
+ * @var string $uploads_path
19
+ */
20
+ private $uploads_path;
21
 
22
+ /**
23
+ * @var WPML_File
24
+ */
25
+ private $wpml_file;
26
 
27
+ /**
28
+ * @var array $templates Collection of WCML_CS_Template
29
+ */
30
+ private $templates = false;
31
 
32
  /**
33
  * @var array $enqueued_templates
34
  */
35
  private $enqueued_templates = array();
36
 
37
+ /**
38
+ * @var string $ds
39
+ */
40
+ private $ds = DIRECTORY_SEPARATOR;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
+ public function __construct( woocommerce_wpml $woocommerce_wpml, WPML_WP_API $wp_api, WCML_File $wpml_file = null ) {
43
+ $this->woocommerce_wpml = $woocommerce_wpml;
44
+ $this->wp_api = $wp_api;
45
+
46
+ if ( ! $wpml_file ) {
47
+ // @todo: use WPML_FILE class instead after changing requirements for WPML >= 3.6.0.
48
+ $wpml_file = new WCML_File();
49
+ }
50
+
51
+ $this->wpml_file = $wpml_file;
52
+ }
53
+
54
+ public function init_hooks() {
55
+ add_action( 'after_setup_theme', [ $this, 'after_setup_theme_action' ] );
56
+ add_action( 'activated_plugin', [ $this, 'activated_plugin_action' ] );
57
+ add_action( 'deactivated_plugin', [ $this, 'activated_plugin_action' ] );
58
+ add_action( 'switch_theme', [ $this, 'activated_plugin_action' ] );
59
+ add_action( 'admin_head', [ $this, 'admin_enqueue_template_resources' ] );
60
+
61
+ // Enqueue front resources only when MC enabled.
62
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
63
+ if ( $wcml_settings['enable_multi_currency'] === $this->wp_api->constant( 'WCML_MULTI_CURRENCIES_INDEPENDENT' ) ) {
64
+ add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_template_resources' ] );
65
+ }
66
+ }
67
+
68
+ public function after_setup_theme_action() {
69
+ $this->init_available_templates();
70
+ }
71
+
72
+ public function activated_plugin_action() {
73
+ delete_option( self::OPTION_NAME );
74
+ }
75
+
76
+ /**
77
+ * @param string $template_slug
78
+ *
79
+ * @return WCML_Currency_Switcher_Template
80
+ */
81
+ public function get_template( $template_slug ) {
82
+ $ret = false;
83
+ if ( array_key_exists( $template_slug, $this->templates ) ) {
84
+ $ret = $this->templates[ $template_slug ];
85
+ }
86
+
87
+ return $ret;
88
+ }
89
+
90
+ /**
91
+ * @param bool $load_default
92
+ *
93
+ * @return array of active WCML_Currency_Switcher_Template
94
+ */
95
+ public function get_active_templates( $load_default = false ) {
96
+ $templates = array();
97
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
98
+
99
+ if ( isset( $wcml_settings['currency_switchers'] ) ) {
100
+ foreach ( $wcml_settings['currency_switchers'] as $switcher_id => $switcher ) {
101
+ if ( ! $this->woocommerce_wpml->cs_properties->is_currency_switcher_active( $switcher_id, $wcml_settings ) ) {
102
+ continue;
103
+ }
104
+
105
+ foreach ( $this->templates as $key => $template ) {
106
+ if ( $switcher['switcher_style'] === $key && ! isset( $templates[ $key ] ) ) {
107
+ $templates[ $key ] = $template;
108
+ }
109
+ }
110
+ }
111
+ }
112
 
113
+ if ( ! $templates && $load_default ) {
114
+ // Set default template to active.
115
+ $templates['wcml-dropdown'] = $this->templates['wcml-dropdown'];
116
+ }
117
+
118
+ return $templates;
119
+ }
120
+
121
+ /**
122
+ * @return array of template data
123
+ */
124
+ public function get_templates() {
125
+ $templates = array();
126
+
127
+ foreach ( $this->templates as $key => $template ) {
128
+
129
+ $template_data = $template->get_template_data();
130
+
131
+ if ( isset( $template_data['is_core'] ) && $template_data['is_core'] ) {
132
+ $templates['core'][ $key ] = $template_data;
133
+ } else {
134
+ $templates['custom'][ $key ] = $template_data;
135
+ }
136
+ }
137
+
138
+ return $templates;
139
+ }
140
+
141
+ /**
142
+ * @return null|string
143
+ */
144
+ private function get_uploads_path() {
145
+ if ( ! $this->uploads_path ) {
146
+ $uploads = wp_upload_dir( null, false );
147
+
148
+ if ( isset( $uploads['basedir'] ) ) {
149
+ $this->uploads_path = $uploads['basedir'];
150
+ }
151
+ }
152
+
153
+ return $this->uploads_path;
154
+ }
155
+
156
+ /**
157
+ * @param string $template_path
158
+ *
159
+ * @return array
160
+ */
161
+ private function parse_template_config( $template_path ) {
162
+ $config = array();
163
+ $configuration_file = $template_path . $this->ds . self::CONFIG_FILE;
164
+ if ( file_exists( $configuration_file ) ) {
165
+ $json_content = file_get_contents( $configuration_file );
166
+ $config = json_decode( $json_content, true );
167
+ }
168
+
169
+ return $config;
170
+ }
171
+
172
+ private function init_available_templates() {
173
  $is_admin_ui_page = isset( $_GET['page'] ) && 'wpml-wcml' === $_GET['page'] && isset( $_GET['tab'] ) && 'multi-currency' === $_GET['tab'];
174
 
175
  if ( ! $is_admin_ui_page ) {
176
  $this->templates = $this->get_templates_from_transient();
177
  }
178
 
179
+ if ( false === $this->templates ) {
180
  $templates = array();
181
  $dirs_to_scan = array();
182
 
224
 
225
  $this->set_templates( $templates );
226
  }
 
227
  }
228
 
229
  private function get_templates_from_transient() {
249
  return $paths_are_valid;
250
  }
251
 
252
+ /**
253
+ * @param array $dirs_to_scan
254
+ *
255
+ * @return array
256
+ */
257
+ private function scan_template_paths( $dirs_to_scan ) {
258
+ $templates_paths = array();
259
+
260
+ foreach ( $dirs_to_scan as $dir ) {
261
+ if ( ! is_dir( $dir ) ) {
262
+ continue;
263
+ }
264
+ $files = scandir( $dir );
265
+ $files = array_diff( $files, array( '..', '.' ) );
266
+ if ( count( $files ) > 0 ) {
267
+ foreach ( $files as $file ) {
268
+ $template_path = $dir . '/' . $file;
269
+ if ( is_dir( $template_path )
270
+ && file_exists( $template_path . $this->ds . WCML_Currency_Switcher_Template::FILENAME )
271
+ && file_exists( $template_path . $this->ds . self::CONFIG_FILE )
272
+ ) {
273
+ $templates_paths[] = $template_path;
274
+ }
275
+ }
276
+ }
277
+ }
278
+
279
+ return $templates_paths;
280
+ }
281
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
282
 
283
  /**
284
+ * @param string $ext
285
+ * @param string $template_path
286
+ * @param array $config
287
  *
288
+ * @return array|null
289
  */
290
+ private function get_files( $ext, $template_path, $config ) {
291
+ $resources = array();
292
+
293
+ if ( isset( $config[ $ext ] ) ) {
294
+ $config[ $ext ] = is_array( $config[ $ext ] ) ? $config[ $ext ] : array( $config[ $ext ] );
295
+ foreach ( $config[ $ext ] as $file ) {
296
+ $file = untrailingslashit( $template_path ) . $this->ds . $file;
297
+ $resources[] = $this->wpml_file->get_uri_from_path( $file );
298
+ }
299
+ } else {
300
+ $search_path = $template_path . $this->ds . '*.' . $ext;
301
+ if ( glob( $search_path ) ) {
302
+ foreach ( glob( $search_path ) as $file ) {
303
+ $resources[] = $this->wpml_file->get_uri_from_path( $file );
304
+ }
305
+ }
306
+ }
307
 
308
+ return $resources;
309
+ }
310
 
311
+ /**
312
+ * @param string $path
313
+ *
314
+ * @return bool
315
+ */
316
+ private function is_core_template( $path ) {
317
+ return strpos( $path, WCML_PLUGIN_PATH ) === 0;
318
+ }
319
+
320
+ /**
321
+ * @param mixed|string|null $name
322
+ * @param string $path
323
+ *
324
+ * @return string
325
+ */
326
+ private function get_unique_name( $name, $path ) {
327
+ if ( is_null( $name ) ) {
328
+ $name = basename( $path );
329
+ }
330
+
331
+ if ( strpos( $path, $this->wpml_file->fix_dir_separator( get_template_directory() ) ) === 0 ) {
332
+ $theme = wp_get_theme();
333
+ $name = $theme . ' - ' . $name;
334
+ } elseif ( strpos( $path, $this->wpml_file->fix_dir_separator( $this->get_uploads_path() ) ) === 0 ) {
335
+ $name = __( 'Uploads', 'woocommerce-multilingual' ) . ' - ' . $name;
336
+ } elseif (
337
+ strpos( $path, $this->wpml_file->fix_dir_separator( WP_PLUGIN_DIR ) ) === 0
338
+ && ! $this->is_core_template( $path )
339
+ ) {
340
+ $plugin_dir = $this->wpml_file->fix_dir_separator( WP_PLUGIN_DIR );
341
+ $plugin_dir = preg_replace( '#' . preg_quote( $plugin_dir ) . '#', '', $path, 1 );
342
+ $plugin_dir = ltrim( $plugin_dir, $this->ds );
343
+ $plugin_dir = explode( $this->ds, $plugin_dir );
344
+
345
+ if ( isset( $plugin_dir[0] ) ) {
346
+ $require = ABSPATH . 'wp-admin' . $this->ds . 'includes' . $this->ds . 'plugin.php';
347
+ require_once $require;
348
+ foreach ( get_plugins() as $slug => $plugin ) {
349
+ if ( strpos( $slug, $plugin_dir[0] ) === 0 ) {
350
+ $name = $plugin['Name'] . ' - ' . $name;
351
+ break;
352
+ }
353
+ }
354
+ } else {
355
+ $name = substr( md5( $path ), 0, 8 ) . ' - ' . $name;
356
+ }
357
+ }
358
+
359
+ return $name;
360
+ }
361
+
362
+ public function enqueue_template_resources( $templates = false ) {
363
+ if ( ! $templates ) {
364
+ $templates = $this->get_active_templates( true );
365
+ }
366
+
367
+ $wcml_settings = $this->woocommerce_wpml->get_settings();
368
+
369
+ foreach ( $templates as $slug => $template ) {
370
+
371
+ $this->enqueue_template_assets( $slug, $template );
372
+
373
+ if ( $template->has_styles() ) {
374
+ $style_handler = $template->get_inline_style_handler();
375
+ }
376
+ }
377
+
378
+ if ( $templates ) {
379
+ if ( isset( $wcml_settings['currency_switchers'] ) ) {
380
+ foreach ( $wcml_settings['currency_switchers'] as $key => $switcher_data ) {
381
+
382
+ $switcher_template = $switcher_data['switcher_style'];
383
+
384
+ if ( ! isset( $templates[ $switcher_template ] ) ) {
385
+ continue;
386
+ }
387
+
388
+ $css = $this->get_color_picket_css( $key, $switcher_data );
389
+ $template = $templates[ $switcher_template ];
390
+
391
+ if ( $template->has_styles() ) {
392
+ wp_add_inline_style( $template->get_inline_style_handler(), $css );
393
+ } else {
394
+ echo $this->get_inline_style( $key, $switcher_template, $css );
395
+ }
396
+ }
397
+ }
398
 
399
+ if ( ! empty( $wcml_settings['currency_switcher_additional_css'] ) ) {
400
+ $additional_css = $this->sanitize_css( $wcml_settings['currency_switcher_additional_css'] );
 
401
 
402
+ if ( ! empty( $style_handler ) ) {
403
+ wp_add_inline_style( $style_handler, $additional_css );
404
+ } else {
405
+ echo $this->get_inline_style( 'currency_switcher', 'additional_css', $additional_css );
406
+ }
407
+ }
408
+ }
409
+ }
410
+
411
+ /**
412
+ * @param string $slug
413
+ * @param WCML_Currency_Switcher_Template $template
414
+ */
415
+ public function enqueue_template_assets( $slug, $template ) {
416
+ $this->enqueued_templates[] = $slug;
417
+
418
+ foreach ( $template->get_scripts() as $k => $url ) {
419
+ wp_enqueue_script( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION, true );
420
+ }
421
+
422
+ foreach ( $template->get_styles() as $k => $url ) {
423
+ wp_enqueue_style( $template->get_resource_handler( $k ), $url, array(), WCML_VERSION );
424
+ }
425
+ }
426
 
427
 
428
  /**
436
  }
437
 
438
 
439
+ /**
440
+ * @param string $css
441
+ *
442
+ * @return string
443
+ */
444
+ private function sanitize_css( $css ) {
445
+ $css = wp_strip_all_tags( $css );
446
+ $css = preg_replace( '/\s+/S', ' ', trim( $css ) );
447
+ return $css;
448
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
449
 
450
+ public function admin_enqueue_template_resources() {
451
+ if ( isset( $_GET['page'] ) && 'wpml-wcml' === $_GET['page'] && isset( $_GET['tab'] ) && 'multi-currency' === $_GET['tab'] ) {
452
+ $this->enqueue_template_resources( $this->templates );
453
+ }
454
+ }
455
+
456
+ public function get_color_picket_css( $switcher_id, $switcher_data ) {
457
+ $css = '';
458
+ $wrapper_class = '.' . $switcher_id . '.' . $switcher_data['switcher_style'];
459
+
460
+ if ( $switcher_data['color_scheme']['border_normal'] ) {
461
+ $css .= "$wrapper_class, $wrapper_class li, $wrapper_class li li{";
462
+ $css .= 'border-color:' . $switcher_data['color_scheme']['border_normal'] . ' ;';
463
+ $css .= '}';
464
+ }
465
+
466
+ if ( $switcher_data['color_scheme']['font_other_normal'] || $switcher_data['color_scheme']['background_other_normal'] ) {
467
+ $css .= "$wrapper_class li>a {";
468
+ $css .= $switcher_data['color_scheme']['font_other_normal'] ? 'color:' . $switcher_data['color_scheme']['font_other_normal'] . ';' : '';
469
+ $css .= $switcher_data['color_scheme']['background_other_normal'] ? 'background-color:' . $switcher_data['color_scheme']['background_other_normal'] . ';' : '';
470
+ $css .= '}';
471
+ }
472
+
473
+ if ( $switcher_data['color_scheme']['font_other_hover'] || $switcher_data['color_scheme']['background_other_hover'] ) {
474
+ $css .= "$wrapper_class li:hover>a, $wrapper_class li:focus>a {";
475
+ $css .= $switcher_data['color_scheme']['font_other_hover'] ? 'color:' . $switcher_data['color_scheme']['font_other_hover'] . ';' : '';
476
+ $css .= $switcher_data['color_scheme']['background_other_hover'] ? 'background-color:' . $switcher_data['color_scheme']['background_other_hover'] . ';' : '';
477
+ $css .= '}';
478
+ }
479
+
480
+ if ( $switcher_data['color_scheme']['font_current_normal'] || $switcher_data['color_scheme']['background_current_normal'] ) {
481
+ $css .= "$wrapper_class .wcml-cs-active-currency>a {";
482
+ $css .= $switcher_data['color_scheme']['font_current_normal'] ? 'color:' . $switcher_data['color_scheme']['font_current_normal'] . ';' : '';
483
+ $css .= $switcher_data['color_scheme']['background_current_normal'] ? 'background-color:' . $switcher_data['color_scheme']['background_current_normal'] . ';' : '';
484
+ $css .= '}';
485
+ }
486
+
487
+ if ( $switcher_data['color_scheme']['font_current_hover'] || $switcher_data['color_scheme']['background_current_hover'] ) {
488
+ $css .= "$wrapper_class .wcml-cs-active-currency:hover>a, $wrapper_class .wcml-cs-active-currency:focus>a {";
489
+ $css .= $switcher_data['color_scheme']['font_current_hover'] ? 'color:' . $switcher_data['color_scheme']['font_current_hover'] . ';' : '';
490
+ $css .= $switcher_data['color_scheme']['background_current_hover'] ? 'background-color:' . $switcher_data['color_scheme']['background_current_hover'] . ';' : '';
491
+ $css .= '}';
492
+ }
493
+
494
+ return $css;
495
  }
496
 
 
 
497
 
498
+ public function get_inline_style( $switcher_id, $switcher_template, $css ) {
499
+ $style_id = 'wcml-cs-inline-styles-' . $switcher_id . '-' . $switcher_template;
500
+ return '<style type="text/css" id="' . $style_id . '">' . $css . '</style>' . PHP_EOL;
501
+ }
502
+
503
+ public function set_templates( $templates ) {
504
+ $this->templates = $templates;
505
+ }
506
 
507
+ public function check_is_active( $template ) {
508
+ $is_active = false;
 
 
 
 
509
 
510
+ $active_templates = $this->get_active_templates( true );
511
 
512
+ foreach ( $active_templates as $template_key => $active_template ) {
513
+ if ( $template === $template_key ) {
514
+ $is_active = true;
515
+ break;
516
+ }
517
+ }
518
 
519
+ return $is_active;
520
+ }
521
 
522
+ public function get_first_active() {
523
+ return current( array_keys( $this->get_active_templates( true ) ) );
524
+ }
525
  }
readme.txt CHANGED
@@ -1,11 +1,12 @@
1
  === WooCommerce Multilingual - run WooCommerce with WPML ===
2
- Contributors: AmirHelzer, sergey.r, mihaimihai, EduardMaghakyan, andrewp-2
3
  Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 4.7
7
- Tested up to: 5.2.4
8
- Stable tag: 4.7.2
 
9
 
10
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
11
 
@@ -136,7 +137,139 @@ WooCommerce Multilingual is compatible with all major WooCommerce extensions. We
136
 
137
  == Changelog ==
138
 
139
- For post 4.1.0 changelogs, see the `changelog` folder.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
  = 4.1.0 =
142
  * Enhanced language switchers
1
  === WooCommerce Multilingual - run WooCommerce with WPML ===
2
+ Contributors: AmirHelzer, sergey.r, mihaimihai, EduardMaghakyan, andrewp-2, kaggdesign
3
  Donate link: http://wpml.org/documentation/related-projects/woocommerce-multilingual/
4
  Tags: CMS, woocommerce, commerce, ecommerce, e-commerce, products, WPML, multilingual, e-shop, shop
5
  License: GPLv2
6
  Requires at least: 4.7
7
+ Tested up to: 5.3
8
+ Stable tag: 4.7.3
9
+ Requires PHP: 5.6
10
 
11
  Allows running fully multilingual e-commerce sites using WooCommerce and WPML.
12
 
137
 
138
  == Changelog ==
139
 
140
+ = 4.7.3 =
141
+ * Fixed PHP Fatal error: Uncaught LogicException: A function must be an instance of \Twig_FunctionInterface or \Twig_SimpleFunction.
142
+ * Fixed wrong language for some string on WooCommerce shipping settings page when switching admin language using language switcher.
143
+
144
+ = 4.7.0 =
145
+ * Replaced some Twig templates with pure PHP templates as the first step towards the removal of Twig dependencies.
146
+ * Added compatibility class for WooCommerce order status Manager plugin
147
+ * Fixed PHP Notice for WC Variations Swatches And Photos compatibility.
148
+ * WooCommerce Bookings compatibility : Fixed notice when trying to cancel booking.
149
+ * Fixed a JavaScript error on the Store URLs tab.
150
+ * Fixed an issue where the "Fix translated variations relationships" troubleshooting option was removing translated variations.
151
+ * Fixed an issue where the strings for the default payment methods were not properly translated on the Checkout page.
152
+ * Fixed an issue where product names were not translated in the admin emails.
153
+ * Fixed an issue with the WooCommerce Subscriptions availability in the secondary language after purchasing the subscription in the original language.
154
+ * Fixed an issue with the cache flush during language switching.
155
+ * Fixed in the original ticket.
156
+ * Fixed an issue where the gateway strings would always register in English instead of the site's default language.
157
+ * Fixed an issue with the price filter widget not showing results in a secondary language.
158
+ * Fixed an issue where customers would not receive notifications in the correct language.
159
+ * Fixed an issue where the shipping classes in secondary languages were not calculated during checkout.
160
+ * Fixed error while sending WooCoomerce Bookings email for bookings which didn't have orders assigned.
161
+ * added comp. class to cover price update when products are edited with WOOBE plugin
162
+ * Updated compatibility class for WC Checkout Addons
163
+ * Fixed an issue where the total price on the Composite product page was not rounded.
164
+ * Fixed an issue causing wrong rewrite rules after saving the settings and visiting a page in a language other than the default.
165
+ * Fixed an issue with incorrect price converting for the Product add-ons.
166
+ * Fixed an issue with the currency reverting to the default one during checkout.
167
+ * Fixed removed meta from original product not synchronized to translation.
168
+ * Fixed an issue where the BACS gateway instructions were not translated when re-sending the customer notification email from the admin.
169
+ * Fixed an issue with missing language information for attribute terms that happened after changing the attribute slug.
170
+ * Removed the Twig Composer dependency as it now relies on Twig from the WPML core plugin.
171
+ * Fixed an issue where the Products shortcode was not working in the secondary language.
172
+ * Fixed the images that were wrongly inserted in the translation job when attachments are not translatable.
173
+ * Significantly improved the site performance on when updating the page, post, or a WooCommerce product page in the admin.
174
+ * Added the "wp_" prefix to all cookies so that hosting and caching layers can properly handle them.
175
+ * Display larger images when hovering thumbnails in the WooCommerce Multilingual Products admin page.
176
+ * Added the "wcml_new_order_admin_email_language" filter to allow setting the language of emails sent to admins for new or updated orders.
177
+
178
+ = 4.6.0 =
179
+ * Fix wrong currency code after removing item from manually created order
180
+ * Replace *_woocommerce_term_meta functions on *_term_meta
181
+ * Fix gallery images not showing up on translated product page
182
+ * Fix double calculating order item price while manually adding it from admin to order with WooCommerce 3.6.0
183
+ * Fix performance issues on checkout with manage stock products
184
+ * Fix performance issue on shop page with WooCommerce 3.6
185
+ * Fix loading scripts on admin pages
186
+ * Fix coupon discount when editing order from admin
187
+ * Fix wrong product price after adding another product to existing order from admin
188
+ * Fix my-account page endpoints in secondary language with pages set to "Display as translated"
189
+
190
+ = 4.5.0 =
191
+ * Add "get_post_metadata" hook to filter Woocommerce product data
192
+ * Added function in troubleshooting page to fix broken variations
193
+ * Fixed DB error when saving a variation with specific steps
194
+ * Fix refreshing of status icon when ATE Job of updated content is synced
195
+ * Fix few notices when removing a Elementor widget and refresh page
196
+ * Fetch ATE translations from WCML Product Translation Tab
197
+ * Fix warning when adding comment to product
198
+ * Fixed wrong price calculation when adding product to new order on backend
199
+ * Fixed bookings counter on admin bookings listing page
200
+ * Fixed stock quantity not synchronized to translation when creating it
201
+ * Fixed notice when saving translation
202
+ * Fixed translated attributes via ATE/Translation service not connected to translated product
203
+ * Fix not translated "On Hold" email subject after returning order from "Processing"
204
+ * Remove unneded $_SESSION variables on checkout page
205
+ * Fix PHP notice `Notice: Only variables should be passed by reference`
206
+ * Implemented dependency check for minimum compatible versions of required WPML plugins
207
+ * Fixed default variation not pre-selected on front-end for translated product with non latin attribute in default language
208
+ * Fix cannot change currency with "wcml_client_currency" filter
209
+ * Fixed not valid API key when trying manually update exchange rates
210
+ * WooCommerce Variation Swatches and Photos compatibility to translate attributes
211
+ * Fix related product displays in all languages
212
+ * Added compatibility with Yikes Custom Product Tabs
213
+
214
+ = 4.4.0 =
215
+ * Added the ability to associate BACS accounts with currencies
216
+ * Hide reviews in other languages link, if there are no reviews in product
217
+ * Update WCML Logo
218
+ * Removed Product Type Column from WCML backend and added compatibility with the WC Product Type Column plugin
219
+ * Fix low_stock_amount not synchronized to translations
220
+ * Fix custom attribute with number in name not appears to translation in Translation editor
221
+ * Fix not applied price rule for WooCommerce Table Rate Shipping in second currency
222
+ * Fix translated custom field wrongly saved to translation if contains array of strings
223
+ * Endless loop when using troubleshooting action to duplicate terms
224
+ * Fixed an issue with Elementor PRO products block showing all categories in the translated page.
225
+ * Fixed Xliff doesn't contains variation descriptions for WooCommerce Subscriptions
226
+ * Fixed compatibility issue with Flatsome theme
227
+ * Fix issue with custom product attribute title when trying to upload translation with XLIFF file
228
+ * Fixed cart validate for specific situations
229
+ * Added filter for translated package rates
230
+ * Added WPML switcher buttons library for Multi Currency in backend
231
+ * Fix loading Jquery to any place in code and in header
232
+ * Added fix for variation product "become" out-of-stock when translating using native screen
233
+ * Removed backward compatibility filters for terms synchronization
234
+ * Fixed attribute slug language always set to English
235
+ * Wrong path in Bookings compatibility class
236
+ * Fixed a fatal error occuring with older versions of WooCommerce (3.3.5)
237
+ * Fixed confirming order as complete from the order edit screen, does not decrement the second language stock qty
238
+ * Product category data always synchronizes on save of the translation and does not respect WPML option to sync taxonomies
239
+ * Fixed call to undefined method WPML_URL_Filters::remove_global_hooks with WPML < 3.6.0
240
+ * Fixed compatibility class name for wc product addons
241
+ * Fixed manual order creation does not respect manual prices
242
+ * Fix email language for the order as complete emails
243
+ * Fixed Composite Products compatibility - Price not rounding to the nearest integer
244
+ * Fixed missing custom attribute in XLIFF file / Pro Translation
245
+ * Fix Endpoint error to prevent 404 in some cases
246
+ * Fixed accepted arguments for terms_clause
247
+ * Resolved an exception causing an error message in the cart in some setups
248
+ * Fixed missed synchronization of 'outofstock' visibility term between product translations
249
+ * Fix broken logic with Table Rate Shipping when product uses class with "break and abort" rule
250
+ * Custom attributes terms not copied to diplicated translation after update values in original
251
+ * Added support for wpml endpoints
252
+ * WP Fastest Cache compatibility - fixed currency switcher problem
253
+ * Added ability to set custom prices for secondary currencies in WC Product Add-Ons
254
+ * Update minimum requirements
255
+ * Added ability to add custom payment methods for each currency
256
+
257
+ = 4.3.0 =
258
+ * Added ability to filtering comments by language
259
+ * Use display-as-translated for product images and product galleries
260
+ * Fixed issue when deleting a currency in Safari
261
+ * Fixed issue causing fatal error when activating WCML and WPML String Translation
262
+ * Changes in the Fixer.io API
263
+ * Added a fix where in some situation the product slug URL is not translated correctly
264
+ * Variable product removed from cart when switching language on the cart page
265
+ * Multicurrency in defaults not calculated correctly when creating manual order
266
+ * Product Bundles - search products returned wrong values
267
+ * Translating custom product category base leads to products returning error 404 when both bases contains the same string
268
+ * Table Rate Shipping - products with different classes produce no shipping method on cart page
269
+ * New order admin email subject and heading were overwrites with wrong data
270
+ * Fix small issue in product stock sync
271
+ * Refund and restock - not working properly when refunding the variation in second language
272
+ * WooCommerce Product Bundles -> original overwrites translation (visible when using title/description override)
273
 
274
  = 4.1.0 =
275
  * Enhanced language switchers
vendor/autoload.php CHANGED
@@ -4,4 +4,4 @@
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
- return ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08::getLoader();
4
 
5
  require_once __DIR__ . '/composer/autoload_real.php';
6
 
7
+ return ComposerAutoloaderInitc704f09bbaeb2888be7b4eaa53cd98b6::getLoader();
vendor/composer/autoload_real.php CHANGED
@@ -2,7 +2,7 @@
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
- class ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08
6
  {
7
  private static $loader;
8
 
@@ -19,15 +19,15 @@ class ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08
19
  return self::$loader;
20
  }
21
 
22
- spl_autoload_register(array('ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
- spl_autoload_unregister(array('ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
- call_user_func(\Composer\Autoload\ComposerStaticInit4805846488f79a5e99bdcddaade3fb08::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
@@ -48,19 +48,19 @@ class ComposerAutoloaderInit4805846488f79a5e99bdcddaade3fb08
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
- $includeFiles = Composer\Autoload\ComposerStaticInit4805846488f79a5e99bdcddaade3fb08::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
- composerRequire4805846488f79a5e99bdcddaade3fb08($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
- function composerRequire4805846488f79a5e99bdcddaade3fb08($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
2
 
3
  // autoload_real.php @generated by Composer
4
 
5
+ class ComposerAutoloaderInitc704f09bbaeb2888be7b4eaa53cd98b6
6
  {
7
  private static $loader;
8
 
19
  return self::$loader;
20
  }
21
 
22
+ spl_autoload_register(array('ComposerAutoloaderInitc704f09bbaeb2888be7b4eaa53cd98b6', 'loadClassLoader'), true, true);
23
  self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitc704f09bbaeb2888be7b4eaa53cd98b6', 'loadClassLoader'));
25
 
26
  $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
  if ($useStaticLoader) {
28
  require_once __DIR__ . '/autoload_static.php';
29
 
30
+ call_user_func(\Composer\Autoload\ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6::getInitializer($loader));
31
  } else {
32
  $map = require __DIR__ . '/autoload_namespaces.php';
33
  foreach ($map as $namespace => $path) {
48
  $loader->register(true);
49
 
50
  if ($useStaticLoader) {
51
+ $includeFiles = Composer\Autoload\ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6::$files;
52
  } else {
53
  $includeFiles = require __DIR__ . '/autoload_files.php';
54
  }
55
  foreach ($includeFiles as $fileIdentifier => $file) {
56
+ composerRequirec704f09bbaeb2888be7b4eaa53cd98b6($fileIdentifier, $file);
57
  }
58
 
59
  return $loader;
60
  }
61
  }
62
 
63
+ function composerRequirec704f09bbaeb2888be7b4eaa53cd98b6($fileIdentifier, $file)
64
  {
65
  if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
66
  require $file;
vendor/composer/autoload_static.php CHANGED
@@ -4,7 +4,7 @@
4
 
5
  namespace Composer\Autoload;
6
 
7
- class ComposerStaticInit4805846488f79a5e99bdcddaade3fb08
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
@@ -235,9 +235,9 @@ class ComposerStaticInit4805846488f79a5e99bdcddaade3fb08
235
  public static function getInitializer(ClassLoader $loader)
236
  {
237
  return \Closure::bind(function () use ($loader) {
238
- $loader->prefixLengthsPsr4 = ComposerStaticInit4805846488f79a5e99bdcddaade3fb08::$prefixLengthsPsr4;
239
- $loader->prefixDirsPsr4 = ComposerStaticInit4805846488f79a5e99bdcddaade3fb08::$prefixDirsPsr4;
240
- $loader->classMap = ComposerStaticInit4805846488f79a5e99bdcddaade3fb08::$classMap;
241
 
242
  }, null, ClassLoader::class);
243
  }
4
 
5
  namespace Composer\Autoload;
6
 
7
+ class ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6
8
  {
9
  public static $files = array (
10
  'b45b351e6b6f7487d819961fef2fda77' => __DIR__ . '/..' . '/jakeasmith/http_build_url/src/http_build_url.php',
235
  public static function getInitializer(ClassLoader $loader)
236
  {
237
  return \Closure::bind(function () use ($loader) {
238
+ $loader->prefixLengthsPsr4 = ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6::$prefixLengthsPsr4;
239
+ $loader->prefixDirsPsr4 = ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6::$prefixDirsPsr4;
240
+ $loader->classMap = ComposerStaticInitc704f09bbaeb2888be7b4eaa53cd98b6::$classMap;
241
 
242
  }, null, ClassLoader::class);
243
  }
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.2.4
11
- * Version: 4.7.2
12
  * Plugin Slug: woocommerce-multilingual
13
  * WC requires at least: 3.3.0
14
- * WC tested up to: 3.7.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.7.2' );
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' );
7
  * Author URI: http://www.onthegosystems.com/
8
  * Text Domain: woocommerce-multilingual
9
  * Requires at least: 4.7
10
+ * Tested up to: 5.3
11
+ * Version: 4.7.3
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.7.3' );
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' );