Prevent network activation of plugin

I have a plugin that currently doesn’t support network activation. The best fix for this of course is to fix it 🙂 which I plan to do. However I wonder if there is a temporary solution I can use to prevent network activation in the meantime, perhaps a workflow similar to:

  1. Detect if the activation is network-wide (how??)
  2. Display message that it’s currently not supported, and I stink, I’m sorry
  3. Interrupt the activation or deactivate

Or, other suggestions accepted. Thanks.

Read More

For clarification: Multisite activation is fine, just not network-wide activation.

Related posts

Leave a Reply

4 comments

  1. The answers here are overthought and too complex. Why deactivating the plugin instead of preventing activation? Something as simple as calling die(‘your error message here) upon activation will do the job.

    function activate($networkwide) {
        if (is_multisite() && $networkwide) 
           die('This plugin can't be activated networkwide');
    }
    
    register_activation_hook('your-plugin/index.php','activate');
    

    Then when you try to activate in the panel, you will get a nice error on top of the page, with your error message.

  2. A plugin header Network: false will be ignored by WordPress … unfortunately. But the activation hook gets a parameter $network_wide, and we can use that to deactivate the plugin during activation:

    <?php
    /**
     * Plugin Name: Prevent Network Activation
     * Plugin URI:  http://wordpress.stackexchange.com/questions/76145/prevent-network-activation-of-plugin
     * Network:     false
     *
     * Note the 'Network' option will be ignored by WordPress.
     */
    
    register_activation_hook( __FILE__, 'pna_check_network_activation' );
    
    function pna_check_network_activation( $network_wide )
    {
        if ( ! $network_wide )
            return;
    
        deactivate_plugins( plugin_basename( __FILE__ ), TRUE, TRUE );
    
        header( 'Location: ' . network_admin_url( 'plugins.php?deactivate=true' ) );
        exit;
    }
    
  3. You could simply hide it from the network-plugins list.

    add_filter( 'all_plugins', 'wpse_76145_hide_network_plugin' );
    function wpse_76145_hide_network_plugin( $all )
    {
        global $current_screen;
    
        if( $current_screen->is_network )
            unset($all['akismet/akismet.php']);
    
        return $all;
    }
    

    And display a one-time network admin notice. Adapting the Q&A add_role() run only once?.

    add_action( 'network_admin_notices', 'wpse_76145_admin_notice' );
    
    function wpse_76145_admin_notice()
    { 
        global $current_screen;
        if( 'plugins-network' == $current_screen->id )
        {
            if ( wpse_25643_run_once( 'hide_akismet_network' ) )
                echo '<div class="error">Akismet not available in Network mode</div>';
        }
    }
    
    function wpse_25643_run_once( $key )
    {
        $test_case = get_option( 'run_once' );
    
        if ( isset( $test_case[$key] ) && $test_case[$key] )
        {
            return false;
        }
        else
        {
            $test_case[$key] = true;
            update_option( 'run_once',$test_case );
            return true;
        }
    }
    

    Or use this other technique: Add a notice to users upon first login to the admin area

  4. (This is untested)

    add_action( 'activated_plugin', 'wpse76145_no_network_activation',10,2 );
    function wpse76145_no_network_activation( $plugin, $network_wide){
    
       if( $plugin == 'myplugin/myplugin.php' && $network_wide ){
           //Plugin was network activated
    
           //Network deactivate
           deactivate_plugins( $plugin,false, true );
    
           //Activate on single site
           activate_plugins( $plugin);
    
           add_option('wpse76145_network_activate_notice',1);
       }
    
    }
    

    And then on admin_notices check for the wpse76145_network_activate_notice option and display notice.

    Note: It would be better not to hardcode ‘myplugin/myplugin.php’ – I think replacing it with plugin_basename(__FILE__); would work (and be preferable).

    Edit if multi-site activation is ok, then you could use switch_to_blog() to activate on each plug-in individually. I would still display a notice as you’ve not done what the user has asked.