3

I adapted a little a function to display a number of random users with their avatars with a shortcode. It works, but something is not good. Sometimes it displays with one user less than I want (just a blank line instead of the first user), sometimes it includes the administrator, although it should not. What is wrong with my code?

add_shortcode( 'random_users', 'display_random_users' );
//Usage: [random_users how_many = 3]

function display_random_users( $atts ) {

    extract(shortcode_atts( array( "how_many" => '' ), $atts ) );

    $args = array(
        'orderby' => 'ID',
        'role' => 'subscriber',
        'fields' => 'ID'
    );

    $users = get_users( $args );
    $users = array_rand( $users, $how_many );

    foreach ( $users as $userID ) {
        echo '<a href="' . 
            bp_core_get_user_domain( $userID ) . '">' . 
            bp_core_fetch_avatar( array( 'item_id' => $userID ) ) . '<br />' . 
            xprofile_get_field_data( '1', $userID ) . '</a><br />';
    }
}
  • Do a print_r($users) to see what your query is returning. That way you can make sure you're only getting subscribers, not admins. Also, does get_users not support orderby=rand? I know wp_query does, but not sure about get_users. If it does, it would be easier to only query the amount of users in $how_many instead. – gdaniel Jan 6 '15 at 22:16
  • @gdaniel This is what returned the print_r($users): Array ( [0] => 0 [1] => 1 [2] => 23 ). So, the first user is inexistent and the second is the admin, right? – Iurie Malai Jan 6 '15 at 22:30
5

I am not sure why your query is returning more IDs than necessary. The $args for get_users look correct.

By default get_users does not support orderby=rand, but you can overwrite that option. See below:

function random_user_query( &$query )
{
    $query->query_orderby = "ORDER BY RAND()";
}

// Usage: [random_users how_many = 3]
add_shortcode( 'random_users', 'display_random_users' );
function display_random_users( $atts ) {

    shortcode_atts( array( "how_many" => '', ), $atts );

    // Create a function to override the ORDER BY clause
    add_action( 'pre_user_query', 'random_user_query' );

    $users = get_users( array(
        'role'    => 'subscriber',
        'fields'  => 'ID',
        'orderby' => 'rand',
        'number'  => $atts['how_many'],
    ) );

    foreach ( $users as $userID ) {
        printf( 
            '<a href="%s">%s<br />%s</a><br />',
            bp_core_get_user_domain( $userID ),
            bp_core_fetch_avatar( array( 'item_id' => $userID ) ),
            xprofile_get_field_data( '1', $userID )
        );
    }

    // Remove the hook
    remove_action( 'pre_user_query', 'random_user_query' );
}

This way, you only query $how_many users, instead of querying all users and then filtering out $how_many.

I found this hook here.

  • The orderby in $args must appear twice? However, it seems that the function works well. Thank you! – Iurie Malai Jan 6 '15 at 22:52
  • I think the 'orderby' => 'ID' is not nedeed, so I removed it. – Iurie Malai Jan 6 '15 at 23:05
  • 2
    It was not needed, I missed that. I removed it. – gdaniel Jan 6 '15 at 23:55
  • As PHP 5.2 and anonymous functions are gone now with 5.3 dead (see those stats about secure versions), I'd suggest to use a Closure: add_action( 'pre_user_query', function( $q ) { ... } ); instead. Anyway, +1 for the answer :) – kaiser Jan 7 '15 at 0:03
  • 1
    I hope you don't mind the edit. Else removing the action wouldn't have been possible. More info about that problem in this answer and in this answer. – kaiser Jan 7 '15 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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