How to order WP_User_Query results to match the order of an array of user IDs?

Updated:

The WP_User_Query class, in WordPress 4.1+, supports it with :

'orderby' => 'include'

Since WordPress 4.7 there’s also support for:

'orderby' => 'login__in'

and

'orderby' => 'nicename__in'

So we no longer need to implement it through a filter, like we did here below.

Previous Answer:

I wonder if this works for you:

add_action( 'pre_user_query', 'wpse_order_by_include_values' )
$query = new WP_User_Query( $args );
remove_action( 'pre_user_query', 'wpse_order_by_include_values' )

where

function wpse_order_by_include_values( $q )
{
    if( isset( $q->query_vars['include'] ) )
    {
        $values = join( ',', $q->query_vars['include'] );
        $q->query_orderby = 'ORDER BY FIELD( ID,' . $values . ' )';         
    }
}

using the FIELD() function in MySQL. There are some usage examples here in the comments of the MySQL doc page.

Update:

To make it more flexible we could use this mini plugin:

/**
 * Support the 'orderby' => '_include' parameter for the WP_User_Query 
 * to order by the values in the include array.
 * 
 * @see http://wordpress.stackexchange.com/a/167095/26350
 */

add_action( 'pre_user_query', function( $q ) {

    if( 
        isset( $q->query_vars['orderby'] )
        && '_include' === $q->query_vars['orderby']
        && isset( $q->query_vars['include'] ) 
        && count( $q->query_vars['include'] ) > 0 
    )
    {
        global $wpdb;
        $users_in = join( ',', array_map( 'absint', $q->query_vars['include'] ) );
        $q->query_orderby = 'ORDER BY FIELD( {$wpdb->users}.ID,' . $users_in . ' )';
    }

});

where we use the underscore prefix _include, just in case the core will use the include value in the future. Update: I’ve adjusted this so now it’s more or less similar to the post__in ordering case of the WP_Query class.

Now you can simply use:

$args = array(
    'include'     => array( 1, 3, 5, 99, 61, 24, 12 ),
    'count_total' => true,
    'search'      => sanitize_text_field( $_GET['phrase'] )
    'orderby'     => '_include',                               //<-- our new value
);

$query = new WP_User_Query( $args );

to order by the include array.

Leave a Comment