Put this in a .php file, upload it as a plugin, and network activate it. Read the comments in the code for more information.
Let me know if you have questions or if it does not work well for you. I made it so Super Administrators can use all sites no matter what.
<?php
/*
Plugin Name: No Role No Login
Description: If the user in a multisite has no role for a site, he will not be able to access it while logged in. Does not affect super administrators.
Author: Nikolay Nikolov
Version: 1.0.0
*/
add_action( 'init', 'no_role_no_login' );
function no_role_no_login() {
// If the user is logged-in and not a super administrator we continue
if ( is_user_logged_in() && ! current_user_can( 'manage_network' ) ) {
// If this is a logout attempt, we do nothing, so we allow it
if ( ( ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' === $GLOBALS['pagenow'] )
|| ( isset( $_SERVER['PHP_SELF'] ) && '/wp-login.php' === $_SERVER['PHP_SELF'] ) )
&& isset( $_GET['action'] ) && 'logout' === $_GET['action'] ) {
// If this is not a logout attempt, we will check if the user has a role for the site and deny access if he does not (and show a message)
} else {
$get_users = get_users(
array(
'blog_id' => get_current_blog_id(),
'include' => array( get_current_user_id() )
)
);
if ( empty( $get_users ) ) {
wp_die( 'You cannot access this site while logged in. To view it, you have to <a href="' . wp_logout_url() . '">logout</a>.' );
}
}
}
}