Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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?

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

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.

share|improve this answer
add comment

Filter the string 'query' and change the ORDER BY part. See https://gist.github.com/1281778#L160 for an example.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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