From 1b27ed042598ba6739763ed93d4093bd58c66648 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Fri, 9 Aug 2024 13:03:58 +0200
Subject: [PATCH 1/8] Delete a suggestion from TM
---
.../templates/style.css | 4 +
.../inc/class-plugin.php | 6 +-
.../inc/class-translation-memory-client.php | 75 +++---
.../inc/routes/class-translation-memory.php | 86 ++++++-
.../js/translation-suggestions.js | 228 +++++++++++-------
.../translation-memory-suggestions.php | 3 +
6 files changed, 287 insertions(+), 115 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
index c52e9b96ea..2c6951ffca 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
@@ -3223,6 +3223,10 @@ ul.sidebar-tabs {
margin-left: auto;
}
+button.is-small.delete-suggestion {
+ margin-right: 0.5rem;
+}
+
.meta.other-locales span.locale.unique {
margin-right: 14px;
}
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-plugin.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-plugin.php
index dfc9d49b77..fe65136412 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-plugin.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-plugin.php
@@ -102,6 +102,7 @@ public function register_routes() {
GP::$router->prepend( "/$set/-get-other-language-suggestions", array( __NAMESPACE__ . '\Routes\Other_Languages', 'get_suggestions' ) );
GP::$router->prepend( "/$set/-get-tm-openai-suggestions", array( __NAMESPACE__ . '\Routes\Translation_Memory', 'get_openai_suggestions' ) );
GP::$router->prepend( "/$set/-get-tm-deepl-suggestions", array( __NAMESPACE__ . '\Routes\Translation_Memory', 'get_deepl_suggestions' ) );
+ GP::$router->prepend( "/$set/-delete-tm-suggestion", array( __NAMESPACE__ . '\Routes\Translation_Memory', 'delete_suggestion' ), 'post' );
}
/**
@@ -148,11 +149,12 @@ public function pre_tmpl_load( $template, $args ) {
wp_add_inline_script(
'gp-translation-suggestions',
sprintf(
- "window.WPORG_TRANSLATION_MEMORY_API_URL = %s;\nwindow.WPORG_TRANSLATION_MEMORY_OPENAI_API_URL = %s;\nwindow.WPORG_TRANSLATION_MEMORY_DEEPL_API_URL = %s;\nwindow.WPORG_OTHER_LANGUAGES_API_URL = %s;",
+ "window.WPORG_TRANSLATION_MEMORY_API_URL = %s;\nwindow.WPORG_TRANSLATION_MEMORY_OPENAI_API_URL = %s;\nwindow.WPORG_TRANSLATION_MEMORY_DEEPL_API_URL = %s;\nwindow.WPORG_OTHER_LANGUAGES_API_URL = %s;\nwindow.WPORG_TRANSLATION_MEMORY_API_DELETE_URL = %s;",
wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-get-tm-suggestions' ) ) ),
wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-get-tm-openai-suggestions' ) ) ),
wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-get-tm-deepl-suggestions' ) ) ),
- wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-get-other-language-suggestions' ) ) )
+ wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-get-other-language-suggestions' ) ) ),
+ wp_json_encode( gp_url_project( $args['project'], gp_url_join( $args['locale_slug'], $args['translation_set_slug'], '-delete-tm-suggestion' ) ) )
)
);
}
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
index 3f0724df0c..365489944d 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
@@ -12,7 +12,7 @@
class Translation_Memory_Client {
- const API_ENDPOINT = 'https://translate.wordpress.com/api/tm/';
+ const API_ENDPOINT = 'https://translate.wordpress.com/api/tm/';
const API_BULK_ENDPOINT = 'https://translate.wordpress.com/api/tm/-bulk';
/**
@@ -22,7 +22,7 @@ class Translation_Memory_Client {
* @return true|\WP_Error True on success, WP_Error on failure.
*/
public static function update( array $translations ) {
- $requests = [];
+ $requests = array();
foreach ( $translations as $original_id => $translation_id ) {
$translation = GP::$translation->get( $translation_id );
@@ -40,34 +40,36 @@ public static function update( array $translations ) {
$locale .= '_' . $translation_set->slug;
}
- $requests[] = [
+ $requests[] = array(
'source' => $original->fields(),
- 'translations' => [
- [
+ 'translations' => array(
+ array(
'singular' => $translation->translation_0,
'plural' => $translation->translation_1,
'locale' => $locale,
- ],
- ],
- ];
+ ),
+ ),
+ );
}
if ( ! $requests ) {
return new WP_Error( 'no_translations' );
}
- $body = wp_json_encode( [
- 'token' => WPCOM_TM_TOKEN,
- 'requests' => $requests,
- ] );
+ $body = wp_json_encode(
+ array(
+ 'token' => WPCOM_TM_TOKEN,
+ 'requests' => $requests,
+ )
+ );
$request = wp_remote_post(
self::API_BULK_ENDPOINT,
- [
+ array(
'timeout' => 10,
'user-agent' => 'WordPress.org Translate',
'body' => $body,
- ]
+ )
);
if ( is_wp_error( $request ) ) {
@@ -100,20 +102,24 @@ public static function query( string $text, string $target_locale ) {
return new WP_Error( 'no_token' );
}
- $url = add_query_arg( urlencode_deep( [
- 'text' => $text,
- 'target' => $target_locale,
- 'token' => WPCOM_TM_TOKEN,
- 'ts' => time(),
- ] ), self::API_ENDPOINT );
-
+ $url = add_query_arg(
+ urlencode_deep(
+ array(
+ 'text' => $text,
+ 'target' => $target_locale,
+ 'token' => WPCOM_TM_TOKEN,
+ 'ts' => time(),
+ )
+ ),
+ self::API_ENDPOINT
+ );
$request = wp_remote_get(
$url,
- [
+ array(
'timeout' => 4,
'user-agent' => 'WordPress.org Translate',
- ]
+ )
);
if ( is_wp_error( $request ) ) {
@@ -132,22 +138,35 @@ public static function query( string $text, string $target_locale ) {
}
if ( empty( $result['matches'] ) ) {
- return [];
+ return array();
}
- $suggestions = [];
+ $suggestions = array();
foreach ( $result['matches'] as $match ) {
- $suggestions[] = [
+ $suggestions[] = array(
'similarity_score' => $match['score'],
'source' => $match['source'],
'translation' => $match['text'],
'diff' => ( 1 === $match['score'] ) ? null : self::diff( $text, $match['source'] ),
- ];
+ );
}
return $suggestions;
}
+ /**
+ * Deletes a translation from translation memory.
+ *
+ * @param string $original_string Original string.
+ * @param string $translation_string Translation string.
+ * @param string $locale_slug Locale slug.
+ * @param string $set_slug Translation set slug.
+ */
+ public static function delete( string $original_string, string $translation_string, string $locale_slug, string $set_slug ):bool {
+ // @todo Implement.
+ return true;
+ }
+
/**
* Generates the differences between two sequences of strings.
*
@@ -156,7 +175,7 @@ public static function query( string $text, string $target_locale ) {
* @return string HTML markup for the differences between the two texts.
*/
protected static function diff( $previous_text, $text ) {
- $diff = new Text_Diff( 'auto', [ [ $text ], [ $previous_text ] ] );
+ $diff = new Text_Diff( 'auto', array( array( $text ), array( $previous_text ) ) );
$renderer = new WP_Text_Diff_Renderer_inline();
return $renderer->render( $diff );
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
index eca2166c63..55b773a14d 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
@@ -48,10 +48,13 @@ public function get_suggestions( $project_path, $locale_slug, $set_slug ) {
wp_send_json_error( $suggestions->get_error_code() );
}
+ $project = GP::$project->by_path( $project_path );
+ $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $set_slug, $locale_slug );
+ $is_user_a_gte_for_locale = $this->is_user_a_gte_for_locale( wp_get_current_user(), $locale );
wp_send_json_success(
gp_tmpl_get_output(
'translation-memory-suggestions',
- compact( 'suggestions', 'type' ),
+ compact( 'suggestions', 'type', 'is_user_a_gte_for_locale' ),
PLUGIN_DIR . '/templates/'
)
);
@@ -170,6 +173,41 @@ public function get_deepl_suggestions( $project_path, $locale_slug, $set_slug )
);
}
+ /**
+ * Delete a suggestion from the translation memory.
+ *
+ * @param string $project_path Project path.
+ * @param string $locale_slug Locale slug.
+ * @param string $set_slug Set slug.
+ *
+ * @return void
+ */
+ public function delete_suggestion( string $project_path, string $locale_slug, string $set_slug ): bool {
+ $original_id = gp_post( 'originalId' );
+ $original_string = gp_post( 'originalString' );
+ $translation_string = gp_post( 'translationString' );
+ $nonce = gp_post( 'nonce' );
+
+ if ( ! wp_verify_nonce( $nonce, 'translation-memory-suggestions-' . $original_id ) ) {
+ wp_send_json_error( 'invalid_nonce' );
+ }
+
+ if ( empty( $original_string ) || empty( $translation_string ) ) {
+ wp_send_json_error( 'missing_data' );
+ }
+
+ if ( ! $this->is_user_a_gte_for_locale( wp_get_current_user(), $locale_slug ) ) {
+ wp_send_json_error( 'user_cannot_delete' );
+ }
+
+ $result = Translation_Memory_Client::delete( $original_string, $translation_string, $locale_slug, $set_slug );
+ if ( ! $result ) {
+ wp_send_json_error( 'delete_failed' );
+ }
+
+ wp_send_json_success();
+ }
+
/**
* Get suggestions from OpenAI (ChatGPT).
*
@@ -533,5 +571,51 @@ private static function update_one_external_translation( string $translation, st
}
update_user_option( get_current_user_id(), 'gp_external_translations', $gp_external_translations );
}
+
+ /**
+ * Determine if the user is a GTE for the given locale.
+ *
+ * @param null|WP_User $user User.
+ * @param string $set Locale set.
+ *
+ * @return bool
+ */
+ private function is_user_a_gte_for_locale( $user, $locale ) {
+ $locale_slug = explode( '_', $locale )[0];
+ $locale = GP_Locales::by_slug( $locale_slug );
+ if ( ! $locale ) {
+ return false;
+ }
+
+ $result = get_sites(
+ array(
+ 'locale' => $locale->wp_locale,
+ 'network_id' => WPORG_GLOBAL_NETWORK_ID,
+ 'path' => '/',
+ 'fields' => 'ids',
+ 'number' => '1',
+ )
+ );
+ $site_id = array_shift( $result );
+ if ( ! $site_id ) {
+ return false;
+ }
+
+ $users = get_users(
+ array(
+ 'blog_id' => $site_id,
+ 'role' => 'general_translation_editor',
+ 'count_total' => false,
+ )
+ );
+
+ foreach ( $users as $gte_user ) {
+ if ( $gte_user->id === $user->id ) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index 1a6bcfc1ad..a2a0788186 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -26,6 +26,7 @@
/**
* Stores the external translations used.
+ *
* @type {object}
*/
var externalSuggestion = {};
@@ -67,39 +68,47 @@
}
// Store a string with a space to avoid making the same request another time.
storeTheSuggestionInTheCache( type, originalId, ' ' );
- var xhr = $.ajax( {
- url: apiUrl,
- data: {
- 'original': originalId,
- 'translation': translationId,
- 'nonce': nonce
- },
- dataType: 'json',
- cache: false,
- } );
-
- xhr.done( function( response ) {
- $container.find( '.suggestions__loading-indicator' ).remove();
- if ( response.success ) {
- $container.append( response.data );
- storeTheSuggestionInTheCache( type, originalId, response.data );
- removeNoSuggestionsMessage( $container );
- copyTranslationMemoryToSidebarTab( $container );
- } else {
- $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
+ var xhr = $.ajax(
+ {
+ url: apiUrl,
+ data: {
+ 'original': originalId,
+ 'translation': translationId,
+ 'nonce': nonce
+ },
+ dataType: 'json',
+ cache: false,
+ }
+ );
+
+ xhr.done(
+ function( response ) {
+ $container.find( '.suggestions__loading-indicator' ).remove();
+ if ( response.success ) {
+ $container.append( response.data );
+ storeTheSuggestionInTheCache( type, originalId, response.data );
+ removeNoSuggestionsMessage( $container );
+ copyTranslationMemoryToSidebarTab( $container );
+ } else {
+ $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
+ }
+ $container.addClass( 'initialized' );
}
- $container.addClass( 'initialized' );
- } );
+ );
- xhr.fail( function() {
- $container.find( '.suggestions__loading-indicator' ).remove();
- $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
- $container.addClass( 'initialized' );
- } );
+ xhr.fail(
+ function() {
+ $container.find( '.suggestions__loading-indicator' ).remove();
+ $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
+ $container.addClass( 'initialized' );
+ }
+ );
- xhr.always( function() {
- $container.removeClass( 'fetching' );
- } );
+ xhr.always(
+ function() {
+ $container.removeClass( 'fetching' );
+ }
+ );
}
/**
@@ -109,12 +118,12 @@
*/
function getSuggestionsForTheFirstRow() {
var firstEditor = $( '#translations' ).find( '.editor' ).first();
- var row_id = firstEditor.closest( 'tr' ).attr( 'row' );
+ var row_id = firstEditor.closest( 'tr' ).attr( 'row' );
if ( ! row_id ) {
return;
}
- firstEditor.row_id = row_id;
- firstEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
+ firstEditor.row_id = row_id;
+ firstEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
firstEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
maybeFetchTranslationMemorySuggestions( firstEditor );
maybeFetchOpenAISuggestions( firstEditor );
@@ -188,14 +197,14 @@
add_amount_to_others_tab = function ( sidebarTab, data, originalId ) {
let elements = 0;
- if ( data?.['helper-history-' + originalId] ) {
+ if ( data ? .['helper-history-' + originalId] ) {
elements += data['helper-history-' + originalId].count;
}
- if ( data?.['helper-other-locales-' + originalId] ) {
+ if ( data ? .['helper-other-locales-' + originalId] ) {
elements += data['helper-other-locales-' + originalId].count;
}
- var editor = $('[data-tab="' + sidebarTab + '"]').closest( '.editor' );
- var TMcontainer = editor.find( '.suggestions__translation-memory' );
+ var editor = $( '[data-tab="' + sidebarTab + '"]' ).closest( '.editor' );
+ var TMcontainer = editor.find( '.suggestions__translation-memory' );
var elementsInTM = 0;
if ( TMcontainer.length ) {
elementsInTM += TMcontainer.find( '.translation-suggestion.with-tooltip.translation' ).length;
@@ -203,10 +212,10 @@
elementsInTM += TMcontainer.find( '.translation-suggestion.with-tooltip.openai' ).length;
}
elements += elementsInTM;
- $( '#summary-translation-memory-' + originalId ).html('Translation Memory (' + elementsInTM + ')');
+ $( '#summary-translation-memory-' + originalId ).html( 'Translation Memory (' + elementsInTM + ')' );
let content = 'Others (' + elements + ')';
- $('[data-tab="' + sidebarTab + '"]').html( content );
+ $( '[data-tab="' + sidebarTab + '"]' ).html( content );
}
/**
@@ -217,16 +226,16 @@
* @return {void}
*/
function copyTranslationMemoryToSidebarTab( $container ){
- var editor = $container.closest( '.editor' );
- var divSidebarWithDiscussion = editor.find( '.meta.discussion' ).first();
- var divId = divSidebarWithDiscussion.attr( 'data-row-id' );
- var TMcontainer = editor.find( '.suggestions__translation-memory' );
- if ( !TMcontainer.length ) {
+ var editor = $container.closest( '.editor' );
+ var divSidebarWithDiscussion = editor.find( '.meta.discussion' ).first();
+ var divId = divSidebarWithDiscussion.attr( 'data-row-id' );
+ var TMcontainer = editor.find( '.suggestions__translation-memory' );
+ if ( ! TMcontainer.length ) {
return;
}
$( '#sidebar-div-others-translation-memory-content-' + divId ).html( TMcontainer.html() );
- add_amount_to_others_tab('sidebar-tab-others-' + divId, window.translationHelpersCache?.[ divId ], divId);
+ add_amount_to_others_tab( 'sidebar-tab-others-' + divId, window.translationHelpersCache ? .[ divId ], divId );
}
/**
@@ -267,7 +276,7 @@
*/
function maybeFetchTranslationMemorySuggestions( editor ) {
var $container = editor.find( '.suggestions__translation-memory' );
- if ( !$container.length ) {
+ if ( ! $container.length ) {
return;
}
@@ -275,15 +284,15 @@
return;
}
- if ( !editor.find('translation-suggestion.with-tooltip.translation').first() ) {
+ if ( ! editor.find( 'translation-suggestion.with-tooltip.translation' ).first() ) {
return;
}
$container.addClass( 'fetching' );
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, window.WPORG_TRANSLATION_MEMORY_API_URL, originalId, translationId, nonce, 'TM' );
}
@@ -322,15 +331,15 @@
*/
function maybeFetchExternalSuggestions( editor, type, getExternalSuggestions, apiUrl ) {
var $container = editor.find( '.suggestions__translation-memory' );
- if ( !$container.length ) {
+ if ( ! $container.length ) {
return;
}
if ( true !== getExternalSuggestions ) {
return;
}
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, apiUrl, originalId, translationId, nonce, type );
}
@@ -354,9 +363,9 @@
$container.addClass( 'fetching' );
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, window.WPORG_OTHER_LANGUAGES_API_URL, originalId , translationId, nonce, 'OL' );
}
@@ -387,27 +396,73 @@
* @return {void}
*/
function removeNoSuggestionsDuplicateMessage( $container ) {
- var $html = $($container);
- var $paragraphs = $html.find('p');
+ var $html = $( $container );
+ var $paragraphs = $html.find( 'p' );
var uniqueParagraphs = [];
- $paragraphs.each(function() {
- var paragraphText = $(this).text().trim();
+ $paragraphs.each(
+ function() {
+ var paragraphText = $( this ).text().trim();
- if (uniqueParagraphs.indexOf(paragraphText) === -1) {
- uniqueParagraphs.push(paragraphText);
- } else {
- $(this).remove();
+ if (uniqueParagraphs.indexOf( paragraphText ) === -1) {
+ uniqueParagraphs.push( paragraphText );
+ } else {
+ $( this ).remove();
+ }
}
- });
+ );
}
+
+ /**
+ * Removes a suggestion from the TM.
+ *
+ * @param {object} event
+ *
+ * @return {void}
+ */
+ function deleteSuggestionFromTM( event ) {
+ event.preventDefault();
+ event.stopImmediatePropagation();
+ var editor = $gp.editor.current;
+ var container = editor.find( '.suggestions__translation-memory' );
+ if ( ! container.length ) {
+ return;
+ }
+ var row = $( this ).closest( '.translation-suggestion' );
+ var deleteButton = row.find( '.delete-suggestion' );
+ var originalString = editor.find( '.original-raw' ).text();
+ var translationString = row.find( '.translation-suggestion__translation' ).text();
+ var originalId = editor.original_id;
+ var nonce = container.data( 'nonce' );
+ deleteButton.prop( 'disabled', true );
+ $.ajax(
+ {
+ type: 'POST',
+ url: window.WPORG_TRANSLATION_MEMORY_API_DELETE_URL,
+ data: {
+ 'originalId' : originalId,
+ 'originalString': originalString,
+ 'translationString': translationString,
+ 'nonce': nonce
+ },
+ dataType: 'json',
+ cache: false,
+ success: function(result) {
+ if ( true === result.success ) {
+ row.remove();
+ }
+ }
+ }
+ );
+ }
+
function copySuggestion( event ) {
if ( 'A' === event.target.tagName ) {
return;
}
- var $el = $( this ).closest( '.translation-suggestion' );
- var $translation = $el.find( '.translation-suggestion__translation-raw');
+ var $el = $( this ).closest( '.translation-suggestion' );
+ var $translation = $el.find( '.translation-suggestion__translation-raw' );
if ( ! $translation.length ) {
return;
}
@@ -460,11 +515,11 @@
maybeFetchOpenAISuggestions( $gp.editor.current );
maybeFetchDeeplSuggestions( $gp.editor.current );
maybeFetchOtherLanguageSuggestions( $gp.editor.current );
- var nextEditor = $gp.editor.current.nextAll('tr.editor' ).first();
+ var nextEditor = $gp.editor.current.nextAll( 'tr.editor' ).first();
if ( nextEditor.length ) {
- var row_id = nextEditor.closest( 'tr' ).attr( 'row' );
- nextEditor.row_id = row_id;
- nextEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
+ var row_id = nextEditor.closest( 'tr' ).attr( 'row' );
+ nextEditor.row_id = row_id;
+ nextEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
nextEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
maybeFetchTranslationMemorySuggestions( nextEditor );
maybeFetchOpenAISuggestions( nextEditor );
@@ -479,11 +534,14 @@
original();
$( $gp.editor.table )
+ .on( 'click', '.translation-suggestion .delete-suggestion', deleteSuggestionFromTM )
.on( 'click', '.translation-suggestion', copySuggestion )
.on( 'click', '.translation-suggestion', addSuggestion );
- $( document ).ready( function() {
- getSuggestionsForTheFirstRow();
- });
+ $( document ).ready(
+ function() {
+ getSuggestionsForTheFirstRow();
+ }
+ );
};
})( $gp.editor.install_hooks );
@@ -499,21 +557,23 @@
return;
}
externalSuggestion.suggestion_source = $row.data( 'suggestion-source' ) == 'translation' ? 'tm' : $row.data( 'suggestion-source' );
- externalSuggestion.translation = $row.find( '.translation-suggestion__translation' ).text();
+ externalSuggestion.translation = $row.find( '.translation-suggestion__translation' ).text();
}
- //Prefilter ajax requests to add external translations used to the request.
- $.ajaxPrefilter( function ( options ) {
- const isSuggestionUsed = Object.keys( externalSuggestion ).length > 0 ? true : false;
+ // Prefilter ajax requests to add external translations used to the request.
+ $.ajaxPrefilter(
+ function ( options ) {
+ const isSuggestionUsed = Object.keys( externalSuggestion ).length > 0 ? true : false;
- if ( ! externalSuggestion || ! isSuggestionUsed ) {
- return;
- }
- if ( 'POST' === options.type && $gp_editor_options.url === options.url ) {
- options.data += '&externalTranslationSource=' + encodeURIComponent( externalSuggestion.suggestion_source );
- options.data += '&externalTranslationUsed=' + encodeURIComponent( externalSuggestion.translation );
- externalSuggestion = {};
+ if ( ! externalSuggestion || ! isSuggestionUsed ) {
+ return;
+ }
+ if ( 'POST' === options.type && $gp_editor_options.url === options.url ) {
+ options.data += '&externalTranslationSource=' + encodeURIComponent( externalSuggestion.suggestion_source );
+ options.data += '&externalTranslationUsed=' + encodeURIComponent( externalSuggestion.translation );
+ externalSuggestion = {};
+ }
}
- });
+ );
})( jQuery );
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
index 05efc2b193..6c87934c3d 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
@@ -25,6 +25,9 @@
echo '' . esc_translation( $suggestion['translation'] ) . '';
+ if ( $is_user_a_gte_for_locale && 1 == $suggestion['similarity_score'] ) {
+ echo '';
+ }
echo '';
echo '';
echo '';
From 75c653b81b6e61f34a00dc3dd6bc67a51f9a5890 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Mon, 12 Aug 2024 09:08:29 +0200
Subject: [PATCH 2/8] Hide both rows (main place and sideber) with the
incorrect translation
---
.../js/translation-suggestions.js | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index a2a0788186..58dc924f7d 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -428,12 +428,15 @@
if ( ! container.length ) {
return;
}
- var row = $( this ).closest( '.translation-suggestion' );
+ var row = $( this ).closest( '.translation-suggestion' );
+ var rows = editor.find( '.translation-suggestion' );
+
var deleteButton = row.find( '.delete-suggestion' );
var originalString = editor.find( '.original-raw' ).text();
var translationString = row.find( '.translation-suggestion__translation' ).text();
var originalId = editor.original_id;
var nonce = container.data( 'nonce' );
+
deleteButton.prop( 'disabled', true );
$.ajax(
{
@@ -449,7 +452,14 @@
cache: false,
success: function(result) {
if ( true === result.success ) {
- row.remove();
+ rows.filter(
+ function () {
+ var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
+ var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
+
+ return translationRaw === translationString && score === "100%";
+ }
+ ).hide();
}
}
}
From af6e3bbcaf08c17901e97ba4f00680f1652c17ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Mon, 12 Aug 2024 16:13:30 +0200
Subject: [PATCH 3/8] Disable both Delete buttons
---
.../js/translation-suggestions.js | 28 +++++++++++--------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index 58dc924f7d..0154bc3985 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -429,15 +429,22 @@
return;
}
var row = $( this ).closest( '.translation-suggestion' );
- var rows = editor.find( '.translation-suggestion' );
+ var rows = editor.find( '.translation-suggestion.with-tooltip.translation' );
- var deleteButton = row.find( '.delete-suggestion' );
var originalString = editor.find( '.original-raw' ).text();
var translationString = row.find( '.translation-suggestion__translation' ).text();
var originalId = editor.original_id;
var nonce = container.data( 'nonce' );
- deleteButton.prop( 'disabled', true );
+ var filteredRows = rows.filter(
+ function() {
+ var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
+ var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
+ return translationRaw === translationString && score === "100%";
+ }
+ );
+
+ filteredRows.find( '.delete-suggestion' ).prop( 'disabled', true );
$.ajax(
{
type: 'POST',
@@ -452,17 +459,16 @@
cache: false,
success: function(result) {
if ( true === result.success ) {
- rows.filter(
- function () {
- var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
- var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
-
- return translationRaw === translationString && score === "100%";
+ filteredRows.each(
+ function() {
+ $( this ).remove();
}
- ).hide();
+ );
}
+
}
- }
+ },
+ 100
);
}
From a269763d1e07d5803a8332511a5f131ebe6660ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Tue, 20 Aug 2024 18:58:56 +0200
Subject: [PATCH 4/8] Add a visual confirmation (JS) for the delete
---
.../js/translation-suggestions.js | 3 +++
1 file changed, 3 insertions(+)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index 0154bc3985..15f94cde2c 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -423,6 +423,9 @@
function deleteSuggestionFromTM( event ) {
event.preventDefault();
event.stopImmediatePropagation();
+ if ( ! confirm( 'Are you sure you want to delete this translation from the Translation Memory?' )) {
+ return;
+ }
var editor = $gp.editor.current;
var container = editor.find( '.suggestions__translation-memory' );
if ( ! container.length ) {
From be68387b16d967106529d6873cf7caa586bf9963 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Thu, 22 Aug 2024 19:46:39 +0200
Subject: [PATCH 5/8] Add changes in the signatures of the methods to support
the plurals and the context
---
.../templates/style.css | 2 +-
.../inc/class-translation-memory-client.php | 69 ++++++++++++++-----
.../inc/routes/class-translation-memory.php | 28 ++++----
.../js/translation-suggestions.js | 28 +++++---
.../translation-memory-suggestions.php | 2 +-
5 files changed, 87 insertions(+), 42 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
index 2c6951ffca..c1d6490048 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
@@ -3352,4 +3352,4 @@ ul.other-locales li {
max-width: 100%;
float: none;
}
-}
\ No newline at end of file
+}
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
index 365489944d..c08a2048f6 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
@@ -3,6 +3,7 @@
namespace WordPressdotorg\GlotPress\TranslationSuggestions;
use GP;
+use GP_Locale;
use Text_Diff;
use WP_Error;
use WP_Http;
@@ -93,11 +94,12 @@ public static function update( array $translations ) {
/**
* Queries translation memory for a string.
*
- * @param string $text Text to search translations for.
+ * @param string $text Singular text to search translations for.
+ * @param string $text_plural Plural text to search translations for.
* @param string $target_locale Locale to search in.
* @return array|\WP_Error List of suggestions on success, WP_Error on failure.
*/
- public static function query( string $text, string $target_locale ) {
+ public static function query( string $text, string $text_plural, string $target_locale ) {
if ( ! defined( 'WPCOM_TM_TOKEN' ) ) {
return new WP_Error( 'no_token' );
}
@@ -105,10 +107,11 @@ public static function query( string $text, string $target_locale ) {
$url = add_query_arg(
urlencode_deep(
array(
- 'text' => $text,
- 'target' => $target_locale,
- 'token' => WPCOM_TM_TOKEN,
- 'ts' => time(),
+ 'text' => $text,
+ 'text_plural' => $text_plural,
+ 'target' => $target_locale,
+ 'token' => WPCOM_TM_TOKEN,
+ 'ts' => time(),
)
),
self::API_ENDPOINT
@@ -144,10 +147,13 @@ public static function query( string $text, string $target_locale ) {
$suggestions = array();
foreach ( $result['matches'] as $match ) {
$suggestions[] = array(
- 'similarity_score' => $match['score'],
- 'source' => $match['source'],
- 'translation' => $match['text'],
- 'diff' => ( 1 === $match['score'] ) ? null : self::diff( $text, $match['source'] ),
+ 'similarity_score' => $match['score'],
+ 'source' => $match['source'],
+ 'source_plural' => $match['source_plural'],
+ 'source_context' => $match['source_context'],
+ 'translation' => $match['text'],
+ 'translation_plural' => $match['text_plural'],
+ 'diff' => ( 1 === $match['score'] ) ? null : self::diff( $text, $match['source'] ),
);
}
@@ -157,13 +163,44 @@ public static function query( string $text, string $target_locale ) {
/**
* Deletes a translation from translation memory.
*
- * @param string $original_string Original string.
- * @param string $translation_string Translation string.
- * @param string $locale_slug Locale slug.
- * @param string $set_slug Translation set slug.
+ * @param array $source Array with the original string (singular and plural) and the context.
+ * @param array $translation Array with the translation (singular and plural).
+ * @param string $locale_slug Locale slug.
+ * @param string $set_slug Translation set slug.
+ *
+ * @return bool
*/
- public static function delete( string $original_string, string $translation_string, string $locale_slug, string $set_slug ):bool {
- // @todo Implement.
+ public static function delete( array $source, array $translation, string $locale_slug, string $set_slug ):bool {
+ $locale = $locale_slug;
+ if ( 'default' !== $set_slug ) {
+ $locale .= '_' . $set_slug;
+ }
+ $body = wp_json_encode(
+ array(
+ 'token' => WPCOM_TM_TOKEN,
+ 'source' => $source,
+ 'translation' => array(
+ 'singular' => $translation['translation'],
+ 'plural' => $translation['translation_plural'],
+ 'locale' => $locale,
+ ),
+ )
+ );
+ $request = wp_remote_post(
+ self::API_BULK_ENDPOINT,
+ array(
+ 'method' => 'DELETE',
+ 'timeout' => 10,
+ 'user-agent' => 'WordPress.org Translate',
+ 'body' => $body,
+ )
+ );
+ if ( is_wp_error( $request ) ) {
+ return false;
+ }
+ if ( WP_Http::OK !== wp_remote_retrieve_response_code( $request ) ) {
+ return false;
+ }
return true;
}
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
index 55b773a14d..37cbb9ffc9 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
@@ -5,7 +5,10 @@
use GP;
use GP_Locales;
use GP_Route;
+use GP_Translation;
use WordPressdotorg\GlotPress\TranslationSuggestions\Translation_Memory_Client;
+use WP_User;
+use function cli\err;
use const WordPressdotorg\GlotPress\TranslationSuggestions\PLUGIN_DIR;
class Translation_Memory extends GP_Route {
@@ -42,14 +45,12 @@ public function get_suggestions( $project_path, $locale_slug, $set_slug ) {
$locale .= '_' . $set_slug;
}
- $suggestions = Translation_Memory_Client::query( $original->singular, $locale );
+ $suggestions = Translation_Memory_Client::query( $original->singular, $original->plural, $locale );
if ( is_wp_error( $suggestions ) ) {
wp_send_json_error( $suggestions->get_error_code() );
}
- $project = GP::$project->by_path( $project_path );
- $translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $set_slug, $locale_slug );
$is_user_a_gte_for_locale = $this->is_user_a_gte_for_locale( wp_get_current_user(), $locale );
wp_send_json_success(
gp_tmpl_get_output(
@@ -174,7 +175,7 @@ public function get_deepl_suggestions( $project_path, $locale_slug, $set_slug )
}
/**
- * Delete a suggestion from the translation memory.
+ * Deletes a suggestion from the translation memory.
*
* @param string $project_path Project path.
* @param string $locale_slug Locale slug.
@@ -183,16 +184,15 @@ public function get_deepl_suggestions( $project_path, $locale_slug, $set_slug )
* @return void
*/
public function delete_suggestion( string $project_path, string $locale_slug, string $set_slug ): bool {
- $original_id = gp_post( 'originalId' );
- $original_string = gp_post( 'originalString' );
- $translation_string = gp_post( 'translationString' );
- $nonce = gp_post( 'nonce' );
-
+ $source = gp_post( 'source' );
+ $translation = gp_post( 'translation' );
+ $original_id = gp_post( 'originalId' );
+ $nonce = gp_post( 'nonce' );
if ( ! wp_verify_nonce( $nonce, 'translation-memory-suggestions-' . $original_id ) ) {
wp_send_json_error( 'invalid_nonce' );
}
- if ( empty( $original_string ) || empty( $translation_string ) ) {
+ if ( empty( $source ) || empty( $translation ) ) {
wp_send_json_error( 'missing_data' );
}
@@ -200,7 +200,7 @@ public function delete_suggestion( string $project_path, string $locale_slug, st
wp_send_json_error( 'user_cannot_delete' );
}
- $result = Translation_Memory_Client::delete( $original_string, $translation_string, $locale_slug, $set_slug );
+ $result = Translation_Memory_Client::delete( $source, $translation, $locale_slug, $set_slug );
if ( ! $result ) {
wp_send_json_error( 'delete_failed' );
}
@@ -575,12 +575,12 @@ private static function update_one_external_translation( string $translation, st
/**
* Determine if the user is a GTE for the given locale.
*
- * @param null|WP_User $user User.
- * @param string $set Locale set.
+ * @param WP_User $user User.
+ * @param string $locale Locale set.
*
* @return bool
*/
- private function is_user_a_gte_for_locale( $user, $locale ) {
+ private function is_user_a_gte_for_locale( WP_User $user, string $locale ): bool {
$locale_slug = explode( '_', $locale )[0];
$locale = GP_Locales::by_slug( $locale_slug );
if ( ! $locale ) {
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index 15f94cde2c..36be7cb9d8 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -431,19 +431,27 @@
if ( ! container.length ) {
return;
}
- var row = $( this ).closest( '.translation-suggestion' );
- var rows = editor.find( '.translation-suggestion.with-tooltip.translation' );
-
- var originalString = editor.find( '.original-raw' ).text();
- var translationString = row.find( '.translation-suggestion__translation' ).text();
- var originalId = editor.original_id;
- var nonce = container.data( 'nonce' );
+ var row = $( this ).closest( '.translation-suggestion' );
+ var deleteButton = event.target;
+ var rows = editor.find( '.translation-suggestion.with-tooltip.translation' );
+
+ var source = {
+ 'source': deleteButton.dataset.sourceSingular,
+ 'source_plural': deleteButton.dataset.sourcePlural,
+ 'source_context': deleteButton.dataset.sourceContext,
+ };
+ var translation = {
+ 'translation': deleteButton.dataset.translation,
+ 'translation_plural': deleteButton.dataset.translationPlural,
+ };
+ var originalId = editor.original_id;
+ var nonce = container.data( 'nonce' );
var filteredRows = rows.filter(
function() {
var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
- return translationRaw === translationString && score === "100%";
+ return translationRaw === deleteButton.dataset.translation && score === "100%";
}
);
@@ -453,9 +461,9 @@
type: 'POST',
url: window.WPORG_TRANSLATION_MEMORY_API_DELETE_URL,
data: {
+ 'source': source,
+ 'translation': translation,
'originalId' : originalId,
- 'originalString': originalString,
- 'translationString': translationString,
'nonce': nonce
},
dataType: 'json',
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
index 6c87934c3d..1da974a673 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
@@ -26,7 +26,7 @@
echo '' . esc_translation( $suggestion['translation'] ) . '';
if ( $is_user_a_gte_for_locale && 1 == $suggestion['similarity_score'] ) {
- echo '';
+ echo '';
}
echo '';
echo '';
From 9e65a5f5f9729eaee5fb810ae9e4f1fb398b9bad Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Fri, 23 Aug 2024 10:41:40 +0200
Subject: [PATCH 6/8] Remove an unused variable and some linting from code
outside of this PR
---
.../js/translation-suggestions.js | 253 ++++++++----------
1 file changed, 115 insertions(+), 138 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
index 36be7cb9d8..a6ec3963c0 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/js/translation-suggestions.js
@@ -26,7 +26,6 @@
/**
* Stores the external translations used.
- *
* @type {object}
*/
var externalSuggestion = {};
@@ -68,47 +67,39 @@
}
// Store a string with a space to avoid making the same request another time.
storeTheSuggestionInTheCache( type, originalId, ' ' );
- var xhr = $.ajax(
- {
- url: apiUrl,
- data: {
- 'original': originalId,
- 'translation': translationId,
- 'nonce': nonce
- },
- dataType: 'json',
- cache: false,
- }
- );
-
- xhr.done(
- function( response ) {
- $container.find( '.suggestions__loading-indicator' ).remove();
- if ( response.success ) {
- $container.append( response.data );
- storeTheSuggestionInTheCache( type, originalId, response.data );
- removeNoSuggestionsMessage( $container );
- copyTranslationMemoryToSidebarTab( $container );
- } else {
- $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
- }
- $container.addClass( 'initialized' );
- }
- );
+ var xhr = $.ajax( {
+ url: apiUrl,
+ data: {
+ 'original': originalId,
+ 'translation': translationId,
+ 'nonce': nonce
+ },
+ dataType: 'json',
+ cache: false,
+ } );
- xhr.fail(
- function() {
- $container.find( '.suggestions__loading-indicator' ).remove();
+ xhr.done( function( response ) {
+ $container.find( '.suggestions__loading-indicator' ).remove();
+ if ( response.success ) {
+ $container.append( response.data );
+ storeTheSuggestionInTheCache( type, originalId, response.data );
+ removeNoSuggestionsMessage( $container );
+ copyTranslationMemoryToSidebarTab( $container );
+ } else {
$container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
- $container.addClass( 'initialized' );
}
- );
+ $container.addClass( 'initialized' );
+ } );
- xhr.always(
- function() {
- $container.removeClass( 'fetching' );
- }
- );
+ xhr.fail( function() {
+ $container.find( '.suggestions__loading-indicator' ).remove();
+ $container.append( $( '', { 'text': 'Error while loading suggestions.' } ) );
+ $container.addClass( 'initialized' );
+ } );
+
+ xhr.always( function() {
+ $container.removeClass( 'fetching' );
+ } );
}
/**
@@ -118,12 +109,12 @@
*/
function getSuggestionsForTheFirstRow() {
var firstEditor = $( '#translations' ).find( '.editor' ).first();
- var row_id = firstEditor.closest( 'tr' ).attr( 'row' );
+ var row_id = firstEditor.closest( 'tr' ).attr( 'row' );
if ( ! row_id ) {
return;
}
- firstEditor.row_id = row_id;
- firstEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
+ firstEditor.row_id = row_id;
+ firstEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
firstEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
maybeFetchTranslationMemorySuggestions( firstEditor );
maybeFetchOpenAISuggestions( firstEditor );
@@ -197,14 +188,14 @@
add_amount_to_others_tab = function ( sidebarTab, data, originalId ) {
let elements = 0;
- if ( data ? .['helper-history-' + originalId] ) {
+ if ( data?.['helper-history-' + originalId] ) {
elements += data['helper-history-' + originalId].count;
}
- if ( data ? .['helper-other-locales-' + originalId] ) {
+ if ( data?.['helper-other-locales-' + originalId] ) {
elements += data['helper-other-locales-' + originalId].count;
}
- var editor = $( '[data-tab="' + sidebarTab + '"]' ).closest( '.editor' );
- var TMcontainer = editor.find( '.suggestions__translation-memory' );
+ var editor = $('[data-tab="' + sidebarTab + '"]').closest( '.editor' );
+ var TMcontainer = editor.find( '.suggestions__translation-memory' );
var elementsInTM = 0;
if ( TMcontainer.length ) {
elementsInTM += TMcontainer.find( '.translation-suggestion.with-tooltip.translation' ).length;
@@ -212,10 +203,10 @@
elementsInTM += TMcontainer.find( '.translation-suggestion.with-tooltip.openai' ).length;
}
elements += elementsInTM;
- $( '#summary-translation-memory-' + originalId ).html( 'Translation Memory (' + elementsInTM + ')' );
+ $( '#summary-translation-memory-' + originalId ).html('Translation Memory (' + elementsInTM + ')');
let content = 'Others (' + elements + ')';
- $( '[data-tab="' + sidebarTab + '"]' ).html( content );
+ $('[data-tab="' + sidebarTab + '"]').html( content );
}
/**
@@ -226,16 +217,16 @@
* @return {void}
*/
function copyTranslationMemoryToSidebarTab( $container ){
- var editor = $container.closest( '.editor' );
- var divSidebarWithDiscussion = editor.find( '.meta.discussion' ).first();
- var divId = divSidebarWithDiscussion.attr( 'data-row-id' );
- var TMcontainer = editor.find( '.suggestions__translation-memory' );
- if ( ! TMcontainer.length ) {
+ var editor = $container.closest( '.editor' );
+ var divSidebarWithDiscussion = editor.find( '.meta.discussion' ).first();
+ var divId = divSidebarWithDiscussion.attr( 'data-row-id' );
+ var TMcontainer = editor.find( '.suggestions__translation-memory' );
+ if ( !TMcontainer.length ) {
return;
}
$( '#sidebar-div-others-translation-memory-content-' + divId ).html( TMcontainer.html() );
- add_amount_to_others_tab( 'sidebar-tab-others-' + divId, window.translationHelpersCache ? .[ divId ], divId );
+ add_amount_to_others_tab('sidebar-tab-others-' + divId, window.translationHelpersCache?.[ divId ], divId);
}
/**
@@ -276,7 +267,7 @@
*/
function maybeFetchTranslationMemorySuggestions( editor ) {
var $container = editor.find( '.suggestions__translation-memory' );
- if ( ! $container.length ) {
+ if ( !$container.length ) {
return;
}
@@ -284,15 +275,15 @@
return;
}
- if ( ! editor.find( 'translation-suggestion.with-tooltip.translation' ).first() ) {
+ if ( !editor.find('translation-suggestion.with-tooltip.translation').first() ) {
return;
}
$container.addClass( 'fetching' );
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, window.WPORG_TRANSLATION_MEMORY_API_URL, originalId, translationId, nonce, 'TM' );
}
@@ -331,15 +322,15 @@
*/
function maybeFetchExternalSuggestions( editor, type, getExternalSuggestions, apiUrl ) {
var $container = editor.find( '.suggestions__translation-memory' );
- if ( ! $container.length ) {
+ if ( !$container.length ) {
return;
}
if ( true !== getExternalSuggestions ) {
return;
}
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, apiUrl, originalId, translationId, nonce, type );
}
@@ -363,9 +354,9 @@
$container.addClass( 'fetching' );
- var originalId = editor.original_id;
+ var originalId = editor.original_id;
var translationId = editor.translation_id;
- var nonce = $container.data( 'nonce' );
+ var nonce = $container.data( 'nonce' );
fetchSuggestions( $container, window.WPORG_OTHER_LANGUAGES_API_URL, originalId , translationId, nonce, 'OL' );
}
@@ -396,21 +387,19 @@
* @return {void}
*/
function removeNoSuggestionsDuplicateMessage( $container ) {
- var $html = $( $container );
- var $paragraphs = $html.find( 'p' );
+ var $html = $($container);
+ var $paragraphs = $html.find('p');
var uniqueParagraphs = [];
- $paragraphs.each(
- function() {
- var paragraphText = $( this ).text().trim();
+ $paragraphs.each(function() {
+ var paragraphText = $(this).text().trim();
- if (uniqueParagraphs.indexOf( paragraphText ) === -1) {
- uniqueParagraphs.push( paragraphText );
- } else {
- $( this ).remove();
- }
+ if (uniqueParagraphs.indexOf(paragraphText) === -1) {
+ uniqueParagraphs.push(paragraphText);
+ } else {
+ $(this).remove();
}
- );
+ });
}
/**
@@ -423,19 +412,17 @@
function deleteSuggestionFromTM( event ) {
event.preventDefault();
event.stopImmediatePropagation();
- if ( ! confirm( 'Are you sure you want to delete this translation from the Translation Memory?' )) {
+ if ( ! confirm( 'Are you sure you want to delete this translation from the Translation Memory?' ) ) {
return;
}
- var editor = $gp.editor.current;
+ var editor = $gp.editor.current;
var container = editor.find( '.suggestions__translation-memory' );
if ( ! container.length ) {
return;
}
- var row = $( this ).closest( '.translation-suggestion' );
- var deleteButton = event.target;
- var rows = editor.find( '.translation-suggestion.with-tooltip.translation' );
- var source = {
+ var deleteButton = event.target;
+ var source = {
'source': deleteButton.dataset.sourceSingular,
'source_plural': deleteButton.dataset.sourcePlural,
'source_context': deleteButton.dataset.sourceContext,
@@ -444,43 +431,37 @@
'translation': deleteButton.dataset.translation,
'translation_plural': deleteButton.dataset.translationPlural,
};
- var originalId = editor.original_id;
- var nonce = container.data( 'nonce' );
-
- var filteredRows = rows.filter(
- function() {
- var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
- var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
- return translationRaw === deleteButton.dataset.translation && score === "100%";
- }
- );
+ var originalId = editor.original_id;
+ var nonce = container.data( 'nonce' );
- filteredRows.find( '.delete-suggestion' ).prop( 'disabled', true );
- $.ajax(
- {
- type: 'POST',
- url: window.WPORG_TRANSLATION_MEMORY_API_DELETE_URL,
- data: {
- 'source': source,
- 'translation': translation,
- 'originalId' : originalId,
- 'nonce': nonce
- },
- dataType: 'json',
- cache: false,
- success: function(result) {
- if ( true === result.success ) {
- filteredRows.each(
- function() {
- $( this ).remove();
- }
- );
- }
+ var rows = editor.find( '.translation-suggestion.with-tooltip.translation' );
+ var filteredRows = rows.filter( function() {
+ var translationRaw = $( this ).find( '.translation-suggestion__translation-raw' ).text().trim();
+ var score = $( this ).find( '.translation-suggestion__score' ).text().trim();
+ return translationRaw === deleteButton.dataset.translation && score === "100%";
+ });
- }
+ filteredRows.find( '.delete-suggestion' ).prop( 'disabled', true );
+ $.ajax( {
+ type: 'POST',
+ url: window.WPORG_TRANSLATION_MEMORY_API_DELETE_URL,
+ data: {
+ 'source': source,
+ 'translation': translation,
+ 'originalId' : originalId,
+ 'nonce': nonce
},
- 100
- );
+ dataType: 'json',
+ cache: false,
+ success: function( result ) {
+ if( true === result.success ) {
+ filteredRows.each( function() {
+ $( this ).remove();
+ });
+ }
+
+ }
+ }, 100 );
}
function copySuggestion( event ) {
@@ -488,8 +469,8 @@
return;
}
- var $el = $( this ).closest( '.translation-suggestion' );
- var $translation = $el.find( '.translation-suggestion__translation-raw' );
+ var $el = $( this ).closest( '.translation-suggestion' );
+ var $translation = $el.find( '.translation-suggestion__translation-raw');
if ( ! $translation.length ) {
return;
}
@@ -542,11 +523,11 @@
maybeFetchOpenAISuggestions( $gp.editor.current );
maybeFetchDeeplSuggestions( $gp.editor.current );
maybeFetchOtherLanguageSuggestions( $gp.editor.current );
- var nextEditor = $gp.editor.current.nextAll( 'tr.editor' ).first();
+ var nextEditor = $gp.editor.current.nextAll('tr.editor' ).first();
if ( nextEditor.length ) {
- var row_id = nextEditor.closest( 'tr' ).attr( 'row' );
- nextEditor.row_id = row_id;
- nextEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
+ var row_id = nextEditor.closest( 'tr' ).attr( 'row' );
+ nextEditor.row_id = row_id;
+ nextEditor.original_id = $gp.editor.original_id_from_row_id( row_id );
nextEditor.translation_id = $gp.editor.translation_id_from_row_id( row_id );
maybeFetchTranslationMemorySuggestions( nextEditor );
maybeFetchOpenAISuggestions( nextEditor );
@@ -564,11 +545,9 @@
.on( 'click', '.translation-suggestion .delete-suggestion', deleteSuggestionFromTM )
.on( 'click', '.translation-suggestion', copySuggestion )
.on( 'click', '.translation-suggestion', addSuggestion );
- $( document ).ready(
- function() {
- getSuggestionsForTheFirstRow();
- }
- );
+ $( document ).ready( function() {
+ getSuggestionsForTheFirstRow();
+ });
};
})( $gp.editor.install_hooks );
@@ -584,23 +563,21 @@
return;
}
externalSuggestion.suggestion_source = $row.data( 'suggestion-source' ) == 'translation' ? 'tm' : $row.data( 'suggestion-source' );
- externalSuggestion.translation = $row.find( '.translation-suggestion__translation' ).text();
+ externalSuggestion.translation = $row.find( '.translation-suggestion__translation' ).text();
}
- // Prefilter ajax requests to add external translations used to the request.
- $.ajaxPrefilter(
- function ( options ) {
- const isSuggestionUsed = Object.keys( externalSuggestion ).length > 0 ? true : false;
+ //Prefilter ajax requests to add external translations used to the request.
+ $.ajaxPrefilter( function ( options ) {
+ const isSuggestionUsed = Object.keys( externalSuggestion ).length > 0 ? true : false;
- if ( ! externalSuggestion || ! isSuggestionUsed ) {
- return;
- }
- if ( 'POST' === options.type && $gp_editor_options.url === options.url ) {
- options.data += '&externalTranslationSource=' + encodeURIComponent( externalSuggestion.suggestion_source );
- options.data += '&externalTranslationUsed=' + encodeURIComponent( externalSuggestion.translation );
- externalSuggestion = {};
- }
+ if ( ! externalSuggestion || ! isSuggestionUsed ) {
+ return;
+ }
+ if ( 'POST' === options.type && $gp_editor_options.url === options.url ) {
+ options.data += '&externalTranslationSource=' + encodeURIComponent( externalSuggestion.suggestion_source );
+ options.data += '&externalTranslationUsed=' + encodeURIComponent( externalSuggestion.translation );
+ externalSuggestion = {};
}
- );
+ });
})( jQuery );
From d05998024379c536cf77537627630edcdea5d867 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Fri, 23 Aug 2024 11:37:50 +0200
Subject: [PATCH 7/8] Add the plural in a Translation_Memory_Client::query call
---
.../inc/routes/class-translation-memory.php | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
index 37cbb9ffc9..117bbe416e 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
@@ -378,7 +378,7 @@ private function is_TM_translation_100_accurate( $project_path, $locale, $set_sl
return false;
}
- $suggestions = Translation_Memory_Client::query( $original->singular, $locale );
+ $suggestions = Translation_Memory_Client::query( $original->singular, $original->plural, $locale );
if ( is_wp_error( $suggestions ) ) {
return false;
}
From fdc3dc6f00a0c615e76330ccfdcf51601f949aa3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jes=C3=BAs=20Amieiro?=
<1667814+amieiro@users.noreply.github.com>
Date: Tue, 26 Nov 2024 16:00:33 +0100
Subject: [PATCH 8/8] Lint
---
.../templates/style.css | 2 +-
.../inc/class-translation-memory-client.php | 86 +++++++++----------
.../inc/routes/class-translation-memory.php | 2 -
.../translation-memory-suggestions.php | 6 +-
4 files changed, 44 insertions(+), 52 deletions(-)
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
index c1d6490048..2c6951ffca 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-customizations/templates/style.css
@@ -3352,4 +3352,4 @@ ul.other-locales li {
max-width: 100%;
float: none;
}
-}
+}
\ No newline at end of file
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
index c08a2048f6..63bc01f6b8 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/class-translation-memory-client.php
@@ -13,7 +13,7 @@
class Translation_Memory_Client {
- const API_ENDPOINT = 'https://translate.wordpress.com/api/tm/';
+ const API_ENDPOINT = 'https://translate.wordpress.com/api/tm/';
const API_BULK_ENDPOINT = 'https://translate.wordpress.com/api/tm/-bulk';
/**
@@ -23,7 +23,7 @@ class Translation_Memory_Client {
* @return true|\WP_Error True on success, WP_Error on failure.
*/
public static function update( array $translations ) {
- $requests = array();
+ $requests = [];
foreach ( $translations as $original_id => $translation_id ) {
$translation = GP::$translation->get( $translation_id );
@@ -41,36 +41,34 @@ public static function update( array $translations ) {
$locale .= '_' . $translation_set->slug;
}
- $requests[] = array(
+ $requests[] = [
'source' => $original->fields(),
- 'translations' => array(
- array(
+ 'translations' => [
+ [
'singular' => $translation->translation_0,
'plural' => $translation->translation_1,
'locale' => $locale,
- ),
- ),
- );
+ ],
+ ],
+ ];
}
if ( ! $requests ) {
return new WP_Error( 'no_translations' );
}
- $body = wp_json_encode(
- array(
- 'token' => WPCOM_TM_TOKEN,
- 'requests' => $requests,
- )
- );
+ $body = wp_json_encode( [
+ 'token' => WPCOM_TM_TOKEN,
+ 'requests' => $requests,
+ ] );
$request = wp_remote_post(
self::API_BULK_ENDPOINT,
- array(
+ [
'timeout' => 10,
'user-agent' => 'WordPress.org Translate',
'body' => $body,
- )
+ ]
);
if ( is_wp_error( $request ) ) {
@@ -94,35 +92,31 @@ public static function update( array $translations ) {
/**
* Queries translation memory for a string.
*
- * @param string $text Singular text to search translations for.
- * @param string $text_plural Plural text to search translations for.
- * @param string $target_locale Locale to search in.
- * @return array|\WP_Error List of suggestions on success, WP_Error on failure.
+ * @param string $text Singular text to search translations for.
+ * @param null|string $text_plural Plural text to search translations for.
+ * @param string $target_locale Locale to search in.
+ *
+ * @return array|\WP_Error List of suggestions on success, WP_Error on failure.
*/
- public static function query( string $text, string $text_plural, string $target_locale ) {
+ public static function query( string $text, $text_plural, string $target_locale ) {
if ( ! defined( 'WPCOM_TM_TOKEN' ) ) {
return new WP_Error( 'no_token' );
}
- $url = add_query_arg(
- urlencode_deep(
- array(
- 'text' => $text,
- 'text_plural' => $text_plural,
- 'target' => $target_locale,
- 'token' => WPCOM_TM_TOKEN,
- 'ts' => time(),
- )
- ),
- self::API_ENDPOINT
- );
+ $url = add_query_arg( urlencode_deep( [
+ 'text' => $text,
+ 'text_plural' => $text_plural,
+ 'target' => $target_locale,
+ 'token' => WPCOM_TM_TOKEN,
+ 'ts' => time(),
+ ] ), self::API_ENDPOINT );
$request = wp_remote_get(
$url,
- array(
+ [
'timeout' => 4,
'user-agent' => 'WordPress.org Translate',
- )
+ ]
);
if ( is_wp_error( $request ) ) {
@@ -141,20 +135,20 @@ public static function query( string $text, string $text_plural, string $target_
}
if ( empty( $result['matches'] ) ) {
- return array();
+ return [];
}
- $suggestions = array();
+ $suggestions = [];
foreach ( $result['matches'] as $match ) {
- $suggestions[] = array(
+ $suggestions[] = [
'similarity_score' => $match['score'],
'source' => $match['source'],
- 'source_plural' => $match['source_plural'],
+ 'source_plural' => $match['source_plural'],
'source_context' => $match['source_context'],
'translation' => $match['text'],
'translation_plural' => $match['text_plural'],
'diff' => ( 1 === $match['score'] ) ? null : self::diff( $text, $match['source'] ),
- );
+ ];
}
return $suggestions;
@@ -175,21 +169,21 @@ public static function delete( array $source, array $translation, string $locale
if ( 'default' !== $set_slug ) {
$locale .= '_' . $set_slug;
}
- $body = wp_json_encode(
+ $body = wp_json_encode(
array(
- 'token' => WPCOM_TM_TOKEN,
- 'source' => $source,
+ 'token' => WPCOM_TM_TOKEN,
+ 'source' => $source,
'translation' => array(
'singular' => $translation['translation'],
'plural' => $translation['translation_plural'],
'locale' => $locale,
- ),
+ )
)
);
$request = wp_remote_post(
self::API_BULK_ENDPOINT,
array(
- 'method' => 'DELETE',
+ 'method' => 'DELETE',
'timeout' => 10,
'user-agent' => 'WordPress.org Translate',
'body' => $body,
@@ -212,7 +206,7 @@ public static function delete( array $source, array $translation, string $locale
* @return string HTML markup for the differences between the two texts.
*/
protected static function diff( $previous_text, $text ) {
- $diff = new Text_Diff( 'auto', array( array( $text ), array( $previous_text ) ) );
+ $diff = new Text_Diff( 'auto', [ [ $text ], [ $previous_text ] ] );
$renderer = new WP_Text_Diff_Renderer_inline();
return $renderer->render( $diff );
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
index 117bbe416e..7837ebbccc 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/inc/routes/class-translation-memory.php
@@ -5,10 +5,8 @@
use GP;
use GP_Locales;
use GP_Route;
-use GP_Translation;
use WordPressdotorg\GlotPress\TranslationSuggestions\Translation_Memory_Client;
use WP_User;
-use function cli\err;
use const WordPressdotorg\GlotPress\TranslationSuggestions\PLUGIN_DIR;
class Translation_Memory extends GP_Route {
diff --git a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
index 1da974a673..f75f7681ea 100644
--- a/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
+++ b/wordpress.org/public_html/wp-content/plugins/wporg-gp-translation-suggestions/templates/translation-memory-suggestions.php
@@ -25,9 +25,9 @@
echo '' . esc_translation( $suggestion['translation'] ) . '';
- if ( $is_user_a_gte_for_locale && 1 == $suggestion['similarity_score'] ) {
- echo '';
- }
+ if ( $is_user_a_gte_for_locale && 1 == $suggestion['similarity_score'] ) {
+ echo '';
+ }
echo '';
echo '';
echo '';