List users by last name in WP_User_Query

How can I list users by last name ASC when using WP_User_Query?

There is an orderby parameter but looking in core it doesn’t accept ordering my user meta. Anyone know how to extend WP to allow this ordering by last name?

Related posts

Leave a Reply

3 comments

  1. There is a better way to do this as of WordPress version 3.7. Use the WordPress property meta_key to select the last name property and then orderby => meta_value with an ascending order.

    <?php
    $args = array(
        'meta_key' => 'last_name',
        'orderby' => 'meta_value',
        'order' => 'ASC'
    );
    
    $user_query = new WP_User_Query( $args );
    
    if ( ! empty( $user_query->results ) ) {
        foreach ( $user_query->results as $author ) {
            // Line below display the author data. 
            // Use print_r($author); to display the complete author object.
            ?>
            <a href="<?php echo get_author_posts_url($author->ID); ?>" class="author"><?php echo get_avatar($author->ID, 96); ?><?php echo $author->display_name; ?></a>
            <?php
        }
    } 
    ?>
    
  2. Made something myself:

    Page template file:

    <?php
    $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
    $paged -= 1;
    $limit = 20;
    $offset = $paged * $limit;
    
    $args  = array(
        'number' => $limit,
        'offset' => $offset,
    );
    
    // Create the WP_User_Query object
    global $wp_query;
    $wp_query = new WP_User_Query($args);
    
    // Get the results
    $authors = $wp_query->get_results();
    
    if($authors): ?>
        <div id="staffmembers" class="clearfix">
            <?php foreach($authors as $author) : ?>
                <a href="<?php echo get_author_posts_url($author->ID); ?>" class="author"><?php echo get_avatar($author->ID, 96); ?><?php echo $author->display_name; ?></a>
            <?php endforeach; ?>
        </div>
    <?php else: ?>
        <div class="post">
            <p>Sorry, no posts matched your criteria.</p>
        </div>
    <?php endif; ?>
    
    <?php wp_pagenavi(); ?>
    

    Just so you are aware I’m using an alpha version of WP-PageNavi that supports pagination for WP_User_Query. The above just deals with layout and pagination. Below is where the magic happens:

    functions.php file:

    add_action('pre_user_query', 'sort_connect_author_list_by_last_name' );
    function sort_connect_author_list_by_last_name(&$object) {
        global $wp, $wpdb;
        if(preg_match( "/^connect(/.+)?$/", $wp->request )) {
            // Sub query
            $sql = "
                (SELECT
                    `{$wpdb->users}`.`ID` AS `c_user_id`,
                    MAX(CASE WHEN `{$wpdb->usermeta}`.`meta_key` = 'location' THEN `{$wpdb->usermeta}`.`meta_value` END ) AS `c_location`,
                    MAX(CASE WHEN `{$wpdb->usermeta}`.`meta_key` = 'last_name' THEN `{$wpdb->usermeta}`.`meta_value` END ) AS `c_last_name`,
                    MAX(CASE WHEN `{$wpdb->usermeta}`.`meta_key` = 'first_name' THEN `{$wpdb->usermeta}`.`meta_value` END ) AS `c_first_name`
                FROM
                    `{$wpdb->users}`
                    LEFT JOIN `{$wpdb->usermeta}` ON ( `{$wpdb->users}`.`ID` = `{$wpdb->usermeta}`.`user_id` )
                WHERE
                    1=1
                GROUP BY
                    `{$wpdb->users}`.`ID`
                ) AS `C`
            ";
            // Modify existing query
            $object->query_fields = "SQL_CALC_FOUND_ROWS `{$wpdb->users}`.`ID`, `{$wpdb->users}`.`display_name`";
            $object->query_from .= " RIGHT JOIN {$sql} ON ( `{$wpdb->users}`.`ID` = `C`.`c_user_id` )";
            $object->query_orderby = "ORDER BY `C`.`c_last_name` ASC";
        }
    }
    

    The above query is not efficient and would be terribly slow on large user base. In my case I’m running on 250 users max. There would be better ways of doing this but I wanted to maintain pagination with WP-PageNavi.