You could save the values with the separate user meta keys:
x1, ..., x6, points
instead of the array:
achievements
to simplify your WP_User_Query()
usage and not having to deal with serialized arrays as user meta values.
But I guess you’ve already considered this setup and wanted to avoid it 😉
A compromise would be to move only the points
out of the achievements
array into a separate meta key.
Update:
When the number of users is relatively small, we can use the following (untested) PHP sorting:
$users2points = array();
$args = array(
'meta_key' => 'achievements',
'number' => $no,
'offset' => $offset
);
$users = get_users( $args );
foreach( (array) $users as $user )
{
$meta = get_user_meta( 'achievements', $user->ID );
if( isset( $meta['points'] )
$users2points[$user->ID] = $meta['points'];
}
asort( $users2points, SORT_NUMERIC );
print_r( $users2points );
Update 2:
Here’s another more adventures PHP sorting that will work directly on the $users
array of WP_User
objects:
$args = array(
'meta_key' => 'achievements',
'number' => $no,
'offset' => $offset
);
$users = get_users( $args );
foreach( (array) $users as $user )
{
$meta = get_user_meta( 'achievements', $user->ID );
// Here we assume the points values are greater or equal to 0:
$user->points = ( isset( $meta['points'] ) ? $meta['points'] : 0;
}
/*
usort( $users, function( $a, $b ) {
return gmp_cmp( $a->points, $b->points );
});
*/
// The gmp_cmp() might suffer from a memory leak,
// according to some PHP bug reports,
// so let's use this instead:
usort( $users, function( $a, $b ) {
if( $a->points === $b->points )
return 0;
else
return ( $a->points > $b->points ) ? 1 : -1;
});
print_r( $users );