Sort custom post type list table by display name of a user id stored as post meta value

An ‘easy’ but not very good solution is to store the user’s display name as well as ID, and sort by that. Obviously an update of a user’s display name would prompt an update of all the domicile that user owns.

Alternatively the following is an outline (untested) of what should work. The idea is to tell WordPress to sort by the meta value still (so that WordPress joins the post meta table) and then its possible to use the post_clauses filter to join the users table and sort by display name:

add_filter('posts_clauses', 'wpse58638_post_clauses',10,2);
function wpse58638_post_clauses( $clauses, $query ) {
    global $wpdb;
    if ( ! $query->is_main_query()
        || ! is_admin()
        || ! $query->get('post_type') == 'domicile'
        || ! $query->get('meta_key') == 'dmb_owner'
        || ! $query->get('orderby') == 'meta_value_num'
    ){
        return $clauses;
    }

    //Get sort order
    $order_dir = $query->get('order');
    $order_dir = ('asc' == $order_dir ? 'ASC' : 'DESC');

    //Join user table onto the postmeta table
    $clauses['join'] .= " LEFT JOIN {$wpdb->users} ON {$wpdb->prefix}postmeta.meta_value={$wpdb->users}.ID";

    //Replace orderby
    $clauses['orderby']  = " {$wpdb->users}.display_name $order_dir";

    return $clauses;
}

Leave a Comment