Plugins: Block plugin activation if it requires a higher version of PHP or WordPress.

Introduce `validate_plugin_requirements()` for validating a plugin's WordPress and PHP version requirements.

Introduce `wp_is_wp_compatible()` and `wp_is_php_compatible()` for checking compatibility with the current WordPress or PHP version.

Props afragen, joyously, DrewAPicture, TimothyBlynJacobs, desrosj, flixos90, SergeyBiryukov.
See #43992.

git-svn-id: https://develop.svn.wordpress.org/trunk@44978 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Sergey Biryukov 2019-03-22 00:36:30 +00:00
parent f170c1dd31
commit 1586c43c8d
2 changed files with 81 additions and 0 deletions

View File

@ -597,6 +597,7 @@ function is_network_only_plugin( $plugin ) {
* ensure that the success redirection will update the error redirection.
*
* @since 2.5.0
* @since 5.2.0 Test for WordPress version and PHP version compatibility.
*
* @param string $plugin Path to the plugin file relative to the plugins directory.
* @param string $redirect Optional. URL to redirect to.
@ -621,6 +622,11 @@ function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silen
return $valid;
}
$requirements = validate_plugin_requirements( $plugin );
if ( is_wp_error( $requirements ) ) {
return $requirements;
}
if ( ( $network_wide && ! isset( $current[ $plugin ] ) ) || ( ! $network_wide && ! in_array( $plugin, $current ) ) ) {
if ( ! empty( $redirect ) ) {
wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) ); // we'll override this later if the plugin can be included without fatal error
@ -1060,6 +1066,55 @@ function validate_plugin( $plugin ) {
return 0;
}
/**
* Validate the plugin requirements for WP version and PHP version.
*
* @since 5.2.0
*
* @param string $plugin Path to the plugin file relative to the plugins directory.
* @return true|WP_Error True if requirements are met, WP_Error on failure.
*/
function validate_plugin_requirements( $plugin ) {
$readme_file = WP_PLUGIN_DIR . '/' . dirname( $plugin ) . '/readme.txt';
if ( file_exists( $readme_file ) ) {
$plugin_data = get_file_data(
$readme_file,
array(
'requires' => 'Requires at least',
'requires_php' => 'Requires PHP',
),
'plugin'
);
} else {
return true;
}
$plugin_data['wp_compatible'] = wp_is_wp_compatible( $plugin_data['requires'] );
$plugin_data['php_compatible'] = wp_is_php_compatible( $plugin_data['requires_php'] );
$plugin_data = array_merge( $plugin_data, get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ) );
if ( ! $plugin_data['wp_compatible'] && ! $plugin_data['php_compatible'] ) {
return new WP_Error( 'plugin_wp_php_incompatible', sprintf(
/* translators: %s: plugin name */
__( '<strong>Error:</strong> Current WordPress and PHP versions do not meet minimum requirements for %s.' ), $plugin_data['Name'] )
);
} elseif ( ! $plugin_data['php_compatible'] ) {
return new WP_Error( 'plugin_php_incompatible', sprintf(
/* translators: %s: plugin name */
__( '<strong>Error:</strong> Current PHP version does not meet minimum requirements for %s.' ), $plugin_data['Name'] )
);
} elseif ( ! $plugin_data['wp_compatible'] ) {
return new WP_Error( 'plugin_wp_incompatible', sprintf(
/* translators: %s: plugin name */
__( '<strong>Error:</strong> Current WordPress version does not meet minimum requirements for %s.' ), $plugin_data['Name'] )
);
}
return true;
}
/**
* Whether the plugin can be uninstalled.
*

View File

@ -6897,3 +6897,29 @@ function wp_direct_php_update_button() {
);
echo '</p>';
}
/**
* Checks compatibility with the current WordPress version.
*
* @since 5.2.0
*
* @param string $required Minimum required WordPress version.
* @return bool True if required version is compatible or empty, false if not.
*/
function wp_is_wp_compatible( $required ) {
$wp_version = get_bloginfo( 'version' );
return empty( $required ) || version_compare( $wp_version, $required, '>=' );
}
/**
* Checks compatibility with the current PHP version.
*
* @since 5.2.0
*
* @param string $required Minimum required PHP version.
* @return bool True if required version is compatible or empty, false if not.
*/
function wp_is_php_compatible( $required ) {
return empty( $required ) || version_compare( phpversion(), $required, '>=' );
}