TranslatePress – Translate Multilingual sites - Version 1.4.5

Version Description

  • Performance improvements
  • Fixed an issue that was causing empty strings to get inserted in the database
  • Improvements to detecting dynamic js strings earlier
  • Fixes some urls for sitemap
  • We now check if str_get_html is successful to avoid fatal error
  • Fixed regular string loaded by ajax not detected in translation editor
  • We now allow translating WooCommerce product base name separately from selected variations
  • Fixed WooCommerce cart details not being translated when changing language
  • Fixed Automatic Google Translation on languages not published yet
  • Fixed Translation Editor not working in default language when no translation language is published yet
  • Fixed gettext wrapping characters showing up in WooCommerce Shipping taxes metabox on Order pages
Download this release

Release Info

Developer madalin.ungureanu
Plugin Icon 128x128 TranslatePress – Translate Multilingual sites
Version 1.4.5
Comparing to
See all releases

Code changes from version 1.4.4 to 1.4.5

assets/js/trp-editor-script.js CHANGED
@@ -711,6 +711,7 @@ function TRP_Editor(){
711
  e.preventDefault();
712
  }
713
  });
 
714
  }
715
 
716
  /**
711
  e.preventDefault();
712
  }
713
  });
714
+ jQuery( "#trp-preview-iframe" ).on( 'trp_page_loaded', _this.initialize );
715
  }
716
 
717
  /**
assets/js/trp-frontend-compatibility.js ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.addEventListener("DOMContentLoaded", function(event) {
2
+ function trpClearWooCartFragments(){
3
+
4
+ // clear WooCommerce cart fragments when switching language
5
+ var trp_language_switcher_urls = document.querySelectorAll(".trp-language-switcher-container a:not(.trp-ls-disabled-language");
6
+
7
+ for (i = 0; i < trp_language_switcher_urls.length; i++) {
8
+ trp_language_switcher_urls[i].addEventListener("click", function(){
9
+ if ( typeof wc_cart_fragments_params !== 'undefined' && typeof wc_cart_fragments_params.fragment_name !== 'undefined' ) {
10
+ window.sessionStorage.removeItem(wc_cart_fragments_params.fragment_name);
11
+ }
12
+ });
13
+ }
14
+ }
15
+
16
+ trpClearWooCartFragments();
17
+ });
assets/js/trp-translate-dom-changes.js CHANGED
@@ -264,12 +264,12 @@ function TRP_Translator(){
264
  var config = {
265
  attributes: true,
266
  childList: true,
267
- characterData: true,
268
  subtree: true
269
  };
270
 
271
 
272
- observer.observe( document.body , config );
273
 
274
  jQuery( document ).ajaxComplete(function( event, request, settings ) {
275
  if( typeof window.parent.jQuery !== "undefined" && window.parent.jQuery('#trp-preview-iframe').length != 0 ) {
@@ -401,10 +401,9 @@ function trp_allow_detect_dom_changes_to_run(){
401
  }
402
 
403
 
404
- // Initialize the Translate Press Editor after jQuery is ready
405
- jQuery( function() {
406
- if ( trp_allow_detect_dom_changes_to_run() ) {
407
- trpTranslator = new TRP_Translator();
408
- }
409
- });
410
 
264
  var config = {
265
  attributes: true,
266
  childList: true,
267
+ characterData: false,//this could be CDATA so I set it to false in v 1.4.5
268
  subtree: true
269
  };
270
 
271
 
272
+ observer.observe( document.documentElement , config );
273
 
274
  jQuery( document ).ajaxComplete(function( event, request, settings ) {
275
  if( typeof window.parent.jQuery !== "undefined" && window.parent.jQuery('#trp-preview-iframe').length != 0 ) {
401
  }
402
 
403
 
404
+ // Initialize the Translate Press Editor when the script loads
405
+ if ( trp_allow_detect_dom_changes_to_run() ) {
406
+ trpTranslator = new TRP_Translator();
407
+ }
408
+
 
409
 
assets/js/trp-update-database.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function() {
2
+ function trigger_update_by_ajax( data ) {
3
+ jQuery.ajax({
4
+ url: trp_updb_localized['admin_ajax_url'],
5
+ type: 'post',
6
+ dataType: 'json',
7
+ data: data,
8
+ success: function (response) {
9
+ jQuery('#trp-update-database-progress').append(response['progress_message'])
10
+ if ( response['trp_update_completed'] == 'no' ) {
11
+ trigger_update_by_ajax(response);
12
+ }
13
+ },
14
+ error: function (errorThrown) {
15
+ console.log('TranslatePress AJAX Request Error while triggering database update');
16
+ }
17
+ });
18
+ };
19
+ trigger_update_by_ajax( {
20
+ action: 'trp_update_database',
21
+ trp_updb_nonce: trp_updb_localized['nonce'],
22
+ } );
23
+ });
class-translate-press.php CHANGED
@@ -41,7 +41,7 @@ class TRP_Translate_Press{
41
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
42
  define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
43
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
44
- define( 'TRP_PLUGIN_VERSION', '1.4.4' );
45
 
46
  wp_cache_add_non_persistent_groups(array('trp'));
47
 
@@ -134,6 +134,8 @@ class TRP_Translate_Press{
134
 
135
  $this->loader->add_action( 'admin_menu', $this->upgrade, 'register_menu_page' );
136
  $this->loader->add_action( 'admin_init', $this->upgrade, 'show_admin_notice' );
 
 
137
 
138
  }
139
 
@@ -141,7 +143,13 @@ class TRP_Translate_Press{
141
  * Hooks methods used in front-end
142
  */
143
  protected function define_frontend_hooks(){
 
 
 
 
 
144
  $this->loader->add_action( 'init', $this->translation_render, 'start_output_buffer', 0 );
 
145
  $this->loader->add_action( 'wp_enqueue_scripts', $this->translation_render, 'enqueue_dynamic_translation', 1 );
146
  $this->loader->add_filter( 'wp_redirect', $this->translation_render, 'force_preview_on_url_redirect', 99, 2 );
147
  $this->loader->add_filter( 'wp_redirect', $this->translation_render, 'force_language_on_form_url_redirect', 99, 2 );
41
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
42
  define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
43
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
44
+ define( 'TRP_PLUGIN_VERSION', '1.4.5' );
45
 
46
  wp_cache_add_non_persistent_groups(array('trp'));
47
 
134
 
135
  $this->loader->add_action( 'admin_menu', $this->upgrade, 'register_menu_page' );
136
  $this->loader->add_action( 'admin_init', $this->upgrade, 'show_admin_notice' );
137
+ $this->loader->add_action( 'admin_enqueue_scripts', $this->upgrade, 'enqueue_update_script', 10, 1 );
138
+ $this->loader->add_action( 'wp_ajax_trp_update_database', $this->upgrade, 'trp_update_database' );
139
 
140
  }
141
 
143
  * Hooks methods used in front-end
144
  */
145
  protected function define_frontend_hooks(){
146
+
147
+ //we do not need the plugin in cron requests ?
148
+ if( isset( $_REQUEST['doing_wp_cron'] ) )
149
+ return;
150
+
151
  $this->loader->add_action( 'init', $this->translation_render, 'start_output_buffer', 0 );
152
+ $this->loader->add_action( 'wp_enqueue_scripts', $this->translation_render, 'enqueue_scripts', 10 );
153
  $this->loader->add_action( 'wp_enqueue_scripts', $this->translation_render, 'enqueue_dynamic_translation', 1 );
154
  $this->loader->add_filter( 'wp_redirect', $this->translation_render, 'force_preview_on_url_redirect', 99, 2 );
155
  $this->loader->add_filter( 'wp_redirect', $this->translation_render, 'force_language_on_form_url_redirect', 99, 2 );
includes/class-language-switcher.php CHANGED
@@ -233,9 +233,9 @@ class TRP_Language_Switcher{
233
  }
234
 
235
  ?>
236
- <div id="trp-floater-ls" onclick="" data-no-translation class="<?php echo $floater_class; ?>" <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : '' ?>>
237
  <div id="trp-floater-ls-current-language" class="<?php echo $floater_flags_class ?>">
238
- <a href="javascript:void(0)" class="trp-floater-ls-disabled-language" onclick="void(0)"><?php echo ( $floater_settings['flags'] ? $this->add_flag( $current_language['code'], $current_language['name'] ) : '' ); echo $current_language_label; ?></a>
239
  </div>
240
  <div id="trp-floater-ls-language-list" class="<?php echo $floater_flags_class;?>" <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : ''?>>
241
  <?php
@@ -255,7 +255,7 @@ class TRP_Language_Switcher{
255
  <?php
256
  }
257
  ?>
258
- <a href="javascript:void(0)" class="trp-floater-ls-disabled-language"><?php echo ( $floater_settings['flags'] ? $this->add_flag( $current_language['code'], $current_language['name'] ) : '' ); echo $current_language_label; ?></a>
259
  </div>
260
  </div>
261
 
@@ -403,6 +403,7 @@ class TRP_Language_Switcher{
403
 
404
 
405
  $items[$key]->url = $this->url_converter->get_url_for_language( $language_code );
 
406
  $items[$key]->title = '<span data-no-translation>';
407
  if ( $menu_settings['flags'] ) {
408
  $items[$key]->title .= $this->add_flag( $language_code, $language_name );
233
  }
234
 
235
  ?>
236
+ <div id="trp-floater-ls" onclick="" data-no-translation class="trp-language-switcher-container <?php echo $floater_class; ?>" <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : '' ?>>
237
  <div id="trp-floater-ls-current-language" class="<?php echo $floater_flags_class ?>">
238
+ <a href="javascript:void(0)" class="trp-floater-ls-disabled-language trp-ls-disabled-language" onclick="void(0)"><?php echo ( $floater_settings['flags'] ? $this->add_flag( $current_language['code'], $current_language['name'] ) : '' ); echo $current_language_label; ?></a>
239
  </div>
240
  <div id="trp-floater-ls-language-list" class="<?php echo $floater_flags_class;?>" <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : ''?>>
241
  <?php
255
  <?php
256
  }
257
  ?>
258
+ <a href="javascript:void(0)" class="trp-floater-ls-disabled-language trp-ls-disabled-language"><?php echo ( $floater_settings['flags'] ? $this->add_flag( $current_language['code'], $current_language['name'] ) : '' ); echo $current_language_label; ?></a>
259
  </div>
260
  </div>
261
 
403
 
404
 
405
  $items[$key]->url = $this->url_converter->get_url_for_language( $language_code );
406
+ $items[$key]->classes[] = 'trp-language-switcher-container';
407
  $items[$key]->title = '<span data-no-translation>';
408
  if ( $menu_settings['flags'] ) {
409
  $items[$key]->title .= $this->add_flag( $language_code, $language_name );
includes/class-query.php CHANGED
@@ -264,44 +264,64 @@ class TRP_Query{
264
  return false;
265
  }
266
 
267
- /**
268
- * Insert translations and new strings in DB.
269
- *
270
- * @param array $new_strings Array of strings for which we do not have a translation. Only inserts original.
271
- * @param array $update_strings Array of arrays, each containing an entry to update.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  * @param string $language_code Language code of table where it should be inserted.
273
  * @param int $block_type
274
- * @param string $on_duplicate
275
  */
276
- public function insert_strings( $new_strings, $update_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ) {
277
  if ( $block_type == null ) {
278
  $block_type = self::BLOCK_TYPE_REGULAR_STRING;
279
  }
280
- if ( count( $new_strings ) == 0 && count( $update_strings ) == 0 ) {
281
  return;
282
  }
283
- $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( id, original, translated, status, block_type ) VALUES ";
284
 
285
  $values = array();
286
  $place_holders = array();
287
  $new_strings = array_unique( $new_strings );
288
 
289
  foreach ( $new_strings as $string ) {
290
- array_push( $values, NULL, $string, NULL, self::NOT_TRANSLATED, $block_type );
291
- $place_holders[] = "('%d','%s','%s','%d','%d')";
292
- }
293
- foreach ( $update_strings as $string ) {
294
- if ( ! isset( $string['block_type'] ) ){
295
- $string['block_type'] = self::BLOCK_TYPE_REGULAR_STRING;
296
- }
297
- array_push( $values, $string['id'], $string['original'], $string['translated'], $string['status'], $string['block_type'] );
298
- $place_holders[] = "('%d','%s','%s','%d','%d')";
299
  }
300
  $query .= implode( ', ', $place_holders );
301
 
302
- $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status), block_type=VALUES(block_type)';
303
- $query .= $on_duplicate;
304
-
305
  // you cannot insert multiple rows at once using insert() method.
306
  // but by using prepare you cannot insert NULL values.
307
  $this->db->query( $this->db->prepare($query . ' ', $values) );
@@ -311,7 +331,7 @@ class TRP_Query{
311
  if ( count( $new_strings ) == 0 ){
312
  return;
313
  }
314
- $query = "INSERT INTO `" . sanitize_text_field( $this->get_gettext_table_name( $language_code ) ) . "` ( id, original, translated, domain, status ) VALUES ";
315
 
316
  $values = array();
317
  $place_holders = array();
@@ -330,8 +350,8 @@ class TRP_Query{
330
  $status = self::HUMAN_REVIEWED;
331
  }
332
 
333
- array_push( $values, NULL, $string['original'], $translated, $string['domain'], $status );
334
- $place_holders[] = "( '%d', '%s', '%s', '%s', '%d')";
335
  }
336
 
337
 
@@ -354,11 +374,14 @@ class TRP_Query{
354
  $values = array();
355
  $place_holders = array();
356
 
357
- $status = !empty( $string['status'] ) ? $string['status'] : self::NOT_TRANSLATED;
358
 
359
  foreach ( $updated_strings as $string ) {
360
- array_push( $values, $string['id'], $string['original'], $string['translated'], $string['domain'], $status );
361
- $place_holders[] = "( '%d', '%s', '%s', '%s', '%d')";
 
 
 
 
362
  }
363
 
364
  $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status)';
@@ -678,7 +701,7 @@ class TRP_Query{
678
  * @param array $columns_to_update Array with the name of columns to update id, original, translated, status, block_type
679
  * @param string $placeholders_query_part For query on all columns '%d', '%s', '%s', '%d', '%d'
680
  */
681
- public function update_strings( $update_strings, $language_code, $columns_to_update, $placeholders ) {
682
  if ( count( $update_strings ) == 0 ) {
683
  return;
684
  }
@@ -726,4 +749,10 @@ class TRP_Query{
726
  $prepared_query = $this->db->prepare($query . ' ', $values);
727
  $this->db->query( $prepared_query );
728
  }
 
 
 
 
 
 
729
  }
264
  return false;
265
  }
266
 
267
+ /**
268
+ * Update regular strings in DB
269
+ *
270
+ * @param $update_strings
271
+ * @param $language_code
272
+ */
273
+ public function update_strings( $update_strings, $language_code ) {
274
+ if ( count( $update_strings ) == 0 ) {
275
+ return;
276
+ }
277
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( id, original, translated, status, block_type ) VALUES ";
278
+
279
+ $values = array();
280
+ $place_holders = array();
281
+
282
+ foreach ( $update_strings as $string ) {
283
+ if ( ! isset( $string['block_type'] ) ){
284
+ $string['block_type'] = self::BLOCK_TYPE_REGULAR_STRING;
285
+ }
286
+ array_push( $values, $string['id'], $string['original'], $string['translated'], $string['status'], $string['block_type'] );
287
+ $place_holders[] = "('%d','%s','%s','%d','%d')";
288
+ }
289
+ $query .= implode( ', ', $place_holders );
290
+
291
+ $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status), block_type=VALUES(block_type)';
292
+ $query .= $on_duplicate;
293
+
294
+ // you cannot insert multiple rows at once using insert() method.
295
+ // but by using prepare you cannot insert NULL values.
296
+ $this->db->query( $this->db->prepare($query . ' ', $values) );
297
+ }
298
+
299
+ /**
300
+ * Insert new regular strings in DB.
301
+ *
302
+ * @param array $new_strings Array of strings for which we do not have a translation. Only inserts original.
303
  * @param string $language_code Language code of table where it should be inserted.
304
  * @param int $block_type
 
305
  */
306
+ public function insert_strings( $new_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ) {
307
  if ( $block_type == null ) {
308
  $block_type = self::BLOCK_TYPE_REGULAR_STRING;
309
  }
310
+ if ( count( $new_strings ) == 0 ) {
311
  return;
312
  }
313
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( original, translated, status, block_type ) VALUES ";
314
 
315
  $values = array();
316
  $place_holders = array();
317
  $new_strings = array_unique( $new_strings );
318
 
319
  foreach ( $new_strings as $string ) {
320
+ array_push( $values, $string, NULL, self::NOT_TRANSLATED, $block_type );
321
+ $place_holders[] = "('%s','%s','%d','%d')";
 
 
 
 
 
 
 
322
  }
323
  $query .= implode( ', ', $place_holders );
324
 
 
 
 
325
  // you cannot insert multiple rows at once using insert() method.
326
  // but by using prepare you cannot insert NULL values.
327
  $this->db->query( $this->db->prepare($query . ' ', $values) );
331
  if ( count( $new_strings ) == 0 ){
332
  return;
333
  }
334
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_gettext_table_name( $language_code ) ) . "` ( original, translated, domain, status ) VALUES ";
335
 
336
  $values = array();
337
  $place_holders = array();
350
  $status = self::HUMAN_REVIEWED;
351
  }
352
 
353
+ array_push( $values, $string['original'], $translated, $string['domain'], $status );
354
+ $place_holders[] = "( '%s', '%s', '%s', '%d')";
355
  }
356
 
357
 
374
  $values = array();
375
  $place_holders = array();
376
 
 
377
 
378
  foreach ( $updated_strings as $string ) {
379
+ $status = !empty( $string['status'] ) ? $string['status'] : self::NOT_TRANSLATED;
380
+
381
+ if( !empty( $string['id'] ) && is_numeric( $string['id'] ) && !empty( $string['original'] ) ) {//we must have an ID and an original
382
+ array_push($values, $string['id'], $string['original'], $string['translated'], $string['domain'], $status);
383
+ $place_holders[] = "( '%d', '%s', '%s', '%s', '%d')";
384
+ }
385
  }
386
 
387
  $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status)';
701
  * @param array $columns_to_update Array with the name of columns to update id, original, translated, status, block_type
702
  * @param string $placeholders_query_part For query on all columns '%d', '%s', '%s', '%d', '%d'
703
  */
704
+ public function update_strings_by_columns( $update_strings, $language_code, $columns_to_update, $placeholders ) {
705
  if ( count( $update_strings ) == 0 ) {
706
  return;
707
  }
749
  $prepared_query = $this->db->prepare($query . ' ', $values);
750
  $this->db->query( $prepared_query );
751
  }
752
+
753
+ public function delete_empty_gettext_strings( $language_code, $limit ){
754
+ $limit = (int) $limit;
755
+ $sql = "DELETE FROM `" . sanitize_text_field( $this->get_gettext_table_name( $language_code ) ). "` WHERE (original IS NULL OR original = '') LIMIT " . $limit;
756
+ return $this->db->query( $sql );
757
+ }
758
  }
includes/class-settings.php CHANGED
@@ -226,7 +226,7 @@ class TRP_Settings{
226
  $this->trp_query->check_gettext_table( $language_code );
227
  }
228
 
229
- $settings['google-translate-codes'] = $this->trp_languages->get_iso_codes( $settings['publish-languages'] );
230
 
231
  // regenerate permalinks in case something changed
232
  flush_rewrite_rules();
226
  $this->trp_query->check_gettext_table( $language_code );
227
  }
228
 
229
+ $settings['google-translate-codes'] = $this->trp_languages->get_iso_codes( $settings['translation-languages'] );
230
 
231
  // regenerate permalinks in case something changed
232
  flush_rewrite_rules();
includes/class-translation-manager.php CHANGED
@@ -413,7 +413,7 @@ class TRP_Translation_Manager{
413
  }
414
 
415
  foreach( $update_strings as $language => $update_string_array ) {
416
- $this->trp_query->insert_strings( array(), $update_string_array, $language, $block_type );
417
  }
418
  }
419
 
@@ -549,7 +549,8 @@ class TRP_Translation_Manager{
549
  $existing_dictionary[$string_key]['block_type'] = $active_block_type;
550
  $originals = array_values( $originals );
551
  }
552
- $this->trp_query->insert_strings( $originals, $existing_dictionary, $language, $active_block_type );
 
553
  }
554
 
555
  }
@@ -695,6 +696,8 @@ class TRP_Translation_Manager{
695
  * Create a global with the gettext strings that exist in the database
696
  */
697
  public function create_gettext_translated_global(){
 
 
698
  global $trp_translated_gettext_texts;
699
  if( !is_admin() || $this::is_ajax_on_frontend() ) {
700
  global $TRP_LANGUAGE;
@@ -720,28 +723,48 @@ class TRP_Translation_Manager{
720
  * function that applies the gettext filter on frontend on different hooks depending on what we need
721
  */
722
  public function initialize_gettext_processing(){
 
 
723
  /* on ajax hooks from frontend that have the init hook ( we found WooCommerce has it ) apply it earlier */
724
- if( $this::is_ajax_on_frontend() ){
725
  add_action( 'wp_loaded', array( $this, 'apply_gettext_filter' ) );
726
  }
727
- elseif( class_exists( 'WooCommerce' ) ){
728
- // WooCommerce launches some ajax calls before wp_head, so we need to apply_gettext_filter earlier to catch them
729
- add_action( 'wp_loaded', array( $this, 'apply_gettext_filter' ), 19 );
730
- }//otherwise start from the wp_head hook
731
- else{
732
  add_action( 'wp_head', array( $this, 'apply_gettext_filter' ), 100 );
733
  }
 
 
 
 
 
 
734
  }
735
 
736
  /* apply the gettext filter here */
737
  public function apply_gettext_filter(){
738
- global $pagenow;
739
- // Do not process gettext strings on wp-login pages. Do not process strings in admin area except for when when is_ajax_on_frontend.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  if( ( $pagenow != 'wp-login.php' ) && ( !is_admin() || $this::is_ajax_on_frontend() ) ) {
741
- add_filter('gettext', array($this, 'process_gettext_strings'), 100, 3);
742
- add_filter('gettext_with_context', array($this, 'process_gettext_strings_with_context'), 100, 4);
743
- add_filter('ngettext', array($this, 'process_ngettext_strings'), 100, 5);
744
- add_filter('ngettext_with_context', array($this, 'process_ngettext_strings_with_context'), 100, 6);
745
  }
746
  }
747
 
@@ -842,14 +865,16 @@ class TRP_Translation_Manager{
842
  $translation = TRP_Translation_Manager::strip_gettext_tags( $translation );
843
 
844
  //try here to exclude some strings that do not require translation
845
- $excluded_gettext_strings = array( '', ' ', '&hellip;', '&nbsp;' );
846
  if( in_array( trp_full_trim( $text ), $excluded_gettext_strings ) )
847
  return $translation;
848
 
 
 
 
 
 
849
  global $TRP_LANGUAGE;
850
- /* don't do anything if we don't have extra languages on the site */
851
- if( count( $this->settings['publish-languages'] ) < 1 )
852
- return $translation;
853
 
854
  if( ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'true' ) || $domain == 'translatepress-multilingual' )
855
  return $translation;
@@ -858,8 +883,12 @@ class TRP_Translation_Manager{
858
  if( isset( $_REQUEST['action'] ) && strpos($_REQUEST['action'], 'trp_') === 0 )
859
  return $translation;
860
 
 
 
 
 
861
 
862
- if ( !defined( 'DOING_AJAX' ) || $this::is_ajax_on_frontend() ) {
863
  $db_id = '';
864
  $skip_gettext_querying = apply_filters( 'trp_skip_gettext_querying', false, $translation, $text, $domain );
865
  if ( !$skip_gettext_querying ) {
@@ -893,9 +922,9 @@ class TRP_Translation_Manager{
893
  'id' => $db_id,
894
  'original' => $text,
895
  'translated' => $translation,
896
- 'domain' => $domain
897
- ),
898
- 'status' => $this->trp_query->get_constant_human_reviewed()
899
  ), get_locale() );
900
  }
901
  }
@@ -973,20 +1002,29 @@ class TRP_Translation_Manager{
973
  'esc_url',
974
  'wc_get_permalink_structure' // make sure we don't touch the woocommerce permalink rewrite slugs that are translated
975
  ), $text, $translation, $domain );
976
- $callstack_functions = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
 
 
 
 
 
 
977
  if( !empty( $callstack_functions ) ){
978
  foreach( $callstack_functions as $callstack_function ){
979
  if ( in_array( $callstack_function['function'], $blacklist_functions ) ){
 
980
  return $translation;
981
  }
982
 
983
  /* make sure we don't touch the woocommerce process_payment function in WC_Gateway_Stripe. It does a wp_remote_post() call to stripe with localized parameters */
984
  if( $callstack_function['function'] == 'process_payment' && $callstack_function['class'] == 'WC_Gateway_Stripe' ){
 
985
  return $translation;
986
  }
987
 
988
  }
989
  }
 
990
 
991
  if ( did_action( 'init' ) ) {
992
  if ( ( ! empty( $TRP_LANGUAGE ) && $this->settings["default-language"] != $TRP_LANGUAGE ) || ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) ) {
@@ -995,7 +1033,21 @@ class TRP_Translation_Manager{
995
  }
996
  }
997
  }
 
 
 
998
 
 
 
 
 
 
 
 
 
 
 
 
999
  return $translation;
1000
  }
1001
 
@@ -1012,6 +1064,16 @@ class TRP_Translation_Manager{
1012
  return $translation;
1013
  }
1014
 
 
 
 
 
 
 
 
 
 
 
1015
  /**
1016
  * function that filters the _n translations
1017
  * @param $translation
@@ -1030,6 +1092,17 @@ class TRP_Translation_Manager{
1030
  return $translation;
1031
  }
1032
 
 
 
 
 
 
 
 
 
 
 
 
1033
  /**
1034
  * function that filters the _nx translations
1035
  * @param $translation
@@ -1045,6 +1118,16 @@ class TRP_Translation_Manager{
1045
  return $translation;
1046
  }
1047
 
 
 
 
 
 
 
 
 
 
 
1048
  /**
1049
  * function that machine translates gettext strings
1050
  */
413
  }
414
 
415
  foreach( $update_strings as $language => $update_string_array ) {
416
+ $this->trp_query->update_strings( $update_string_array, $language );
417
  }
418
  }
419
 
549
  $existing_dictionary[$string_key]['block_type'] = $active_block_type;
550
  $originals = array_values( $originals );
551
  }
552
+ $this->trp_query->insert_strings( $originals, $language, $active_block_type );
553
+ $this->trp_query->update_strings( $existing_dictionary, $language );
554
  }
555
 
556
  }
696
  * Create a global with the gettext strings that exist in the database
697
  */
698
  public function create_gettext_translated_global(){
699
+
700
+
701
  global $trp_translated_gettext_texts;
702
  if( !is_admin() || $this::is_ajax_on_frontend() ) {
703
  global $TRP_LANGUAGE;
723
  * function that applies the gettext filter on frontend on different hooks depending on what we need
724
  */
725
  public function initialize_gettext_processing(){
726
+ $is_ajax_on_frontend = $this::is_ajax_on_frontend();
727
+
728
  /* on ajax hooks from frontend that have the init hook ( we found WooCommerce has it ) apply it earlier */
729
+ if( $is_ajax_on_frontend ){
730
  add_action( 'wp_loaded', array( $this, 'apply_gettext_filter' ) );
731
  }
732
+ else{//otherwise start from the wp_head hook
 
 
 
 
733
  add_action( 'wp_head', array( $this, 'apply_gettext_filter' ), 100 );
734
  }
735
+
736
+ //if we have woocommerce installed and it is not an ajax request add a gettext hook starting from wp_loaded and remove it on wp_head
737
+ if( class_exists( 'WooCommerce' ) && !$is_ajax_on_frontend ){
738
+ // WooCommerce launches some ajax calls before wp_head, so we need to apply_gettext_filter earlier to catch them
739
+ add_action( 'wp_loaded', array( $this, 'apply_woocommerce_gettext_filter' ), 19 );
740
+ }
741
  }
742
 
743
  /* apply the gettext filter here */
744
  public function apply_gettext_filter(){
745
+
746
+ //if we have wocommerce installed remove te hook that was added on wp_loaded
747
+ if( class_exists( 'WooCommerce' ) ){
748
+ // WooCommerce launches some ajax calls before wp_head, so we need to apply_gettext_filter earlier to catch them
749
+ remove_action( 'wp_loaded', array( $this, 'apply_woocommerce_gettext_filter' ), 19 );
750
+ }
751
+
752
+ $this->call_gettext_filters();
753
+
754
+ }
755
+
756
+ public function apply_woocommerce_gettext_filter(){
757
+ $this->call_gettext_filters('woocommerce_');
758
+ }
759
+
760
+ public function call_gettext_filters( $prefix = '' ){
761
+ global $pagenow;
762
+ // Do not process gettext strings on wp-login pages. Do not process strings in admin area except for when when is_ajax_on_frontend.
763
  if( ( $pagenow != 'wp-login.php' ) && ( !is_admin() || $this::is_ajax_on_frontend() ) ) {
764
+ add_filter('gettext', array($this, $prefix.'process_gettext_strings'), 100, 3);
765
+ add_filter('gettext_with_context', array($this, $prefix.'process_gettext_strings_with_context'), 100, 4);
766
+ add_filter('ngettext', array($this, $prefix.'process_ngettext_strings'), 100, 5);
767
+ add_filter('ngettext_with_context', array($this, $prefix.'process_ngettext_strings_with_context'), 100, 6);
768
  }
769
  }
770
 
865
  $translation = TRP_Translation_Manager::strip_gettext_tags( $translation );
866
 
867
  //try here to exclude some strings that do not require translation
868
+ $excluded_gettext_strings = array( '', ' ', '&hellip;', '&nbsp;', '&raquo;' );
869
  if( in_array( trp_full_trim( $text ), $excluded_gettext_strings ) )
870
  return $translation;
871
 
872
+ //set a global so we remember the last string we processed and if it is the same with the current one return a result immediately for performance reasons ( this could happen in loops )
873
+ global $tp_last_gettext_processed;
874
+ if( isset( $tp_last_gettext_processed[$text.'::'.$domain] ) )
875
+ return $tp_last_gettext_processed[$text.'::'.$domain];
876
+
877
  global $TRP_LANGUAGE;
 
 
 
878
 
879
  if( ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'true' ) || $domain == 'translatepress-multilingual' )
880
  return $translation;
883
  if( isset( $_REQUEST['action'] ) && strpos($_REQUEST['action'], 'trp_') === 0 )
884
  return $translation;
885
 
886
+ //use a global for is_ajax_on_frontend() so we don't execute it multiple times
887
+ global $tp_gettext_is_ajax_on_frontend;
888
+ if( !isset($tp_gettext_is_ajax_on_frontend) )
889
+ $tp_gettext_is_ajax_on_frontend = $this::is_ajax_on_frontend();
890
 
891
+ if ( !defined( 'DOING_AJAX' ) || $tp_gettext_is_ajax_on_frontend ) {
892
  $db_id = '';
893
  $skip_gettext_querying = apply_filters( 'trp_skip_gettext_querying', false, $translation, $text, $domain );
894
  if ( !$skip_gettext_querying ) {
922
  'id' => $db_id,
923
  'original' => $text,
924
  'translated' => $translation,
925
+ 'domain' => $domain,
926
+ 'status' => $this->trp_query->get_constant_human_reviewed()
927
+ )
928
  ), get_locale() );
929
  }
930
  }
1002
  'esc_url',
1003
  'wc_get_permalink_structure' // make sure we don't touch the woocommerce permalink rewrite slugs that are translated
1004
  ), $text, $translation, $domain );
1005
+
1006
+ if ( version_compare( PHP_VERSION, '5.4.0', '>=' ) ) {
1007
+ $callstack_functions = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 15);//set a limit if it is supported to improve performance
1008
+ }
1009
+ else{
1010
+ $callstack_functions = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
1011
+ }
1012
  if( !empty( $callstack_functions ) ){
1013
  foreach( $callstack_functions as $callstack_function ){
1014
  if ( in_array( $callstack_function['function'], $blacklist_functions ) ){
1015
+ $tp_last_gettext_processed = array( $text.'::'.$domain => $translation );
1016
  return $translation;
1017
  }
1018
 
1019
  /* make sure we don't touch the woocommerce process_payment function in WC_Gateway_Stripe. It does a wp_remote_post() call to stripe with localized parameters */
1020
  if( $callstack_function['function'] == 'process_payment' && $callstack_function['class'] == 'WC_Gateway_Stripe' ){
1021
+ $tp_last_gettext_processed = array( $text.'::'.$domain => $translation );
1022
  return $translation;
1023
  }
1024
 
1025
  }
1026
  }
1027
+ unset($callstack_functions);//maybe free up some memory
1028
 
1029
  if ( did_action( 'init' ) ) {
1030
  if ( ( ! empty( $TRP_LANGUAGE ) && $this->settings["default-language"] != $TRP_LANGUAGE ) || ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) ) {
1033
  }
1034
  }
1035
  }
1036
+ $tp_last_gettext_processed = array( $text.'::'.$domain => $translation );
1037
+ return $translation;
1038
+ }
1039
 
1040
+ /**
1041
+ * caller for woocommerce domain texts
1042
+ * @param $translation
1043
+ * @param $text
1044
+ * @param $domain
1045
+ * @return string
1046
+ */
1047
+ function woocommerce_process_gettext_strings( $translation, $text, $domain ){
1048
+ if( $domain === 'woocommerce' ){
1049
+ $translation = $this->process_gettext_strings( $translation, $text, $domain );
1050
+ }
1051
  return $translation;
1052
  }
1053
 
1064
  return $translation;
1065
  }
1066
 
1067
+ /**
1068
+ * caller for woocommerce domain texts with context
1069
+ */
1070
+ function woocommerce_process_gettext_strings_with_context( $translation, $text, $context, $domain ){
1071
+ if( $domain === 'woocommerce' ) {
1072
+ $translation = $this->process_gettext_strings_with_context( $translation, $text, $context, $domain );
1073
+ }
1074
+ return $translation;
1075
+ }
1076
+
1077
  /**
1078
  * function that filters the _n translations
1079
  * @param $translation
1092
  return $translation;
1093
  }
1094
 
1095
+ /**
1096
+ * caller for woocommerce domain numeric texts
1097
+ */
1098
+ function woocommerce_process_ngettext_strings($translation, $single, $plural, $number, $domain){
1099
+ if( $domain === 'woocommerce' ) {
1100
+ $translation = $this->process_ngettext_strings($translation, $single, $plural, $number, $domain);
1101
+ }
1102
+
1103
+ return $translation;
1104
+ }
1105
+
1106
  /**
1107
  * function that filters the _nx translations
1108
  * @param $translation
1118
  return $translation;
1119
  }
1120
 
1121
+ /**
1122
+ * caller for woocommerce domain numeric texts with context
1123
+ */
1124
+ function woocommerce_process_ngettext_strings_with_context( $translation, $single, $plural, $number, $context, $domain ){
1125
+ if( $domain === 'woocommerce' ) {
1126
+ $translation = $this->process_ngettext_strings_with_context( $translation, $single, $plural, $number, $context, $domain );
1127
+ }
1128
+ return $translation;
1129
+ }
1130
+
1131
  /**
1132
  * function that machine translates gettext strings
1133
  */
includes/class-translation-render.php CHANGED
@@ -8,6 +8,7 @@
8
  class TRP_Translation_Render{
9
  protected $settings;
10
  protected $machine_translator;
 
11
  protected $trp_query;
12
  /* @var TRP_Url_Converter */
13
  protected $url_converter;
@@ -70,7 +71,7 @@ class TRP_Translation_Render{
70
  // in the translation editor we need a different language then the default because we need string ID's.
71
  // so we're forcing it to the first translation language because if it's the default, we're just returning the $output
72
  if ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) {
73
- if( count( $this->settings['publish-languages'] ) > 1 ){
74
  foreach ($this->settings['translation-languages'] as $language) {
75
  if ($language != $TRP_LANGUAGE) {
76
  // return the first language not default. only used for preview mode
@@ -217,6 +218,23 @@ class TRP_Translation_Render{
217
  return preg_replace('/\s+/', ' ', strip_tags( html_entity_decode( htmlspecialchars_decode( trp_full_trim( $string ), ENT_QUOTES ) ) ));
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  /**
221
  * Return translation block if matches any existing translation block from db
222
  *
@@ -230,12 +248,17 @@ class TRP_Translation_Render{
230
  */
231
  public function find_translation_block( $row, $all_existing_translation_blocks, $merge_rules ){
232
  if ( in_array( $row->tag, $merge_rules['top_parents'] ) ){
233
- $trimmed_inner_text = $this->trim_translation_block( $row->innertext );
234
- foreach( $all_existing_translation_blocks as $existing_translation_block ){
235
- if ( $existing_translation_block->trimmed_original == $trimmed_inner_text ){
236
- return $existing_translation_block;
237
- }
238
- }
 
 
 
 
 
239
  }
240
  return null;
241
  }
@@ -352,14 +375,27 @@ class TRP_Translation_Render{
352
  $count_translation_blocks = 0;
353
  if ( $translate_normal_strings ) {
354
  $all_existing_translation_blocks = $this->trp_query->get_all_translation_blocks( $language_code );
355
- $count_translation_blocks = count( $all_existing_translation_blocks );
356
  // trim every translation block original now, to avoid over-calling trim function later
357
  foreach ( $all_existing_translation_blocks as $key => $existing_tb ) {
358
  $all_existing_translation_blocks[ $key ]->trimmed_original = $this->trim_translation_block( $all_existing_translation_blocks[ $key ]->original );
359
  }
 
 
 
 
 
 
 
 
 
360
  $merge_rules = $this->translation_manager->get_merge_rules();
361
  }
362
  $html = TranslatePress\str_get_html($output, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
 
 
 
 
 
363
 
364
  /**
365
  * When we are in the translation editor: Intercept the trp-gettext that was wrapped around all the gettext texts, grab the attribute data-trpgettextoriginal
@@ -449,6 +485,9 @@ class TRP_Translation_Render{
449
 
450
  // convert to a node
451
  $node_from_value = TranslatePress\str_get_html(html_entity_decode(htmlspecialchars_decode($attr_value, ENT_QUOTES)), true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
 
 
 
452
  foreach ($node_from_value->find('trp-gettext') as $nfv_row) {
453
  $nfv_row->outertext = $nfv_row->innertext();
454
  $row->setAttribute($attr_name, $node_from_value->save() );
@@ -467,18 +506,15 @@ class TRP_Translation_Render{
467
  }
468
  }
469
 
470
- /* save it as a string */
471
- $trpremoved = $html->save();
472
- /* perform preg replace on the remaining trp-gettext tags */
473
- $trpremoved = preg_replace( '/(<|&lt;)trp-gettext (.*?)(>|&gt;)/', '', $trpremoved );
474
- $trpremoved = preg_replace( '/(<|&lt;)(\\\\)*\/trp-gettext(>|&gt;)/', '', $trpremoved );
475
 
476
  if ( ! $translate_normal_strings ) {
 
 
 
 
477
  return $trpremoved;
478
  }
479
 
480
- $html = TranslatePress\str_get_html($trpremoved, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
481
-
482
  $no_translate_selectors = apply_filters( 'trp_no_translate_selectors', array( '#wpadminbar' ), $TRP_LANGUAGE );
483
 
484
  /*
@@ -490,46 +526,49 @@ class TRP_Translation_Render{
490
  $row->setAttribute( $no_translate_attribute, '' );
491
  }
492
  }
493
- foreach ( $html->find('.translation-block') as $k => $row ){
494
- $trimmed_string = trp_full_trim($row->innertext);
 
495
  if( $trimmed_string!=""
496
- && $row->parent()->tag!="script"
497
- && $row->parent()->tag!="style"
 
 
498
  && !is_numeric($trimmed_string)
499
  && !preg_match('/^\d+%$/',$trimmed_string)
500
- && !$this->has_ancestor_attribute( $row, $no_translate_attribute )
501
- && $row->parent()->tag != 'title'
502
- && strpos($row->outertext,'[vc_') === false )
503
  {
504
- array_push( $translateable_strings, $trimmed_string );
505
- array_push( $nodes, array('node' => $row, 'type' => 'block'));
506
  }
507
  }
508
 
509
- foreach ( $html->find('text') as $k => $row ){
510
- $trimmed_string = trp_full_trim($row->outertext);
 
 
511
  if( $trimmed_string!=""
512
- && $row->parent()->tag!="script"
513
- && $row->parent()->tag!="style"
 
 
514
  && !is_numeric($trimmed_string)
515
  && !preg_match('/^\d+%$/',$trimmed_string)
516
  && !$this->has_ancestor_attribute( $row, $no_translate_attribute )
517
- && !$this->has_ancestor_class( $row, 'translation-block')
518
- && $row->parent()->tag != 'title'
519
- && strpos($row->outertext,'[vc_') === false )
520
  {
521
- // $translateable_strings array needs to be in sync in $nodes array
522
- array_push( $translateable_strings, $trimmed_string );
523
- if( $row->parent()->tag == 'button') {
524
- array_push($nodes, array('node' => $row, 'type' => 'button'));
525
- }
526
- else {
527
- if ( $row->parent()->tag == 'option' ) {
528
- array_push( $nodes, array( 'node' => $row, 'type' => 'option' ) );
529
- } else {
530
- array_push( $nodes, array( 'node' => $row, 'type' => 'text' ) );
531
- }
532
  }
 
533
  }
534
  }
535
 
@@ -666,8 +705,19 @@ class TRP_Translation_Render{
666
 
667
 
668
  // We need to save here in order to access the translated links too.
669
- $html = $html->save();
670
- $html = TranslatePress\str_get_html($html, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
 
 
 
 
 
 
 
 
 
 
 
671
 
672
  // force custom links to have the correct language
673
  foreach( $html->find('a[href!="#"]') as $a_href) {
@@ -675,10 +725,10 @@ class TRP_Translation_Render{
675
 
676
  $url = $a_href->href;
677
 
678
- $url = $this->maybe_is_local_url($url);
679
 
680
- $is_external_link = $this->is_external_link( $url );
681
- $is_admin_link = $this->is_admin_link($url);
682
 
683
  if( $preview_mode && ! $is_external_link ){
684
  $a_href->setAttribute( 'data-trp-original-href', $url );
@@ -703,8 +753,8 @@ class TRP_Translation_Render{
703
  $row->innertext .= apply_filters( 'trp_form_inputs', '<input type="hidden" name="trp-form-language" value="'. $this->settings['url-slugs'][$TRP_LANGUAGE] .'"/>', $TRP_LANGUAGE, $this->settings['url-slugs'][$TRP_LANGUAGE] );
704
  $form_action = $row->action;
705
 
706
- $is_external_link = $this->is_external_link( $form_action );
707
- $is_admin_link = $this->is_admin_link($form_action );
708
 
709
  if ( !empty($form_action)
710
  && $this->settings['force-language-to-custom-links'] == 'yes'
@@ -728,9 +778,24 @@ class TRP_Translation_Render{
728
  $body->innertext = '<div data-no-translation class="trp-editor-notices">' . $trp_editor_notices . "</div>" . $body->innertext;
729
  }
730
  $final_html = $html->save();
 
 
 
 
731
  return apply_filters( 'trp_translated_html', $final_html, $TRP_LANGUAGE, $language_code );
732
  }
733
 
 
 
 
 
 
 
 
 
 
 
 
734
  /**
735
  * Callback for the array_walk_recursive to translate json. It translates the values in the resulting json array if they contain html
736
  * @param $value
@@ -761,9 +826,10 @@ class TRP_Translation_Render{
761
  * Whether given url links to an external domain.
762
  *
763
  * @param string $url Url.
 
764
  * @return bool Whether given url links to an external domain.
765
  */
766
- public function is_external_link( $url ){
767
  // Abort if parameter URL is empty
768
  if( empty($url) ) {
769
  return false;
@@ -774,7 +840,9 @@ class TRP_Translation_Render{
774
 
775
  // Parse home URL and parameter URL
776
  $link_url = parse_url( $url );
777
- $home_url = parse_url( home_url() );
 
 
778
 
779
  // Decide on target
780
  if( !isset ($link_url['host'] ) || $link_url['host'] == $home_url['host'] ) {
@@ -791,9 +859,10 @@ class TRP_Translation_Render{
791
  * Takes into account http, https, www and all the possible combinations between them.
792
  *
793
  * @param string $url Url.
 
794
  * @return string Correct URL that's the same structure as home_url
795
  */
796
- public function maybe_is_local_url( $url ){
797
 
798
  if ( apply_filters('disable_maybe_is_local_url', false) ){
799
  return $url;
@@ -809,7 +878,9 @@ class TRP_Translation_Render{
809
 
810
  // Parse home URL and parameter URL
811
  $link_url = parse_url( $url );
812
- $home_url = parse_url( home_url() );
 
 
813
 
814
  // Decide on target
815
  if( !isset ($link_url['host'] ) || $link_url['host'] == $home_url['host'] ) {
@@ -860,9 +931,15 @@ class TRP_Translation_Render{
860
  * @param string $url Url.
861
  * @return bool Whether given url links to an admin page.
862
  */
863
- protected function is_admin_link( $url ){
 
 
 
 
 
 
864
 
865
- if ( strpos( $url, admin_url() ) !== false || strpos( $url, wp_login_url() ) !== false ){
866
  return true;
867
  }
868
  return false;
@@ -950,7 +1027,8 @@ class TRP_Translation_Render{
950
  }
951
  }
952
 
953
- $this->trp_query->insert_strings( $new_strings, $update_strings, $language_code, $block_type );
 
954
 
955
  return $translated_strings;
956
  }
@@ -996,6 +1074,18 @@ class TRP_Translation_Render{
996
  return false;
997
  }
998
 
 
 
 
 
 
 
 
 
 
 
 
 
999
  /**
1000
  * Enqueue dynamic translation script.
1001
  */
@@ -1023,12 +1113,12 @@ class TRP_Translation_Render{
1023
  'trp_language_to_query' => $language_to_query,
1024
  'trp_original_language' => $this->settings['default-language'],
1025
  'trp_current_language' => $TRP_LANGUAGE,
1026
- 'trp_skip_selectors' => apply_filters( 'trp_skip_selectors_from_dynamic_translation', array( '[data-no-translation]', '[data-no-dynamic-translation]', '[data-trpgettextoriginal]', '[data-trp-translate-id]' ), $TRP_LANGUAGE, $this->settings )
1027
  );
1028
  if ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) {
1029
  $trp_data['trp_ajax_url'] = $trp_data['trp_wp_ajax_url'];
1030
  }
1031
- wp_enqueue_script('trp-dynamic-translator', TRP_PLUGIN_URL . 'assets/js/trp-translate-dom-changes.js', array('jquery'), TRP_PLUGIN_VERSION );
1032
  wp_localize_script('trp-dynamic-translator', 'trp_data', $trp_data);
1033
  $trp = TRP_Translate_Press::get_trp_instance();
1034
  if ( ! $this->translation_manager ) {
8
  class TRP_Translation_Render{
9
  protected $settings;
10
  protected $machine_translator;
11
+ /* @var TRP_Query */
12
  protected $trp_query;
13
  /* @var TRP_Url_Converter */
14
  protected $url_converter;
71
  // in the translation editor we need a different language then the default because we need string ID's.
72
  // so we're forcing it to the first translation language because if it's the default, we're just returning the $output
73
  if ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) {
74
+ if( count( $this->settings['translation-languages'] ) > 1 ){
75
  foreach ($this->settings['translation-languages'] as $language) {
76
  if ($language != $TRP_LANGUAGE) {
77
  // return the first language not default. only used for preview mode
218
  return preg_replace('/\s+/', ' ', strip_tags( html_entity_decode( htmlspecialchars_decode( trp_full_trim( $string ), ENT_QUOTES ) ) ));
219
  }
220
 
221
+ /**
222
+ * Recursive function that checks if a DOM node contains certain tags or not
223
+ * @param $row
224
+ * @param $tags
225
+ * @return bool
226
+ */
227
+ public function check_children_for_tags( $row, $tags ){
228
+ foreach( $row->children as $child ){
229
+ if( in_array( $child->tag, $tags ) ){
230
+ return true;
231
+ }
232
+ else{
233
+ $this->check_children_for_tags( $child, $tags );
234
+ }
235
+ }
236
+ }
237
+
238
  /**
239
  * Return translation block if matches any existing translation block from db
240
  *
248
  */
249
  public function find_translation_block( $row, $all_existing_translation_blocks, $merge_rules ){
250
  if ( in_array( $row->tag, $merge_rules['top_parents'] ) ){
251
+ //$row->innertext is very intensive on dom nodes that have a lot of children so we try here to eliminate as many as possible here
252
+ // the ideea is that if a dom node contains any top parent tags for blocks it can't be a block itself so we skip it
253
+ $skip = $this->check_children_for_tags( $row, $merge_rules['top_parents'] );
254
+ if( !$skip ) {
255
+ $trimmed_inner_text = $this->trim_translation_block($row->innertext);
256
+ foreach ($all_existing_translation_blocks as $existing_translation_block) {
257
+ if ($existing_translation_block->trimmed_original == $trimmed_inner_text) {
258
+ return $existing_translation_block;
259
+ }
260
+ }
261
+ }
262
  }
263
  return null;
264
  }
375
  $count_translation_blocks = 0;
376
  if ( $translate_normal_strings ) {
377
  $all_existing_translation_blocks = $this->trp_query->get_all_translation_blocks( $language_code );
 
378
  // trim every translation block original now, to avoid over-calling trim function later
379
  foreach ( $all_existing_translation_blocks as $key => $existing_tb ) {
380
  $all_existing_translation_blocks[ $key ]->trimmed_original = $this->trim_translation_block( $all_existing_translation_blocks[ $key ]->original );
381
  }
382
+
383
+ //try to find if there are any blocks on the current page html
384
+ foreach( $all_existing_translation_blocks as $key => $existing_translation_block ){
385
+ if ( strpos( $this->trim_translation_block( $output ), $existing_translation_block->trimmed_original ) === false ){
386
+ unset($all_existing_translation_blocks[$key] );//if it isn't present remove it, this way we don't look for them on pages that don't contain blocks
387
+ }
388
+ }
389
+ $count_translation_blocks = count( $all_existing_translation_blocks );//see here how many remain on the current page
390
+
391
  $merge_rules = $this->translation_manager->get_merge_rules();
392
  }
393
  $html = TranslatePress\str_get_html($output, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
394
+ if ( $html === false ){
395
+ $trpremoved = preg_replace( '/(<|&lt;)trp-gettext (.*?)(>|&gt;)/', '', $output );
396
+ $trpremoved = preg_replace( '/(<|&lt;)(\\\\)*\/trp-gettext(>|&gt;)/', '', $trpremoved );
397
+ return $trpremoved;
398
+ }
399
 
400
  /**
401
  * When we are in the translation editor: Intercept the trp-gettext that was wrapped around all the gettext texts, grab the attribute data-trpgettextoriginal
485
 
486
  // convert to a node
487
  $node_from_value = TranslatePress\str_get_html(html_entity_decode(htmlspecialchars_decode($attr_value, ENT_QUOTES)), true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
488
+ if ( $node_from_value === false ){
489
+ continue;
490
+ }
491
  foreach ($node_from_value->find('trp-gettext') as $nfv_row) {
492
  $nfv_row->outertext = $nfv_row->innertext();
493
  $row->setAttribute($attr_name, $node_from_value->save() );
506
  }
507
  }
508
 
 
 
 
 
 
509
 
510
  if ( ! $translate_normal_strings ) {
511
+ /* save it as a string */
512
+ $trpremoved = $html->save();
513
+ /* perform preg replace on the remaining trp-gettext tags */
514
+ $trpremoved = $this->remove_trp_html_tags($trpremoved );
515
  return $trpremoved;
516
  }
517
 
 
 
518
  $no_translate_selectors = apply_filters( 'trp_no_translate_selectors', array( '#wpadminbar' ), $TRP_LANGUAGE );
519
 
520
  /*
526
  $row->setAttribute( $no_translate_attribute, '' );
527
  }
528
  }
529
+ foreach ( $html->find('.translation-block') as $row ){
530
+ $trimmed_string = trp_full_trim($row->innertext);
531
+ $parent = $row->parent();
532
  if( $trimmed_string!=""
533
+ && $parent->tag!="script"
534
+ && $parent->tag!="style"
535
+ && $parent->tag != 'title'
536
+ && strpos($row->outertext,'[vc_') === false
537
  && !is_numeric($trimmed_string)
538
  && !preg_match('/^\d+%$/',$trimmed_string)
539
+ && !$this->has_ancestor_attribute( $row, $no_translate_attribute ) )
 
 
540
  {
541
+ array_push( $translateable_strings, $trimmed_string );
542
+ array_push( $nodes, array('node' => $row, 'type' => 'block'));
543
  }
544
  }
545
 
546
+ foreach ( $html->find('text') as $row ){
547
+ $outertext = $row->outertext;
548
+ $parent = $row->parent();
549
+ $trimmed_string = trp_full_trim($outertext);
550
  if( $trimmed_string!=""
551
+ && $parent->tag!="script"
552
+ && $parent->tag!="style"
553
+ && $parent->tag != 'title'
554
+ && strpos($outertext,'[vc_') === false
555
  && !is_numeric($trimmed_string)
556
  && !preg_match('/^\d+%$/',$trimmed_string)
557
  && !$this->has_ancestor_attribute( $row, $no_translate_attribute )
558
+ && !$this->has_ancestor_class( $row, 'translation-block') )
 
 
559
  {
560
+ // $translateable_strings array needs to be in sync in $nodes array
561
+ array_push( $translateable_strings, $trimmed_string );
562
+ if( $parent->tag == 'button') {
563
+ array_push($nodes, array('node' => $row, 'type' => 'button'));
564
+ }
565
+ else {
566
+ if ( $parent->tag == 'option' ) {
567
+ array_push( $nodes, array( 'node' => $row, 'type' => 'option' ) );
568
+ } else {
569
+ array_push( $nodes, array( 'node' => $row, 'type' => 'text' ) );
 
570
  }
571
+ }
572
  }
573
  }
574
 
705
 
706
 
707
  // We need to save here in order to access the translated links too.
708
+ if( apply_filters('tp_handle_custom_links_in_translation_blocks', false) ) {
709
+ $html_string = $html->save();
710
+ $html = TranslatePress\str_get_html($html_string, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
711
+ if ( $html === false ){
712
+ return $html_string;
713
+ }
714
+ }
715
+
716
+
717
+ //set up general links variables
718
+ $home_url = home_url();
719
+ $admin_url = admin_url();
720
+ $wp_login_url = wp_login_url();
721
 
722
  // force custom links to have the correct language
723
  foreach( $html->find('a[href!="#"]') as $a_href) {
725
 
726
  $url = $a_href->href;
727
 
728
+ $url = $this->maybe_is_local_url($url, $home_url);
729
 
730
+ $is_external_link = $this->is_external_link( $url, $home_url );
731
+ $is_admin_link = $this->is_admin_link($url, $admin_url, $wp_login_url);
732
 
733
  if( $preview_mode && ! $is_external_link ){
734
  $a_href->setAttribute( 'data-trp-original-href', $url );
753
  $row->innertext .= apply_filters( 'trp_form_inputs', '<input type="hidden" name="trp-form-language" value="'. $this->settings['url-slugs'][$TRP_LANGUAGE] .'"/>', $TRP_LANGUAGE, $this->settings['url-slugs'][$TRP_LANGUAGE] );
754
  $form_action = $row->action;
755
 
756
+ $is_external_link = $this->is_external_link( $form_action, $home_url );
757
+ $is_admin_link = $this->is_admin_link($form_action, $admin_url, $wp_login_url );
758
 
759
  if ( !empty($form_action)
760
  && $this->settings['force-language-to-custom-links'] == 'yes'
778
  $body->innertext = '<div data-no-translation class="trp-editor-notices">' . $trp_editor_notices . "</div>" . $body->innertext;
779
  }
780
  $final_html = $html->save();
781
+
782
+ /* perform preg replace on the remaining trp-gettext tags */
783
+ $final_html = $this->remove_trp_html_tags( $final_html );
784
+
785
  return apply_filters( 'trp_translated_html', $final_html, $TRP_LANGUAGE, $language_code );
786
  }
787
 
788
+ /**
789
+ * function that removes any unwanted leftover <trp-gettext> tags
790
+ * @param $string
791
+ * @return string|string[]|null
792
+ */
793
+ function remove_trp_html_tags( $string ){
794
+ $string = preg_replace( '/(<|&lt;)trp-gettext (.*?)(>|&gt;)/', '', $string );
795
+ $string = preg_replace( '/(<|&lt;)(\\\\)*\/trp-gettext(>|&gt;)/', '', $string );
796
+ return $string;
797
+ }
798
+
799
  /**
800
  * Callback for the array_walk_recursive to translate json. It translates the values in the resulting json array if they contain html
801
  * @param $value
826
  * Whether given url links to an external domain.
827
  *
828
  * @param string $url Url.
829
+ * @param string $home_url Optional home_url so we avoid calling the home_url() inside loops.
830
  * @return bool Whether given url links to an external domain.
831
  */
832
+ public function is_external_link( $url, $home_url = '' ){
833
  // Abort if parameter URL is empty
834
  if( empty($url) ) {
835
  return false;
840
 
841
  // Parse home URL and parameter URL
842
  $link_url = parse_url( $url );
843
+ if( empty( $home_url ) )
844
+ $home_url = home_url();
845
+ $home_url = parse_url( $home_url );
846
 
847
  // Decide on target
848
  if( !isset ($link_url['host'] ) || $link_url['host'] == $home_url['host'] ) {
859
  * Takes into account http, https, www and all the possible combinations between them.
860
  *
861
  * @param string $url Url.
862
+ * @param string $home_url Optional home_url so we avoid calling the home_url() inside loops.
863
  * @return string Correct URL that's the same structure as home_url
864
  */
865
+ public function maybe_is_local_url( $url, $home_url='' ){
866
 
867
  if ( apply_filters('disable_maybe_is_local_url', false) ){
868
  return $url;
878
 
879
  // Parse home URL and parameter URL
880
  $link_url = parse_url( $url );
881
+ if( empty( $home_url ) )
882
+ $home_url = home_url();
883
+ $home_url = parse_url( $home_url );
884
 
885
  // Decide on target
886
  if( !isset ($link_url['host'] ) || $link_url['host'] == $home_url['host'] ) {
931
  * @param string $url Url.
932
  * @return bool Whether given url links to an admin page.
933
  */
934
+ protected function is_admin_link( $url, $admin_url = '', $wp_login_url = '' ){
935
+
936
+ if( empty( $admin_url ) )
937
+ $admin_url = admin_url();
938
+
939
+ if( empty( $wp_login_url ) )
940
+ $wp_login_url = wp_login_url();
941
 
942
+ if ( strpos( $url, $admin_url ) !== false || strpos( $url, $wp_login_url ) !== false ){
943
  return true;
944
  }
945
  return false;
1027
  }
1028
  }
1029
 
1030
+ $this->trp_query->insert_strings( $new_strings, $language_code, $block_type );
1031
+ $this->trp_query->update_strings( $update_strings, $language_code );
1032
 
1033
  return $translated_strings;
1034
  }
1074
  return false;
1075
  }
1076
 
1077
+ /*
1078
+ * Enqueue scripts on all pages
1079
+ */
1080
+ public function enqueue_scripts() {
1081
+
1082
+ // so far only when woocommerce is active we need to enqueue this script on all pages
1083
+ if ( class_exists( 'WooCommerce' ) ){
1084
+ wp_enqueue_script('trp-frontend-compatibility', TRP_PLUGIN_URL . 'assets/js/trp-frontend-compatibility.js', array(), TRP_PLUGIN_VERSION );
1085
+ }
1086
+
1087
+ }
1088
+
1089
  /**
1090
  * Enqueue dynamic translation script.
1091
  */
1113
  'trp_language_to_query' => $language_to_query,
1114
  'trp_original_language' => $this->settings['default-language'],
1115
  'trp_current_language' => $TRP_LANGUAGE,
1116
+ 'trp_skip_selectors' => apply_filters( 'trp_skip_selectors_from_dynamic_translation', array( '[data-no-translation]', '[data-no-dynamic-translation]', '[data-trpgettextoriginal]', '[data-trp-translate-id]', 'script', 'style', 'head' ), $TRP_LANGUAGE, $this->settings )
1117
  );
1118
  if ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) {
1119
  $trp_data['trp_ajax_url'] = $trp_data['trp_wp_ajax_url'];
1120
  }
1121
+ wp_enqueue_script('trp-dynamic-translator', TRP_PLUGIN_URL . 'assets/js/trp-translate-dom-changes.js', array('jquery'), TRP_PLUGIN_VERSION, true );
1122
  wp_localize_script('trp-dynamic-translator', 'trp_data', $trp_data);
1123
  $trp = TRP_Translate_Press::get_trp_instance();
1124
  if ( ! $this->translation_manager ) {
includes/class-upgrade.php CHANGED
@@ -25,7 +25,7 @@ class TRP_Upgrade {
25
  */
26
  public function register_menu_page(){
27
  add_submenu_page( 'TRPHidden', 'TranslatePress Remove Duplicate Rows', 'TRPHidden', 'manage_options', 'trp_remove_duplicate_rows', array($this, 'trp_remove_duplicate_rows') );
28
- add_submenu_page( 'TRPHidden', 'TranslatePress Update Database', 'TRPHidden', 'manage_options', 'trp_update_database', array( $this, 'trp_full_trim_originals' ) );
29
  }
30
 
31
  /**
@@ -43,8 +43,11 @@ class TRP_Upgrade {
43
  $this->trp_query->check_for_block_type_column();
44
  }
45
  if( !empty( $stored_database_version ) ) {
46
- if ( version_compare( '1.4.0', $stored_database_version, '>' ) ) {
47
- update_option( 'trp_updated_database_full_trim_originals_140', 'no' );
 
 
 
48
  }
49
  }
50
 
@@ -66,22 +69,47 @@ class TRP_Upgrade {
66
  }
67
  }
68
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
69
 
70
  /**
71
  * Show admin notice about updating database
72
  */
73
  public function show_admin_notice(){
74
- $option = get_option( 'trp_updated_database_full_trim_originals_140', 'is not set' );
75
- // show admin notice if option is set to false AND we are not on the update database page
76
- if ( $option === 'no' && !( isset( $_GET[ 'page'] ) && $_GET['page'] == 'trp_update_database' ) ){
77
- add_action( 'admin_notices', array( $this, 'admin_notice_update_database_full_trim' ) );
 
 
 
 
 
 
78
  }
79
  }
80
 
81
  /**
82
  * Print admin notice message
83
  */
84
- public function admin_notice_update_database_full_trim() {
 
85
  $url = add_query_arg( array(
86
  'page' => 'trp_update_database',
87
  ), site_url('wp-admin/admin.php') );
@@ -89,148 +117,142 @@ class TRP_Upgrade {
89
  // maybe change notice color to blue #28B1FF
90
  $html = '<div id="message" class="updated">';
91
  $html .= '<p><strong>' . esc_html__( 'TranslatePress data update', 'translatepress-multilingual' ) . '</strong> &#8211; ' . esc_html__( 'We need to update your translations database to the latest version.', 'translatepress-multilingual' ) . '</p>';
92
- $html .= '<p class="submit"><a href="' . esc_url( $url ) . '" class="button-primary">' . esc_html__( 'Run the updater', 'translatepress-multilingual' ) . '</a></p>';
93
  $html .= '</div>';
94
  echo $html;
95
  }
96
 
 
 
 
 
97
  /**
98
- * Remove duplicate rows from DB for trp_dictionary tables.
99
- * Removes untranslated strings if there is a translated version.
100
  *
101
- * Iterates over languages. Each language is iterated in batches of 10 000
102
- *
103
- * Not accessible from anywhere else
104
- * http://example.com/wp-admin/admin.php?page=trp_remove_duplicate_rows
105
  */
106
- public function trp_full_trim_originals(){
107
- $start_time = microtime(true);
108
- if ( ! current_user_can( 'manage_options' ) ){
109
- return;
110
  }
111
- // prepare page structure
112
- require_once TRP_PLUGIN_DIR . 'partials/trp-update-database.php';
113
 
114
- if ( empty( $_GET['trp_updb_lang'] ) ){
115
- // iteration not started
116
- return;
117
- }
118
- if ( $_GET['trp_updb_lang'] === 'done' ){
119
- // iteration finished
120
- $this->print_queried_tables();
121
- echo __( '<p><strong>Successfully updated database!</strong></p>', 'translatepress-multilingual' ) . '<br><a href="' . site_url( 'wp-admin/options-general.php?page=translate-press' ) . '"> <input type="button" value="' . __( 'Back to TranslatePress Settings page', 'translatepress-multilingual' ) . '" class="button-primary"></a>';
122
- return;
123
- }
124
- $nonce = wp_verify_nonce( $_GET['trp_updb_nonce'], 'tpupdatedatabase' );
125
  if ( $nonce === false ){
126
- echo __('Invalid nonce.', 'translatepress-multilingual' ) . '<br><br><a href="' . site_url('wp-admin/options-general.php?page=translate-press') . '"> <input type="button" value="' . __('Back to TranslatePress Settings page', 'translatepress-multilingual' ) . '" class="button-primary"></a>';
127
- return;
128
  }
129
 
130
- $next_get_batch = 0;
131
- $batch_size = apply_filters( 'trp_updb_batch_size', 200 );
132
- if ( !empty( $_GET['trp_updb_batch_size'] ) && (int) $_GET['trp_updb_batch'] >= 0 ){
133
- $batch_size = (int) $_GET['trp_updb_batch_size'];
134
- }
135
- if ( in_array( $_GET['trp_updb_lang'], $this->settings['translation-languages'] ) ) {
136
- // language code found in array
137
- $language_code = $_GET['trp_updb_lang'];
138
- // skip default language since it doesn't have a table
139
- $finished_with_language = true;
140
- if ( $language_code != $this->settings['default-language'] ) {
141
- if ( ! $this->trp_query ) {
142
- $trp = TRP_Translate_Press::get_trp_instance();
143
- /* @var TRP_Query */
144
- $this->trp_query = $trp->get_component( 'query' );
145
- }
146
-
147
- if ( !empty( $_GET['trp_updb_batch'] ) && (int) $_GET['trp_updb_batch'] > 0 ) {
148
- $get_batch = (int)$_GET['trp_updb_batch'];
149
- }else{
150
- $get_batch = 0;
151
- }
152
-
153
- $this->print_queried_tables( $language_code );
154
-
155
- $start_time = microtime(true);
156
- $duration = 0;
157
- while( $duration < 2 ){
158
- $inferior_limit = $batch_size * $get_batch;
159
- $finished_with_language = $this->execute_full_trim( $language_code, $inferior_limit, $batch_size );
160
- if ( $finished_with_language ) {
161
- break;
162
- }else {
163
- $get_batch = $get_batch + 1;
164
- }
165
- $stop_time = microtime( true );
166
- $duration = $stop_time - $start_time;
167
- }
168
- if ( ! $finished_with_language ) {
169
- $next_get_batch = $get_batch + 1;
170
  }
171
  }
172
-
173
- if ( $finished_with_language ) {
174
- // finished with the current language
175
- $index = array_search( $language_code, $this->settings['translation-languages'] );
176
- if ( isset ( $this->settings['translation-languages'][ $index + 1 ] ) ) {
177
- // next language code in array
178
- $next_language = $this->settings['translation-languages'][ $index + 1 ];
179
- } else {
180
- // finish iteration due to completing all the translation languages
181
- $next_language = 'done';
182
- // this will stop showing the admin notice
183
- update_option( 'trp_updated_database_full_trim_originals_140', 'yes' );
184
- }
185
  }else{
186
- $next_language = $language_code;
 
 
 
187
  }
188
  }else{
189
- // finish iteration due to incorrect translation language
190
- $next_language = 'done';
 
 
 
 
191
  }
192
 
193
- // construct and redirect to next url
194
- $url = add_query_arg( array(
195
- 'page' => 'trp_update_database',
196
- 'trp_updb_lang' => $next_language,
197
- 'trp_updb_batch' => $next_get_batch,
198
- 'trp_updb_batch_size' => $batch_size,
199
- 'trp_updb_nonce' => wp_create_nonce('tpupdatedatabase')
200
- ), site_url('wp-admin/admin.php') );
201
- echo "<meta http-equiv='refresh' content='0; url={$url}' />";
202
- echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
203
- exit;
204
- }
205
 
206
- /**
207
- * Prints all the tables in the translation languages array until the current language with Done.
208
- *
209
- * If current language is given, do not print Done for it.
210
- *
211
- * @param bool | string $current_language_code
212
- */
213
- public function print_queried_tables( $current_language_code = false ){
214
  if ( ! $this->trp_query ) {
215
  $trp = TRP_Translate_Press::get_trp_instance();
216
  /* @var TRP_Query */
217
  $this->trp_query = $trp->get_component( 'query' );
218
  }
219
- foreach ( $this->settings['translation-languages'] as $language_code ){
220
- if ( $language_code == $this->settings['default-language'] ){
221
- continue;
222
- }
223
- $table_name = $this->trp_query->get_table_name( $language_code );
224
- $html = '<div>' . sprintf( __( 'Querying table <strong>%s</strong>... ', 'translatepress-multilingual' ), $table_name );
225
- if ( $language_code != $current_language_code ) {
226
- $html .= __( 'Done.', 'translatepress-multilingual' );
227
- }
228
- $html .= '</div>';
229
- echo $html;
230
- if ( $language_code == $current_language_code ) {
231
  break;
 
 
232
  }
 
 
233
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  }
235
 
236
  /**
@@ -242,12 +264,16 @@ class TRP_Upgrade {
242
  *
243
  * @return bool
244
  */
245
- public function execute_full_trim( $language_code, $inferior_limit, $batch_size ){
246
  if ( ! $this->trp_query ) {
247
  $trp = TRP_Translate_Press::get_trp_instance();
248
  /* @var TRP_Query */
249
  $this->trp_query = $trp->get_component( 'query' );
250
  }
 
 
 
 
251
  $strings = $this->trp_query->get_rows_from_location( $language_code, $inferior_limit, $batch_size, array( 'id', 'original' ) );
252
  if ( count( $strings ) == 0 ) {
253
  return true;
@@ -257,10 +283,33 @@ class TRP_Upgrade {
257
  }
258
 
259
  // overwrite original only
260
- $this->trp_query->update_strings( $strings, $language_code, array( 'id', 'original' ), array( '%d', '%s' ) );
261
  return false;
262
  }
263
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  /**
265
  * Remove duplicate rows from DB for trp_dictionary tables.
266
  * Removes untranslated strings if there is a translated version.
@@ -371,4 +420,17 @@ class TRP_Upgrade {
371
  echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
372
  exit;
373
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
374
  }
25
  */
26
  public function register_menu_page(){
27
  add_submenu_page( 'TRPHidden', 'TranslatePress Remove Duplicate Rows', 'TRPHidden', 'manage_options', 'trp_remove_duplicate_rows', array($this, 'trp_remove_duplicate_rows') );
28
+ add_submenu_page( 'TRPHidden', 'TranslatePress Update Database', 'TRPHidden', 'manage_options', 'trp_update_database', array( $this, 'trp_update_database_page' ) );
29
  }
30
 
31
  /**
43
  $this->trp_query->check_for_block_type_column();
44
  }
45
  if( !empty( $stored_database_version ) ) {
46
+ $updates = $this->get_updates_details();
47
+ foreach( $updates as $update ){
48
+ if ( version_compare( $update['version'], $stored_database_version, '>' ) ){
49
+ update_option( $update['option_name'], 'no' );
50
+ }
51
  }
52
  }
53
 
69
  }
70
  }
71
 
72
+ public function get_updates_details(){
73
+ return apply_filters( 'trp_updates_details',
74
+ array(
75
+ 'full_trim_originals_140' => array(
76
+ 'version' => '1.4.0',
77
+ 'option_name' => 'trp_updated_database_full_trim_originals_140',
78
+ 'callback' => array( $this, 'trp_updated_database_full_trim_originals_140' ),
79
+ 'batch_size' => 200
80
+ ),
81
+ 'gettext_empty_rows_145' => array(
82
+ 'version' => '1.4.5',
83
+ 'option_name' => 'trp_updated_database_gettext_empty_rows_145',
84
+ 'callback' => array( $this,'trp_updated_database_gettext_empty_rows_145'),
85
+ 'batch_size' => 20000
86
+ )
87
+ )
88
+ );
89
+ }
90
 
91
  /**
92
  * Show admin notice about updating database
93
  */
94
  public function show_admin_notice(){
95
+ if ( ( isset( $_GET[ 'page'] ) && $_GET['page'] == 'trp_update_database' ) ){
96
+ return;
97
+ }
98
+ $updates_needed = $this->get_updates_details();
99
+ foreach( $updates_needed as $update ){
100
+ $option = get_option( $update['option_name'], 'is not set' );
101
+ if ( $option === 'no' ){
102
+ add_action( 'admin_notices', array( $this, 'admin_notice_update_database' ) );
103
+ break;
104
+ }
105
  }
106
  }
107
 
108
  /**
109
  * Print admin notice message
110
  */
111
+ public function admin_notice_update_database() {
112
+
113
  $url = add_query_arg( array(
114
  'page' => 'trp_update_database',
115
  ), site_url('wp-admin/admin.php') );
117
  // maybe change notice color to blue #28B1FF
118
  $html = '<div id="message" class="updated">';
119
  $html .= '<p><strong>' . esc_html__( 'TranslatePress data update', 'translatepress-multilingual' ) . '</strong> &#8211; ' . esc_html__( 'We need to update your translations database to the latest version.', 'translatepress-multilingual' ) . '</p>';
120
+ $html .= '<p class="submit"><a href="' . esc_url( $url ) . '" onclick="return confirm( \'' . __( 'IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?', 'translatepress-multilingual' ) . '\');" class="button-primary">' . esc_html__( 'Run the updater', 'translatepress-multilingual' ) . '</a></p>';
121
  $html .= '</div>';
122
  echo $html;
123
  }
124
 
125
+ public function trp_update_database_page(){
126
+ require_once TRP_PLUGIN_DIR . 'partials/trp-update-database.php';
127
+ }
128
+
129
  /**
130
+ * Call all functions to update database
 
131
  *
132
+ * hooked to wp_ajax_trp_update_database
 
 
 
133
  */
134
+ public function trp_update_database(){
135
+ if ( ! current_user_can( apply_filters('trp_update_database_capability', 'manage_options') ) ){
136
+ $this->stop_and_print_error( __('Update aborted! Your user account doesn\'t have the capability to perform database updates.', 'translatepress-multilingual' ) );
 
137
  }
 
 
138
 
139
+ $nonce = wp_verify_nonce( $_REQUEST['trp_updb_nonce'], 'tpupdatedatabase' );
 
 
 
 
 
 
 
 
 
 
140
  if ( $nonce === false ){
141
+ $this->stop_and_print_error( __('Update aborted! Invalid nonce.', 'translatepress-multilingual' ) );
 
142
  }
143
 
144
+ $request = array();
145
+ $request['progress_message'] = '';
146
+ $updates_needed = $this->get_updates_details();
147
+ if ( empty ( $_REQUEST['trp_updb_action'] ) ){
148
+ foreach( $updates_needed as $update_action_key => $update ) {
149
+ $option = get_option( $update['option_name'], 'is not set' );
150
+ if ( $option === 'no' ) {
151
+ $_REQUEST['trp_updb_action'] = $update_action_key;
152
+ break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
153
  }
154
  }
155
+ if ( empty ( $_REQUEST['trp_updb_action'] ) ){
156
+ $back_to_settings_button = '<p><a href="' . site_url('wp-admin/options-general.php?page=translate-press') . '"> <input type="button" value="' . __('Back to TranslatePress Settings page', 'translatepress-multilingual' ) . '" class="button-primary"></a></p>';
157
+ // finished successfully
158
+ echo json_encode( array(
159
+ 'trp_update_completed' => 'yes',
160
+ 'progress_message' => '<p><strong>' . __('Successfully updated database!', 'translatepress-multilingual' ) . '</strong></p>' . $back_to_settings_button
161
+ ));
162
+ wp_die();
 
 
 
 
 
163
  }else{
164
+ $_REQUEST['trp_updb_lang'] = $this->settings['translation-languages'][0];
165
+ $_REQUEST['trp_updb_batch'] = 0;
166
+ $request['progress_message'] .= '<p>' . sprintf(__('Updating database to version %s+', 'translatepress-multilingual' ), $updates_needed[ $_REQUEST['trp_updb_action'] ]['version'] ). '</p>';
167
+ $request['progress_message'] .= sprintf(__('Processing table for language %s...', 'translatepress-multilingual' ), $_REQUEST['trp_updb_lang'] );
168
  }
169
  }else{
170
+ if ( !isset( $updates_needed[ $_REQUEST['trp_updb_action'] ] ) ){
171
+ $this->stop_and_print_error( __('Update aborted! Incorrect action.', 'translatepress-multilingual' ) );
172
+ }
173
+ if ( !in_array( $_REQUEST['trp_updb_lang'], $this->settings['translation-languages'] ) ) {
174
+ $this->stop_and_print_error( __('Update aborted! Incorrect language code.', 'translatepress-multilingual' ) );
175
+ }
176
  }
177
 
178
+ $request['trp_updb_action'] = $_REQUEST['trp_updb_action'];
179
+ if ( !empty( $_REQUEST['trp_updb_batch'] ) && (int) $_REQUEST['trp_updb_batch'] > 0 ) {
180
+ $get_batch = (int)$_REQUEST['trp_updb_batch'];
181
+ }else{
182
+ $get_batch = 0;
183
+ }
184
+
185
+ $request['trp_updb_batch'] = 0;
186
+ $update_details = $updates_needed[$_REQUEST['trp_updb_action']];
187
+ $batch_size = apply_filters( 'trp_updb_batch_size', $update_details['batch_size'], $_REQUEST['trp_updb_action'], $update_details );
188
+ $language_code = $_REQUEST['trp_updb_lang'];
 
189
 
 
 
 
 
 
 
 
 
190
  if ( ! $this->trp_query ) {
191
  $trp = TRP_Translate_Press::get_trp_instance();
192
  /* @var TRP_Query */
193
  $this->trp_query = $trp->get_component( 'query' );
194
  }
195
+
196
+ $start_time = microtime(true);
197
+ $duration = 0;
198
+ while( $duration < 2 ){
199
+ $inferior_limit = $batch_size * $get_batch;
200
+ $finished_with_language = call_user_func( $update_details['callback'], $language_code, $inferior_limit, $batch_size );
201
+
202
+ if ( $finished_with_language ) {
 
 
 
 
203
  break;
204
+ }else {
205
+ $get_batch = $get_batch + 1;
206
  }
207
+ $stop_time = microtime( true );
208
+ $duration = $stop_time - $start_time;
209
  }
210
+ if ( ! $finished_with_language ) {
211
+ $request['trp_updb_batch'] = $get_batch + 1;
212
+ }
213
+
214
+
215
+ if ( $finished_with_language ) {
216
+ // finished with the current language
217
+ $index = array_search( $language_code, $this->settings['translation-languages'] );
218
+ if ( isset ( $this->settings['translation-languages'][ $index + 1 ] ) ) {
219
+ // next language code in array
220
+ $request['trp_updb_lang'] = $this->settings['translation-languages'][ $index + 1 ];
221
+ $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
222
+ $request['progress_message'] .= '</br>' . sprintf(__('Processing table for language %s...', 'translatepress-multilingual' ), $request['trp_updb_lang'] );
223
+ } else {
224
+ // finish action due to completing all the translation languages
225
+ $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
226
+ $request['trp_updb_lang'] = '';
227
+ // this will stop showing the admin notice
228
+ update_option( $update_details['option_name'], 'yes' );
229
+ $request['trp_updb_action'] = '';
230
+ }
231
+ }else{
232
+ $request['trp_updb_lang'] = $language_code;
233
+ }
234
+
235
+ $query_arguments = array(
236
+ 'action' => 'trp_update_database',
237
+ 'trp_updb_action' => $request['trp_updb_action'],
238
+ 'trp_updb_lang' => $request['trp_updb_lang'],
239
+ 'trp_updb_batch' => $request['trp_updb_batch'],
240
+ 'trp_updb_nonce' => wp_create_nonce('tpupdatedatabase'),
241
+ 'trp_update_completed' => 'no',
242
+ 'progress_message' => $request['progress_message']
243
+ );
244
+ echo( json_encode( $query_arguments ));
245
+ wp_die();
246
+ }
247
+
248
+ public function stop_and_print_error( $error_message ){
249
+ $back_to_settings_button = '<p><a href="' . site_url('wp-admin/options-general.php?page=translate-press') . '"> <input type="button" value="' . __('Back to TranslatePress Settings page', 'translatepress-multilingual' ) . '" class="button-primary"></a></p>';
250
+ $query_arguments = array(
251
+ 'trp_update_completed' => 'yes',
252
+ 'progress_message' => '<p><strong>' . $error_message . '</strong></strong></p>' . $back_to_settings_button
253
+ );
254
+ echo( json_encode( $query_arguments ));
255
+ wp_die();
256
  }
257
 
258
  /**
264
  *
265
  * @return bool
266
  */
267
+ public function trp_updated_database_full_trim_originals_140( $language_code, $inferior_limit, $batch_size ){
268
  if ( ! $this->trp_query ) {
269
  $trp = TRP_Translate_Press::get_trp_instance();
270
  /* @var TRP_Query */
271
  $this->trp_query = $trp->get_component( 'query' );
272
  }
273
+ if ( $language_code == $this->settings['default-language']){
274
+ // default language doesn't have a dictionary table
275
+ return true;
276
+ }
277
  $strings = $this->trp_query->get_rows_from_location( $language_code, $inferior_limit, $batch_size, array( 'id', 'original' ) );
278
  if ( count( $strings ) == 0 ) {
279
  return true;
283
  }
284
 
285
  // overwrite original only
286
+ $this->trp_query->update_strings_by_columns( $strings, $language_code, array( 'id', 'original' ), array( '%d', '%s' ) );
287
  return false;
288
  }
289
 
290
+ /**
291
+ * Delete all empty gettext rows
292
+ *
293
+ * @param string $language_code Language code of the table
294
+ * @param int $inferior_limit Omit first X rows
295
+ * @param int $batch_size How many rows to query
296
+ *
297
+ * @return bool
298
+ */
299
+ public function trp_updated_database_gettext_empty_rows_145( $language_code, $inferior_limit, $batch_size ){
300
+ if ( ! $this->trp_query ) {
301
+ $trp = TRP_Translate_Press::get_trp_instance();
302
+ /* @var TRP_Query */
303
+ $this->trp_query = $trp->get_component( 'query' );
304
+ }
305
+ $rows_affected = $this->trp_query->delete_empty_gettext_strings( $language_code, $batch_size );
306
+ if ( $rows_affected > 0 ){
307
+ return false;
308
+ }else{
309
+ return true;
310
+ }
311
+ }
312
+
313
  /**
314
  * Remove duplicate rows from DB for trp_dictionary tables.
315
  * Removes untranslated strings if there is a translated version.
420
  echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
421
  exit;
422
  }
423
+
424
+ public function enqueue_update_script( $hook ) {
425
+ if ( $hook === 'admin_page_trp_update_database' ) {
426
+ wp_enqueue_script( 'trp-update-database', TRP_PLUGIN_URL . 'assets/js/trp-update-database.js', array(
427
+ 'jquery',
428
+ ), TRP_PLUGIN_VERSION );
429
+ }
430
+
431
+ wp_localize_script( 'trp-update-database', 'trp_updb_localized ', array(
432
+ 'admin_ajax_url' => admin_url( 'admin-ajax.php' ),
433
+ 'nonce' => wp_create_nonce('tpupdatedatabase')
434
+ ) );
435
+ }
436
  }
includes/class-url-converter.php CHANGED
@@ -36,10 +36,9 @@ class TRP_Url_Converter {
36
  return $url;
37
  }
38
 
39
- if( is_customize_preview() || $this->is_admin_request() )
40
  return $url;
41
 
42
-
43
  $url_slug = $this->get_url_slug( $TRP_LANGUAGE );
44
  $abs_home = $this->get_abs_home();
45
  $new_url = trailingslashit( trailingslashit( $abs_home ) . $url_slug );
@@ -94,6 +93,28 @@ class TRP_Url_Converter {
94
  }
95
  }
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  /**
98
  * Add Hreflang entries for each language to Header.
99
  */
@@ -301,12 +322,24 @@ class TRP_Url_Converter {
301
  $english_woocommerce_slugs = array('product-category', 'product-tag', 'product');
302
  foreach ($english_woocommerce_slugs as $english_woocommerce_slug){
303
  // current woo slugs are based on the localized default language OR the current language
304
- $current_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $this->settings['default-language'] );
 
 
 
 
305
  if( strpos($new_url, '/'.$current_slug.'/') === false){
306
- $current_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $TRP_LANGUAGE );
 
 
 
 
307
  }
308
 
309
- $translated_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $language );
 
 
 
 
310
  $new_url = str_replace( '/'.$current_slug.'/', '/'.$translated_slug.'/', $new_url );
311
  }
312
  }
@@ -504,17 +537,27 @@ class TRP_Url_Converter {
504
  global $default_language_wc_permalink_structure; //we use a global because apparently you can't do switch to locale and restore multiple times. I should keep an eye on this
505
  /* get rewrite rules from original language */
506
  if( empty($default_language_wc_permalink_structure) ) {
507
- $default_language_wc_permalink_structure = array();
508
- $default_language_wc_permalink_structure['product_rewrite_slug'] = trp_x( 'product', 'slug', 'woocommerce', $this->settings['default-language'] );
509
- $default_language_wc_permalink_structure['category_rewrite_slug'] = trp_x( 'product-category', 'slug', 'woocommerce', $this->settings['default-language'] );
510
- $default_language_wc_permalink_structure['tag_rewrite_slug'] = trp_x( 'product-tag', 'slug', 'woocommerce', $this->settings['default-language'] );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  }
512
-
513
- //always generate the slugs for defaults on the current language
514
- $current_language_permalink_structure = array();
515
- $current_language_permalink_structure['product_rewrite_slug'] = trp_x( 'product', 'slug', 'woocommerce', $TRP_LANGUAGE );
516
- $current_language_permalink_structure['category_rewrite_slug'] = trp_x( 'product-category', 'slug', 'woocommerce', $TRP_LANGUAGE );
517
- $current_language_permalink_structure['tag_rewrite_slug'] = trp_x( 'product-tag', 'slug', 'woocommerce', $TRP_LANGUAGE );
518
 
519
 
520
  $new_rewrite_rules = array();
36
  return $url;
37
  }
38
 
39
+ if( is_customize_preview() || $this->is_admin_request() || $this->is_sitemap_link( $path ) )
40
  return $url;
41
 
 
42
  $url_slug = $this->get_url_slug( $TRP_LANGUAGE );
43
  $abs_home = $this->get_abs_home();
44
  $new_url = trailingslashit( trailingslashit( $abs_home ) . $url_slug );
93
  }
94
  }
95
 
96
+ /**
97
+ * A function that is used inside the home_url filter to detect if the current link is a sitemap link
98
+ * @param $path the path that is passed inside home_url
99
+ * @return bool
100
+ */
101
+ public function is_sitemap_link( $path ) {
102
+
103
+ //we first check in the $path
104
+ if( !empty( $path ) ){
105
+ if( strpos($path, 'sitemap') !== false && strpos($path, '.xml') !== false )
106
+ return true;
107
+ else
108
+ return false;
109
+ }
110
+ else { //if the path is empty check the request URI
111
+ if (strpos( $_SERVER['REQUEST_URI'], 'sitemap') !== false && strpos( $_SERVER['REQUEST_URI'], '.xml') !== false)
112
+ return true;
113
+ }
114
+
115
+ return false;
116
+ }
117
+
118
  /**
119
  * Add Hreflang entries for each language to Header.
120
  */
322
  $english_woocommerce_slugs = array('product-category', 'product-tag', 'product');
323
  foreach ($english_woocommerce_slugs as $english_woocommerce_slug){
324
  // current woo slugs are based on the localized default language OR the current language
325
+ $current_slug = get_transient( 'tp_'.$english_woocommerce_slug.'_'. $this->settings['default-language'] );
326
+ if( $current_slug === false ){
327
+ $current_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $this->settings['default-language'] );
328
+ set_transient( 'tp_'.$english_woocommerce_slug.'_'. $this->settings['default-language'], $current_slug, 12 * HOUR_IN_SECONDS );
329
+ }
330
  if( strpos($new_url, '/'.$current_slug.'/') === false){
331
+ $current_slug = get_transient( 'tp_'.$english_woocommerce_slug.'_'. $TRP_LANGUAGE );
332
+ if( $current_slug === false ){
333
+ $current_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $TRP_LANGUAGE );
334
+ set_transient( 'tp_'.$english_woocommerce_slug.'_'. $TRP_LANGUAGE, $current_slug, 12 * HOUR_IN_SECONDS );
335
+ }
336
  }
337
 
338
+ $translated_slug = get_transient( 'tp_'.$english_woocommerce_slug.'_'. $language );
339
+ if( $current_slug === false ){
340
+ $translated_slug = trp_x( $english_woocommerce_slug, 'slug', 'woocommerce', $language );
341
+ set_transient( 'tp_'.$english_woocommerce_slug.'_'. $language, $translated_slug, 12 * HOUR_IN_SECONDS );
342
+ }
343
  $new_url = str_replace( '/'.$current_slug.'/', '/'.$translated_slug.'/', $new_url );
344
  }
345
  }
537
  global $default_language_wc_permalink_structure; //we use a global because apparently you can't do switch to locale and restore multiple times. I should keep an eye on this
538
  /* get rewrite rules from original language */
539
  if( empty($default_language_wc_permalink_structure) ) {
540
+ $default_language_wc_permalink_structure = get_transient( 'tp_default_language_wc_permalink_structure_'.$this->settings['default-language'] );
541
+ if( $default_language_wc_permalink_structure === false ) {
542
+ $default_language_wc_permalink_structure = array();
543
+ $default_language_wc_permalink_structure['product_rewrite_slug'] = trp_x('product', 'slug', 'woocommerce', $this->settings['default-language']);
544
+ $default_language_wc_permalink_structure['category_rewrite_slug'] = trp_x('product-category', 'slug', 'woocommerce', $this->settings['default-language']);
545
+ $default_language_wc_permalink_structure['tag_rewrite_slug'] = trp_x('product-tag', 'slug', 'woocommerce', $this->settings['default-language']);
546
+
547
+ set_transient('tp_default_language_wc_permalink_structure_' . $this->settings['default-language'], $default_language_wc_permalink_structure, 12 * HOUR_IN_SECONDS);
548
+ }
549
+ }
550
+
551
+ $current_language_permalink_structure = get_transient( 'tp_current_language_permalink_structure_'.$TRP_LANGUAGE );
552
+ if( $current_language_permalink_structure === false ) {
553
+ //always generate the slugs for defaults on the current language
554
+ $current_language_permalink_structure = array();
555
+ $current_language_permalink_structure['product_rewrite_slug'] = trp_x('product', 'slug', 'woocommerce', $TRP_LANGUAGE);
556
+ $current_language_permalink_structure['category_rewrite_slug'] = trp_x('product-category', 'slug', 'woocommerce', $TRP_LANGUAGE);
557
+ $current_language_permalink_structure['tag_rewrite_slug'] = trp_x('product-tag', 'slug', 'woocommerce', $TRP_LANGUAGE);
558
+
559
+ set_transient( 'tp_current_language_permalink_structure_'.$TRP_LANGUAGE, $current_language_permalink_structure, 12 * HOUR_IN_SECONDS );
560
  }
 
 
 
 
 
 
561
 
562
 
563
  $new_rewrite_rules = array();
includes/functions.php CHANGED
@@ -673,6 +673,15 @@ function trp_woo_notes_strip_trpst( $note_array ){
673
  return $note_array;
674
  }
675
 
 
 
 
 
 
 
 
 
 
676
  /**
677
  * Compatibility with WooCommerce country list on checkout.
678
  *
@@ -683,4 +692,17 @@ add_filter( 'trp_skip_selectors_from_dynamic_translation', 'trp_woo_skip_dynamic
683
  function trp_woo_skip_dynamic_translation( $skip_selectors ){
684
  $add_skip_selectors = array( '#select2-billing_country-results', '#select2-shipping_country-results' );
685
  return array_merge( $skip_selectors, $add_skip_selectors );
686
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
673
  return $note_array;
674
  }
675
 
676
+ /*
677
+ * Compatibility with WooCommerce back-end display order shipping taxes
678
+ */
679
+ add_filter('woocommerce_order_item_display_meta_key','trp_woo_data_strip_trpst');
680
+ add_filter('woocommerce_order_item_get_method_title','trp_woo_data_strip_trpst');
681
+ function trp_woo_data_strip_trpst( $data ){
682
+ return TRP_Translation_Manager::strip_gettext_tags( $data );
683
+ }
684
+
685
  /**
686
  * Compatibility with WooCommerce country list on checkout.
687
  *
692
  function trp_woo_skip_dynamic_translation( $skip_selectors ){
693
  $add_skip_selectors = array( '#select2-billing_country-results', '#select2-shipping_country-results' );
694
  return array_merge( $skip_selectors, $add_skip_selectors );
695
+ }
696
+
697
+ /**
698
+ * Compatibility with WooCommerce product variation.
699
+ *
700
+ * Add span tag to woocommerce product variation name.
701
+ *
702
+ * Product variation name keep changes, but the prefix is the same. Wrap the prefix to allow translating that part separately.
703
+ */
704
+ add_filter( 'woocommerce_product_variation_title', 'trp_woo_wrap_variation', 8, 4);
705
+ function trp_woo_wrap_variation($name, $product, $title_base, $title_suffix){
706
+ $separator = '<span> - </span>';
707
+ return $title_suffix ? $title_base . $separator . $title_suffix : $title_base;
708
+ }
index.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: TranslatePress - Multilingual
4
  Plugin URI: https://translatepress.com/
5
  Description: Experience a better way of translating your WordPress site, with full support for WooCommerce and site builders.
6
- Version: 1.4.4
7
  Author: Cozmoslabs, Razvan Mocanu, Madalin Ungureanu, Cristophor Hurduban
8
  Author URI: https://cozmoslabs.com/
9
  Text Domain: translatepress-multilingual
3
  Plugin Name: TranslatePress - Multilingual
4
  Plugin URI: https://translatepress.com/
5
  Description: Experience a better way of translating your WordPress site, with full support for WooCommerce and site builders.
6
+ Version: 1.4.5
7
  Author: Cozmoslabs, Razvan Mocanu, Madalin Ungureanu, Cristophor Hurduban
8
  Author URI: https://cozmoslabs.com/
9
  Text Domain: translatepress-multilingual
languages/translatepress-multilingual.catalog.php CHANGED
@@ -60,16 +60,23 @@
60
  <?php __("Page Title", "translatepress-multilingual"); ?>
61
  <?php __("TranslatePress data update", "translatepress-multilingual"); ?>
62
  <?php __("We need to update your translations database to the latest version.", "translatepress-multilingual"); ?>
 
63
  <?php __("Run the updater", "translatepress-multilingual"); ?>
64
- <?php __("<p><strong>Successfully updated database!</strong></p>", "translatepress-multilingual"); ?>
 
65
  <?php __("Back to TranslatePress Settings page", "translatepress-multilingual"); ?>
66
- <?php __("Invalid nonce.", "translatepress-multilingual"); ?>
67
- <?php __("If the page does not redirect automatically", "translatepress-multilingual"); ?>
68
- <?php __("click here", "translatepress-multilingual"); ?>
69
- <?php __("Querying table <strong>%s</strong>... ", "translatepress-multilingual"); ?>
 
 
70
  <?php __("Done.", "translatepress-multilingual"); ?>
 
71
  <?php __("Querying table <strong>%s</strong>", "translatepress-multilingual"); ?>
72
  <?php __("%s duplicates removed", "translatepress-multilingual"); ?>
 
 
73
  <?php __("<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server.", "translatepress-multilingual"); ?>
74
  <?php __("Select the language you wish to make your website available in.", "translatepress-multilingual"); ?>
75
  <?php __("To add <strong>more then two languages</strong> and support for SEO Title, Description, Slug and more check out <a href=\"%s\" class=\"button button-primary\" target=\"_blank\" title=\"TranslatePress Pro\">TranslatePress PRO</a>", "translatepress-multilingual"); ?>
@@ -140,13 +147,11 @@
140
  <?php __("Find Out More", "translatepress-multilingual"); ?>
141
  <?php __("Remove duplicate rows from TranslatePress tables", "translatepress-multilingual"); ?>
142
  <?php __("<strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong><br><br>This feature can be used to cleanup duplicate entries in TranslatePress trp_dictionary tables. Such duplicates can appear in exceptional situations of unexpected behavior.", "translatepress-multilingual"); ?>
143
- <?php __("IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?", "translatepress-multilingual"); ?>
144
  <?php __("Batch size", "translatepress-multilingual"); ?>
145
  <?php __("The number of rows to check at once.<br>Choosing a smaller number helps solve the 502 error \"Page took too long to respond\" on large databases.<br>May take several minutes depending on the database size.", "translatepress-multilingual"); ?>
146
  <?php __("Remove duplicate rows", "translatepress-multilingual"); ?>
147
- <?php __("Update TranslatePress tables", "translatepress-multilingual"); ?>
148
- <?php __("<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>", "translatepress-multilingual"); ?>
149
- <?php __("Update database", "translatepress-multilingual"); ?>
150
  <?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
151
  <?php __("Translator", "translatepress-multilingual"); ?>
152
  <?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
60
  <?php __("Page Title", "translatepress-multilingual"); ?>
61
  <?php __("TranslatePress data update", "translatepress-multilingual"); ?>
62
  <?php __("We need to update your translations database to the latest version.", "translatepress-multilingual"); ?>
63
+ <?php __("IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?", "translatepress-multilingual"); ?>
64
  <?php __("Run the updater", "translatepress-multilingual"); ?>
65
+ <?php __("Update aborted! Your user account doesn't have the capability to perform database updates.", "translatepress-multilingual"); ?>
66
+ <?php __("Update aborted! Invalid nonce.", "translatepress-multilingual"); ?>
67
  <?php __("Back to TranslatePress Settings page", "translatepress-multilingual"); ?>
68
+ <?php __("Successfully updated database!", "translatepress-multilingual"); ?>
69
+ <?php __("Updating database to version %s+", "translatepress-multilingual"); ?>
70
+ <?php __("Processing table for language %s...", "translatepress-multilingual"); ?>
71
+ <?php __("Update aborted! Incorrect action.", "translatepress-multilingual"); ?>
72
+ <?php __("Update aborted! Incorrect language code.", "translatepress-multilingual"); ?>
73
+ <?php __(" done.", "translatepress-multilingual"); ?>
74
  <?php __("Done.", "translatepress-multilingual"); ?>
75
+ <?php __("Invalid nonce.", "translatepress-multilingual"); ?>
76
  <?php __("Querying table <strong>%s</strong>", "translatepress-multilingual"); ?>
77
  <?php __("%s duplicates removed", "translatepress-multilingual"); ?>
78
+ <?php __("If the page does not redirect automatically", "translatepress-multilingual"); ?>
79
+ <?php __("click here", "translatepress-multilingual"); ?>
80
  <?php __("<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server.", "translatepress-multilingual"); ?>
81
  <?php __("Select the language you wish to make your website available in.", "translatepress-multilingual"); ?>
82
  <?php __("To add <strong>more then two languages</strong> and support for SEO Title, Description, Slug and more check out <a href=\"%s\" class=\"button button-primary\" target=\"_blank\" title=\"TranslatePress Pro\">TranslatePress PRO</a>", "translatepress-multilingual"); ?>
147
  <?php __("Find Out More", "translatepress-multilingual"); ?>
148
  <?php __("Remove duplicate rows from TranslatePress tables", "translatepress-multilingual"); ?>
149
  <?php __("<strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong><br><br>This feature can be used to cleanup duplicate entries in TranslatePress trp_dictionary tables. Such duplicates can appear in exceptional situations of unexpected behavior.", "translatepress-multilingual"); ?>
 
150
  <?php __("Batch size", "translatepress-multilingual"); ?>
151
  <?php __("The number of rows to check at once.<br>Choosing a smaller number helps solve the 502 error \"Page took too long to respond\" on large databases.<br>May take several minutes depending on the database size.", "translatepress-multilingual"); ?>
152
  <?php __("Remove duplicate rows", "translatepress-multilingual"); ?>
153
+ <?php __("TranslatePress Database Updater", "translatepress-multilingual"); ?>
154
+ <?php __("Updating TranslatePress tables", "translatepress-multilingual"); ?>
 
155
  <?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
156
  <?php __("Translator", "translatepress-multilingual"); ?>
157
  <?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
languages/translatepress-multilingual.pot CHANGED
@@ -49,7 +49,7 @@ msgstr ""
49
  msgid "<div class=\"warning\">WARNING. Cannot determine your language preference based on your current IP.<br>This is most likely because the website is on a local environment.</div>"
50
  msgstr ""
51
 
52
- #: partials/license-settings-page.php:4, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:4, ../tp-add-on-extra-languages/partials/license-settings-page.php:4, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:4, ../tp-add-on-seo-pack/partials/license-settings-page.php:4, ../translatepress/partials/addons-settings-page.php:3, ../translatepress/partials/main-settings-page.php:5, ../translatepress/partials/test-google-key-settings-page.php:10, ../translatepress/partials/trp-remove-duplicate-rows.php:3, ../translatepress/partials/trp-update-database.php:3, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
53
  msgid "TranslatePress Settings"
54
  msgstr ""
55
 
@@ -153,7 +153,7 @@ msgstr ""
153
  msgid "General"
154
  msgstr ""
155
 
156
- #: ../translatepress/includes/class-settings.php:389, ../translatepress/includes/class-translation-manager.php:617
157
  msgid "Translate Site"
158
  msgstr ""
159
 
@@ -165,7 +165,7 @@ msgstr ""
165
  msgid "Addons"
166
  msgstr ""
167
 
168
- #: ../translatepress/includes/class-settings.php:428, ../translatepress/includes/class-translation-manager.php:648
169
  msgid "Settings"
170
  msgstr ""
171
 
@@ -205,98 +205,128 @@ msgstr ""
205
  msgid "Dynamic Added Strings"
206
  msgstr ""
207
 
208
- #: ../translatepress/includes/class-translation-manager.php:629
209
  msgid "Translate Page"
210
  msgstr ""
211
 
212
- #: ../translatepress/includes/class-translation-manager.php:1242
213
  msgid "Security check"
214
  msgstr ""
215
 
216
- #: ../translatepress/includes/class-translation-manager.php:1316
217
  msgid "<strong>Warning:</strong> Some strings have possibly incorrectly encoded characters. This may result in breaking the queries, rendering the page untranslated in live mode. Consider revising the following strings or their method of outputting."
218
  msgstr ""
219
 
220
- #: ../translatepress/includes/class-translation-render.php:143
221
  msgid "Description"
222
  msgstr ""
223
 
224
- #: ../translatepress/includes/class-translation-render.php:149
225
  msgid "OG Title"
226
  msgstr ""
227
 
228
- #: ../translatepress/includes/class-translation-render.php:155
229
  msgid "OG Site Name"
230
  msgstr ""
231
 
232
- #: ../translatepress/includes/class-translation-render.php:161
233
  msgid "OG Description"
234
  msgstr ""
235
 
236
- #: ../translatepress/includes/class-translation-render.php:167
237
  msgid "Twitter Title"
238
  msgstr ""
239
 
240
- #: ../translatepress/includes/class-translation-render.php:173
241
  msgid "Twitter Description"
242
  msgstr ""
243
 
244
- #: ../translatepress/includes/class-translation-render.php:179
245
  msgid "Post Slug"
246
  msgstr ""
247
 
248
- #: ../translatepress/includes/class-translation-render.php:183
249
  msgid "Page Title"
250
  msgstr ""
251
 
252
- #: ../translatepress/includes/class-upgrade.php:91
253
  msgid "TranslatePress data update"
254
  msgstr ""
255
 
256
- #: ../translatepress/includes/class-upgrade.php:91
257
  msgid "We need to update your translations database to the latest version."
258
  msgstr ""
259
 
260
- #: ../translatepress/includes/class-upgrade.php:92
 
 
 
 
 
 
261
  msgid "Run the updater"
262
  msgstr ""
263
 
264
- #: ../translatepress/includes/class-upgrade.php:121
265
- msgid "<p><strong>Successfully updated database!</strong></p>"
 
 
 
 
266
  msgstr ""
267
 
268
- #: ../translatepress/includes/class-upgrade.php:121, ../translatepress/includes/class-upgrade.php:126, ../translatepress/includes/class-upgrade.php:286, ../translatepress/includes/class-upgrade.php:291
269
  msgid "Back to TranslatePress Settings page"
270
  msgstr ""
271
 
272
- #: ../translatepress/includes/class-upgrade.php:126, ../translatepress/includes/class-upgrade.php:291
273
- msgid "Invalid nonce."
274
  msgstr ""
275
 
276
- #: ../translatepress/includes/class-upgrade.php:202, ../translatepress/includes/class-upgrade.php:371
277
- msgid "If the page does not redirect automatically"
278
  msgstr ""
279
 
280
- #: ../translatepress/includes/class-upgrade.php:202, ../translatepress/includes/class-upgrade.php:371
281
- msgid "click here"
 
 
 
 
282
  msgstr ""
283
 
284
- #: ../translatepress/includes/class-upgrade.php:224
285
- msgid "Querying table <strong>%s</strong>... "
286
  msgstr ""
287
 
288
- #: ../translatepress/includes/class-upgrade.php:226, ../translatepress/includes/class-upgrade.php:286
 
 
 
 
289
  msgid "Done."
290
  msgstr ""
291
 
292
- #: ../translatepress/includes/class-upgrade.php:311
 
 
 
 
293
  msgid "Querying table <strong>%s</strong>"
294
  msgstr ""
295
 
296
- #: ../translatepress/includes/class-upgrade.php:341
297
  msgid "%s duplicates removed"
298
  msgstr ""
299
 
 
 
 
 
 
 
 
 
300
  #: ../translatepress/includes/functions.php:258
301
  msgid "<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server."
302
  msgstr ""
@@ -577,12 +607,6 @@ msgstr ""
577
  msgid "<strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong><br><br>This feature can be used to cleanup duplicate entries in TranslatePress trp_dictionary tables. Such duplicates can appear in exceptional situations of unexpected behavior."
578
  msgstr ""
579
 
580
- #: ../translatepress/partials/trp-remove-duplicate-rows.php:12, ../translatepress/partials/trp-update-database.php:12
581
- msgid ""
582
- "IMPORTANT: It is strongly recommended to backup the database first!\n"
583
- "Are you sure you want to continue?"
584
- msgstr ""
585
-
586
  #: ../translatepress/partials/trp-remove-duplicate-rows.php:15
587
  msgid "Batch size"
588
  msgstr ""
@@ -595,16 +619,12 @@ msgstr ""
595
  msgid "Remove duplicate rows"
596
  msgstr ""
597
 
598
- #: ../translatepress/partials/trp-update-database.php:7
599
- msgid "Update TranslatePress tables"
600
- msgstr ""
601
-
602
- #: ../translatepress/partials/trp-update-database.php:10
603
- msgid "<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>"
604
  msgstr ""
605
 
606
- #: ../translatepress/partials/trp-update-database.php:18
607
- msgid "Update database"
608
  msgstr ""
609
 
610
  #: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
49
  msgid "<div class=\"warning\">WARNING. Cannot determine your language preference based on your current IP.<br>This is most likely because the website is on a local environment.</div>"
50
  msgstr ""
51
 
52
+ #: partials/license-settings-page.php:4, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:4, ../tp-add-on-extra-languages/partials/license-settings-page.php:4, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:4, ../tp-add-on-seo-pack/partials/license-settings-page.php:4, ../translatepress/partials/addons-settings-page.php:3, ../translatepress/partials/main-settings-page.php:5, ../translatepress/partials/test-google-key-settings-page.php:10, ../translatepress/partials/trp-remove-duplicate-rows.php:3, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
53
  msgid "TranslatePress Settings"
54
  msgstr ""
55
 
153
  msgid "General"
154
  msgstr ""
155
 
156
+ #: ../translatepress/includes/class-settings.php:389, ../translatepress/includes/class-translation-manager.php:618
157
  msgid "Translate Site"
158
  msgstr ""
159
 
165
  msgid "Addons"
166
  msgstr ""
167
 
168
+ #: ../translatepress/includes/class-settings.php:428, ../translatepress/includes/class-translation-manager.php:649
169
  msgid "Settings"
170
  msgstr ""
171
 
205
  msgid "Dynamic Added Strings"
206
  msgstr ""
207
 
208
+ #: ../translatepress/includes/class-translation-manager.php:630
209
  msgid "Translate Page"
210
  msgstr ""
211
 
212
+ #: ../translatepress/includes/class-translation-manager.php:1325
213
  msgid "Security check"
214
  msgstr ""
215
 
216
+ #: ../translatepress/includes/class-translation-manager.php:1399
217
  msgid "<strong>Warning:</strong> Some strings have possibly incorrectly encoded characters. This may result in breaking the queries, rendering the page untranslated in live mode. Consider revising the following strings or their method of outputting."
218
  msgstr ""
219
 
220
+ #: ../translatepress/includes/class-translation-render.php:144
221
  msgid "Description"
222
  msgstr ""
223
 
224
+ #: ../translatepress/includes/class-translation-render.php:150
225
  msgid "OG Title"
226
  msgstr ""
227
 
228
+ #: ../translatepress/includes/class-translation-render.php:156
229
  msgid "OG Site Name"
230
  msgstr ""
231
 
232
+ #: ../translatepress/includes/class-translation-render.php:162
233
  msgid "OG Description"
234
  msgstr ""
235
 
236
+ #: ../translatepress/includes/class-translation-render.php:168
237
  msgid "Twitter Title"
238
  msgstr ""
239
 
240
+ #: ../translatepress/includes/class-translation-render.php:174
241
  msgid "Twitter Description"
242
  msgstr ""
243
 
244
+ #: ../translatepress/includes/class-translation-render.php:180
245
  msgid "Post Slug"
246
  msgstr ""
247
 
248
+ #: ../translatepress/includes/class-translation-render.php:184
249
  msgid "Page Title"
250
  msgstr ""
251
 
252
+ #: ../translatepress/includes/class-upgrade.php:119
253
  msgid "TranslatePress data update"
254
  msgstr ""
255
 
256
+ #: ../translatepress/includes/class-upgrade.php:119
257
  msgid "We need to update your translations database to the latest version."
258
  msgstr ""
259
 
260
+ #: ../translatepress/includes/class-upgrade.php:120, ../translatepress/partials/trp-remove-duplicate-rows.php:12
261
+ msgid ""
262
+ "IMPORTANT: It is strongly recommended to backup the database first!\n"
263
+ "Are you sure you want to continue?"
264
+ msgstr ""
265
+
266
+ #: ../translatepress/includes/class-upgrade.php:120
267
  msgid "Run the updater"
268
  msgstr ""
269
 
270
+ #: ../translatepress/includes/class-upgrade.php:136
271
+ msgid "Update aborted! Your user account doesn't have the capability to perform database updates."
272
+ msgstr ""
273
+
274
+ #: ../translatepress/includes/class-upgrade.php:141
275
+ msgid "Update aborted! Invalid nonce."
276
  msgstr ""
277
 
278
+ #: ../translatepress/includes/class-upgrade.php:156, ../translatepress/includes/class-upgrade.php:249, ../translatepress/includes/class-upgrade.php:335, ../translatepress/includes/class-upgrade.php:340
279
  msgid "Back to TranslatePress Settings page"
280
  msgstr ""
281
 
282
+ #: ../translatepress/includes/class-upgrade.php:160
283
+ msgid "Successfully updated database!"
284
  msgstr ""
285
 
286
+ #: ../translatepress/includes/class-upgrade.php:166
287
+ msgid "Updating database to version %s+"
288
  msgstr ""
289
 
290
+ #: ../translatepress/includes/class-upgrade.php:167, ../translatepress/includes/class-upgrade.php:222
291
+ msgid "Processing table for language %s..."
292
+ msgstr ""
293
+
294
+ #: ../translatepress/includes/class-upgrade.php:171
295
+ msgid "Update aborted! Incorrect action."
296
  msgstr ""
297
 
298
+ #: ../translatepress/includes/class-upgrade.php:174
299
+ msgid "Update aborted! Incorrect language code."
300
  msgstr ""
301
 
302
+ #: ../translatepress/includes/class-upgrade.php:221, ../translatepress/includes/class-upgrade.php:225
303
+ msgid " done."
304
+ msgstr ""
305
+
306
+ #: ../translatepress/includes/class-upgrade.php:335
307
  msgid "Done."
308
  msgstr ""
309
 
310
+ #: ../translatepress/includes/class-upgrade.php:340
311
+ msgid "Invalid nonce."
312
+ msgstr ""
313
+
314
+ #: ../translatepress/includes/class-upgrade.php:360
315
  msgid "Querying table <strong>%s</strong>"
316
  msgstr ""
317
 
318
+ #: ../translatepress/includes/class-upgrade.php:390
319
  msgid "%s duplicates removed"
320
  msgstr ""
321
 
322
+ #: ../translatepress/includes/class-upgrade.php:420
323
+ msgid "If the page does not redirect automatically"
324
+ msgstr ""
325
+
326
+ #: ../translatepress/includes/class-upgrade.php:420
327
+ msgid "click here"
328
+ msgstr ""
329
+
330
  #: ../translatepress/includes/functions.php:258
331
  msgid "<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server."
332
  msgstr ""
607
  msgid "<strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong><br><br>This feature can be used to cleanup duplicate entries in TranslatePress trp_dictionary tables. Such duplicates can appear in exceptional situations of unexpected behavior."
608
  msgstr ""
609
 
 
 
 
 
 
 
610
  #: ../translatepress/partials/trp-remove-duplicate-rows.php:15
611
  msgid "Batch size"
612
  msgstr ""
619
  msgid "Remove duplicate rows"
620
  msgstr ""
621
 
622
+ #: ../translatepress/partials/trp-update-database.php:3
623
+ msgid "TranslatePress Database Updater"
 
 
 
 
624
  msgstr ""
625
 
626
+ #: ../translatepress/partials/trp-update-database.php:7
627
+ msgid "Updating TranslatePress tables"
628
  msgstr ""
629
 
630
  #: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
partials/language-switcher-shortcode.php CHANGED
@@ -2,7 +2,7 @@
2
  $current_language_preference = $this->add_shortcode_preferences($shortcode_settings, $current_language['code'], $current_language['name']);
3
 
4
  ?>
5
- <div class="trp-language-switcher" data-no-translation <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : '' ?>>
6
  <script type="application/javascript">
7
  jQuery( document ).ready(function(){
8
  // need to have the same with set from JS on both divs. Otherwise it can push stuff around in HTML
@@ -16,10 +16,10 @@ $current_language_preference = $this->add_shortcode_preferences($shortcode_setti
16
  })
17
  </script>
18
  <div class="trp-ls-shortcode-current-language">
19
- <a href="javascript:void(0)" class="trp-ls-shortcode-disabled-language" title="<?php echo $current_language['name'] ?>"><?php echo $current_language_preference ?></a>
20
  </div>
21
  <div class="trp-ls-shortcode-language">
22
- <a href="javascript:void(0)" class="trp-ls-shortcode-disabled-language" title="<?php echo $current_language['name'] ?>"><?php echo $current_language_preference ?></a>
23
  <?php foreach ( $other_languages as $code => $name ){
24
 
25
  $language_preference = $this->add_shortcode_preferences($shortcode_settings, $code, $name);
2
  $current_language_preference = $this->add_shortcode_preferences($shortcode_settings, $current_language['code'], $current_language['name']);
3
 
4
  ?>
5
+ <div class="trp-language-switcher trp-language-switcher-container" data-no-translation <?php echo ( isset( $_GET['trp-edit-translation'] ) && $_GET['trp-edit-translation'] == 'preview' ) ? 'data-trp-unpreviewable="trp-unpreviewable"' : '' ?>>
6
  <script type="application/javascript">
7
  jQuery( document ).ready(function(){
8
  // need to have the same with set from JS on both divs. Otherwise it can push stuff around in HTML
16
  })
17
  </script>
18
  <div class="trp-ls-shortcode-current-language">
19
+ <a href="javascript:void(0)" class="trp-ls-shortcode-disabled-language trp-ls-disabled-language" title="<?php echo $current_language['name'] ?>"><?php echo $current_language_preference ?></a>
20
  </div>
21
  <div class="trp-ls-shortcode-language">
22
+ <a href="javascript:void(0)" class="trp-ls-shortcode-disabled-language trp-ls-disabled-language" title="<?php echo $current_language['name'] ?>"><?php echo $current_language_preference ?></a>
23
  <?php foreach ( $other_languages as $code => $name ){
24
 
25
  $language_preference = $this->add_shortcode_preferences($shortcode_settings, $code, $name);
partials/trp-update-database.php CHANGED
@@ -1,24 +1,13 @@
1
  <div id="trp-addons-page" class="wrap">
2
 
3
- <h1> <?php _e( 'TranslatePress Settings', 'translatepress-multilingual' );?></h1>
4
 
5
  <div class="grid feat-header">
6
  <div class="grid-cell">
7
- <h2><?php _e('Update TranslatePress tables', 'translatepress-multilingual' );?> </h2>
8
- <?php if ( empty( $_GET['trp_updb_lang'] ) ){ ?>
9
- <div>
10
- <?php _e( '<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>', 'translatepress-multilingual' )?>
11
- </div>
12
- <form onsubmit="return confirm('<?php _e( 'IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?', 'translatepress-multilingual' ) ?>');">
13
- <input type="hidden" name="trp_updb_nonce" value="<?php echo wp_create_nonce('tpupdatedatabase')?>">
14
- <input type="hidden" name="page" value="trp_update_database">
15
- <input type="hidden" name="trp_updb_batch" value="0">
16
- <input type="hidden" name="trp_updb_batch_size" value="200">
17
- <input type="hidden" name="trp_updb_lang" value="<?php echo $this->settings['translation-languages'][0]?>">
18
- <input type="submit" class="button-primary" value="<?php _e( 'Update database', 'translatepress-multilingual' ); ?>">
19
- </form>
20
- <?php } ?>
21
 
 
22
  </div>
23
  </div>
24
 
1
  <div id="trp-addons-page" class="wrap">
2
 
3
+ <h1> <?php _e( 'TranslatePress Database Updater', 'translatepress-multilingual' );?></h1>
4
 
5
  <div class="grid feat-header">
6
  <div class="grid-cell">
7
+ <h2><?php _e('Updating TranslatePress tables', 'translatepress-multilingual' );?> </h2>
8
+ <div id="trp-update-database-progress">
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ </div>
11
  </div>
12
  </div>
13
 
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.cozmoslabs.com/
4
  Tags: translate, translation, multilingual, automatic translation, bilingual, front-end translation, google translate, language
5
  Requires at least: 3.1.0
6
  Tested up to: 5.1.1
7
- Stable tag: 1.4.4
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -125,6 +125,19 @@ For more information please check out [TranslatePress - Multilingual plugin docu
125
  6. Menu Language Switcher
126
 
127
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
 
 
128
  = 1.4.4 =
129
  * Added more filters
130
  * Make sure we do not insert empty strings in the gettext translation table
4
  Tags: translate, translation, multilingual, automatic translation, bilingual, front-end translation, google translate, language
5
  Requires at least: 3.1.0
6
  Tested up to: 5.1.1
7
+ Stable tag: 1.4.5
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
125
  6. Menu Language Switcher
126
 
127
  == Changelog ==
128
+ = 1.4.5 =
129
+ * Performance improvements
130
+ * Fixed an issue that was causing empty strings to get inserted in the database
131
+ * Improvements to detecting dynamic js strings earlier
132
+ * Fixes some urls for sitemap
133
+ * We now check if str_get_html is successful to avoid fatal error
134
+ * Fixed regular string loaded by ajax not detected in translation editor
135
+ * We now allow translating WooCommerce product base name separately from selected variations
136
+ * Fixed WooCommerce cart details not being translated when changing language
137
+ * Fixed Automatic Google Translation on languages not published yet
138
+ * Fixed Translation Editor not working in default language when no translation language is published yet
139
+ * Fixed gettext wrapping characters showing up in WooCommerce Shipping taxes metabox on Order pages
140
+
141
  = 1.4.4 =
142
  * Added more filters
143
  * Make sure we do not insert empty strings in the gettext translation table