Files
profile/api/coauthor.php
Profile Profile ed4d79b706 add files inc
2026-03-09 20:51:08 +03:00

307 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
add_action('rest_api_init', function() {
register_rest_route('my/v1', '/author/(?P<slug>[a-zA-Z0-9-]+)', [
'methods' => 'GET',
'callback' => function($request) {
$slug = $request['slug'];
if (!function_exists('get_coauthors')) {
return new WP_Error('no_plugin', 'Co-Authors Plus not active', ['status' => 404]);
}
global $coauthors_plus;
if (isset($coauthors_plus) && method_exists($coauthors_plus, 'get_coauthor_by')) {
$coauthor = $coauthors_plus->get_coauthor_by('user_nicename', $slug);
if ($coauthor) {
// Получаем ID записи гостевого автора
$author_post_id = $coauthor->ID;
// ПОЛУЧАЕМ ФОТО ИЗ МИНИАТЮРЫ ЗАПИСИ (post thumbnail)
$photo = null;
$photo_sizes = [];
if (has_post_thumbnail($author_post_id)) {
$photo_id = get_post_thumbnail_id($author_post_id);
// Основные размеры
$photo_sizes = [
'thumbnail' => wp_get_attachment_image_url($photo_id, 'thumbnail'),
'medium' => wp_get_attachment_image_url($photo_id, 'medium'),
'large' => wp_get_attachment_image_url($photo_id, 'large'),
'full' => wp_get_attachment_image_url($photo_id, 'full'),
];
$photo = $photo_sizes['medium'];
}
return [
'id' => $coauthor->user_nicename,
'name' => $coauthor->display_name,
'firstName' => $coauthor->first_name ?? '',
'lastName' => $coauthor->last_name ?? '',
'description' => $coauthor->description ?? '',
// Фото из миниатюры поста (это то, что вам нужно)
'photo' => $photo,
'photo_sizes' => $photo_sizes,
// Для обратной совместимости
'avatar' => $photo ?: '',
'url' => get_author_posts_url($coauthor->ID, $coauthor->user_nicename),
'type' => $coauthor->type ?? 'guest-author'
];
}
}
return new WP_Error('not_found', 'Author not found', ['status' => 404]);
},
'permission_callback' => '__return_true'
]);
});
add_action('rest_api_init', function() {
register_rest_route('my/v1', '/author/(?P<slug>[a-zA-Z0-9-]+)/posts', [
'methods' => 'GET',
'callback' => function($request) {
$slug = $request['slug'];
$per_page = $request->get_param('per_page') ?: 10;
$cursor = $request->get_param('cursor');
$before = $request->get_param('before');
$after = $request->get_param('after');
// Устанавливаем нужные типы постов
$post_type = ['profile_article', 'anew', 'yellow'];
if (!function_exists('get_coauthors')) {
return new WP_Error('no_plugin', 'Co-Authors Plus not active', ['status' => 404]);
}
global $coauthors_plus;
// Получаем автора по slug
$coauthor = null;
if (isset($coauthors_plus) && method_exists($coauthors_plus, 'get_coauthor_by')) {
$coauthor = $coauthors_plus->get_coauthor_by('user_nicename', $slug);
}
if (!$coauthor) {
return new WP_Error('not_found', 'Author not found', ['status' => 404]);
}
// Определяем тип автора и получаем термин таксономии author
$author_term = null;
if ($coauthor->type === 'guest-author') {
$author_term = get_term_by('slug', 'cap-' . $coauthor->user_nicename, 'author');
} else {
$author_term = get_term_by('slug', $coauthor->user_nicename, 'author');
}
if (!$author_term) {
return new WP_Error('not_found', 'Author term not found', ['status' => 404]);
}
// Базовые аргументы запроса
$args = [
'post_type' => $post_type,
'posts_per_page' => $per_page,
'post_status' => 'publish',
'tax_query' => [
[
'taxonomy' => 'author',
'field' => 'term_id',
'terms' => $author_term->term_id,
]
],
'orderby' => 'date',
'order' => 'DESC',
];
// Применяем курсорную пагинацию
if ($after) {
$args['date_query'] = [
[
'column' => 'post_date',
'before' => $after,
'inclusive' => false,
]
];
} elseif ($before) {
$args['date_query'] = [
[
'column' => 'post_date',
'after' => $before,
'inclusive' => false,
]
];
$args['order'] = 'ASC';
} elseif ($cursor) {
$cursor_post = get_post($cursor);
if ($cursor_post) {
$args['date_query'] = [
[
'column' => 'post_date',
'before' => $cursor_post->post_date,
'inclusive' => false,
]
];
}
}
$query = new WP_Query($args);
$posts = $query->posts;
if ($before) {
$posts = array_reverse($posts);
}
// Форматируем посты - ТОЛЬКО нужные поля
$formatted_posts = [];
foreach ($posts as $post) {
setup_postdata($post);
// Получаем соавторов
$coauthors = [];
if (function_exists('get_coauthors')) {
$post_coauthors = get_coauthors($post->ID);
foreach ($post_coauthors as $post_coauthor) {
$coauthors[] = [
'id' => $post_coauthor->user_nicename,
'name' => $post_coauthor->display_name,
];
}
}
// Получаем рубрики/категории
$categories = [];
$taxonomies = ['category', 'rubric'];
foreach ($taxonomies as $taxonomy) {
$terms = get_the_terms($post->ID, $taxonomy);
if ($terms && !is_wp_error($terms)) {
foreach ($terms as $term) {
$categories[] = [
'id' => $term->term_id,
'name' => $term->name,
'slug' => $term->slug,
'taxonomy' => $taxonomy,
];
}
}
}
$formatted_posts[] = [
'id' => $post->ID,
'title' => $post->post_title,
'slug' => $post->post_name,
'type' => $post->post_type,
'date' => $post->post_date,
'link' => get_permalink($post->ID),
// Только картинка (разные размеры)
'featured_image' => [
'full' => get_the_post_thumbnail_url($post->ID, 'full'),
'large' => get_the_post_thumbnail_url($post->ID, 'large'),
'medium' => get_the_post_thumbnail_url($post->ID, 'medium'),
'thumbnail' => get_the_post_thumbnail_url($post->ID, 'thumbnail'),
],
// Рубрики
'categories' => $categories,
// Соавторы
'coauthors' => $coauthors,
// Курсор для пагинации
'cursor' => $post->post_date,
];
}
wp_reset_postdata();
// ИСПРАВЛЕННАЯ ПАГИНАЦИЯ
$has_next = false;
$next_cursor = null;
$has_previous = false;
$previous_cursor = null;
$first_cursor = null;
$last_cursor = null;
if (!empty($posts)) {
$first_post = reset($posts);
$last_post = end($posts);
$first_cursor = $first_post->post_date;
$last_cursor = $last_post->post_date;
// Простая проверка: если количество найденных постов больше, чем количество на странице
// ИЛИ если есть больше страниц
$has_next = $query->max_num_pages > 1;
// Если есть следующая страница, курсор - дата последнего поста
if ($has_next) {
$next_cursor = $last_post->post_date;
}
// Проверяем предыдущие посты (если это не первая страница)
if ($cursor || $after || $before) {
// Если есть курсор, значит это не первая страница
$has_previous = true;
$previous_cursor = $first_post->post_date;
}
}
// Добавим отладку (можно убрать после тестирования)
error_log('=== AUTHOR POSTS DEBUG ===');
error_log('Slug: ' . $slug);
error_log('Posts found: ' . count($posts));
error_log('Total posts: ' . $query->found_posts);
error_log('Max num pages: ' . $query->max_num_pages);
error_log('Has next: ' . ($has_next ? 'true' : 'false'));
error_log('Next cursor: ' . ($next_cursor ?? 'null'));
error_log('========================');
return [
'data' => $formatted_posts,
'pagination' => [
'total' => $query->found_posts,
'per_page' => (int)$per_page,
'has_next' => $has_next,
'has_previous' => $has_previous,
'next_cursor' => $next_cursor,
'previous_cursor' => $previous_cursor,
'first_cursor' => $first_cursor,
'last_cursor' => $last_cursor,
],
'author' => [
'id' => $coauthor->user_nicename,
'name' => $coauthor->display_name,
]
];
},
'args' => [
'per_page' => [
'type' => 'integer',
'default' => 10,
'minimum' => 1,
'maximum' => 100,
],
'cursor' => [
'type' => 'string',
'description' => 'Cursor for pagination',
],
'after' => [
'type' => 'string',
'description' => 'Get posts after this date',
],
'before' => [
'type' => 'string',
'description' => 'Get posts before this date',
],
],
'permission_callback' => '__return_true'
]);
});