1

I have a custom Wordpress theme that includes a members only section. In order to implement this, I have the following code at the top of my restricted pages.

<?php if ( ! current_user_can ('view_players_area') ) { header('Location: ' . wp_login_url( "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ) ); } ?>

Most of the time, this works fine, however every so often it simply fails to work for NO reason at all. No error message, just when you log in, it redirects back to the login page continually. I originally used is_user_logged_in() and had a similar problem which is what caused me to use this code.

If anyone has any suggestions what might be causing this I will be hugely appreciative - this has me tearing my hair out, as the members area needs to go live in the next couple of weeks.

Regards

Ben

Edit

Following advice from replies and some users in the chatroom, I have modified my code so the the redirect is not done in the template. Now in a functions.php include, I have the following:

<?php

function redirect_restricted_areas( $query )
{
    if ( !is_admin() && $query->is_main_query() )
    {
          if ( ! current_user_can( 'view_players_area' ) && (
               $query->is_singular ('player-page') ||
               $query->is_post_type_archive ('player-page')
          ) ) 

          header('Location: ' . wp_login_url( "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" ) );
    }

}

add_action ( 'pre_get_posts', 'redirect_restricted_areas' );

Sadly, although this is good advice that makes my code simpler, it doesn't solve my problem.

Further Edit

So with some debugging, I can see that $current_user is not always being set, but I have no idea why.

Another Edit

Investigating this further, it seems to be something to do with the cookies. After learning a bit about the Wordpress authentication cookies I noticed the following. Using dBug (a prettier version of print_r()) I determined that according to PHP the Wordpress auth cookie didn't exist, yet if I open up Chrome inspector I can clearly see the cookie sitting there. Not quite sure what to make of this yet, but if anybody is able to point me in the right direction...

2

Do not set header in a template file. Those are part of the HTTP request itself.

About your problem:

Add a template (whatever file you need - see "Template Hierarchy"). On top of it you include the default stuff like get_header(); and so on. For the restricted part, you use the following:

if ( current_user_can( 'view_players_area' ) )
{
    // Code that you want to show to logged in users
    // with a capability of `view_players_area`
}
else
{
    # @link http://queryposts.com/function/wp_login_form/
    wp_login_form();
}
|improve this answer|||||
  • Hi there, thanks for your response. Sadly this doesn't solve my problem; logging in still occasionally causes the login box to reload. – Ben Wainwright Jul 22 '14 at 17:14
1

Put this on the top of the file with your code:

global $current_user;
if ( !$current_user->ID ) {
    get_currentuserinfo();
}
|improve this answer|||||
  • Thanks! Is there any reason why I can't just put it in functions.php, as there are 4 or 5 templates that will need this change... – Ben Wainwright Jul 20 '14 at 16:22
  • Any reason. Sure, you can put it in the functions.php. – MaximOrlovsky Jul 20 '14 at 16:24
  • Thanks. I Thought that had fixed the problem, but apparently not - still getting the same behaviour. Any other ideas what I could do? I am at my wits end here :/ – Ben Wainwright Jul 22 '14 at 16:40
1

You need to exit() after you set the header (and I'd recommend using wp_redirect()).

Untested, but the following should work. If it's really the case that current_user_can() isn't working, I'd first disable any other plug-ins to rule out a conflict, and then check that user really does have the permissions you think they should have.

function redirect_restricted_areas( $query )
{

    //Determine if we're on the log-in page
    global $pagenow;
    $on_login_page = in_array( $pagenow, array( 'wp-login.php', 'wp-register.php' ) );

    //If we're on the front-end and the main query is restricted
    //redirect the user if they do not have permission.
    if ( !$on_login_page && !is_admin() && $query->is_main_query() )
    {
          if ( ! current_user_can( 'view_players_area' ) && (
               $query->is_singular ('player-page') ||
               $query->is_post_type_archive ('player-page')
          ) ) {

            $url = wp_login_url( "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]" );
            wp_redirect( $url );
            exit();
          }
    }

}
add_action ( 'pre_get_posts', 'redirect_restricted_areas' );
|improve this answer|||||
  • Thanks for the help, but that still leads to a redirect loop :( – Ben Wainwright Jul 22 '14 at 19:53
0

You can try using wp_redirect(); and the hook after_setup_theme (shouldn't be any output at this point).

Create more manageable conditionals with early bail outs.

Here's my take on it I guess...

if(!function_exists('mbe_redirect_restricted_areas')){
    function mbe_redirect_restricted_areas(){

        // Determine login page status.
        global $pagenow;

        // Do nothing on login page.
        if(in_array($pagenow, array(
            'wp-login.php',
            'wp-register.php'
        )){
            return false;
        }

        // Do nothing in admin area.
        if(is_admin()){
            return false;
        }

        // Do nothing if user is logged in and has capability.
        if(is_user_logged_in() && current_user_can('view_players_area')){
            return false;
        }

        // Do nothing if not in player page area.
        if(stripos($_SERVER['REQUEST_URI'], 'player-page') === false){
            return false;
        }

        // Guests and users without capability.
        wp_redirect(wp_login_url("http://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}"));
        exit;

    }
    add_action('after_setup_theme', 'mbe_redirect_restricted_areas');
}
|improve this answer|||||
  • Thanks for the response. Sadly using that hook seems to lead to anybody being able to view my members area. – Ben Wainwright Jul 22 '14 at 21:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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