feat: display the current translating stuff in settings
This commit is contained in:
@@ -73,6 +73,8 @@ Before production use, add WordPress PHPUnit integration tests with mocked `wp_r
|
||||
|
||||
The Posts and Pages lists show a status column for every target language, including the latest successful translation time and a translation action. The Settings page also provides **重新翻译所有内容**. It shows a confirmation warning before scheduling a forced refresh of published posts, pages, categories, and tags; this bypasses persisted translations and consumes Baidu API quota.
|
||||
|
||||
The Settings page also shows a live progress panel. It refreshes every five seconds and counts completed post/page and category/tag items for every configured target language. Progress reads only local WordPress and translation-table data; it does not send additional requests to Baidu.
|
||||
|
||||
## Known Limitations
|
||||
|
||||
- The settings UI accepts language codes but does not yet validate them against a maintained Baidu language-code list.
|
||||
|
||||
@@ -8,6 +8,7 @@ class WPT_Admin {
|
||||
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
||||
add_action( 'admin_post_wpt_queue_existing_translations', array( $this, 'queue_existing_translations' ) );
|
||||
add_action( 'admin_post_wpt_translate_post', array( $this, 'queue_post_translation' ) );
|
||||
add_action( 'wp_ajax_wpt_translation_progress', array( $this, 'translation_progress' ) );
|
||||
add_filter( 'manage_post_posts_columns', array( $this, 'add_translation_column' ) );
|
||||
add_filter( 'manage_page_posts_columns', array( $this, 'add_translation_column' ) );
|
||||
add_action( 'manage_post_posts_custom_column', array( $this, 'render_translation_column' ), 10, 2 );
|
||||
@@ -76,6 +77,38 @@ class WPT_Admin {
|
||||
<?php wp_nonce_field( 'wpt_queue_existing_translations' ); ?>
|
||||
<?php submit_button( '重新翻译所有内容', 'secondary', 'submit', false ); ?>
|
||||
</form>
|
||||
<hr />
|
||||
<h2>翻译进度</h2>
|
||||
<div id="wpt-translation-progress" aria-live="polite">
|
||||
<p>正在读取翻译进度...</p>
|
||||
</div>
|
||||
<script>
|
||||
(function () {
|
||||
var container = document.getElementById('wpt-translation-progress');
|
||||
var endpoint = <?php echo wp_json_encode( admin_url( 'admin-ajax.php' ) ); ?>;
|
||||
var nonce = <?php echo wp_json_encode( wp_create_nonce( 'wpt_translation_progress' ) ); ?>;
|
||||
|
||||
function updateProgress() {
|
||||
fetch(endpoint + '?action=wpt_translation_progress&_ajax_nonce=' + encodeURIComponent(nonce), { credentials: 'same-origin' })
|
||||
.then(function (response) { return response.json(); })
|
||||
.then(function (response) {
|
||||
if (!response.success) {
|
||||
throw new Error('progress_request_failed');
|
||||
}
|
||||
var progress = response.data;
|
||||
container.innerHTML = '<p><strong>' + progress.percent + '%</strong>(' + progress.completed + ' / ' + progress.total + ' 个内容项)</p>' +
|
||||
'<div style="max-width:480px;height:12px;background:#dcdcde"><div style="height:12px;width:' + progress.percent + '%;background:#2271b1"></div></div>' +
|
||||
'<p class="description">文章和页面:' + progress.posts_completed + ' / ' + progress.posts_total + ';分类和标签:' + progress.terms_completed + ' / ' + progress.terms_total + '。每 5 秒自动更新。</p>';
|
||||
})
|
||||
.catch(function () {
|
||||
container.innerHTML = '<p>暂时无法读取翻译进度。</p>';
|
||||
});
|
||||
}
|
||||
|
||||
updateProgress();
|
||||
window.setInterval(updateProgress, 5000);
|
||||
}());
|
||||
</script>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
@@ -134,6 +167,46 @@ class WPT_Admin {
|
||||
return $links;
|
||||
}
|
||||
|
||||
public function translation_progress() {
|
||||
check_ajax_referer( 'wpt_translation_progress' );
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
wp_send_json_error( array( 'message' => 'forbidden' ), 403 );
|
||||
}
|
||||
|
||||
$post_count = (int) wp_count_posts( 'post' )->publish + (int) wp_count_posts( 'page' )->publish;
|
||||
$terms = get_terms(
|
||||
array(
|
||||
'taxonomy' => array( 'category', 'post_tag' ),
|
||||
'hide_empty' => false,
|
||||
'fields' => 'ids',
|
||||
)
|
||||
);
|
||||
$term_count = is_wp_error( $terms ) ? 0 : count( $terms );
|
||||
$languages = WPT_Settings::target_languages();
|
||||
$counts = ( new WPT_Translation_Store() )->get_completed_item_counts( $languages );
|
||||
|
||||
$posts_total = $post_count * count( $languages );
|
||||
$terms_total = $term_count * count( $languages );
|
||||
$total = $posts_total + $terms_total;
|
||||
$posts_completed = min( $counts['posts'], $posts_total );
|
||||
$terms_completed = min( $counts['terms'], $terms_total );
|
||||
$completed = $posts_completed + $terms_completed;
|
||||
$percent = $total ? (int) floor( ( $completed / $total ) * 100 ) : 100;
|
||||
|
||||
wp_send_json_success(
|
||||
array(
|
||||
'posts_completed' => $posts_completed,
|
||||
'posts_total' => $posts_total,
|
||||
'terms_completed' => $terms_completed,
|
||||
'terms_total' => $terms_total,
|
||||
'completed' => $completed,
|
||||
'total' => $total,
|
||||
'percent' => $percent,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function add_translation_column( $columns ) {
|
||||
$columns['wpt_translation'] = '翻译状态';
|
||||
|
||||
|
||||
@@ -86,4 +86,36 @@ class WPT_Translation_Store {
|
||||
|
||||
return $wpdb->get_row( $sql, ARRAY_A );
|
||||
}
|
||||
|
||||
public function get_completed_item_counts( $target_languages ) {
|
||||
global $wpdb;
|
||||
|
||||
$target_languages = array_values( array_filter( array_map( 'sanitize_key', (array) $target_languages ) ) );
|
||||
if ( empty( $target_languages ) ) {
|
||||
return array(
|
||||
'posts' => 0,
|
||||
'terms' => 0,
|
||||
);
|
||||
}
|
||||
|
||||
$table_name = self::table_name();
|
||||
$placeholders = implode( ',', array_fill( 0, count( $target_languages ), '%s' ) );
|
||||
$post_sql = $wpdb->prepare(
|
||||
"SELECT COUNT(DISTINCT CONCAT(target_language, '|', SUBSTRING_INDEX(field_context, ':', 2)))
|
||||
FROM {$table_name}
|
||||
WHERE status = 'complete' AND target_language IN ({$placeholders}) AND field_context LIKE 'post:%'",
|
||||
$target_languages
|
||||
);
|
||||
$term_sql = $wpdb->prepare(
|
||||
"SELECT COUNT(DISTINCT CONCAT(target_language, '|', SUBSTRING_INDEX(field_context, ':', 2)))
|
||||
FROM {$table_name}
|
||||
WHERE status = 'complete' AND target_language IN ({$placeholders}) AND field_context LIKE 'term:%'",
|
||||
$target_languages
|
||||
);
|
||||
|
||||
return array(
|
||||
'posts' => (int) $wpdb->get_var( $post_sql ),
|
||||
'terms' => (int) $wpdb->get_var( $term_sql ),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user