WordpressのアバターをDiscourseから取得(DiscourseがSSOプロバイダーの場合)

WordPressとDiscourseを連携させ、DiscourseをWPのDiscourseConnectプロバイダーとして設定しています。WP Discourseプラグインを使用しており、これまでは順調に動作していました。今のところ遭遇した唯一の問題は、Discourseのアバター画像をWPに表示させることができないことです。

Could you update user avatar for wordpress plugin sso? - #2 by angus に記載されている解決策を試しました。WPサイトのfunction.phpファイルにコードを追加しましたが、うまくいきません。アバターを設定するためにどのコードを追加すればよいかわかりません。

どなたかこれを機能させた方はいらっしゃいますか?Simple Local Avatarプラグインを使用していますが、他のプラグインで成功した方がいれば、それに変更しても構いません。

Hey @uffehe

どのようなコードを追加していますか?また、Simple Local Avatarプラグインはアバターをどのように保存しますか?

こんにちは、@angusさん

私は開発者ではないので、推測になりますが、私の理解では、Simple Local Avatarプラグインは通常、画像をメディアライブラリに追加します。URLから提供された場合の動作に関するドキュメントはあまり見つかりませんでした。私が試しているコードは次のとおりです。

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
        );
        update_user_meta($updated_user, 'simple_local_avatar', $avatar_data);
    }
}

これにより、SSOを使用してログインしようとすると、未処理の例外が発生します。

開発者を雇って手伝ってもらうこともできますが、これは他の人がすでに実装している可能性のある非常に一般的なユースケースのように思えます。たとえこのプラグインでなくても。

例外の原因は、function my_wpdc_sso_client_updated_user$updated_user 配列を返していないことだと思います。この配列は、wpdc_sso_client_updated_user フィルターを追加する関数に必要です。

また、update_user_meta の呼び出しでユーザーのWordPressユーザーIDを設定する必要があります。

これは機能しますが、Simple Local Avatars プラグインのリサイズ機能を無効にします。

add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ); // アバターのリサイズを防止
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
		);
		update_user_meta( $wp_user_id, 'simple_local_avatar', $avatar_data );
	}

	return $updated_user;
}

アバターのリサイズを防止する理由は、リサイズがWordPressの画像エディタコードで行われるためです。機能させるには、画像をWordPressにダウンロードする必要があります。上記のコードから add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ) の行を削除すると、Simple Local Avatars プラグインは画像をリサイズしようとし、PHPの警告が発生しますが、その後フルサイズの画像が使用されるため、ユーザーからは何も問題がないように見えることに注意してください。

DiscourseアバターとSimple Local Avatars プラグインの併用については、やや不確実です。問題は、このプラグインがWordPressでカスタムアバターをアップロードするオプションをユーザーに提供することです。もしユーザーがカスタムアバターをアップロードしてからDiscourseからWordPressに再度ログインした場合、アップロードしたアバターがどうなったのか疑問に思うかもしれません。開発はより複雑になりますが、ユーザーのWordPressプロフィールページでDiscourseアバターをWordPressアバターとして明示的に設定する機能を追加する方が良いかもしれません。

「いいね!」 2

そうかもしれません。どうせ見ていたので、Simple Local Avatars プラグインを使用しないアプローチを試してみることにしました。

以下のコードは、ユーザーが Discourse 経由で WordPress にログインしたときに呼び出される 'wpdc_sso_client_updated_user' フィルターにフックします。ユーザーが Discourse にカスタムアバターをアップロードした場合、その Discourse の custom_avatar_template は WordPress のユーザーメタデータとして保存されます。次に、WordPress の 'get_avatar_url' フィルターにフックし、Discourse の custom_avatar_template を使用してアバターの URL を設定します。このアプローチは、Discourse のテンプレートリサイズ機能を利用できるため気に入っています。

これはローカルでのみテストしたことに注意してください。

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

    // 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}";
    // アバターテンプレートを保存します。表示されるサイズは `get_avatar_url` フィルターで置換されます。
    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 ) {
    // $user_id を `null` で初期化します。以下のコードでは一部のケースが欠落する可能性があります。
    $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;
    }

    // $user_id が設定されていない場合は、$url パラメータを返します。
    if ( empty( $user_id ) ) {

        return $url;
    }

    $discourse_avatar_template = get_user_meta( $user_id, 'discourse_avatar_template', true );
    // テンプレートメタデータが設定されていない場合は、$url を返します。
    if (empty( $discourse_avatar_template ) ) {

        return $url;
    }

    $size = isset( $args['size']) ? $args['size'] : 128;  // 'size' が空になる可能性があるかどうかはわかりません。128 は安全なフォールバックのように思えます。

    return str_replace( '{size}', $size, $discourse_avatar_template );
}
「いいね!」 3

こんにちは @simon さん

完璧です。説明どおりに動作します。また、WPプラグインやアバターの競合に関する混乱を必要とせずに、はるかにクリーンになったことにも同意します。ありがとうございます!

「いいね!」 2

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