TranslatePress – Translate Multilingual sites - Version 1.6.6

Version Description

  • Implemented Search functionality in translated languages
  • Added support for WooCommerce product search in translated languages
  • Skip dynamic strings detection of ad links
  • Added filters for adjusting gettext machine translation
Download this release

Release Info

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

Code changes from version 1.6.5 to 1.6.6

assets/js/trp-translate-dom-changes.js CHANGED
@@ -231,11 +231,28 @@ function TRP_Translator(){
231
  return false;
232
  };
233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
234
  /*
235
  * Skip string based on original string text
236
  */
237
- this.skip_string_original = function ( string ){
238
- return ( ( already_detected[string] > duplicate_detections_allowed ) || _this.in_array( string, trp_data.skip_strings_from_dynamic_translation ) )
 
 
 
 
239
  }
240
 
241
  this.skip_string_attribute = function(node, attribute){
@@ -270,7 +287,7 @@ function TRP_Translator(){
270
  // a text without HTML was added
271
  if ( _this.trim( direct_string.textContent, except_characters ) != '' ) {
272
  var extracted_original = _this.trim(direct_string.textContent, trim_characters);
273
- if ( ! _this.skip_string_original( extracted_original )) {
274
  nodesInfo.push({node: node, original: extracted_original, attribute: ''});
275
  string_originals.push(extracted_original)
276
 
@@ -295,7 +312,7 @@ function TRP_Translator(){
295
  var all_strings_length = all_strings.length;
296
  for (var j = 0; j < all_strings_length; j++ ) {
297
  if ( _this.trim( all_strings[j].textContent, except_characters ) != '' ) {
298
- if ( ! _this.skip_string_original( all_strings[j].textContent )) {
299
  nodesInfo.push({node: all_strings[j], original: all_strings[j].textContent, attribute: ''});
300
  string_originals.push(all_strings[j].textContent)
301
  if (trp_data ['showdynamiccontentbeforetranslation'] == false) {
@@ -327,7 +344,7 @@ function TRP_Translator(){
327
  }
328
 
329
  var attribute_content = all_nodes[j].getAttribute( attribute_selector_item.accessor )
330
- if ( _this.skip_string_original( attribute_content )){
331
  continue;
332
  }
333
  if ( attribute_content && _this.trim( attribute_content.trim(), except_characters ) != '' ) {
231
  return false;
232
  };
233
 
234
+ this.contains_substring_that_needs_skipped = function ( string, attribute ){
235
+ for (var attribute_to_skip in trp_data.skip_strings_from_dynamic_translation_for_substrings ){
236
+ if (trp_data.skip_strings_from_dynamic_translation_for_substrings.hasOwnProperty(attribute_to_skip) && attribute === attribute_to_skip) {
237
+ for ( var i = 0 ; i < trp_data.skip_strings_from_dynamic_translation_for_substrings[attribute_to_skip].length; i++ ){
238
+ if ( string.indexOf(trp_data.skip_strings_from_dynamic_translation_for_substrings[attribute_to_skip][i]) !== -1 ){
239
+ return true
240
+ }
241
+ }
242
+ }
243
+ }
244
+ return false
245
+ };
246
+
247
  /*
248
  * Skip string based on original string text
249
  */
250
+ this.skip_string_original = function ( string, attribute ){
251
+ return (
252
+ ( already_detected[string] > duplicate_detections_allowed ) ||
253
+ _this.in_array( string, trp_data.skip_strings_from_dynamic_translation ) ||
254
+ _this.contains_substring_that_needs_skipped( string, attribute)
255
+ )
256
  }
257
 
258
  this.skip_string_attribute = function(node, attribute){
287
  // a text without HTML was added
288
  if ( _this.trim( direct_string.textContent, except_characters ) != '' ) {
289
  var extracted_original = _this.trim(direct_string.textContent, trim_characters);
290
+ if ( ! _this.skip_string_original( extracted_original, false )) {
291
  nodesInfo.push({node: node, original: extracted_original, attribute: ''});
292
  string_originals.push(extracted_original)
293
 
312
  var all_strings_length = all_strings.length;
313
  for (var j = 0; j < all_strings_length; j++ ) {
314
  if ( _this.trim( all_strings[j].textContent, except_characters ) != '' ) {
315
+ if ( ! _this.skip_string_original( all_strings[j].textContent, false )) {
316
  nodesInfo.push({node: all_strings[j], original: all_strings[j].textContent, attribute: ''});
317
  string_originals.push(all_strings[j].textContent)
318
  if (trp_data ['showdynamiccontentbeforetranslation'] == false) {
344
  }
345
 
346
  var attribute_content = all_nodes[j].getAttribute( attribute_selector_item.accessor )
347
+ if ( _this.skip_string_original( attribute_content, attribute_selector_item.accessor )){
348
  continue;
349
  }
350
  if ( attribute_content && _this.trim( attribute_content.trim(), except_characters ) != '' ) {
class-translate-press.php CHANGED
@@ -27,6 +27,7 @@ class TRP_Translate_Press{
27
  protected $translation_memory;
28
  protected $machine_translation_tab;
29
  protected $error_manager;
 
30
 
31
  public $active_pro_addons = array();
32
  public static $translate_press = null;
@@ -52,7 +53,7 @@ class TRP_Translate_Press{
52
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
53
  define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
54
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
55
- define( 'TRP_PLUGIN_VERSION', '1.6.5' );
56
 
57
  wp_cache_add_non_persistent_groups(array('trp'));
58
 
@@ -104,10 +105,9 @@ class TRP_Translate_Press{
104
  require_once TRP_PLUGIN_DIR . 'assets/lib/simplehtmldom/simple_html_dom.php';
105
  require_once TRP_PLUGIN_DIR . 'includes/shortcodes.php';
106
  require_once TRP_PLUGIN_DIR . 'includes/class-machine-translation-tab.php';
107
-
108
  if ( did_action( 'elementor/loaded' ) )
109
  require_once TRP_PLUGIN_DIR . 'includes/class-elementor-language-for-blocks.php';
110
-
111
  }
112
 
113
  /**
@@ -138,6 +138,7 @@ class TRP_Translate_Press{
138
  $this->license_page = new TRP_LICENSE_PAGE();
139
  $this->translation_memory = new TRP_Translation_Memory( $this->settings->get_settings() );
140
  $this->error_manager = new TRP_Error_Manager( $this->settings->get_settings() );
 
141
  }
142
 
143
  /**
@@ -266,6 +267,10 @@ class TRP_Translate_Press{
266
  $this->loader->add_action( "trp_allow_machine_translation_for_string", $this->translation_render, 'allow_machine_translation_for_string', 10, 4 );
267
  $this->loader->add_action( "init", $this->translation_render, 'add_callbacks_for_translating_rest_api', 10, 4 );
268
 
 
 
 
 
269
 
270
 
271
 
@@ -343,6 +348,10 @@ class TRP_Translate_Press{
343
 
344
  // machine translation
345
  $this->loader->add_action( 'plugins_loaded', $this, 'init_machine_translation', 10 );
 
 
 
 
346
  }
347
 
348
  /**
@@ -368,4 +377,4 @@ class TRP_Translate_Press{
368
  public function init_machine_translation(){
369
  $this->machine_translator = $this->machine_translation_tab->get_active_engine();
370
  }
371
- }
27
  protected $translation_memory;
28
  protected $machine_translation_tab;
29
  protected $error_manager;
30
+ protected $search;
31
 
32
  public $active_pro_addons = array();
33
  public static $translate_press = null;
53
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
54
  define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
55
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
56
+ define( 'TRP_PLUGIN_VERSION', '1.6.6' );
57
 
58
  wp_cache_add_non_persistent_groups(array('trp'));
59
 
105
  require_once TRP_PLUGIN_DIR . 'assets/lib/simplehtmldom/simple_html_dom.php';
106
  require_once TRP_PLUGIN_DIR . 'includes/shortcodes.php';
107
  require_once TRP_PLUGIN_DIR . 'includes/class-machine-translation-tab.php';
108
+ require_once TRP_PLUGIN_DIR . 'includes/class-search.php';
109
  if ( did_action( 'elementor/loaded' ) )
110
  require_once TRP_PLUGIN_DIR . 'includes/class-elementor-language-for-blocks.php';
 
111
  }
112
 
113
  /**
138
  $this->license_page = new TRP_LICENSE_PAGE();
139
  $this->translation_memory = new TRP_Translation_Memory( $this->settings->get_settings() );
140
  $this->error_manager = new TRP_Error_Manager( $this->settings->get_settings() );
141
+ $this->search = new TRP_Search( $this->settings->get_settings() );
142
  }
143
 
144
  /**
267
  $this->loader->add_action( "trp_allow_machine_translation_for_string", $this->translation_render, 'allow_machine_translation_for_string', 10, 4 );
268
  $this->loader->add_action( "init", $this->translation_render, 'add_callbacks_for_translating_rest_api', 10, 4 );
269
 
270
+ /* add custom containers for post content and pots title so we can identify string that are part of them */
271
+ $this->loader->add_filter( "the_content", $this->translation_render, 'wrap_with_post_id', 1000 );
272
+ $this->loader->add_filter( "the_title", $this->translation_render, 'wrap_with_post_id', 1000, 2 );
273
+
274
 
275
 
276
 
348
 
349
  // machine translation
350
  $this->loader->add_action( 'plugins_loaded', $this, 'init_machine_translation', 10 );
351
+
352
+ //search
353
+ $this->loader->add_filter( 'pre_get_posts', $this->search, 'trp_search_filter', 10 );
354
+ $this->loader->add_filter( 'get_search_query', $this->search, 'trp_search_query', 10 );
355
  }
356
 
357
  /**
377
  public function init_machine_translation(){
378
  $this->machine_translator = $this->machine_translation_tab->get_active_engine();
379
  }
380
+ }
includes/class-query.php CHANGED
@@ -162,6 +162,7 @@ class TRP_Query{
162
  translated longtext,
163
  status int(20) DEFAULT " . $this::NOT_TRANSLATED .",
164
  block_type int(20) DEFAULT " . $this::BLOCK_TYPE_REGULAR_STRING .",
 
165
  UNIQUE KEY id (id) )
166
  $charset_collate;";
167
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
@@ -185,6 +186,7 @@ class TRP_Query{
185
  }
186
  }else{
187
  $this->check_for_block_type_column( $language_code, $default_language );
 
188
  }
189
  }
190
 
@@ -245,7 +247,7 @@ class TRP_Query{
245
  $destination_table_name = $this->get_table_name( $language_code, $default_language );
246
 
247
  // get all tb from $source_table_name and copy to $destination_table_name
248
- $sql = 'INSERT INTO `' . $destination_table_name . '` SELECT NULL, original, "", ' . $this::NOT_TRANSLATED . ', block_type FROM `' . $source_table_name . '` WHERE block_type = ' . self::BLOCK_TYPE_ACTIVE . ' OR block_type = ' . self::BLOCK_TYPE_DEPRECATED;
249
  $this->db->query( $sql );
250
  }
251
  }
@@ -285,6 +287,236 @@ class TRP_Query{
285
  }
286
  }
287
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
288
  /**
289
  * Add block_type column to dictionary tables, if it doesn't exist.
290
  *
@@ -313,6 +545,35 @@ class TRP_Query{
313
  }
314
  }
315
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  /**
317
  * Returns true if a database table column exists. Otherwise returns false.
318
  *
@@ -403,21 +664,25 @@ class TRP_Query{
403
  * @param int $block_type
404
  */
405
  public function insert_strings( $new_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ) {
 
406
  if ( $block_type == null ) {
407
  $block_type = self::BLOCK_TYPE_REGULAR_STRING;
408
  }
409
  if ( count( $new_strings ) == 0 ) {
410
  return;
411
  }
412
- $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( original, translated, status, block_type ) VALUES ";
413
 
414
  $values = array();
415
  $place_holders = array();
416
  $new_strings = array_unique( $new_strings );
417
 
 
 
 
418
  foreach ( $new_strings as $string ) {
419
- array_push( $values, $string, NULL, self::NOT_TRANSLATED, $block_type );
420
- $place_holders[] = "('%s','%s','%d','%d')";
421
  }
422
  $query .= implode( ', ', $place_holders );
423
 
@@ -426,6 +691,7 @@ class TRP_Query{
426
  $this->db->query( $this->db->prepare($query . ' ', $values) );
427
 
428
  $this->maybe_record_automatic_translation_error(array( 'details' => 'Error running insert_strings()' ) );
 
429
  }
430
 
431
  public function insert_gettext_strings( $new_strings, $language_code ){
@@ -553,6 +819,41 @@ class TRP_Query{
553
  return $dictionary;
554
  }
555
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
556
  /**
557
  * Returns the entries for the provided strings.
558
  *
@@ -603,6 +904,32 @@ class TRP_Query{
603
  return $language_code;
604
  }
605
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
606
  public function get_all_gettext_strings( $language_code ){
607
  $dictionary = $this->db->get_results( "SELECT id, original, translated, domain FROM `" . sanitize_text_field( $this->get_gettext_table_name( $language_code ) ) . "`", ARRAY_A );
608
  if ( is_array( $dictionary ) && count( $dictionary ) === 0 && !$this->table_exists($this->get_gettext_table_name( $language_code )) ){
162
  translated longtext,
163
  status int(20) DEFAULT " . $this::NOT_TRANSLATED .",
164
  block_type int(20) DEFAULT " . $this::BLOCK_TYPE_REGULAR_STRING .",
165
+ original_id bigint(20) DEFAULT NULL,
166
  UNIQUE KEY id (id) )
167
  $charset_collate;";
168
  require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
186
  }
187
  }else{
188
  $this->check_for_block_type_column( $language_code, $default_language );
189
+ $this->check_for_original_id_column( $language_code, $default_language );
190
  }
191
  }
192
 
247
  $destination_table_name = $this->get_table_name( $language_code, $default_language );
248
 
249
  // get all tb from $source_table_name and copy to $destination_table_name
250
+ $sql = 'INSERT INTO `' . $destination_table_name . '` (id, original, translated, status, block_type) SELECT NULL, original, "", ' . $this::NOT_TRANSLATED . ', block_type FROM `' . $source_table_name . '` WHERE block_type = ' . self::BLOCK_TYPE_ACTIVE . ' OR block_type = ' . self::BLOCK_TYPE_DEPRECATED;
251
  $this->db->query( $sql );
252
  }
253
  }
287
  }
288
  }
289
 
290
+ /**
291
+ * Check if the original string table exists
292
+ *
293
+ * If the table does not exists it is created.
294
+ *
295
+ * @since 1.6.6
296
+ */
297
+ public function check_original_table(){
298
+
299
+ $table_name = $this->get_table_name_for_original_strings();
300
+ if ( $this->db->get_var( "SHOW TABLES LIKE '$table_name'" ) != $table_name ) {
301
+ // table not in database. Create new table
302
+ $charset_collate = $this->db->get_charset_collate();
303
+
304
+ $sql = "CREATE TABLE `" . $table_name . "`(
305
+ id bigint(20) AUTO_INCREMENT NOT NULL PRIMARY KEY,
306
+ original TEXT NOT NULL )
307
+ $charset_collate;";
308
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
309
+ dbDelta( $sql );
310
+
311
+ $sql_index = "CREATE INDEX index_original ON `" . $table_name . "` (original(100));";
312
+ $this->db->query( $sql_index );
313
+ }
314
+ }
315
+
316
+ /**
317
+ * Function that takes care of inserting original strings from dictionary to original_strings table when updating to version 1.6.6
318
+ */
319
+ public function original_ids_insert( $language_code, $inferior_limit, $batch_size ){
320
+
321
+ //don't do anything for default language
322
+ if ( $this->settings['default-language'] === $language_code )
323
+ return 0;
324
+
325
+ if( !$this->error_manager ){
326
+ $trp = TRP_Translate_Press::get_trp_instance();
327
+ $this->error_manager = $trp->get_component( 'error_manager' );
328
+ }
329
+
330
+ $originals_table = $this->get_table_name_for_original_strings();
331
+ $table_name = sanitize_text_field( $this->get_table_name( $language_code, $this->settings['default-language'] ) );
332
+
333
+ /*
334
+ * select all string that are in the dictionary table and are not in the original tables and insert them in the original
335
+ */
336
+ $insert_records = $this->db->query( $this->db->prepare( "INSERT INTO `$originals_table` (original) SELECT DISTINCT ( BINARY t1.original ) FROM `$table_name` t1 LEFT JOIN `$originals_table` t2 on t2.original = BINARY t1.original WHERE t2.original IS NULL AND t1.id > %d AND t1.id <= %d", $inferior_limit, ($inferior_limit + $batch_size) ) );
337
+
338
+ if (!empty($this->db->last_error)) {
339
+ $this->error_manager->record_error(array('last_error_insert_original_strings' => $this->db->last_error));
340
+ }
341
+
342
+ return $insert_records;
343
+
344
+ }
345
+
346
+ /**
347
+ * Function that makes sure we don't have duplicates in original_strings table when updating to version 1.6.6
348
+ * It is executed after we inserted all the strings
349
+ */
350
+ public function original_ids_cleanup(){
351
+ if( !$this->error_manager ){
352
+ $trp = TRP_Translate_Press::get_trp_instance();
353
+ $this->error_manager = $trp->get_component( 'error_manager' );
354
+ }
355
+
356
+ $originals_table = $this->get_table_name_for_original_strings();
357
+ $this->db->query( "DELETE t1 FROM `$originals_table` t1 INNER JOIN `$originals_table` t2 WHERE t1.id > t2.id AND t1.original = BINARY t2.original" );
358
+
359
+ if (!empty($this->db->last_error)) {
360
+ $this->error_manager->record_error(array('last_error_cleaning_original_strings' => $this->db->last_error));
361
+ }
362
+
363
+ }
364
+
365
+ /**
366
+ * Function that takes care of synchronizing the dictionaries with the original table by inserting the original ids in the original_id column
367
+ */
368
+ public function original_ids_reindex( $language_code, $inferior_limit, $batch_size ){
369
+
370
+ //don't do anything for default language
371
+ if ( $this->settings['default-language'] === $language_code )
372
+ return 0;
373
+
374
+ if( !$this->error_manager ){
375
+ $trp = TRP_Translate_Press::get_trp_instance();
376
+ $this->error_manager = $trp->get_component( 'error_manager' );
377
+ }
378
+
379
+ $originals_table = $this->get_table_name_for_original_strings();
380
+ $table_name = sanitize_text_field( $this->get_table_name( $language_code, $this->settings['default-language'] ) );
381
+
382
+ /*
383
+ * perform a UPDATE JOIN with the original table https://www.mysqltutorial.org/mysql-update-join/
384
+ */
385
+ $update_records = $this->db->query( $this->db->prepare( "UPDATE $table_name, $originals_table SET $table_name.original_id = $originals_table.id WHERE $table_name.original = BINARY $originals_table.original AND $table_name.id > %d AND $table_name.id <= %d", $inferior_limit, ($inferior_limit + $batch_size) ) );
386
+
387
+ if (!empty($this->db->last_error)) {
388
+ $this->error_manager->record_error(array('last_error_reindex_original_ids' => $this->db->last_error));
389
+ }
390
+
391
+ return $update_records;
392
+ }
393
+
394
+ /**
395
+ * Function that makes sure that when new strings are inserted in dictionaries they are also inserted in original_strings table if they don't exist
396
+ * @param $language_code
397
+ * @param $new_strings
398
+ * @return array|object|null
399
+ */
400
+ public function original_strings_sync( $language_code, $new_strings ){
401
+ if ( $this->settings['default-language'] != $language_code ) {
402
+
403
+ $originals_table = $this->get_table_name_for_original_strings();
404
+
405
+ $possible_new_strings = array();
406
+ foreach ( $new_strings as $string ) {
407
+ $possible_new_strings[] = $this->db->prepare( "%s", $string );
408
+ }
409
+
410
+ $existing_strings = $this->db->get_results( "SELECT original FROM `$originals_table` WHERE BINARY $originals_table.original IN (".implode( ',', $possible_new_strings ).")", OBJECT_K );
411
+
412
+ if( !empty( $existing_strings ) ){
413
+ $existing_strings = array_keys($existing_strings);
414
+ $insert_strings = array_diff( $new_strings, $existing_strings );
415
+ }
416
+ else{
417
+ $insert_strings = $new_strings;
418
+ }
419
+
420
+ foreach ( $insert_strings as $k => $string ) {
421
+ $insert_strings[$k] = $this->db->prepare( "(%s)", $string );
422
+ }
423
+
424
+ if( !empty( $insert_strings ) ) {
425
+ //insert the strings that are missing
426
+ $this->db->query("INSERT INTO `$originals_table` (original) VALUES " . implode(',', $insert_strings));
427
+ }
428
+
429
+ //get the ids for all the new strings (new in dictionary)
430
+ $new_strings_in_dictionary_with_original_id = $this->db->get_results( "SELECT original,id FROM `$originals_table` WHERE BINARY $originals_table.original IN (".implode( ',', $possible_new_strings ).")", OBJECT_K );
431
+
432
+ if( count( $new_strings_in_dictionary_with_original_id ) === count( $new_strings ) ){
433
+ return $new_strings_in_dictionary_with_original_id;
434
+ }
435
+ }
436
+
437
+ return array();
438
+
439
+ }
440
+
441
+ /**
442
+ * Function that adds post_parent_id meta to original_meta table
443
+ * @param $original_string_ids
444
+ * @param $post_ids
445
+ */
446
+ public function set_original_string_meta_post_id( $original_string_ids, $post_ids ){
447
+
448
+ //group the strings in a new array by post_id
449
+ $strings_grouped = array();
450
+ if( !empty( $post_ids ) ){
451
+ foreach( $post_ids as $i => $post_id ){
452
+ $strings_grouped[ $post_id ][] = $original_string_ids[$i];
453
+ }
454
+ }
455
+
456
+ if( !empty($strings_grouped) ){
457
+ foreach ( $strings_grouped as $post_id => $original_ids ){
458
+ /*
459
+ * - select all id's that are in the meta already
460
+ * - in php compare our $original_ids with the result and leave just the ones that are not in the db
461
+ * - insert all the remaining ones
462
+ */
463
+
464
+ $existing_entries = $this->db->get_results( $this->db->prepare(
465
+ "SELECT original_id FROM ".$this->get_table_name_for_original_meta()." WHERE meta_key = '". $this->get_meta_key_for_post_parent_id() ."' AND meta_value = '%1d' AND original_id IN ( %2s )",
466
+ $post_id, implode( ', ', $original_ids )
467
+ ), OBJECT_K );
468
+
469
+ $existing_entries = array_keys( $existing_entries );
470
+ $insert_this = array_unique( array_diff( $original_ids, $existing_entries ) );
471
+
472
+ if( !empty( $insert_this ) ){
473
+ $insert_values = array();
474
+ foreach ( $insert_this as $missing_entry ) {
475
+ $insert_values[] = $this->db->prepare( "( %d, %s, %d )", $missing_entry, $this->get_meta_key_for_post_parent_id(), $post_id );
476
+ }
477
+
478
+ $this->db->query( "INSERT INTO ".$this->get_table_name_for_original_meta()." ( original_id, meta_key, meta_value ) VALUES ". implode( ', ', $insert_values ) );
479
+ }
480
+
481
+ }
482
+
483
+ }
484
+
485
+ }
486
+
487
+ /**
488
+ * Check if the original meta table exists
489
+ *
490
+ * If the table does not exists it is created.
491
+ *
492
+ * @since 1.6.6
493
+ */
494
+ public function check_original_meta_table(){
495
+
496
+ $table_name = $table_name = $this->db->get_blog_prefix() . 'trp_original_meta';
497
+ if ( $this->db->get_var( "SHOW TABLES LIKE '$table_name'" ) != $table_name ) {
498
+ // table not in database. Create new table
499
+ $charset_collate = $this->db->get_charset_collate();
500
+
501
+ $sql = "CREATE TABLE `" . $table_name . "`(
502
+ meta_id bigint(20) AUTO_INCREMENT NOT NULL PRIMARY KEY,
503
+ original_id bigint(20) NOT NULL,
504
+ meta_key varchar(255),
505
+ meta_value longtext,
506
+ UNIQUE KEY meta_id (meta_id) )
507
+ $charset_collate;";
508
+ require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
509
+ dbDelta( $sql );
510
+
511
+ //create indexes
512
+ $sql_index = "CREATE INDEX index_original_id ON `" . $table_name . "` (original_id);";
513
+ $this->db->query( $sql_index );
514
+ $sql_index = "CREATE INDEX meta_key ON `" . $table_name . "`(meta_key);";
515
+ $this->db->query( $sql_index );
516
+ }
517
+ }
518
+
519
+
520
  /**
521
  * Add block_type column to dictionary tables, if it doesn't exist.
522
  *
545
  }
546
  }
547
 
548
+
549
+ /**
550
+ * Add original_id column to dictionary tables, if it doesn't exist.
551
+ *
552
+ * Affects all existing tables, including deactivated languages
553
+ *
554
+ * @param null $language_code
555
+ * @param null $default_language
556
+ */
557
+ public function check_for_original_id_column($language_code = null, $default_language = null ){
558
+ if ( $default_language == null ){
559
+ $default_language = $this->settings['default-language'];
560
+ }
561
+
562
+ if ( $language_code ){
563
+ // check only this language
564
+ $array_of_table_names = array( $this->get_table_name( $language_code, $default_language ) );
565
+ }else {
566
+ // check all languages, including deactivated ones
567
+ $array_of_table_names = $this->get_all_table_names( $default_language, array() );
568
+ }
569
+
570
+ foreach( $array_of_table_names as $table_name ){
571
+ if ( ! $this->table_column_exists( $table_name, 'original_id' ) ) {
572
+ $this->db->query("ALTER TABLE " . $table_name . " ADD original_id BIGINT(20) DEFAULT NULL" );
573
+ }
574
+ }
575
+ }
576
+
577
  /**
578
  * Returns true if a database table column exists. Otherwise returns false.
579
  *
664
  * @param int $block_type
665
  */
666
  public function insert_strings( $new_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ) {
667
+
668
  if ( $block_type == null ) {
669
  $block_type = self::BLOCK_TYPE_REGULAR_STRING;
670
  }
671
  if ( count( $new_strings ) == 0 ) {
672
  return;
673
  }
674
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( original, translated, status, block_type, original_id ) VALUES ";
675
 
676
  $values = array();
677
  $place_holders = array();
678
  $new_strings = array_unique( $new_strings );
679
 
680
+ //make sure we have the same strings in the original table as well
681
+ $original_inserts = $this->original_strings_sync( $language_code, $new_strings );
682
+
683
  foreach ( $new_strings as $string ) {
684
+ array_push( $values, $string, NULL, self::NOT_TRANSLATED, $block_type, $original_inserts[$string]->id );
685
+ $place_holders[] = "('%s','%s','%d','%d', %d)";
686
  }
687
  $query .= implode( ', ', $place_holders );
688
 
691
  $this->db->query( $this->db->prepare($query . ' ', $values) );
692
 
693
  $this->maybe_record_automatic_translation_error(array( 'details' => 'Error running insert_strings()' ) );
694
+
695
  }
696
 
697
  public function insert_gettext_strings( $new_strings, $language_code ){
819
  return $dictionary;
820
  }
821
 
822
+ /**
823
+ * Returns the DB ids of the provided original strings
824
+ *
825
+ * @param array $original_strings Array of original strings to search for.
826
+ * @return array Associative Array of objects with translations where key is original string.
827
+ */
828
+ public function get_original_string_ids( $original_strings ){
829
+ if ( !is_array( $original_strings ) || count ( $original_strings ) == 0 ){
830
+ return array();
831
+ }
832
+ $query = "SELECT original,id FROM `" . $this->get_table_name_for_original_strings() . "` WHERE BINARY original IN ";
833
+
834
+ $placeholders = array();
835
+ $values = array();
836
+ foreach( $original_strings as $string ){
837
+ $placeholders[] = '%s';
838
+ $values[] = $string;
839
+ }
840
+
841
+ $query .= "( " . implode ( ", ", $placeholders ) . " )";
842
+ $results = $this->db->get_results( $this->db->prepare( $query, $values ), OBJECT_K );
843
+
844
+ $results_ids = array();
845
+ if( !empty( $results ) && !empty( $original_strings ) ){
846
+ foreach( $original_strings as $string ){
847
+ if( !empty( $results[$string] ) )
848
+ $results_ids[] = $results[$string]->id;
849
+ else
850
+ $results_ids[] = null; //this should not happen but if it does we need to keep the same number of result ids as original_strings to have a correlation
851
+ }
852
+ }
853
+
854
+ return $results_ids;
855
+ }
856
+
857
  /**
858
  * Returns the entries for the provided strings.
859
  *
904
  return $language_code;
905
  }
906
 
907
+ /**
908
+ * Return table name for original strings table
909
+ *
910
+ * @return string Table name.
911
+ */
912
+ public function get_table_name_for_original_strings(){
913
+ return sanitize_text_field( $this->db->prefix . 'trp_original_strings' );
914
+ }
915
+
916
+ /**
917
+ * Return table name for original meta table
918
+ *
919
+ * @return string Table name.
920
+ */
921
+ public function get_table_name_for_original_meta(){
922
+ return sanitize_text_field( $this->db->prefix . 'trp_original_meta' );
923
+ }
924
+ /**
925
+ * Return meta_key for post parent id from meta table
926
+ *
927
+ * @return string key name.
928
+ */
929
+ public function get_meta_key_for_post_parent_id(){
930
+ return 'post_parent_id';
931
+ }
932
+
933
  public function get_all_gettext_strings( $language_code ){
934
  $dictionary = $this->db->get_results( "SELECT id, original, translated, domain FROM `" . sanitize_text_field( $this->get_gettext_table_name( $language_code ) ) . "`", ARRAY_A );
935
  if ( is_array( $dictionary ) && count( $dictionary ) === 0 && !$this->table_exists($this->get_gettext_table_name( $language_code )) ){
includes/class-search.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class TRP_Search
5
+ *
6
+ * Queries for translations in custom trp tables.
7
+ *
8
+ */
9
+ class TRP_Search extends WP_Query{
10
+
11
+ protected $settings;
12
+ protected $db;
13
+
14
+
15
+ /**
16
+ * TRP_Search constructor.
17
+ * @param $settings
18
+ */
19
+ public function __construct( $settings ){
20
+
21
+
22
+ parent::__construct('');
23
+
24
+ global $wpdb;
25
+ $this->db = $wpdb;
26
+ $this->settings = $settings;
27
+ }
28
+
29
+ /**
30
+ * Filter function to replace the search results on other languages. Basically we destroy the search query by unseting the s query var and give it post__in argument with the
31
+ * results from our own query
32
+ * @param $query
33
+ * @return mixed
34
+ */
35
+ public function trp_search_filter( $query ) {
36
+ global $TRP_LANGUAGE;
37
+
38
+ if ( $TRP_LANGUAGE !== $this->settings['default-language'] ) {
39
+ if (!is_admin() && $query->is_main_query() && $query->is_search()) {
40
+
41
+ // Get the "s" query arg from the initial search
42
+ $search_query = get_query_var('s');
43
+
44
+
45
+ /* start adapted from parse_search() function from WP_Query */
46
+
47
+ // added slashes screw with quote grouping when done early, so done later
48
+ $search_query = stripslashes( $search_query );
49
+ // there are no line breaks in <input /> fields
50
+ $search_query = str_replace( array( "\r", "\n" ), '', $search_query );
51
+ $search_terms_count = 1;
52
+
53
+ if ( preg_match_all( '/".*?("|$)|((?<=[\t ",+])|^)[^\t ",+]+/', $search_query, $matches ) ) {
54
+ $search_terms_count = count( $matches[0] );
55
+ $search_terms = $this->parse_search_terms( $matches[0] );
56
+ // if the search string has only short terms or stopwords, or is 10+ terms long, match it as sentence
57
+ if ( empty( $search_terms ) || count( $search_terms ) > 9 ) {
58
+ $search_terms = array( $search_query );
59
+ $search_terms_count = 1;
60
+ }
61
+ } else {
62
+ $search_terms = array( $search_query );
63
+ }
64
+ /* end adapted from parse_search() function from WP_Query */
65
+
66
+
67
+ $trp = TRP_Translate_Press::get_trp_instance();
68
+ if ( ! $this->trp_query ) {
69
+ $this->trp_query = $trp->get_component( 'query' );
70
+ }
71
+
72
+ $search_result_ids = array();
73
+ $trp_search_query = '';
74
+ $dictionary_name = $this->trp_query->get_table_name( $TRP_LANGUAGE );
75
+ $meta_table_name = $this->trp_query->get_table_name_for_original_meta();
76
+
77
+ if( $search_terms_count === 1 ){
78
+ /**
79
+ * for one search term we can find it directly in the translated column
80
+ */
81
+ $trp_search_query = $this->db->prepare( "SELECT meta_value FROM
82
+ $dictionary_name
83
+ INNER JOIN $meta_table_name ON $dictionary_name.original_id = $meta_table_name.original_id AND $meta_table_name.meta_key = '". $this->trp_query->get_meta_key_for_post_parent_id() ."'
84
+ WHERE $dictionary_name.translated LIKE %s", '%' . $search_terms[0] . '%' );
85
+ }
86
+ else{
87
+ $where_terms_or = array();
88
+ $where_terms_and = array();
89
+ foreach ( $search_terms as $search_term ){
90
+ $where_terms_or[] = $this->db->prepare("$dictionary_name.translated LIKE %s", '%' . $search_term . '%');
91
+ $where_terms_and[] = $this->db->prepare("t1.tra LIKE %s", '%' . $search_term . '%');
92
+ }
93
+
94
+ $where_or = implode( ' OR ', $where_terms_or);
95
+ $where_and = implode( ' AND ', $where_terms_and);
96
+
97
+ /**
98
+ * in the inner SELECT we search for the translated strings in dictionaries that have either of the search terms ( OR )
99
+ * and their original strings belong to the same post_id and we combine them in a virtual column with GROUP_CONCAT()
100
+ * basically we recreate the translated post_content but in a random order (we don't care about the order of the strings)
101
+ * in the outer SELECT we search in the result from inner SELECT the values that have all the search terms (AND)
102
+ */
103
+ $trp_search_query = "SELECT meta_value FROM
104
+ ( SELECT meta_value, GROUP_CONCAT( translated SEPARATOR ' ' ) AS tra FROM $dictionary_name
105
+ INNER JOIN $meta_table_name ON $dictionary_name.original_id = $meta_table_name.original_id AND $meta_table_name.meta_key = '". $this->trp_query->get_meta_key_for_post_parent_id() ."'
106
+ WHERE ( ". $where_or ." ) GROUP BY meta_value ) AS t1
107
+ WHERE ( ".$where_and." )";
108
+
109
+ }
110
+
111
+ $search_result_ids = $this->db->get_results( $trp_search_query, OBJECT_K );
112
+ $search_result_ids = array_keys($search_result_ids);
113
+ if( !empty($search_result_ids) ) {
114
+ $query->set('s', '');
115
+ $query->set('post__in', $search_result_ids);
116
+ }
117
+ }
118
+ }
119
+
120
+ return $query;
121
+ }
122
+
123
+ /**
124
+ * In our search filter we unset the s variable from the query so we need to recreate it later from the $_GET
125
+ * @param $s string the search query var
126
+ * @return string
127
+ */
128
+ public function trp_search_query( $s ){
129
+ global $TRP_LANGUAGE;
130
+
131
+ if ( $TRP_LANGUAGE !== $this->settings['default-language'] ) {
132
+ if ( !is_admin() && isset( $_GET['s'] ) && empty( $s ) ){
133
+ $s = sanitize_text_field( $_GET['s'] );
134
+ }
135
+ }
136
+
137
+ return $s;
138
+ }
139
+ }
includes/class-settings.php CHANGED
@@ -251,6 +251,10 @@ class TRP_Settings{
251
  $this->trp_query->check_gettext_table( $language_code );
252
  }
253
 
 
 
 
 
254
  // regenerate permalinks in case something changed
255
  flush_rewrite_rules();
256
 
251
  $this->trp_query->check_gettext_table( $language_code );
252
  }
253
 
254
+ //in version 1.6.6 we normalized the original strings and created new tables
255
+ $this->trp_query->check_original_table();
256
+ $this->trp_query->check_original_meta_table();
257
+
258
  // regenerate permalinks in case something changed
259
  flush_rewrite_rules();
260
 
includes/class-translation-manager.php CHANGED
@@ -803,8 +803,13 @@ class TRP_Translation_Manager{
803
  $new_strings[] = $trp_gettext_string_for_machine_translation['original'];
804
  }
805
 
806
- // Gettext strings are always in the English language
807
- $machine_strings = $this->machine_translator->translate( $new_strings, $TRP_LANGUAGE, 'en_US' );
 
 
 
 
 
808
 
809
  if( !empty( $machine_strings ) ){
810
  foreach( $machine_strings as $key => $machine_string ){
803
  $new_strings[] = $trp_gettext_string_for_machine_translation['original'];
804
  }
805
 
806
+ // Gettext strings are considered by default to be in the English language
807
+ $source_language = apply_filters( 'trp_gettext_source_language', 'en_US', $TRP_LANGUAGE, $new_strings, $trp_gettext_strings_for_machine_translation );
808
+ if ( apply_filters( 'trp_gettext_allow_machine_translation', true, $source_language, $TRP_LANGUAGE, $new_strings, $trp_gettext_strings_for_machine_translation ) ){
809
+ $machine_strings = $this->machine_translator->translate( $new_strings, $TRP_LANGUAGE, $source_language );
810
+ }else{
811
+ $machine_strings = apply_filters( 'trp_gettext_machine_translate_strings', array(), $new_strings, $TRP_LANGUAGE, $trp_gettext_strings_for_machine_translation );
812
+ }
813
 
814
  if( !empty( $machine_strings ) ){
815
  foreach( $machine_strings as $key => $machine_string ){
includes/class-translation-render.php CHANGED
@@ -572,8 +572,11 @@ class TRP_Translation_Render{
572
  && !preg_match('/^\d+%$/',$trimmed_string)
573
  && !$this->has_ancestor_attribute( $row, $no_translate_attribute ) )
574
  {
575
- array_push( $translateable_strings, $trimmed_string );
576
  array_push( $nodes, array('node' => $row, 'type' => 'block'));
 
 
 
577
  }
578
  }
579
 
@@ -592,7 +595,7 @@ class TRP_Translation_Render{
592
  && !$this->has_ancestor_class( $row, 'translation-block') )
593
  {
594
  // $translateable_strings array needs to be in sync in $nodes array
595
- array_push( $translateable_strings, $trimmed_string );
596
  if( $parent->tag == 'button') {
597
  array_push($nodes, array('node' => $row, 'type' => 'button'));
598
  }
@@ -603,6 +606,9 @@ class TRP_Translation_Render{
603
  array_push( $nodes, array( 'node' => $row, 'type' => 'text' ) );
604
  }
605
  }
 
 
 
606
  }
607
  }
608
  //set up general links variables
@@ -650,6 +656,32 @@ class TRP_Translation_Render{
650
 
651
  do_action('trp_translateable_information', $translateable_information, $translated_strings, $language_code);
652
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  if ( $preview_mode ) {
654
  $translated_string_ids = $this->trp_query->get_string_ids($translateable_strings, $language_code);
655
  }
@@ -795,6 +827,14 @@ class TRP_Translation_Render{
795
  return $translatable_string;
796
  }
797
 
 
 
 
 
 
 
 
 
798
  /*
799
  * Update other image attributes (srcset) with the translated image
800
  *
@@ -1119,16 +1159,16 @@ class TRP_Translation_Render{
1119
  *
1120
  * @param object $node Html Node.
1121
  * @param string $attribute Attribute to search for.
1122
- * @return bool Whether given node has ancestor with given attribute.
1123
  */
1124
  public function has_ancestor_attribute($node,$attribute) {
1125
  $currentNode = $node;
1126
  if ( isset( $node->$attribute ) ){
1127
- return true;
1128
  }
1129
  while($currentNode->parent() && $currentNode->parent()->tag!="html") {
1130
  if(isset($currentNode->parent()->$attribute))
1131
- return true;
1132
  else
1133
  $currentNode = $currentNode->parent();
1134
  }
@@ -1253,19 +1293,20 @@ class TRP_Translation_Render{
1253
  $language_to_query = ( count ( $this->settings['translation-languages'] ) < 2 ) ? '' : $language_to_query;
1254
 
1255
  return array(
1256
- 'trp_custom_ajax_url' => apply_filters('trp_custom_ajax_url', TRP_PLUGIN_URL . 'includes/trp-ajax.php' ),
1257
- 'trp_wp_ajax_url' => apply_filters('trp_wp_ajax_url', admin_url('admin-ajax.php')),
1258
- 'trp_language_to_query' => $language_to_query,
1259
- 'trp_original_language' => $this->settings['default-language'],
1260
- 'trp_current_language' => $TRP_LANGUAGE,
1261
- 'trp_skip_selectors' => apply_filters( 'trp_skip_selectors_from_dynamic_translation', array( '[data-no-translation]', '[data-no-dynamic-translation]', '[data-trp-translate-id-innertext]', 'script', 'style', 'head', 'trp-span', 'translate-press' ), $TRP_LANGUAGE, $this->settings ), // data-trp-translate-id-innertext refers to translation block and it shouldn't be detected
1262
- 'trp_base_selectors' => $this->get_base_attribute_selectors(),
1263
- 'trp_attributes_selectors' => $this->get_node_accessors(),
1264
- 'trp_attributes_accessors' => $this->get_accessors_array(),
1265
- 'gettranslationsnonceregular' => $nonces['gettranslationsnonceregular'],
1266
- 'showdynamiccontentbeforetranslation' => apply_filters( 'trp_show_dynamic_content_before_translation', false ),
1267
- 'skip_strings_from_dynamic_translation' => apply_filters( 'trp_skip_strings_from_dynamic_translation', array() ),
1268
- 'duplicate_detections_allowed' => apply_filters( 'trp_duplicate_detections_allowed', 20 )
 
1269
  );
1270
  }
1271
 
@@ -1489,4 +1530,25 @@ class TRP_Translation_Render{
1489
 
1490
  return $translated;
1491
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1492
  }
572
  && !preg_match('/^\d+%$/',$trimmed_string)
573
  && !$this->has_ancestor_attribute( $row, $no_translate_attribute ) )
574
  {
575
+ $string_count = array_push( $translateable_strings, $trimmed_string );
576
  array_push( $nodes, array('node' => $row, 'type' => 'block'));
577
+
578
+ //add data-trp-post-id attribute if needed
579
+ $nodes = $this->maybe_add_post_id_in_node( $nodes, $row, $string_count );
580
  }
581
  }
582
 
595
  && !$this->has_ancestor_class( $row, 'translation-block') )
596
  {
597
  // $translateable_strings array needs to be in sync in $nodes array
598
+ $string_count = array_push( $translateable_strings, $trimmed_string );
599
  if( $parent->tag == 'button') {
600
  array_push($nodes, array('node' => $row, 'type' => 'button'));
601
  }
606
  array_push( $nodes, array( 'node' => $row, 'type' => 'text' ) );
607
  }
608
  }
609
+
610
+ //add data-trp-post-id attribute if needed
611
+ $nodes = $this->maybe_add_post_id_in_node( $nodes, $row, $string_count );
612
  }
613
  }
614
  //set up general links variables
656
 
657
  do_action('trp_translateable_information', $translateable_information, $translated_strings, $language_code);
658
 
659
+ //check for post_id meta on original strings, and insert for non existing
660
+ /*
661
+ * - get only strings that have the post_id in the nodes from $translateable_information
662
+ * - get the original id's for these string from the original table
663
+ * - see which of these id's have the meta with the current post_id value and insert into the meta table the ones that don't
664
+ *
665
+ */
666
+
667
+ if( !empty($translateable_information['nodes']) ){
668
+ $strings_in_post_content = array();
669
+ foreach ( $translateable_information['nodes'] as $i => $node ){
670
+ if( !empty( $node['post_id'] ) ){
671
+ $strings_in_post_content['strings'][] = $translateable_information['translateable_strings'][$i];
672
+ $strings_in_post_content['post_ids'][] = $node['post_id'];
673
+ }
674
+ }
675
+ if( !empty( $strings_in_post_content ) ){
676
+ $original_string_ids = $this->trp_query->get_original_string_ids($strings_in_post_content['strings']);
677
+
678
+ if( !empty( $original_string_ids ) ){
679
+ //there is a correlation between the two arrays
680
+ $this->trp_query->set_original_string_meta_post_id( $original_string_ids, $strings_in_post_content['post_ids'] );
681
+ }
682
+ }
683
+ }
684
+
685
  if ( $preview_mode ) {
686
  $translated_string_ids = $this->trp_query->get_string_ids($translateable_strings, $language_code);
687
  }
827
  return $translatable_string;
828
  }
829
 
830
+ public function maybe_add_post_id_in_node( $nodes, $row, $string_count ){
831
+ $post_container_node = $this->has_ancestor_attribute( $row, 'data-trp-post-id' );
832
+ if( $post_container_node && $post_container_node->attr['data-trp-post-id'] ) {
833
+ $nodes[$string_count - 1]['post_id'] = $post_container_node->attr['data-trp-post-id'];
834
+ }
835
+ return $nodes;
836
+ }
837
+
838
  /*
839
  * Update other image attributes (srcset) with the translated image
840
  *
1159
  *
1160
  * @param object $node Html Node.
1161
  * @param string $attribute Attribute to search for.
1162
+ * @return mixed Whether given node has ancestor with given attribute.
1163
  */
1164
  public function has_ancestor_attribute($node,$attribute) {
1165
  $currentNode = $node;
1166
  if ( isset( $node->$attribute ) ){
1167
+ return $node;
1168
  }
1169
  while($currentNode->parent() && $currentNode->parent()->tag!="html") {
1170
  if(isset($currentNode->parent()->$attribute))
1171
+ return $currentNode->parent();
1172
  else
1173
  $currentNode = $currentNode->parent();
1174
  }
1293
  $language_to_query = ( count ( $this->settings['translation-languages'] ) < 2 ) ? '' : $language_to_query;
1294
 
1295
  return array(
1296
+ 'trp_custom_ajax_url' => apply_filters( 'trp_custom_ajax_url', TRP_PLUGIN_URL . 'includes/trp-ajax.php' ),
1297
+ 'trp_wp_ajax_url' => apply_filters( 'trp_wp_ajax_url', admin_url( 'admin-ajax.php' ) ),
1298
+ 'trp_language_to_query' => $language_to_query,
1299
+ 'trp_original_language' => $this->settings['default-language'],
1300
+ 'trp_current_language' => $TRP_LANGUAGE,
1301
+ 'trp_skip_selectors' => apply_filters( 'trp_skip_selectors_from_dynamic_translation', array( '[data-no-translation]', '[data-no-dynamic-translation]', '[data-trp-translate-id-innertext]', 'script', 'style', 'head', 'trp-span', 'translate-press' ), $TRP_LANGUAGE, $this->settings ), // data-trp-translate-id-innertext refers to translation block and it shouldn't be detected
1302
+ 'trp_base_selectors' => $this->get_base_attribute_selectors(),
1303
+ 'trp_attributes_selectors' => $this->get_node_accessors(),
1304
+ 'trp_attributes_accessors' => $this->get_accessors_array(),
1305
+ 'gettranslationsnonceregular' => $nonces['gettranslationsnonceregular'],
1306
+ 'showdynamiccontentbeforetranslation' => apply_filters( 'trp_show_dynamic_content_before_translation', false ),
1307
+ 'skip_strings_from_dynamic_translation' => apply_filters( 'trp_skip_strings_from_dynamic_translation', array() ),
1308
+ 'skip_strings_from_dynamic_translation_for_substrings' => apply_filters( 'trp_skip_strings_from_dynamic_translation_for_substrings', array( 'href' => array('amazon-adsystem', 'googleads', 'g.doubleclick') ) ),
1309
+ 'duplicate_detections_allowed' => apply_filters( 'trp_duplicate_detections_allowed', 20 )
1310
  );
1311
  }
1312
 
1530
 
1531
  return $translated;
1532
  }
1533
+
1534
+
1535
+ function wrap_with_post_id( $content, $id = null ){
1536
+ global $post, $TRP_LANGUAGE;
1537
+
1538
+ if( empty($post->ID) )
1539
+ return $content;
1540
+
1541
+ //for the_tile filter we have an $id and we can compare it with the post we are on ..to avoid wrapping titles in menus for example
1542
+ if( !is_null( $id ) && $id !== $post->ID ){
1543
+ return $content;
1544
+ }
1545
+
1546
+ if ( $TRP_LANGUAGE !== $this->settings['default-language'] ) {
1547
+ if ( is_singular() && !empty($post->ID)) {
1548
+ $content = '<trp-post-container data-trp-post-id="' . $post->ID . '">' . $content . '</trp-post-container>';
1549
+ }
1550
+ }
1551
+
1552
+ return $content;
1553
+ }
1554
  }
includes/class-upgrade.php CHANGED
@@ -64,6 +64,11 @@ class TRP_Upgrade {
64
  if ( version_compare($stored_database_version, '1.6.1', '<=')) {
65
  $this->upgrade_machine_translation_settings();
66
  }
 
 
 
 
 
67
  }
68
 
69
  // don't update the db version unless they are different. Otherwise the query is run on every page load.
@@ -101,7 +106,31 @@ class TRP_Upgrade {
101
  'option_name' => 'trp_updated_database_gettext_empty_rows_145',
102
  'callback' => array( $this,'trp_updated_database_gettext_empty_rows_145'),
103
  'batch_size' => 20000
104
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  )
106
  );
107
  }
@@ -181,8 +210,17 @@ class TRP_Upgrade {
181
  }else{
182
  $_REQUEST['trp_updb_lang'] = $this->settings['translation-languages'][0];
183
  $_REQUEST['trp_updb_batch'] = 0;
184
- $request['progress_message'] .= '<p>' . sprintf(__('Updating database to version %s+', 'translatepress-multilingual' ), $updates_needed[ $_REQUEST['trp_updb_action'] ]['version'] ). '</p>';
185
- $request['progress_message'] .= sprintf(__('Processing table for language %s...', 'translatepress-multilingual' ), $_REQUEST['trp_updb_lang'] );
 
 
 
 
 
 
 
 
 
186
  }
187
  }else{
188
  if ( !isset( $updates_needed[ $_REQUEST['trp_updb_action'] ] ) ){
@@ -226,7 +264,7 @@ class TRP_Upgrade {
226
  $duration = $stop_time - $start_time;
227
  }
228
  if ( ! $finished_with_language ) {
229
- $request['trp_updb_batch'] = $get_batch + 1;
230
  }
231
 
232
 
@@ -237,7 +275,10 @@ class TRP_Upgrade {
237
  // next language code in array
238
  $request['trp_updb_lang'] = $this->settings['translation-languages'][ $index + 1 ];
239
  $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
240
- $request['progress_message'] .= '</br>' . sprintf(__('Processing table for language %s...', 'translatepress-multilingual' ), $request['trp_updb_lang'] );
 
 
 
241
  } else {
242
  // finish action due to completing all the translation languages
243
  $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
@@ -328,6 +369,68 @@ class TRP_Upgrade {
328
  }
329
  }
330
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
331
  /**
332
  * Remove duplicate rows from DB for trp_dictionary tables.
333
  * Removes untranslated strings if there is a translated version.
64
  if ( version_compare($stored_database_version, '1.6.1', '<=')) {
65
  $this->upgrade_machine_translation_settings();
66
  }
67
+ if ( version_compare( $stored_database_version, '1.6.5', '<=' ) ) {
68
+ $this->trp_query->check_for_original_id_column();
69
+ $this->trp_query->check_original_table();
70
+ $this->trp_query->check_original_meta_table();
71
+ }
72
  }
73
 
74
  // don't update the db version unless they are different. Otherwise the query is run on every page load.
106
  'option_name' => 'trp_updated_database_gettext_empty_rows_145',
107
  'callback' => array( $this,'trp_updated_database_gettext_empty_rows_145'),
108
  'batch_size' => 20000
109
+ ),
110
+ 'original_id_insert_166' => array(
111
+ 'version' => '1.6.6',
112
+ 'option_name' => 'trp_updated_database_original_id_insert_166',
113
+ 'callback' => array( $this,'trp_updated_database_original_id_insert_166'),
114
+ 'batch_size' => 1000,
115
+ 'message_processing'=> __('Inserting original strings for language %s...', 'translatepress-multilingual' )
116
+ ),
117
+ 'original_id_cleanup_166' => array(
118
+ 'version' => '1.6.6',
119
+ 'option_name' => 'trp_updated_database_original_id_cleanup_166',
120
+ 'callback' => array( $this,'trp_updated_database_original_id_cleanup_166'),
121
+ 'progress_message' => 'clean',
122
+ 'batch_size' => 1000,
123
+ 'message_initial' => '',
124
+ 'message_processing'=> __('Cleaning original strings table for language %s...', 'translatepress-multilingual' )
125
+ ),
126
+ 'original_id_update_166' => array(
127
+ 'version' => '1.6.6',
128
+ 'option_name' => 'trp_updated_database_original_id_update_166',
129
+ 'callback' => array( $this,'trp_updated_database_original_id_update_166'),
130
+ 'batch_size' => 5000,
131
+ 'message_initial' => '',
132
+ 'message_processing'=> __('Updating original string ids for language %s...', 'translatepress-multilingual' )
133
+ )
134
  )
135
  );
136
  }
210
  }else{
211
  $_REQUEST['trp_updb_lang'] = $this->settings['translation-languages'][0];
212
  $_REQUEST['trp_updb_batch'] = 0;
213
+
214
+ $update_message_initial = isset( $updates_needed[$_REQUEST['trp_updb_action']]['message_initial'] ) ?
215
+ $updates_needed[$_REQUEST['trp_updb_action']]['message_initial']
216
+ : __('Updating database to version %s+', 'translatepress-multilingual' );
217
+
218
+ $update_message_processing = isset( $updates_needed[$_REQUEST['trp_updb_action']]['message_processing'] ) ?
219
+ $updates_needed[$_REQUEST['trp_updb_action']]['message_processing']
220
+ : __('Processing table for language %s...', 'translatepress-multilingual' );
221
+
222
+ $request['progress_message'] .= '<p>' . sprintf( $update_message_initial, $updates_needed[ $_REQUEST['trp_updb_action'] ]['version'] ) . '</p>';
223
+ $request['progress_message'] .= sprintf( $update_message_processing, $_REQUEST['trp_updb_lang'] );
224
  }
225
  }else{
226
  if ( !isset( $updates_needed[ $_REQUEST['trp_updb_action'] ] ) ){
264
  $duration = $stop_time - $start_time;
265
  }
266
  if ( ! $finished_with_language ) {
267
+ $request['trp_updb_batch'] = $get_batch;
268
  }
269
 
270
 
275
  // next language code in array
276
  $request['trp_updb_lang'] = $this->settings['translation-languages'][ $index + 1 ];
277
  $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
278
+ $update_message_processing = isset( $updates_needed[$_REQUEST['trp_updb_action']]['message_processing'] ) ?
279
+ $updates_needed[$_REQUEST['trp_updb_action']]['message_processing']
280
+ : __('Processing table for language %s...', 'translatepress-multilingual' );
281
+ $request['progress_message'] .= '</br>' . sprintf( $update_message_processing, $request['trp_updb_lang'] );
282
  } else {
283
  // finish action due to completing all the translation languages
284
  $request['progress_message'] .= __(' done.', 'translatepress-multilingual' ) . '</br>';
369
  }
370
  }
371
 
372
+ /**
373
+ * Normalize original ids for all dictionary entries
374
+ *
375
+ * @param string $language_code Language code of the table
376
+ * @param int $inferior_limit Omit first X rows
377
+ * @param int $batch_size How many rows to query
378
+ *
379
+ * @return bool
380
+ */
381
+ public function trp_updated_database_original_id_insert_166( $language_code, $inferior_limit, $batch_size ){
382
+ if ( ! $this->trp_query ) {
383
+ $trp = TRP_Translate_Press::get_trp_instance();
384
+ /* @var TRP_Query */
385
+ $this->trp_query = $trp->get_component( 'query' );
386
+ }
387
+
388
+ $rows_inserted = $this->trp_query->original_ids_insert( $language_code, $inferior_limit, $batch_size );
389
+
390
+ if ( $rows_inserted > 0 ){
391
+ return false;
392
+ }else{
393
+ return true;
394
+ }
395
+ }
396
+
397
+ public function trp_updated_database_original_id_cleanup_166( $language_code, $inferior_limit, $batch_size ){
398
+ if ( ! $this->trp_query ) {
399
+ $trp = TRP_Translate_Press::get_trp_instance();
400
+ /* @var TRP_Query */
401
+ $this->trp_query = $trp->get_component( 'query' );
402
+ }
403
+
404
+ $this->trp_query->original_ids_cleanup();
405
+
406
+ return true;
407
+ }
408
+
409
+ /**
410
+ * Normalize original ids for all dictionary entries
411
+ *
412
+ * @param string $language_code Language code of the table
413
+ * @param int $inferior_limit Omit first X rows
414
+ * @param int $batch_size How many rows to query
415
+ *
416
+ * @return bool
417
+ */
418
+ public function trp_updated_database_original_id_update_166( $language_code, $inferior_limit, $batch_size ){
419
+ if ( ! $this->trp_query ) {
420
+ $trp = TRP_Translate_Press::get_trp_instance();
421
+ /* @var TRP_Query */
422
+ $this->trp_query = $trp->get_component( 'query' );
423
+ }
424
+
425
+ $rows_updated = $this->trp_query->original_ids_reindex( $language_code, $inferior_limit, $batch_size );
426
+
427
+ if ( $rows_updated > 0 ){
428
+ return false;
429
+ }else {
430
+ return true;
431
+ }
432
+ }
433
+
434
  /**
435
  * Remove duplicate rows from DB for trp_dictionary tables.
436
  * Removes untranslated strings if there is a translated version.
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 using a visual front-end translation editor, with full support for WooCommerce and site builders.
6
- Version: 1.6.5
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 using a visual front-end translation editor, with full support for WooCommerce and site builders.
6
+ Version: 1.6.6
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
@@ -136,6 +136,9 @@
136
  <?php __("Twitter Title", "translatepress-multilingual"); ?>
137
  <?php __("Twitter Description", "translatepress-multilingual"); ?>
138
  <?php __("Page Title", "translatepress-multilingual"); ?>
 
 
 
139
  <?php __("TranslatePress data update", "translatepress-multilingual"); ?>
140
  <?php __("We need to update your translations database to the latest version.", "translatepress-multilingual"); ?>
141
  <?php __("IMPORTANT: It is strongly recommended to first backup the database!\nAre you sure you want to continue?", "translatepress-multilingual"); ?>
136
  <?php __("Twitter Title", "translatepress-multilingual"); ?>
137
  <?php __("Twitter Description", "translatepress-multilingual"); ?>
138
  <?php __("Page Title", "translatepress-multilingual"); ?>
139
+ <?php __("Inserting original strings for language %s...", "translatepress-multilingual"); ?>
140
+ <?php __("Cleaning original strings table for language %s...", "translatepress-multilingual"); ?>
141
+ <?php __("Updating original string ids for language %s...", "translatepress-multilingual"); ?>
142
  <?php __("TranslatePress data update", "translatepress-multilingual"); ?>
143
  <?php __("We need to update your translations database to the latest version.", "translatepress-multilingual"); ?>
144
  <?php __("IMPORTANT: It is strongly recommended to first backup the database!\nAre you sure you want to continue?", "translatepress-multilingual"); ?>
languages/translatepress-multilingual.pot CHANGED
@@ -13,7 +13,7 @@ msgstr ""
13
  "X-Poedit-SourceCharset: UTF-8\n"
14
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
 
16
- #: ../tp-add-on-extra-languages/class-extra-languages.php:57, ../translatepress/includes/class-settings.php:374
17
  msgid "Error! Duplicate URL slug values."
18
  msgstr ""
19
 
@@ -253,31 +253,31 @@ msgstr ""
253
  msgid "Top Left"
254
  msgstr ""
255
 
256
- #: ../translatepress/includes/class-settings.php:410
257
  msgid "Current Language"
258
  msgstr ""
259
 
260
- #: ../translatepress/includes/class-settings.php:451
261
  msgid "General"
262
  msgstr ""
263
 
264
- #: ../translatepress/includes/class-settings.php:456, ../translatepress/includes/class-translation-manager.php:244
265
  msgid "Translate Site"
266
  msgstr ""
267
 
268
- #: ../translatepress/includes/class-settings.php:461
269
  msgid "Addons"
270
  msgstr ""
271
 
272
- #: ../translatepress/includes/class-settings.php:469
273
  msgid "License"
274
  msgstr ""
275
 
276
- #: ../translatepress/includes/class-settings.php:497, ../translatepress/includes/class-translation-manager.php:276
277
  msgid "Settings"
278
  msgstr ""
279
 
280
- #: ../translatepress/includes/class-settings.php:501
281
  msgid "Pro Features"
282
  msgstr ""
283
 
@@ -525,11 +525,11 @@ msgstr ""
525
  msgid "Translate Page"
526
  msgstr ""
527
 
528
- #: ../translatepress/includes/class-translation-manager.php:981
529
  msgid "Security check"
530
  msgstr ""
531
 
532
- #: ../translatepress/includes/class-translation-manager.php:1055
533
  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."
534
  msgstr ""
535
 
@@ -561,79 +561,91 @@ msgstr ""
561
  msgid "Page Title"
562
  msgstr ""
563
 
564
- #: ../translatepress/includes/class-upgrade.php:137
 
 
 
 
 
 
 
 
 
 
 
 
565
  msgid "TranslatePress data update"
566
  msgstr ""
567
 
568
- #: ../translatepress/includes/class-upgrade.php:137
569
  msgid "We need to update your translations database to the latest version."
570
  msgstr ""
571
 
572
- #: ../translatepress/includes/class-upgrade.php:138
573
  msgid "IMPORTANT: It is strongly recommended to first backup the database!\nAre you sure you want to continue?"
574
  msgstr ""
575
 
576
- #: ../translatepress/includes/class-upgrade.php:138
577
  msgid "Run the updater"
578
  msgstr ""
579
 
580
- #: ../translatepress/includes/class-upgrade.php:154
581
  msgid "Update aborted! Your user account doesn't have the capability to perform database updates."
582
  msgstr ""
583
 
584
- #: ../translatepress/includes/class-upgrade.php:159
585
  msgid "Update aborted! Invalid nonce."
586
  msgstr ""
587
 
588
- #: ../translatepress/includes/class-upgrade.php:174, ../translatepress/includes/class-upgrade.php:267, ../translatepress/includes/class-upgrade.php:353, ../translatepress/includes/class-upgrade.php:358
589
  msgid "Back to TranslatePress Settings"
590
  msgstr ""
591
 
592
- #: ../translatepress/includes/class-upgrade.php:178
593
  msgid "Successfully updated database!"
594
  msgstr ""
595
 
596
- #: ../translatepress/includes/class-upgrade.php:184
597
  msgid "Updating database to version %s+"
598
  msgstr ""
599
 
600
- #: ../translatepress/includes/class-upgrade.php:185, ../translatepress/includes/class-upgrade.php:240
601
  msgid "Processing table for language %s..."
602
  msgstr ""
603
 
604
- #: ../translatepress/includes/class-upgrade.php:189
605
  msgid "Update aborted! Incorrect action."
606
  msgstr ""
607
 
608
- #: ../translatepress/includes/class-upgrade.php:192
609
  msgid "Update aborted! Incorrect language code."
610
  msgstr ""
611
 
612
- #: ../translatepress/includes/class-upgrade.php:239, ../translatepress/includes/class-upgrade.php:243
613
  msgid " done."
614
  msgstr ""
615
 
616
- #: ../translatepress/includes/class-upgrade.php:353
617
  msgid "Done."
618
  msgstr ""
619
 
620
- #: ../translatepress/includes/class-upgrade.php:358
621
  msgid "Invalid nonce."
622
  msgstr ""
623
 
624
- #: ../translatepress/includes/class-upgrade.php:378
625
  msgid "Querying table <strong>%s</strong>"
626
  msgstr ""
627
 
628
- #: ../translatepress/includes/class-upgrade.php:408
629
  msgid "%s duplicates removed"
630
  msgstr ""
631
 
632
- #: ../translatepress/includes/class-upgrade.php:438
633
  msgid "If the page does not redirect automatically"
634
  msgstr ""
635
 
636
- #: ../translatepress/includes/class-upgrade.php:438
637
  msgid "click here"
638
  msgstr ""
639
 
13
  "X-Poedit-SourceCharset: UTF-8\n"
14
  "Plural-Forms: nplurals=2; plural=(n != 1);\n"
15
 
16
+ #: ../tp-add-on-extra-languages/class-extra-languages.php:57, ../translatepress/includes/class-settings.php:378
17
  msgid "Error! Duplicate URL slug values."
18
  msgstr ""
19
 
253
  msgid "Top Left"
254
  msgstr ""
255
 
256
+ #: ../translatepress/includes/class-settings.php:414
257
  msgid "Current Language"
258
  msgstr ""
259
 
260
+ #: ../translatepress/includes/class-settings.php:455
261
  msgid "General"
262
  msgstr ""
263
 
264
+ #: ../translatepress/includes/class-settings.php:460, ../translatepress/includes/class-translation-manager.php:244
265
  msgid "Translate Site"
266
  msgstr ""
267
 
268
+ #: ../translatepress/includes/class-settings.php:465
269
  msgid "Addons"
270
  msgstr ""
271
 
272
+ #: ../translatepress/includes/class-settings.php:473
273
  msgid "License"
274
  msgstr ""
275
 
276
+ #: ../translatepress/includes/class-settings.php:501, ../translatepress/includes/class-translation-manager.php:276
277
  msgid "Settings"
278
  msgstr ""
279
 
280
+ #: ../translatepress/includes/class-settings.php:505
281
  msgid "Pro Features"
282
  msgstr ""
283
 
525
  msgid "Translate Page"
526
  msgstr ""
527
 
528
+ #: ../translatepress/includes/class-translation-manager.php:986
529
  msgid "Security check"
530
  msgstr ""
531
 
532
+ #: ../translatepress/includes/class-translation-manager.php:1060
533
  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."
534
  msgstr ""
535
 
561
  msgid "Page Title"
562
  msgstr ""
563
 
564
+ #: ../translatepress/includes/class-upgrade.php:115
565
+ msgid "Inserting original strings for language %s..."
566
+ msgstr ""
567
+
568
+ #: ../translatepress/includes/class-upgrade.php:124
569
+ msgid "Cleaning original strings table for language %s..."
570
+ msgstr ""
571
+
572
+ #: ../translatepress/includes/class-upgrade.php:132
573
+ msgid "Updating original string ids for language %s..."
574
+ msgstr ""
575
+
576
+ #: ../translatepress/includes/class-upgrade.php:166
577
  msgid "TranslatePress data update"
578
  msgstr ""
579
 
580
+ #: ../translatepress/includes/class-upgrade.php:166
581
  msgid "We need to update your translations database to the latest version."
582
  msgstr ""
583
 
584
+ #: ../translatepress/includes/class-upgrade.php:167
585
  msgid "IMPORTANT: It is strongly recommended to first backup the database!\nAre you sure you want to continue?"
586
  msgstr ""
587
 
588
+ #: ../translatepress/includes/class-upgrade.php:167
589
  msgid "Run the updater"
590
  msgstr ""
591
 
592
+ #: ../translatepress/includes/class-upgrade.php:183
593
  msgid "Update aborted! Your user account doesn't have the capability to perform database updates."
594
  msgstr ""
595
 
596
+ #: ../translatepress/includes/class-upgrade.php:188
597
  msgid "Update aborted! Invalid nonce."
598
  msgstr ""
599
 
600
+ #: ../translatepress/includes/class-upgrade.php:203, ../translatepress/includes/class-upgrade.php:308, ../translatepress/includes/class-upgrade.php:456, ../translatepress/includes/class-upgrade.php:461
601
  msgid "Back to TranslatePress Settings"
602
  msgstr ""
603
 
604
+ #: ../translatepress/includes/class-upgrade.php:207
605
  msgid "Successfully updated database!"
606
  msgstr ""
607
 
608
+ #: ../translatepress/includes/class-upgrade.php:216
609
  msgid "Updating database to version %s+"
610
  msgstr ""
611
 
612
+ #: ../translatepress/includes/class-upgrade.php:220, ../translatepress/includes/class-upgrade.php:280
613
  msgid "Processing table for language %s..."
614
  msgstr ""
615
 
616
+ #: ../translatepress/includes/class-upgrade.php:227
617
  msgid "Update aborted! Incorrect action."
618
  msgstr ""
619
 
620
+ #: ../translatepress/includes/class-upgrade.php:230
621
  msgid "Update aborted! Incorrect language code."
622
  msgstr ""
623
 
624
+ #: ../translatepress/includes/class-upgrade.php:277, ../translatepress/includes/class-upgrade.php:284
625
  msgid " done."
626
  msgstr ""
627
 
628
+ #: ../translatepress/includes/class-upgrade.php:456
629
  msgid "Done."
630
  msgstr ""
631
 
632
+ #: ../translatepress/includes/class-upgrade.php:461
633
  msgid "Invalid nonce."
634
  msgstr ""
635
 
636
+ #: ../translatepress/includes/class-upgrade.php:481
637
  msgid "Querying table <strong>%s</strong>"
638
  msgstr ""
639
 
640
+ #: ../translatepress/includes/class-upgrade.php:511
641
  msgid "%s duplicates removed"
642
  msgstr ""
643
 
644
+ #: ../translatepress/includes/class-upgrade.php:541
645
  msgid "If the page does not redirect automatically"
646
  msgstr ""
647
 
648
+ #: ../translatepress/includes/class-upgrade.php:541
649
  msgid "click here"
650
  msgstr ""
651
 
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: translate, translation, multilingual, automatic translation, bilingual, fr
5
  Requires at least: 3.1.0
6
  Tested up to: 5.3.2
7
  Requires PHP: 5.6.20
8
- Stable tag: 1.6.5
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -143,6 +143,12 @@ For more information please check out [TranslatePress - Multilingual plugin docu
143
 
144
 
145
  == Changelog ==
 
 
 
 
 
 
146
  = 1.6.5 =
147
  * Fixed Exclude words from automatic translation when many excluded words are added
148
  * Compatibility with WooCommerce Fondy payment gateway
5
  Requires at least: 3.1.0
6
  Tested up to: 5.3.2
7
  Requires PHP: 5.6.20
8
+ Stable tag: 1.6.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
143
 
144
 
145
  == Changelog ==
146
+ = 1.6.6 =
147
+ * Implemented Search functionality in translated languages
148
+ * Added support for WooCommerce product search in translated languages
149
+ * Skip dynamic strings detection of ad links
150
+ * Added filters for adjusting gettext machine translation
151
+
152
  = 1.6.5 =
153
  * Fixed Exclude words from automatic translation when many excluded words are added
154
  * Compatibility with WooCommerce Fondy payment gateway