WordPress.org

Make WordPress Core

Ticket #15677: 15677.2.patch

File 15677.2.patch, 20.0 KB (added by ocean90, 7 years ago)
  • src/wp-admin/includes/translation-install.php

     
     1<?php
     2/**
     3 * WordPress Translation Install Administration API
     4 *
     5 * @package WordPress
     6 * @subpackage Administration
     7 */
     8
     9
     10/**
     11 * Retrieve translations from WordPress Plugins API.
     12 *
     13 * @since 4.0.0
     14 *
     15 * @param string       $type Type of translations. Accepts 'plugins', 'themes', 'core'.
     16 * @param array|object $args Translation API arguments. Optional.
     17 *
     18 * @return object|WP_Error On success an object of translations, WP_Error on failure.
     19 */
     20function translations_api( $type, $args = null ) {
     21        if ( ! in_array( $type, array( 'plugins', 'themes', 'core' ) ) ) {
     22                return  new WP_Error( 'invalid_type', __( 'Invalid translation type.' ) );
     23        }
     24
     25        /**
     26         * Allows a plugin to override the WordPress.org Translation Install API entirely.
     27         *
     28         * @since 4.0.0
     29         *
     30         * @param bool|array  $result The result object. Default false.
     31         * @param string      $type   The type of translations being requested.
     32         * @param object      $args   Translation API arguments.
     33         */
     34        $res = apply_filters( 'translations_api', false, $action, $args );
     35
     36        if ( false === $res ) {
     37                $url = 'http://api.wordpress.org/translations/' . $type . '/1.0/';
     38                if ( $ssl = wp_http_supports( array( 'ssl' ) ) ) {
     39                        $url = set_url_scheme( $url, 'https' );
     40                }
     41
     42                $options = array(
     43                        'timeout' => 3,
     44                        'body' => array(
     45                                'version' => $GLOBALS['wp_version'],
     46                                'request' => json_encode( $args ) // @TODO
     47                        ),
     48                );
     49
     50                $request = wp_remote_post( $url, $options );
     51
     52                if ( $ssl && is_wp_error( $request ) ) {
     53                        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 );
     54
     55                        $request = wp_remote_post( $http_url, $args );
     56                }
     57
     58                if ( is_wp_error( $request ) ) {
     59                        $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() );
     60                } else {
     61                        $res = json_decode( wp_remote_retrieve_body( $request ), true );
     62                        if ( ! is_object( $res ) && ! is_array( $res ) ) {
     63                                $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 ) );
     64                        }
     65                }
     66        }
     67
     68        /**
     69         * Filter the Translation Install API response results.
     70         *
     71         * @since 4.0.0
     72         *
     73         * @param object|WP_Error $res  Response object or WP_Error.
     74         * @param string          $type The type of translations being requested.
     75         * @param object          $args Translation API arguments.
     76         */
     77        return apply_filters( 'translations_api_result', $res, $action, $args );
     78}
     79
     80/**
     81 * Get available translations from the WordPress.org API.
     82 *
     83 * @since 4.0.0
     84 *
     85 * @return array Array of translations, each an array of data.
     86 */
     87function wp_get_available_translations() {
     88        if ( false !== ( $translations = get_site_transient( 'available_translations' ) ) ) {
     89                return $translations;
     90        }
     91
     92        $api = translations_api( 'core' ); // @TODO pass $wp_version
     93
     94        if ( is_wp_error( $api ) ) {
     95                return array();
     96        }
     97
     98        $translations = array();
     99        // Key the array with the language code for now
     100        foreach ( $api['translations'] as $translation ) {
     101                $translations[ $translation['language'] ] = $translation;
     102        }
     103
     104        set_site_transient( 'available_translations', $translations, 3 * HOUR_IN_SECONDS );
     105
     106        return $translations;
     107}
     108
     109/**
     110 * Output the input fields for the language selection form on the installation screen.
     111 *
     112 * @since 4.0.0
     113 *
     114 * @see wp_get_available_translations()
     115 *
     116 * @param array $languages Array of available languages (populated via the Translations API).
     117 */
     118function wp_install_language_form( $languages ) {
     119        $installed_languages = get_available_languages();
     120
     121        echo "<label class='screen-reader-text' for='language'>Select a default language</label>\n";
     122        echo "<select size='14' name='language' id='language'>\n";
     123        echo '<option value="" lang="en" selected="selected" data-continue="Continue" data-installed="1">English (United States)</option>';
     124        echo "\n";
     125
     126        if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && ( 'en_US' !== WPLANG ) ) {
     127                if ( isset( $languages[ WPLANG ] ) ) {
     128                        $language = $languages[ WPLANG ];
     129                        echo '<option value="' . esc_attr( $language['language'] ) . '" lang="' . esc_attr( $language['iso'][1] ) . '">' . esc_html( $language['native_name'] ) . "</option>\n";
     130                }
     131        }
     132
     133        foreach ( $languages as $language ) {
     134                printf( '<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . "\n",
     135                        esc_attr( $language['language'] ),
     136                        esc_attr( $language['iso'][1] ),
     137                        esc_attr( $language['strings']['continue'] ),
     138                        in_array( $language['language'], $installed_languages ) ? ' data-installed="1"' : '',
     139                        esc_html( $language['native_name'] ) );
     140        }
     141        echo "</select>\n";
     142        echo '<p class="step"><span class="spinner"></span><input id="language-continue" type="submit" class="button button-primary button-large" value="Continue" /></p>';
     143}
     144
     145/**
     146 * Download a language pack.
     147 *
     148 * @since 4.0.0
     149 *
     150 * @see wp_get_available_translations()
     151 *
     152 * @param string $download Language code to download.
     153 * @return string|bool Returns the language code if successfully downloaded
     154 *                     (or already installed), or false on failure.
     155 */
     156function wp_install_download_language_pack( $download ) {
     157        // Check if the translation is already installed.
     158        if ( in_array( $download, get_available_languages() ) ) {
     159                return $download;
     160        }
     161
     162        // Confirm the translation is one we can download.
     163        $translations = wp_get_available_translations();
     164        if ( ! $translations ) {
     165                return false;
     166        }
     167        foreach ( $translations as $translation ) {
     168                if ( $translation['language'] === $download ) {
     169                        $translation_to_load = true;
     170                        break;
     171                }
     172        }
     173
     174        if ( empty( $translation_to_load ) ) {
     175                return false;
     176        }
     177        $translation = (object) $translation;
     178
     179        require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
     180        $skin = new Automatic_Upgrader_Skin;
     181        $upgrader = new Language_Pack_Upgrader( $skin );
     182        $translation->type = 'core';
     183        /**
     184         * @todo failures (such as non-direct FS)
     185         */
     186        $upgrader->upgrade( $translation, array( 'clear_update_cache' => false ) );
     187        return $translation->language;
     188}
     189
     190/**
     191 * Load a translation during the install process.
     192 *
     193 * @since 4.0.0
     194 *
     195 * @see load_textdomain()
     196 *
     197 * @param string $translation Translation to load.
     198 * @return string|bool Returns the language code if successfully loaded,
     199 *                     or false on failure.
     200 */
     201function wp_install_load_language( $translation ) {
     202        if ( ! empty( $translation ) ) {
     203                if ( in_array( $translation, get_available_languages() ) ) {
     204                        $translation_to_load = $translation;
     205                }
     206        }
     207
     208        if ( empty( $translation_to_load ) ) {
     209                return false;
     210        }
     211
     212        unload_textdomain( 'default' ); // Start over.
     213        load_textdomain( 'default', WP_LANG_DIR . "/{$translation_to_load}.mo" );
     214        load_textdomain( 'default', WP_LANG_DIR . "/admin-{$translation_to_load}.mo" );
     215        return $translation_to_load;
     216}
  • src/wp-admin/includes/upgrade.php

     
    14191419 */
    14201420function maybe_create_table($table_name, $create_ddl) {
    14211421        global $wpdb;
    1422        
     1422
    14231423        $query = $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->esc_like( $table_name ) );
    14241424
    14251425        if ( $wpdb->get_var( $query ) == $table_name ) {
     
    21922192        dbDelta( $ms_queries );
    21932193}
    21942194endif;
    2195 
    2196 /**
    2197  * Output the input fields for the language selection form on the installation screen.
    2198  *
    2199  * @since 4.0.0
    2200  *
    2201  * @see wp_get_available_translations_from_api()
    2202  *
    2203  * @param array $languages Array of available languages (populated via the Translations API).
    2204  */
    2205 function wp_install_language_form( $languages ) {
    2206         $installed_languages = get_available_languages();
    2207 
    2208         echo "<label class='screen-reader-text' for='language'>Select a default language</label>\n";
    2209         echo "<select size='14' name='language' id='language'>\n";
    2210         echo '<option value="" lang="en" selected="selected" data-continue="Continue" data-installed="1">English (United States)</option>';
    2211         echo "\n";
    2212 
    2213         if ( defined( 'WPLANG' ) && ( '' !== WPLANG ) && ( 'en_US' !== WPLANG ) ) {
    2214                 if ( isset( $languages[ WPLANG ] ) ) {
    2215                         $language = $languages[ WPLANG ];
    2216                         echo '<option value="' . esc_attr( $language['language'] ) . '" lang="' . esc_attr( $language['iso'][1] ) . '">' . esc_html( $language['native_name'] ) . "</option>\n";
    2217                 }
    2218         }
    2219 
    2220         foreach ( $languages as $language ) {
    2221                 printf( '<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . "\n",
    2222                         esc_attr( $language['language'] ),
    2223                         esc_attr( $language['iso'][1] ),
    2224                         esc_attr( $language['strings']['continue'] ),
    2225                         in_array( $language['language'], $installed_languages ) ? ' data-installed="1"' : '',
    2226                         esc_html( $language['native_name'] ) );
    2227         }
    2228         echo "</select>\n";
    2229         echo '<p class="step"><span class="spinner"></span><input id="language-continue" type="submit" class="button button-primary button-large" value="Continue" /></p>';
    2230 }
    2231 
    2232 /**
    2233  * Get available translations from the WordPress.org API.
    2234  *
    2235  * @since 4.0.0
    2236  *
    2237  * @see wp_remote_post()
    2238  *
    2239  * @return array Array of translations, each an array of data.
    2240  */
    2241 function wp_get_available_translations_from_api() {
    2242         $url = 'http://api.wordpress.org/translations/core/1.0/';
    2243         if ( wp_http_supports( array( 'ssl' ) ) ) {
    2244                 $url = set_url_scheme( $url, 'https' );
    2245         }
    2246 
    2247         $options = array(
    2248                 'timeout' => 3,
    2249                 'body' => array( 'version' => $GLOBALS['wp_version'] ),
    2250         );
    2251 
    2252         $response = wp_remote_post( $url, $options );
    2253         $body = wp_remote_retrieve_body( $response );
    2254         if ( $body && $body = json_decode( $body, true ) ) {
    2255                 $translations = array();
    2256                 // Key the array with the language code for now
    2257                 foreach ( $body['translations'] as $translation ) {
    2258                         $translations[ $translation['language'] ] = $translation;
    2259                 }
    2260                 return $translations;
    2261         }
    2262         return false;
    2263 }
    2264 
    2265 /**
    2266  * Download a language pack.
    2267  *
    2268  * @since 4.0.0
    2269  *
    2270  * @see wp_get_available_translations_from_api()
    2271  *
    2272  * @param string $download Language code to download.
    2273  * @return string|bool Returns the language code if successfully downloaded
    2274  *                     (or already installed), or false on failure.
    2275  */
    2276 function wp_install_download_language_pack( $download ) {
    2277         // Check if the translation is already installed.
    2278         if ( in_array( $download, get_available_languages() ) ) {
    2279                 return $download;
    2280         }
    2281 
    2282         // Confirm the translation is one we can download.
    2283         $translations = wp_get_available_translations_from_api();
    2284         if ( ! $translations ) {
    2285                 return false;
    2286         }
    2287         foreach ( $translations as $translation ) {
    2288                 if ( $translation['language'] === $download ) {
    2289                         $translation_to_load = true;
    2290                         break;
    2291                 }
    2292         }
    2293 
    2294         if ( empty( $translation_to_load ) ) {
    2295                 return false;
    2296         }
    2297         $translation = (object) $translation;
    2298 
    2299         require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    2300         $skin = new Automatic_Upgrader_Skin;
    2301         $upgrader = new Language_Pack_Upgrader( $skin );
    2302         $translation->type = 'core';
    2303         /**
    2304          * @todo failures (such as non-direct FS)
    2305          */
    2306         $upgrader->upgrade( $translation, array( 'clear_update_cache' => false ) );
    2307         return $translation->language;
    2308 }
    2309 
    2310 /**
    2311  * Load a translation during the install process.
    2312  *
    2313  * @since 4.0.0
    2314  *
    2315  * @see load_textdomain()
    2316  *
    2317  * @param string $translation Translation to load.
    2318  * @return string|bool Returns the language code if successfully loaded,
    2319  *                     or false on failure.
    2320  */
    2321 function wp_install_load_language( $translation ) {
    2322         if ( ! empty( $translation ) ) {
    2323                 if ( in_array( $translation, get_available_languages() ) ) {
    2324                         $translation_to_load = $translation;
    2325                 }
    2326         }
    2327 
    2328         if ( empty( $translation_to_load ) ) {
    2329                 return false;
    2330         }
    2331 
    2332         unload_textdomain( 'default' ); // Start over.
    2333         load_textdomain( 'default', WP_LANG_DIR . "/{$translation_to_load}.mo" );
    2334         load_textdomain( 'default', WP_LANG_DIR . "/admin-{$translation_to_load}.mo" );
    2335         return $translation_to_load;
    2336 }
  • src/wp-admin/install.php

     
    3838/** Load WordPress Administration Upgrade API */
    3939require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    4040
     41/** Load WordPress Translation Install API */
     42require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
     43
    4144/** Load wpdb */
    4245require_once( ABSPATH . WPINC . '/wp-db.php' );
    4346
     
    179182switch($step) {
    180183        case 0: // Step 0
    181184
    182                 if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations_from_api() ) ) {
     185                if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations() ) ) {
    183186                        display_header( 'language-chooser' );
    184187                        echo '<form id="setup" method="post" action="?step=1">';
    185188                        wp_install_language_form( $languages );
  • src/wp-admin/options-general.php

     
    302302</select></td>
    303303</tr>
    304304<?php do_settings_fields('general', 'default'); ?>
    305 <?php
    306         $languages = get_available_languages();
    307         if ( $languages ) :
    308 ?>
    309         <tr>
    310                 <th width="33%" scope="row"><label for="WPLANG"><?php _e('Site Language') ?></label></th>
    311                 <td>
    312                         <?php wp_dropdown_languages( array(
    313                                 'name'      => 'WPLANG',
    314                                 'id'        => 'WPLANG',
    315                                 'selected'  => get_option( 'WPLANG' ),
    316                                 'languages' => $languages,
    317                         ) ); ?>
    318                 </td>
    319         </tr>
    320 <?php
    321         endif;
    322 ?>
     305
     306<tr>
     307        <th width="33%" scope="row"><label for="WPLANG"><?php _e( 'Site Language' ); ?></label></th>
     308        <td>
     309                <?php
     310                $wp_lang = get_option( 'WPLANG' );
     311                if ( ! in_array( $wp_lang, get_available_languages() ) ) {
     312                        $wp_lang = '';
     313                }
     314                wp_dropdown_languages( array(
     315                        'name'     => 'WPLANG',
     316                        'id'       => 'WPLANG',
     317                        'selected' => $wp_lang,
     318                ) );
     319
     320                if ( empty( $wp_lang ) && defined( 'WPLANG' ) && WPLANG ) {
     321                        ?>
     322                        <p class="description"><?php _e( '<code>WPLANG</code> is defined and is used instead of English.' ); ?></p>
     323                        <?php
     324                }
     325                ?>
     326        </td>
     327</tr>
    323328</table>
    324329
    325330<?php do_settings_sections('general'); ?>
  • src/wp-admin/options.php

     
    151151                $options = $whitelist_options[ $option_page ];
    152152        }
    153153
    154         // Handle custom date/time formats
    155154        if ( 'general' == $option_page ) {
     155                // Handle custom date/time formats
    156156                if ( !empty($_POST['date_format']) && isset($_POST['date_format_custom']) && '\c\u\s\t\o\m' == wp_unslash( $_POST['date_format'] ) )
    157157                        $_POST['date_format'] = $_POST['date_format_custom'];
    158158                if ( !empty($_POST['time_format']) && isset($_POST['time_format_custom']) && '\c\u\s\t\o\m' == wp_unslash( $_POST['time_format'] ) )
     
    163163                        $_POST['gmt_offset'] = preg_replace('/UTC\+?/', '', $_POST['gmt_offset']);
    164164                        $_POST['timezone_string'] = '';
    165165                }
     166
     167                // Handle translation install
     168                if ( ! empty( $_POST['WPLANG'] ) ) {
     169                        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
     170                        require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
     171
     172                        $language = wp_install_download_language_pack( $_POST['WPLANG'] );
     173                        if ( $language ) {
     174                                $_POST['WPLANG'] = $language;
     175                                wp_install_load_language( $language );
     176                        }
     177                }
    166178        }
    167179
    168180        if ( $options ) {
  • src/wp-admin/setup-config.php

     
    3232
    3333require( ABSPATH . 'wp-settings.php' );
    3434
    35 require( ABSPATH . 'wp-admin/includes/upgrade.php' );
     35/** Load WordPress Administration Upgrade API */
     36require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
    3637
     38/** Load WordPress Translation Install API */
     39require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
     40
    3741// Support wp-config-sample.php one level up, for the develop repo.
    3842if ( file_exists( ABSPATH . 'wp-config-sample.php' ) )
    3943        $config_file = file( ABSPATH . 'wp-config-sample.php' );
     
    8690switch($step) {
    8791        case -1:
    8892
    89                 if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations_from_api() ) ) {
     93                if ( empty( $_GET['language'] ) && ( $languages = wp_get_available_translations() ) ) {
    9094                        setup_config_display_header( 'language-chooser' );
    9195                        echo '<form id="setup" method="post" action="?step=0">';
    9296                        wp_install_language_form( $languages );
  • src/wp-includes/l10n.php

     
    823823 * @since 4.0.0
    824824 *
    825825 * @see get_available_languages()
     826 * @see wp_get_available_translations()
    826827 *
    827828 * @param array $args Optional arguments. Default empty array.
    828829 */
    829830function wp_dropdown_languages( $args = array() ) {
    830         if ( isset( $args['languages'] ) ) {
    831                 $languages = $args['languages'];
    832         } else {
    833                 $languages = get_available_languages();
     831        require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
     832
     833        $locales = get_available_languages();
     834        $translations = wp_get_available_translations();
     835
     836        /*
     837         * get_available_languages() just returns the locales. Find the locale in
     838         * $translations to get the native name.
     839         */
     840        $languages = array();
     841        foreach ( $locales as $locale ) {
     842                if ( isset( $translations[ $locale ] ) ) {
     843                        $translation = $translations[ $locale ];
     844                        $languages[ $locale ] = array(
     845                                'language'     => $translation['language'],
     846                                'native_name'  => $translation['native_name'],
     847                        );
     848                } else {
     849                        $languages[ $locale ] = array(
     850                                'language'     => $locale,
     851                                'native_name'  => '',
     852                        );
     853                }
    834854        }
    835855
     856        // Remove installed languages from available translations
     857        $translations = array_diff_key( $translations, $languages );
     858
    836859        printf( '<select name="%s" id="%s">', esc_attr( $args['name'] ), esc_attr( $args['id'] ) );
    837         echo '<option value="">en_US</option>';
     860
     861        $structure = array();
     862
     863        // Installed languages
     864        $structure[] = '<optgroup label="' . esc_attr__( 'Installed Languages' ) . '">';
     865        $structure[] = '<option value="">English</option>';
    838866        foreach ( $languages as $language ) {
    839                 $selected = selected( $language, $args['selected'], false );
    840                 echo '<option value="' . esc_attr( $language ) .'"' . $selected . '>' . $language . '</option>';
     867                $selected = selected( $language['language'], $args['selected'], false );
     868                $structure[] = '<option value="' . esc_attr( $language['language'] ) .'"' . $selected . '>' . esc_html( $language['native_name'] ) . '</option>';
    841869        }
     870        $structure[] = '</optgroup>';
     871
     872        // Available translations
     873        if ( ! empty( $translations ) ) {
     874                $structure[] = '<optgroup label="' . esc_attr__( 'Available Translations' ) . '">';
     875                foreach ( $translations as $translation ) {
     876                        $selected = selected( $translation['language'], $args['selected'], false );
     877                        $structure[] = '<option value="' . esc_attr( $translation['language'] ) .'"' . $selected . '>' . esc_html( $translation['native_name'] ) . '</option>';
     878                }
     879                $structure[] = '</optgroup>';
     880        }
     881
     882        echo join( "\n", $structure );
     883
    842884        echo '</select>';
    843885}