Avatares de WordPress desde Discourse cuando Discourse es el proveedor SSO

Tengo Wordpress con Discourse configurado donde Discourse es el proveedor de DiscourseConnect para WP. Estoy usando el plugin WP Discourse y está funcionando muy bien hasta ahora. El único problema que he encontrado hasta ahora es que no puedo mostrar las imágenes de avatar de Discourse en WP.

He intentado implementar la solución en Could you update user avatar for wordpress plugin sso? - #2 by angus - agregando el código al archivo function.php de mi sitio WP. Pero no me funciona; no sé qué código agregar para configurar el avatar.

Me pregunto si alguien ha logrado que esto funcione. Estoy usando el plugin Simple Local Avatar, pero no me importa cambiarlo si alguien ha tenido éxito con otro plugin.

Hola @uffehe

¿Qué código estás añadiendo y cómo guarda avatares el plugin Simple Local Avatar?

Hola @angus

No soy desarrollador, así que estoy adivinando, pero según entiendo, el plugin Simple Local Avatar normalmente añade la imagen a la biblioteca de medios. No encontré mucha documentación sobre cómo funciona si se proporciona a través de una URL. El código que estoy probando es el siguiente:

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 de la nueva imagen de avatar
        );
        update_user_meta($updated_user, 'simple_local_avatar', $avatar_data);
    }
}

Esto me da una excepción no controlada cuando intento iniciar sesión usando SSO.

Probablemente podría contratar a un desarrollador para que me ayude, pero parece que este sería un caso de uso bastante común que otros podrían haber implementado, aunque no con este plugin.

Creo que la causa de la excepción es que tu function my_wpdc_sso_client_updated_user no está devolviendo la matriz $updated_user. Esa matriz es necesaria para la función que agrega el filtro wpdc_sso_client_updated_user para que continúe.

También necesitas establecer el ID de usuario de WordPress del usuario en la llamada a update_user_meta.

Esto funciona, pero deshabilita la funcionalidad de redimensionamiento del plugin Simple Local Avatars:

add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ); // previene el redimensionamiento 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 de la nueva imagen de avatar
		);
		update_user_meta( $wp_user_id, 'simple_local_avatar', $avatar_data );
	}

	return $updated_user;
}

La razón para prevenir el redimensionamiento de avatares es que el redimensionamiento se realiza con el código del editor de imágenes de WordPress. Para que funcione, la imagen debe descargarse en WordPress. Ten en cuenta que si omites la línea add_filter( 'simple_local_avatars_dynamic_resize', '__return_false' ) del código anterior, el plugin Simple Local Avatars intentará redimensionar las imágenes, generará una advertencia de PHP y luego usará la imagen de tamaño completo, por lo que nada parecerá roto desde el punto de vista del usuario.

No estoy muy seguro de combinar el uso de avatares de Discourse con el plugin Simple Local Avatars. El problema que veo es que el plugin da a los usuarios la opción de subir un avatar personalizado en WordPress. Si lo hacen, y luego vuelven a iniciar sesión en WordPress desde Discourse, podrían preguntarse qué ha pasado con el avatar que subieron. Sería más complejo de desarrollar, pero podría ser mejor agregar la capacidad de establecer deliberadamente tu avatar de Discourse como tu avatar de WordPress en la página de perfil de usuario de WordPress.

2 Me gusta

Quizás lo sea. Ya que lo estaba revisando de todos modos, pensé que podría intentar un enfoque que no usara el plugin Simple Local Avatars.

El código a continuación se engancha al filtro 'wpdc_sso_client_updated_user' que se llama cuando un usuario inicia sesión en WordPress a través de Discourse. Si el usuario ha subido un avatar personalizado a Discourse, su custom_avatar_template de Discourse se guarda como metadatos del usuario en WordPress. Luego se engancha al filtro 'get_avatar_url' de WordPress y utiliza el custom_avatar_template de Discourse para establecer la URL del avatar. Me gusta este enfoque porque aprovecha la funcionalidad de redimensionamiento de plantillas de Discourse.

Tenga en cuenta que solo he probado esto 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;
	}

    // Comprueba si el usuario tiene una plantilla para un avatar subido en 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}";
    // Guarda la plantilla del avatar. El tamaño a mostrar se sustituye en el 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 ) {
    // Empieza con $user_id establecido en `null`. El código a continuación puede omitir algunos 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;
    }

    // Si $user_id no se ha establecido, devuelve el parámetro $url.
    if ( empty( $user_id ) ) {

        return $url;
    }

    $discourse_avatar_template = get_user_meta( $user_id, 'discourse_avatar_template', true );
    // Si los metadatos de la plantilla no se han establecido, devuelve $url.
    if (empty( $discourse_avatar_template ) ) {

        return $url;
    }

    $size = isset( $args['size']) ? $args['size'] : 128;  // No estoy seguro de si 'size' podría ser vacío. 128 parece una opción segura.

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

Hola @simon

Perfecto, funciona exactamente como se describe. Y estoy de acuerdo, es mucho más limpio sin necesidad de un plugin de WP y la confusión en torno a los avatares conflictivos. ¡Gracias!

2 Me gusta

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