diff --git a/wp-admin/includes/translation-install.php b/wp-admin/includes/translation-install.php new file mode 100644 index 0000000000..a618c848cc --- /dev/null +++ b/wp-admin/includes/translation-install.php @@ -0,0 +1,206 @@ + 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’s configuration. If you continue to have problems, please try the support forums.' ) . ' ' . __( '(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’s configuration. If you continue to have problems, please try the support forums.' ), $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’s configuration. If you continue to have problems, please try the support forums.' ), 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 "\n"; + echo "\n"; + echo '

'; +} + +/** + * 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; +} diff --git a/wp-admin/includes/upgrade.php b/wp-admin/includes/upgrade.php index a455841106..02dfe093d3 100644 --- a/wp-admin/includes/upgrade.php +++ b/wp-admin/includes/upgrade.php @@ -437,6 +437,9 @@ function upgrade_all() { if ( $wp_current_db_version < 26691 ) upgrade_380(); + if ( $wp_current_db_version < 29630 ) + upgrade_400(); + maybe_disable_link_manager(); maybe_disable_automattic_widgets(); @@ -1304,6 +1307,25 @@ function upgrade_380() { 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 * @@ -1419,7 +1441,7 @@ function upgrade_network() { */ function maybe_create_table($table_name, $create_ddl) { global $wpdb; - + $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) ); if ( $wpdb->get_var( $query ) == $table_name ) { @@ -2192,145 +2214,3 @@ CREATE TABLE $wpdb->sitecategories ( dbDelta( $ms_queries ); } 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 "\n"; - echo "\n"; - echo '

'; -} - -/** - * 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; -} diff --git a/wp-admin/install.php b/wp-admin/install.php index f857a0362e..daddaafd51 100644 --- a/wp-admin/install.php +++ b/wp-admin/install.php @@ -38,6 +38,9 @@ require_once( dirname( dirname( __FILE__ ) ) . '/wp-load.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' ); + /** Load wpdb */ require_once( ABSPATH . WPINC . '/wp-db.php' ); @@ -178,10 +181,15 @@ if ( ! is_string( $wpdb->base_prefix ) || '' === $wpdb->base_prefix ) { die( '

' . __( 'Configuration Error' ) . '

' . __( 'Your wp-config.php file has an empty database table prefix, which is not supported.' ) . '

' ); } +$langugage = ''; +if ( ! empty( $_REQUEST['language'] ) ) { + $langugage = preg_replace( '/[^a-zA-Z_]/', '', $_REQUEST['language'] ); +} + switch($step) { 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' ); echo '
'; wp_install_language_form( $languages ); @@ -192,10 +200,10 @@ switch($step) { // Deliberately fall through if we can't reach the translations API. case 1: // Step 1, direct link or from language chooser. - if ( ! empty( $_REQUEST['language'] ) ) { - $loaded_language = wp_install_download_language_pack( $_REQUEST['language'] ); + if ( ! empty( $langugage ) ) { + $loaded_language = wp_download_language_pack( $langugage ); if ( $loaded_language ) { - wp_install_load_language( $loaded_language ); + load_default_textdomain( $loaded_language ); } } @@ -211,8 +219,8 @@ switch($step) { display_setup_form(); break; case 2: - if ( !empty( $_REQUEST['language'] ) ) { - $loaded_language = wp_install_load_language( $_REQUEST['language'] ); + if ( ! empty( $langugage ) && load_default_textdomain( $langugage ) ) { + $loaded_language = $langugage; } else { $loaded_language = 'en_US'; } @@ -226,8 +234,8 @@ switch($step) { $user_name = isset($_POST['user_name']) ? trim( wp_unslash( $_POST['user_name'] ) ) : ''; $admin_password = isset($_POST['admin_password']) ? wp_unslash( $_POST['admin_password'] ) : ''; $admin_password_check = isset($_POST['admin_password2']) ? wp_unslash( $_POST['admin_password2'] ) : ''; - $admin_email = isset( $_POST['admin_email'] ) ?trim( wp_unslash( $_POST['admin_email'] ) ) : ''; - $public = isset( $_POST['blog_public'] ) ? (int) $_POST['blog_public'] : 0; + $admin_email = isset( $_POST['admin_email'] ) ?trim( wp_unslash( $_POST['admin_email'] ) ) : ''; + $public = isset( $_POST['blog_public'] ) ? (int) $_POST['blog_public'] : 0; // Check e-mail address. $error = false; diff --git a/wp-admin/network/settings.php b/wp-admin/network/settings.php index 663220ccf7..6349e8cdd0 100644 --- a/wp-admin/network/settings.php +++ b/wp-admin/network/settings.php @@ -102,7 +102,7 @@ if ( isset( $_GET['updated'] ) ) {

-

+

@@ -165,7 +165,7 @@ if ( isset( $_GET['updated'] ) ) {

-

+

@@ -231,7 +231,7 @@ if ( isset( $_GET['updated'] ) ) {

-

+

@@ -273,25 +273,34 @@ if ( isset( $_GET['updated'] ) ) { - -

- + ?> +

+
-
- + 'WPLANG', + 'id' => 'WPLANG', + 'selected' => $lang, + 'languages' => $languages, + ) ); + ?>
- + +

@@ -324,7 +333,7 @@ if ( isset( $_GET['updated'] ) ) { - + +$languages = get_available_languages(); +if ( ! empty( $languages ) ) { + ?> - + - 'WPLANG', 'id' => 'WPLANG', - 'selected' => get_option( 'WPLANG' ), + 'selected' => $locale, 'languages' => $languages, - ) ); ?> + ) ); + + // Add note about deprecated WPLANG constant. + if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && $locale !== WPLANG ) { + if ( is_super_admin() ) { + ?> +

+ WPLANG', 'wp-config.php' ); ?> +

+ - diff --git a/wp-admin/options.php b/wp-admin/options.php index ef4ab7abb2..29a9344694 100644 --- a/wp-admin/options.php +++ b/wp-admin/options.php @@ -151,7 +151,7 @@ if ( 'update' == $action ) { $options = $whitelist_options[ $option_page ]; } - // Handle custom date/time formats + // Handle custom date/time formats. 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'] ) ) $_POST['date_format'] = $_POST['date_format_custom']; @@ -180,6 +180,14 @@ if ( 'update' == $action ) { } 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' ); + } } /** diff --git a/wp-admin/setup-config.php b/wp-admin/setup-config.php index 3ca3059d7c..8c75c2bf9b 100644 --- a/wp-admin/setup-config.php +++ b/wp-admin/setup-config.php @@ -32,7 +32,11 @@ define( 'ABSPATH', dirname( dirname( __FILE__ ) ) . '/' ); 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(); @@ -85,10 +89,13 @@ function setup_config_display_header( $body_classes = array() ) { '; wp_install_language_form( $languages ); @@ -99,10 +106,10 @@ switch($step) { // Deliberately fall through if we can't reach the translations API. case 0: - if ( ! empty( $_REQUEST['language'] ) ) { - $loaded_language = wp_install_download_language_pack( $_REQUEST['language'] ); + if ( ! empty( $language ) ) { + $loaded_language = wp_download_language_pack( $language ); if ( $loaded_language ) { - wp_install_load_language( $loaded_language ); + load_default_textdomain( $loaded_language ); } } @@ -136,7 +143,7 @@ switch($step) { break; case 1: - $loaded_language = wp_install_load_language( $_REQUEST['language'] ); + load_default_textdomain( $language ); setup_config_display_header(); ?> @@ -169,14 +176,14 @@ switch($step) { - +

'', + '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 { + $languages[] = array( + 'language' => $locale, + 'native_name' => $locale, + 'lang' => '', + ); + } } printf( ''; } diff --git a/wp-includes/version.php b/wp-includes/version.php index 85d021ed37..119c4d0066 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -11,7 +11,7 @@ $wp_version = '4.0-beta4-20140826'; * * @global int $wp_db_version */ -$wp_db_version = 29188; +$wp_db_version = 29630; /** * Holds the TinyMCE version