# 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:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![uffehe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/uffehe/32/208266_2.png) [@uffehe](https://meta.discourse.org/u/uffehe)
#### Post date: [August 2, 2023, 3:15pm UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/1 "2023-08-02T15:15:37Z")

</div>

I have Wordpress with Discourse setup where Discourse is the [DiscourseConnect](https://meta.discourse.org/t/13045?silent=true) provider for WP. I’m using the [WP Discourse](https://github.com/discourse/wp-discourse) plugin and it’s working great so far. The only issue I have encountered so far is that I can’t get the avatar images from Discourse to display in WP.

I have tried to implement the solution in [Could you update user avatar for wordpress plugin sso? - #2 by angus](https://meta.discourse.org/t/could-you-update-user-avatar-for-wordpress-plugin-sso/204517/2) - adding the code to my WP site’s function.php file. But it’s not working for me - I don’t know what code to add to set the avatar.

I’m wondering if anyone has gotten this to work? I’m using the Simple Local Avatar plugin, but I’m happy to change it if anyone has been successful with another plugin.

---

<div class="post-metadata">

### Author: ![angus](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/angus/32/341715_2.png) [@angus](https://meta.discourse.org/u/angus)
#### Post date: [August 3, 2023, 7:02am UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/2 "2023-08-03T07:02:38Z")

</div>

Hey @uffehe

> [@uffehe](#):
>
> adding the code to my WP site’s function.php file  
> …  
> I’m using the Simple Local Avatar plugin

What code are you adding and how does the Simple Local Avatar plugin save avatars?

---

<div class="post-metadata">

### Author: ![uffehe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/uffehe/32/208266_2.png) [@uffehe](https://meta.discourse.org/u/uffehe)
#### Post date: [August 3, 2023, 6:42pm UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/3 "2023-08-03T18:42:35Z")

</div>

Hi @angus

I’m not a developer so I’m kind of guessing here, but as I understand it the Simple Local Avatar plugin normally adds the image to the media library. I couldn’t find much documentation on how it works if it’s supplied via a URL. The code I’m trying looks like this:

```plaintext
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 ) {
    if (isset($query['avatar_url'])) {
        $new_avatar_url = $query['avatar_url'];

        $avatar_data = array(
            'full' => $new_avatar_url, // URL of the new avatar image
        );
        update_user_meta($updated_user, 'simple_local_avatar', $avatar_data);
    }
}

```

This gives me an unhandled exception when I try to log in using SSO.

I could probably hire a developer to help me, but it seems that this would be a pretty common use case that others might have already implemented - even if not with this plugin.

---

<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, 5:59am UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/4 "2023-08-04T05:59:10Z")

</div>

> [@uffehe](#):
>
> This gives me an unhandled exception when I try to log in using SSO.

I think the cause of the exception is that your `function my_wpdc_sso_client_updated_user` isn’t returning the `$updated_user` array. That array is needed for the function that adds the `wpdc_sso_client_updated_user` filter to continue.

You also need to set the user’s WordPress user ID in the call to `update_user_meta`.

This works, but disables the Simple Local Avatars plugin’s rescaling functionality:

```php
add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ); // prevent resizing of avatars
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 ) {
	if ( isset( $query['avatar_url'] ) ) {
		$new_avatar_url = $query['avatar_url'];
		$wp_user_id = $updated_user['ID'];

		$avatar_data = array(
			'full' => $new_avatar_url, // URL of the new avatar image
		);
		update_user_meta( $wp_user_id, 'simple_local_avatar', $avatar_data );
	}

	return $updated_user;
}

```

The reason for preventing the resizing of avatars is because the resizing is done with the WordPress image editor code. For it to work, the image needs to be downloaded to WordPress. Note that if you leave off the `add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' )` line from the code above, the Simple Local Avatars plugin will attempt to resize the images, throw a PHP warning, then use the full size image - so nothing would seem broken from a user’s point of view.

I’m somewhat unsure about combining the use of Discourse avatars with the Simple Local Avatars plugin. The issue I see is that the plugin gives users the option to upload a custom avatar on WordPress. If they do that, then log back into WordPress from Discourse, they might wonder what has happened to the avatar they uploaded. It would be more complex to develop, but it might be better to add the ability to deliberately set your Discourse avatar as your WordPress avatar on the user’s WordPress profile page.

---

<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 );
}

```

---

<div class="post-metadata">

### Author: ![uffehe](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/uffehe/32/208266_2.png) [@uffehe](https://meta.discourse.org/u/uffehe)
#### Post date: [August 6, 2023, 4:12pm UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/6 "2023-08-06T16:12:07Z")

</div>

Hi @simon

Perfect - it works exactly as described. And I agree, it’s much cleaner without needing a WP plugin and the confusion around conflicting avatars. Thanks!

---

<div class="post-metadata">

### Author: ![system](https://sea3.discourse-cdn.com/meta/user_avatar/meta.discourse.org/system/32/443519_2.png) [@system](https://meta.discourse.org/u/system)
#### Post date: [September 5, 2023, 4:12pm UTC](https://meta.discourse.org/t/wordpress-avatars-from-discourse-when-discourse-is-the-sso-provider/273669/7 "2023-09-05T16:12:38Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
