WP Discourse SSO не синхронизирует локальные аватары, предоставляемые Advanced Site Enhancements

Здравствуйте,

Я использую:

  • WordPress
  • WP Discourse (последняя версия)
  • Advanced Site Enhancements (ASE), используя его функцию Local User Avatar (без Gravatar)

Аватар корректно отображается везде в WordPress.

ASE хранит идентификатор вложения в поле метаданных пользователя:

local_user_avatar_attachment_id

Однако при входе через SSO WordPress Discourse всегда импортирует аватар по умолчанию, а не локальный аватар.

Я уже пробовал использовать фильтр wpdc_sso_avatar_url для возврата URL из медиабиблиотеки, но это не помогло.

Поэтому у меня два вопроса:

  1. Использует ли WP Discourse фильтр wpdc_sso_avatar_url для синхронизации аватара?
  2. Какая функция или фильтр в настоящее время отвечает за определение URL аватара, отправляемого в Discourse?

Буду благодарен за любые рекомендации.

Привет @miednr, да, wpdc_sso_avatar_url по-прежнему используется для синхронизации аватаров. Давай посмотрим, сможем ли мы заставить это работать у тебя.

  1. Включена ли у тебя опция Force Avatar Update в настройках DiscourseConnect Provider?
  2. Пожалуйста, покажи функцию, которую ты используешь с wpdc_sso_avatar_url

Привет, @angus!

Спасибо, что уделили внимание этому вопросу. Да, у меня включена опция «Force Avatar Update».

В данный момент моя функция выглядит так:



<?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 сохраняет идентификатор локального аватара в поле пользовательских метаданных local_user_avatar_attachment_id. Идентификатор существует и указывает на изображение в медиатеке. Однако Discourse по-прежнему импортирует аватар по умолчанию после входа в WordPress/синхронизации SSO.

Я также пробовал тот же подход с размером изображения thumbnail вместо full, но результат был таким же.

Спасибо, что посмотрели!

Привет, @angus,

Я получил ответ от разработчика плагина ASE (Advanced Site Enhancements), который, возможно, поможет сузить круг поиска проблемы.

Согласно их ответу:

  • ASE подключается к стандартным API аватаров WordPress:

  • get_avatar (приоритет 5)

  • get_avatar_url (приоритет 10)

  • get_avatar_data (приоритет 10)

  • В настоящее время не известно о проблемах совместимости с другими плагинами.

  • Локальный аватар хранится в медиатеке, а идентификатор вложения сохраняется в поле пользовательских метаданных:

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 вызывает get_avatar_url() до или после применения фильтра wpdc_sso_avatar_url?

  • Существуют ли какие-либо особые требования к URL аватара (размер, доступность, время вызова и т. д.), которые Discourse ожидает при синхронизации аватара?

Я буду рад выполнить любые дополнительные тесты или добавить временную отладку, если это поможет.

Ещё раз спасибо за вашу помощь!

Включена ли в 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;
});

Сниппет загружается при каждой загрузке страницы, но wpdc_sso_params никогда не срабатывает при выходе/входе в систему или во время процесса входа в Discourse.

Если этот фильтр никогда не срабатывает, то, скорее всего, у вас неправильно настроен DiscourseConnect или вы не используете WordPress в качестве провайдера для входа в Discourse. Пожалуйста, поделитесь файлом meta из WP Discourse > Логи.

Привет, @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) во вкладке «Сеть» (Network) в инструментах разработчика.

но wpdc_sso_params никогда не срабатывает при выходе/входе или во время процесса входа в Discourse

Также, пожалуйста, поделитесь тем, как вы пришли к этому выводу.

Я добавил «error_log( ‘[WPDC avatar debug] snippet loaded’ );»

  1. Я использую DiscourseConnect для входа через стандартную форму входа WordPress.
  2. Я использую менеджер сниппетов Advanced Site Enhancements (ASE) для добавления своих сниппетов. И ваш отладочный сниппет (модифицированный, как описано) позволил записать некоторые записи в debug.log

Что-то не так, так как невозможно войти через DiscourseConnect без срабатывания wpdc_sso_params. Вам нужно разобраться, в чём дело. Без прямого доступа к вашей конфигурации я не смогу это выяснить.

Спасибо @angus за ваши усилия. Я постараюсь узнать больше о этой проблеме и сообщу вам о своих находках.