Role/Capability: Introduce capabilities dedicated to installing and updating language files.
The new meta capabilities are called `install_languages` and `update_languages`. Prior to this change, there were no proper capability checks applied. Instead only the filesystem and related constants were checked, and for actual permissions a rather vague fallback was used where a user needed to have at least one of the other updating capabilities. In addition to being generally more verbose, the new capabilities make it possible for example to allow a user to update languages, but nothing else. By default they fall back to the original way of how they were handled. Props johnbillion, flixos90. Fixes #39677. git-svn-id: https://develop.svn.wordpress.org/trunk@41268 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
parent
c56dd07a30
commit
f16b2a650e
@ -33,12 +33,15 @@ if ( ! is_multisite() || current_user_can( 'update_core' ) ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( ! is_multisite() ) {
|
if ( ! is_multisite() ) {
|
||||||
if ( current_user_can( 'update_core' ) )
|
if ( current_user_can( 'update_core' ) ) {
|
||||||
$cap = 'update_core';
|
$cap = 'update_core';
|
||||||
elseif ( current_user_can( 'update_plugins' ) )
|
} elseif ( current_user_can( 'update_plugins' ) ) {
|
||||||
$cap = 'update_plugins';
|
$cap = 'update_plugins';
|
||||||
else
|
} elseif ( current_user_can( 'update_themes' ) ) {
|
||||||
$cap = 'update_themes';
|
$cap = 'update_themes';
|
||||||
|
} else {
|
||||||
|
$cap = 'update_languages';
|
||||||
|
}
|
||||||
$submenu[ 'index.php' ][10] = array( sprintf( __('Updates %s'), "<span class='update-plugins count-{$update_data['counts']['total']}'><span class='update-count'>" . number_format_i18n($update_data['counts']['total']) . "</span></span>" ), $cap, 'update-core.php');
|
$submenu[ 'index.php' ][10] = array( sprintf( __('Updates %s'), "<span class='update-plugins count-{$update_data['counts']['total']}'><span class='update-count'>" . number_format_i18n($update_data['counts']['total']) . "</span></span>" ), $cap, 'update-core.php');
|
||||||
unset( $cap );
|
unset( $cap );
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ if ( $_POST ) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Handle translation install.
|
// Handle translation install.
|
||||||
if ( ! empty( $_POST['WPLANG'] ) && wp_can_install_language_pack() ) { // @todo: Skip if already installed
|
if ( ! empty( $_POST['WPLANG'] ) && current_user_can( 'install_languages' ) ) {
|
||||||
$language = wp_download_language_pack( $_POST['WPLANG'] );
|
$language = wp_download_language_pack( $_POST['WPLANG'] );
|
||||||
if ( $language ) {
|
if ( $language ) {
|
||||||
$_POST['WPLANG'] = $language;
|
$_POST['WPLANG'] = $language;
|
||||||
@ -342,7 +342,7 @@ if ( isset( $_GET['updated'] ) ) {
|
|||||||
'selected' => $lang,
|
'selected' => $lang,
|
||||||
'languages' => $languages,
|
'languages' => $languages,
|
||||||
'translations' => $translations,
|
'translations' => $translations,
|
||||||
'show_available_translations' => wp_can_install_language_pack(),
|
'show_available_translations' => current_user_can( 'install_languages' ),
|
||||||
) );
|
) );
|
||||||
?>
|
?>
|
||||||
</td>
|
</td>
|
||||||
|
@ -66,7 +66,9 @@ if ( isset($_REQUEST['action']) && 'add-site' == $_REQUEST['action'] ) {
|
|||||||
if ( isset( $_POST['WPLANG'] ) ) {
|
if ( isset( $_POST['WPLANG'] ) ) {
|
||||||
if ( '' === $_POST['WPLANG'] ) {
|
if ( '' === $_POST['WPLANG'] ) {
|
||||||
$meta['WPLANG'] = ''; // en_US
|
$meta['WPLANG'] = ''; // en_US
|
||||||
} elseif ( wp_can_install_language_pack() ) {
|
} elseif ( in_array( $_POST['WPLANG'], get_available_languages() ) ) {
|
||||||
|
$meta['WPLANG'] = $_POST['WPLANG'];
|
||||||
|
} elseif ( current_user_can( 'install_languages' ) ) {
|
||||||
$language = wp_download_language_pack( wp_unslash( $_POST['WPLANG'] ) );
|
$language = wp_download_language_pack( wp_unslash( $_POST['WPLANG'] ) );
|
||||||
if ( $language ) {
|
if ( $language ) {
|
||||||
$meta['WPLANG'] = $language;
|
$meta['WPLANG'] = $language;
|
||||||
@ -234,7 +236,7 @@ if ( ! empty( $messages ) ) {
|
|||||||
'selected' => $lang,
|
'selected' => $lang,
|
||||||
'languages' => $languages,
|
'languages' => $languages,
|
||||||
'translations' => $translations,
|
'translations' => $translations,
|
||||||
'show_available_translations' => wp_can_install_language_pack(),
|
'show_available_translations' => current_user_can( 'install_languages' ),
|
||||||
) );
|
) );
|
||||||
?>
|
?>
|
||||||
</td>
|
</td>
|
||||||
|
@ -151,7 +151,7 @@ if ( ! empty( $languages ) || ! empty( $translations ) ) {
|
|||||||
'selected' => $locale,
|
'selected' => $locale,
|
||||||
'languages' => $languages,
|
'languages' => $languages,
|
||||||
'translations' => $translations,
|
'translations' => $translations,
|
||||||
'show_available_translations' => ( ! is_multisite() || is_super_admin() ) && wp_can_install_language_pack(),
|
'show_available_translations' => current_user_can( 'install_languages' ),
|
||||||
) );
|
) );
|
||||||
|
|
||||||
// Add note about deprecated WPLANG constant.
|
// Add note about deprecated WPLANG constant.
|
||||||
|
@ -177,14 +177,12 @@ if ( 'update' == $action ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Handle translation install.
|
// Handle translation install.
|
||||||
if ( ! empty( $_POST['WPLANG'] ) && ( ! is_multisite() || is_super_admin() ) ) { // @todo: Skip if already installed
|
if ( ! empty( $_POST['WPLANG'] ) && current_user_can( 'install_languages' ) ) {
|
||||||
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
|
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
|
||||||
|
|
||||||
if ( wp_can_install_language_pack() ) {
|
$language = wp_download_language_pack( $_POST['WPLANG'] );
|
||||||
$language = wp_download_language_pack( $_POST['WPLANG'] );
|
if ( $language ) {
|
||||||
if ( $language ) {
|
$_POST['WPLANG'] = $language;
|
||||||
$_POST['WPLANG'] = $language;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ if ( is_multisite() && ! is_network_admin() ) {
|
|||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ! current_user_can( 'update_core' ) && ! current_user_can( 'update_themes' ) && ! current_user_can( 'update_plugins' ) )
|
if ( ! current_user_can( 'update_core' ) && ! current_user_can( 'update_themes' ) && ! current_user_can( 'update_plugins' ) && ! current_user_can( 'update_languages' ) )
|
||||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -608,15 +608,19 @@ if ( 'upgrade-core' == $action ) {
|
|||||||
echo ' <a class="button" href="' . esc_url( self_admin_url('update-core.php?force-check=1') ) . '">' . __( 'Check Again' ) . '</a>';
|
echo ' <a class="button" href="' . esc_url( self_admin_url('update-core.php?force-check=1') ) . '">' . __( 'Check Again' ) . '</a>';
|
||||||
echo '</p>';
|
echo '</p>';
|
||||||
|
|
||||||
if ( $core = current_user_can( 'update_core' ) )
|
if ( current_user_can( 'update_core' ) ) {
|
||||||
core_upgrade_preamble();
|
core_upgrade_preamble();
|
||||||
if ( $plugins = current_user_can( 'update_plugins' ) )
|
}
|
||||||
|
if ( current_user_can( 'update_plugins' ) ) {
|
||||||
list_plugin_updates();
|
list_plugin_updates();
|
||||||
if ( $themes = current_user_can( 'update_themes' ) )
|
}
|
||||||
|
if ( current_user_can( 'update_themes' ) ) {
|
||||||
list_theme_updates();
|
list_theme_updates();
|
||||||
if ( $core || $plugins || $themes )
|
}
|
||||||
|
if ( current_user_can( 'update_languages' ) ) {
|
||||||
list_translation_updates();
|
list_translation_updates();
|
||||||
unset( $core, $plugins, $themes );
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires after the core, plugin, and theme update tables.
|
* Fires after the core, plugin, and theme update tables.
|
||||||
*
|
*
|
||||||
@ -729,7 +733,7 @@ if ( 'upgrade-core' == $action ) {
|
|||||||
|
|
||||||
} elseif ( 'do-translation-upgrade' == $action ) {
|
} elseif ( 'do-translation-upgrade' == $action ) {
|
||||||
|
|
||||||
if ( ! current_user_can( 'update_core' ) && ! current_user_can( 'update_plugins' ) && ! current_user_can( 'update_themes' ) )
|
if ( ! current_user_can( 'update_languages' ) )
|
||||||
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
wp_die( __( 'Sorry, you are not allowed to update this site.' ) );
|
||||||
|
|
||||||
check_admin_referer( 'upgrade-translations' );
|
check_admin_referer( 'upgrade-translations' );
|
||||||
|
@ -392,6 +392,20 @@ function map_meta_cap( $cap, $user_id ) {
|
|||||||
$caps[] = $cap;
|
$caps[] = $cap;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'install_languages':
|
||||||
|
case 'update_languages':
|
||||||
|
if ( ! function_exists( 'wp_can_install_language_pack' ) ) {
|
||||||
|
require_once( ABSPATH . 'wp-admin/includes/translation-install.php' );
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! wp_can_install_language_pack() ) {
|
||||||
|
$caps[] = 'do_not_allow';
|
||||||
|
} elseif ( is_multisite() && ! is_super_admin( $user_id ) ) {
|
||||||
|
$caps[] = 'do_not_allow';
|
||||||
|
} else {
|
||||||
|
$caps[] = 'install_languages';
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'activate_plugins':
|
case 'activate_plugins':
|
||||||
$caps[] = $cap;
|
$caps[] = $cap;
|
||||||
if ( is_multisite() ) {
|
if ( is_multisite() ) {
|
||||||
@ -826,3 +840,22 @@ function revoke_super_admin( $user_id ) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the user capabilities to grant the 'install_languages' capability as necessary.
|
||||||
|
*
|
||||||
|
* A user must have at least one out of the 'update_core', 'install_plugins', and
|
||||||
|
* 'install_themes' capabilities to qualify for 'install_languages'.
|
||||||
|
*
|
||||||
|
* @since 4.9.0
|
||||||
|
*
|
||||||
|
* @param array $allcaps An array of all the user's capabilities.
|
||||||
|
* @return array Filtered array of the user's capabilities.
|
||||||
|
*/
|
||||||
|
function wp_maybe_grant_install_languages_cap( $allcaps ) {
|
||||||
|
if ( ! empty( $allcaps['update_core'] ) || ! empty( $allcaps['install_plugins'] ) || ! empty( $allcaps['install_themes'] ) ) {
|
||||||
|
$allcaps['install_languages'] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $allcaps;
|
||||||
|
}
|
||||||
|
@ -512,4 +512,7 @@ add_filter( 'oembed_dataparse', 'wp_filter_oembed_result', 10, 3 );
|
|||||||
add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
|
add_filter( 'oembed_response_data', 'get_oembed_response_data_rich', 10, 4 );
|
||||||
add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 );
|
add_filter( 'pre_oembed_result', 'wp_filter_pre_oembed_result', 10, 3 );
|
||||||
|
|
||||||
|
// Capabilities
|
||||||
|
add_filter( 'user_has_cap', 'wp_maybe_grant_install_languages_cap', 1 );
|
||||||
|
|
||||||
unset( $filter, $action );
|
unset( $filter, $action );
|
||||||
|
@ -233,6 +233,8 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
|
|||||||
'upload_themes' => array( 'administrator' ),
|
'upload_themes' => array( 'administrator' ),
|
||||||
'customize' => array( 'administrator' ),
|
'customize' => array( 'administrator' ),
|
||||||
'add_users' => array( 'administrator' ),
|
'add_users' => array( 'administrator' ),
|
||||||
|
'install_languages' => array( 'administrator' ),
|
||||||
|
'update_languages' => array( 'administrator' ),
|
||||||
|
|
||||||
'edit_categories' => array( 'administrator', 'editor' ),
|
'edit_categories' => array( 'administrator', 'editor' ),
|
||||||
'delete_categories' => array( 'administrator', 'editor' ),
|
'delete_categories' => array( 'administrator', 'editor' ),
|
||||||
@ -261,6 +263,8 @@ class Tests_User_Capabilities extends WP_UnitTestCase {
|
|||||||
'upload_themes' => array(),
|
'upload_themes' => array(),
|
||||||
'edit_css' => array(),
|
'edit_css' => array(),
|
||||||
'upgrade_network' => array(),
|
'upgrade_network' => array(),
|
||||||
|
'install_languages' => array(),
|
||||||
|
'update_languages' => array(),
|
||||||
|
|
||||||
'customize' => array( 'administrator' ),
|
'customize' => array( 'administrator' ),
|
||||||
'delete_site' => array( 'administrator' ),
|
'delete_site' => array( 'administrator' ),
|
||||||
|
Loading…
Reference in New Issue
Block a user