0

I need users to redirect to login if not logged and once they are, redirect them to backend if they try to see front end pages. This is my code:

add_action( 'template_redirect', function () {
    if(is_user_logged_in() ):
        bk1_debug('logged in');
        if (!is_admin()):
            bk1_debug('not in admin, redirecting...');
            wp_redirect(admin_url());
        endif;
    else:
        bk1_debug('not logged in, redirecting...');
        wp_redirect(wp_login_url( admin_url() ));
    endif;

}, 10 );

Of course it doesn't work... For some reason 'not in admin, redirecting...' is called also in backend, and even better, in front end nothing happens altogether! Only redirecting for not logged in user goes.

Any idea?

  • Take a look at if the current user object is already set up. Afaik, it's not. – kaiser Jun 21 '13 at 17:21
  • redirecting not logged in user is the only thing that works :) in the backend. It doesn't work in the front end. – Bakaburg Jun 21 '13 at 17:43
4

redirecting not logged in user is the only thing that works :) in the backend.

What you are describing is very peculiar. template_redirect is a front-end hook. Your code will never run on the backend, as far as I can tell. You can demonstrate that with this line:

add_action('template_redirect',function() {die;});

You can traverse the back-end all you want, but try to get to the front and you get nothing. I really think you have the analysis backwards. Your code should never be executing in the back-end at all.

I put die; at the top of your function and get the same results. It does not execute in the back-end.

What you are probably seeing is "not logged in" users getting shuffled to the front end, at which point that code runs.

All I can think is that there is some other redirect that is giving the illusion of this execution on the back-end.

While initially writing this answer, I missed the obvious. You shouldn't need to redirect a "not logged in" user from the backend to the login screen. WordPress will do that automatically-- or should unless something has done something unwise to your site.

All you should really need is this:

add_action( 
  'template_redirect', 
  function () {
    wp_redirect(admin_url());
  }
  ,10
);

That pretty much completely prevents access to the front end, which sound like what you describe:

I need users to redirect to login if not logged and once they are, redirect them to backend if they try to see front end pages.

Is that really what you want?

  • but it does! 'eppur si muove' quoting someone... :) the various console messages are shot in backend! Anyway, without digging into the problem, which could be the right hook to run that code? – Bakaburg Jun 21 '13 at 18:25
  • 1
    But that should not be executing on the back-end to the best of my knowledge, backed up by the experiments I have done. I expect that your code is going to be buggy until you work out why it (appears) to execute on the back-end. See the edit. – s_ha_dum Jun 21 '13 at 18:39
  • yep that's my purpose! Mmmm apparently you code is the same as mine but with the !is_admin included in the first statement! and if someone is not logged in you allow him to stay in the front end! You're right that if someone is not logged cannot access backend. So i want to try this: if(!is_admin) wp_redirect(admin_url()); that would do it I hope. – Bakaburg Jun 22 '13 at 9:41
  • 1
    I simplified the code even more. Sorry, it took awhile for me to get my head around what you wanted. :) – s_ha_dum Jun 22 '13 at 14:52
  • read my answer below. the problem was that I had to embed 'template_redirect' into 'init' to make it work properly! – Bakaburg Jun 22 '13 at 15:02
1

What your function says:

On FRONT END do this before template display:
     if user is logged in:
          check if you are NOT on admin page (back end), if you are not on admin page:
               , go to admin

     if user is not logged in:
          redirect to login no matter what...

So you can see yourself that your approach have some holes :-) Also wp_redirect() docs say:

wp_redirect() does not exit automatically and should almost always be followed by exit

And you did not, nor anybody else here...

SOLUTION

From what you are describing you are want to do something everywhere, no matter what, for that you could think of 2 "really" general actions that would be logical for this execution:

init - available since WordPress 1.5, still up-to-date in WordPress 4.5, altough many plugins hook to it, but you could play with add_action(...)'s priority set to 1 ...

set_current_user

Since WordPress 2.0.1, still up-to-date in WordPress 4.5; the docs say about it:

Runs after the user has been changed by the default wp_set_current_user() function. Note that wp_set_current_user() is also a "pluggable" function, meaning that plugins can override it (docs link)

After this point you can determinate everything you need to know:

  1. Whether or not is user logged in - is_user_logged_in()
  2. Whether you are on admin page or somewhere else - is_admin()
  3. Whether your current page is wp-login.php or not - $GLOBALS['pagenow'] == "wp-login.php"

THE CODE

add_action( 'set_current_user', function(){  
  //"After user is set, do ..."

  //"If user IS logged in, but is NOT on any admin/backend page 
  //=> redirect to admin url and !exit current execution!"  
  if( is_user_logged_in() && ! is_admin() ){
    wp_redirect(admin_url());
    exit();
  }

  //"If user is NOT logged in and we are NOT on (default) login page
  //=> redirect to login page !and exit current execution!"
  if( ! is_user_logged_in() && ($GLOBALS['pagenow'] != "wp-login.php") ){
    wp_redirect(wp_login_url());
    exit();
  }  

} );

Tested on WordPress 4.5, works as you've described on both front&&back-end...

0

Following suggestions from @s_ha_dum who noted that user need be logged in anyway to go to back end and that 'template_redirect' doesn't work in backend (even if my code did trigged console messages only in back end), I simplify the code as such:

add_action( 'template_redirect', function () {
    if(!is_admin()) wp_redirect(admin_url());
}, 10 );

But nothing changed. Still I go to front end and nothing happens. I also tried with 'init' and nothing.

Then I thought that maybe I was calling 'template_redirect' in the wrong moment, so I mixed the two hooks:

add_action( 'init', function () {
    add_action( 'template_redirect', function(){
        if(!is_admin()) wp_redirect(admin_url());
    }, 10);
}, 10 );

And that finally worked!!!

  • That double "hooking" should not be necessary. Adding the template_redirect anywhere before the template_redirect hook runs should be sufficient. Your site appears to be behaving in a non-standard way and I suspect your code will be buggy until you work out why. It is your site. You can do what you want of course, but I'd consider this a work-around, not a fix-- a hack on top of another hack, the one hack fixing something broken by the other. – s_ha_dum Jun 22 '13 at 15:10
  • Ok, but I have no idea of where the problem could be. there are no other redirects in my function.php! The theme code is here btw github.com/bakaburg1/Overseer – Bakaburg Jun 22 '13 at 15:16
  • It is puzzling, I agree. Perhaps a plugin or one of those included dependencies is responsible. – s_ha_dum Jun 22 '13 at 16:26
  • speaking of the devil, I just moved the git submodules and now wp-less is not working anymore, with a require_once() not found error. I double checked the path and is correct... who knows... Ok this was off topic. – Bakaburg Jun 22 '13 at 16:34
  • and now suddenly started to work again – Bakaburg Jun 22 '13 at 20:14

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.