1

I've seen there are several ways to display a user's last login date on the Users page without having to use a 3rd party plugin. Building on that, I'd really like to have the user's last login date column be sortable (hopefully orderby date).

I'm using the display user last login function via wpdailybits, but my additions to the code can't get the column to sort.

Suggestions? I know I'm missing something...

//Capture User Last Login
    add_action('wp_login','wpdb_capture_user_last_login', 10, 2);
    function wpdb_capture_user_last_login($user_login, $user){
        update_user_meta($user->ID, 'last_login', current_time('mysql'));
    }

//Display Last Login Date in Admin
    add_filter( 'manage_users_columns', 'wpdb_user_last_login_column');
    function wpdb_user_last_login_column($columns){
        $columns['lastlogin'] = __('Last Login', 'lastlogin');
        return $columns;
    }

    add_action( 'manage_users_custom_column',  'wpdb_add_user_last_login_column', 10, 3); 
    function wpdb_add_user_last_login_column($value, $column_name, $user_id ) {
        if ( 'lastlogin' != $column_name )
            return $value;

        return get_user_last_login($user_id,false);
    }

    function get_user_last_login($user_id,$echo = true){
        $date_format = get_option('date_format') . ' ' . get_option('time_format');
        $last_login = get_user_meta($user_id, 'last_login', true);
        $login_time = 'Never logged in';
        if(!empty($last_login)){
           if(is_array($last_login)){
                $login_time = mysql2date($date_format, array_pop($last_login), false);
            }
            else{
                $login_time = mysql2date($date_format, $last_login, false);
            }
        }
        if($echo){
            echo $login_time;
        }
        else{
            return $login_time;
        }
    }
//Sort the Columns
    add_filter( 'manage_edit-users_sortable_columns', 'sortable_users_column' );
    function sortable_users_column( $sortable_columns  ) {

        $sortable_columns[ 'last_login_column' ] = 'lastlogin';

    }
1

I don't see anywhere in your code that the query is being modified. Just flagging a column to be sortable doesn't mean it knows how to sort the data - it will just add the little up/down arrow and make the column clickable but you have to intercept the query var accordingly and tell WP what to do. You'll want to hook into pre_get_users and modify the query accordingly. Since you're already storing the time using current_time( 'mysql' ) then the default ordering should work as intended.

This is untested but should work or at least get you started.

add_action( 'pre_get_users', 'wpse_filter_user_query' );
function wpse_filter_user_query( $user_query ) {
    global $current_screen;

    if ( !is_admin() || 'users' != $current_screen->id ) 
        return;

    if( 'lastlogin' == $user_query->get( 'orderby' ) ) 
    {
        $user_query->set( 'orderby', 'meta_value' ); 
        $user_query->set( 'meta_key', 'last_login' );
    } 
}
  • If this really is an action, then it will not use any return value. It probably is a filter or you have to reference it: &$user_query to have any affect on the actual query. – kaiser Jun 1 '16 at 2:32
  • 1
    @kaiser spot on. After looking up the pre_user_query hook again, it occurred to me that hooking into pre_get_users is probably a better fit, although they will both work. Updated the answer based on your feedback and the updated hook. – brianjohnhanna Jun 1 '16 at 13:50

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.