TranslatePress – Translate Multilingual sites - Version 1.3.2

Version Description

  • Speed improvements
  • Add support for the Ginger EU Cookie Law plugin
  • Add support for data-no-dynamic-translation attribute that skips dynamic strings from being translated by dom changes detector
  • Fixed Edit Pencil icon css in Translation Editor for some sites
  • Refactored the way we add trp-gettext tag. This should have a lot of benefits in compatibility with other plugins
  • Optimized block translation detection
  • Added caching to trp_x function when reading external .mo files
  • Fixed issue with translatepress icon css that was broken on wpforms forms
  • Added secret page for removing duplicate rows from database: wp-admin/admin.php?page=trp_remove_duplicate_rows
Download this release

Release Info

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

Code changes from version 1.3.1 to 1.3.2

assets/css/trp-preview-iframe-style.css CHANGED
@@ -6,27 +6,27 @@
6
  width: 30px !important;
7
  height: 30px !important;
8
  display: inline-block;
9
- position: absolute;
10
  margin-left: -30px !important;
11
- cursor: pointer;
12
  pointer-events: auto;
13
- color: #fff;
14
- min-width: 30px;
15
- min-height: 30px;
16
  line-height: 1em!important;
17
- font-size: 18px;
18
- z-index: 5;
19
  background: #0085ba!important;
20
- -webkit-border-radius: 50%;
21
- border-radius: 50%;
22
- border: 2px solid #fff;
23
- -webkit-box-shadow: 0 2px 1px rgba(46,68,83,.15);
24
- box-shadow: 0 2px 1px rgba(46,68,83,.15);
25
- text-align: center;
26
- -webkit-box-sizing: border-box;
27
- -moz-box-sizing: border-box;
28
- box-sizing: border-box;
29
- padding: 3px;
30
  }
31
 
32
  .trp-icon:hover {
@@ -47,7 +47,7 @@
47
  }
48
 
49
  .trp-highlight{
50
- outline: 2px solid #e2e4e7;
51
  }
52
 
53
  *[data-trpgettextoriginal] .trp-icon, .trpgettext-wrap .trp-icon{
6
  width: 30px !important;
7
  height: 30px !important;
8
  display: inline-block;
9
+ position: absolute !important;
10
  margin-left: -30px !important;
11
+ cursor: pointer !important;
12
  pointer-events: auto;
13
+ color: #fff !important;
14
+ min-width: 30px !important;
15
+ min-height: 30px !important;
16
  line-height: 1em!important;
17
+ font-size: 18px !important;
18
+ z-index: 5 !important;
19
  background: #0085ba!important;
20
+ -webkit-border-radius: 50% !important;
21
+ border-radius: 50% !important;
22
+ border: 2px solid #fff !important;
23
+ -webkit-box-shadow: 0 2px 1px rgba(46,68,83,.15) !important;
24
+ box-shadow: 0 2px 1px rgba(46,68,83,.15) !important;
25
+ text-align: center !important;
26
+ -webkit-box-sizing: border-box !important;
27
+ -moz-box-sizing: border-box !important;
28
+ box-sizing: border-box !important;
29
+ padding: 3px !important;
30
  }
31
 
32
  .trp-icon:hover {
47
  }
48
 
49
  .trp-highlight{
50
+ outline: 2px solid #e2e4e7 !important;
51
  }
52
 
53
  *[data-trpgettextoriginal] .trp-icon, .trpgettext-wrap .trp-icon{
assets/js/trp-translate-dom-changes.js CHANGED
@@ -129,18 +129,17 @@ function TRP_Translator(){
129
  if ( mutation.addedNodes[i].textContent && _this.trim( mutation.addedNodes[i].textContent.trim(), except_characters ) != '' ) {
130
  var node = jQuery( mutation.addedNodes[i] );
131
 
132
- var noTranslation = node.attr( 'data-no-translation' );
133
- if ( (typeof noTranslation !== typeof undefined && noTranslation !== false) || node.parents( '[data-no-translation]').length > 0 ){
134
- continue;
135
- }
136
-
137
- var gettextString = node.attr( 'data-trpgettextoriginal' );
138
- if ( (typeof gettextString !== typeof undefined && gettextString !== false) || node.parents( '[data-trpgettextoriginal]').length > 0 ){
139
- continue;
 
140
  }
141
-
142
- var simpleString = node.attr( 'data-trp-translate-id' );
143
- if ( (typeof simpleString !== typeof undefined && simpleString !== false) || node.parents( '[data-trp-translate-id]').length > 0 ){
144
  continue;
145
  }
146
 
129
  if ( mutation.addedNodes[i].textContent && _this.trim( mutation.addedNodes[i].textContent.trim(), except_characters ) != '' ) {
130
  var node = jQuery( mutation.addedNodes[i] );
131
 
132
+ // skip nodes containing these attributes
133
+ var attr_array = ['data-no-translation', 'data-no-dynamic-translation', 'data-trpgettextoriginal', 'data-trp-translate-id'];
134
+ var skip_string = false;
135
+ for (var at = 0; at < attr_array.length ; at++ ){
136
+ var current_attribute = node.attr( attr_array[ at ] );
137
+ if ( (typeof current_attribute !== typeof undefined && current_attribute !== false) || node.parents( '[' + attr_array[ at ] + ']').length > 0 ){
138
+ skip_string = true;
139
+ break;
140
+ }
141
  }
142
+ if ( skip_string ){
 
 
143
  continue;
144
  }
145
 
class-translate-press.php CHANGED
@@ -39,7 +39,7 @@ class TRP_Translate_Press{
39
  define( 'TRP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
40
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
41
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
42
- define( 'TRP_PLUGIN_VERSION', '1.3.1' );
43
 
44
  $this->load_dependencies();
45
  $this->initialize_components();
@@ -181,13 +181,6 @@ class TRP_Translate_Press{
181
  $this->loader->add_action( 'admin_init', $this->translation_manager, 'apply_gettext_filter' );
182
  $this->loader->add_action( 'shutdown', $this->translation_manager, 'machine_translate_gettext', 100 );
183
 
184
- /* we need the esc_ functions for html and attributes not to escape our tags so we put them back */
185
- $this->loader->add_filter( 'esc_html', $this->translation_manager, 'handle_esc_functions_for_gettext', 10, 2 );
186
- $this->loader->add_filter( 'attribute_escape', $this->translation_manager, 'handle_esc_functions_for_gettext', 10, 2 );
187
- /* we need to allow the trp-gettext tag in kses functions */
188
- $this->loader->add_filter( 'wp_kses_allowed_html', $this->translation_manager, 'handle_kses_functions_for_gettext', 10 );
189
- /* handle trp-gettext tag from attributes of other tags in kses functions*/
190
- $this->loader->add_filter( 'pre_kses', $this->translation_manager, 'escape_gettext_from_attributes_kses', 5, 3 );
191
 
192
  /* we need to treat the date_i18n function differently so we remove the gettext wraps */
193
  $this->loader->add_filter( 'date_i18n', $this->translation_manager, 'handle_date_i18n_function_for_gettext', 1, 4 );
39
  define( 'TRP_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
40
  define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
41
  define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
42
+ define( 'TRP_PLUGIN_VERSION', '1.3.2' );
43
 
44
  $this->load_dependencies();
45
  $this->initialize_components();
181
  $this->loader->add_action( 'admin_init', $this->translation_manager, 'apply_gettext_filter' );
182
  $this->loader->add_action( 'shutdown', $this->translation_manager, 'machine_translate_gettext', 100 );
183
 
 
 
 
 
 
 
 
184
 
185
  /* we need to treat the date_i18n function differently so we remove the gettext wraps */
186
  $this->loader->add_filter( 'date_i18n', $this->translation_manager, 'handle_date_i18n_function_for_gettext', 1, 4 );
includes/class-query.php CHANGED
@@ -87,8 +87,9 @@ class TRP_Query{
87
  }
88
 
89
  $query .= "( " . implode ( ", ", $placeholders ) . " )";
90
- $dictionary = $this->db->get_results( $this->db->prepare( $query, $values ), OBJECT_K );
91
- return $dictionary;
 
92
  }
93
 
94
  /**
@@ -461,7 +462,7 @@ class TRP_Query{
461
  * @param string $default_language Default language. Defaults to the one from settings.
462
  * @return string Table name.
463
  */
464
- protected function get_table_name( $language_code, $default_language = null ){
465
  if ( $default_language == null ) {
466
  $default_language = $this->settings['default-language'];
467
  }
@@ -488,7 +489,7 @@ class TRP_Query{
488
  return $dictionary;
489
  }
490
 
491
- protected function get_gettext_table_name( $language_code ){
492
  global $wpdb;
493
  return $wpdb->get_blog_prefix() . 'trp_gettext_' . strtolower( $language_code );
494
  }
@@ -618,4 +619,65 @@ class TRP_Query{
618
 
619
  return $this->db->query( $this->db->prepare( $query, $values ) );
620
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
621
  }
87
  }
88
 
89
  $query .= "( " . implode ( ", ", $placeholders ) . " )";
90
+ $prepared_query = $this->db->prepare( $query, $values );
91
+ $dictionary = $this->db->get_results( $prepared_query, OBJECT_K );
92
+ return apply_filters( 'trp_get_existing_translations', $dictionary, $prepared_query );
93
  }
94
 
95
  /**
462
  * @param string $default_language Default language. Defaults to the one from settings.
463
  * @return string Table name.
464
  */
465
+ public function get_table_name( $language_code, $default_language = null ){
466
  if ( $default_language == null ) {
467
  $default_language = $this->settings['default-language'];
468
  }
489
  return $dictionary;
490
  }
491
 
492
+ public function get_gettext_table_name( $language_code ){
493
  global $wpdb;
494
  return $wpdb->get_blog_prefix() . 'trp_gettext_' . strtolower( $language_code );
495
  }
619
 
620
  return $this->db->query( $this->db->prepare( $query, $values ) );
621
  }
622
+
623
+ /**
624
+ * Removes duplicate rows of regular strings table
625
+ *
626
+ * (original, translated, status, block_type) have to be identical.
627
+ * Only the row with the lowest ID remains
628
+ *
629
+ * https://stackoverflow.com/a/25206828
630
+ *
631
+ * @param $table
632
+ */
633
+ public function remove_duplicate_rows_in_dictionary_table( $language_code, $batch ){
634
+ $table_name = $this->get_table_name( $language_code );
635
+ $query = ' DELETE `b`
636
+ FROM
637
+ ' . $table_name . ' AS `a`,
638
+ ' . $table_name . ' AS `b`
639
+ WHERE
640
+ -- IMPORTANT: Ensures one version remains
641
+ `a`.ID < ' . $batch . '
642
+ AND `b`.ID < ' . $batch . '
643
+ AND `a`.`ID` < `b`.`ID`
644
+
645
+ -- Check for all duplicates. Binary ensure case sensitive comparison
646
+ AND (`a`.`original` = BINARY `b`.`original` OR `a`.`original` IS NULL AND `b`.`original` IS NULL)
647
+ AND (`a`.`translated` = BINARY`b`.`translated` OR `a`.`translated` IS NULL AND `b`.`translated` IS NULL)
648
+ AND (`a`.`status` = `b`.`status` OR `a`.`status` IS NULL AND `b`.`status` IS NULL)
649
+ AND (`a`.`block_type` = `b`.`block_type` OR `a`.`block_type` IS NULL AND `b`.`block_type` IS NULL)
650
+ ;';
651
+ return $this->db->query( $query );
652
+ }
653
+
654
+ /**
655
+ * Removes a row if translation status 0, if the original exists translated
656
+ *
657
+ * Only the original with translation remains
658
+ */
659
+ public function remove_untranslated_strings_if_translation_available( $language_code ){
660
+ $table_name = $this->get_table_name( $language_code );
661
+ $query = ' DELETE `a`
662
+ FROM
663
+ ' . $table_name . ' AS `a`,
664
+ ' . $table_name . ' AS `b`
665
+ WHERE
666
+ (`a`.`original` = BINARY `b`.`original` OR `a`.`original` IS NULL AND `b`.`original` IS NULL)
667
+ AND (`a`.`status` = 0 )
668
+ AND (`b`.`status` != 0 )
669
+ AND (`a`.`block_type` = `b`.`block_type` OR `a`.`block_type` IS NULL AND `b`.`block_type` IS NULL)
670
+ ;';
671
+ return $this->db->query( $query );
672
+ }
673
+
674
+ /*
675
+ * Get last inserted ID for this table
676
+ *
677
+ * Useful for optimizing database by removing duplicate rows
678
+ */
679
+ public function get_last_id( $table_name ){
680
+ $last_id = $this->db->get_var("SELECT MAX(id) FROM " . $table_name );
681
+ return $last_id;
682
+ }
683
  }
includes/class-settings.php CHANGED
@@ -68,6 +68,7 @@ class TRP_Settings{
68
  add_options_page( 'TranslatePress', 'TranslatePress', apply_filters( 'trp_settings_capability', 'manage_options' ), 'translate-press', array( $this, 'settings_page_content' ) );
69
  add_submenu_page( 'TRPHidden', 'TranslatePress Addons', 'TRPHidden', 'manage_options', 'trp_addons_page', array($this, 'addons_page_content') );
70
  add_submenu_page( 'TRPHidden', 'TranslatePress Test Google API Key', 'TRPHidden', 'manage_options', 'trp_test_google_key_page', array($this, 'test_google_key_page_content') );
 
71
  }
72
 
73
  /**
@@ -90,12 +91,120 @@ class TRP_Settings{
90
  }
91
 
92
  /**
93
- * Addons page content.
94
  */
95
  public function test_google_key_page_content(){
96
  require_once TRP_PLUGIN_DIR . 'partials/test-google-key-settings-page.php';
97
  }
98
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
  /**
100
  * Register settings option.
101
  */
68
  add_options_page( 'TranslatePress', 'TranslatePress', apply_filters( 'trp_settings_capability', 'manage_options' ), 'translate-press', array( $this, 'settings_page_content' ) );
69
  add_submenu_page( 'TRPHidden', 'TranslatePress Addons', 'TRPHidden', 'manage_options', 'trp_addons_page', array($this, 'addons_page_content') );
70
  add_submenu_page( 'TRPHidden', 'TranslatePress Test Google API Key', 'TRPHidden', 'manage_options', 'trp_test_google_key_page', array($this, 'test_google_key_page_content') );
71
+ add_submenu_page( 'TRPHidden', 'TranslatePress Remove Duplicate Rows', 'TRPHidden', 'manage_options', 'trp_remove_duplicate_rows', array($this, 'trp_remove_duplicate_rows') );
72
  }
73
 
74
  /**
91
  }
92
 
93
  /**
94
+ * Test Google Key page content.
95
  */
96
  public function test_google_key_page_content(){
97
  require_once TRP_PLUGIN_DIR . 'partials/test-google-key-settings-page.php';
98
  }
99
 
100
+ /**
101
+ * Remove duplicate rows from DB for trp_dictionary tables.
102
+ * Removes untranslated strings if there is a translated version.
103
+ *
104
+ * Iterates over languages. Each language is iterated in batches of 10 000
105
+ */
106
+ public function trp_remove_duplicate_rows(){
107
+ if ( ! current_user_can( 'manage_options' ) ){
108
+ return;
109
+ }
110
+ // prepare page structure
111
+ require_once TRP_PLUGIN_DIR . 'partials/trp-remove-duplicate-rows.php';
112
+
113
+ if ( empty( $_GET['trp_rm_duplicates'] ) ){
114
+ // iteration not started
115
+ return;
116
+ }
117
+ if ( $_GET['trp_rm_duplicates'] === 'done' ){
118
+ // iteration finished
119
+ echo __('Done.', '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>';
120
+ return;
121
+ }
122
+ $nonce = wp_verify_nonce( $_GET['trp_rm_nonce'], 'tpremoveduplicaterows' );
123
+ if ( $nonce === false ){
124
+ 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>';
125
+ return;
126
+ }
127
+
128
+ $next_get_batch = 1;
129
+ $batch_size = apply_filters( 'trp_rm_duplicate_batch_size', 10000 );
130
+ if ( !empty( $_GET['trp_rm_batch_size'] ) && (int) $_GET['trp_rm_batch'] > 0 ){
131
+ $batch_size = (int) $_GET['trp_rm_batch_size'];
132
+ }
133
+ if ( in_array( $_GET['trp_rm_duplicates'], $this->settings['translation-languages'] ) ) {
134
+ // language code found in array
135
+ $language_code = $_GET['trp_rm_duplicates'];
136
+ // skip default language since it doesn't have a table
137
+ if ( $language_code != $this->settings['default-language'] ) {
138
+ if ( ! $this->trp_query ) {
139
+ $trp = TRP_Translate_Press::get_trp_instance();
140
+ /* @var TRP_Query */
141
+ $this->trp_query = $trp->get_component( 'query' );
142
+ }
143
+ $table_name = $this->trp_query->get_table_name( $language_code );
144
+ echo '<div>' . sprintf( __( 'Querying table <strong>%s</strong>', 'translatepress-multilingual' ), $table_name ) . '</div>';
145
+
146
+ $last_id = $this->trp_query->get_last_id( $table_name );
147
+ if ( !empty( $_GET['trp_rm_batch'] ) && (int) $_GET['trp_rm_batch'] > 0 ) {
148
+ $get_batch = (int)$_GET['trp_rm_batch'];
149
+ }else{
150
+ $get_batch = 1;
151
+ }
152
+ $batch = $batch_size * $get_batch;
153
+
154
+ /* Execute this query only for string with ID < $batch. This ensures that the query is fast.
155
+ * Deleting duplicate rows for the first 20k rows might take too long.
156
+ * As a solution we are deleting the duplicates of the first 10k rows ( 1 to 10 000),
157
+ * then delete duplicates of the first 20k rows( 1 to 20 000, not 10 000 to 20 000 because we there could still be duplicates).
158
+ * Same goes for higher numbers.
159
+ */
160
+ $result1 = $this->trp_query->remove_duplicate_rows_in_dictionary_table( $language_code, $batch );
161
+ $result2 = 0;
162
+ if ( $batch > $last_id ){
163
+ // execute this query only when we do not have any more duplicate rows
164
+ $result2 = $this->trp_query->remove_untranslated_strings_if_translation_available( $language_code );
165
+ }else{
166
+ $next_get_batch = $get_batch + 1;
167
+ }
168
+
169
+ if ( ( $result1 === false ) || ( $result2 === false ) ) {
170
+ // if query outputted error do not continue iteration
171
+ return;
172
+ }else{
173
+ $result = $result1 + $result2;
174
+ echo '<div>' . sprintf( __( '%s duplicates removed', 'translatepress-multilingual' ), $result ) . '</div>';
175
+ }
176
+ }
177
+ if ( $next_get_batch == 1 ) {
178
+ // finished with the current language
179
+ $index = array_search( $language_code, $this->settings['translation-languages'] );
180
+ if ( isset ( $this->settings['translation-languages'][ $index + 1 ] ) ) {
181
+ // next language code in array
182
+ $next_language = $this->settings['translation-languages'][ $index + 1 ];
183
+ } else {
184
+ // finish iteration due to completing all the translation languages
185
+ $next_language = 'done';
186
+ }
187
+ }else{
188
+ $next_language = $language_code;
189
+ }
190
+ }else{
191
+ // finish iteration due to incorrect translation language
192
+ $next_language = 'done';
193
+ }
194
+
195
+ // construct and redirect to next url
196
+ $url = add_query_arg( array(
197
+ 'page' => 'trp_remove_duplicate_rows',
198
+ 'trp_rm_duplicates' => $next_language,
199
+ 'trp_rm_batch' => $next_get_batch,
200
+ 'trp_rm_batch_size' => $batch_size,
201
+ 'trp_rm_nonce' => wp_create_nonce('tpremoveduplicaterows')
202
+ ), site_url('wp-admin/admin.php') );
203
+ echo "<meta http-equiv='refresh' content='0; url={$url}' />";
204
+ echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
205
+ exit;
206
+ }
207
+
208
  /**
209
  * Register settings option.
210
  */
includes/class-translation-manager.php CHANGED
@@ -84,11 +84,11 @@ class TRP_Translation_Manager{
84
  'metainformation' => __( 'Meta Information', 'translatepress-multilingual' ),
85
  'stringlist' => __( 'String List', 'translatepress-multilingual' ),
86
  'dynamicstrings' => __( 'Dynamic Added Strings', 'translatepress-multilingual' ),
87
- 'gettranslationsnonce' => wp_create_nonce('get_translations'), 'translatepress-multilingual',
88
- 'savestringsnonce' => wp_create_nonce('save_translations'), 'translatepress-multilingual',
89
- 'splittbnonce' => wp_create_nonce('split_translation_block'), 'translatepress-multilingual',
90
- 'gettextgettranslationsnonce' => wp_create_nonce('gettext_get_translations'), 'translatepress-multilingual',
91
- 'gettextsavetranslationsnonce' => wp_create_nonce('gettext_save_translations'), 'translatepress-multilingual',
92
  'showdynamiccontentbeforetranslation' => apply_filters( 'trp_show_dynamic_content_before_translation', false )
93
  );
94
  return $text;
@@ -923,7 +923,6 @@ class TRP_Translation_Manager{
923
  $callstack_function['function'] == 'get_bloginfo' ||
924
  $callstack_function['function'] == 'wp_get_document_title' ||
925
  $callstack_function['function'] == 'wp_title' ||
926
- $callstack_function['function'] == 'wptexturize' ||
927
  $callstack_function['function'] == 'wp_trim_words'
928
  ) {
929
  return $translation;
@@ -943,7 +942,7 @@ class TRP_Translation_Manager{
943
  }
944
 
945
  if( ( !empty($TRP_LANGUAGE) && $this->settings["default-language"] != $TRP_LANGUAGE ) || ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) )
946
- $translation = '<trp-gettext data-trpgettextoriginal=\'' . $db_id . '\'>' . $translation . '</trp-gettext>';
947
  }
948
 
949
  return $translation;
@@ -1034,77 +1033,6 @@ class TRP_Translation_Manager{
1034
  }
1035
  }
1036
 
1037
- /* we need the esc_ functions for html and attributes not to escape our tags so we put them back */
1038
- function handle_esc_functions_for_gettext( $safe_text, $text ){
1039
- if( preg_match( '/(&lt;)trp-gettext (.*?)(&gt;)/', $safe_text, $matches ) ) {
1040
- if( !empty($matches[2]) ) {
1041
- $safe_text = preg_replace('/(&lt;)trp-gettext (.*?)(&gt;)/', "<trp-gettext " . htmlspecialchars_decode( $matches[2], ENT_QUOTES ) . ">", $safe_text);
1042
- $safe_text = preg_replace('/(&lt;)(.?)\/trp-gettext(&gt;)/', '</trp-gettext>', $safe_text);
1043
- }
1044
- }
1045
-
1046
- return $safe_text;
1047
- }
1048
-
1049
- /* let the trp-gettext wrap and data-trpgettextoriginal pass through kses filters */
1050
- function handle_kses_functions_for_gettext( $tags ){
1051
- if( is_array($tags) ){
1052
- $tags['trp-gettext'] = array( 'data-trpgettextoriginal' => true );
1053
- }
1054
- return $tags;
1055
- }
1056
-
1057
- /**
1058
- * Copy function of esc_attr, unfiltered.
1059
- *
1060
- * Needed because all esc functions are hooked to handle_esc_functions_for_gettext, which will not escape trp-gettext tags
1061
- *
1062
- * @param $text string Text to escape
1063
- *
1064
- * @return string Escaped text
1065
- */
1066
- function esc_attr_unfilttered( $text ){
1067
- $safe_text = wp_check_invalid_utf8( $text );
1068
- $safe_text = _wp_specialchars( $safe_text, ENT_QUOTES );
1069
- return $safe_text;
1070
- }
1071
-
1072
- /**
1073
- * Escape attributes containing trp-gettext tag before passing to wp_kses.
1074
- *
1075
- * wp_kses will accidentally escape the parent tag, if another unescaped tag is present withing its attribute
1076
- * Ex. <img alt="<trp-gettext>Placeholder</trp-gettext">"/> will be transformed by trp-gettext like this: &lt;img alt=&quot;<trp-gettext>Placeholder</trp-gettext">"/>
1077
- *
1078
- * As a side consequence this function will disable translation of the string contained in the trp-gettext tag because there is no hook available that will allow us to undo the escaping the tags, after wp_kses is finished
1079
- *
1080
- * @param $string
1081
- * @param $allowed_html
1082
- * @param $allowed_protocols
1083
- *
1084
- * @return mixed
1085
- */
1086
- function escape_gettext_from_attributes_kses( $string, $allowed_html, $allowed_protocols ){
1087
- /* remove trp-gettext tag from attributes of other tags in kses functions*/
1088
- $html_modified = false;
1089
- if ( !is_admin () && strpos( $string, 'trp-gettext' ) !== false ) {
1090
- $html = trp_str_get_html($string, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
1091
- foreach ( $html->find("*[!nuartrebuisaexiteatributulasta]") as $k => $row ) {
1092
- $all_attributes = $row->getAllAttributes();
1093
- if ( ! empty( $all_attributes ) ) {
1094
- foreach ( $all_attributes as $attr_name => $attr_value ) {
1095
- if ( strpos( $attr_value, 'trp-gettext' ) !== false ) {
1096
- $row->setAttribute($attr_name, $this->esc_attr_unfilttered($attr_value));
1097
- $html_modified = true;
1098
- }
1099
- }
1100
- }
1101
- }
1102
- if ( $html_modified ){
1103
- $string = $html->save();
1104
- }
1105
- }
1106
- return $string;
1107
- }
1108
 
1109
 
1110
  /**
@@ -1114,8 +1042,8 @@ class TRP_Translation_Manager{
1114
  function handle_date_i18n_function_for_gettext( $j, $dateformatstring, $unixtimestamp, $gmt ){
1115
 
1116
  /* remove trp-gettext wrap */
1117
- $dateformatstring = preg_replace( '/(<|&lt;)trp-gettext (.*?)(>|&gt;)/', '', $dateformatstring );
1118
- $dateformatstring = preg_replace( '/(<|&lt;)(.?)\/trp-gettext(>|&gt;)/', '', $dateformatstring );
1119
 
1120
 
1121
  global $wp_locale;
84
  'metainformation' => __( 'Meta Information', 'translatepress-multilingual' ),
85
  'stringlist' => __( 'String List', 'translatepress-multilingual' ),
86
  'dynamicstrings' => __( 'Dynamic Added Strings', 'translatepress-multilingual' ),
87
+ 'gettranslationsnonce' => wp_create_nonce('get_translations'),
88
+ 'savestringsnonce' => wp_create_nonce('save_translations'),
89
+ 'splittbnonce' => wp_create_nonce('split_translation_block'),
90
+ 'gettextgettranslationsnonce' => wp_create_nonce('gettext_get_translations'),
91
+ 'gettextsavetranslationsnonce' => wp_create_nonce('gettext_save_translations'),
92
  'showdynamiccontentbeforetranslation' => apply_filters( 'trp_show_dynamic_content_before_translation', false )
93
  );
94
  return $text;
923
  $callstack_function['function'] == 'get_bloginfo' ||
924
  $callstack_function['function'] == 'wp_get_document_title' ||
925
  $callstack_function['function'] == 'wp_title' ||
 
926
  $callstack_function['function'] == 'wp_trim_words'
927
  ) {
928
  return $translation;
942
  }
943
 
944
  if( ( !empty($TRP_LANGUAGE) && $this->settings["default-language"] != $TRP_LANGUAGE ) || ( isset( $_REQUEST['trp-edit-translation'] ) && $_REQUEST['trp-edit-translation'] == 'preview' ) )
945
+ $translation = '#!trpst#trp-gettext data-trpgettextoriginal=' . $db_id . '#!trpen#' . $translation . '#!trpst#/trp-gettext#!trpen#';//add special start and end tags so that it does not influence html in any way. we will replace them with < and > at the start of the translate function
946
  }
947
 
948
  return $translation;
1033
  }
1034
  }
1035
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1036
 
1037
 
1038
  /**
1042
  function handle_date_i18n_function_for_gettext( $j, $dateformatstring, $unixtimestamp, $gmt ){
1043
 
1044
  /* remove trp-gettext wrap */
1045
+ $dateformatstring = preg_replace( '/#!trpst#trp-gettext (.*?)#!trpen#/', '', $dateformatstring );
1046
+ $dateformatstring = preg_replace( '/#!trpst#(.?)\/trp-gettext#!trpen#/', '', $dateformatstring );
1047
 
1048
 
1049
  global $wp_locale;
includes/class-translation-render.php CHANGED
@@ -252,7 +252,7 @@ class TRP_Translation_Render{
252
  if ( in_array( $row->tag, $merge_rules['top_parents'] ) ){
253
  $trimmed_inner_text = $this->trim_translation_block( $row->innertext );
254
  foreach( $all_existing_translation_blocks as $existing_translation_block ){
255
- if ( $this->trim_translation_block( $existing_translation_block->original ) == $trimmed_inner_text ){
256
  return $existing_translation_block;
257
  }
258
  }
@@ -281,6 +281,11 @@ class TRP_Translation_Render{
281
  * @return string Translated HTML page.
282
  */
283
  public function translate_page( $output ){
 
 
 
 
 
284
  $output = apply_filters('trp_before_translate_content', $output);
285
 
286
  if ( strlen( $output ) < 1 || $output == false ){
@@ -370,6 +375,10 @@ class TRP_Translation_Render{
370
  $this->translation_manager = $trp->get_component( 'translation_manager' );
371
  }
372
  $all_existing_translation_blocks = $this->trp_query->get_all_translation_blocks( $language_code );
 
 
 
 
373
  $merge_rules = $this->translation_manager->get_merge_rules();
374
 
375
  $html = trp_str_get_html($output, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
@@ -846,6 +855,9 @@ class TRP_Translation_Render{
846
 
847
  // get existing translations
848
  $dictionary = $this->trp_query->get_existing_translations( array_values($translateable_strings), $language_code );
 
 
 
849
  $new_strings = array();
850
  foreach( $translateable_strings as $i => $string ){
851
  //strings existing in database,
252
  if ( in_array( $row->tag, $merge_rules['top_parents'] ) ){
253
  $trimmed_inner_text = $this->trim_translation_block( $row->innertext );
254
  foreach( $all_existing_translation_blocks as $existing_translation_block ){
255
+ if ( $existing_translation_block->trimmed_original == $trimmed_inner_text ){
256
  return $existing_translation_block;
257
  }
258
  }
281
  * @return string Translated HTML page.
282
  */
283
  public function translate_page( $output ){
284
+
285
+ /* replace our special tags so we have valid html */
286
+ $output = str_replace('#!trpst#', '<', $output);
287
+ $output = str_replace('#!trpen#', '>', $output);
288
+
289
  $output = apply_filters('trp_before_translate_content', $output);
290
 
291
  if ( strlen( $output ) < 1 || $output == false ){
375
  $this->translation_manager = $trp->get_component( 'translation_manager' );
376
  }
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
  $merge_rules = $this->translation_manager->get_merge_rules();
383
 
384
  $html = trp_str_get_html($output, true, true, TRP_DEFAULT_TARGET_CHARSET, false, TRP_DEFAULT_BR_TEXT, TRP_DEFAULT_SPAN_TEXT);
855
 
856
  // get existing translations
857
  $dictionary = $this->trp_query->get_existing_translations( array_values($translateable_strings), $language_code );
858
+ if ( $dictionary === false ){
859
+ return array();
860
+ }
861
  $new_strings = array();
862
  foreach( $translateable_strings as $i => $string ){
863
  //strings existing in database,
includes/class-url-converter.php CHANGED
@@ -156,14 +156,37 @@ class TRP_Url_Converter {
156
  $language = $TRP_LANGUAGE;
157
  }
158
 
159
- $post_id = url_to_postid( $url );
 
 
 
 
 
 
 
 
 
 
 
 
 
160
  if( empty( $url ) ) {
161
  $url = $this->cur_page_url();
162
- $post_id = ( url_to_postid( $url ) ) ? ( url_to_postid( $url ) ) : ( $trp_backup_post_id );
 
 
 
 
 
163
  }
 
164
  if ( $post_id == 0 ) {
165
  $TRP_LANGUAGE = $this->settings['default-language'];
166
- $post_id = url_to_postid( $url );
 
 
 
 
167
  $TRP_LANGUAGE = $trp_language_copy;
168
  }
169
 
@@ -252,6 +275,32 @@ class TRP_Url_Converter {
252
  return is_file($path);
253
  }
254
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  /**
256
  * Get language code slug to use in url.
257
  *
156
  $language = $TRP_LANGUAGE;
157
  }
158
 
159
+ /* @ TO-DO
160
+ * need our own url_to_postid()This is due to the fact that we're using get_permalink that's filtered to get the correct url based on language with SEO Addon.
161
+ * url_to_postid() can be slow because it's doing a query for each bloody url.
162
+ * this is not a problem with pages that have fewer links, however, it is a problem
163
+ * with archive pages that list a ton of tags/categories the post is in.
164
+ * so we're doing a quick ignore of possible taxonomy links that contain /tag/ or /category/ in them
165
+ *
166
+ */
167
+ if ( $this->url_is_taxonomy($url) ){
168
+ $post_id = 0;
169
+ } else {
170
+ $post_id = url_to_postid( $url );
171
+ }
172
+
173
  if( empty( $url ) ) {
174
  $url = $this->cur_page_url();
175
+ if ( $this->url_is_taxonomy($url) ){
176
+ $post_id = 0;
177
+ } else {
178
+ $url_to_postid = url_to_postid( $url );
179
+ $post_id = ( $url_to_postid ) ? ( $url_to_postid ) : ( $trp_backup_post_id );
180
+ }
181
  }
182
+
183
  if ( $post_id == 0 ) {
184
  $TRP_LANGUAGE = $this->settings['default-language'];
185
+ if ( $this->url_is_taxonomy($url) ){
186
+ $post_id = 0;
187
+ } else {
188
+ $post_id = url_to_postid( $url );
189
+ }
190
  $TRP_LANGUAGE = $trp_language_copy;
191
  }
192
 
275
  return is_file($path);
276
  }
277
 
278
+ /**
279
+ * Check is a url is an taxonomy.
280
+ *
281
+ * @param string $url
282
+ * @return bool
283
+ */
284
+ public function url_is_taxonomy( $url = null ){
285
+
286
+ $taxonomies = wp_cache_get( 'trp_taxonomies' );
287
+ if ( false === $taxonomies ){
288
+ $taxonomies = get_taxonomies(array( 'public' => true ));
289
+ wp_cache_set('trp_taxonomies', $taxonomies);
290
+ }
291
+
292
+ $url_is_taxonomy = false;
293
+ foreach ($taxonomies as $tax){
294
+ if ( strpos($url, '/'.$tax.'/' ) === true ){
295
+ $url_is_taxonomy = true;
296
+ break;
297
+ }
298
+ }
299
+
300
+ return $url_is_taxonomy;
301
+
302
+ }
303
+
304
  /**
305
  * Get language code slug to use in url.
306
  *
includes/functions.php CHANGED
@@ -67,10 +67,18 @@ function trp_x( $text, $context, $domain, $language ){
67
  /* try to find the correct path for the textdomain */
68
  $path = trp_find_translation_location_for_domain( $domain, $language );
69
 
70
- $mo_file = new MO();
71
-
72
  if( !empty( $path ) ) {
73
- if (!$mo_file->import_from_file( $path )) return $text;
 
 
 
 
 
 
 
 
 
 
74
 
75
  if (!empty($mo_file->entries[$context . '' . $text]))
76
  $text = $mo_file->entries[$context . '' . $text]->translations[0];
@@ -532,4 +540,19 @@ function trp_remove_accents( $string ){
532
  }
533
 
534
  return $string;
535
- };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
67
  /* try to find the correct path for the textdomain */
68
  $path = trp_find_translation_location_for_domain( $domain, $language );
69
 
 
 
70
  if( !empty( $path ) ) {
71
+
72
+ $mo_file = wp_cache_get( 'trp_x_' . $domain .'_'. $language );
73
+
74
+ if( false === $mo_file ){
75
+ $mo_file = new MO();
76
+ $mo_file->import_from_file( $path );
77
+ wp_cache_set( 'trp_x_' . $domain .'_'. $language, $mo_file );
78
+ }
79
+
80
+ if ( !$mo_file ) return $text;
81
+
82
 
83
  if (!empty($mo_file->entries[$context . '' . $text]))
84
  $text = $mo_file->entries[$context . '' . $text]->translations[0];
540
  }
541
 
542
  return $string;
543
+ };
544
+
545
+ /**
546
+ * Filter ginger_iframe_banner and ginger_text_banner to use shortcodes so our conditional lang shortcode works.
547
+ *
548
+ * @since 1.3.1
549
+ *
550
+ * @param string $content
551
+ * @return string
552
+ */
553
+
554
+ add_filter('ginger_iframe_banner', 'trpc_do_shortcode', 999 );
555
+ add_filter('ginger_text_banner', 'trpc_do_shortcode', 999 );
556
+ function trpc_do_shortcode($content){
557
+ return do_shortcode(stripcslashes($content));
558
+ }
index.php CHANGED
@@ -3,14 +3,14 @@
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.3.1
7
  Author: Cozmoslabs, Razvan Mocanu, Madalin Ungureanu, Cristophor Hurduban
8
  Author URI: https://cozmoslabs.com/
9
  Text Domain: translatepress-multilingual
10
  Domain Path: /languages
11
  License: GPL2
12
  WC requires at least: 2.5.0
13
- WC tested up to: 3.3
14
 
15
  == Copyright ==
16
  Copyright 2017 Cozmoslabs (www.cozmoslabs.com)
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.3.2
7
  Author: Cozmoslabs, Razvan Mocanu, Madalin Ungureanu, Cristophor Hurduban
8
  Author URI: https://cozmoslabs.com/
9
  Text Domain: translatepress-multilingual
10
  Domain Path: /languages
11
  License: GPL2
12
  WC requires at least: 2.5.0
13
+ WC tested up to: 3.4
14
 
15
  == Copyright ==
16
  Copyright 2017 Cozmoslabs (www.cozmoslabs.com)
languages/translatepress-multilingual.catalog.php CHANGED
@@ -31,6 +31,13 @@
31
  <?php __("Flags with Full Language Names", "translatepress-multilingual"); ?>
32
  <?php __("Flags with Short Language Names", "translatepress-multilingual"); ?>
33
  <?php __("Only Flags", "translatepress-multilingual"); ?>
 
 
 
 
 
 
 
34
  <?php __("Current Language", "translatepress-multilingual"); ?>
35
  <?php __("General", "translatepress-multilingual"); ?>
36
  <?php __("Translate Site", "translatepress-multilingual"); ?>
@@ -118,6 +125,12 @@
118
  <?php __("Publish when the translation is done", "translatepress-multilingual"); ?>
119
  <?php __("Supported By Real People", "translatepress-multilingual"); ?>
120
  <?php __("Learn More", "translatepress-multilingual"); ?>
 
 
 
 
 
 
121
  <?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
122
  <?php __("Translator", "translatepress-multilingual"); ?>
123
  <?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
31
  <?php __("Flags with Full Language Names", "translatepress-multilingual"); ?>
32
  <?php __("Flags with Short Language Names", "translatepress-multilingual"); ?>
33
  <?php __("Only Flags", "translatepress-multilingual"); ?>
34
+ <?php __("Done.", "translatepress-multilingual"); ?>
35
+ <?php __("Back to TranslatePress Settings page", "translatepress-multilingual"); ?>
36
+ <?php __("Invalid nonce.", "translatepress-multilingual"); ?>
37
+ <?php __("Querying table <strong>%s</strong>", "translatepress-multilingual"); ?>
38
+ <?php __("%s duplicates removed", "translatepress-multilingual"); ?>
39
+ <?php __("If the page does not redirect automatically", "translatepress-multilingual"); ?>
40
+ <?php __("click here", "translatepress-multilingual"); ?>
41
  <?php __("Current Language", "translatepress-multilingual"); ?>
42
  <?php __("General", "translatepress-multilingual"); ?>
43
  <?php __("Translate Site", "translatepress-multilingual"); ?>
125
  <?php __("Publish when the translation is done", "translatepress-multilingual"); ?>
126
  <?php __("Supported By Real People", "translatepress-multilingual"); ?>
127
  <?php __("Learn More", "translatepress-multilingual"); ?>
128
+ <?php __("Remove duplicate rows from TranslatePress tables", "translatepress-multilingual"); ?>
129
+ <?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"); ?>
130
+ <?php __("IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?", "translatepress-multilingual"); ?>
131
+ <?php __("Batch size", "translatepress-multilingual"); ?>
132
+ <?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"); ?>
133
+ <?php __("Remove duplicate rows", "translatepress-multilingual"); ?>
134
  <?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
135
  <?php __("Translator", "translatepress-multilingual"); ?>
136
  <?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
languages/translatepress-multilingual.pot CHANGED
@@ -45,7 +45,7 @@ msgstr ""
45
  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>"
46
  msgstr ""
47
 
48
- #: 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:17, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
49
  msgid "TranslatePress Settings"
50
  msgstr ""
51
 
@@ -141,23 +141,51 @@ msgstr ""
141
  msgid "Only Flags"
142
  msgstr ""
143
 
144
- #: ../translatepress/includes/class-settings.php:338
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  msgid "Current Language"
146
  msgstr ""
147
 
148
- #: ../translatepress/includes/class-settings.php:379
149
  msgid "General"
150
  msgstr ""
151
 
152
- #: ../translatepress/includes/class-settings.php:384, ../translatepress/includes/class-translation-manager.php:626
153
  msgid "Translate Site"
154
  msgstr ""
155
 
156
- #: ../translatepress/includes/class-settings.php:392
157
  msgid "License"
158
  msgstr ""
159
 
160
- #: ../translatepress/includes/class-settings.php:398
161
  msgid "Addons"
162
  msgstr ""
163
 
@@ -201,7 +229,7 @@ msgstr ""
201
  msgid "Settings"
202
  msgstr ""
203
 
204
- #: ../translatepress/includes/class-translation-manager.php:1197
205
  msgid "Security check"
206
  msgstr ""
207
 
@@ -237,7 +265,7 @@ msgstr ""
237
  msgid "Page Title"
238
  msgstr ""
239
 
240
- #: ../translatepress/includes/functions.php:184
241
  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."
242
  msgstr ""
243
 
@@ -489,6 +517,32 @@ msgstr ""
489
  msgid "Learn More"
490
  msgstr ""
491
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
492
  #: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
493
  msgid " TranslatePress Settings"
494
  msgstr ""
45
  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>"
46
  msgstr ""
47
 
48
+ #: 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:17, ../translatepress/partials/trp-remove-duplicate-rows.php:3, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
49
  msgid "TranslatePress Settings"
50
  msgstr ""
51
 
141
  msgid "Only Flags"
142
  msgstr ""
143
 
144
+ #: ../translatepress/includes/class-settings.php:119
145
+ msgid "Done."
146
+ msgstr ""
147
+
148
+ #: ../translatepress/includes/class-settings.php:119, ../translatepress/includes/class-settings.php:124
149
+ msgid "Back to TranslatePress Settings page"
150
+ msgstr ""
151
+
152
+ #: ../translatepress/includes/class-settings.php:124
153
+ msgid "Invalid nonce."
154
+ msgstr ""
155
+
156
+ #: ../translatepress/includes/class-settings.php:144
157
+ msgid "Querying table <strong>%s</strong>"
158
+ msgstr ""
159
+
160
+ #: ../translatepress/includes/class-settings.php:174
161
+ msgid "%s duplicates removed"
162
+ msgstr ""
163
+
164
+ #: ../translatepress/includes/class-settings.php:204
165
+ msgid "If the page does not redirect automatically"
166
+ msgstr ""
167
+
168
+ #: ../translatepress/includes/class-settings.php:204
169
+ msgid "click here"
170
+ msgstr ""
171
+
172
+ #: ../translatepress/includes/class-settings.php:447
173
  msgid "Current Language"
174
  msgstr ""
175
 
176
+ #: ../translatepress/includes/class-settings.php:488
177
  msgid "General"
178
  msgstr ""
179
 
180
+ #: ../translatepress/includes/class-settings.php:493, ../translatepress/includes/class-translation-manager.php:626
181
  msgid "Translate Site"
182
  msgstr ""
183
 
184
+ #: ../translatepress/includes/class-settings.php:501
185
  msgid "License"
186
  msgstr ""
187
 
188
+ #: ../translatepress/includes/class-settings.php:507
189
  msgid "Addons"
190
  msgstr ""
191
 
229
  msgid "Settings"
230
  msgstr ""
231
 
232
+ #: ../translatepress/includes/class-translation-manager.php:1125
233
  msgid "Security check"
234
  msgstr ""
235
 
265
  msgid "Page Title"
266
  msgstr ""
267
 
268
+ #: ../translatepress/includes/functions.php:192
269
  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."
270
  msgstr ""
271
 
517
  msgid "Learn More"
518
  msgstr ""
519
 
520
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:7
521
+ msgid "Remove duplicate rows from TranslatePress tables"
522
+ msgstr ""
523
+
524
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:10
525
+ 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."
526
+ msgstr ""
527
+
528
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:12
529
+ msgid ""
530
+ "IMPORTANT: It is strongly recommended to backup the database first!\n"
531
+ "Are you sure you want to continue?"
532
+ msgstr ""
533
+
534
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:15
535
+ msgid "Batch size"
536
+ msgstr ""
537
+
538
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:19
539
+ msgid "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."
540
+ msgstr ""
541
+
542
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:28
543
+ msgid "Remove duplicate rows"
544
+ msgstr ""
545
+
546
  #: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
547
  msgid " TranslatePress Settings"
548
  msgstr ""
partials/trp-remove-duplicate-rows.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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('Remove duplicate rows from TranslatePress tables', 'translatepress-multilingual' );?> </h2>
8
+ <?php if ( empty( $_GET['trp_rm_duplicates'] ) ){ ?>
9
+ <div>
10
+ <?php _e( '<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' )?>
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
+ <table class="form-table">
14
+ <tr>
15
+ <th scope="row"><?php _e( 'Batch size', 'translatepress-multilingual' ); ?></th>
16
+ <td>
17
+ <input name="trp_rm_batch_size" type="number" value="10000" step="100" min="100">
18
+ <p>
19
+ <i><?php _e( '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' ); ?></i>
20
+ </p>
21
+ </td>
22
+ </tr>
23
+ </table>
24
+ <input type="hidden" name="trp_rm_nonce" value="<?php echo wp_create_nonce('tpremoveduplicaterows')?>">
25
+ <input type="hidden" name="page" value="trp_remove_duplicate_rows">
26
+ <input type="hidden" name="trp_rm_batch" value="1">
27
+ <input type="hidden" name="trp_rm_duplicates" value="<?php echo $this->settings['translation-languages'][0]?>">
28
+ <input type="submit" class="button-primary" value="<?php _e( 'Remove duplicate rows', 'translatepress-multilingual' ); ?>">
29
+ </form>
30
+ <?php } ?>
31
+
32
+ </div>
33
+ </div>
34
+
35
+ </div>
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: 4.9.8
7
- Stable tag: 1.3.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -14,6 +14,8 @@ Easily translate your entire site directly from the front-end and go multilingua
14
 
15
  **Experience a better way to translate your WordPress site and go multilingual, directly from the front-end using a friendly user interface.**
16
 
 
 
17
  The interface allows you to easily translate the entire page at once, including output from shortcodes, forms and page builders. It also works out of the box with WooCommerce.
18
 
19
  Built the WordPress way, TranslatePress - Multilingual is a GPL and self hosted translation plugin, meaning you'll own all your translations, forever. It's the fastest way to create a bilingual or multilingual site.
@@ -36,7 +38,7 @@ https://www.youtube.com/watch?v=pUlYisvBm8g
36
  * Possibility to edit gettext strings from themes and plugins from english to english, without adding another language. Basically a string-replace functionality.
37
  * Translation Block feature in which you can translate multiple html elements together
38
 
39
- Note: this plugin uses the Google Translation API to translate the strings on your site. This feature can be enabled or disabled according to your preferences.
40
 
41
  Users with administrator rights have access to the following translate settings:
42
 
@@ -48,7 +50,7 @@ Users with administrator rights have access to the following translate settings:
48
 
49
  = Powerful Translation Add-ons =
50
 
51
- TranslatePress - Multilingual has a range of premium [Add-ons](https://translatepress.com/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree) that allow you to extend the power of the translation plugin:
52
 
53
  **Pro Add-ons** (available in the [premium versions](https://translatepress.com/pricing/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree) only)
54
 
@@ -69,7 +71,7 @@ TranslatePress - Multilingual has a range of premium [Add-ons](https://translate
69
 
70
  = Documentation =
71
 
72
- [Visit our documentation page](https://translatepress.com/docs/translatepress/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree)
73
 
74
  = Add-ons =
75
 
@@ -77,7 +79,7 @@ TranslatePress - Multilingual has a range of premium [Add-ons](https://translate
77
 
78
  = Demo Site =
79
 
80
- You can test out TranslatePress - Multilingual by [visiting our demo site](https://demo.translatepress.com/)
81
 
82
  == Installation ==
83
 
@@ -94,19 +96,23 @@ All the translation are stored locally in your server's database.
94
 
95
  = What types of content can I translate? =
96
 
97
- TranslatePress - Multilingual works out of the box with WooCommerce, custom post types, complex themes and site builders, so you'll be able to translate any type of content.
98
 
99
  = How is it different from other multilingual & translation plugins like WPML or Polylang? =
100
 
101
  TranslatePress is easier to use and more intuitive altogether. No more switching between the editor, string translation interfaces or badly translated plugins. You can now translate the full page content directly from the front-end. This makes TranslatePress a great alternative to plugins like Polylang and WPML.
102
 
103
- = How do I start to translate my site? =
104
 
105
  After installing the plugin, select your secondary language and click "Translate Site" to start translating your entire site exactly as it looks in the front-end.
106
 
 
 
 
 
107
  = Where can I find out more information? =
108
 
109
- For more information please check out [TranslatePress documentation](https://translatepress.com/docs/translatepress/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree).
110
 
111
 
112
  == Screenshots ==
@@ -118,6 +124,17 @@ For more information please check out [TranslatePress documentation](https://tra
118
  6. Menu Language Switcher
119
 
120
  == Changelog ==
 
 
 
 
 
 
 
 
 
 
 
121
  = 1.3.1 =
122
  * Fixed Woocommerce translation of permalinks
123
  * Added support for remove_accents to be based on default language when called from the sanitize_title function
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: 4.9.8
7
+ Stable tag: 1.3.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
14
 
15
  **Experience a better way to translate your WordPress site and go multilingual, directly from the front-end using a friendly user interface.**
16
 
17
+ TranslatePress is a WordPress translation plugin that anyone can use.
18
+
19
  The interface allows you to easily translate the entire page at once, including output from shortcodes, forms and page builders. It also works out of the box with WooCommerce.
20
 
21
  Built the WordPress way, TranslatePress - Multilingual is a GPL and self hosted translation plugin, meaning you'll own all your translations, forever. It's the fastest way to create a bilingual or multilingual site.
38
  * Possibility to edit gettext strings from themes and plugins from english to english, without adding another language. Basically a string-replace functionality.
39
  * Translation Block feature in which you can translate multiple html elements together
40
 
41
+ Note: this WordPress translation plugin uses the Google Translation API to translate the strings on your site. This feature can be enabled or disabled according to your preferences.
42
 
43
  Users with administrator rights have access to the following translate settings:
44
 
50
 
51
  = Powerful Translation Add-ons =
52
 
53
+ TranslatePress - Multilingual has a range of premium [Add-ons](https://translatepress.com/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree) that allow you to extend the power of the WordPress translation plugin:
54
 
55
  **Pro Add-ons** (available in the [premium versions](https://translatepress.com/pricing/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree) only)
56
 
71
 
72
  = Documentation =
73
 
74
+ [Visit TranslatePress WordPress Translation plugin documentation page](https://translatepress.com/docs/translatepress/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree)
75
 
76
  = Add-ons =
77
 
79
 
80
  = Demo Site =
81
 
82
+ You can test out TranslatePress - Multilingual plugin by [visiting our demo site](https://demo.translatepress.com/)
83
 
84
  == Installation ==
85
 
96
 
97
  = What types of content can I translate? =
98
 
99
+ TranslatePress - Multilingual plugin works out of the box with WooCommerce, custom post types, complex themes and site builders, so you'll be able to translate any type of content.
100
 
101
  = How is it different from other multilingual & translation plugins like WPML or Polylang? =
102
 
103
  TranslatePress is easier to use and more intuitive altogether. No more switching between the editor, string translation interfaces or badly translated plugins. You can now translate the full page content directly from the front-end. This makes TranslatePress a great alternative to plugins like Polylang and WPML.
104
 
105
+ = How do I start to translate my WordPress site? =
106
 
107
  After installing the plugin, select your secondary language and click "Translate Site" to start translating your entire site exactly as it looks in the front-end.
108
 
109
+ = Will it slow down my website? =
110
+
111
+ TranslatePress will have little impact on your site speed. For more details see [Top WordPress Translation Plugins Compared Based on Page Load Time](https://translatepress.com/top-wordpress-translation-plugins-compared-based-on-page-load-time/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree)
112
+
113
  = Where can I find out more information? =
114
 
115
+ For more information please check out [TranslatePress - Multilingual plugin documentation](https://translatepress.com/docs/translatepress/?utm_source=wp.org&utm_medium=tp-description-page&utm_campaign=TPFree).
116
 
117
 
118
  == Screenshots ==
124
  6. Menu Language Switcher
125
 
126
  == Changelog ==
127
+ = 1.3.2 =
128
+ * Speed improvements
129
+ * Add support for the Ginger – EU Cookie Law plugin
130
+ * Add support for data-no-dynamic-translation attribute that skips dynamic strings from being translated by dom changes detector
131
+ * Fixed Edit Pencil icon css in Translation Editor for some sites
132
+ * Refactored the way we add trp-gettext tag. This should have a lot of benefits in compatibility with other plugins
133
+ * Optimized block translation detection
134
+ * Added caching to trp_x function when reading external .mo files
135
+ * Fixed issue with translatepress icon css that was broken on wpforms forms
136
+ * Added secret page for removing duplicate rows from database: wp-admin/admin.php?page=trp_remove_duplicate_rows
137
+
138
  = 1.3.1 =
139
  * Fixed Woocommerce translation of permalinks
140
  * Added support for remove_accents to be based on default language when called from the sanitize_title function