В WordPress по умолчанию аватары пользователей загружаются и хранятся на сторонних сервисах, таких как Gravatar. Однако многие сайты используют кастомные аватары, загруженные напрямую в медиатеку WordPress или через плагины. При наличии нескольких сайтов на WordPress возникает необходимость синхронизировать пользовательские аватары между ними, чтобы обеспечить единое отображение профилей.
Почему стандартная синхронизация аватаров невозможна
Стандартный механизм WordPress не предусматривает синхронизацию локальных файлов аватаров между сайтами. В случае, если аватар хранится в медиатеке одного сайта, при переходе на другой сайт он будет недоступен, что приведёт к отображению стандартного Gravatar или пустого изображения.
Кроме того, плагины, которые расширяют возможности аватаров, часто сохраняют данные в пользовательских метаполях или отдельной таблице, что усложняет задачу синхронизации.
Поэтому для решения задачи необходимо использовать кастомные методы синхронизации файлов и метаданных.
Основные подходы к синхронизации пользовательских аватаров
Существует несколько способов, как сделать синхронизацию аватаров между сайтами:
- Репликация файлов аватаров — перенос изображений в медиатеке с одного сайта на другой;
- Синхронизация метаданных — копирование данных о пользователях и ссылок на аватары;
- Использование центрального сервера аватаров — хранение всех аватаров в одном месте и вывод их на всех сайтах;
- REST API для передачи аватаров — обмен данными через API-запросы между сайтами.
Рассмотрим практическую реализацию одного из рабочих решений — синхронизацию аватаров через REST API с загрузкой файлов на целевой сайт.
Пример реализации синхронизации аватаров через REST API
Для примера создадим два сайта: источник и приёмник. На источнике мы будем получать аватары пользователей и отправлять их на приёмник, где они сохранятся в медиатеку и привяжутся к пользователям.
1. Регистрация REST API endpoint на приёмнике
Добавьте следующий код в файл functions.php темы или в собственный плагин на сайте-приёмнике:
add_action('rest_api_init', function () {
register_rest_route('wpsync/v1', '/avatar-upload', array(
'methods' => 'POST',
'callback' => 'wpsync_avatar_upload_callback',
'permission_callback' => function () {
return current_user_can('upload_files');
},
));
});
function wpsync_avatar_upload_callback(WP_REST_Request $request) {
$user_id = $request->get_param('user_id');
$avatar_data = $request->get_file_params()['avatar'];
if (!$user_id || !$avatar_data) {
return new WP_Error('missing_data', 'Параметры user_id или avatar отсутствуют', array('status' => 400));
}
// Проверяем пользователя
$user = get_user_by('ID', $user_id);
if (!$user) {
return new WP_Error('invalid_user', 'Пользователь не найден', array('status' => 404));
}
// Загружаем файл аватара в медиатеку
require_once(ABSPATH . 'wp-admin/includes/file.php');
require_once(ABSPATH . 'wp-admin/includes/media.php');
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_id = media_handle_upload('avatar', 0);
if (is_wp_error($attach_id)) {
return $attach_id;
}
// Сохраняем ID вложения в метаполе пользователя
update_user_meta($user_id, 'wpsync_custom_avatar', $attach_id);
return array('success' => true, 'attachment_id' => $attach_id);
}
Этот endpoint принимает POST-запрос с параметром user_id и файлом аватара avatar, загружает его в медиатеку и сохраняет связь с пользователем.
2. Отправка аватара с сайта-источника
Для отправки файла используем PHP и функцию curl:
function wpsync_send_avatar_to_site($user_id, $target_url, $target_api_key) {
$avatar_id = get_user_meta($user_id, 'wpsync_custom_avatar', true);
if (!$avatar_id) {
return new WP_Error('no_avatar', 'У пользователя нет кастомного аватара');
}
$avatar_path = get_attached_file($avatar_id);
if (!file_exists($avatar_path)) {
return new WP_Error('file_not_found', 'Файл аватара не найден');
}
$curl = curl_init();
$cfile = curl_file_create($avatar_path);
$post = array(
'user_id' => $user_id,
'avatar' => $cfile
);
curl_setopt_array($curl, array(
CURLOPT_URL => $target_url . '/wp-json/wpsync/v1/avatar-upload',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $post,
CURLOPT_HTTPHEADER => array(
'Authorization: Bearer ' . $target_api_key
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
return new WP_Error('curl_error', $err);
}
return json_decode($response, true);
}
Вызовите эту функцию, передавая ID пользователя, URL сайта-приёмника и API-ключ для авторизации.
Как использовать синхронизированные аватары на сайте
Чтобы WordPress использовал кастомный аватар, сохранённый в метаполе, добавим фильтр:
add_filter('get_avatar', 'wpsync_custom_avatar_display', 10, 5);
function wpsync_custom_avatar_display($avatar, $id_or_email, $size, $default, $alt) {
$user = false;
if (is_numeric($id_or_email)) {
$user = get_user_by('id', (int) $id_or_email);
} elseif (is_object($id_or_email)) {
if (!empty($id_or_email->user_id)) {
$user = get_user_by('id', (int) $id_or_email->user_id);
}
} elseif (is_string($id_or_email)) {
$user = get_user_by('email', $id_or_email);
}
if ($user) {
$attach_id = get_user_meta($user->ID, 'wpsync_custom_avatar', true);
if ($attach_id) {
$custom_avatar = wp_get_attachment_image_url($attach_id, array($size, $size));
if ($custom_avatar) {
$avatar = '<img alt="' . esc_attr($alt) . '" src="' . esc_url($custom_avatar) . '" class="avatar avatar-' . esc_attr($size) . ' photo" height="' . esc_attr($size) . '" width="' . esc_attr($size) . '" />';
}
}
}
return $avatar;
}
Этот фильтр заменит стандартный Gravatar на кастомный аватар, если он есть.
Дополнительные рекомендации и плагины
Для упрощения работы с аватарами можно использовать плагины, которые расширяют возможности загрузки и управления аватарами, например WP User Avatar или Clearfy Pro для оптимизации и безопасности.
Также стоит обратить внимание на реализацию авторизации API с помощью токенов или ключей для защиты REST API endpoint.
Выводы по синхронизации аватаров в мультисайте и между сайтами
Синхронизация пользовательских аватаров — задача, требующая комплексного подхода: перенос файлов, обновление метаданных и корректное отображение на стороне клиента. Использование REST API для передачи файлов и данных — современный и гибкий метод, который можно адаптировать под любые задачи.
При желании можно расширить функционал, добавив автоматическую синхронизацию через cron или триггеры при обновлении аватара.