Avatares do Wordpress do Discourse, com o Discourse como provedor de SSO

Tenho o WordPress com o Discourse configurado, onde o Discourse é o provedor do DiscourseConnect para o WP. Estou usando o plugin WP Discourse e ele está funcionando bem até agora. O único problema que encontrei até agora é que não consigo exibir as imagens de avatar do Discourse no WP.

Tentei implementar a solução em Could you update user avatar for wordpress plugin sso? - #2 by angus - adicionando o código ao arquivo function.php do meu site WP. Mas não está funcionando para mim - não sei que código adicionar para definir o avatar.

Gostaria de saber se alguém conseguiu fazer isso funcionar? Estou usando o plugin Simple Local Avatar, mas estou feliz em mudá-lo se alguém obteve sucesso com outro plugin.

Olá @uffehe

Que código você está adicionando e como o plugin Simple Local Avatar salva os avatares?

Olá @angus

Eu não sou um desenvolvedor, então estou meio que adivinhando, mas pelo que entendi, o plugin Simple Local Avatar normalmente adiciona a imagem à biblioteca de mídia. Não encontrei muita documentação sobre como ele funciona se for fornecido por meio de uma URL. O código que estou tentando se parece com isto:

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 da nova imagem do avatar
        );
        update_user_meta($updated_user, 'simple_local_avatar', $avatar_data);
    }
}

Isso me dá uma exceção não tratada quando tento fazer login usando SSO.

Eu poderia contratar um desenvolvedor para me ajudar, mas parece que este seria um caso de uso bastante comum que outros já poderiam ter implementado - mesmo que não com este plugin.

Acho que a causa da exceção é que sua function my_wpdc_sso_client_updated_user não está retornando o array $updated_user. Esse array é necessário para a função que adiciona o filtro wpdc_sso_client_updated_user continuar.

Você também precisa definir o ID do usuário do WordPress na chamada para update_user_meta.

Isso funciona, mas desabilita a funcionalidade de redimensionamento do plugin Simple Local Avatars:

add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ); // impede o redimensionamento de avatares
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 da nova imagem de avatar
		);
		update_user_meta( $wp_user_id, 'simple_local_avatar', $avatar_data );
	}

	return $updated_user;
}

O motivo para impedir o redimensionamento de avatares é que o redimensionamento é feito com o código do editor de imagens do WordPress. Para funcionar, a imagem precisa ser baixada para o WordPress. Observe que se você remover a linha add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ) do código acima, o plugin Simple Local Avatars tentará redimensionar as imagens, gerará um aviso PHP e, em seguida, usará a imagem em tamanho real - então nada parecerá quebrado do ponto de vista do usuário.

Estou um tanto incerto sobre a combinação do uso de avatares do Discourse com o plugin Simple Local Avatars. O problema que vejo é que o plugin oferece aos usuários a opção de fazer upload de um avatar personalizado no WordPress. Se eles fizerem isso, e depois fizerem login no WordPress novamente do Discourse, eles podem se perguntar o que aconteceu com o avatar que fizeram upload. Seria mais complexo de desenvolver, mas pode ser melhor adicionar a capacidade de definir deliberadamente seu avatar do Discourse como seu avatar do WordPress na página de perfil do usuário no WordPress.

2 curtidas

Talvez seja. Como eu estava olhando de qualquer maneira, pensei que poderia tentar uma abordagem que não usa o plugin Simple Local Avatars.

O código abaixo se conecta ao filtro 'wpdc_sso_client_updated_user' que é chamado quando um usuário faz login no WordPress via Discourse. Se o usuário carregou um avatar personalizado para o Discourse, seu custom_avatar_template do Discourse é salvo como metadados do usuário no WordPress. Em seguida, ele se conecta ao filtro 'get_avatar_url' do WordPress e usa o custom_avatar_template do Discourse para definir o URL do avatar. Gosto dessa abordagem porque ela utiliza a funcionalidade de redimensionamento de modelo do Discourse.

Note que eu testei isso apenas localmente.

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

    // Verifica se o usuário tem um modelo para um avatar carregado no 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}";
    // Salva o modelo de avatar. O tamanho a ser exibido é substituído no filtro `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 ) {
    // Começa com $user_id definido como `null`. O código abaixo pode perder alguns casos.
    $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;
    }

    // Se $user_id não foi definido, retorna o parâmetro $url.
    if ( empty( $user_id ) ) {

        return $url;
    }

    $discourse_avatar_template = get_user_meta( $user_id, 'discourse_avatar_template', true );
    // Se os metadados do modelo não foram definidos, retorna $url.
    if (empty( $discourse_avatar_template ) ) {

        return $url;
    }

    $size = isset( $args['size']) ? $args['size'] : 128;  // Não tenho certeza se 'size' poderia ser vazio. 128 parece um fallback seguro.

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

Oi @simon

Perfeito - funciona exatamente como descrito. E concordo, é muito mais limpo sem precisar de um plugin do WP e da confusão em torno de avatares conflitantes. Obrigado!

2 curtidas

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