WP Discourse SSO 不会同步由 Advanced Site Enhancements 提供的本地头像

你好,

我正在使用:

  • WordPress
  • WP Discourse(最新版本)
  • Advanced Site Enhancements (ASE),使用其本地用户头像功能(不使用 Gravatar)

头像在 WordPress 的所有地方都正确显示。

ASE 将附件 ID 存储在用户元字段中:

local_user_avatar_attachment_id

然而,在进行 WordPress SSO 登录时,Discourse 始终导入默认头像,而不是本地头像。

我已经尝试使用 wpdc_sso_avatar_url 过滤器返回媒体库 URL,但没有效果。

因此我有两个问题:

  1. WP Discourse 是否仍然使用 wpdc_sso_avatar_url 进行头像同步?
  2. 目前哪个函数或过滤器负责确定发送到 Discourse 的头像 URL?

任何指导都将不胜感激。

@miednr,是的,wpdc_sso_avatar_url 仍然用于头像同步。让我们看看能否帮你让它正常工作。

  1. 你是否在 DiscourseConnect Provider 设置中启用了 Force Avatar Update(强制更新头像)?
  2. 请分享你使用 wpdc_sso_avatar_url 的函数。

你好 @angus

感谢你的关注。是的,我已经启用了“强制更新头像”。

我目前的函数如下:



<?php
add_filter( 'get_avatar_url', function( $url, $id_or_email, $args ) {
    $user = false;
    if ( is_numeric( $id_or_email ) ) {
        $user = get_user_by( 'id', (int) $id_or_email );
    } elseif ( $id_or_email instanceof WP_User ) {
        $user = $id_or_email;
    }
    if ( ! $user ) {
        return $url;
    }
    $avatar_id = get_user_meta( $user->ID, 'local_user_avatar_attachment_id', true );
    if ( ! $avatar_id ) {
        return $url;
    }
    $local_avatar_url = wp_get_attachment_image_url( (int) $avatar_id, 'full' );
    return $local_avatar_url ?: $url;
}, 10, 3 );

我修改过几次,试图让它正常工作。不过,我想我之前有一个更好的版本。:wink:

如果能找到一个能正常工作的版本,那就太好了。

您是不是分享错了代码片段?那段代码使用的是 get_avatar_url 过滤器。正如您所注意到的,正确的过滤器是 wpdc_sso_avatar_url

你好 @angus

我分享了一种不同的方法,这是我尝试过的。抱歉。这是我能分享的最佳代码片段:

add_filter( 'wpdc_sso_avatar_url', function( $avatar_url, $user_id ) {

$avatar_id = get_user_meta( $user_id, 'local_user_avatar_attachment_id', true );

if ( ! $avatar_id ) {
    return $avatar_url;
}

$local_avatar_url = wp_get_attachment_image_url( (int) $avatar_id, 'full' );

if ( ! $local_avatar_url ) {
    return $avatar_url;
}

return esc_url_raw( $local_avatar_url );

}, 10, 2 );

我尝试了这个代码片段。ASE 将本地头像附件 ID 存储在用户元字段 local_user_avatar_attachment_id 中。该附件 ID 存在并指向媒体库中的图片。然而,在 WordPress 登录/SSO 同步后,Discourse 仍然导入默认头像。

我还尝试了使用 thumbnail 图片尺寸代替 full 的相同方法,但结果相同。

感谢查看!

@angus

我收到了 ASE(Advanced Site Enhancements,高级站点增强)开发人员的回复,这可能有助于缩小问题范围。

根据他们的说法:

  • ASE 挂钩了标准的 WordPress 头像 API:

  • get_avatar(优先级 5)

  • get_avatar_url(优先级 10)

  • get_avatar_data(优先级 10)

  • 目前尚无已知的与其他插件的兼容性问题。

  • 本地头像存储在媒体库中,附件 ID 保存在用户元数据字段中:

local_user_avatar_attachment_id

他们还建议手动获取头像 URL,如下所示:

$attachment_id = (int) get_user_meta( $user_id, 'local_user_avatar_attachment_id', true );

if ( $attachment_id ) {

$avatar_url = wp_get_attachment_image_url( $attachment_id, array( 128, 128 ) );

}

我也尝试在 wpdc_sso_avatar_url 过滤器中使用此方法,但结果没有变化——登录后仍然使用默认的 Discourse 头像。

由于 ASE 声称挂钩了 get_avatar_url(),我想知道:

  • WP Discourse 是在应用 wpdc_sso_avatar_url 过滤器之前还是之后调用 get_avatar_url()?

  • 在头像同步过程中,Discourse 对头像 URL(大小、可访问性、时机等)是否有任何特定要求?

如果有帮助,我很乐意运行其他测试或添加临时调试。

再次感谢您的帮助!

您是否在 Discourse 中启用了 discourse_connect_overrides_avatar 站点设置?

是的,它已被激活。

好的,让我们检查一下最终的 SSO 参数。请添加此过滤器并查看它记录了什么

add_filter( 'wpdc_sso_params', function ( $params ) {
   error_log( "avatar_url: {$params['avatar_url']} force: {$params['avatar_force_update']}" );
   return $params;
});

该代码片段在每次页面加载时都会执行,但在登出/登录或 Discourse 登录流程中,wpdc_sso_params 从未触发。

如果该过滤器从未触发,则很可能是您没有正确配置 DiscourseConnect,或者您没有使用 WordPress 作为登录 Discourse 的提供商。请分享来自 WP Discourse > Logs 的 meta 文件。

你好 @angus

当然,请查看:

### 服务器 ###

WordPress - 7.0

PHP - 8.3.6

MySQL - 8.4.9

### WP Discourse 设置(已排除密钥) ###

connection-logs - 0

display-subcategories - 1

allow-tags - 1

max-tags - 15

publish-as-unlisted - 0

full-post-content - 0

custom-excerpt-length - 100

add-featured-link - 1

auto-publish - 1

force-publish - 1

force-publish-max-age - 0

publish-failure-notice - 1

auto-track - 1

allowed_post_types - post

exclude_tags -

hide-discourse-name-field - 0

discourse-username-editable - 0

direct-db-publication-flags - 0

verbose-publication-logs - 0

enable-discourse-comments - 1

comment-type - display-public-comments-only

ajax-load - 1

load-comment-css - 1

discourse-new-tab - 1

hide-wordpress-comments - 1

show-existing-comments - 0

max-comments - 10

min-replies - 0

min-score - 0

min-trust-level - 0

bypass-trust-level-score - 0

only-show-moderator-liked - 0

custom-datetime-format -

cache-html - 0

clear-cached-comment-html - 0

verbose-comment-logs - 0

use-discourse-webhook - 1

use-discourse-user-webhook - 1

webhook-match-user-email - 0

verbose-webhook-logs - 0

verbose-sso-logs - 1

enable-sso - 1

auto-create-sso-user - 1

real-name-as-discourse-name - 0

force-avatar-update - 1

redirect-without-login - 0

sso-client-enabled - 0

sso-client-login-form-change - 0

sso-client-sync-by-email - 0

sso-client-disable-create-user - 0

sso-client-sync-logout - 0

logs-enabled - 1

WordPress 确实已设置为提供商,但 DiscourseConnect 代码似乎并未触发。这暗示您实际上并未使用 DiscourseConnect 进行登录,或者您未正确加载代码片段或日志。您是否设置了其他登录方法,例如 OAuth?建议您录制测试过程中的具体操作步骤。尝试在录制中捕获 URL,并通过在开发者工具的网络选项卡中启用“保留日志”(Preserve Log)来捕获。

wpdc_sso_params 在注销/登录或 Discourse 登录流程期间从未触发

此外,请分享您得出此结论的依据。

我添加了 error_log( '[WPDC avatar debug] snippet loaded' );

  1. 我确实是通过标准的 WordPress 登录界面使用 DiscourseConnect 进行登录的。
  2. 我使用 Advanced Site Enhancements (ASE) Snippets Manager 来添加代码片段。按照说明修改后的调试代码片段,确实能够在 debug.log 中生成一些日志条目。

有些不对劲,因为如果没有 wpdc_sso_params 触发,就无法使用 DiscourseConnect 登录。你需要找出问题所在。由于无法直接访问你的环境,我无法确定这部分的具体情况。

感谢 @angus 的努力。我现在会尽力去了解更多关于这个问题的信息,并告诉你我的发现。