Pro sites - limit sites per user per level

Hi,

I'm attempting to add some bespoke code to limit the number of sites per user per level using pro sites and wanted to check if there any hooks I can use to:-

1) Obtain the number of sites created per user.
2) What level a user has subscribed to.

I'm hoping if I can obtain this information I can add some bespoke code to limit the user to a number of sites per level.

Regards
SteveB

  • Predrag Dubajic

    Hey Steve,

    Hope you're doing well today :slight_smile:

    I must say that I'm not sure about this and I'll need to check with the developers for more information so I've flagged this thread to our second level support devs.

    Please note that, developer response might be slower than usual staff response, so we appreciate your patience on this.

    For number of sites you may want to check this thread:
    https://premium.wpmudev.org/forums/topic/no-of-sites-per-level-on-prosite

    Best regards,
    Predrag

  • Matej

    Hi SteveB,

    interesting question, I was thinking something same for my site. However I end up disabling option for user to have multiple networks on one account. I thought about your problem and I have some ideas.

    So the first thing is where will you limit signup option. Probably when logged in user opens wp-signup.php. That's what I would do and I would put this code in my child theme for main page. So that other users of your multisite (if they using same theme) don't have this customization.

    So first of all we need to edit some options on wp-signup.php

    add_action( 'signup_extra_fields' , 'custom_signup_extra_fields' );
    
    function custom_signup_extra_fields( $errors ) {
    	//code here
    }

    Now we need user id to check if user is logged and get main blog id ($primary_blog_id) and pro-sites level ($primary_blog_level) of that blog. Also notice that I am using default prefix of wordpress installation "wp_".

    if ( is_user_logged_in() ){
    	global $wpdb;
    	$primary_blog_id = $wpdb->get_var("SELECT meta_value FROM wp_usermeta WHERE meta_key=primary_blog AND user_id ='" . $user_id . "'");
    	$primary_blog_level = $wpdb->get_var( "SELECT level FROM wp_pro_sites WHERE blog_ID ='" . $primary_blog_id . "'");
    }

    This is how far I came when trying to solve this problem. I think you can look at some ideas how to go forward. We need to get COUNT of networks registered by same user. This is problem. I currently don't have time to find solution... but here is link that can help you: https://developer.wordpress.org/reference/functions/get_blogs_of_user/

    Great. Now we know user_id, primary_blog_id and primary_blog_level. We can use this options to continue on this customization. We need to set some limit's so that if pro-site level is 1 or 2. There may be more if you added more levels in pro-sites settigns page.

    The idea is if number of blogs > your limit disable ... look at: https://mu.wordpress.org/forums/topic/2361

    I hope It was somehow helpful.

  • pxwm

    Hi Predrag - Many thanks and I'll wait for the developer's thoughts

    Hi Matej - Many thanks for your ideas, very useful.

    To confirm all users will be site limited by Pro Site level(s) so I could place the code in a single child theme functions.php file.

    I'm hoping I've identified some code to determine the number of Blog sites by user and I may have some code to determine the Pro Site level the user has subscribed to.

    However before trying I'm hoping the developer may be able to provide some hooks I can use to obtain the information.

    Thanks agin for your thoughts.

    Regards
    SteveB

  • Adam Czajczyk

    Hello SteveB!

    I'm afraid I don't have a response for you yet. I realize that some time has passed already and I'm sorry for keeping you waiting. Developers are usually quite busy with a "current stuff" such as updates and bug fixing so in case of a solution that's not an implemented feature it may take some more time. I or one of my colleagues - we'll update this thread as soon as we get a word about on the issue.

    Best regards,
    Adam

  • Dimitris

    Hey there pxwm,

    hope you're doing good and I'm deeply sorry for the late feedback here!
    It's true that we are used to faster replies.
    Our SLS team has multiple issues to deal with though, this should have been skipped somehow so I nagged to our devs about it. Me or another colleague of mine will keep you posted as soon as possible! Once again, I'm sorry for any frustration here!

    Warm regards,
    Dimitris

  • Lindeni Mahlalela

    Hell pxwm.

    I hope you are doing well today and thank you for your patience so far.

    One thing you need to note before we proceed is that Pro Sites does not work on a per user basis but per site basis so it makes thing a little bit difficult if you want to limit the sites per user as wordpress itself works on a per site basis.

    With that said, I have done some research and some coding to find a way to achieve what you want to achieve and as a result I ended with an almost working Pro Sites addon from which you can build your functionality.

    My solution relies heavily on the two action hooks below.

    add_action('signup_header', array($this, 'set_blog_creation_limit') );	//for standard wordpress
    add_action('signup_blogform', array(&$this, 'set_blog_creation_limit') ); //pro sites signup form

    Where the function 'set_blog_creation_limit' will get the blogs of the user, get the level for each blog and then count and compare the number of blogs per level. If one of the limits have been reached, then the user will not see the signup form but the error message saying the limits were reached.

    Here is how I wrote the whole thing as a complete plugin which you can install and activate on your multisite:

    <?php
    /*
      Plugin Name: Limit Blogs per User
      Plugin Author: WPMUDEV
      Author URI: premium.wpmudev.org
      Description: Limit number of blogs a user can register on a multisite.
    */
    
    add_action('signup_header', 'set_blog_creation_limit') ;
    add_action('signup_blogform', 'set_blog_creation_limit') ;
    
    function set_blog_creation_limit() {
    	global $psts;
    
    	if ( is_user_logged_in() ){
    		$user_id = get_current_user_id();
    		$blogs_of_user = get_blogs_of_user( $user_id );
    	}
    
    	$blogs = get_blogs_of_user($user_id);
    
    	//you should store and retrieve these values from the database
    	$limit_blogs = 10; //$psts->get_setting('psts-limit-blogs');
    	$limit_per_level = 2; //$psts->get_setting('psts-limit-per-level');
    
    	switch_to_blog( 1);
    	$levels = (array) get_site_option( 'psts_levels' );
    	restore_current_blog();
    
    	$limit_level = false;
    	$count_pro_sites = 0;
    	$count_per_level = 0;
    	$count_free = 0;
    
    	$limit_reason = ""; //DEBUG
    
    	foreach ( $blogs as $blog ) {
    		$counted = array();
    		if ( is_pro_site( $blog->userblog_id ) && ! in_array( $blog->userblog_id, $counted) ) {
    
    			$count_pro_sites +=1;
    
    			$level = $psts->get_level_setting( $psts->get_level( $blog->userblog_id ) , 'name' );
    
    			if ( ! in_array ( $level, $levels )  && ! in_array( $blog->userblog_id, $counted) ) { //if not a free site
    				$count_per_level += 1;
    			}
    
    		}
    		elseif ( ! is_pro_site( $blog->userblog_id ) && ! in_array( $blog->userblog_id, $counted ) ){
    			$count_free += 1;
    		}
    
    		$counted[] = $blog->userblog_id;
    	}
    
    	if ( $count_per_level >= $limit_per_level ) {
    		$content .= _e('<p>You have reached the maximum number of blogs allowed per level.</p>');
    		$limit_blogs = true;
    
    		$limit_reason .= ", Limit per level reached."; //DEBUG
    	}
    
    	if ( $count_free >= $limit_per_level || $count_free >= $limit_blogs ) {
    		$content .= _e('<p>You have reached the maximum number of free sites you can register on the network.</p>');
    		$limit_blogs = true;
    
    		$limit_reason .= ", Free sites exceeds total or limit per level"; //DEBUG
    	}
    
    	if (  count($blogs) >= $limit_blogs  ) {
    		$content .= _e('<p>You have reached the total number of sites allowed per user on our network.</p>');
    		$limit_blogs = true;
    
    		$limit_reason .= ", Total limit reached"; //DEBUG
    	}
    
    	//DEBUG: uncomment to debug
    	//error_log ( "User ID : " . $this->user_id .", Num prosites : ". $count_pro_sites . ", Num Free Sites : ". $count_free . $limit_reason );
    
    	if ( $limit_blogs == true ){
    		wp_die( $content );
    	}
    }

    You may also download the attached 'limit-blogs-per-user.zip' file and install it to your network as a plugin. I have hard coded the limits but you should store and retrieve them on your database for ease of use.

    I have also turned this into an addon, but then the updates to Pro Sites will override the addon as implementing it involves modifying Pro Sites core files. If you are interested in it, just let me know I will give it to you with instructions on how to complete the implementation.

    I hope this helps you achieve all your goals. Please do let me know if you need more help with regards to this.

    Please enjoy your day further.

    Cheers,
    Mahlamusa

  • pxwm

    Hi Mahlamusa

    That's fantastic, many thanks.
    We've also been working on a solution so it will be good to compare.
    Looking at your code I can confirm the methods you have used in your plugin will be extremely useful to us when coming up with a final version.

    We are also having to hard code the site limits per pro-site level but we are hoping to set these either through creating a backend settings page for the plugin and allowing superadmin to override per user.

    Again many thanks.

    Regards
    SteveB

  • Lindeni Mahlalela

    Hi pxwm,

    I am glad you are in the right direction with your development. In order to be able to test the module I developed, you will have to modify some core Pro Sites files. So you should do this in your development server.

    Here is what you need to do:

    In the file: '/pro-sites/pro-sites-files/lib/ProSites/Helper/Settings.php'
    inside function get tabs, I added the code

    'limitblogs' => array_merge( $section_options, array(
    	'title' => __( 'Limit Blogs and Levels', 'psts' ),
    	'desc'  => array(
    		__( 'Allows you to limit the number of blogs a user can have in total and the number of blogs a user can have per level.', 'psts' ),
    	),
    ) ),

    inside the $tabs array of the get_tabs() function and added the code

    if ( ! in_array( 'ProSites_Module_LimitUserBlogs', $modules ) ) {
    	unset( $tabs['limitblogs'] );
    }

    above $modules = array( ...

    in the function remove_disabled_module_tabs(){}, then in the same function modified $modules = array() by adding the element: 'ProSites_Module_LimitUserBlogs', at the end

    In the file: '/pro-sites/pro-sites-files/lib/ProSites/View/Settings.php'
    add the following function at the bottom of the class

    public static function render_tab_limitblogs() {
    	ProSites_Helper_Settings::settings_header( ProSites_Helper_Tabs_Settings::get_active_tab() );
    	$module = new ProSites_Module_LimitUserBlogs();
    	echo $module->settings();
    }

    In the file: '/pro-sites/pro-sites-files/plugins-loader.php'

    add 'ProSites_Module_LimitUserBlogs' => 'limitblogs',

    to 'public static $modules = array(..., 'ProSites_Module_LimitUserBlogs' => 'limitblogs',);

    Then finally upload the file 'limitblogs.php' from the attached file into the folder '/pro-sites/pro-sites-files/modules/', make sure to extract the zip file and upload the .php file alone not with its folder.

    Then go to your wordpress dashboard and click on "Settings > Modules" and you should see the new module. Activate it and go to "Pro Sites > Settings" and you should see a new tab for "Limit Blogs and Levels", you should see the settings page has 2 options from which you can expand your options.

    I hope this helps you in your development.

    Cheers,
    Mahlamusa

Thank NAME, for their help.

Let NAME know exactly why they deserved these points.

Gift a custom amount of points.