Форматирование ответа в пользовательской конечной точке WP-API v2

18 авг. 2016 г., 00:58:45
Просмотры: 14.1K
Голосов: 8

Я пытаюсь использовать пользовательскую конечную точку (в основном для реализации случайной сортировки) и использую следующий код:

// Пользовательская конечная точка 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.

Стандартный ответ:

Пример стандартного ответа WP REST API

Пользовательская конечная точка:

Пример ответа пользовательской конечной точки

Основная проблема в том, что я не могу получить доступ к информации о таксономиях и полях ACF, как в стандартном API. Возможно, я неправильно их получаю, так как не очень силен в PHP.

Спасибо.

0
Все ответы на вопрос 3
3
10

Вы можете вызывать методы 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);
}
18 авг. 2016 г. 12:51:21
Комментарии

Я столкнулся с похожей проблемой, но ваш ответ решает её лишь частично: у меня точно такая же проблема, но она вызвана объектом 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);

Merc Merc
20 нояб. 2017 г. 19:10:59

Но я получаю множество таких ошибок: <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

Merc Merc
20 нояб. 2017 г. 19:14:45

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

Merc Merc
21 нояб. 2017 г. 01:43:30
0

Принятый ответ был полезен. Спасибо. Однако метод 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 );

    }
14 февр. 2020 г. 15:15:04
0

В приведенном выше ответе забыли задать новую переменную массива. После добавления все работает отлично.

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.

28 мар. 2018 г. 17:26:44