3

By default, Wordpress uses Gravatar for user avatars.

I've created a custom field for avatar uploads, and I'm using this as users' avatars on various pages in the theme.

In the admin - on the all users page - there is a column that would normally display the user's avatar (see below). Is there a way to use my custom field instead of the default gravatar field?

enter image description here

  • How did you go with this Koleon? – Tim Malone Jul 6 '16 at 4:09
5

As an alternative to my other answer, you can also use the get_avatar filter. Props to Sumit to alerting me to this one.

The benefit of using the get_avatar filter is your custom avatar should be applied anywhere Wordpress uses it, rather than just in this users list like my other answer deals with. If you use plugins that display user avatars, this solution should also work for them, providing they play nicely and use the Wordpress filters they should be using :)

The official docs for the get_avatar filter are here.

In your theme's functions.php, you'll want set up your function like this:

add_filter("get_avatar", "wpse_228870_custom_user_avatar", 1, 5);

function wpse_228870_custom_user_avatar($avatar, $id_or_email, $size, $alt, $args){

  // determine which user we're asking about - this is the hard part!
  // ........

  // get your custom field here, using the user's object to get the correct one
  // ........

  // enter your custom image output here
  $avatar = '<img alt="' . $alt . '" src="image.png" width="' . $size . '" height="' . $size . '" />';

  return $avatar;

}

Now there's a lot missing from that because, perhaps frustratingly, Wordpress doesn't send a nice clean user object or user ID through to this filter - according to the docs it can give us:

a user_id, gravatar md5 hash, user email, WP_User object, WP_Post object, or WP_Comment object

Most of these we can deal with - if we got a Gravatar hash that'd be a bit difficult - but the rest we can use the built in Wordpress functions to get the correct user object.

There's an example that gets started on this in the old Wordpress docs. However for this filter to work properly everywhere it's used, you'll need to write a little extra to make sure you can detect and deal with a post or comment object coming through as well (perhaps using the PHP is_a function) and then getting the associated post or comment author.

  • 1
    Additional upvote is added for you efforts ;) – Sumit Jun 6 '16 at 13:30
2

We could also use one of the following filters, available since WordPress 4.2:

Regarding how to get the user ID from the $id_or_email we can see how it's done in the core:

$email_hash = '';
$user = $email = false;
if ( is_object( $id_or_email ) && isset( $id_or_email->comment_ID ) ) {
    $id_or_email = get_comment( $id_or_email );
}
// Process the user identifier.
if ( is_numeric( $id_or_email ) ) {
    $user = get_user_by( 'id', absint( $id_or_email ) );
} elseif ( is_string( $id_or_email ) ) {
    if ( strpos( $id_or_email, '@md5.gravatar.com' ) ) {
        // md5 hash
        list( $email_hash ) = explode( '@', $id_or_email );
    } else {
        // email address
        $email = $id_or_email;
    }
} elseif ( $id_or_email instanceof WP_User ) {
    // User Object
    $user = $id_or_email;
} elseif ( $id_or_email instanceof WP_Post ) {
    // Post Object
    $user = get_user_by( 'id', (int) $id_or_email->post_author );
} elseif ( $id_or_email instanceof WP_Comment ) {
    /**
     * Filter the list of allowed comment types for retrieving avatars.
     *
     * @since 3.0.0
     *
     * @param array $types An array of content types. Default only contains 'comment'.
     */
    $allowed_comment_types = apply_filters( 'get_avatar_comment_types', array( 'comment' ) );
    if ( ! empty( $id_or_email->comment_type ) && ! in_array( $id_or_email->comment_type, (array) $allowed_comment_types ) ) {
        $args['url'] = false;
        /** This filter is documented in wp-includes/link-template.php */
        return apply_filters( 'get_avatar_data', $args, $id_or_email );
    }
    if ( ! empty( $id_or_email->user_id ) ) {
        $user = get_user_by( 'id', (int) $id_or_email->user_id );
    }
    if ( ( ! $user || is_wp_error( $user ) ) && ! empty( $id_or_email->comment_author_email ) ) {
        $email = $id_or_email->comment_author_email;
    }
}

It would be easier if the user ID would be passed to the filter callbacks or if there would be a special function available for this, e.g.

wp_get_user_from_id_or_email( $id_or_email )
  • 1
    Thanks for this @birgire. You should submit a patch that puts this into a function as you have suggested! – Tim Malone Jun 6 '16 at 19:45
  • Thanks for the suggestion, I think it might make life easier for those working on similar projects ;-) @TimMalone – birgire Jun 6 '16 at 19:49
1

EDIT: My original solution is below, but Sumit alerted me in the comments to the existence of the get_avatar filter. I've posted an additional answer that shows how to implement that option as well.


Yes, you can do this.

The columns displayed in any of these 'list tables' in Wordpress admin are filterable - so using a custom function in your theme's functions.php, you can remove columns or add your own.

This function will allow you to both remove the default column and add a custom one:

add_filter("manage_users_columns", "wpse_228870_custom_user_avatar");

function wpse_228870_custom_user_avatar($columns){

    $columns = 
        array_slice($columns, 0, 1) // leave the checkbox in place (the 0th column)
        + array("custom_avatar" => "") // splice in a custom avatar column in the next space
        + array_slice($columns, 1) // include any other remaining columns (the 1st column onwards)
    ;

    return $columns;

}

There's many ways you can do that but in this I've basically just taken the $columns array and massaged it to stick your custom avatar in at the second position. You can use any PHP array function to do whatever you want to these columns.

Next, we need to tell Wordpress what to display in that custom_avatar column:

add_filter("manage_users_custom_column", "wpse_228870_custom_user_avatar_column", 10, 3);

function wpse_228870_custom_user_avatar_column($output, $column_name, $user_id){

    // bow out early if this isn't our custom column!
    if($column_name != "custom_avatar"){ return $output; }

    // get your custom field here, using $user_id to get the correct one
    // ........

    // enter your custom image output here
    $output = '<img src="image.png" width="50" height="50" />';

    return $output;

}

If the image doesn't come out at the right dimensions or isn't styled appropriately, you can add styles to Wordpress admin if you want to have more control over how the columns and their contents are sized.

You can also read more about the two filters I used in the Wordpress documentation - manage_users_columns is on the Codex and manage_users_custom_column is on the newer code reference. Similar filters exist for any of the other tables, such as posts and pages.

  • 1
    Good solution @Tim but I was just wondering why not use get_avatar filters ? – Sumit Jun 6 '16 at 7:08
  • Hahaha! I didn't even realise that filter was there. Thanks @Sumit! – Tim Malone Jun 6 '16 at 7:09
  • yw:) Then you can add another answer :D – Sumit Jun 6 '16 at 7:10

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.