Deactivate a plugin on wp version

The problem is not version_compare, the problem is that register_activation_hook is just a shortcut for

add_action( 'activate_' . $file, $function );

where $file is plugin_basename( __FILE__ ); and __FILE__ is your main plugin file absolute path.

So, what your code does is to call dw_deactivate_theme_options() when the action 'activate_' . $plugin is fired.

But this action is fired before the plugin is activated i.e. before the plugin is added to the option 'active_plugins'.

In short you are trying to deactivate a plugin that is not yet active and so your function does nothing.

There are 2 easy ways to avoid a plugin is activated under some conditions inside the function registered with register_activation_hook:

  1. the first is do a redirect:

    function dw_deactivate_theme_options() {
      if ( version_compare( get_bloginfo('version'), '4.0', '<') )  {
        global $status, $paged, $s;
        $url = self_admin_url( "plugins.php?plugin_status=$status&paged=$page&s=$s" );
        wp_redirect( $url );
        exit();
      }
    }
    

    this works, but users just see the page being reloaded and plugin not activated, but without any error message… it’s not very intuitive

  2. the second, probably better, way is die inside the function, in this way the plugin is not activated and you can give a feedback to users putting a message into die function:

    function dw_deactivate_theme_options() {
      if ( version_compare( get_bloginfo('version'), '4.0', '<') )  {
        $message = "Impossible activate Theme Settings plugin because ";
        $message .= "WordPress version is lower than 4.0";
        die( $message );
      }
    }
    

    In this way plugin is not activated and users see a message, even if WordPress will say that your plugin triggered a fatal error..

Check WP version before activate a plugin, and trigger error if check fail