• Resolved Pioneer Web Design

    (@swansonphotos)


    Using below on a mu site (in functions.php of a child-theme in a site):

    //Hide admin bar for all but admin
    if ( current_user_can( 'manage_options') ) {
    add_filter ('show_admin_bar', '__return_true');
    } else {
    add_filter ('show_admin_bar', '__return_false');
    }
    
    //if current user can manage options - therefore is admin, go to admin //page, else, go to a specific page
    if ( current_user_can( 'manage_options') ) {
    function go_tpn(){
    	wp_redirect( 'https://site.com/wp-admin/' );
    		exit();
    		}
    	add_action('wp_login','go_tpn');
    } else {
    function go_referral(){
    	wp_redirect( 'https:/site.com/page_slug/' );
    		exit();
    		}
    	add_action('wp_login','go_referral');
    }
    
    //redirect all on logout to home page
    add_action('wp_logout','go_home');
    function go_home(){
      wp_redirect( home_url() );
      exit();
    }

    The admin part works as expected.
    The logout part works as expected.
    This does not:

    if ( current_user_can( 'manage_options') ) {
    function go_tpn(){
    	wp_redirect( 'https://site.com/wp-admin/' );
    		exit();
    		}
    	add_action('wp_login','go_tpn');
    } else {

    The top part of the if fails as all users, even admin, are redirected to the page in the else.

    What did I do wrong? Stumped. Is it due to being in WPMU? Is it due to using the add_action and not add_filter?

    Cannot post url or provide login (would to a moderator here off site)

Viewing 14 replies - 1 through 14 (of 14 total)
  • Moderator bcworkz

    (@bcworkz)

    Just guessing really. When your theme is loaded, WP is not entirely stable yet, I don’t think the current user is established at this point, so calling current_user_can() could lead to unpredictable results. You should establish a single function that works for all users, deciding where to redirect by user capability when the function is called.

    I am certain you cannot add an action callback from within that callback function. First of all, you would need to initially call the function for it to be added. That can be done though unorthodox. The real issue is every time the action fires, another instance of the callback is added to the $wp_filters array. The number of entries will grow geometrically out of control. Whether it is an action of filter does not matter, add_action() is actually just a wrapper for add_filter().

    The difference is in how WP handles the two. Filter returns are always assigned to something, action returns are ignored. Regardless, just define the function to work for all users as described above, then add the action when the theme loads, do not add the action from within another function unless you have a special need to control when the callback is used to a specific instance.

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    Hmmm…then why does the second part of the if not fail? I think it has to do with WPMU…I have tested same when not a site in WPMU, and it works there. It’s the manage_options capability is failing as a ‘test’ under WPMU, is my thought (and therefore is the problem). I can simply switch the if and else and then…well, I hope you get my point and someone at core can look at this.

    Moderator bcworkz

    (@bcworkz)

    When you call a function before WP is stable, the results are unpredictable, so trying to use logic to explain the behavior is fallacious. I really think all you need to do is setup the part of your code that relies on current_user_can() to execute during the ‘init’ action and the problem will go away.

    If by chance it does not, consider submitting a bug report (Trac Ticket), it is the best way to have core developers look at the issue.

    P.S. You probably already did, but you can disregard what I was on about adding actions from callbacks, I was confused a bit about where the function declarations ended, I use a different indent style.

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    More hmmm’s…not sure you realize that the site has been fully loaded and then a user is logging in….so, I do not get your point about the theme loading, ‘stable’, etc.

    Moderator bcworkz

    (@bcworkz)

    Hmmm.. not sure you realize WP completely reloads itself on every request ?? You are not alone, this really surprised me when I first learned this, but now I see it can be no other way. A detailed explanation is in Query Overview. It is oriented for querying for posts, but the initial parsing of a request happens even for logins. Admittedly, it is a bit TL:DR, maybe the following will suffice.

    The first code line of wp-login.php (as for most WP pages requested directly) requires (loads) wp-load.php. This in turn requires wp-config.php and a few other minor though essential pages. As you probably know, wp-config.php initializes many of the specific constants for your particular installation. At the very bottom wp-settings.php is required.

    If you look at the source code of wp-settings.php, you will see a huge pile of files are required, plugins are loaded, theme loaded, current user established, etc. In addition, many other files are loaded indirectly from this page, but eventually, WP is completely loaded. In fact, the final line is do_action( 'wp_loaded' );

    If you look up from the end a bit, you will see the call to $wp->init() that sets up the current user. Anything done before this, such as setup themes, cannot make calls to current_user_can() because WP does not yet know who the current user is yet. This is what I mean by WP not being stable. The function is defined, but without a user it is not yet reliably functional. Anything after $wp->init() can safely use the function. There is scant little after this, only the actions ‘init’ and ‘wp-loaded’, and in the case of MU, the current blog status is checked.

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    Maybe it’s the server cache at the WPMU site that is in use?

    Moderator bcworkz

    (@bcworkz)

    That would explain the illusion that WP is already “fully loaded”. If we were trying to use the function for anything else where the user object is already established, I could see how the function would work even though it technically is being called too early.

    In the specific case of user login, the correct user object has not been established when the theme loads, so anything the function might return cannot be trusted. It’s simply wrong to use the function when the theme is loading. It needs to be called from an ‘init’ action callback or later.

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    I will await a core dev to respond.

    Moderator Jan Dembowski

    (@jdembowski)

    Forum Moderator and Brute Squad

    I will await a core dev to respond.

    That will probably be an extremely long wait as that’s not how reporting core issues work. Looking at this topic I’m not sure why you think this is a core issue.

    Can you please reduce what you are trying to accomplish as a set of requirements? No code, just what you are trying to do i.e. “When the user is logged in, this is what I want to do, etc.”

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    Jan, yes I can:

    1. When the (only) admin user logs in, I want (me) to go the dashboard.
    2. When any other user logs in, I want them to go to a specific page. The main purpose of a user registering and logging in is to submit a form, which is on the page all users will be redirected to at login.

    Moderator Jan Dembowski

    (@jdembowski)

    Forum Moderator and Brute Squad

    Thanks, that’s a perfect description. ??

    For item 2: once the user has logged in and gone to that defined page (URL) do you still want future logins from those other (non-admin, not you) users to go to that page (URL)?

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    Yes, the form is a master form and covers many business needs for my client, so each time a registered user logs in, they go directly to the form page.

    Moderator Jan Dembowski

    (@jdembowski)

    Forum Moderator and Brute Squad

    Give this plugin a look.

    https://www.ads-software.com/plugins/peters-login-redirect/

    It does Network Activate but the settings seem to be site specific.

    This one may work too.

    https://www.ads-software.com/plugins/speedy-page-redirect/

    The codes in those plugins may help you sort it out in multisite.

    Also I noticed you are working with https URLs. I’m not sure how those plugins work but if they depend on referrer URLs then they may fail for https. When the https protocol is use there are no referrers unless the target is also https.

    Thread Starter Pioneer Web Design

    (@swansonphotos)

    I took a look at the first plugin. Very lightweight and straightforward. Installed and is now in use and has resolved my issue.

    Sidenote: All the url’s are at HTTPS (was a typo in my example url’s).

    Thanks, Jan.

Viewing 14 replies - 1 through 14 (of 14 total)
  • The topic ‘Current User Can on WPMU’ is closed to new replies.