Themes: Block theme activation if it requires a higher version of PHP or WordPress.

Introduce `validate_theme_requirements()` for validating a theme's WordPress and PHP version requirements.

Follow-up to [44978] and [45546] for plugins.

Props afragen, audrasjb, SergeyBiryukov.
See #43992.

git-svn-id: https://develop.svn.wordpress.org/trunk@47573 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Sergey Biryukov 2020-04-13 15:26:37 +00:00
parent d5df031e6f
commit 286d672389

View File

@ -733,6 +733,11 @@ function locale_stylesheet() {
function switch_theme( $stylesheet ) { function switch_theme( $stylesheet ) {
global $wp_theme_directories, $wp_customize, $sidebars_widgets; global $wp_theme_directories, $wp_customize, $sidebars_widgets;
$requirements = validate_theme_requirements( $stylesheet );
if ( is_wp_error( $requirements ) ) {
wp_die( $requirements );
}
$_sidebars_widgets = null; $_sidebars_widgets = null;
if ( 'wp_ajax_customize_save' === current_action() ) { if ( 'wp_ajax_customize_save' === current_action() ) {
$old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' ); $old_sidebars_widgets_data_setting = $wp_customize->get_setting( 'old_sidebars_widgets_data' );
@ -880,6 +885,78 @@ function validate_current_theme() {
return false; return false;
} }
/**
* Validates the theme requirements for WordPress version and PHP version.
*
* Uses the information from `Requires at least` and `Requires PHP` headers
* defined in the theme's `style.css` file.
*
* If the headers are not present in the theme's stylesheet file,
* `readme.txt` is also checked as a fallback.
*
* @since 5.5.0
*
* @param string $stylesheet Directory name for the theme.
* @return true|WP_Error True if requirements are met, WP_Error on failure.
*/
function validate_theme_requirements( $stylesheet ) {
$theme = wp_get_theme( $stylesheet );
$requirements = array(
'requires' => ! empty( $theme->get( 'RequiresWP' ) ) ? $theme->get( 'RequiresWP' ) : '',
'requires_php' => ! empty( $theme->get( 'RequiresPHP' ) ) ? $theme->get( 'RequiresPHP' ) : '',
);
$readme_file = $theme->theme_root . '/' . $stylesheet . '/readme.txt';
if ( file_exists( $readme_file ) ) {
$readme_headers = get_file_data(
$readme_file,
array(
'requires' => 'Requires at least',
'requires_php' => 'Requires PHP',
),
'theme'
);
$requirements = array_merge( $readme_headers, $requirements );
}
$compatible_wp = is_wp_version_compatible( $requirements['requires'] );
$compatible_php = is_php_version_compatible( $requirements['requires_php'] );
if ( ! $compatible_wp && ! $compatible_php ) {
return new WP_Error(
'theme_wp_php_incompatible',
sprintf(
/* translators: %s: Theme name. */
_x( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.', 'theme' ),
$theme->display( 'Name' )
)
);
} elseif ( ! $compatible_php ) {
return new WP_Error(
'theme_php_incompatible',
sprintf(
/* translators: %s: Theme name. */
_x( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.', 'theme' ),
$theme->display( 'Name' )
)
);
} elseif ( ! $compatible_wp ) {
return new WP_Error(
'theme_wp_incompatible',
sprintf(
/* translators: %s: Theme name. */
_x( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.', 'theme' ),
$theme->display( 'Name' )
)
);
}
return true;
}
/** /**
* Retrieve all theme modifications. * Retrieve all theme modifications.
* *