Синхронизация данных между несколькими сайтами на WordPress — частая задача, особенно когда готовые плагины не подходят под конкретные бизнес-требования. В этой статье мы рассмотрим, как создать собственный плагин для синхронизации данных WordPress, который можно адаптировать под любые нужды. Разберём архитектуру, реализацию ключевых функций и дадим практические примеры кода.
Понимание задачи: что и зачем синхронизировать в WordPress
В зависимости от целей, синхронизация может касаться различных типов данных: записи (посты), пользовательские поля, таксономии, настройки плагинов, медиафайлы. Важно чётко определить, что именно нужно синхронизировать, и с какой периодичностью.
Например, если у вас несколько сайтов, где публикуются одинаковые новости, разумно синхронизировать только посты и связанные метаданные. Если же речь о мультисайте с разными контентами, можно ограничиться только общими настройками.
Перед реализацией стоит продумать формат обмена данными — XML, JSON, REST API, а также механизм аутентификации и безопасности передачи.
Структура плагина для синхронизации WordPress
Минимальная структура плагина включает в себя:
- Файл основного плагина
wpsync-sync.phpс подключением всех модулей. - Классы и функции для обработки запросов синхронизации.
- API-интерфейс для приёма и отправки данных.
- Механизм аутентификации — например, через OAuth или ключ API.
- Логирование процесса синхронизации и ошибок.
Пример базовой структуры папок:
wpsync-sync/
├── wpsync-sync.php
├── includes/
│ ├── class-wpsync-api.php
│ ├── class-wpsync-sync-handler.php
│ └── functions-wpsync.php
└── logs/
└── wpsync.log
Реализация REST API для синхронизации данных
WordPress имеет встроенный REST API, который мы можем использовать для обмена данными между сайтами. Создадим собственный эндпоинт, который будет принимать и отдавать данные в формате JSON.
В файле class-wpsync-api.php зарегистрируем маршрут:
add_action('rest_api_init', function () {
register_rest_route('wpsync/v1', '/sync/', [
'methods' => 'POST',
'callback' => 'wpsync_handle_sync_request',
'permission_callback' => 'wpsync_check_permissions',
]);
});
function wpsync_handle_sync_request(WP_REST_Request $request) {
$data = $request->get_json_params();
// Обработка полученных данных
$result = wpsync_process_data($data);
if ($result) {
return new WP_REST_Response(['status' => 'success'], 200);
} else {
return new WP_REST_Response(['status' => 'error'], 500);
}
}
function wpsync_check_permissions() {
// Проверка ключа API или авторизации
$headers = getallheaders();
if (isset($headers['X-WPSYNC-APIKEY']) && $headers['X-WPSYNC-APIKEY'] === WPSYNC_API_KEY) {
return true;
}
return false;
}В этом примере реализована простая проверка ключа API в заголовках запроса. Для реальных проектов лучше использовать более надёжные методы аутентификации.
Обработка и запись данных в базу WordPress
После получения данных необходимо сохранить их в базе. Например, если синхронизируем записи, используем функцию wp_insert_post() или wp_update_post().
function wpsync_process_data(array $data) {
foreach ($data['posts'] as $post_data) {
$existing = get_page_by_title($post_data['post_title'], OBJECT, $post_data['post_type']);
$post_arr = [
'post_title' => $post_data['post_title'],
'post_content' => $post_data['post_content'],
'post_status' => $post_data['post_status'],
'post_type' => $post_data['post_type'],
];
if ($existing) {
$post_arr['ID'] = $existing->ID;
wp_update_post($post_arr);
} else {
wp_insert_post($post_arr);
}
}
return true;
}В этом коде происходит проверка по заголовку поста, чтобы обновлять существующие записи, а не создавать дубликаты. При необходимости можно расширить логику проверки уникальности.
Синхронизация медиафайлов
Медиафайлы — одна из самых сложных частей синхронизации, так как требуют передачи больших объёмов данных и правильной обработки метаданных.
Чтобы синхронизировать изображения, можно реализовать отдельный API-эндпоинт, который будет принимать файл через POST-запрос и сохранять его в библиотеку медиа WordPress:
function wpsync_handle_media_upload(WP_REST_Request $request) {
$files = $request->get_file_params();
if (empty($files['file'])) {
return new WP_REST_Response(['error' => 'No file uploaded'], 400);
}
$file = $files['file'];
$upload = wp_handle_upload($file, ['test_form' => false]);
if (isset($upload['error'])) {
return new WP_REST_Response(['error' => $upload['error']], 500);
}
$attachment = [
'post_mime_type' => $upload['type'],
'post_title' => sanitize_file_name($file['name']),
'post_content' => '',
'post_status' => 'inherit'
];
$attach_id = wp_insert_attachment($attachment, $upload['file']);
require_once(ABSPATH . 'wp-admin/includes/image.php');
$attach_data = wp_generate_attachment_metadata($attach_id, $upload['file']);
wp_update_attachment_metadata($attach_id, $attach_data);
return new WP_REST_Response(['attachment_id' => $attach_id], 200);
}После загрузки файла его можно связать с соответствующим постом через метаполя.
Практические советы по отладке и логированию синхронизации
Для эффективной разработки и поддержки плагина важно вести логирование всех этапов синхронизации. Это поможет быстро выявлять ошибки и корректировать поведение.
В плагине можно реализовать простое логирование в файл:
function wpsync_log($message) {
$log_file = plugin_dir_path(__FILE__) . 'logs/wpsync.log';
$date = date('Y-m-d H:i:s');
file_put_contents($log_file, "[{$date}] {$message}\n", FILE_APPEND);
}Вызывайте эту функцию в ключевых местах, например, при получении данных, ошибках или успешных операциях.
Использование готовых плагинов и библиотек для ускорения разработки
Хотя создание собственного плагина даёт контроль и гибкость, можно использовать сторонние библиотеки для упрощения задач:
- WP REST API Controller — для быстрого создания кастомных REST API эндпоинтов.
- WordPress HTTP API — для отправки запросов к другим сайтам из вашего плагина.
- WP All Import / Export — для импорта и экспорта данных, которые можно интегрировать с вашим плагином.
Комбинируя собственные решения с проверенными инструментами, можно сократить время разработки и повысить надёжность.