2014-08-26 21:59:16 +02:00
< ? php
/**
2017-08-22 13:52:48 +02:00
* WordPress Translation Installation Administration API
2014-08-26 21:59:16 +02:00
*
* @ 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 .
2022-01-27 22:15:03 +01:00
* @ return array | WP_Error On success an associative array of translations , WP_Error on failure .
2014-08-26 21:59:16 +02:00
*/
function translations_api ( $type , $args = null ) {
2020-01-29 01:45:18 +01:00
// Include an unmodified $wp_version.
2020-02-06 07:33:11 +01:00
require ABSPATH . WPINC . '/version.php' ;
2014-08-26 21:59:16 +02:00
2020-04-05 05:02:11 +02:00
if ( ! in_array ( $type , array ( 'plugins' , 'themes' , 'core' ), true ) ) {
2020-02-07 20:16:06 +01:00
return new WP_Error ( 'invalid_type' , __ ( 'Invalid translation type.' ) );
2014-08-26 21:59:16 +02:00
}
/**
2017-08-22 13:52:48 +02:00
* Allows a plugin to override the WordPress . org Translation Installation API entirely .
2014-08-26 21:59:16 +02:00
*
* @ since 4.0 . 0
*
2022-01-27 22:15:03 +01:00
* @ param false | array $result The result array . Default false .
* @ param string $type The type of translations being requested .
* @ param object $args Translation API arguments .
2014-08-26 21:59:16 +02:00
*/
$res = apply_filters ( 'translations_api' , false , $type , $args );
if ( false === $res ) {
2019-07-01 14:52:01 +02:00
$url = 'http://api.wordpress.org/translations/' . $type . '/1.0/' ;
$http_url = $url ;
$ssl = wp_http_supports ( array ( 'ssl' ) );
if ( $ssl ) {
2014-08-26 21:59:16 +02:00
$url = set_url_scheme ( $url , 'https' );
}
$options = array (
'timeout' => 3 ,
2017-12-01 00:11:00 +01:00
'body' => array (
2014-08-26 21:59:16 +02:00
'wp_version' => $wp_version ,
'locale' => get_locale (),
2020-01-29 01:45:18 +01:00
'version' => $args [ 'version' ], // Version of plugin, theme or core.
2014-08-26 21:59:16 +02:00
),
);
if ( 'core' !== $type ) {
2020-01-29 01:45:18 +01:00
$options [ 'body' ][ 'slug' ] = $args [ 'slug' ]; // Plugin or theme slug.
2014-08-26 21:59:16 +02:00
}
$request = wp_remote_post ( $url , $options );
if ( $ssl && is_wp_error ( $request ) ) {
Code Modernization: Use wp_trigger_error() instead of trigger_error().
Replaces `trigger_error()` with `wp_trigger_error()`.
The usage of `wp_trigger_error()` avoids generating `E_USER` family errors unless `WP_DEBUG` is on. In doing so, users should not see these messages in normal production.
Notes:
* Removes `E_USER_NOTICE` when passed as an argumnent, as it's the default error level.
* An empty string is passed for the function name when its name is already in the error message or does not add value to the error message.
* Externally maintained libraries are not included.
Follow-up to [55204], [25956], [29630], [38883], [52062], [52049], [54272], [38883], [55245], [51599], [14452], [38883], [24976].
Props prasadkarmalkar, rajinsharwar, thelovekesh, hellofromTonya, swissspidy.
Fixes #59652.
Built from https://develop.svn.wordpress.org/trunk@58409
git-svn-id: http://core.svn.wordpress.org/trunk@57858 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2024-06-13 22:50:14 +02:00
wp_trigger_error (
__FUNCTION__ ,
2016-11-21 02:52:32 +01:00
sprintf (
2019-09-03 02:41:05 +02:00
/* translators: %s: Support forums URL. */
2016-11-21 02:52:32 +01:00
__ ( '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 <a href="%s">support forums</a>.' ),
2019-05-25 16:24:50 +02:00
__ ( 'https://wordpress.org/support/forums/' )
2016-11-21 02:52:32 +01:00
) . ' ' . __ ( '(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
);
2014-08-26 21:59:16 +02:00
$request = wp_remote_post ( $http_url , $options );
}
if ( is_wp_error ( $request ) ) {
2017-12-01 00:11:00 +01:00
$res = new WP_Error (
'translations_api_failed' ,
2016-11-21 02:52:32 +01:00
sprintf (
2019-09-03 02:41:05 +02:00
/* translators: %s: Support forums URL. */
2016-11-21 02:52:32 +01:00
__ ( '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 <a href="%s">support forums</a>.' ),
2019-05-25 16:24:50 +02:00
__ ( 'https://wordpress.org/support/forums/' )
2016-11-21 02:52:32 +01:00
),
$request -> get_error_message ()
);
2014-08-26 21:59:16 +02:00
} else {
$res = json_decode ( wp_remote_retrieve_body ( $request ), true );
if ( ! is_object ( $res ) && ! is_array ( $res ) ) {
2017-12-01 00:11:00 +01:00
$res = new WP_Error (
'translations_api_failed' ,
2016-11-21 02:52:32 +01:00
sprintf (
2019-09-03 02:41:05 +02:00
/* translators: %s: Support forums URL. */
2016-11-21 02:52:32 +01:00
__ ( '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 <a href="%s">support forums</a>.' ),
2019-05-25 16:24:50 +02:00
__ ( 'https://wordpress.org/support/forums/' )
2016-11-21 02:52:32 +01:00
),
wp_remote_retrieve_body ( $request )
);
2014-08-26 21:59:16 +02:00
}
}
}
/**
2017-08-22 13:52:48 +02:00
* Filters the Translation Installation API response results .
2014-08-26 21:59:16 +02:00
*
* @ since 4.0 . 0
*
2022-01-27 22:15:03 +01:00
* @ param array | WP_Error $res Response as an associative array or WP_Error .
* @ param string $type The type of translations being requested .
* @ param object $args Translation API arguments .
2014-08-26 21:59:16 +02:00
*/
return apply_filters ( 'translations_api_result' , $res , $type , $args );
}
/**
* Get available translations from the WordPress . org API .
*
* @ since 4.0 . 0
*
* @ see translations_api ()
*
2019-11-05 22:30:03 +01:00
* @ return array [] Array of translations , each an array of data , keyed by the language . If the API response results
* in an error , an empty array will be returned .
2014-08-26 21:59:16 +02:00
*/
function wp_get_available_translations () {
2019-07-01 14:52:01 +02:00
if ( ! wp_installing () ) {
$translations = get_site_transient ( 'available_translations' );
if ( false !== $translations ) {
return $translations ;
}
2014-08-26 21:59:16 +02:00
}
2020-01-29 01:45:18 +01:00
// Include an unmodified $wp_version.
2020-02-06 07:33:11 +01:00
require ABSPATH . WPINC . '/version.php' ;
2014-08-26 21:59:16 +02:00
$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
*
2020-02-10 04:30:06 +01:00
* @ global string $wp_local_package Locale code of the package .
2015-05-29 04:06:31 +02:00
*
2019-10-26 23:09:04 +02:00
* @ param array [] $languages Array of available languages ( populated via the Translation API ) .
2014-08-26 21:59:16 +02:00
*/
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 ];
2017-12-01 00:11:00 +01:00
printf (
'<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . " \n " ,
2014-08-27 00:27:16 +02:00
esc_attr ( $language [ 'language' ] ),
2015-02-13 12:23:26 +01:00
esc_attr ( current ( $language [ 'iso' ] ) ),
2020-06-08 23:27:10 +02:00
esc_attr ( $language [ 'strings' ][ 'continue' ] ? $language [ 'strings' ][ 'continue' ] : 'Continue' ),
2020-04-05 05:02:11 +02:00
in_array ( $language [ 'language' ], $installed_languages , true ) ? ' data-installed="1"' : '' ,
2017-12-01 00:11:00 +01:00
esc_html ( $language [ 'native_name' ] )
);
2014-08-27 00:27:16 +02:00
2014-08-26 21:59:16 +02:00
unset ( $languages [ $wp_local_package ] );
}
}
foreach ( $languages as $language ) {
2017-12-01 00:11:00 +01:00
printf (
'<option value="%s" lang="%s" data-continue="%s"%s>%s</option>' . " \n " ,
2014-08-26 21:59:16 +02:00
esc_attr ( $language [ 'language' ] ),
2015-02-13 12:23:26 +01:00
esc_attr ( current ( $language [ 'iso' ] ) ),
2020-06-08 23:27:10 +02:00
esc_attr ( $language [ 'strings' ][ 'continue' ] ? $language [ 'strings' ][ 'continue' ] : 'Continue' ),
2020-04-05 05:02:11 +02:00
in_array ( $language [ 'language' ], $installed_languages , true ) ? ' data-installed="1"' : '' ,
2017-12-01 00:11:00 +01:00
esc_html ( $language [ 'native_name' ] )
);
2014-08-26 21:59:16 +02:00
}
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 .
2021-01-03 23:04:04 +01:00
* @ return string | false Returns the language code if successfully downloaded
* ( or already installed ), or false on failure .
2014-08-26 21:59:16 +02:00
*/
function wp_download_language_pack ( $download ) {
// Check if the translation is already installed.
2020-04-05 05:02:11 +02:00
if ( in_array ( $download , get_available_languages (), true ) ) {
2014-08-26 21:59:16 +02:00
return $download ;
}
2017-05-11 21:24:41 +02:00
if ( ! wp_is_file_mod_allowed ( 'download_language_pack' ) ) {
2014-08-26 21:59:16 +02:00
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 ;
2016-08-31 18:31:29 +02:00
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
2022-11-29 16:51:14 +01:00
$skin = new Automatic_Upgrader_Skin ();
2017-12-01 00:11:00 +01:00
$upgrader = new Language_Pack_Upgrader ( $skin );
2014-08-26 21:59:16 +02:00
$translation -> type = 'core' ;
2017-12-01 00:11:00 +01:00
$result = $upgrader -> upgrade ( $translation , array ( 'clear_update_cache' => false ) );
2014-09-02 20:07:18 +02:00
if ( ! $result || is_wp_error ( $result ) ) {
return false ;
}
2014-08-26 21:59:16 +02:00
return $translation -> language ;
}
2014-09-02 20:07:18 +02:00
/**
* Check if WordPress has access to the filesystem without asking for
* credentials .
*
* @ since 4.0 . 0
*
* @ return bool Returns true on success , false on failure .
*/
function wp_can_install_language_pack () {
2017-05-11 21:24:41 +02:00
if ( ! wp_is_file_mod_allowed ( 'can_install_language_pack' ) ) {
2014-09-02 20:07:18 +02:00
return false ;
}
2016-08-31 18:31:29 +02:00
require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php' ;
2022-11-29 16:51:14 +01:00
$skin = new Automatic_Upgrader_Skin ();
2014-09-02 20:07:18 +02:00
$upgrader = new Language_Pack_Upgrader ( $skin );
2015-01-08 00:43:24 +01:00
$upgrader -> init ();
2014-09-02 20:07:18 +02:00
$check = $upgrader -> fs_connect ( array ( WP_CONTENT_DIR , WP_LANG_DIR ) );
if ( ! $check || is_wp_error ( $check ) ) {
return false ;
}
return true ;
}