Restrict usage of a Network Activated plugin

Hi there!

I wonder if you could add your own made plugins (or others) that need to be network activated to work on Pro Sites.

For example: Restrict access to /wp-admin/myplugin.php for anyone lower than level 2 Pro Sites.

It shouldn't be that hard, the question is really: What piece of code needs to be placed where? Both in the self-made plugin and the Pro Site's core code, or only in the Pro-Sites code?

I would like this to be lightened up. Thanks :slight_smile:

  • Tyler Postle

    Hey Sybre,

    Hope you're doing well today!

    Which plugins are you referring to here?

    I am going to mark this as a feature request so the developer will see it and can consider it for a future update, I think it's a cool idea :slight_smile:

    Perhaps we can come up with a workaround in the meantime. You could use the admin menu editor plugin to hide menu items per user role level then create a separate user role for each access level. You can create user roles with the user role editor plugin.

    If the plugin has it's own custom capabilities for it then you can restrict access right through the user role editor.

    Hope this helps! Let me know what you think :slight_smile:

    All the best,
    Tyler

  • aristath

    Hello again @Sybre, I hope you're well today!

    You can determine the current site's pro-sites level and do what you want using the code below:

    <?php
    
    global $wpdb;
    $blog_id = $wpdb->blogid;
    
    $sql = "SELECT level FROM {$wpdb->base_prefix}pro_sites WHERE blog_ID = '$blog_id'";
    
    $level = $wpdb->get_var($sql);
    
    if ( 1 == $level ) {
      // Do something if level 1
    } elseif ( 2 == $level ) {
      // Do something if level 2
    } elseif ( 3 == $level ) {
      // Do something if level 3
    }

    I hope that helps!

    Cheers,
    Ari.

  • Sybre Waaijer

    Looks brilliant Ari!

    In the related topics I found something else, which supports your Pro Site plugin!

    http://wordpress.org/plugins/multisite-plugin-manager/

    Related topic: https://premium.wpmudev.org/forums/topic/how-do-i-control-access-to-certian-plugins

    I'll test that out first, if that fails I'll go straight ahead with your code :')

    Thanks and have a great day!

    EDIT: It doesn't work as I intended, onward to coding D:

  • Sybre Waaijer

    I created a plugin from it, enjoy!

    <?php
    /*
    Plugin Name: Pro Site Extras [Multisite module]
    Plugin URI: https://hostmijnpagina.nl/
    Description: Lets you remove admin menu items if user has no paid Pro Site subscription.
    Author: Sybre Waaijer
    Author URI: https://cyberwire.nl/
    */
    
    /**
    Install this as a php file in /wp-content/mu-plugins
    
    This plugin restricts access to the "delete site" option if a user has a Pro Site subscription.
    
    This plugin restricts access to the export site function and Domain Mapping plugin if a user has no Pro Site subscription.
    
    There is no WordPress admin menu for this plugin. All menu items should be managed whitin this file. I'm sorry but you have to do all the work on this one for each new menu item you want to remove from users.
    **/
    
    global $wpdb;
    $blog_id = $wpdb->blogid;
    
    function wpmu_remove_menu() {
    if(is_pro_site($blog_id, $level)) { //For all Pro Site levels
           remove_menu_page('ms-delete-site.php');
        }
    if(is_pro_site($blog_id, $level) ==false) { //Free Level
    	remove_menu_page('Domain Mapping', 'wordpress-mu-domain-mapping', 'domainmapping');
        remove_menu_page('export.php');
    	}
    }
    
    add_action( 'admin_init', 'wpmu_remove_menu' );
    
    function no_permission_admin_redirect() {
        if(is_pro_site($blog_id, $level)) { //For all Pro Site levels
            if (stripos($_SERVER['REQUEST_URI'],'ms-delete-site.php') !== false) {
                wp_redirect(get_option('siteurl') . '/wp-admin/index.php?permissions_error=true');
            }
        }
    	if(is_pro_site($blog_id, $level) ==false) { //Free Level
    		if (stripos($_SERVER['REQUEST_URI'],'tools.php?page=domainmapping') !== false
                || stripos($_SERVER['REQUEST_URI'],'export.php') !== false) {
    		wp_redirect(get_option('siteurl') . '/wp-admin/index.php?permissions_error=true');
    		}
    	}
    }
    add_action('admin_menu','no_permission_admin_redirect');
    
    function no_permissions_admin_notice() {
            echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Your custom error message')."</strong></p></div>";
        }
    
    function no_permissions_show_notice() {
            if(isset($_GET['permissions_error']) && $_GET['permissions_error']) {
                add_action('admin_notices', 'no_permissions_admin_notice');
            }
        }
    add_action('admin_init','no_permissions_show_notice');

    Credits to code: @Ashok - https://premium.wpmudev.org/forums/topic/hiding-wp-panel-with-pro-sites

    I think this is pretty much what you have done on Edublogs, but then you created a link to the pro-site payment page instead of an error. In regards for Forums and BuddyPress?

  • Sybre Waaijer

    I noticed, tracking my changes back, that this plugin I created added a few megabytes of error lines in the error log.

    This is the first error of it's kind, recreating itself every few seconds, sometimes even multiple times a second:
    [15-Aug-2014 18:21:42 UTC] PHP Warning: Invalid argument supplied for foreach() in /../plugin.php on line 1395

    However, after a while it stopped, changed itself into this error every few seconds:
    [05-Sep-2014 11:22:31 UTC] PHP Warning: Invalid argument supplied for foreach() in /../plugin.php on line 1401

    Any idea's?

    This is the code it's referring to:

    function remove_menu_page( $menu_slug ) {
    	global $menu;
    
    	foreach ( $menu as $i => $item ) { // line 1401
    		if ( $menu_slug == $item[2] ) {
    			unset( $menu[$i] );
    			return $item;
    		}
    	}
    
    	return false;
    }
  • Sybre Waaijer

    Alright, rewritten the code to be more flexible and determined, I am getting "undefined variable" errors though on every line which tries to call $level (e.g.
    if( $level >= 1) {)

    Notice: Undefined variable: level in /../mu-plugins/pro-site-extras.php on line 32 (35,45 and 50 as well)

    I haven't used the is_array function since these kind of errors aren't reporting anymore and seems to be related to another plugin (still investigating it though :slight_smile: ).

    Anyway, the plugin below isn't working as intended. It treats every blog as level 0, aka Free, even if it has a Pro Subscription.
    It seems it can either not determine the site which is being used at the moment or that the whole $level thing is ignored in some way.

    <?php
    /*
    Plugin Name: Pro Site Extras [Multisite module]
    Plugin URI: https://hostmijnpagina.nl/
    Description: Lets you remove admin menu items if user has no paid Pro Site subscription.
    Author: Sybre Waaijer
    Author URI: https://cyberwire.nl/
    */
    
    /**
    Install this as a php file in /wp-content/mu-plugins
    
    This plugin restricts access to the "delete site" option if a user has a Pro Site subscription.
    
    This plugin restricts access to the export site function and Domain Mapping plugin if a user has no Pro Site 
    
    subscription.
    
    There is no WordPress admin menu for this plugin. All menu items should be managed whitin this file. I'm sorry but you 
    
    have to do all the work on this one for each new menu item you want to remove from users.
    **/
    
    global $wpdb;
    $blog_id = get_current_blog_id();
    
    $sql = "SELECT level FROM {$wpdb->base_prefix}_pro_sites WHERE blog_ID = '$blog_id'";
    
    $level = $wpdb->get_var($sql);
    
    function wpmu_remove_menu() {
    	if( $level >= 1) { //For all Pro Site Subscriptions
    		remove_submenu_page('ms-delete-site.php');
    	}
    	if( $level == 0) { //Free Level
    		remove_submenu_page('tools.php', 'wordpress-mu-domain-mapping');
    		remove_menu_page('export.php');
    	}
    }
    
    add_action( 'admin_init', 'wpmu_remove_menu' );
    add_action('admin_menu','wpmu_remove_menu' );
    
    function no_permission_admin_redirect() {
    	if( $level >= 1 ) { //For all Pro Site Subscriptions
    		if (stripos($_SERVER['REQUEST_URI'],'ms-delete-site.php') !== false) {
    			wp_redirect(get_option('siteurl') . '/wp-admin/index.php?toegang_geweigerd=true');
    		}
    	}
    	if( $level == 0 ) { //Free Level
    		if (stripos($_SERVER['REQUEST_URI'],'tools.php?page=domainmapping') !== false
    			|| stripos($_SERVER['REQUEST_URI'],'export.php') !== false) {
    		wp_redirect(get_option('siteurl') . '/wp-admin/index.php?toegang_geweigerd=true');
    		}
    	}
    }
    
    add_action('admin_menu','no_permission_admin_redirect');
    
    function no_permissions_admin_notice() {
    	echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Your custom error message')."</strong></p></div>";
    }
    
    function no_permissions_show_notice() {
    	if(isset($_GET['toegang_geweigerd']) && $_GET['toegang_geweigerd']) {
    		add_action('admin_notices', 'no_permissions_admin_notice');
    	}
    }
    add_action('admin_init','no_permissions_show_notice');

    Oh, toegang_geweigerd is Dutch for access_denied

    ------

    EDIT:
    Tested it, $level returns null and/or 0.

  • Sybre Waaijer

    Alright, I FINALLY (after about 12 years) found the use of the function (thanks to the is_supporter code) is_pro_site.

    Determined the following by this code:

    echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Level is ') .('gratis'). is_pro_site($blog_id,$level=0) .('basic'). is_pro_site($blog_id,$level=1) .('pro'). is_pro_site($blog_id,$level=2) .('business'). is_pro_site($blog_id,$level=3) ."</strong></p></div>";

    That a free level will send out a TRUE if level=0 and a false is level is above 0.
    And a "Business" (Pro level 3) will send out a TRUE for anything below level 3. This means that's it's possible, though hard, to determine which blog has what pro site.

    I think I can move on with this now and will report back when it's fixed :slight_smile:

  • Sybre Waaijer

    Returning back with a slab of code that would determine the EXACT level of a blog, got any ideas for optimization? Any tips and help would be appriciated :slight_smile: (ps. I haven't tested this code yet)

    function pro_is_0() { // free level
    	if ( is_pro_site($blog_id,$level=0) xor is_pro_site($blog_id,$level=1) ) {
    		return true;
    	}
    }
    
    function pro_is_1() { // lowest pro level
    	if ( is_pro_site($blog_id,$level=1) xor is_pro_site($blog_id,$level=2) ) {
    		return true;
    	}
    }
    
    function pro_is_2() { // higher pro level
    	if ( is_pro_site($blog_id,$level=2) xor is_pro_site($blog_id,$level=3) ) {
    		return true;
    	}
    }
    function pro_is_3() { // even higher pro level, etc. Continue this code until you've reached your highest pro level. For now, we have 3 pro levels, therefor "xor 4" in this code is not used
    	if ( is_pro_site($blog_id,$level=3) ) {
    		return true;
    	}
    }
  • Sybre Waaijer

    Alright, the code is done and working! To be used together with Pro Sites. Feel free to edit it however you like it. Just post it into /wp-content/mu-plugins/pluginname.php and it will work directly.

    <?php
    /*
    Plugin Name: Pro Site Extras [Multisite module]
    Plugin URI: https://hostmijnpagina.nl/
    Description: Lets you remove admin menu items if user has no paid Pro Site subscription.
    Author: Sybre Waaijer
    Author URI: https://cyberwire.nl/
    */
    
    /**
    Install this as a php file in /wp-content/mu-plugins
    This plugin restricts access to the "delete site" option if a user has a Pro Site subscription.
    This plugin restricts access to the export site function and Domain Mapping plugin if a user has no Pro Site subscription.
    There is no WordPress admin menu for this plugin. All menu items should be managed whitin this file. I'm sorry but you have to do all the work on this one for each new menu item you want to remove from users.
    **/
    
    $blog_id = get_current_blog_id();
    
    /**
    BEGIN Exact Pro Site Calculation
    A higher Pro site level will return True even is the asked pro level is LOWER. Therefor I made this code to exterminate higher levels from using a piece of code. pro_is_1 can only be used by a level 1 Pro user, not by a level 2+ or 0.
    **/
    
    function pro_is_0() { // free level
    	global $blog_id;
    	if ( is_pro_site($blog_id,$level=0) xor is_pro_site($blog_id,$level=1) ) {
    		return true;
    	}
    }
    
    /**
    ** UNUSED CODE (FOR NOW) **
    
    function pro_is_1() { // lowest pro level
    	global $blog_id;
    	if ( is_pro_site($blog_id,$level=1) xor is_pro_site($blog_id,$level=2) ) {
    		return true;
    	}
    }
    
    function pro_is_2() { // higher pro level
    	global $blog_id;
    	if ( is_pro_site($blog_id,$level=2) xor is_pro_site($blog_id,$level=3) ) {
    		return true;
    	}
    }
    
    function pro_is_3() { // even higher pro level, etc. Continue this code until you've reached your highest pro level. For now, we have 3 pro levels, therefor "xor 4" in this code is not used
    	global $blog_id;
    	if ( is_pro_site($blog_id,$level=3) ) {
    		return true;
    	}
    }
    
    **/
    
    /**
    END Exact Pro Site Calculation
    **/
    
    function wpmu_remove_menu() {
    	global $blog_id;
    	if( is_pro_site($blog_id,$level=1)) { //For all Pro Site Subscriptions
    		remove_submenu_page('tools.php', 'ms-delete-site.php');
    	}
    	if( pro_is_0() ) { //Free Level
    		remove_submenu_page('tools.php', 'wordpress-mu-domain-mapping');
    		remove_submenu_page('tools.php', 'export.php');
    	}
    }
    
    add_action( 'admin_init', 'wpmu_remove_menu' );
    
    function no_permission_admin_redirect() {
    	global $blog_id;
    	if( is_pro_site($blog_id,$level=1) ) { //For all Pro Site Subscriptions
    		if (stripos($_SERVER['REQUEST_URI'],'ms-delete-site.php') !== false) {
    			wp_redirect(get_option('siteurl') . '/wp-admin/index.php?del_permission_denied=true');
    		}
    	}
    	if( pro_is_0() ) { //Free Level
    		if ( stripos($_SERVER['REQUEST_URI'],'tools.php?page=domainmapping') !== false) {
    				wp_redirect(get_option('siteurl') . '/wp-admin/index.php?dm_permission_denied=true');
    		}
    	}
    	if (pro_is_0() ) {
    		if (stripos($_SERVER['REQUEST_URI'],'export.php') !== false) {
    			wp_redirect(get_option('siteurl') . '/wp-admin/index.php?exp_permission_denied=true');
    		}
    	}
    }
    
    add_action('admin_menu','no_permission_admin_redirect');
    
    function del_no_permissions_admin_notice() {
    		echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Pro Sites cannot delete their website. If you still wish to delete your website please contact us at support@example.com')."</strong></p></div>";
    }
    
    function dm_no_permissions_admin_notice() {
    		echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Free websites cannot use Domain Mapping.')."</strong></p></div>";
    }
    
    function exp_no_permissions_admin_notice() {
    		echo "<div id='permissions-warning' class='error fade'><p><strong>".__('Free websites cannot export their content.')."</strong></p></div>";
    }
    
    function no_permissions_show_notice() {
    	if(isset($_GET['del_permission_denied']) && $_GET['del_permission_denied']) {
    		add_action('admin_notices', 'del_no_permissions_admin_notice');
    	}
    	if(isset($_GET['dm_permission_denied']) && $_GET['dm_permission_denied']) {
    		add_action('admin_notices', 'dm_no_permissions_admin_notice');
    	}
    	if(isset($_GET['exp_permission_denied']) && $_GET['exp_permission_denied']) {
    		add_action('admin_notices', 'exp_no_permissions_admin_notice');
    	}
    }
    
    add_action('admin_init','no_permissions_show_notice');

    This plugin has been written because I wanted to use Automattic's Domain Mapping plugin (because of SSL issues with the, unfortunately much better in every other way, WPMUDEV's Domain Mapping plugin).

    While doing so, I took the liberty for removing certain features from users that could harm your (users) websites, like exporting a free website (it would be nasty if users just came to your website to build it, export it and delete it...) and deletion of a Pro Website.

    Most bugs are splattered, like the constant undefined errors.. Just 2 small bugs left but shouldn't remove its overall purpose:
    1. Export Site menu link isn't "removed", however a Free user cannot use it anyway.
    2. Delete Site menu link isn't "removed", however, a Pro user cannot use it anyway.

    I will see in the near future if your solution will help this plugin @Michelle Shull, for now, this plugin has been rewritten into what you see above and I'll look in my logs in a few days from now. On to the next project!

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.