Skip to content

Instantly share code, notes, and snippets.

@dartiss
Last active September 2, 2023 07:02
Show Gist options
  • Save dartiss/b7357bf26ccba4a8b4f785361cb39dc5 to your computer and use it in GitHub Desktop.
Save dartiss/b7357bf26ccba4a8b4f785361cb39dc5 to your computer and use it in GitHub Desktop.
WordPress function to perform certain validation checks on a plugin
/**
* Validate Plugin Requirements
*
* Deactivate the plugin if a minimum set of requirements aren't met.
*/
function validate_plugin_requirements() {
$exit = false;
$reasons = '';
// Override this, if necessary.
$plugin_basename = plugin_basename( __FILE__ );
// Check for a fork.
if ( function_exists( 'calmpress_version' ) || function_exists( 'classicpress_version' ) ) {
$exit = true;
$reasons .= '<li>' . __( 'A fork of WordPress was detected.', 'your-text-domain' ) . '</li>';
}
// Try and get plugin data from directory. If it can't be found above defaults will be used.
$plugins = get_plugins();
if ( array_key_exists( $plugin_basename, $plugins ) ) {
$minimum_wp = $plugins[ $plugin_basename ]['RequiresWP'];
$minimum_php = $plugins[ $plugin_basename ]['RequiresPHP'];
$name = $plugins[ $plugin_basename ]['Name'];
} else {
$name = __( 'The plugin', 'your-text-domain' );
$minimum_php = 0;
$minimum_wp = 0;
}
// Check for WordPress version.
if ( version_compare( get_bloginfo( 'version' ), $minimum_wp, '<' ) && ( false == $exit ) ) { // This second check is so that a WP check isn't performed on a fork (which may be using different version numbers anyway).
$exit = true;
/* translators: 1: minimum WordPress version, 2: the current WordPress version. */
$reasons .= '<li>' . sprintf( __( 'This plugin requires a minimum WordPress version of %1$s. This site is using WordPress %2$s.', 'your-text-domain' ), $minimum_wp, get_bloginfo( 'version' ) ) . '</li>';
}
// Check for PHP requirements.
if ( version_compare( PHP_VERSION, $minimum_php, '<' ) ) {
$exit = true;
/* translators: 1: minimum PHP version, 2: the current PHP version. */
$reasons .= '<li>' . sprintf( __( 'This plugin requires a minimum PHP level of %1$s. This site is using PHP %2$s.', 'your-text-domain' ), $minimum_php, PHP_VERSION ) . '</li>';
}
// If a reason was found, deactivate the plugin and output a message.
if ( $exit ) {
// Deactivate this plugin.
deactivate_plugins( $plugin_basename );
// Set up a message and output it via wp_die.
/* translators: 1: The plugin name. */
$message = '<p><b>' . sprintf( __( '%1$s has been deactivated', 'your-text-domain' ), $name ) . '</b></p><p>' . __( 'Reason:', 'your-text-domain' ) . '</p>';
/* translators: 1: The plugin name. */
$message .= '<ul>' . $reasons . '</ul><p>' . sprintf( __( 'The author of %1$s will not provide any support until the above are resolved.', 'your-text-domain' ), $name ) . '</p>';
$allowed = array(
'p' => array(),
'b' => array(),
'ul' => array(),
'li' => array(),
);
wp_die( wp_kses( $message, $allowed ), '', array( 'back_link' => true ) );
}
}
add_action( 'admin_init', 'validate_plugin_requirements' );
@dartiss
Copy link
Author

dartiss commented Sep 1, 2023

This is a combination of 2 previous Gists, but now with some added automation.

This function would be added to a plugin and checks that a minimum set of criteria are met. If not, a message is output and the plugin is deactivated. At the moment 3 checks are performed...

  1. Make sure the PHP level meets the minimum requirement
  2. Make sure the WordPress version meets the minimum requirement
  3. Make sure it's not running on a forked version of a WordPress (checks for CalmPress and ClassicPress)

1 and 2 minimum requirements are based on the meta in the README, which you'll need to make sure you specify. This is an example of what you need to add to the header...

Requires at least: 4.6
Requires PHP: 7.4

I should also note that both of these are not needed - recent versions of WordPress checks for this and prevents the plugin from being enabled. However, both are presented here of demonstrations of what you can do, particularly with looking up the meta data.

They also serve as a secondary lock, if the core solution doesn't work.

You will to change the text domain, which is currently set to your-text-domain.

If the function is added to your base plugin file then no further changes are required, otherwise, you'll need to add the basename to line 13 - this is in the format of {plugin folder}/{plugin name}.php.

Validated with PHPCS WordPress and WordPress VIP rulesets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment