# Wordpress avatars from Discourse when Discourse is the SSO provider

**URL:** <https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669>\
**Category:** WordPress\
**Created:** [August 2, 2023, 3:15pm UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669 "2023-08-02T15:15:37Z")\
**Posts on this page:** 1\
**Showing post:** 5

<div class="post-metadata">

**Author:** ![simon](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/simon/32/339122_2.png) [@simon](https://meta.discourse.org/u/simon)\
**Post date:** [August 4, 2023, 8:48am UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/5 "2023-08-04T08:48:40Z")

</div>

> [@uffehe](#):
>
> it seems that this would be a pretty common use case

Maybe it is. Since I was looking at it anyway, I figured I might as well try an approach that doesn’t use the Simple Local Avatars plugin.

The code below hooks into the `'wpdc_sso_client_updated_user'` filter that’s called when a user logs into WordPress via Discourse. If the user has uploaded a custom avatar to Discourse, their Discourse `custom_avatar_template` is saved as user metadata on WordPress. It then hooks into the WordPress `'get_avatar_url'` filter and uses the Discourse `custom_avatar_template` to set the avatar’s URL. I like this approach because it makes use of Discourse’s template resizing functionality.

Note that I’ve only tested this locally.

```php
use WPDiscourse\Utilities\Utilities as DiscourseUtilities;
add_filter( 'wpdc_sso_client_updated_user', 'my_wpdc_sso_client_updated_user', 10, 2 );
function my_wpdc_sso_client_updated_user( $updated_user, $query ) {
	$options = DiscourseUtilities::get_options();
	$base_url = $options['url'];
	$discourse_username = $query['username'];
	$discourse_profile_url = "{$base_url}/u/{$discourse_username}.json";
	$wp_user_id = $updated_user['ID'];
	$profile_data = DiscourseUtilities::discourse_request( $discourse_profile_url );
	if ( is_wp_error( $profile_data ) ) {

		return $updated_user;
	}

    // Check to see if the user has a template for an uploaded avatar on Discourse.
	$user_data = $profile_data->user;
	if ( ! property_exists( $user_data, 'custom_avatar_template' ) ) {

		return $updated_user;
	}

	$custom_avatar_template_path = $profile_data->user->custom_avatar_template;
    $custom_avatar_template = "{$base_url}{$custom_avatar_template_path}";
    // Save the avatar template. The size to display gets substituted in the `get_avatar_url` filter.
    update_user_meta( $wp_user_id, 'discourse_avatar_template', $custom_avatar_template );

    return $updated_user;
}

add_filter('get_avatar_url', 'my_get_avatar_url', 10, 3 );
function my_get_avatar_url($url, $id_or_email, $args ) {
    // Start with $user_id set to `null`. The code below may miss some cases.
    $user_id = null;
    if ( is_numeric( $id_or_email ) ) {
        $user_id = $id_or_email;
    } elseif ( $id_or_email instanceof WP_User ) {
        $user_id = $id_or_email->ID;
    } elseif ( $id_or_email instanceof WP_Post ) {
        $user_id = $id_or_email->user_id;
    } elseif ( $id_or_email instanceof WP_Comment ) {
        $user_id = $id_or_email->user_id;
    }

    // If $user_id hasn't been set, return the $url parameter.
    if ( empty( $user_id ) ) {

        return $url;
    }

    $discourse_avatar_template = get_user_meta( $user_id, 'discourse_avatar_template', true );
    // If the template metadata hasn't been set, return $url.
    if (empty( $discourse_avatar_template ) ) {

        return $url;
    }

    $size = isset( $args['size']) ? $args['size'] : 128; // I'm not sure if 'size' could ever be empty. 128 seems like a safe fallback.

    return str_replace( '{size}', $size, $discourse_avatar_template );
}

```

---

_[View the full topic](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669)._
