0

I'm trying to redirect a user to a specific post after logging in. This post is the latest post of a custom post type where the author is the current logged in user.

I currently have to following code to get the specific post url:

function member_permalink () {  
    $user_id = get_current_user_id();
    $args=array(
        'post_type' => 'cursist',
        'author' => $user_id
    );

    $current_user_posts = get_posts( $args );       
    $post_link =  get_permalink( $current_user_posts->ID );

    return $post_link;  
}

And the code to redirect the user after login (taken from the Codex)

function my_login_redirect( $redirect_to, $request, $user ) {
    //is there a user to check?
    if (isset($user->roles) && is_array($user->roles)) {
        //check for subscribers
        if (in_array('subscriber', $user->roles)) {
            // redirect them to another URL, in this case, the homepage 
            $redirect_to =  member_permalink();
        }
    }

    return $redirect_to;
}

add_filter( 'login_redirect', 'my_login_redirect', 10, 3 );

However I get redirected to WP-admin instead of the post.

If I do a var_dump of the function to get the specific post url I get the following in return (which is the data that I want):

string(52) "http://example.com/cpt-slug/niels-pilon/" 

I'm probably doing something wrong but can't figure out what.

3
  • 1
    Hey Niels :) member_permalink() returns the URL to a post authored by the current user - if there is any. Though in line 5 of my_login_redirect(), you are only redirecting the current user if they are a "subscriber". Pretty sure this is the culprit here.
    – Iceable
    Commented Jul 31, 2018 at 10:04
  • 1
    What is the role of given user? Commented Jul 31, 2018 at 10:10
  • 1
    The user that's redirected has a role of subscriber. The function is fine if I change the $redirect_to to home_url(). The author of the CPT has also a role as member as I create the CPT with a function when registering a new user.
    – NielsPilon
    Commented Jul 31, 2018 at 10:12

1 Answer 1

3

You should pass the $user as a parameter to member_permalink() instead of relying on get_current_user_id().

From the codex about the login_redirect filter:

The $current_user global may not be available at the time this filter is run. So you should use the $user global or the $user parameter passed to this filter.

Sample updated code:

function member_permalink( $user = null ) {

    if ( null == $user || is_wp_error( $user ) ) {
        $user_id = get_current_user_id();
    } else {
        $user_id = $user->ID;
    }

    $args = array(
        'post_type'   => 'cursist',
        'author'      => $user_id,
        'numberposts' => 1,
    );

    $current_user_posts = get_posts( $args ); 

    if ( empty( $current_user_posts ) ) {
        return;
    }

    $post_link = get_permalink( $current_user_posts[0] );

    return $post_link;  
}

function my_login_redirect( $redirect_to, $request, $user ) {
    //is there a user to check?
    if (isset($user->roles) && is_array($user->roles)) {
        //check for subscribers
        if (in_array('subscriber', $user->roles)) {
            // redirect them to another URL
            $redirect_to = member_permalink( $user );
        }
    }

    return $redirect_to;
}

add_filter( 'login_redirect', 'my_login_redirect', 10, 3 );

[edit]: I made the $user parameter optional to provide flexibility in case you use this function without parameters in some other places.

4
  • 1
    Thanks but I only get an Trying to get property of non-object notice reffering to $post_link = get_permalink( $current_user_posts->ID );
    – NielsPilon
    Commented Jul 31, 2018 at 11:07
  • Indeed, now that you mention it I wonder how this function was working before, considering get_posts() returns an array of objects (and not an object) even if there is only one result. I just edited my answer to hopefully fix this.
    – Iceable
    Commented Jul 31, 2018 at 11:22
  • 1
    After $current_user_posts = get_posts( $args ), you should check if there are any results: if (is_array($current_user_posts) && count($current_user_posts) > 0).
    – nmr
    Commented Jul 31, 2018 at 11:27
  • @NielsPilon brilliant, glad I could help :) Good point @nmr, I just updated the answer. get_posts() always returns an array - an empty one if there are no results - so I'm just checking that it is not empty. Also get_permalink() accepts either an id or a WP_Post object, so I removed the "->ID" part to only pass $current_user_posts[0]
    – Iceable
    Commented Jul 31, 2018 at 11:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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