TranslatePress – Translate Multilingual sites - Version 1.4.0

Version Description

  • Added Enfold compatibility by increasing the template_include hook priority
  • Add the costa rica flag
  • Speed improvements by optimizing the full_trim function
  • Added compatibility for WooCommerce Invoices plugins
  • Fixed querying for dynamic strings in Translation Editor not bringing up translations for all languages
  • Fixed notice when gettext table is empty
  • Added function to display strings with bad encoding in Translation Editor
Download this release

Release Info

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

Code changes from version 1.3.9 to 1.4.0

assets/css/trp-preview-iframe-style.css CHANGED
@@ -122,3 +122,33 @@ translate-press{
122
.trp-icon.trp-split.trp-active-icon, .trp-icon.trp-split.trp-active-icon:hover{
123
display: inline;
124
}
122
.trp-icon.trp-split.trp-active-icon, .trp-icon.trp-split.trp-active-icon:hover{
123
display: inline;
124
}
125
+
126
+ .trp-editor-notices{
127
+ font-family: inherit;
128
+ font-size: 13px;
129
+ font-style: inherit;
130
+ font-weight: inherit;
131
+ position:relative;
132
+ z-index: 99999;
133
+ width: 100%;
134
+ max-height: 200px;
135
+ overflow-y: auto;
136
+ background: #f1f1f1;
137
+ overflow-x: hidden;
138
+ }
139
+
140
+ .trp-notice{
141
+ background: #fff;
142
+ border-left: 4px solid #fff;
143
+ box-shadow: 0 1px 1px 0 rgba(0,0,0,.1);
144
+ margin: 15px;
145
+ padding: 12px;
146
+ }
147
+
148
+ .trp-notice-warning {
149
+ border-left-color: #ffb900;
150
+ }
151
+
152
+ .trp-bad-encoded-strings-list{
153
+ padding-left: 15px;
154
+ }
assets/images/flags/es_CR.png ADDED
Binary file
assets/js/trp-translate-dom-changes.js CHANGED
@@ -17,12 +17,17 @@ function TRP_Translator(){
17
* Ajax request to get translations for strings
18
*/
19
this.ajax_get_translation = function( strings_to_query, url ) {
20
jQuery.ajax({
21
url: url,
22
type: 'post',
23
dataType: 'json',
24
data: {
25
action: 'trp_get_translations',
26
security: trp_localized_text['gettranslationsnonce'],
27
language: language_to_query,
28
original_language: original_language,
@@ -68,26 +73,24 @@ function TRP_Translator(){
68
*/
69
this.update_strings = function( response, strings_to_query ) {
70
if ( response != null && response[language_to_query] != null ){
71
- var strings_to_store = {};
72
for ( var j in strings_to_query ) {
73
var queried_string = strings_to_query[j];
74
var translation_found = false;
75
var initial_value = queried_string.original;
76
for( var i in response[language_to_query] ) {
77
- if ( typeof strings_to_store[language_to_query] == 'undefined' ){
78
- strings_to_store[language_to_query] = {};
79
- }
80
var response_string = response[language_to_query][i];
81
if (response_string.original.trim() == queried_string.original.trim()) {
82
- strings_to_store[language_to_query][j] = {};
83
- strings_to_store[language_to_query][j].id = response[language_to_query][i].id;
84
- strings_to_store[language_to_query][j].original = response[language_to_query][i].original;
85
- strings_to_store[language_to_query][j].translated = response[language_to_query][i].translated;
86
- strings_to_store[language_to_query][j].status = response[language_to_query][i].status;
87
- strings_to_store[language_to_query][j].jquery_object = jQuery( queried_string.node ).parent( 'translate-press' );
88
if ( typeof parent.trpEditor !== 'undefined' ) {
89
- strings_to_store[language_to_query][j].jquery_object.attr('data-trp-translate-id', response[language_to_query][i].id);
90
- strings_to_store[language_to_query][j].jquery_object.attr('data-trp-node-type', 'Dynamic Added Strings');
91
}
92
93
if (response_string.translated != '' && language_to_query == current_language ) {
@@ -107,7 +110,8 @@ function TRP_Translator(){
107
}
108
// this should always be outside the for loop
109
if ( typeof parent.trpEditor !== 'undefined' ) {
110
- parent.trpEditor.populate_strings( strings_to_store );
111
if ( parent.trpEditor.trp_lister != null ) {
112
parent.trpEditor.trp_lister.reload_list();
113
}
17
* Ajax request to get translations for strings
18
*/
19
this.ajax_get_translation = function( strings_to_query, url ) {
20
+ var all_languages_true_false = 'false';
21
+ if ( typeof parent.trpEditor !== 'undefined' ) {
22
+ all_languages_true_false = 'true';
23
+ }
24
jQuery.ajax({
25
url: url,
26
type: 'post',
27
dataType: 'json',
28
data: {
29
action: 'trp_get_translations',
30
+ all_languages: all_languages_true_false,
31
security: trp_localized_text['gettranslationsnonce'],
32
language: language_to_query,
33
original_language: original_language,
73
*/
74
this.update_strings = function( response, strings_to_query ) {
75
if ( response != null && response[language_to_query] != null ){
76
+ var dictionary = {};
77
for ( var j in strings_to_query ) {
78
var queried_string = strings_to_query[j];
79
var translation_found = false;
80
var initial_value = queried_string.original;
81
for( var i in response[language_to_query] ) {
82
var response_string = response[language_to_query][i];
83
if (response_string.original.trim() == queried_string.original.trim()) {
84
+ // We use j instead of i index because the strings_to_query can contain duplicates and response cannot. We need duplicates to refer to different jQuery objects where the same string appears in different places on the page.
85
+ dictionary[j] = {};
86
+ dictionary[j].id = response[language_to_query][i].id;
87
+ dictionary[j].original = response[language_to_query][i].original;
88
+ dictionary[j].translated = response[language_to_query][i].translated;
89
+ dictionary[j].status = response[language_to_query][i].status;
90
+ dictionary[j].jquery_object = jQuery( queried_string.node ).parent( 'translate-press' );
91
if ( typeof parent.trpEditor !== 'undefined' ) {
92
+ dictionary[j].jquery_object.attr('data-trp-translate-id', response[language_to_query][i].id);
93
+ dictionary[j].jquery_object.attr('data-trp-node-type', 'Dynamic Added Strings');
94
}
95
96
if (response_string.translated != '' && language_to_query == current_language ) {
110
}
111
// this should always be outside the for loop
112
if ( typeof parent.trpEditor !== 'undefined' ) {
113
+ response[language_to_query] = dictionary;
114
+ parent.trpEditor.populate_strings( response );
115
if ( parent.trpEditor.trp_lister != null ) {
116
parent.trpEditor.trp_lister.reload_list();
117
}
class-translate-press.php CHANGED
@@ -17,6 +17,7 @@ class TRP_Translate_Press{
17
protected $url_converter;
18
protected $languages;
19
protected $slug_manager;
20
public static $translate_press = null;
21
22
/**
@@ -40,7 +41,7 @@ class TRP_Translate_Press{
40
define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
41
define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
42
define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
43
- define( 'TRP_PLUGIN_VERSION', '1.3.9' );
44
45
wp_cache_add_non_persistent_groups(array('trp'));
46
@@ -76,6 +77,7 @@ class TRP_Translate_Press{
76
require_once TRP_PLUGIN_DIR . 'includes/class-query.php';
77
require_once TRP_PLUGIN_DIR . 'includes/class-url-converter.php';
78
require_once TRP_PLUGIN_DIR . 'includes/class-uri.php';
79
require_once TRP_PLUGIN_DIR . 'includes/class-plugin-notices.php';
80
require_once TRP_PLUGIN_DIR . 'includes/functions.php';
81
require_once TRP_PLUGIN_DIR . 'assets/lib/simplehtmldom/simple_html_dom.php';
@@ -96,6 +98,7 @@ class TRP_Translate_Press{
96
$this->machine_translator = new TRP_Machine_Translator( $this->settings->get_settings() );
97
$this->translation_manager = new TRP_Translation_Manager( $this->settings->get_settings() );
98
$this->notifications = new TRP_Trigger_Plugin_Notifications();
99
}
100
101
/**
@@ -119,6 +122,7 @@ class TRP_Translate_Press{
119
$this->loader->add_action( 'wp_ajax_trp_save_translations', $this->translation_manager, 'save_translations' );
120
$this->loader->add_action( 'wp_ajax_trp_create_translation_block', $this->translation_manager, 'create_translation_block' );
121
$this->loader->add_action( 'init', $this->translation_manager, 'split_translation_block' );
122
123
124
$this->loader->add_action( 'wp_ajax_trp_process_js_strings_in_translation_editor', $this->translation_render, 'process_js_strings_in_translation_editor' );
@@ -128,6 +132,9 @@ class TRP_Translate_Press{
128
129
$this->loader->add_action( 'wp_ajax_trp_publish_language', $this->translation_manager, 'publish_language' );
130
131
}
132
133
/**
@@ -160,7 +167,7 @@ class TRP_Translate_Press{
160
161
162
$this->loader->add_action( 'trp_head', $this->translation_manager, 'enqueue_scripts_and_styles' );
163
- $this->loader->add_filter( 'template_include', $this->translation_manager, 'translation_editor', 9999 );
164
$this->loader->add_action( 'wp_enqueue_scripts', $this->translation_manager, 'enqueue_preview_scripts_and_styles' );
165
$this->loader->add_action( 'admin_bar_menu', $this->translation_manager, 'add_shortcut_to_translation_editor', 90, 1 );
166
$this->loader->add_action( 'admin_head', $this->translation_manager, 'add_styling_to_admin_bar_button', 10 );
@@ -194,7 +201,7 @@ class TRP_Translate_Press{
194
$this->loader->add_filter( 'sanitize_title', $this->translation_manager, 'trp_sanitize_title', 1, 3 );
195
196
/* define an update hook here */
197
- $this->loader->add_action( 'plugins_loaded', $this->query, 'check_for_necessary_updates', 10 );
198
199
$this->loader->add_filter( 'trp_language_name', $this->languages, 'beautify_language_name', 10, 4 );
200
$this->loader->add_filter( 'trp_languages', $this->languages, 'reorder_languages', 10, 2 );
17
protected $url_converter;
18
protected $languages;
19
protected $slug_manager;
20
+ protected $upgrade;
21
public static $translate_press = null;
22
23
/**
41
define( 'TRP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
42
define( 'TRP_PLUGIN_BASE', plugin_basename( __DIR__ . '/index.php' ) );
43
define( 'TRP_PLUGIN_SLUG', 'translatepress-multilingual' );
44
+ define( 'TRP_PLUGIN_VERSION', '1.4.0' );
45
46
wp_cache_add_non_persistent_groups(array('trp'));
47
77
require_once TRP_PLUGIN_DIR . 'includes/class-query.php';
78
require_once TRP_PLUGIN_DIR . 'includes/class-url-converter.php';
79
require_once TRP_PLUGIN_DIR . 'includes/class-uri.php';
80
+ require_once TRP_PLUGIN_DIR . 'includes/class-upgrade.php';
81
require_once TRP_PLUGIN_DIR . 'includes/class-plugin-notices.php';
82
require_once TRP_PLUGIN_DIR . 'includes/functions.php';
83
require_once TRP_PLUGIN_DIR . 'assets/lib/simplehtmldom/simple_html_dom.php';
98
$this->machine_translator = new TRP_Machine_Translator( $this->settings->get_settings() );
99
$this->translation_manager = new TRP_Translation_Manager( $this->settings->get_settings() );
100
$this->notifications = new TRP_Trigger_Plugin_Notifications();
101
+ $this->upgrade = new TRP_Upgrade( $this->settings->get_settings() );
102
}
103
104
/**
122
$this->loader->add_action( 'wp_ajax_trp_save_translations', $this->translation_manager, 'save_translations' );
123
$this->loader->add_action( 'wp_ajax_trp_create_translation_block', $this->translation_manager, 'create_translation_block' );
124
$this->loader->add_action( 'init', $this->translation_manager, 'split_translation_block' );
125
+ $this->loader->add_filter( 'trp_get_existing_translations', $this->translation_manager, 'display_possible_db_errors', 20, 3 );
126
127
128
$this->loader->add_action( 'wp_ajax_trp_process_js_strings_in_translation_editor', $this->translation_render, 'process_js_strings_in_translation_editor' );
132
133
$this->loader->add_action( 'wp_ajax_trp_publish_language', $this->translation_manager, 'publish_language' );
134
135
+ $this->loader->add_action( 'admin_menu', $this->upgrade, 'register_menu_page' );
136
+ $this->loader->add_action( 'admin_init', $this->upgrade, 'show_admin_notice' );
137
+
138
}
139
140
/**
167
168
169
$this->loader->add_action( 'trp_head', $this->translation_manager, 'enqueue_scripts_and_styles' );
170
+ $this->loader->add_filter( 'template_include', $this->translation_manager, 'translation_editor', 99999 );
171
$this->loader->add_action( 'wp_enqueue_scripts', $this->translation_manager, 'enqueue_preview_scripts_and_styles' );
172
$this->loader->add_action( 'admin_bar_menu', $this->translation_manager, 'add_shortcut_to_translation_editor', 90, 1 );
173
$this->loader->add_action( 'admin_head', $this->translation_manager, 'add_styling_to_admin_bar_button', 10 );
201
$this->loader->add_filter( 'sanitize_title', $this->translation_manager, 'trp_sanitize_title', 1, 3 );
202
203
/* define an update hook here */
204
+ $this->loader->add_action( 'plugins_loaded', $this->upgrade, 'check_for_necessary_updates', 10 );
205
206
$this->loader->add_filter( 'trp_language_name', $this->languages, 'beautify_language_name', 10, 4 );
207
$this->loader->add_filter( 'trp_languages', $this->languages, 'reorder_languages', 10, 2 );
includes/class-query.php CHANGED
@@ -31,20 +31,6 @@ class TRP_Query{
31
$this->settings = $settings;
32
}
33
34
- /**
35
- * Trim unwanted characters from string.
36
- *
37
- * @param string $string String to trim.
38
- * @return string Trimmed string.
39
- */
40
- protected function full_trim( $string ) {
41
- $trp = TRP_Translate_Press::get_trp_instance();
42
- if ( ! $this->translation_render ) {
43
- $this->translation_render = $trp->get_component( 'translation_render' );
44
- }
45
-
46
- return $this->translation_render->full_trim( $string );
47
- }
48
49
/**
50
* Return an array of all the active translation blocks
@@ -83,13 +69,13 @@ class TRP_Query{
83
$values = array();
84
foreach( $strings_array as $string ){
85
$placeholders[] = '%s';
86
- $values[] = $this->full_trim( $string );
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
/**
@@ -228,31 +214,6 @@ class TRP_Query{
228
}
229
}
230
231
- /**
232
- * When changing plugin version, call certain database upgrade functions.
233
- *
234
- */
235
- public function check_for_necessary_updates(){
236
- $stored_database_version = get_option('trp_plugin_version');
237
- if( empty($stored_database_version) || version_compare( TRP_PLUGIN_VERSION, $stored_database_version, '>' ) ){
238
- $this->check_if_gettext_tables_exist();
239
- $this->check_for_block_type_column();
240
- }
241
-
242
- update_option( 'trp_plugin_version', TRP_PLUGIN_VERSION );
243
- }
244
-
245
- /**
246
- * Iterates over all languages to call gettext table checking
247
- */
248
- public function check_if_gettext_tables_exist(){
249
- if( !empty( $this->settings['translation-languages'] ) ){
250
- foreach( $this->settings['translation-languages'] as $site_language_code ){
251
- $this->check_gettext_table($site_language_code);
252
- }
253
- }
254
- }
255
-
256
/**
257
* Add block_type column to dictionary tables, if it doesn't exist.
258
*
@@ -306,18 +267,20 @@ class TRP_Query{
306
/**
307
* Insert translations and new strings in DB.
308
*
309
- * @param array $new_strings Array of strings for which we do not have a translation. Only inserts original.
310
- * @param array $update_strings Array of arrays, each containing an entry to update.
311
- * @param string $language_code Language code of table where it should be inserted.
312
- */
313
- public function insert_strings( $new_strings, $update_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ){
314
- if ( $block_type == null ){
315
- $block_type = self::BLOCK_TYPE_REGULAR_STRING;
316
- }
317
- if ( count( $new_strings ) == 0 && count( $update_strings ) == 0 ){
318
- return;
319
- }
320
- $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( id, original, translated, status, block_type ) VALUES ";
321
322
$values = array();
323
$place_holders = array();
@@ -325,20 +288,19 @@ class TRP_Query{
325
326
foreach ( $new_strings as $string ) {
327
array_push( $values, NULL, $string, NULL, self::NOT_TRANSLATED, $block_type );
328
- $place_holders[] = "( '%d', '%s', '%s', '%d', '%d')";
329
}
330
foreach ( $update_strings as $string ) {
331
if ( ! isset( $string['block_type'] ) ){
332
$string['block_type'] = self::BLOCK_TYPE_REGULAR_STRING;
333
}
334
array_push( $values, $string['id'], $string['original'], $string['translated'], $string['status'], $string['block_type'] );
335
- $place_holders[] = "( '%d', '%s', '%s', '%d', '%d')";
336
}
337
338
- $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status), block_type=VALUES(block_type)';
339
-
340
- $query .= implode(', ', $place_holders);
341
- $query .= $on_duplicate;
342
343
// you cannot insert multiple rows at once using insert() method.
344
// but by using prepare you cannot insert NULL values.
@@ -419,7 +381,7 @@ class TRP_Query{
419
$values = array();
420
foreach( $original_strings as $string ){
421
$placeholders[] = '%s';
422
- $values[] = $this->full_trim( $string );
423
}
424
425
$query .= "( " . implode ( ", ", $placeholders ) . " )";
@@ -446,12 +408,11 @@ class TRP_Query{
446
$values = array();
447
foreach( $strings_array as $string ){
448
$placeholders[] = '%s';
449
- $values[] = $this->full_trim( $string );
450
}
451
452
$query .= "( " . implode ( ", ", $placeholders ) . " )";
453
$dictionary = $this->db->get_results( $this->db->prepare( $query, $values ), OBJECT_K );
454
-
455
return $dictionary;
456
}
457
@@ -512,7 +473,7 @@ class TRP_Query{
512
$values = array();
513
foreach ($original_array as $string) {
514
$placeholders[] = '%s';
515
- $values[] = $this->full_trim($string);
516
}
517
518
$query1 = "original IN ( " . implode(", ", $placeholders) . " )";
@@ -580,7 +541,7 @@ class TRP_Query{
580
$values = array();
581
foreach( $original_array as $string ){
582
$placeholders[] = '%s';
583
- $values[] = $this->full_trim( $string );
584
}
585
586
$query .= "( " . implode ( ", ", $placeholders ) . " )";
@@ -610,7 +571,7 @@ class TRP_Query{
610
$placeholders = array();
611
foreach( $original_array as $string ){
612
$placeholders[] = '%s';
613
- $values[] = $this->full_trim( $string );
614
}
615
}
616
@@ -680,4 +641,85 @@ class TRP_Query{
680
$last_id = $this->db->get_var("SELECT MAX(id) FROM " . $table_name );
681
return $last_id;
682
}
683
}
31
$this->settings = $settings;
32
}
33
34
35
/**
36
* Return an array of all the active translation blocks
69
$values = array();
70
foreach( $strings_array as $string ){
71
$placeholders[] = '%s';
72
+ $values[] = $string;
73
}
74
75
$query .= "( " . implode ( ", ", $placeholders ) . " )";
76
$prepared_query = $this->db->prepare( $query, $values );
77
$dictionary = $this->db->get_results( $prepared_query, OBJECT_K );
78
+ return apply_filters( 'trp_get_existing_translations', $dictionary, $prepared_query, $strings_array );
79
}
80
81
/**
214
}
215
}
216
217
/**
218
* Add block_type column to dictionary tables, if it doesn't exist.
219
*
267
/**
268
* Insert translations and new strings in DB.
269
*
270
+ * @param array $new_strings Array of strings for which we do not have a translation. Only inserts original.
271
+ * @param array $update_strings Array of arrays, each containing an entry to update.
272
+ * @param string $language_code Language code of table where it should be inserted.
273
+ * @param int $block_type
274
+ * @param string $on_duplicate
275
+ */
276
+ public function insert_strings( $new_strings, $update_strings, $language_code, $block_type = self::BLOCK_TYPE_REGULAR_STRING ) {
277
+ if ( $block_type == null ) {
278
+ $block_type = self::BLOCK_TYPE_REGULAR_STRING;
279
+ }
280
+ if ( count( $new_strings ) == 0 && count( $update_strings ) == 0 ) {
281
+ return;
282
+ }
283
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( id, original, translated, status, block_type ) VALUES ";
284
285
$values = array();
286
$place_holders = array();
288
289
foreach ( $new_strings as $string ) {
290
array_push( $values, NULL, $string, NULL, self::NOT_TRANSLATED, $block_type );
291
+ $place_holders[] = "('%d','%s','%s','%d','%d')";
292
}
293
foreach ( $update_strings as $string ) {
294
if ( ! isset( $string['block_type'] ) ){
295
$string['block_type'] = self::BLOCK_TYPE_REGULAR_STRING;
296
}
297
array_push( $values, $string['id'], $string['original'], $string['translated'], $string['status'], $string['block_type'] );
298
+ $place_holders[] = "('%d','%s','%s','%d','%d')";
299
}
300
+ $query .= implode( ', ', $place_holders );
301
302
+ $on_duplicate = ' ON DUPLICATE KEY UPDATE translated=VALUES(translated), status=VALUES(status), block_type=VALUES(block_type)';
303
+ $query .= $on_duplicate;
304
305
// you cannot insert multiple rows at once using insert() method.
306
// but by using prepare you cannot insert NULL values.
381
$values = array();
382
foreach( $original_strings as $string ){
383
$placeholders[] = '%s';
384
+ $values[] = $string;
385
}
386
387
$query .= "( " . implode ( ", ", $placeholders ) . " )";
408
$values = array();
409
foreach( $strings_array as $string ){
410
$placeholders[] = '%s';
411
+ $values[] = $string;
412
}
413
414
$query .= "( " . implode ( ", ", $placeholders ) . " )";
415
$dictionary = $this->db->get_results( $this->db->prepare( $query, $values ), OBJECT_K );
416
return $dictionary;
417
}
418
473
$values = array();
474
foreach ($original_array as $string) {
475
$placeholders[] = '%s';
476
+ $values[] = $string;
477
}
478
479
$query1 = "original IN ( " . implode(", ", $placeholders) . " )";
541
$values = array();
542
foreach( $original_array as $string ){
543
$placeholders[] = '%s';
544
+ $values[] = trp_full_trim( $string );
545
}
546
547
$query .= "( " . implode ( ", ", $placeholders ) . " )";
571
$placeholders = array();
572
foreach( $original_array as $string ){
573
$placeholders[] = '%s';
574
+ $values[] = trp_full_trim( $string );
575
}
576
}
577
641
$last_id = $this->db->get_var("SELECT MAX(id) FROM " . $table_name );
642
return $last_id;
643
}
644
+
645
+ /**
646
+ * Returns a selection of rows from a specific location.
647
+ * Only id and original are selected.
648
+ *
649
+ * Ex. if $inferior_limit = 400 and $batch_size = 10
650
+ * You will get rows 401 to 411
651
+ *
652
+ * @param $language_code
653
+ * @param $inferior_limit
654
+ * @param $batch_size
655
+ *
656
+ * @return array|null|object
657
+ */
658
+ public function get_rows_from_location( $language_code, $inferior_limit, $batch_size, $columns_to_retrieve ) {
659
+ $columns_query_part = '';
660
+ foreach ( $columns_to_retrieve as $column ) {
661
+ $columns_query_part .= $column . ',';
662
+ }
663
+ $columns_query_part = rtrim( $columns_query_part, ',' );
664
+ $query = "SELECT " . $columns_query_part . " FROM `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` WHERE status != " . self::NOT_TRANSLATED . " ORDER BY id LIMIT " . $inferior_limit . ", " . $batch_size;
665
+ $dictionary = $this->db->get_results( $query, ARRAY_A );
666
+ return $dictionary;
667
+ }
668
+
669
+ /**
670
+ * Update non-gettext strings in DB
671
+ *
672
+ * @param array $update_strings Array of strings to update
673
+ * @param string $language_code Language code
674
+ * @param array $columns_to_update Array with the name of columns to update id, original, translated, status, block_type
675
+ * @param string $placeholders_query_part For query on all columns '%d', '%s', '%s', '%d', '%d'
676
+ */
677
+ public function update_strings( $update_strings, $language_code, $columns_to_update, $placeholders ) {
678
+ if ( count( $update_strings ) == 0 ) {
679
+ return;
680
+ }
681
+
682
+ $columns_query_part = '';
683
+ foreach ( $columns_to_update as $column ) {
684
+ $columns_query_part .= $column . ',';
685
+ }
686
+ $columns_query_part = rtrim( $columns_query_part, ',' );
687
+
688
+ $query = "INSERT INTO `" . sanitize_text_field( $this->get_table_name( $language_code ) ) . "` ( " . $columns_query_part . " ) VALUES ";
689
+
690
+ $values = array();
691
+ $place_holders = array();
692
+
693
+ $placeholders_query_part = '(';
694
+ foreach ( $placeholders as $placeholder ) {
695
+ $placeholders_query_part .= "'" . $placeholder . "',";
696
+ }
697
+ $placeholders_query_part = rtrim( $placeholders_query_part, ',' );
698
+ $placeholders_query_part .= ')';
699
+
700
+ foreach ( $update_strings as $string ) {
701
+ foreach( $columns_to_update as $column ) {
702
+ array_push( $values, $string[$column] );
703
+ }
704
+ $place_holders[] = $placeholders_query_part;
705
+ }
706
+
707
+ $on_duplicate = ' ON DUPLICATE KEY UPDATE ';
708
+ foreach ( $columns_to_update as $column ) {
709
+ if ( $column == 'id' ){
710
+ continue;
711
+ }
712
+ $on_duplicate .= $column . '=VALUES(' . $column . '),';
713
+ }
714
+ $query .= implode( ', ', $place_holders );
715
+
716
+ $on_duplicate = rtrim( $on_duplicate, ',' );
717
+ $query .= $on_duplicate;
718
+
719
+ // you cannot insert multiple rows at once using insert() method.
720
+ // but by using prepare you cannot insert NULL values.
721
+
722
+ $prepared_query = $this->db->prepare($query . ' ', $values);
723
+ $this->db->query( $prepared_query );
724
+ }
725
}
includes/class-settings.php CHANGED
@@ -69,7 +69,6 @@ class TRP_Settings{
69
add_options_page( 'TranslatePress', 'TranslatePress', apply_filters( 'trp_settings_capability', 'manage_options' ), 'translate-press', array( $this, 'settings_page_content' ) );
70
add_submenu_page( 'TRPHidden', 'TranslatePress Addons', 'TRPHidden', 'manage_options', 'trp_addons_page', array($this, 'addons_page_content') );
71
add_submenu_page( 'TRPHidden', 'TranslatePress Test Google API Key', 'TRPHidden', 'manage_options', 'trp_test_google_key_page', array($this, 'test_google_key_page_content') );
72
- add_submenu_page( 'TRPHidden', 'TranslatePress Remove Duplicate Rows', 'TRPHidden', 'manage_options', 'trp_remove_duplicate_rows', array($this, 'trp_remove_duplicate_rows') );
73
}
74
75
/**
@@ -102,114 +101,6 @@ class TRP_Settings{
102
require_once TRP_PLUGIN_DIR . 'partials/test-google-key-settings-page.php';
103
}
104
105
- /**
106
- * Remove duplicate rows from DB for trp_dictionary tables.
107
- * Removes untranslated strings if there is a translated version.
108
- *
109
- * Iterates over languages. Each language is iterated in batches of 10 000
110
- */
111
- public function trp_remove_duplicate_rows(){
112
- if ( ! current_user_can( 'manage_options' ) ){
113
- return;
114
- }
115
- // prepare page structure
116
- require_once TRP_PLUGIN_DIR . 'partials/trp-remove-duplicate-rows.php';
117
-
118
- if ( empty( $_GET['trp_rm_duplicates'] ) ){
119
- // iteration not started
120
- return;
121
- }
122
- if ( $_GET['trp_rm_duplicates'] === 'done' ){
123
- // iteration finished
124
- 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>';
125
- return;
126
- }
127
- $nonce = wp_verify_nonce( $_GET['trp_rm_nonce'], 'tpremoveduplicaterows' );
128
- if ( $nonce === false ){
129
- 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>';
130
- return;
131
- }
132
-
133
- $next_get_batch = 1;
134
- $batch_size = apply_filters( 'trp_rm_duplicate_batch_size', 10000 );
135
- if ( !empty( $_GET['trp_rm_batch_size'] ) && (int) $_GET['trp_rm_batch'] > 0 ){
136
- $batch_size = (int) $_GET['trp_rm_batch_size'];
137
- }
138
- if ( in_array( $_GET['trp_rm_duplicates'], $this->settings['translation-languages'] ) ) {
139
- // language code found in array
140
- $language_code = $_GET['trp_rm_duplicates'];
141
- // skip default language since it doesn't have a table
142
- if ( $language_code != $this->settings['default-language'] ) {
143
- if ( ! $this->trp_query ) {
144
- $trp = TRP_Translate_Press::get_trp_instance();
145
- /* @var TRP_Query */
146
- $this->trp_query = $trp->get_component( 'query' );
147
- }
148
- $table_name = $this->trp_query->get_table_name( $language_code );
149
- echo '<div>' . sprintf( __( 'Querying table <strong>%s</strong>', 'translatepress-multilingual' ), $table_name ) . '</div>';
150
-
151
- $last_id = $this->trp_query->get_last_id( $table_name );
152
- if ( !empty( $_GET['trp_rm_batch'] ) && (int) $_GET['trp_rm_batch'] > 0 ) {
153
- $get_batch = (int)$_GET['trp_rm_batch'];
154
- }else{
155
- $get_batch = 1;
156
- }
157
- $batch = $batch_size * $get_batch;
158
-
159
- /* Execute this query only for string with ID < $batch. This ensures that the query is fast.
160
- * Deleting duplicate rows for the first 20k rows might take too long.
161
- * As a solution we are deleting the duplicates of the first 10k rows ( 1 to 10 000),
162
- * 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).
163
- * Same goes for higher numbers.
164
- */
165
- $result1 = $this->trp_query->remove_duplicate_rows_in_dictionary_table( $language_code, $batch );
166
- $result2 = 0;
167
- if ( $batch > $last_id ){
168
- // execute this query only when we do not have any more duplicate rows
169
- $result2 = $this->trp_query->remove_untranslated_strings_if_translation_available( $language_code );
170
- }else{
171
- $next_get_batch = $get_batch + 1;
172
- }
173
-
174
- if ( ( $result1 === false ) || ( $result2 === false ) ) {
175
- // if query outputted error do not continue iteration
176
- return;
177
- }else{
178
- $result = $result1 + $result2;
179
- echo '<div>' . sprintf( __( '%s duplicates removed', 'translatepress-multilingual' ), $result ) . '</div>';
180
- }
181
- }
182
- if ( $next_get_batch == 1 ) {
183
- // finished with the current language
184
- $index = array_search( $language_code, $this->settings['translation-languages'] );
185
- if ( isset ( $this->settings['translation-languages'][ $index + 1 ] ) ) {
186
- // next language code in array
187
- $next_language = $this->settings['translation-languages'][ $index + 1 ];
188
- } else {
189
- // finish iteration due to completing all the translation languages
190
- $next_language = 'done';
191
- }
192
- }else{
193
- $next_language = $language_code;
194
- }
195
- }else{
196
- // finish iteration due to incorrect translation language
197
- $next_language = 'done';
198
- }
199
-
200
- // construct and redirect to next url
201
- $url = add_query_arg( array(
202
- 'page' => 'trp_remove_duplicate_rows',
203
- 'trp_rm_duplicates' => $next_language,
204
- 'trp_rm_batch' => $next_get_batch,
205
- 'trp_rm_batch_size' => $batch_size,
206
- 'trp_rm_nonce' => wp_create_nonce('tpremoveduplicaterows')
207
- ), site_url('wp-admin/admin.php') );
208
- echo "<meta http-equiv='refresh' content='0; url={$url}' />";
209
- echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
210
- exit;
211
- }
212
-
213
/**
214
* Register settings option.
215
*/
69
add_options_page( 'TranslatePress', 'TranslatePress', apply_filters( 'trp_settings_capability', 'manage_options' ), 'translate-press', array( $this, 'settings_page_content' ) );
70
add_submenu_page( 'TRPHidden', 'TranslatePress Addons', 'TRPHidden', 'manage_options', 'trp_addons_page', array($this, 'addons_page_content') );
71
add_submenu_page( 'TRPHidden', 'TranslatePress Test Google API Key', 'TRPHidden', 'manage_options', 'trp_test_google_key_page', array($this, 'test_google_key_page_content') );
72
}
73
74
/**
101
require_once TRP_PLUGIN_DIR . 'partials/test-google-key-settings-page.php';
102
}
103
104
/**
105
* Register settings option.
106
*/
includes/class-translation-manager.php CHANGED
@@ -181,7 +181,7 @@ class TRP_Translation_Manager{
181
if ( isset( $string->id ) && is_numeric( $string->id ) ) {
182
$id_array[$key] = (int)$string->id;
183
} else if ( isset( $string->original ) ) {
184
- $original_array[$key] = trp_sanitize_string( $string->original );
185
}
186
}
187
@@ -396,7 +396,7 @@ class TRP_Translation_Manager{
396
}
397
array_push($update_strings[ $language ], array(
398
'id' => (int)$string->id,
399
- 'original' => trp_sanitize_string( $string->original ),
400
'translated' => trp_sanitize_string( $string->translated ),
401
'status' => (int)$string->status,
402
'block_type' => (int)$string->block_type
@@ -513,7 +513,7 @@ class TRP_Translation_Manager{
513
}
514
$ajax_translated_string_list = $strings->$language;
515
foreach( $ajax_translated_string_list as $ajax_key => $ajax_string ) {
516
- if ( trp_sanitize_string( $ajax_string->original ) == $dictionary_string->original ) {
517
if ( $ajax_string->translated != '' ) {
518
$dictionaries[ $language ][ $dictionary_string_key ]->translated = trp_sanitize_string( $ajax_string->translated );
519
$dictionaries[ $language ][ $dictionary_string_key ]->status = (int) $ajax_string->status;
@@ -705,13 +705,14 @@ class TRP_Translation_Manager{
705
}
706
707
$strings = $this->trp_query->get_all_gettext_strings($TRP_LANGUAGE);
708
- if (!empty($strings))
709
- $trp_translated_gettext_texts = $strings;
710
711
- foreach( $trp_translated_gettext_texts as $key => $value ){
712
- $trp_strings[$value['domain'] . '::' . $value['original']] = $value;
713
}
714
- $trp_translated_gettext_texts = $trp_strings;
715
}
716
}
717
@@ -1212,5 +1213,77 @@ class TRP_Translation_Manager{
1212
}
1213
}
1214
}
1215
-
1216
- }
181
if ( isset( $string->id ) && is_numeric( $string->id ) ) {
182
$id_array[$key] = (int)$string->id;
183
} else if ( isset( $string->original ) ) {
184
+ $original_array[$key] = trp_full_trim( trp_sanitize_string( $string->original ) );
185
}
186
}
187
396
}
397
array_push($update_strings[ $language ], array(
398
'id' => (int)$string->id,
399
+ 'original' => trp_full_trim( trp_sanitize_string( $string->original ) ),
400
'translated' => trp_sanitize_string( $string->translated ),
401
'status' => (int)$string->status,
402
'block_type' => (int)$string->block_type
513
}
514
$ajax_translated_string_list = $strings->$language;
515
foreach( $ajax_translated_string_list as $ajax_key => $ajax_string ) {
516
+ if ( trp_full_trim( trp_sanitize_string( $ajax_string->original ) ) == $dictionary_string->original ) {
517
if ( $ajax_string->translated != '' ) {
518
$dictionaries[ $language ][ $dictionary_string_key ]->translated = trp_sanitize_string( $ajax_string->translated );
519
$dictionaries[ $language ][ $dictionary_string_key ]->status = (int) $ajax_string->status;
705
}
706
707
$strings = $this->trp_query->get_all_gettext_strings($TRP_LANGUAGE);
708
+ if ( !empty( $strings ) ) {
709
+ $trp_translated_gettext_texts = $strings;
710
711
+ foreach ( $trp_translated_gettext_texts as $key => $value ) {
712
+ $trp_strings[ $value['domain'] . '::' . $value['original'] ] = $value;
713
+ }
714
+ $trp_translated_gettext_texts = $trp_strings;
715
}
716
}
717
}
718
1213
}
1214
}
1215
}
1216
+
1217
+ /**
1218
+ * Return true if the string contains characters which are not allowed in the query
1219
+ *
1220
+ * Only valid for utf8.
1221
+ * Function is an extract of strip_invalid_text() function from wp-includes/wp-db.php
1222
+ *
1223
+ * @param $string
1224
+ *
1225
+ * @return bool
1226
+ */
1227
+ public function has_bad_characters( $string ) {
1228
+ $regex = '/
1229
+ (
1230
+ (?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
1231
+ | [\xC2-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
1232
+ | \xE0[\xA0-\xBF][\x80-\xBF] # triple-byte sequences 1110xxxx 10xxxxxx * 2
1233
+ | [\xE1-\xEC][\x80-\xBF]{2}
1234
+ | \xED[\x80-\x9F][\x80-\xBF]
1235
+ | [\xEE-\xEF][\x80-\xBF]{2}';
1236
+
1237
+ $regex .= '
1238
+ | \xF0[\x90-\xBF][\x80-\xBF]{2} # four-byte sequences 11110xxx 10xxxxxx * 3
1239
+ | [\xF1-\xF3][\x80-\xBF]{3}
1240
+ | \xF4[\x80-\x8F][\x80-\xBF]{2}
1241
+ ';
1242
+
1243
+
1244
+ $regex .= '){1,40} # ...one or more times
1245
+ )
1246
+ | . # anything else
1247
+ /x';
1248
+ $stripped_string = preg_replace( $regex, '$1', $string );
1249
+
1250
+ if ( $stripped_string === $string ){
1251
+ return false;
1252
+ }else {
1253
+ return true;
1254
+ }
1255
+ }
1256
+
1257
+ /**
1258
+ * Records a series of strings which may have encoding issues
1259
+ *
1260
+ * Does not alter dictionary.
1261
+ *
1262
+ * @param $dictionary
1263
+ * @param $prepared_query
1264
+ * @param $strings_array
1265
+ *
1266
+ * @return mixed
1267
+ */
1268
+ public function display_possible_db_errors( $dictionary, $prepared_query, $strings_array ){
1269
+ global $trp_editor_notices;
1270
+ if ( trp_is_translation_editor( 'preview' ) && is_array( $dictionary ) && count( $dictionary ) === 0 ){
1271
+ if ( $this->has_bad_characters( $prepared_query ) ) {
1272
+ $html = "<div class='trp-notice trp-notice-warning'><p class='trp-bad-encoded-strings'>" . __( '<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.', 'translatepress-multilingual' ) . "</p>";
1273
+ $html .= "<ul class='trp-bad-encoded-strings-list'>";
1274
+ foreach( $strings_array as $string ){
1275
+ if ( $this->has_bad_characters( $string ) ){
1276
+ $html .= "<li>" . $string . "</li>";
1277
+ }
1278
+ }
1279
+ $html .= "</ul></div>";
1280
+
1281
+ $trp_editor_notices .= $html;
1282
+ }
1283
+ }
1284
+
1285
+ // no modifications to the dictionary
1286
+ return $dictionary;
1287
+ }
1288
+
1289
+ }
includes/class-translation-render.php CHANGED
@@ -89,40 +89,17 @@ class TRP_Translation_Render{
89
return false;
90
}
91
92
- /**
93
- * Trim strings.
94
- *
95
- * @param string $string Raw string.
96
- * @return string Trimmed string.
97
- */
98
- public function full_trim( $string ) {
99
- /* Make sure you update full_trim function from trp-ajax too*/
100
-
101
- /* Apparently the � char in the trim function turns some strings in an empty string so they can't be translated but I don't really know if we should remove it completely
102
- Removed chr( 194 ) . chr( 160 ) because it altered some special characters (¿¡)
103
- Also removed \xA0 (the same as chr(160) for altering special characters */
104
- //$word = trim($word," \t\n\r\0\x0B\xA0�".chr( 194 ) . chr( 160 ) );
105
-
106
- /* Solution to replace the chr(194).chr(160) from trim function, in order to escape the whitespace character ( \xc2\xa0 ), an old bug that couldn't be replicated anymore. */
107
- $prefix = "\xc2\xa0";
108
- $prefix_length = strlen($prefix);
109
- do{
110
- $previous_iteration_string = $string;
111
- $string = trim( $string," \t\n\r\0\x0B");
112
- if ( substr( $string, 0, $prefix_length ) == $prefix ) {
113
- $string = substr( $string, $prefix_length );
114
- }
115
- if ( substr( $string, - $prefix_length, $prefix_length ) == $prefix ) {
116
- $string = substr( $string, 0, - $prefix_length );
117
- }
118
- }while( $string != $previous_iteration_string );
119
-
120
- if ( strip_tags( $string ) == "" || trim ($string, " \t\n\r\0\x0B\xA0�.,/`~!@#\$€£%^&*():;-_=+[]{}\\|?/<>1234567890'\"" ) == '' ){
121
- $string = '';
122
- }
123
-
124
- return $string;
125
- }
126
127
/**
128
* Preview mode string category name for give node type.
@@ -237,7 +214,7 @@ class TRP_Translation_Render{
237
* @return string
238
*/
239
public function trim_translation_block( $string ){
240
- return preg_replace('/\s+/', ' ', strip_tags( html_entity_decode( htmlspecialchars_decode( $this->full_trim( $string ), ENT_QUOTES ) ) ));
241
}
242
243
/**
@@ -284,6 +261,7 @@ class TRP_Translation_Render{
284
* @return string Translated HTML page.
285
*/
286
public function translate_page( $output ){
287
288
/* replace our special tags so we have valid html */
289
$output = str_replace('#!trpst#', '<', $output);
@@ -367,8 +345,10 @@ class TRP_Translation_Render{
367
if ( ! $this->translation_manager ) {
368
$this->translation_manager = $trp->get_component( 'translation_manager' );
369
}
370
if ( $translate_normal_strings ) {
371
$all_existing_translation_blocks = $this->trp_query->get_all_translation_blocks( $language_code );
372
// trim every translation block original now, to avoid over-calling trim function later
373
foreach ( $all_existing_translation_blocks as $key => $existing_tb ) {
374
$all_existing_translation_blocks[ $key ]->trimmed_original = $this->trim_translation_block( $all_existing_translation_blocks[ $key ]->original );
@@ -398,7 +378,7 @@ class TRP_Translation_Render{
398
if( $row->nodetype !== 5 && $row->nodetype !== 3 )//add all tags that are not root or text, text nodes can't have attributes
399
$trp_attr_rows[] = $row;
400
401
- if ( $translate_normal_strings ) {
402
$translation_block = $this->find_translation_block( $row, $all_existing_translation_blocks, $merge_rules );
403
if ( $translation_block ) {
404
$existing_classes = $row->getAttribute( 'class' );
@@ -507,33 +487,35 @@ class TRP_Translation_Render{
507
}
508
}
509
foreach ( $html->find('.translation-block') as $k => $row ){
510
- if( $this->full_trim($row->outertext)!=""
511
&& $row->parent()->tag!="script"
512
&& $row->parent()->tag!="style"
513
- && !is_numeric($this->full_trim($row->outertext))
514
- && !preg_match('/^\d+%#x2F;',$this->full_trim($row->outertext))
515
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
516
&& $row->parent()->tag != 'title'
517
&& strpos($row->outertext,'[vc_') === false )
518
{
519
- array_push( $translateable_strings, $this->full_trim( $row->innertext ) );
520
array_push( $nodes, array('node' => $row, 'type' => 'block'));
521
}
522
}
523
524
foreach ( $html->find('text') as $k => $row ){
525
- if( $this->full_trim($row->outertext)!=""
526
&& $row->parent()->tag!="script"
527
&& $row->parent()->tag!="style"
528
- && !is_numeric($this->full_trim($row->outertext))
529
- && !preg_match('/^\d+%#x2F;',$this->full_trim($row->outertext))
530
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
531
&& !$this->has_ancestor_class( $row, 'translation-block')
532
&& $row->parent()->tag != 'title'
533
&& strpos($row->outertext,'[vc_') === false )
534
{
535
// $translateable_strings array needs to be in sync in $nodes array
536
- array_push( $translateable_strings, $this->full_trim( $row->outertext ) );
537
if( $row->parent()->tag == 'button') {
538
array_push($nodes, array('node' => $row, 'type' => 'button'));
539
}
@@ -548,9 +530,10 @@ class TRP_Translation_Render{
548
}
549
550
foreach ( $html->find('input[type=\'submit\'],input[type=\'button\']') as $k => $row ){
551
- if( $this->full_trim($row->value)!=""
552
- && !is_numeric($this->full_trim($row->value))
553
- && !preg_match('/^\d+%#x2F;',$this->full_trim($row->value))
554
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
555
&& !$this->has_ancestor_class( $row, 'translation-block') )
556
{
@@ -559,9 +542,10 @@ class TRP_Translation_Render{
559
}
560
}
561
foreach ( $html->find('input[type=\'text\'],input[type=\'password\'],input[type=\'search\'],input[type=\'email\'],input:not([type]),textarea') as $k => $row ){
562
- if( $this->full_trim($row->placeholder)!=""
563
- && !is_numeric($this->full_trim($row->placeholder))
564
- && !preg_match('/^\d+%#x2F;',$this->full_trim($row->placeholder))
565
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
566
&& !$this->has_ancestor_class( $row, 'translation-block') )
567
{
@@ -733,7 +717,14 @@ class TRP_Translation_Render{
733
$link->href = str_replace('#TRPLINKPROCESSED', '', $link->href);
734
}
735
736
- return $html->save();
737
}
738
739
/**
@@ -901,7 +892,7 @@ class TRP_Translation_Render{
901
//strings existing in database,
902
903
if ( isset( $dictionary[$string]->translated ) ){
904
- $translated_strings[$i] = $dictionary[$this->full_trim($string)]->translated;
905
}else{
906
$new_strings[$i] = $translateable_strings[$i];
907
}
89
return false;
90
}
91
92
+ /**
93
+ * Trim strings.
94
+ * This function is kept for backwards compatibility for earlier versions of SEO Pack Add-on
95
+ *
96
+ * @deprecated
97
+ * @param string $string Raw string.
98
+ * @return string Trimmed string.
99
+ */
100
+ public function full_trim( $string ) {
101
+ return trp_full_trim( $string );
102
+ }
103
104
/**
105
* Preview mode string category name for give node type.
214
* @return string
215
*/
216
public function trim_translation_block( $string ){
217
+ return preg_replace('/\s+/', ' ', strip_tags( html_entity_decode( htmlspecialchars_decode( trp_full_trim( $string ), ENT_QUOTES ) ) ));
218
}
219
220
/**
261
* @return string Translated HTML page.
262
*/
263
public function translate_page( $output ){
264
+ global $trp_editor_notices;
265
266
/* replace our special tags so we have valid html */
267
$output = str_replace('#!trpst#', '<', $output);
345
if ( ! $this->translation_manager ) {
346
$this->translation_manager = $trp->get_component( 'translation_manager' );
347
}
348
+ $count_translation_blocks = 0;
349
if ( $translate_normal_strings ) {
350
$all_existing_translation_blocks = $this->trp_query->get_all_translation_blocks( $language_code );
351
+ $count_translation_blocks = count( $all_existing_translation_blocks );
352
// trim every translation block original now, to avoid over-calling trim function later
353
foreach ( $all_existing_translation_blocks as $key => $existing_tb ) {
354
$all_existing_translation_blocks[ $key ]->trimmed_original = $this->trim_translation_block( $all_existing_translation_blocks[ $key ]->original );
378
if( $row->nodetype !== 5 && $row->nodetype !== 3 )//add all tags that are not root or text, text nodes can't have attributes
379
$trp_attr_rows[] = $row;
380
381
+ if ( $translate_normal_strings && $count_translation_blocks > 0 ) {
382
$translation_block = $this->find_translation_block( $row, $all_existing_translation_blocks, $merge_rules );
383
if ( $translation_block ) {
384
$existing_classes = $row->getAttribute( 'class' );
487
}
488
}
489
foreach ( $html->find('.translation-block') as $k => $row ){
490
+ $trimmed_string = trp_full_trim($row->innertext);
491
+ if( $trimmed_string!=""
492
&& $row->parent()->tag!="script"
493
&& $row->parent()->tag!="style"
494
+ && !is_numeric($trimmed_string)
495
+ && !preg_match('/^\d+%#x2F;',$trimmed_string)
496
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
497
&& $row->parent()->tag != 'title'
498
&& strpos($row->outertext,'[vc_') === false )
499
{
500
+ array_push( $translateable_strings, $trimmed_string );
501
array_push( $nodes, array('node' => $row, 'type' => 'block'));
502
}
503
}
504
505
foreach ( $html->find('text') as $k => $row ){
506
+ $trimmed_string = trp_full_trim($row->outertext);
507
+ if( $trimmed_string!=""
508
&& $row->parent()->tag!="script"
509
&& $row->parent()->tag!="style"
510
+ && !is_numeric($trimmed_string)
511
+ && !preg_match('/^\d+%#x2F;',$trimmed_string)
512
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
513
&& !$this->has_ancestor_class( $row, 'translation-block')
514
&& $row->parent()->tag != 'title'
515
&& strpos($row->outertext,'[vc_') === false )
516
{
517
// $translateable_strings array needs to be in sync in $nodes array
518
+ array_push( $translateable_strings, $trimmed_string );
519
if( $row->parent()->tag == 'button') {
520
array_push($nodes, array('node' => $row, 'type' => 'button'));
521
}
530
}
531
532
foreach ( $html->find('input[type=\'submit\'],input[type=\'button\']') as $k => $row ){
533
+ $trimmed_string = trp_full_trim($row->value);
534
+ if( $trimmed_string!=""
535
+ && !is_numeric($trimmed_string)
536
+ && !preg_match('/^\d+%#x2F;',$trimmed_string)
537
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
538
&& !$this->has_ancestor_class( $row, 'translation-block') )
539
{
542
}
543
}
544
foreach ( $html->find('input[type=\'text\'],input[type=\'password\'],input[type=\'search\'],input[type=\'email\'],input:not([type]),textarea') as $k => $row ){
545
+ $trimmed_string = trp_full_trim($row->placeholder);
546
+ if( $trimmed_string!=""
547
+ && !is_numeric($trimmed_string)
548
+ && !preg_match('/^\d+%#x2F;',$trimmed_string)
549
&& !$this->has_ancestor_attribute( $row, $no_translate_attribute )
550
&& !$this->has_ancestor_class( $row, 'translation-block') )
551
{
717
$link->href = str_replace('#TRPLINKPROCESSED', '', $link->href);
718
}
719
720
+ // Append an html table containing the errors
721
+ $trp_editor_notices = apply_filters( 'trp_editor_notices', $trp_editor_notices );
722
+ if ( trp_is_translation_editor('preview') && $trp_editor_notices != '' ){
723
+ $body = $html->find('body', 0 );
724
+ $body->innertext = '<div data-no-translation class="trp-editor-notices">' . $trp_editor_notices . "</div>" . $body->innertext;
725
+ }
726
+
727
+ return $html->save();
728
}
729
730
/**
892
//strings existing in database,
893
894
if ( isset( $dictionary[$string]->translated ) ){
895
+ $translated_strings[$i] = $dictionary[$string]->translated;
896
}else{
897
$new_strings[$i] = $translateable_strings[$i];
898
}
includes/class-upgrade.php ADDED
@@ -0,0 +1,378 @@
1
+ <?php
2
+
3
+ /**
4
+ * Class TRP_Upgrade
5
+ *
6
+ * When changing plugin version, do the necessary checks and database upgrades.
7
+ */
8
+ class TRP_Upgrade {
9
+
10
+ protected $settings;
11
+ /* @var TRP_Query */
12
+ protected $trp_query;
13
+
14
+ /**
15
+ * TRP_Upgrade constructor.
16
+ *
17
+ * @param $settings
18
+ */
19
+ public function __construct( $settings ){
20
+ $this->settings = $settings;
21
+ }
22
+
23
+ /**
24
+ * Register Settings subpage for TranslatePress
25
+ */
26
+ public function register_menu_page(){
27
+ add_submenu_page( 'TRPHidden', 'TranslatePress Remove Duplicate Rows', 'TRPHidden', 'manage_options', 'trp_remove_duplicate_rows', array($this, 'trp_remove_duplicate_rows') );
28
+ add_submenu_page( 'TRPHidden', 'TranslatePress Update Database', 'TRPHidden', 'manage_options', 'trp_update_database', array( $this, 'trp_full_trim_originals' ) );
29
+ }
30
+
31
+ /**
32
+ * When changing plugin version, call certain database upgrade functions.
33
+ *
34
+ */
35
+ public function check_for_necessary_updates(){
36
+ $trp = TRP_Translate_Press::get_trp_instance();
37
+ if( ! $this->trp_query ) {
38
+ $this->trp_query = $trp->get_component( 'query' );
39
+ }
40
+ $stored_database_version = get_option('trp_plugin_version');
41
+ if( empty($stored_database_version) || version_compare( TRP_PLUGIN_VERSION, $stored_database_version, '>' ) ){
42
+ $this->check_if_gettext_tables_exist();
43
+ $this->trp_query->check_for_block_type_column();
44
+ $this->check_for_full_trim_originals( $stored_database_version );
45
+ }
46
+
47
+ update_option( 'trp_plugin_version', TRP_PLUGIN_VERSION );
48
+ }
49
+
50
+ /**
51
+ * Iterates over all languages to call gettext table checking
52
+ */
53
+ public function check_if_gettext_tables_exist(){
54
+ $trp = TRP_Translate_Press::get_trp_instance();
55
+ if( ! $this->trp_query ) {
56
+ $this->trp_query = $trp->get_component( 'query' );
57
+ }
58
+ if( !empty( $this->settings['translation-languages'] ) ){
59
+ foreach( $this->settings['translation-languages'] as $site_language_code ){
60
+ $this->trp_query->check_gettext_table($site_language_code);
61
+ }
62
+ }
63
+ }
64
+
65
+ /**
66
+ * Sets an option to know that an upgrade is needed
67
+ */
68
+ public function check_for_full_trim_originals( $stored_database_version ){
69
+ if ( version_compare( '1.4.0', $stored_database_version, '>' ) ){
70
+ update_option( 'trp_updated_database_full_trim_originals_140', 'no' );
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Show admin notice about updating database
76
+ */
77
+ public function show_admin_notice(){
78
+ $option = get_option( 'trp_updated_database_full_trim_originals_140', 'is not set' );
79
+ // show admin notice if option is set to false AND we are not on the update database page
80
+ if ( $option === 'no' && !( isset( $_GET[ 'page'] ) && $_GET['page'] == 'trp_update_database' ) ){
81
+ add_action( 'admin_notices', array( $this, 'admin_notice_update_database_full_trim' ) );
82
+ }
83
+ }
84
+
85
+ /**
86
+ * Print admin notice message
87
+ */
88
+ public function admin_notice_update_database_full_trim() {
89
+ $url = add_query_arg( array(
90
+ 'page' => 'trp_update_database',
91
+ ), site_url('wp-admin/admin.php') );
92
+
93
+ // maybe change notice color to blue #28B1FF
94
+ $html = '<div id="message" class="updated">';
95
+ $html .= '<p><strong>' . esc_html__( 'TranslatePress data update', 'translatepress-multilingual' ) . '</strong> &#8211; ' . esc_html__( 'We need to update your translations database to the latest version.', 'translatepress-multilingual' ) . '</p>';
96
+ $html .= '<p class="submit"><a href="' . esc_url( $url ) . '" class="button-primary">' . esc_html__( 'Run the updater', 'translatepress-multilingual' ) . '</a></p>';
97
+ $html .= '</div>';
98
+ echo $html;
99
+ }
100
+
101
+ /**
102
+ * Remove duplicate rows from DB for trp_dictionary tables.
103
+ * Removes untranslated strings if there is a translated version.
104
+ *
105
+ * Iterates over languages. Each language is iterated in batches of 10 000
106
+ *
107
+ * Not accessible from anywhere else
108
+ * http://example.com/wp-admin/admin.php?page=trp_remove_duplicate_rows
109
+ */
110
+ public function trp_full_trim_originals(){
111
+ $start_time = microtime(true);
112
+ if ( ! current_user_can( 'manage_options' ) ){
113
+ return;
114
+ }
115
+ // prepare page structure
116
+ require_once TRP_PLUGIN_DIR . 'partials/trp-update-database.php';
117
+
118
+ if ( empty( $_GET['trp_updb_lang'] ) ){
119
+ // iteration not started
120
+ return;
121
+ }
122
+ if ( $_GET['trp_updb_lang'] === 'done' ){
123
+ // iteration finished
124
+ $this->print_queried_tables();
125
+ echo __( '<p><strong>Successfully updated database!</strong></p>', 'translatepress-multilingual' ) . '<br><a href="' . site_url( 'wp-admin/options-general.php?page=translate-press' ) . '"> <input type="button" value="' . __( 'Back to TranslatePress Settings page', 'translatepress-multilingual' ) . '" class="button-primary"></a>';
126
+ return;
127
+ }
128
+ $nonce = wp_verify_nonce( $_GET['trp_updb_nonce'], 'tpupdatedatabase' );
129
+ if ( $nonce === false ){
130
+ 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>';
131
+ return;
132
+ }
133
+
134
+ $next_get_batch = 0;
135
+ $batch_size = apply_filters( 'trp_updb_batch_size', 200 );
136
+ if ( !empty( $_GET['trp_updb_batch_size'] ) && (int) $_GET['trp_updb_batch'] >= 0 ){
137
+ $batch_size = (int) $_GET['trp_updb_batch_size'];
138
+ }
139
+ if ( in_array( $_GET['trp_updb_lang'], $this->settings['translation-languages'] ) ) {
140
+ // language code found in array
141
+ $language_code = $_GET['trp_updb_lang'];
142
+ // skip default language since it doesn't have a table
143
+ $finished_with_language = true;
144
+ if ( $language_code != $this->settings['default-language'] ) {
145
+ if ( ! $this->trp_query ) {
146
+ $trp = TRP_Translate_Press::get_trp_instance();
147
+ /* @var TRP_Query */
148
+ $this->trp_query = $trp->get_component( 'query' );
149
+ }
150
+
151
+ if ( !empty( $_GET['trp_updb_batch'] ) && (int) $_GET['trp_updb_batch'] > 0 ) {
152
+ $get_batch = (int)$_GET['trp_updb_batch'];
153
+ }else{
154
+ $get_batch = 0;
155
+ }
156
+
157
+ $this->print_queried_tables( $language_code );
158
+
159
+ $start_time = microtime(true);
160
+ $duration = 0;
161
+ while( $duration < 2 ){
162
+ $inferior_limit = $batch_size * $get_batch;
163
+ $finished_with_language = $this->execute_full_trim( $language_code, $inferior_limit, $batch_size );
164
+ if ( $finished_with_language ) {
165
+ break;
166
+ }else {
167
+ $get_batch = $get_batch + 1;
168
+ }
169
+ $stop_time = microtime( true );
170
+ $duration = $stop_time - $start_time;
171
+ }
172
+ if ( ! $finished_with_language ) {
173
+ $next_get_batch = $get_batch + 1;
174
+ }
175
+ }
176
+
177
+ if ( $finished_with_language ) {
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
+ // this will stop showing the admin notice
187
+ update_option( 'trp_updated_database_full_trim_originals_140', 'yes' );
188
+ }
189
+ }else{
190
+ $next_language = $language_code;
191
+ }
192
+ }else{
193
+ // finish iteration due to incorrect translation language
194
+ $next_language = 'done';
195
+ }
196
+
197
+ // construct and redirect to next url
198
+ $url = add_query_arg( array(
199
+ 'page' => 'trp_update_database',
200
+ 'trp_updb_lang' => $next_language,
201
+ 'trp_updb_batch' => $next_get_batch,
202
+ 'trp_updb_batch_size' => $batch_size,
203
+ 'trp_updb_nonce' => wp_create_nonce('tpupdatedatabase')
204
+ ), site_url('wp-admin/admin.php') );
205
+ echo "<meta http-equiv='refresh' content='0; url={$url}' />";
206
+ echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
207
+ exit;
208
+ }
209
+
210
+ /**
211
+ * Prints all the tables in the translation languages array until the current language with Done.
212
+ *
213
+ * If current language is given, do not print Done for it.
214
+ *
215
+ * @param bool | string $current_language_code
216
+ */
217
+ public function print_queried_tables( $current_language_code = false ){
218
+ if ( ! $this->trp_query ) {
219
+ $trp = TRP_Translate_Press::get_trp_instance();
220
+ /* @var TRP_Query */
221
+ $this->trp_query = $trp->get_component( 'query' );
222
+ }
223
+ foreach ( $this->settings['translation-languages'] as $language_code ){
224
+ if ( $language_code == $this->settings['default-language'] ){
225
+ continue;
226
+ }
227
+ $table_name = $this->trp_query->get_table_name( $language_code );
228
+ $html = '<div>' . sprintf( __( 'Querying table <strong>%s</strong>... ', 'translatepress-multilingual' ), $table_name );
229
+ if ( $language_code != $current_language_code ) {
230
+ $html .= __( 'Done.', 'translatepress-multilingual' );
231
+ }
232
+ $html .= '</div>';
233
+ echo $html;
234
+ if ( $language_code == $current_language_code ) {
235
+ break;
236
+ }
237
+ }
238
+ }
239
+
240
+ /**
241
+ * Get all originals from the table, trim them and update originals back into table
242
+ *
243
+ * @param string $language_code Language code of the table
244
+ * @param int $inferior_limit Omit first X rows
245
+ * @param int $batch_size How many rows to query
246
+ *
247
+ * @return bool
248
+ */
249
+ public function execute_full_trim( $language_code, $inferior_limit, $batch_size ){
250
+ if ( ! $this->trp_query ) {
251
+ $trp = TRP_Translate_Press::get_trp_instance();
252
+ /* @var TRP_Query */
253
+ $this->trp_query = $trp->get_component( 'query' );
254
+ }
255
+ $strings = $this->trp_query->get_rows_from_location( $language_code, $inferior_limit, $batch_size, array( 'id', 'original' ) );
256
+ if ( count( $strings ) == 0 ) {
257
+ return true;
258
+ }
259
+ foreach( $strings as $key => $string ){
260
+ $strings[$key]['original'] = trp_full_trim( $strings[$key]['original'] );
261
+ }
262
+
263
+ // overwrite original only
264
+ $this->trp_query->update_strings( $strings, $language_code, array( 'id', 'original' ), array( '%d', '%s' ) );
265
+ return false;
266
+ }
267
+
268
+ /**
269
+ * Remove duplicate rows from DB for trp_dictionary tables.
270
+ * Removes untranslated strings if there is a translated version.
271
+ *
272
+ * Iterates over languages. Each language is iterated in batches of 10 000
273
+ *
274
+ * Not accessible from anywhere else
275
+ * http://example.com/wp-admin/admin.php?page=trp_remove_duplicate_rows
276
+ */
277
+ public function trp_remove_duplicate_rows(){
278
+ if ( ! current_user_can( 'manage_options' ) ){
279
+ return;
280
+ }
281
+ // prepare page structure
282
+ require_once TRP_PLUGIN_DIR . 'partials/trp-remove-duplicate-rows.php';
283
+
284
+ if ( empty( $_GET['trp_rm_duplicates'] ) ){
285
+ // iteration not started
286
+ return;
287
+ }
288
+ if ( $_GET['trp_rm_duplicates'] === 'done' ){
289
+ // iteration finished
290
+ 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>';
291
+ return;
292
+ }
293
+ $nonce = wp_verify_nonce( $_GET['trp_rm_nonce'], 'tpremoveduplicaterows' );
294
+ if ( $nonce === false ){
295
+ 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>';
296
+ return;
297
+ }
298
+
299
+ $next_get_batch = 1;
300
+ $batch_size = apply_filters( 'trp_rm_duplicate_batch_size', 10000 );
301
+ if ( !empty( $_GET['trp_rm_batch_size'] ) && (int) $_GET['trp_rm_batch'] > 0 ){
302
+ $batch_size = (int) $_GET['trp_rm_batch_size'];
303
+ }
304
+ if ( in_array( $_GET['trp_rm_duplicates'], $this->settings['translation-languages'] ) ) {
305
+ // language code found in array
306
+ $language_code = $_GET['trp_rm_duplicates'];
307
+ // skip default language since it doesn't have a table
308
+ if ( $language_code != $this->settings['default-language'] ) {
309
+ if ( ! $this->trp_query ) {
310
+ $trp = TRP_Translate_Press::get_trp_instance();
311
+ /* @var TRP_Query */
312
+ $this->trp_query = $trp->get_component( 'query' );
313
+ }
314
+ $table_name = $this->trp_query->get_table_name( $language_code );
315
+ echo '<div>' . sprintf( __( 'Querying table <strong>%s</strong>', 'translatepress-multilingual' ), $table_name ) . '</div>';
316
+
317
+ $last_id = $this->trp_query->get_last_id( $table_name );
318
+ if ( !empty( $_GET['trp_rm_batch'] ) && (int) $_GET['trp_rm_batch'] > 0 ) {
319
+ $get_batch = (int)$_GET['trp_rm_batch'];
320
+ }else{
321
+ $get_batch = 1;
322
+ }
323
+ $batch = $batch_size * $get_batch;
324
+
325
+ /* Execute this query only for string with ID < $batch. This ensures that the query is fast.
326
+ * Deleting duplicate rows for the first 20k rows might take too long.
327
+ * As a solution we are deleting the duplicates of the first 10k rows ( 1 to 10 000),
328
+ * 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).
329
+ * Same goes for higher numbers.
330
+ */
331
+ $result1 = $this->trp_query->remove_duplicate_rows_in_dictionary_table( $language_code, $batch );
332
+ $result2 = 0;
333
+ if ( $batch > $last_id ){
334
+ // execute this query only when we do not have any more duplicate rows
335
+ $result2 = $this->trp_query->remove_untranslated_strings_if_translation_available( $language_code );
336
+ }else{
337
+ $next_get_batch = $get_batch + 1;
338
+ }
339
+
340
+ if ( ( $result1 === false ) || ( $result2 === false ) ) {
341
+ // if query outputted error do not continue iteration
342
+ return;
343
+ }else{
344
+ $result = $result1 + $result2;
345
+ echo '<div>' . sprintf( __( '%s duplicates removed', 'translatepress-multilingual' ), $result ) . '</div>';
346
+ }
347
+ }
348
+ if ( $next_get_batch == 1 ) {
349
+ // finished with the current language
350
+ $index = array_search( $language_code, $this->settings['translation-languages'] );
351
+ if ( isset ( $this->settings['translation-languages'][ $index + 1 ] ) ) {
352
+ // next language code in array
353
+ $next_language = $this->settings['translation-languages'][ $index + 1 ];
354
+ } else {
355
+ // finish iteration due to completing all the translation languages
356
+ $next_language = 'done';
357
+ }
358
+ }else{
359
+ $next_language = $language_code;
360
+ }
361
+ }else{
362
+ // finish iteration due to incorrect translation language
363
+ $next_language = 'done';
364
+ }
365
+
366
+ // construct and redirect to next url
367
+ $url = add_query_arg( array(
368
+ 'page' => 'trp_remove_duplicate_rows',
369
+ 'trp_rm_duplicates' => $next_language,
370
+ 'trp_rm_batch' => $next_get_batch,
371
+ 'trp_rm_batch_size' => $batch_size,
372
+ 'trp_rm_nonce' => wp_create_nonce('tpremoveduplicaterows')
373
+ ), site_url('wp-admin/admin.php') );
374
+ echo "<meta http-equiv='refresh' content='0; url={$url}' />";
375
+ echo "<br> " . __( 'If the page does not redirect automatically', 'translatepress-multilingual' ) . " <a href='$url' >" . __( 'click here', 'translatepress-multilingual' ) . ".</a>";
376
+ exit;
377
+ }
378
+ }
includes/functions.php CHANGED
@@ -164,6 +164,43 @@ function trp_sanitize_string( $filtered ){
164
return $filtered;
165
}
166
167
168
/**
169
* function that checks if $_REQUEST['trp-edit-translation'] is set or if it has a certain value
@@ -582,4 +619,21 @@ function trp_bulk_debug($debug = false, $logger = array()){
582
error_log("$key : " . str_repeat(' ', $key_length - strlen($key)) . $value);
583
}
584
error_log('---------------------------------------------------------');
585
}
164
return $filtered;
165
}
166
167
+ /**
168
+ * Trim strings.
169
+ *
170
+ * @param string $string Raw string.
171
+ * @return string Trimmed string.
172
+ */
173
+ function trp_full_trim( $string ) {
174
+ /* Make sure you update full_trim function from trp-ajax too*/
175
+
176
+ /* Apparently the � char in the trim function turns some strings in an empty string so they can't be translated but I don't really know if we should remove it completely
177
+ Removed chr( 194 ) . chr( 160 ) because it altered some special characters (¿¡)
178
+ Also removed \xA0 (the same as chr(160) for altering special characters */
179
+ //$word = trim($word," \t\n\r\0\x0B\xA0�".chr( 194 ) . chr( 160 ) );
180
+
181
+ /* Solution to replace the chr(194).chr(160) from trim function, in order to escape the whitespace character ( \xc2\xa0 ), an old bug that couldn't be replicated anymore. */
182
+ /* Trim nbsp the same way as the whitespace (chr194 chr160) above */
183
+ $prefixes = array( "\xc2\xa0", "&nbsp;" );
184
+ do{
185
+ $previous_iteration_string = $string;
186
+ $string = trim($string, " \t\n\r\0\x0B");
187
+ foreach( $prefixes as $prefix ) {
188
+ $prefix_length = strlen($prefix);
189
+ if (substr($string, 0, $prefix_length) == $prefix) {
190
+ $string = substr($string, $prefix_length);
191
+ }
192
+ if (substr($string, -$prefix_length, $prefix_length) == $prefix) {
193
+ $string = substr($string, 0, -$prefix_length);
194
+ }
195
+ }
196
+ }while( $string != $previous_iteration_string );
197
+
198
+ if ( strip_tags( $string ) == "" || trim ($string, " \t\n\r\0\x0B\xA0�.,/`~!@#\$€£%^&*():;-_=+[]{}\\|?/<>1234567890'\"" ) == '' ){
199
+ $string = '';
200
+ }
201
+
202
+ return $string;
203
+ }
204
205
/**
206
* function that checks if $_REQUEST['trp-edit-translation'] is set or if it has a certain value
619
error_log("$key : " . str_repeat(' ', $key_length - strlen($key)) . $value);
620
}
621
error_log('---------------------------------------------------------');
622
+ }
623
+
624
+ /**
625
+ * Compatibility with WooCommerce PDF Invoices & Packing Slips
626
+ * https://wordpress.org/plugins/woocommerce-pdf-invoices-packing-slips/
627
+ *
628
+ * @since 1.4.0
629
+ *
630
+ * @param string $html
631
+ * @param object $instance
632
+ */
633
+
634
+ add_filter( 'wpo_wcpdf_get_html', 'trp_woo_pdf_invoices_and_packing_slips_compatibility', 10, 2);
635
+ function trp_woo_pdf_invoices_and_packing_slips_compatibility($html, $instance){
636
+ $html = str_replace('#!trpst#', '<', $html);
637
+ $html = str_replace('#!trpen#', '>', $html);
638
+ return $html;
639
}
includes/trp-ajax.php CHANGED
@@ -144,26 +144,29 @@ class TRP_Ajax{
144
* @return string Trimmed string.
145
*/
146
protected function full_trim( $string ) {
147
- /* Make sure you update full_trim function from translation-render too*/
148
-
149
- /* Apparently the � char in the trim function turns some strings in an empty string so they can't be translated but I don't really know if we should remove it completely
150
- Removed chr( 194 ) . chr( 160 ) because it altered some special characters (¿¡)
151
- Also removed \xA0 (the same as chr(160) for altering special characters */
152
- //$word = trim($word," \t\n\r\0\x0B\xA0�".chr( 194 ) . chr( 160 ) );
153
-
154
- /* Solution to replace the chr(194).chr(160) from trim function, in order to escape the whitespace character ( \xc2\xa0 ), an old bug that couldn't be replicated anymore. */
155
- $prefix = "\xc2\xa0";
156
- $prefix_length = strlen($prefix);
157
- do{
158
- $previous_iteration_string = $string;
159
- $string = trim( $string," \t\n\r\0\x0B");
160
- if ( substr( $string, 0, $prefix_length ) == $prefix ) {
161
- $string = substr( $string, $prefix_length );
162
- }
163
- if ( substr( $string, - $prefix_length, $prefix_length ) == $prefix ) {
164
- $string = substr( $string, 0, - $prefix_length );
165
- }
166
- }while( $string != $previous_iteration_string );
167
168
if ( strip_tags( $string ) == "" || trim ($string, " \t\n\r\0\x0B\xA0�.,/`~!@#\$€£%^&*():;-_=+[]{}\\|?/<>1234567890'\"" ) == '' ){
169
$string = '';
144
* @return string Trimmed string.
145
*/
146
protected function full_trim( $string ) {
147
+ /* Make sure you update full_trim function from translatepress/includes/functions.php too*/
148
+
149
+ /* Apparently the � char in the trim function turns some strings in an empty string so they can't be translated but I don't really know if we should remove it completely
150
+ Removed chr( 194 ) . chr( 160 ) because it altered some special characters (¿¡)
151
+ Also removed \xA0 (the same as chr(160) for altering special characters */
152
+ //$word = trim($word," \t\n\r\0\x0B\xA0�".chr( 194 ) . chr( 160 ) );
153
+
154
+ /* Solution to replace the chr(194).chr(160) from trim function, in order to escape the whitespace character ( \xc2\xa0 ), an old bug that couldn't be replicated anymore. */
155
+ /* Trim nbsp the same way as the whitespace (chr194 chr160) above */
156
+ $prefixes = array( "\xc2\xa0", "&nbsp;" );
157
+ do{
158
+ $previous_iteration_string = $string;
159
+ $string = trim($string, " \t\n\r\0\x0B");
160
+ foreach( $prefixes as $prefix ) {
161
+ $prefix_length = strlen($prefix);
162
+ if (substr($string, 0, $prefix_length) == $prefix) {
163
+ $string = substr($string, $prefix_length);
164
+ }
165
+ if (substr($string, -$prefix_length, $prefix_length) == $prefix) {
166
+ $string = substr($string, 0, -$prefix_length);
167
+ }
168
+ }
169
+ }while( $string != $previous_iteration_string );
170
171
if ( strip_tags( $string ) == "" || trim ($string, " \t\n\r\0\x0B\xA0�.,/`~!@#\$€£%^&*():;-_=+[]{}\\|?/<>1234567890'\"" ) == '' ){
172
$string = '';
index.php CHANGED
@@ -3,7 +3,7 @@
3
Plugin Name: TranslatePress - Multilingual
4
Plugin URI: https://translatepress.com/
5
Description: Experience a better way of translating your WordPress site, with full support for WooCommerce and site builders.
6
- Version: 1.3.9
7
Author: Cozmoslabs, Razvan Mocanu, Madalin Ungureanu, Cristophor Hurduban
8
Author URI: https://cozmoslabs.com/
9
Text Domain: translatepress-multilingual
3
Plugin Name: TranslatePress - Multilingual
4
Plugin URI: https://translatepress.com/
5
Description: Experience a better way of translating your WordPress site, with full support for WooCommerce and site builders.
6
+ Version: 1.4.0
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
@@ -1,6 +1,7 @@
1
<?php __("", "translatepress-multilingual"); ?>
2
<?php __("Error! Duplicate Url slug values.", "translatepress-multilingual"); ?>
3
<?php __("Limit this menu item to the following languages", "translatepress-multilingual"); ?>
4
<?php __("The Yoast SEO Sitemaps will now contain the default language slug: example.com/en/sitemap_index.xml <br/> This works perfectly, just take it into account when you submit the sitemap to Google.", "translatepress-multilingual"); ?>
5
<?php __("First by browser language, then IP address (recommended)", "translatepress-multilingual"); ?>
6
<?php __("First by IP address, then browser language", "translatepress-multilingual"); ?>
@@ -14,7 +15,6 @@
14
<?php __("Deactivate License", "translatepress-multilingual"); ?>
15
<?php __("Method of language detection", "translatepress-multilingual"); ?>
16
<?php __("Select how the language should be detected for first time visitors.<br>The visitor's last displayed language will be remembered through cookies.", "translatepress-multilingual"); ?>
17
- <?php __("All Languages", "translatepress-multilingual"); ?>
18
<?php __("Language", "translatepress-multilingual"); ?>
19
<?php __("Code", "translatepress-multilingual"); ?>
20
<?php __("Slug", "translatepress-multilingual"); ?>
@@ -32,13 +32,6 @@
32
<?php __("Flags with Full Language Names", "translatepress-multilingual"); ?>
33
<?php __("Flags with Short Language Names", "translatepress-multilingual"); ?>
34
<?php __("Only Flags", "translatepress-multilingual"); ?>
35
- <?php __("Done.", "translatepress-multilingual"); ?>
36
- <?php __("Back to TranslatePress Settings page", "translatepress-multilingual"); ?>
37
- <?php __("Invalid nonce.", "translatepress-multilingual"); ?>
38
- <?php __("Querying table <strong>%s</strong>", "translatepress-multilingual"); ?>
39
- <?php __("%s duplicates removed", "translatepress-multilingual"); ?>
40
- <?php __("If the page does not redirect automatically", "translatepress-multilingual"); ?>
41
- <?php __("click here", "translatepress-multilingual"); ?>
42
<?php __("Current Language", "translatepress-multilingual"); ?>
43
<?php __("General", "translatepress-multilingual"); ?>
44
<?php __("Translate Site", "translatepress-multilingual"); ?>
@@ -56,6 +49,7 @@
56
<?php __("Dynamic Added Strings", "translatepress-multilingual"); ?>
57
<?php __("Translate Page", "translatepress-multilingual"); ?>
58
<?php __("Security check", "translatepress-multilingual"); ?>
59
<?php __("Description", "translatepress-multilingual"); ?>
60
<?php __("OG Title", "translatepress-multilingual"); ?>
61
<?php __("OG Site Name", "translatepress-multilingual"); ?>
@@ -64,6 +58,18 @@
64
<?php __("Twitter Description", "translatepress-multilingual"); ?>
65
<?php __("Post Slug", "translatepress-multilingual"); ?>
66
<?php __("Page Title", "translatepress-multilingual"); ?>
67
<?php __("<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server.", "translatepress-multilingual"); ?>
68
<?php __("Select the language you wish to make your website available in.", "translatepress-multilingual"); ?>
69
<?php __("To add <strong>more then two languages</strong> and support for SEO Title, Description, Slug and more check out <a href=\"%s\" class=\"button button-primary\" target=\"_blank\" title=\"TranslatePress Pro\">TranslatePress PRO</a>", "translatepress-multilingual"); ?>
@@ -138,6 +144,9 @@
138
<?php __("Batch size", "translatepress-multilingual"); ?>
139
<?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"); ?>
140
<?php __("Remove duplicate rows", "translatepress-multilingual"); ?>
141
<?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
142
<?php __("Translator", "translatepress-multilingual"); ?>
143
<?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
1
<?php __("", "translatepress-multilingual"); ?>
2
<?php __("Error! Duplicate Url slug values.", "translatepress-multilingual"); ?>
3
<?php __("Limit this menu item to the following languages", "translatepress-multilingual"); ?>
4
+ <?php __("All Languages", "translatepress-multilingual"); ?>
5
<?php __("The Yoast SEO Sitemaps will now contain the default language slug: example.com/en/sitemap_index.xml <br/> This works perfectly, just take it into account when you submit the sitemap to Google.", "translatepress-multilingual"); ?>
6
<?php __("First by browser language, then IP address (recommended)", "translatepress-multilingual"); ?>
7
<?php __("First by IP address, then browser language", "translatepress-multilingual"); ?>
15
<?php __("Deactivate License", "translatepress-multilingual"); ?>
16
<?php __("Method of language detection", "translatepress-multilingual"); ?>
17
<?php __("Select how the language should be detected for first time visitors.<br>The visitor's last displayed language will be remembered through cookies.", "translatepress-multilingual"); ?>
18
<?php __("Language", "translatepress-multilingual"); ?>
19
<?php __("Code", "translatepress-multilingual"); ?>
20
<?php __("Slug", "translatepress-multilingual"); ?>
32
<?php __("Flags with Full Language Names", "translatepress-multilingual"); ?>
33
<?php __("Flags with Short Language Names", "translatepress-multilingual"); ?>
34
<?php __("Only Flags", "translatepress-multilingual"); ?>
35
<?php __("Current Language", "translatepress-multilingual"); ?>
36
<?php __("General", "translatepress-multilingual"); ?>
37
<?php __("Translate Site", "translatepress-multilingual"); ?>
49
<?php __("Dynamic Added Strings", "translatepress-multilingual"); ?>
50
<?php __("Translate Page", "translatepress-multilingual"); ?>
51
<?php __("Security check", "translatepress-multilingual"); ?>
52
+ <?php __("<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.", "translatepress-multilingual"); ?>
53
<?php __("Description", "translatepress-multilingual"); ?>
54
<?php __("OG Title", "translatepress-multilingual"); ?>
55
<?php __("OG Site Name", "translatepress-multilingual"); ?>
58
<?php __("Twitter Description", "translatepress-multilingual"); ?>
59
<?php __("Post Slug", "translatepress-multilingual"); ?>
60
<?php __("Page Title", "translatepress-multilingual"); ?>
61
+ <?php __("TranslatePress data update", "translatepress-multilingual"); ?>
62
+ <?php __("We need to update your translations database to the latest version.", "translatepress-multilingual"); ?>
63
+ <?php __("Run the updater", "translatepress-multilingual"); ?>
64
+ <?php __("<p><strong>Successfully updated database!</strong></p>", "translatepress-multilingual"); ?>
65
+ <?php __("Back to TranslatePress Settings page", "translatepress-multilingual"); ?>
66
+ <?php __("Invalid nonce.", "translatepress-multilingual"); ?>
67
+ <?php __("If the page does not redirect automatically", "translatepress-multilingual"); ?>
68
+ <?php __("click here", "translatepress-multilingual"); ?>
69
+ <?php __("Querying table <strong>%s</strong>... ", "translatepress-multilingual"); ?>
70
+ <?php __("Done.", "translatepress-multilingual"); ?>
71
+ <?php __("Querying table <strong>%s</strong>", "translatepress-multilingual"); ?>
72
+ <?php __("%s duplicates removed", "translatepress-multilingual"); ?>
73
<?php __("<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server.", "translatepress-multilingual"); ?>
74
<?php __("Select the language you wish to make your website available in.", "translatepress-multilingual"); ?>
75
<?php __("To add <strong>more then two languages</strong> and support for SEO Title, Description, Slug and more check out <a href=\"%s\" class=\"button button-primary\" target=\"_blank\" title=\"TranslatePress Pro\">TranslatePress PRO</a>", "translatepress-multilingual"); ?>
144
<?php __("Batch size", "translatepress-multilingual"); ?>
145
<?php __("The number of rows to check at once.<br>Choosing a smaller number helps solve the 502 error \"Page took too long to respond\" on large databases.<br>May take several minutes depending on the database size.", "translatepress-multilingual"); ?>
146
<?php __("Remove duplicate rows", "translatepress-multilingual"); ?>
147
+ <?php __("Update TranslatePress tables", "translatepress-multilingual"); ?>
148
+ <?php __("<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>", "translatepress-multilingual"); ?>
149
+ <?php __("Update database", "translatepress-multilingual"); ?>
150
<?php __(" TranslatePress Settings", "translatepress-multilingual"); ?>
151
<?php __("Translator", "translatepress-multilingual"); ?>
152
<?php __("Allow this user to translate the website.", "translatepress-multilingual"); ?>
languages/translatepress-multilingual.pot CHANGED
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2018 TranslatePress Multilingual
2
# This file is distributed under the same license as the TranslatePress Multilingual package.
3
msgid ""
4
msgstr ""
@@ -13,70 +13,70 @@ 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:416
17
msgid "Error! Duplicate Url slug values."
18
msgstr ""
19
20
- #: class-navigation-based-on-language.php:85
21
msgid "Limit this menu item to the following languages"
22
msgstr ""
23
24
#: ../tp-add-on-seo-pack/class-seo-pack.php:160
25
msgid "The Yoast SEO Sitemaps will now contain the default language slug: example.com/en/sitemap_index.xml <br/> This works perfectly, just take it into account when you submit the sitemap to Google."
26
msgstr ""
27
28
- #: ../tp-add-on-automatic-language-detection/includes/class-ald-settings.php:37
29
msgid "First by browser language, then IP address (recommended)"
30
msgstr ""
31
32
- #: ../tp-add-on-automatic-language-detection/includes/class-ald-settings.php:38
33
msgid "First by IP address, then browser language"
34
msgstr ""
35
36
- #: ../tp-add-on-automatic-language-detection/includes/class-ald-settings.php:39
37
msgid "Only by browser language"
38
msgstr ""
39
40
- #: ../tp-add-on-automatic-language-detection/includes/class-ald-settings.php:40
41
msgid "Only by IP address"
42
msgstr ""
43
44
- #: ../tp-add-on-automatic-language-detection/includes/class-ald-settings.php:110
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
- #: ../tp-add-on-automatic-language-detection/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, partials/license-settings-page.php:4, ../tp-add-on-seo-pack/partials/license-settings-page.php:4, ../translatepress/partials/addons-settings-page.php:3, ../translatepress/partials/main-settings-page.php:5, ../translatepress/partials/test-google-key-settings-page.php:10, ../translatepress/partials/trp-remove-duplicate-rows.php:3, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
49
msgid "TranslatePress Settings"
50
msgstr ""
51
52
- #: ../tp-add-on-automatic-language-detection/partials/license-settings-page.php:10, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:10, ../tp-add-on-extra-languages/partials/license-settings-page.php:10, partials/license-settings-page.php:10, ../tp-add-on-seo-pack/partials/license-settings-page.php:10, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:10
53
msgid "License Key"
54
msgstr ""
55
56
- #: ../tp-add-on-automatic-language-detection/partials/license-settings-page.php:15, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:15, ../tp-add-on-extra-languages/partials/license-settings-page.php:15, partials/license-settings-page.php:15, ../tp-add-on-seo-pack/partials/license-settings-page.php:15, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:15
57
msgid "Enter your license key."
58
msgstr ""
59
60
- #: ../tp-add-on-automatic-language-detection/partials/license-settings-page.php:22, ../tp-add-on-automatic-language-detection/partials/license-settings-page.php:31, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:22, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:31, ../tp-add-on-extra-languages/partials/license-settings-page.php:22, ../tp-add-on-extra-languages/partials/license-settings-page.php:31, partials/license-settings-page.php:22, partials/license-settings-page.php:31, ../tp-add-on-seo-pack/partials/license-settings-page.php:22, ../tp-add-on-seo-pack/partials/license-settings-page.php:31, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:22, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:31
61
msgid "Activate License"
62
msgstr ""
63
64
- #: ../tp-add-on-automatic-language-detection/partials/license-settings-page.php:28, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:28, ../tp-add-on-extra-languages/partials/license-settings-page.php:28, partials/license-settings-page.php:28, ../tp-add-on-seo-pack/partials/license-settings-page.php:28, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:28
65
msgid "Deactivate License"
66
msgstr ""
67
68
- #: ../tp-add-on-automatic-language-detection/partials/settings-option.php:2
69
msgid "Method of language detection"
70
msgstr ""
71
72
- #: ../tp-add-on-automatic-language-detection/partials/settings-option.php:14
73
msgid "Select how the language should be detected for first time visitors.<br>The visitor's last displayed language will be remembered through cookies."
74
msgstr ""
75
76
- #: ../tp-add-on-extra-languages/partials/language-selector-pro.php:2, ../translatepress/partials/main-settings-language-selector.php:2
77
- msgid "All Languages"
78
- msgstr ""
79
-
80
#: ../tp-add-on-extra-languages/partials/language-selector-pro.php:7, ../translatepress/partials/main-settings-language-selector.php:7
81
msgid "Language"
82
msgstr ""
@@ -145,59 +145,31 @@ msgstr ""
145
msgid "Only Flags"
146
msgstr ""
147
148
- #: ../translatepress/includes/class-settings.php:124
149
- msgid "Done."
150
- msgstr ""
151
-
152
- #: ../translatepress/includes/class-settings.php:124, ../translatepress/includes/class-settings.php:129
153
- msgid "Back to TranslatePress Settings page"
154
- msgstr ""
155
-
156
- #: ../translatepress/includes/class-settings.php:129
157
- msgid "Invalid nonce."
158
- msgstr ""
159
-
160
- #: ../translatepress/includes/class-settings.php:149
161
- msgid "Querying table <strong>%s</strong>"
162
- msgstr ""
163
-
164
- #: ../translatepress/includes/class-settings.php:179
165
- msgid "%s duplicates removed"
166
- msgstr ""
167
-
168
- #: ../translatepress/includes/class-settings.php:209
169
- msgid "If the page does not redirect automatically"
170
- msgstr ""
171
-
172
- #: ../translatepress/includes/class-settings.php:209
173
- msgid "click here"
174
- msgstr ""
175
-
176
- #: ../translatepress/includes/class-settings.php:452
177
msgid "Current Language"
178
msgstr ""
179
180
- #: ../translatepress/includes/class-settings.php:493
181
msgid "General"
182
msgstr ""
183
184
- #: ../translatepress/includes/class-settings.php:498, ../translatepress/includes/class-translation-manager.php:617
185
msgid "Translate Site"
186
msgstr ""
187
188
- #: ../translatepress/includes/class-settings.php:506
189
msgid "License"
190
msgstr ""
191
192
- #: ../translatepress/includes/class-settings.php:512
193
msgid "Addons"
194
msgstr ""
195
196
- #: ../translatepress/includes/class-settings.php:537, ../translatepress/includes/class-translation-manager.php:648
197
msgid "Settings"
198
msgstr ""
199
200
- #: ../translatepress/includes/class-settings.php:541
201
msgid "Pro Features"
202
msgstr ""
203
@@ -237,43 +209,95 @@ msgstr ""
237
msgid "Translate Page"
238
msgstr ""
239
240
- #: ../translatepress/includes/class-translation-manager.php:1197
241
msgid "Security check"
242
msgstr ""
243
244
- #: ../translatepress/includes/class-translation-render.php:166
245
msgid "Description"
246
msgstr ""
247
248
- #: ../translatepress/includes/class-translation-render.php:172
249
msgid "OG Title"
250
msgstr ""
251
252
- #: ../translatepress/includes/class-translation-render.php:178
253
msgid "OG Site Name"
254
msgstr ""
255
256
- #: ../translatepress/includes/class-translation-render.php:184
257
msgid "OG Description"
258
msgstr ""
259
260
- #: ../translatepress/includes/class-translation-render.php:190
261
msgid "Twitter Title"
262
msgstr ""
263
264
- #: ../translatepress/includes/class-translation-render.php:196
265
msgid "Twitter Description"
266
msgstr ""
267
268
- #: ../translatepress/includes/class-translation-render.php:202
269
msgid "Post Slug"
270
msgstr ""
271
272
- #: ../translatepress/includes/class-translation-render.php:206
273
msgid "Page Title"
274
msgstr ""
275
276
- #: ../translatepress/includes/functions.php:216
277
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."
278
msgstr ""
279
@@ -553,7 +577,7 @@ msgstr ""
553
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."
554
msgstr ""
555
556
- #: ../translatepress/partials/trp-remove-duplicate-rows.php:12
557
msgid ""
558
"IMPORTANT: It is strongly recommended to backup the database first!\n"
559
"Are you sure you want to continue?"
@@ -571,6 +595,18 @@ msgstr ""
571
msgid "Remove duplicate rows"
572
msgstr ""
573
574
#: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
575
msgid " TranslatePress Settings"
576
msgstr ""
1
+ # Copyright (C) 2019 TranslatePress Multilingual
2
# This file is distributed under the same license as the TranslatePress Multilingual package.
3
msgid ""
4
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:307
17
msgid "Error! Duplicate Url slug values."
18
msgstr ""
19
20
+ #: ../tp-add-on-navigation-based-on-language/class-navigation-based-on-language.php:86
21
msgid "Limit this menu item to the following languages"
22
msgstr ""
23
24
+ #: ../tp-add-on-navigation-based-on-language/class-navigation-based-on-language.php:92, ../tp-add-on-extra-languages/partials/language-selector-pro.php:2, ../translatepress/partials/main-settings-language-selector.php:2
25
+ msgid "All Languages"
26
+ msgstr ""
27
+
28
#: ../tp-add-on-seo-pack/class-seo-pack.php:160
29
msgid "The Yoast SEO Sitemaps will now contain the default language slug: example.com/en/sitemap_index.xml <br/> This works perfectly, just take it into account when you submit the sitemap to Google."
30
msgstr ""
31
32
+ #: includes/class-ald-settings.php:37
33
msgid "First by browser language, then IP address (recommended)"
34
msgstr ""
35
36
+ #: includes/class-ald-settings.php:38
37
msgid "First by IP address, then browser language"
38
msgstr ""
39
40
+ #: includes/class-ald-settings.php:39
41
msgid "Only by browser language"
42
msgstr ""
43
44
+ #: includes/class-ald-settings.php:40
45
msgid "Only by IP address"
46
msgstr ""
47
48
+ #: includes/class-ald-settings.php:110
49
msgid "<div class=\"warning\">WARNING. Cannot determine your language preference based on your current IP.<br>This is most likely because the website is on a local environment.</div>"
50
msgstr ""
51
52
+ #: partials/license-settings-page.php:4, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:4, ../tp-add-on-extra-languages/partials/license-settings-page.php:4, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:4, ../tp-add-on-seo-pack/partials/license-settings-page.php:4, ../translatepress/partials/addons-settings-page.php:3, ../translatepress/partials/main-settings-page.php:5, ../translatepress/partials/test-google-key-settings-page.php:10, ../translatepress/partials/trp-remove-duplicate-rows.php:3, ../translatepress/partials/trp-update-database.php:3, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:4
53
msgid "TranslatePress Settings"
54
msgstr ""
55
56
+ #: partials/license-settings-page.php:10, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:10, ../tp-add-on-extra-languages/partials/license-settings-page.php:10, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:10, ../tp-add-on-seo-pack/partials/license-settings-page.php:10, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:10
57
msgid "License Key"
58
msgstr ""
59
60
+ #: partials/license-settings-page.php:15, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:15, ../tp-add-on-extra-languages/partials/license-settings-page.php:15, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:15, ../tp-add-on-seo-pack/partials/license-settings-page.php:15, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:15
61
msgid "Enter your license key."
62
msgstr ""
63
64
+ #: partials/license-settings-page.php:22, partials/license-settings-page.php:31, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:22, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:31, ../tp-add-on-extra-languages/partials/license-settings-page.php:22, ../tp-add-on-extra-languages/partials/license-settings-page.php:31, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:22, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:31, ../tp-add-on-seo-pack/partials/license-settings-page.php:22, ../tp-add-on-seo-pack/partials/license-settings-page.php:31, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:22, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:31
65
msgid "Activate License"
66
msgstr ""
67
68
+ #: partials/license-settings-page.php:28, ../tp-add-on-browse-as-other-roles/partials/license-settings-page.php:28, ../tp-add-on-extra-languages/partials/license-settings-page.php:28, ../tp-add-on-navigation-based-on-language/partials/license-settings-page.php:28, ../tp-add-on-seo-pack/partials/license-settings-page.php:28, ../trp-add-on-translator-accounts-add-on/partials/license-settings-page.php:28
69
msgid "Deactivate License"
70
msgstr ""
71
72
+ #: partials/settings-option.php:2
73
msgid "Method of language detection"
74
msgstr ""
75
76
+ #: partials/settings-option.php:14
77
msgid "Select how the language should be detected for first time visitors.<br>The visitor's last displayed language will be remembered through cookies."
78
msgstr ""
79
80
#: ../tp-add-on-extra-languages/partials/language-selector-pro.php:7, ../translatepress/partials/main-settings-language-selector.php:7
81
msgid "Language"
82
msgstr ""
145
msgid "Only Flags"
146
msgstr ""
147
148
+ #: ../translatepress/includes/class-settings.php:343
149
msgid "Current Language"
150
msgstr ""
151
152
+ #: ../translatepress/includes/class-settings.php:384
153
msgid "General"
154
msgstr ""
155
156
+ #: ../translatepress/includes/class-settings.php:389, ../translatepress/includes/class-translation-manager.php:617
157
msgid "Translate Site"
158
msgstr ""
159
160
+ #: ../translatepress/includes/class-settings.php:397
161
msgid "License"
162
msgstr ""
163
164
+ #: ../translatepress/includes/class-settings.php:403
165
msgid "Addons"
166
msgstr ""
167
168
+ #: ../translatepress/includes/class-settings.php:428, ../translatepress/includes/class-translation-manager.php:648
169
msgid "Settings"
170
msgstr ""
171
172
+ #: ../translatepress/includes/class-settings.php:432
173
msgid "Pro Features"
174
msgstr ""
175
209
msgid "Translate Page"
210
msgstr ""
211
212
+ #: ../translatepress/includes/class-translation-manager.php:1198
213
msgid "Security check"
214
msgstr ""
215
216
+ #: ../translatepress/includes/class-translation-manager.php:1272
217
+ msgid "<strong>Warning:</strong> Some strings have possibly incorrectly encoded characters. This may result in breaking the queries, rendering the page untranslated in live mode. Consider revising the following strings or their method of outputting."
218
+ msgstr ""
219
+
220
+ #: ../translatepress/includes/class-translation-render.php:143
221
msgid "Description"
222
msgstr ""
223
224
+ #: ../translatepress/includes/class-translation-render.php:149
225
msgid "OG Title"
226
msgstr ""
227
228
+ #: ../translatepress/includes/class-translation-render.php:155
229
msgid "OG Site Name"
230
msgstr ""
231
232
+ #: ../translatepress/includes/class-translation-render.php:161
233
msgid "OG Description"
234
msgstr ""
235
236
+ #: ../translatepress/includes/class-translation-render.php:167
237
msgid "Twitter Title"
238
msgstr ""
239
240
+ #: ../translatepress/includes/class-translation-render.php:173
241
msgid "Twitter Description"
242
msgstr ""
243
244
+ #: ../translatepress/includes/class-translation-render.php:179
245
msgid "Post Slug"
246
msgstr ""
247
248
+ #: ../translatepress/includes/class-translation-render.php:183
249
msgid "Page Title"
250
msgstr ""
251
252
+ #: ../translatepress/includes/class-upgrade.php:95
253
+ msgid "TranslatePress data update"
254
+ msgstr ""
255
+
256
+ #: ../translatepress/includes/class-upgrade.php:95
257
+ msgid "We need to update your translations database to the latest version."
258
+ msgstr ""
259
+
260
+ #: ../translatepress/includes/class-upgrade.php:96
261
+ msgid "Run the updater"
262
+ msgstr ""
263
+
264
+ #: ../translatepress/includes/class-upgrade.php:125
265
+ msgid "<p><strong>Successfully updated database!</strong></p>"
266
+ msgstr ""
267
+
268
+ #: ../translatepress/includes/class-upgrade.php:125, ../translatepress/includes/class-upgrade.php:130, ../translatepress/includes/class-upgrade.php:290, ../translatepress/includes/class-upgrade.php:295
269
+ msgid "Back to TranslatePress Settings page"
270
+ msgstr ""
271
+
272
+ #: ../translatepress/includes/class-upgrade.php:130, ../translatepress/includes/class-upgrade.php:295
273
+ msgid "Invalid nonce."
274
+ msgstr ""
275
+
276
+ #: ../translatepress/includes/class-upgrade.php:206, ../translatepress/includes/class-upgrade.php:375
277
+ msgid "If the page does not redirect automatically"
278
+ msgstr ""
279
+
280
+ #: ../translatepress/includes/class-upgrade.php:206, ../translatepress/includes/class-upgrade.php:375
281
+ msgid "click here"
282
+ msgstr ""
283
+
284
+ #: ../translatepress/includes/class-upgrade.php:228
285
+ msgid "Querying table <strong>%s</strong>... "
286
+ msgstr ""
287
+
288
+ #: ../translatepress/includes/class-upgrade.php:230, ../translatepress/includes/class-upgrade.php:290
289
+ msgid "Done."
290
+ msgstr ""
291
+
292
+ #: ../translatepress/includes/class-upgrade.php:315
293
+ msgid "Querying table <strong>%s</strong>"
294
+ msgstr ""
295
+
296
+ #: ../translatepress/includes/class-upgrade.php:345
297
+ msgid "%s duplicates removed"
298
+ msgstr ""
299
+
300
+ #: ../translatepress/includes/functions.php:253
301
msgid "<strong>TranslatePress</strong> requires <strong><a href=\"http://php.net/manual/en/book.mbstring.php\">Multibyte String PHP library</a></strong>. Please contact your server administrator to install it on your server."
302
msgstr ""
303
577
msgid "<strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong><br><br>This feature can be used to cleanup duplicate entries in TranslatePress trp_dictionary tables. Such duplicates can appear in exceptional situations of unexpected behavior."
578
msgstr ""
579
580
+ #: ../translatepress/partials/trp-remove-duplicate-rows.php:12, ../translatepress/partials/trp-update-database.php:12
581
msgid ""
582
"IMPORTANT: It is strongly recommended to backup the database first!\n"
583
"Are you sure you want to continue?"
595
msgid "Remove duplicate rows"
596
msgstr ""
597
598
+ #: ../translatepress/partials/trp-update-database.php:7
599
+ msgid "Update TranslatePress tables"
600
+ msgstr ""
601
+
602
+ #: ../translatepress/partials/trp-update-database.php:10
603
+ msgid "<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>"
604
+ msgstr ""
605
+
606
+ #: ../translatepress/partials/trp-update-database.php:18
607
+ msgid "Update database"
608
+ msgstr ""
609
+
610
#: ../trp-add-on-translator-accounts-add-on/includes/class-translator-accounts.php:119
611
msgid " TranslatePress Settings"
612
msgstr ""
partials/trp-update-database.php ADDED
@@ -0,0 +1,25 @@
1
+ <div id="trp-addons-page" class="wrap">
2
+
3
+ <h1> <?php _e( 'TranslatePress Settings', 'translatepress-multilingual' );?></h1>
4
+
5
+ <div class="grid feat-header">
6
+ <div class="grid-cell">
7
+ <h2><?php _e('Update TranslatePress tables', 'translatepress-multilingual' );?> </h2>
8
+ <?php if ( empty( $_GET['trp_updb_lang'] ) ){ ?>
9
+ <div>
10
+ <?php _e( '<p><strong>IMPORTANT NOTE: Before performing this action it is strongly recommended to backup the database first.</strong></p>', 'translatepress-multilingual' )?>
11
+ </div>
12
+ <form onsubmit="return confirm('<?php _e( 'IMPORTANT: It is strongly recommended to backup the database first!\nAre you sure you want to continue?', 'translatepress-multilingual' ) ?>');">
13
+ <input type="hidden" name="trp_updb_nonce" value="<?php echo wp_create_nonce('tpupdatedatabase')?>">
14
+ <input type="hidden" name="page" value="trp_update_database">
15
+ <input type="hidden" name="trp_updb_batch" value="0">
16
+ <input type="hidden" name="trp_updb_batch_size" value="200">
17
+ <input type="hidden" name="trp_updb_lang" value="<?php echo $this->settings['translation-languages'][0]?>">
18
+ <input type="submit" class="button-primary" value="<?php _e( 'Update database', 'translatepress-multilingual' ); ?>">
19
+ </form>
20
+ <?php } ?>
21
+
22
+ </div>
23
+ </div>
24
+
25
+ </div>
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: cozmoslabs, razvan.mo, madalin.ungureanu, cristophor
3
Donate link: https://www.cozmoslabs.com/
4
Tags: translate, translation, multilingual, automatic translation, bilingual, front-end translation, google translate, language
5
Requires at least: 3.1.0
6
- Tested up to: 5.0.1
7
- Stable tag: 1.3.9
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
@@ -124,6 +124,16 @@ For more information please check out [TranslatePress - Multilingual plugin docu
124
6. Menu Language Switcher
125
126
== Changelog ==
127
= 1.3.9 =
128
* Fixed some issues with url translations
129
* Speed improvements
3
Donate link: https://www.cozmoslabs.com/
4
Tags: translate, translation, multilingual, automatic translation, bilingual, front-end translation, google translate, language
5
Requires at least: 3.1.0
6
+ Tested up to: 5.0.3
7
+ Stable tag: 1.4.0
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
124
6. Menu Language Switcher
125
126
== Changelog ==
127
+ = 1.4.0 =
128
+ * Added Enfold compatibility by increasing the template_include hook priority
129
+ * Add the costa rica flag
130
+ * Speed improvements by optimizing the full_trim function
131
+ * Added compatibility for WooCommerce Invoices plugins
132
+ * Fixed querying for dynamic strings in Translation Editor not bringing up translations for all languages
133
+ * Fixed notice when gettext table is empty
134
+ * Added function to display strings with bad encoding in Translation Editor
135
+
136
+
137
= 1.3.9 =
138
* Fixed some issues with url translations
139
* Speed improvements