Files
profile/inc/generate_coauthors_cache.php

195 lines
7.0 KiB
PHP
Raw Normal View History

2026-03-09 20:51:08 +03:00
<?php
/**
* CLI команда для генерации кеша соавторов
*
* Запуск: wp coauthors generate-cache
* Или: wp eval "generate_coauthors_cache();"
*/
if (defined('WP_CLI') && WP_CLI) {
/**
* Генерирует кеш всех соавторов
*/
function generate_coauthors_cache_cli() {
WP_CLI::line('Начинаю генерацию кеша соавторов...');
$result = generate_coauthors_cache();
if ($result['success']) {
WP_CLI::success($result['message']);
WP_CLI::line("Всего соавторов: {$result['total']}");
WP_CLI::line("Файл сохранен: {$result['file']}");
} else {
WP_CLI::error($result['message']);
}
}
WP_CLI::add_command('coauthors generate-cache', 'generate_coauthors_cache_cli');
}
/**
* Генерирует кеш всех соавторов и сохраняет в JSON файл
*
* @return array Результат операции
*/
function generate_coauthors_cache() {
if (!function_exists('get_coauthors')) {
return array(
'success' => false,
'message' => 'Плагин CoAuthors Plus не активен'
);
}
global $wpdb, $coauthors_plus;
$cache_file = get_coauthors_cache_file_path();
$cache_data = array(
'generated' => current_time('mysql'),
'total' => 0,
'authors' => array(),
'by_display_name' => array(), // Индекс по display_name
'by_last_name' => array(), // Индекс по фамилии
'by_login' => array(), // Индекс по логину
'by_nicename' => array() // Индекс по nicename
);
// Получаем всех соавторов через термины таксономии 'author'
$terms = get_terms(array(
'taxonomy' => 'author',
'hide_empty' => false,
'number' => 0 // Получаем все
));
$authors = array();
$processed_ids = array();
WP_CLI::line('Получение соавторов из терминов...');
$progress = \WP_CLI\Utils\make_progress_bar('Обработка соавторов', count($terms));
foreach ($terms as $term) {
$coauthor = $coauthors_plus->get_coauthor_by('user_nicename', $term->slug);
if ($coauthor && !in_array($coauthor->ID, $processed_ids)) {
$authors[] = $coauthor;
$processed_ids[] = $coauthor->ID;
}
$progress->tick();
}
$progress->finish();
// Дополнительно: получаем авторов из постов за последние 2 года (на случай если в терминах не все)
WP_CLI::line('Проверка авторов в постах...');
$two_years_ago = date('Y-m-d H:i:s', strtotime('-2 years'));
$post_ids = $wpdb->get_col($wpdb->prepare(
"SELECT DISTINCT ID FROM {$wpdb->posts}
WHERE post_type IN ('post', 'profile_article')
AND post_status = 'publish'
AND post_date >= %s
ORDER BY post_date DESC
LIMIT 5000",
$two_years_ago
));
$post_progress = \WP_CLI\Utils\make_progress_bar('Поиск авторов в постах', count($post_ids));
foreach ($post_ids as $pid) {
foreach (get_coauthors($pid) as $ca) {
if (!in_array($ca->ID, $processed_ids)) {
$authors[] = $ca;
$processed_ids[] = $ca->ID;
}
}
$post_progress->tick();
}
$post_progress->finish();
// Формируем структуру данных для кеша
WP_CLI::line('Формирование структуры кеша...');
$total = count($authors);
foreach ($authors as $author) {
$display_name = $author->display_name;
$last_name = extract_last_name($display_name);
$author_data = array(
'ID' => $author->ID,
'display_name' => $display_name,
'last_name' => $last_name,
'user_login' => $author->user_login,
'user_nicename' => $author->user_nicename,
'type' => isset($author->type) ? $author->type : 'wpuser',
'description' => isset($author->description) ? $author->description : '',
'show_only_articles' => get_user_meta($author->ID, 'show_only_articles', true)
);
// Добавляем в основной массив
$cache_data['authors'][] = $author_data;
// Индексируем по display_name (полное имя)
$display_name_key = sanitize_key_for_cache($display_name);
$cache_data['by_display_name'][$display_name_key] = $author_data;
// Индексируем по фамилии
if (!empty($last_name)) {
$last_name_key = sanitize_key_for_cache($last_name);
if (!isset($cache_data['by_last_name'][$last_name_key])) {
$cache_data['by_last_name'][$last_name_key] = array();
}
$cache_data['by_last_name'][$last_name_key][] = $author_data;
}
// Индексируем по логину
if (!empty($author->user_login)) {
$login_key = sanitize_key_for_cache($author->user_login);
$cache_data['by_login'][$login_key] = $author_data;
}
// Индексируем по nicename
if (!empty($author->user_nicename)) {
$nicename_key = sanitize_key_for_cache($author->user_nicename);
$cache_data['by_nicename'][$nicename_key] = $author_data;
}
}
$cache_data['total'] = $total;
// Сохраняем в файл
$written = file_put_contents($cache_file, json_encode($cache_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
if ($written === false) {
return array(
'success' => false,
'message' => "Ошибка при записи файла кеша: {$cache_file}"
);
}
return array(
'success' => true,
'message' => "Кеш соавторов успешно сгенерирован",
'total' => $total,
'file' => $cache_file
);
}
/**
* Извлекает фамилию из полного имени
* Предполагает, что фамилия - последнее слово
*/
function extract_last_name($full_name) {
$parts = explode(' ', trim($full_name));
return end($parts);
}
/**
* Очищает строку для использования в качестве ключа кеша
*/
function sanitize_key_for_cache($string) {
return mb_strtolower(trim(preg_replace('/\s+/', ' ', $string)));
}
/**
* Возвращает путь к файлу кеша
*/
function get_coauthors_cache_file_path() {
$upload_dir = wp_upload_dir();
return $upload_dir['basedir'] . '/coauthors-cache.json';
}