diff --git a/src/wp-admin/network/settings.php b/src/wp-admin/network/settings.php
index 1d527c8723..1d3e03519f 100644
|
a
|
b
|
if ( $_POST ) {
|
| 63 | 63 | ); |
| 64 | 64 | |
| 65 | 65 | // Handle translation install. |
| 66 | | if ( ! empty( $_POST['WPLANG'] ) && wp_can_install_language_pack() ) { // @todo: Skip if already installed |
| | 66 | if ( ! empty( $_POST['WPLANG'] ) && current_user_can( 'install_languages' ) ) { |
| 67 | 67 | $language = wp_download_language_pack( $_POST['WPLANG'] ); |
| 68 | 68 | if ( $language ) { |
| 69 | 69 | $_POST['WPLANG'] = $language; |
| … |
… |
if ( isset( $_GET['updated'] ) ) {
|
| 342 | 342 | 'selected' => $lang, |
| 343 | 343 | 'languages' => $languages, |
| 344 | 344 | 'translations' => $translations, |
| 345 | | 'show_available_translations' => wp_can_install_language_pack(), |
| | 345 | 'show_available_translations' => current_user_can( 'install_languages' ), |
| 346 | 346 | ) ); |
| 347 | 347 | ?> |
| 348 | 348 | </td> |
diff --git a/src/wp-admin/network/site-new.php b/src/wp-admin/network/site-new.php
index 0810f8a87a..e0ccfc26fa 100644
|
a
|
b
|
if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] ) {
|
| 66 | 66 | if ( isset( $_POST['WPLANG'] ) ) { |
| 67 | 67 | if ( '' === $_POST['WPLANG'] ) { |
| 68 | 68 | $meta['WPLANG'] = ''; // en_US |
| 69 | | } elseif ( wp_can_install_language_pack() ) { |
| | 69 | } elseif ( in_array( $_POST['WPLANG'], get_available_languages() ) ) { |
| | 70 | $meta['WPLANG'] = $_POST['WPLANG']; |
| | 71 | } elseif ( current_user_can( 'install_languages' ) ) { |
| 70 | 72 | $language = wp_download_language_pack( wp_unslash( $_POST['WPLANG'] ) ); |
| 71 | 73 | if ( $language ) { |
| 72 | 74 | $meta['WPLANG'] = $language; |
| … |
… |
if ( ! empty( $messages ) ) {
|
| 234 | 236 | 'selected' => $lang, |
| 235 | 237 | 'languages' => $languages, |
| 236 | 238 | 'translations' => $translations, |
| 237 | | 'show_available_translations' => wp_can_install_language_pack(), |
| | 239 | 'show_available_translations' => current_user_can( 'install_languages' ), |
| 238 | 240 | ) ); |
| 239 | 241 | ?> |
| 240 | 242 | </td> |
diff --git a/src/wp-admin/options-general.php b/src/wp-admin/options-general.php
index 834f02733a..a5364a6b62 100644
|
a
|
b
|
if ( ! empty( $languages ) || ! empty( $translations ) ) {
|
| 144 | 144 | 'selected' => $locale, |
| 145 | 145 | 'languages' => $languages, |
| 146 | 146 | 'translations' => $translations, |
| 147 | | 'show_available_translations' => ( ! is_multisite() || is_super_admin() ) && wp_can_install_language_pack(), |
| | 147 | 'show_available_translations' => current_user_can( 'install_languages' ), |
| 148 | 148 | ) ); |
| 149 | 149 | |
| 150 | 150 | // Add note about deprecated WPLANG constant. |
diff --git a/src/wp-admin/options.php b/src/wp-admin/options.php
index d2e1c0374f..bf7141c43f 100644
|
a
|
b
|
if ( 'update' == $action ) {
|
| 182 | 182 | } |
| 183 | 183 | |
| 184 | 184 | // Handle translation install. |
| 185 | | if ( ! empty( $_POST['WPLANG'] ) && ( ! is_multisite() || is_super_admin() ) ) { // @todo: Skip if already installed |
| | 185 | if ( ! empty( $_POST['WPLANG'] ) && current_user_can( 'install_languages' ) ) { |
| 186 | 186 | require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); |
| 187 | 187 | |
| 188 | | if ( wp_can_install_language_pack() ) { |
| 189 | | $language = wp_download_language_pack( $_POST['WPLANG'] ); |
| 190 | | if ( $language ) { |
| 191 | | $_POST['WPLANG'] = $language; |
| 192 | | } |
| | 188 | $language = wp_download_language_pack( $_POST['WPLANG'] ); |
| | 189 | if ( $language ) { |
| | 190 | $_POST['WPLANG'] = $language; |
| 193 | 191 | } |
| 194 | 192 | } |
| 195 | 193 | } |
diff --git a/src/wp-admin/update-core.php b/src/wp-admin/update-core.php
index a0801b9bad..83b7be539b 100644
|
a
|
b
|
if ( 'upgrade-core' == $action ) {
|
| 608 | 608 | echo ' <a class="button" href="' . esc_url( self_admin_url('update-core.php?force-check=1') ) . '">' . __( 'Check Again' ) . '</a>'; |
| 609 | 609 | echo '</p>'; |
| 610 | 610 | |
| 611 | | if ( $core = current_user_can( 'update_core' ) ) |
| | 611 | if ( current_user_can( 'update_core' ) ) { |
| 612 | 612 | core_upgrade_preamble(); |
| 613 | | if ( $plugins = current_user_can( 'update_plugins' ) ) |
| | 613 | } |
| | 614 | if ( current_user_can( 'update_plugins' ) ) { |
| 614 | 615 | list_plugin_updates(); |
| 615 | | if ( $themes = current_user_can( 'update_themes' ) ) |
| | 616 | } |
| | 617 | if ( current_user_can( 'update_themes' ) ) { |
| 616 | 618 | list_theme_updates(); |
| 617 | | if ( $core || $plugins || $themes ) |
| | 619 | } |
| | 620 | if ( current_user_can( 'update_languages' ) ) { |
| 618 | 621 | list_translation_updates(); |
| 619 | | unset( $core, $plugins, $themes ); |
| | 622 | } |
| | 623 | |
| 620 | 624 | /** |
| 621 | 625 | * Fires after the core, plugin, and theme update tables. |
| 622 | 626 | * |
| … |
… |
if ( 'upgrade-core' == $action ) {
|
| 729 | 733 | |
| 730 | 734 | } elseif ( 'do-translation-upgrade' == $action ) { |
| 731 | 735 | |
| 732 | | if ( ! current_user_can( 'update_core' ) && ! current_user_can( 'update_plugins' ) && ! current_user_can( 'update_themes' ) ) |
| | 736 | if ( ! current_user_can( 'update_languages' ) ) |
| 733 | 737 | wp_die( __( 'Sorry, you are not allowed to update this site.' ) ); |
| 734 | 738 | |
| 735 | 739 | check_admin_referer( 'upgrade-translations' ); |
diff --git a/src/wp-includes/capabilities.php b/src/wp-includes/capabilities.php
index 13851cc2e1..5993a77caf 100644
|
a
|
b
|
function map_meta_cap( $cap, $user_id ) {
|
| 392 | 392 | $caps[] = $cap; |
| 393 | 393 | } |
| 394 | 394 | break; |
| | 395 | case 'install_languages': |
| | 396 | case 'update_languages': |
| | 397 | if ( ! function_exists( 'wp_can_install_language_pack' ) ) { |
| | 398 | require_once( ABSPATH . 'wp-admin/includes/translation-install.php' ); |
| | 399 | } |
| | 400 | |
| | 401 | if ( ! wp_can_install_language_pack() ) { |
| | 402 | $caps[] = 'do_not_allow'; |
| | 403 | } elseif ( is_multisite() && ! is_super_admin( $user_id ) ) { |
| | 404 | $caps[] = 'do_not_allow'; |
| | 405 | } else { |
| | 406 | $caps[] = 'install_languages'; |
| | 407 | } |
| | 408 | break; |
| 395 | 409 | case 'activate_plugins': |
| 396 | 410 | $caps[] = $cap; |
| 397 | 411 | if ( is_multisite() ) { |
| … |
… |
function revoke_super_admin( $user_id ) {
|
| 826 | 840 | } |
| 827 | 841 | return false; |
| 828 | 842 | } |
| | 843 | |
| | 844 | /** |
| | 845 | * Filters the user capabilities to grant the 'install_languages' capability as necessary. |
| | 846 | * |
| | 847 | * A user must have at least one out of the 'update_core', 'install_plugins', and |
| | 848 | * 'install_themes' capabilities to qualify for 'install_languages'. |
| | 849 | * |
| | 850 | * @since 4.9.0 |
| | 851 | * |
| | 852 | * @param array $allcaps An array of all the user's capabilities. |
| | 853 | * @return array Filtered array of the user's capabilities. |
| | 854 | */ |
| | 855 | function wp_maybe_grant_install_languages_cap( $allcaps ) { |
| | 856 | if ( ! empty( $allcaps['update_core'] ) || ! empty( $allcaps['install_plugins'] ) || ! empty( $allcaps['install_themes'] ) ) { |
| | 857 | $allcaps['install_languages'] = true; |
| | 858 | } |
| | 859 | |
| | 860 | return $allcaps; |
| | 861 | } |
diff --git a/src/wp-includes/default-filters.php b/src/wp-includes/default-filters.php
index 8f0237028d..72a2b7f596 100644
|
a
|
b
|
add_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10, 3 );
|
| 511 | 511 | add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 ); |
| 512 | 512 | add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 ); |
| 513 | 513 | |
| | 514 | // Capabilities |
| | 515 | add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 ); |
| | 516 | |
| 514 | 517 | unset( $filter, $action ); |
diff --git a/tests/phpunit/tests/user/capabilities.php b/tests/phpunit/tests/user/capabilities.php
index 2dffd25c9f..641b8d1faa 100644
|
a
|
b
|
class Tests_User_Capabilities extends WP_UnitTestCase {
|
| 233 | 233 | 'upload_themes' => array( 'administrator' ), |
| 234 | 234 | 'customize' => array( 'administrator' ), |
| 235 | 235 | 'add_users' => array( 'administrator' ), |
| | 236 | 'install_languages' => array( 'administrator' ), |
| | 237 | 'update_languages' => array( 'administrator' ), |
| 236 | 238 | |
| 237 | 239 | 'edit_categories' => array( 'administrator', 'editor' ), |
| 238 | 240 | 'delete_categories' => array( 'administrator', 'editor' ), |
| … |
… |
class Tests_User_Capabilities extends WP_UnitTestCase {
|
| 261 | 263 | 'upload_themes' => array(), |
| 262 | 264 | 'edit_css' => array(), |
| 263 | 265 | 'upgrade_network' => array(), |
| | 266 | 'install_languages' => array(), |
| | 267 | 'update_languages' => array(), |
| 264 | 268 | |
| 265 | 269 | 'customize' => array( 'administrator' ), |
| 266 | 270 | 'delete_site' => array( 'administrator' ), |