Language packs: No WPLANG anymore.

* The WPLANG constant is no longer needed. Remove define('WPLANG', ''); from wp-config-sample.php. Populate WPLANG option based on the WPLANG constant. When get_option('WPLANG') is an empty string it will override WPLANG.
* Introduce translations_api() which is available to communicate with the translation API. Move translation install related functions to a new file.
* Replace mu_dropdown_languages() with wp_dropdown_languages(). wp_dropdown_languages() is now populated by the translation API.
* Remove wp_install_load_language() and allow load_default_textdomain() to switch a core translation.

fixes #13069, #15677, #19760, #28730, #29281. 
Built from https://develop.svn.wordpress.org/trunk@29630


git-svn-id: http://core.svn.wordpress.org/trunk@29404 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Dominik Schilling 2014-08-26 19:59:16 +00:00
parent 7586e15e0d
commit d544610681
10 changed files with 408 additions and 222 deletions

View File

@ -0,0 +1,206 @@
<?php
/**
* WordPress Translation Install Administration API
*
* @package WordPress
* @subpackage Administration
*/
/**
* Retrieve translations from WordPress Translation API.
*
* @since 4.0.0
*
* @param string $type Type of translations. Accepts 'plugins', 'themes', 'core'.
* @param array|object $args Translation API arguments. Optional.
* @return object|WP_Error On success an object of translations, WP_Error on failure.
*/
function translations_api( $type, $args = null ) {
include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
if ( ! in_array( $type, array( 'plugins', 'themes', 'core' ) ) ) {
return new WP_Error( 'invalid_type', __( 'Invalid translation type.' ) );
}
/**
* Allows a plugin to override the WordPress.org Translation Install API entirely.
*
* @since 4.0.0
*
* @param bool|array $result The result object. Default false.
* @param string $type The type of translations being requested.
* @param object $args Translation API arguments.
*/
$res = apply_filters( 'translations_api', false, $type, $args );
if ( false === $res ) {
$url = $http_url = 'http://api.wordpress.org/translations/' . $type . '/1.0/';
if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
$url = set_url_scheme( $url, 'https' );
}
$options = array(
'timeout' => 3,
'body' => array(
'wp_version' => $wp_version,
'locale' => get_locale(),
'version' => $args['version'], // Version of plugin, theme or core
),
);
if ( 'core' !== $type ) {
$options['body']['slug'] = $args['slug']; // Plugin or theme slug
}
$request = wp_remote_post( $url, $options );
if ( $ssl && is_wp_error( $request ) ) {
trigger_error( __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ) . ' ' . __( '(WordPress could not establish a secure connection to WordPress.org. Please contact your server administrator.)' ), headers_sent() || WP_DEBUG ? E_USER_WARNING : E_USER_NOTICE );
$request = wp_remote_post( $http_url, $options );
}
if ( is_wp_error( $request ) ) {
$res = new WP_Error( 'translations_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ), $request->get_error_message() );
} else {
$res = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! is_object( $res ) && ! is_array( $res ) ) {
$res = new WP_Error( 'translations_api_failed', __( 'An unexpected error occurred. Something may be wrong with WordPress.org or this server&#8217;s configuration. If you continue to have problems, please try the <a href="https://wordpress.org/support/">support forums</a>.' ), wp_remote_retrieve_body( $request ) );
}
}
}
/**
* Filter the Translation Install API response results.
*
* @since 4.0.0
*
* @param object|WP_Error $res Response object or WP_Error.
* @param string $type The type of translations being requested.
* @param object $args Translation API arguments.
*/
return apply_filters( 'translations_api_result', $res, $type, $args );
}
/**
* Get available translations from the WordPress.org API.
*
* @since 4.0.0
*
* @see translations_api()
*
* @return array Array of translations, each an array of data. If the API response results
* in an error, an empty array will be returned.
*/
function wp_get_available_translations() {
if ( ! defined( 'WP_INSTALLING' ) && false !== ( $translations = get_site_transient( 'available_translations' ) ) ) {
return $translations;
}
include( ABSPATH . WPINC . '/version.php' ); // include an unmodified $wp_version
$api = translations_api( 'core', array( 'version' => $wp_version ) );
if ( is_wp_error( $api ) || empty( $api['translations'] ) ) {
return array();
}
$translations = array();
// Key the array with the language code for now.
foreach ( $api['translations'] as $translation ) {
$translations[ $translation['language'] ] = $translation;
}
if ( ! defined( 'WP_INSTALLING' ) ) {
set_site_transient( 'available_translations', $translations, 3 * HOUR_IN_SECONDS );
}
return $translations;
}
/**
* Output the select form for the language selection on the installation screen.
*
* @since 4.0.0
*
* @param array $languages Array of available languages (populated via the Translation API).
*/
function wp_install_language_form( $languages ) {
global $wp_local_package;
$installed_languages = get_available_languages();
echo "<label class='screen-reader-text' for='language'>Select a default language</label>\n";
echo "<select size='14' name='language' id='language'>\n";
echo '<option value="" lang="en" selected="selected" data-continue="Continue" data-installed="1">English (United States)</option>';
echo "\n";
if ( ! empty( $wp_local_package ) && isset( $languages[ $wp_local_package ] ) ) {
if ( isset( $languages[ $wp_local_package ] ) ) {
$language = $languages[ $wp_local_package ];
echo '<option value="' . esc_attr( $language['language'] ) . '" lang="' . esc_attr( $language['iso'][1] ) . '">' . esc_html( $language['native_name'] ) . "</option>\n";
unset( $languages[ $wp_local_package ] );
}
}
foreach ( $languages as $language ) {
printf( '<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . "\n",
esc_attr( $language['language'] ),
esc_attr( $language['iso'][1] ),
esc_attr( $language['strings']['continue'] ),
in_array( $language['language'], $installed_languages ) ? ' data-installed="1"' : '',
esc_html( $language['native_name'] ) );
}
echo "</select>\n";
echo '<p class="step"><span class="spinner"></span><input id="language-continue" type="submit" class="button button-primary button-large" value="Continue" /></p>';
}
/**
* Download a language pack.
*
* @since 4.0.0
*
* @see wp_get_available_translations()
*
* @param string $download Language code to download.
* @return string|bool Returns the language code if successfully downloaded
* (or already installed), or false on failure.
*/
function wp_download_language_pack( $download ) {
// Check if the translation is already installed.
if ( in_array( $download, get_available_languages() ) ) {
return $download;
}
if ( defined( 'DISALLOW_FILE_MODS' ) && DISALLOW_FILE_MODS ) {
return false;
}
// Confirm the translation is one we can download.
$translations = wp_get_available_translations();
if ( ! $translations ) {
return false;
}
foreach ( $translations as $translation ) {
if ( $translation['language'] === $download ) {
$translation_to_load = true;
break;
}
}
if ( empty( $translation_to_load ) ) {
return false;
}
$translation = (object) $translation;
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$skin = new Automatic_Upgrader_Skin;
$upgrader = new Language_Pack_Upgrader( $skin );
$translation->type = 'core';
/**
* @todo failures (such as non-direct FS)
*/
$result = $upgrader->upgrade( $translation, array( 'clear_update_cache' => false ) );
return $translation->language;
}

View File

@ -437,6 +437,9 @@ function upgrade_all() {
if ( $wp_current_db_version < 26691 ) if ( $wp_current_db_version < 26691 )
upgrade_380(); upgrade_380();
if ( $wp_current_db_version < 29630 )
upgrade_400();
maybe_disable_link_manager(); maybe_disable_link_manager();
maybe_disable_automattic_widgets(); maybe_disable_automattic_widgets();
@ -1304,6 +1307,25 @@ function upgrade_380() {
deactivate_plugins( array( 'mp6/mp6.php' ), true ); deactivate_plugins( array( 'mp6/mp6.php' ), true );
} }
} }
/**
* Execute changes made in WordPress 4.0.0.
*
* @since 4.0.0
*/
function upgrade_400() {
global $wp_current_db_version;
if ( $wp_current_db_version < 29630 ) {
if ( ! is_multisite() && false === get_option( 'WPLANG' ) ) {
if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && in_array( WPLANG, get_available_languages() ) ) {
update_option( 'WPLANG', WPLANG );
} else {
update_option( 'WPLANG', '' );
}
}
}
}
/** /**
* Execute network level changes * Execute network level changes
* *
@ -2192,145 +2214,3 @@ CREATE TABLE $wpdb->sitecategories (
dbDelta( $ms_queries ); dbDelta( $ms_queries );
} }
endif; endif;
/**
* Output the input fields for the language selection form on the installation screen.
*
* @since 4.0.0
*
* @see wp_get_available_translations_from_api()
*
* @param array $languages Array of available languages (populated via the Translations API).
*/
function wp_install_language_form( $languages ) {
$installed_languages = get_available_languages();
echo "<label class='screen-reader-text' for='language'>Select a default language</label>\n";
echo "<select size='14' name='language' id='language'>\n";
echo '<option value="" lang="en" selected="selected" data-continue="Continue" data-installed="1">English (United States)</option>';
echo "\n";
if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && ( 'en_US' !== WPLANG ) ) {
if ( isset( $languages[ WPLANG ] ) ) {
$language = $languages[ WPLANG ];
echo '<option value="' . esc_attr( $language['language'] ) . '" lang="' . esc_attr( $language['iso'][1] ) . '">' . esc_html( $language['native_name'] ) . "</option>\n";
}
}
foreach ( $languages as $language ) {
printf( '<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . "\n",
esc_attr( $language['language'] ),
esc_attr( $language['iso'][1] ),
esc_attr( $language['strings']['continue'] ),
in_array( $language['language'], $installed_languages ) ? ' data-installed="1"' : '',
esc_html( $language['native_name'] ) );
}
echo "</select>\n";
echo '<p class="step"><span class="spinner"></span><input id="language-continue" type="submit" class="button button-primary button-large" value="Continue" /></p>';
}
/**
* Get available translations from the WordPress.org API.
*
* @since 4.0.0
*
* @see wp_remote_post()
*
* @return array Array of translations, each an array of data.
*/
function wp_get_available_translations_from_api() {
$url = 'http://api.wordpress.org/translations/core/1.0/';
if ( wp_http_supports( array( 'ssl' ) ) ) {
$url = set_url_scheme( $url, 'https' );
}
$options = array(
'timeout' => 3,
'body' => array( 'version' => $GLOBALS['wp_version'] ),
);
$response = wp_remote_post( $url, $options );
$body = wp_remote_retrieve_body( $response );
if ( $body && $body = json_decode( $body, true ) ) {
$translations = array();
// Key the array with the language code for now
foreach ( $body['translations'] as $translation ) {
$translations[ $translation['language'] ] = $translation;
}
return $translations;
}
return false;
}
/**
* Download a language pack.
*
* @since 4.0.0
*
* @see wp_get_available_translations_from_api()
*
* @param string $download Language code to download.
* @return string|bool Returns the language code if successfully downloaded
* (or already installed), or false on failure.
*/
function wp_install_download_language_pack( $download ) {
// Check if the translation is already installed.
if ( in_array( $download, get_available_languages() ) ) {
return $download;
}
// Confirm the translation is one we can download.
$translations = wp_get_available_translations_from_api();
if ( ! $translations ) {
return false;
}
foreach ( $translations as $translation ) {
if ( $translation['language'] === $download ) {
$translation_to_load = true;
break;
}
}
if ( empty( $translation_to_load ) ) {
return false;
}
$translation = (object) $translation;
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
$skin = new Automatic_Upgrader_Skin;
$upgrader = new Language_Pack_Upgrader( $skin );
$translation->type = 'core';
/**
* @todo failures (such as non-direct FS)
*/
$upgrader->upgrade( $translation, array( 'clear_update_cache' => false ) );
return $translation->language;
}
/**
* Load a translation during the install process.
*
* @since 4.0.0
*
* @see load_textdomain()
*
* @param string $translation Translation to load.
* @return string|bool Returns the language code if successfully loaded,
* or false on failure.
*/
function wp_install_load_language( $translation ) {
if ( ! empty( $translation ) ) {
if ( in_array( $translation, get_available_languages() ) ) {
$translation_to_load = $translation;
}
}
if ( empty( $translation_to_load ) ) {
return false;
}
unload_textdomain( 'default' ); // Start over.
load_textdomain( 'default', WP_LANG_DIR . "/{$translation_to_load}.mo" );
load_textdomain( 'default', WP_LANG_DIR . "/admin-{$translation_to_load}.mo" );
return $translation_to_load;
}

View File

@ -38,6 +38,9 @@ require_once( dirname( dirname( __FILE__ ) ) . '/wp-load.php' );
/** Load WordPress Administration Upgrade API */ /** Load WordPress Administration Upgrade API */
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' ); require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
/** Load WordPress Translation Install API */
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
/** Load wpdb */ /** Load wpdb */
require_once( ABSPATH . WPINC . '/wp-db.php' ); require_once( ABSPATH . WPINC . '/wp-db.php' );
@ -178,10 +181,15 @@ if ( ! is_string( $wpdb->base_prefix ) || '' === $wpdb->base_prefix ) {
die( '<h1>' . __( 'Configuration Error' ) . '</h1><p>' . __( 'Your <code>wp-config.php</code> file has an empty database table prefix, which is not supported.' ) . '</p></body></html>' ); die( '<h1>' . __( 'Configuration Error' ) . '</h1><p>' . __( 'Your <code>wp-config.php</code> file has an empty database table prefix, which is not supported.' ) . '</p></body></html>' );
} }
$langugage = '';
if ( ! empty( $_REQUEST['language'] ) ) {
$langugage = preg_replace( '/[^a-zA-Z_]/', '', $_REQUEST['language'] );
}
switch($step) { switch($step) {
case 0: // Step 0 case 0: // Step 0
if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations_from_api() ) ) { if ( empty( $langugage ) && ( $languages = wp_get_available_translations() ) ) {
display_header( 'language-chooser' ); display_header( 'language-chooser' );
echo '<form id="setup" method="post" action="?step=1">'; echo '<form id="setup" method="post" action="?step=1">';
wp_install_language_form( $languages ); wp_install_language_form( $languages );
@ -192,10 +200,10 @@ switch($step) {
// Deliberately fall through if we can't reach the translations API. // Deliberately fall through if we can't reach the translations API.
case 1: // Step 1, direct link or from language chooser. case 1: // Step 1, direct link or from language chooser.
if ( ! empty( $_REQUEST['language'] ) ) { if ( ! empty( $langugage ) ) {
$loaded_language = wp_install_download_language_pack( $_REQUEST['language'] ); $loaded_language = wp_download_language_pack( $langugage );
if ( $loaded_language ) { if ( $loaded_language ) {
wp_install_load_language( $loaded_language ); load_default_textdomain( $loaded_language );
} }
} }
@ -211,8 +219,8 @@ switch($step) {
display_setup_form(); display_setup_form();
break; break;
case 2: case 2:
if ( !empty( $_REQUEST['language'] ) ) { if ( ! empty( $langugage ) && load_default_textdomain( $langugage ) ) {
$loaded_language = wp_install_load_language( $_REQUEST['language'] ); $loaded_language = $langugage;
} else { } else {
$loaded_language = 'en_US'; $loaded_language = 'en_US';
} }

View File

@ -273,25 +273,34 @@ if ( isset( $_GET['updated'] ) ) {
</tr> </tr>
</table> </table>
<?php <?php
$languages = get_available_languages(); $languages = get_available_languages();
if ( ! empty( $languages ) ) { if ( ! empty( $languages ) ) {
$lang = get_site_option( 'WPLANG' ); ?>
?>
<h3><?php _e( 'Language Settings' ); ?></h3> <h3><?php _e( 'Language Settings' ); ?></h3>
<table class="form-table"> <table class="form-table">
<tr> <tr>
<th><label for="WPLANG"><?php _e( 'Default Language' ); ?></label></th> <th><label for="WPLANG"><?php _e( 'Default Language' ); ?></label></th>
<td> <td>
<select name="WPLANG" id="WPLANG"> <?php
<?php mu_dropdown_languages( $languages, get_site_option( 'WPLANG' ) ); ?> $lang = get_site_option( 'WPLANG' );
</select> if ( ! in_array( $lang, $languages ) ) {
$lang = '';
}
wp_dropdown_languages( array(
'name' => 'WPLANG',
'id' => 'WPLANG',
'selected' => $lang,
'languages' => $languages,
) );
?>
</td> </td>
</tr> </tr>
</table> </table>
<?php <?php
} // languages }
?> ?>
<h3><?php _e( 'Menu Settings' ); ?></h3> <h3><?php _e( 'Menu Settings' ); ?></h3>
<table id="menu" class="form-table"> <table id="menu" class="form-table">

View File

@ -302,23 +302,43 @@ endfor;
</select></td> </select></td>
</tr> </tr>
<?php do_settings_fields('general', 'default'); ?> <?php do_settings_fields('general', 'default'); ?>
<?php <?php
$languages = get_available_languages(); $languages = get_available_languages();
if ( $languages ) : if ( ! empty( $languages ) ) {
?> ?>
<tr> <tr>
<th width="33%" scope="row"><label for="WPLANG"><?php _e('Site Language') ?></label></th> <th width="33%" scope="row"><label for="WPLANG"><?php _e( 'Site Language' ); ?></label></th>
<td> <td>
<?php wp_dropdown_languages( array( <?php
$locale = get_locale();
if ( ! in_array( $locale, $languages ) ) {
$locale = '';
}
wp_dropdown_languages( array(
'name' => 'WPLANG', 'name' => 'WPLANG',
'id' => 'WPLANG', 'id' => 'WPLANG',
'selected' => get_option( 'WPLANG' ), 'selected' => $locale,
'languages' => $languages, 'languages' => $languages,
) ); ?> ) );
// Add note about deprecated WPLANG constant.
if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && $locale !== WPLANG ) {
if ( is_super_admin() ) {
?>
<p class="description">
<strong><?php _e( 'Note:' ); ?></strong> <?php printf( __( 'The %s constant in your %s file is no longer needed.' ), '<code>WPLANG</code>', '<code>wp-config.php</code>' ); ?>
</p>
<?php
}
_deprecated_argument( 'define()', '4.0', sprintf( __( 'The %s constant in your %s file is no longer needed.' ), 'WPLANG', 'wp-config.php' ) );
}
?>
</td> </td>
</tr> </tr>
<?php <?php
endif; }
?> ?>
</table> </table>

View File

@ -151,7 +151,7 @@ if ( 'update' == $action ) {
$options = $whitelist_options[ $option_page ]; $options = $whitelist_options[ $option_page ];
} }
// Handle custom date/time formats // Handle custom date/time formats.
if ( 'general' == $option_page ) { if ( 'general' == $option_page ) {
if ( !empty($_POST['date_format']) && isset($_POST['date_format_custom']) && '\c\u\s\t\o\m' == wp_unslash( $_POST['date_format'] ) ) if ( !empty($_POST['date_format']) && isset($_POST['date_format_custom']) && '\c\u\s\t\o\m' == wp_unslash( $_POST['date_format'] ) )
$_POST['date_format'] = $_POST['date_format_custom']; $_POST['date_format'] = $_POST['date_format_custom'];
@ -180,6 +180,14 @@ if ( 'update' == $action ) {
} }
update_option( $option, $value ); update_option( $option, $value );
} }
// Switch translation in case WPLANG was changed.
$language = get_option( 'WPLANG' );
if ( $language ) {
load_default_textdomain( $language );
} else {
unload_textdomain( 'default' );
}
} }
/** /**

View File

@ -32,7 +32,11 @@ define( 'ABSPATH', dirname( dirname( __FILE__ ) ) . '/' );
require( ABSPATH . 'wp-settings.php' ); require( ABSPATH . 'wp-settings.php' );
require( ABSPATH . 'wp-admin/includes/upgrade.php' ); /** Load WordPress Administration Upgrade API */
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
/** Load WordPress Translation Install API */
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
nocache_headers(); nocache_headers();
@ -85,10 +89,13 @@ function setup_config_display_header( $body_classes = array() ) {
<?php <?php
} // end function setup_config_display_header(); } // end function setup_config_display_header();
$language = '';
if ( ! empty( $_REQUEST['language'] ) ) {
$language = preg_replace( '/[^a-zA-Z_]/', '', $_REQUEST['language'] );
}
switch($step) { switch($step) {
case -1: case -1:
if ( empty( $language ) && ( $languages = wp_get_available_translations() ) ) {
if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations_from_api() ) ) {
setup_config_display_header( 'language-chooser' ); setup_config_display_header( 'language-chooser' );
echo '<form id="setup" method="post" action="?step=0">'; echo '<form id="setup" method="post" action="?step=0">';
wp_install_language_form( $languages ); wp_install_language_form( $languages );
@ -99,10 +106,10 @@ switch($step) {
// Deliberately fall through if we can't reach the translations API. // Deliberately fall through if we can't reach the translations API.
case 0: case 0:
if ( ! empty( $_REQUEST['language'] ) ) { if ( ! empty( $language ) ) {
$loaded_language = wp_install_download_language_pack( $_REQUEST['language'] ); $loaded_language = wp_download_language_pack( $language );
if ( $loaded_language ) { if ( $loaded_language ) {
wp_install_load_language( $loaded_language ); load_default_textdomain( $loaded_language );
} }
} }
@ -136,7 +143,7 @@ switch($step) {
break; break;
case 1: case 1:
$loaded_language = wp_install_load_language( $_REQUEST['language'] ); load_default_textdomain( $language );
setup_config_display_header(); setup_config_display_header();
?> ?>
<form method="post" action="setup-config.php?step=2"> <form method="post" action="setup-config.php?step=2">
@ -169,14 +176,14 @@ switch($step) {
</tr> </tr>
</table> </table>
<?php if ( isset( $_GET['noapi'] ) ) { ?><input name="noapi" type="hidden" value="1" /><?php } ?> <?php if ( isset( $_GET['noapi'] ) ) { ?><input name="noapi" type="hidden" value="1" /><?php } ?>
<input type="hidden" name="language" value="<?php echo esc_attr( $loaded_language ); ?>" /> <input type="hidden" name="language" value="<?php echo esc_attr( $language ); ?>" />
<p class="step"><input name="submit" type="submit" value="<?php echo htmlspecialchars( __( 'Submit' ), ENT_QUOTES ); ?>" class="button button-large" /></p> <p class="step"><input name="submit" type="submit" value="<?php echo htmlspecialchars( __( 'Submit' ), ENT_QUOTES ); ?>" class="button button-large" /></p>
</form> </form>
<?php <?php
break; break;
case 2: case 2:
$loaded_language = wp_install_load_language( $_REQUEST['language'] ); load_default_textdomain( $language );
$dbname = trim( wp_unslash( $_POST[ 'dbname' ] ) ); $dbname = trim( wp_unslash( $_POST[ 'dbname' ] ) );
$uname = trim( wp_unslash( $_POST[ 'uname' ] ) ); $uname = trim( wp_unslash( $_POST[ 'uname' ] ) );
$pwd = trim( wp_unslash( $_POST[ 'pwd' ] ) ); $pwd = trim( wp_unslash( $_POST[ 'pwd' ] ) );
@ -189,9 +196,9 @@ switch($step) {
$step_1 .= '&amp;noapi'; $step_1 .= '&amp;noapi';
} }
if ( $loaded_language ) { if ( ! empty( $language ) ) {
$step_1 .= '&amp;language=' . $loaded_language; $step_1 .= '&amp;language=' . $language;
$install .= '?language=' . $loaded_language; $install .= '?language=' . $language;
} else { } else {
$install .= '?language=en_US'; $install .= '?language=en_US';
} }

View File

@ -61,16 +61,6 @@ define('NONCE_SALT', 'put your unique phrase here');
*/ */
$table_prefix = 'wp_'; $table_prefix = 'wp_';
/**
* WordPress Localized Language, defaults to English.
*
* Change this to localize WordPress. A corresponding MO file for the chosen
* language must be installed to wp-content/languages. For example, install
* de_DE.mo to wp-content/languages and set WPLANG to 'de_DE' to enable German
* language support.
*/
define('WPLANG', '');
/** /**
* For developers: WordPress debugging mode. * For developers: WordPress debugging mode.
* *

View File

@ -24,7 +24,7 @@
* @return string The locale of the blog or from the 'locale' hook. * @return string The locale of the blog or from the 'locale' hook.
*/ */
function get_locale() { function get_locale() {
global $locale; global $locale, $wp_local_package;
if ( isset( $locale ) ) { if ( isset( $locale ) ) {
/** /**
@ -37,27 +37,35 @@ function get_locale() {
return apply_filters( 'locale', $locale ); return apply_filters( 'locale', $locale );
} }
// WPLANG is defined in wp-config. if ( isset( $wp_local_package ) ) {
if ( defined( 'WPLANG' ) ) $locale = $wp_local_package;
}
// WPLANG was defined in wp-config.
if ( defined( 'WPLANG' ) ) {
$locale = WPLANG; $locale = WPLANG;
}
// If multisite, check options. // If multisite, check options.
if ( is_multisite() ) { if ( is_multisite() ) {
// Don't check blog option when installing. // Don't check blog option when installing.
if ( defined( 'WP_INSTALLING' ) || ( false === $ms_locale = get_option( 'WPLANG' ) ) ) if ( defined( 'WP_INSTALLING' ) || ( false === $ms_locale = get_option( 'WPLANG' ) ) ) {
$ms_locale = get_site_option('WPLANG'); $ms_locale = get_site_option( 'WPLANG' );
}
if ( $ms_locale !== false ) if ( $ms_locale !== false ) {
$locale = $ms_locale; $locale = $ms_locale;
} elseif ( ! defined( 'WP_INSTALLING' ) ) { }
} else {
$db_locale = get_option( 'WPLANG' ); $db_locale = get_option( 'WPLANG' );
if ( $db_locale ) { if ( $db_locale !== false ) {
$locale = $db_locale; $locale = $db_locale;
} }
} }
if ( empty( $locale ) ) if ( empty( $locale ) ) {
$locale = 'en_US'; $locale = 'en_US';
}
/** This filter is documented in wp-includes/l10n.php */ /** This filter is documented in wp-includes/l10n.php */
return apply_filters( 'locale', $locale ); return apply_filters( 'locale', $locale );
@ -523,23 +531,32 @@ function unload_textdomain( $domain ) {
* @see load_textdomain() * @see load_textdomain()
* *
* @since 1.5.0 * @since 1.5.0
*
* @param string $locale Optional. Locale to load. Defaults to get_locale().
*/ */
function load_default_textdomain() { function load_default_textdomain( $locale = null ) {
if ( null === $locale ) {
$locale = get_locale(); $locale = get_locale();
}
load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo" ); // Unload previously loaded strings so we can switch translations.
unload_textdomain( 'default' );
$return = load_textdomain( 'default', WP_LANG_DIR . "/$locale.mo" );
if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) { if ( ( is_multisite() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) && ! file_exists( WP_LANG_DIR . "/admin-$locale.mo" ) ) {
load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" ); load_textdomain( 'default', WP_LANG_DIR . "/ms-$locale.mo" );
return; return $return;
} }
if ( is_admin() || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) if ( is_admin() || defined( 'WP_INSTALLING' ) || ( defined( 'WP_REPAIRING' ) && WP_REPAIRING ) ) {
load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" ); load_textdomain( 'default', WP_LANG_DIR . "/admin-$locale.mo" );
}
if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) ) if ( is_network_admin() || ( defined( 'WP_INSTALLING_NETWORK' ) && WP_INSTALLING_NETWORK ) )
load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" ); load_textdomain( 'default', WP_LANG_DIR . "/admin-network-$locale.mo" );
return $return;
} }
/** /**
@ -818,26 +835,67 @@ function wp_get_pomo_file_data( $po_file ) {
} }
/** /**
* Language selector. More to come. * Language selector.
* *
* @since 4.0.0 * @since 4.0.0
* *
* @see get_available_languages() * @see get_available_languages()
* @see wp_get_available_translations()
* *
* @param array $args Optional arguments. Default empty array. * @param array $args Optional arguments. Default empty array.
*/ */
function wp_dropdown_languages( $args = array() ) { function wp_dropdown_languages( $args = array() ) {
if ( isset( $args['languages'] ) ) { require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
$languages = $args['languages'];
$args = wp_parse_args( $args, array(
'id' => '',
'name' => '',
'languages' => array(),
'selected' => ''
) );
if ( empty( $args['languages'] ) ) {
return false;
}
$translations = wp_get_available_translations();
/*
* $args['languages'] should only contain the locales. Find the locale in
* $translations to get the native name. Fall back to locale.
*/
$languages = array();
foreach ( $args['languages'] as $locale ) {
if ( isset( $translations[ $locale ] ) ) {
$translation = $translations[ $locale ];
$languages[] = array(
'language' => $translation['language'],
'native_name' => $translation['native_name'],
'lang' => $translation['iso'][1],
);
} else { } else {
$languages = get_available_languages(); $languages[] = array(
'language' => $locale,
'native_name' => $locale,
'lang' => '',
);
}
} }
printf( '<select name="%s" id="%s">', esc_attr( $args['name'] ), esc_attr( $args['id'] ) ); printf( '<select name="%s" id="%s">', esc_attr( $args['name'] ), esc_attr( $args['id'] ) );
echo '<option value="">en_US</option>';
// List installed languages.
echo '<option value="" lang="en">English (United States)</option>';
foreach ( $languages as $language ) { foreach ( $languages as $language ) {
$selected = selected( $language, $args['selected'], false ); $selected = selected( $language['language'], $args['selected'], false );
echo '<option value="' . esc_attr( $language ) .'"' . $selected . '>' . $language . '</option>'; printf(
'<option value="%s" lang="%s"%s>%s</option>',
esc_attr( $language['language'] ),
esc_attr( $language['lang'] ),
$selected,
esc_html( $language['native_name'] )
);
} }
echo '</select>'; echo '</select>';
} }

View File

@ -11,7 +11,7 @@ $wp_version = '4.0-beta4-20140826';
* *
* @global int $wp_db_version * @global int $wp_db_version
*/ */
$wp_db_version = 29188; $wp_db_version = 29630;
/** /**
* Holds the TinyMCE version * Holds the TinyMCE version