Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I need to block access to all other content except Index,wp-login.php, register.php till the user login. how to accomplish it.

i created everthing but, when i try mysite.com/members it shows the page how to disable it..

share|improve this question
    
What did you create? –  soulseekah Oct 21 '11 at 9:48

4 Answers 4

Functional code written using PHP 5.3+ Closures. Read the comments throughout to understand concept and flow.

// Hook right before Themes kick in
add_action('wp', function(){
    // Allow viewing of home/front_page
    if(is_home() or is_front_page()) return;
    // Maybe allow access to archives (non singulars) to?
    // (when you hide important content after <!--more-->)
    // if(is_archive()) return; // Uncomment to allow access to archives
    // Allow access to BuddyPress registration/login page (experimental)
    if(is_callable('bb_get_location')){
        if(preg_match('~^(login|registration)-page$~i', bb_get_location())){
            return; // Allow access
        }
    }
    // Skip BuddyPress registration page directly (slightly experimental)
    if(is_page() and is_array($bp_pages = get_option('bp-pages'))){
        $current_page = get_queried_object_id();
        // Allow direct access to registration page
        if(!empty($bp_pages['register']) and ($bp_pages['register'] == $current_page)){
            return; // Bail on registration page
        }
        // If you also want access to other special BuddyPress pages do this:
        if(in_array($current_page, $bp_pages)){
            // return; // Uncomment me to allows access to them
        }
    }
    // Allow access to BBPress registration/login page (experimental)
    if(is_callable('bbp_get_query_name')){
        if(preg_match('~^bbp_(login|register)$~i', bbp_get_query_name())){
            return; // Allow access
        }
    }
    // If user is logged it let it be
    if(is_user_logged_in()) return;
    // Block Robots using X-Robots-Tag: header
    // (no point in allowing Robots to index this)
    if(!headers_sent()){ // Be defensive
        header('X-Robots-Tag', 'noindex, nofollow, noarchive');
    }
    // Redirect to Login URL here
    wp_redirect(wp_login_url($_SERVER['REQUEST_URI']), 302);
    die; // Bail here
});
// And add some Memberhsip info on wp-login.php
add_action('login_footer', function(){
    // Print some information here about Membership and site
    echo '<p style="text-align: center;">', 'Awesome Memberhsip stuff.', '</p>';
});
// Block indexing of login page
add_action('login_init', function(){
    // Block Robots using X-Robots-Tag: header
    if(!headers_sent()){ // Be defensive
        header('X-Robots-Tag', 'noindex, nofollow, noarchive');
    }
});

Regards.

share|improve this answer
1  
Nice and clean...Thanks for mentioning that closures are a PHP 5.3 addition since Wordpress only requires PHP 5.2.4... –  Taylor Dewey Oct 21 '11 at 10:46
    
@earnesto i cannot access the register page, it redirects to the login page, iam using buddypress, mysite.com/register, how to proceed –  Ezhil Oct 21 '11 at 11:14
1  
I like how you commented everything, put together really well. –  soulseekah Oct 21 '11 at 11:38
2  
I see no need to use PHP 5.3 closures here. Simply move the function definitions into proper callbacks. But the inline commenting is fantastic! –  Chip Bennett Oct 21 '11 at 12:54
1  
@EarnestoDev sorry, but I disagree. Plugins and Themes should adhere as closely as possibly to the coding standards and conventions used in WordPress core, since core, Plugins, and Themes all must co-exist. –  Chip Bennett Oct 21 '11 at 14:01

/members shows because it's rewritten to index.php?pagename=members or index.php?category=members when the WordPress Rewrite engine kicks in.

Depending on what 'members' actually is, and what other pages are you'll be able to restrict access to certain areas by using the is_user_logged_in() function and use it to conditionally redirect when certain criteria are met when user is not logged in.

As the simplest example (this goes in your template file):

if ( !is_user_logged_in() ) exit( 'Access is restricted' );

You can also write you plugin to hook into the query and let it block the page or redirect in case certain criteria are met, like so:

function wpse31700_restrict_access() {
    global $wp_query;
    $query_vars = $wp_query->query_vars;

    // Allow by returning
    $allowed_pages = array( '', 'contact' );
     if ( in_array($query_vars['pagename'], $allowed_pages )
        return;

    // Or restrict by redirecting
    $restricted_pages = array( 'members', 'pricelist', 'etc' );
    if ( !is_user_logged_in() and in_array($query_vars['pagename'], $restricted_pages )
        wp_redirect( ... );
}
add_action( 'wp', 'wpse31700_restrict_access' );

The above code is simply there to illustrate the concept, it will not work out of the box. You can check pagenames, postnames, author_name, or even meta values of a post/page by ID to see if they contain a 'restricted' value for example.

share|improve this answer
1  
I like the flexibility here though, because you can add more pages to a whitelist/blacklist. Glad you had the same action hook - though. Was trying to figure out the best one to use. –  Taylor Dewey Oct 21 '11 at 10:07
    
Thanks. Yes, 'wp' is good, because it has already figured out and filtered the query variables, and will load the template next, so it's a great hook to stop at. –  soulseekah Oct 21 '11 at 10:17

So you're looking to "lock-down" everything but the front page (or does it have to be index.php?) and the admin side of pages for register and login, correct?

Unfortunately there is no template conditional tag to tell us when we're on the registration or login pages, but I found a blurb here that gives us that conditional tag: http://stackoverflow.com/questions/5266945/wordpress-how-detect-if-current-page-is-the-login-page

From there it's a matter of writing the functions. I hooked it into the wp action hook because it's late enough that the template has been selected (we know if it's the home page). Anyway, try this script out.

function is_login_page() {
    return in_array($GLOBALS['pagenow'], array('wp-login.php', 'wp-register.php'));
}

function access_control(){
    if ( !is_front_page() && !is_user_logged_in() && !is_login_page() ){
        wp_die('Sorry, you must be logged into access this content', 'Access Denied', array( 
        'response' => 401,
        'back_link' => true
        ));
    }
}

add_action( 'wp', 'access_control' );
share|improve this answer
    
+1 this is good, too –  soulseekah Oct 21 '11 at 10:05
    
@taylor thanks for the input, i just tested your code, the register page is also getting redirected, iam using buddypress, where register is a page, how to overcome it. –  Ezhil Oct 21 '11 at 10:53
    
This code is not good. First of all 'wp_head' has certainly generated output already. Not the place to die or send redirects. Always use the 'wp' action here as it also avoids the login/registration pages! And there's more... but I'll stop here ;) –  EarnestoDev Oct 21 '11 at 11:35
    
@EarnestoDev I disagree. Waiting until after the query is setup allows access to useful conditionals such as is_front_page(), and no really meaningful content has been output yet. EDIT if the query is setup at wp, then that certainly is a good hook to use. –  Chip Bennett Oct 21 '11 at 12:57
1  
@EarnestoDev yep! Thus my edited comment. :) –  Chip Bennett Oct 21 '11 at 13:29

I wrote the exact code you're looking for in a project a while back. The below code presumes you are using a child theme and that a 403.php file exists in your child directory. (I copied 404.php and made minor changes to it.)

Note that Login/Register pages are available with this code, even though there is nothing in the code that might suggest that.

function wpse31700_403_error( $template ){
    if( !is_user_logged_in() && !is_front_page() ){
        header('HTTP/1.1 403 Forbidden');
        return get_stylesheet_directory().'/403.php';
    }
    return $template;
}
add_filter('template_include', 'wpse31700_403_error', 1, 1);

Additionally, if you want to modify your main menu to not include other links when the user is not logged in, you can utilize the wp_nav_menu_items filter. A good guide on playing with that filter is located here.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.