Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/wp-admin/includes/class-language-pack-upgrader.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ public static function async_upgrade( $upgrader = false ) {
foreach ( $language_updates as $key => $language_update ) {
$update = ! empty( $language_update->autoupdate );

if ( wp_is_translation_update_deferred( $language_update ) ) {
$update = false;
}

/**
* Filters whether to asynchronously update translation for core, a plugin, or a theme.
*
Expand Down
4 changes: 4 additions & 0 deletions src/wp-admin/includes/class-wp-automatic-updater.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,10 @@ public function should_update( $type, $item, $context ) {
}
} else {
$update = ! empty( $item->autoupdate );

if ( wp_is_translation_update_deferred( $item ) ) {
$update = false;
}
}

// If the `disable_autoupdate` flag is set, override any user-choice, but allow filters.
Expand Down
140 changes: 140 additions & 0 deletions src/wp-admin/includes/update.php
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,146 @@ function get_theme_updates() {
return $update_themes;
}

/**
* Gets the display name for a translation update.
*
* @since 7.1.0
*
* @param object $update Translation update object.
* @return string The translation update name.
*/
function wp_get_translation_update_name( $update ) {
$type = isset( $update->type ) ? $update->type : '';
$slug = isset( $update->slug ) ? $update->slug : '';

switch ( $type ) {
case 'core':
return 'WordPress'; // Not translated.

case 'theme':
$theme = wp_get_theme( $slug );
if ( $theme->exists() ) {
return $theme->get( 'Name' );
}
break;

case 'plugin':
require_once ABSPATH . 'wp-admin/includes/plugin.php';

$plugin_names = array();
$all_plugins = get_plugins();
$plugin_update = get_site_transient( 'update_plugins' );

if ( is_object( $plugin_update ) ) {
$plugin_updates = array();

if ( ! empty( $plugin_update->response ) && is_array( $plugin_update->response ) ) {
$plugin_updates = array_merge( $plugin_updates, $plugin_update->response );
}

if ( ! empty( $plugin_update->no_update ) && is_array( $plugin_update->no_update ) ) {
$plugin_updates = array_merge( $plugin_updates, $plugin_update->no_update );
}

foreach ( $plugin_updates as $plugin_file => $plugin_data ) {
$plugin_data = (object) $plugin_data;

if ( ! empty( $plugin_data->slug ) && ! empty( $all_plugins[ $plugin_file ]['Name'] ) ) {
$plugin_names[ $plugin_data->slug ] = $all_plugins[ $plugin_file ]['Name'];
}
}
}

foreach ( $all_plugins as $plugin_file => $plugin_data ) {
$plugin_basename = dirname( $plugin_file );

if ( isset( $plugin_data['Name'] ) ) {
$plugin_names[ $plugin_file ] = $plugin_data['Name'];
$plugin_names[ basename( $plugin_file, '.php' ) ] = $plugin_data['Name'];

if ( '.' !== $plugin_basename ) {
$plugin_names[ $plugin_basename ] = $plugin_data['Name'];
}
}
}

if ( ! empty( $plugin_names[ $slug ] ) ) {
return $plugin_names[ $slug ];
}
break;
}

return $slug;
}

/**
* Gets the display language for a translation update.
*
* @since 7.1.0
*
* @param string $locale Translation update locale.
* @return string The translation update language.
*/
function wp_get_translation_update_language( $locale ) {
$translations = get_site_transient( 'available_translations' );

if ( is_array( $translations ) && ! empty( $translations[ $locale ]['native_name'] ) ) {
return sprintf(
/* translators: 1: Native language name, 2: Locale. */
__( '%1$s (%2$s)' ),
$translations[ $locale ]['native_name'],
$locale
);
}

return $locale;
}

/**
* Gets display data for available translation updates.
*
* @since 7.1.0
*
* @return array[] {
* An array of translation update display data.
*
* @type bool $checked Whether the translation update is selected for installation.
* @type bool $deferred Whether the translation update has been deferred.
* @type string $id Translation update identifier.
* @type string $language Translation update language.
* @type string $language_code Translation update locale.
* @type string $name Translation update name.
* @type string $slug Translation update slug.
* @type string $type Translation update type.
* @type string $version Translation update version.
* }
*/
function wp_get_translation_update_data() {
$available_updates = wp_get_translation_updates();
$deferred_translation_updates = wp_get_deferred_translation_updates( $available_updates );
$translation_updates = array();

foreach ( $available_updates as $update ) {
$translation_update_id = wp_get_translation_update_id( $update );
$language = isset( $update->language ) ? $update->language : '';
$deferred = isset( $deferred_translation_updates[ $translation_update_id ] );

$translation_updates[] = array(
'checked' => ! $deferred,
'deferred' => $deferred,
'id' => $translation_update_id,
'language' => wp_get_translation_update_language( $language ),
'language_code' => $language,
'name' => wp_get_translation_update_name( $update ),
'slug' => isset( $update->slug ) ? $update->slug : '',
'type' => isset( $update->type ) ? $update->type : '',
'version' => isset( $update->version ) ? $update->version : '',
);
}

return $translation_updates;
}

/**
* Adds a callback to display update information for themes with updates available.
*
Expand Down
140 changes: 132 additions & 8 deletions src/wp-admin/update-core.php
Original file line number Diff line number Diff line change
Expand Up @@ -813,22 +813,88 @@ function list_theme_updates() {
* @since 3.7.0
*/
function list_translation_updates() {
$updates = wp_get_translation_updates();
if ( ! $updates ) {
$translation_updates = wp_get_translation_update_data();
if ( ! $translation_updates ) {
if ( 'en_US' !== get_locale() ) {
echo '<h2>' . __( 'Translations' ) . '</h2>';
echo '<p>' . __( 'Your translations are all up to date.' ) . '</p>';
}
return;
}

$form_action = 'update-core.php?action=do-translation-upgrade';
$form_action = 'update-core.php?action=do-translation-upgrade';
$updates_count = count( $translation_updates );
?>
<h2><?php _e( 'Translations' ); ?></h2>
<h2>
<?php
printf(
'%s <span class="count">(%d)</span>',
__( 'Translations' ),
number_format_i18n( $updates_count )
);
?>
</h2>
<form method="post" action="<?php echo esc_url( $form_action ); ?>" name="upgrade-translations" class="upgrade">
<p><?php _e( 'New translations are available.' ); ?></p>
<p><?php _e( 'The following translation updates are available. Leave any translation updates unchecked if you want to install them later, then click &#8220;Update Translations&#8221;.' ); ?></p>
<p><?php _e( 'Translation updates you leave unchecked will remain available until you select them.' ); ?></p>
<?php wp_nonce_field( 'upgrade-translations' ); ?>
<p><input class="button" type="submit" value="<?php esc_attr_e( 'Update Translations' ); ?>" name="upgrade" /></p>
<p><input id="upgrade-translations" class="button" type="submit" value="<?php esc_attr_e( 'Update Translations' ); ?>" name="upgrade" /></p>
<table class="widefat updates-table" id="update-translations-table">
<thead>
<tr>
<td class="manage-column check-column"><input type="checkbox" id="translations-select-all" /></td>
<td class="manage-column"><label for="translations-select-all"><?php _e( 'Select All' ); ?></label></td>
</tr>
</thead>

<tbody class="plugins">
<?php foreach ( $translation_updates as $translation_update ) : ?>
<?php $checkbox_id = 'checkbox_' . md5( $translation_update['id'] ); ?>
<tr>
<td class="check-column">
<input type="hidden" name="translations[]" value="<?php echo esc_attr( $translation_update['id'] ); ?>" />
<input type="checkbox" name="checked[]" id="<?php echo esc_attr( $checkbox_id ); ?>" value="<?php echo esc_attr( $translation_update['id'] ); ?>" <?php checked( $translation_update['checked'] ); ?> />
<label for="<?php echo esc_attr( $checkbox_id ); ?>">
<span class="screen-reader-text">
<?php
printf(
/* translators: 1: Project name, 2: Language name or locale. */
esc_html__( 'Select the translation update for %1$s in %2$s' ),
esc_html( $translation_update['name'] ),
esc_html( $translation_update['language'] )
);
?>
</span>
</label>
</td>
<td class="plugin-title"><p>
<strong><?php echo esc_html( $translation_update['name'] ); ?></strong>
<?php
printf(
/* translators: 1: Language name or locale, 2: Version number. */
esc_html__( '%1$s translation is available for version %2$s.' ),
esc_html( $translation_update['language'] ),
esc_html( $translation_update['version'] )
);

if ( $translation_update['deferred'] ) {
echo ' ';
esc_html_e( 'This translation update will remain available until you select it.' );
}
?>
</p></td>
</tr>
<?php endforeach; ?>
</tbody>

<tfoot>
<tr>
<td class="manage-column check-column"><input type="checkbox" id="translations-select-all-2" /></td>
<td class="manage-column"><label for="translations-select-all-2"><?php _e( 'Select All' ); ?></label></td>
</tr>
</tfoot>
</table>
<p><input id="upgrade-translations-2" class="button" type="submit" value="<?php esc_attr_e( 'Update Translations' ); ?>" name="upgrade" /></p>
</form>
<?php
}
Expand Down Expand Up @@ -1002,7 +1068,7 @@ function do_undismiss_core_update() {
$updates_howto .= '<p>' . __( '<strong>Themes and Plugins</strong> &mdash; To update individual themes or plugins from this screen, use the checkboxes to make your selection, then <strong>click on the appropriate &#8220;Update&#8221; button</strong>. To update all of your themes or plugins at once, you can check the box at the top of the section to select all before clicking the update button.' ) . '</p>';

if ( 'en_US' !== get_locale() ) {
$updates_howto .= '<p>' . __( '<strong>Translations</strong> &mdash; The files translating WordPress into your language are updated for you whenever any other updates occur. But if these files are out of date, you can <strong>click the &#8220;Update Translations&#8221;</strong> button.' ) . '</p>';
$updates_howto .= '<p>' . __( '<strong>Translations</strong> &mdash; Translation updates are selected for installation by default. Leave any translation updates unchecked if you want to install them later, then <strong>click the &#8220;Update Translations&#8221;</strong> button. Translation updates you leave unchecked will remain available until you select them.' ) . '</p>';
}

get_current_screen()->add_help_tab(
Expand Down Expand Up @@ -1092,6 +1158,15 @@ function do_undismiss_core_update() {
}
}

if ( isset( $_GET['translation_updates'] ) && 'deferred' === $_GET['translation_updates'] ) {
wp_admin_notice(
__( 'The unchecked translation updates will remain available until you select them.' ),
array(
'type' => 'success',
)
);
}

$last_update_check = false;
$current = get_site_transient( 'update_core' );

Expand Down Expand Up @@ -1275,6 +1350,55 @@ function do_undismiss_core_update() {

check_admin_referer( 'upgrade-translations' );

if ( empty( $_POST['translations'] ) ) {
wp_redirect( self_admin_url( 'update-core.php' ) );
exit;
}

$translation_updates = wp_get_translation_updates_by_id();

$translation_update_ids = array_unique(
array_map(
'sanitize_text_field',
wp_unslash( (array) $_POST['translations'] )
)
);

$translation_updates = array_intersect_key( $translation_updates, array_flip( $translation_update_ids ) );

if ( empty( $translation_updates ) ) {
wp_redirect( self_admin_url( 'update-core.php' ) );
exit;
}

$selected_translation_updates = array();

if ( ! empty( $_POST['checked'] ) ) {
$selected_translation_update_ids = array_unique(
array_map(
'sanitize_text_field',
wp_unslash( (array) $_POST['checked'] )
)
);

$selected_translation_updates = array_intersect_key( $translation_updates, array_flip( $selected_translation_update_ids ) );
}

$current_translation_updates = wp_get_translation_updates_by_id();
$deferred_translation_updates = array_intersect_key(
$current_translation_updates,
wp_get_deferred_translation_updates( $current_translation_updates )
);
$deferred_translation_updates = array_diff_key( $deferred_translation_updates, $translation_updates );
$deferred_translation_updates += array_diff_key( $translation_updates, $selected_translation_updates );

wp_set_deferred_translation_updates( $deferred_translation_updates );

if ( empty( $selected_translation_updates ) ) {
wp_redirect( add_query_arg( 'translation_updates', 'deferred', self_admin_url( 'update-core.php' ) ) );
exit;
}

require_once ABSPATH . 'wp-admin/admin-header.php';
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';

Expand All @@ -1284,7 +1408,7 @@ function do_undismiss_core_update() {
$context = WP_LANG_DIR;

$upgrader = new Language_Pack_Upgrader( new Language_Pack_Upgrader_Skin( compact( 'url', 'nonce', 'title', 'context' ) ) );
$result = $upgrader->bulk_upgrade();
$result = $upgrader->bulk_upgrade( array_values( $selected_translation_updates ) );

wp_localize_script(
'updates',
Expand Down
Loading
Loading