Форматирование ответа в пользовательской конечной точке WP-API v2
Я пытаюсь использовать пользовательскую конечную точку (в основном для реализации случайной сортировки) и использую следующий код:
// Пользовательская конечная точка WP API
function theme_enable_random_api() {
// создаем конечную точку json-api
add_action('rest_api_init', function () {
// http://example.com/wp-json/random/v2/posts
register_rest_route('random/v2', '/random', array (
'methods' => 'GET',
'callback' => 'wp_json_offers_v2__posts',
'permission_callback' => function (WP_REST_Request $request) {
return true;
}
));
});
// обработка запроса
function wp_json_offers_v2__posts($request) {
// параметры json-api
$parameters = $request->get_query_params();
// аргументы поиска по умолчанию
$args = array(
'post_type' => $parameters['type'],
'numberposts' => 9,
'offset' => $parameters['offset'],
'post_not_in' => $parameters['exclude'],
'orderby' => 'rand',
);
// выполняем запрос
$posts = get_posts($args);
// возвращаем результаты
return new WP_REST_Response($posts, 200);
}
}
add_action('init', 'theme_enable_random_api');
Однако ответ, который я получаю, отличается от ответа стандартного вызова API.
Стандартный ответ:
Пользовательская конечная точка:
Основная проблема в том, что я не могу получить доступ к информации о таксономиях и полях ACF, как в стандартном API. Возможно, я неправильно их получаю, так как не очень силен в PHP.
Спасибо.
Вы можете вызывать методы REST API для подготовки вашего вывода таким же образом, как это делает плагин по умолчанию. Это также позволит другим плагинам взаимодействовать с выводом, как в вашем примере с использованием плагина ACF.
Класс WP_REST_Posts_Controller
содержит следующий код в своем методе получения записей:
$posts_query = new WP_Query();
$query_result = $posts_query->query( $query_args );
$posts = array();
foreach ( $query_result as $post ) {
if ( ! $this->check_read_permission( $post ) ) {
continue;
}
$data = $this->prepare_item_for_response( $post, $request );
$posts[] = $this->prepare_response_for_collection( $data );
}
Таким образом, вы можете создать новый экземпляр WP_REST_Posts_Controller
и вызвать методы prepare_item_for_response
и prepare_response_for_collection
для ваших данных, чтобы отформатировать их идентично стандартным конечным точкам.
Нечто подобное должно работать (не тестировалось):
function wp_json_offers_v2__posts($request) {
// параметры json-api
$parameters = $request->get_query_params();
// стандартные аргументы поиска
$args = array(
'post_type' => $parameters['type'],
'numberposts' => 9,
'offset' => $parameters['offset'],
'post_not_in' => $parameters['exclude'],
'orderby' => 'rand',
);
// выполнение запроса
$posts = get_posts($args);
$controller = new WP_REST_Posts_Controller($parameters['type']);
foreach ( $posts as $post ) {
$data = $controller->prepare_item_for_response( $post, $request );
$posts[] = $controller->prepare_response_for_collection( $data );
}
// возврат результатов
return new WP_REST_Response($posts, 200);
}

Я столкнулся с похожей проблемой, но ваш ответ решает её лишь частично: у меня точно такая же проблема, но она вызвана объектом WP Post, который на самом деле является ревизией.
Я попытался подготовить объект поста, как вы сделали, и также пробовал использовать контроллер ревизий.
$latest_revision = wp_get_post_revisions( $id, $args );
$postController = new \WP_REST_Revisions_Controller('revision');
$response = $postController->prepare_item_for_response( $latest_revision, $request );
print_r($response);

Но я получаю множество таких ошибок: <b>Notice</b>: Trying to get property of non-object in <b>/Users/jones/Documents/github/lucid/sos-aerzte-api/wp/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php</b> on line <b>350</b><br />
на разных строках.
Думаю, они относятся к строкам https://developer.wordpress.org/reference/classes/wp_rest_revisions_controller/ -> строка 350 > author

Я решил проблему следующим образом: https://stackoverflow.com/a/47402964/1121268 — Не до конца понимаю почему, но с ревизиями это сработало...

Принятый ответ был полезен. Спасибо. Однако метод prepare_item_for_response() устарел, начиная с версии 3.0, так что надеюсь, этот сниппет поможет кому-то с кастомной конечной точкой для заказов WooCommerce.
// Парсим все остальные параметры
$args = wp_parse_args( $request->get_params(), $args );
// Получаем заказы
$orders = wc_get_orders( $args );
if ( ! empty( $orders ) && is_array( $orders ) ) {
$controller = new WC_REST_Orders_Controller ();
// Данные для ответа
$orders_data = [];
// Подготавливаем объекты для ответа
foreach ( $orders as $order ) {
if ( $order instanceof WC_Order ) {
// Объекты
$prepared_object = $controller->prepare_object_for_response( $order, $request );
$orders_data[] = $controller->prepare_response_for_collection( $prepared_object );
} else {
// ID
$orders_data[] = (int) $order;
}
}
// Возвращаем ответ
return new WP_REST_Response( $orders_data, 200 );
}

В приведенном выше ответе забыли задать новую переменную массива. После добавления все работает отлично.
function get_all_posts($request)
{
$posts = get_posts([
'posts_per_page' => -1,
'post_status' => 'publish'
]);
$controller = new WP_REST_Posts_Controller('post');
$array = [];
foreach ( $posts as $post ) {
$data = $controller->prepare_item_for_response($post,$request);
$array[] = $controller->prepare_response_for_collection($data);
}
return $array;
}
Вывод выглядит точно так же, как обычный ответ API.
