8

I'm trying to use a custom endpoint (basically to get a random sorting working) and am using the following code:

// Custom WP API endpoint
function theme_enable_random_api() {

    // create json-api endpoint

    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;
            }
        ));
    });

    // handle the request

    function wp_json_offers_v2__posts($request) {
        // json-api params

        $parameters = $request->get_query_params();

        // default search args

        $args = array(
            'post_type'     => $parameters['type'],
            'numberposts'   => 9,
            'offset'        => $parameters['offset'],
            'post_not_in'       => $parameters['exclude'],
            'orderby'       => 'rand',
        );

        // run query

        $posts = get_posts($args);

        // return results
        return new WP_REST_Response($posts, 200);
    }

}

add_action('init', 'theme_enable_random_api');

However the response I'm getting is not the same as the response I would get from a standard call to the api.

Standard:

Custom Endpoint:

The problem really is that I can't access the taxonomy/acf information like I can in the standard one. I'm not great with PHP so more than likely I'm not getting it properly.

Cheers.

10

You can call the REST API methods to prepare your output in the same way that the plugin does by default, this will also allow any plugins to tie into the output as you have used the ACF plugin as seen in your example output.

The WP_REST_Posts_Controller class has the following in its get posts method

$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 );
}

So you could instantiate a new WP_REST_Posts_Controller instance and call the prepare_item_for_response and prepare_response_for_collection methods on your data to format it identically to the default endpoints.

Something similar to the following should work (untested)

function wp_json_offers_v2__posts($request) {
    // json-api params

    $parameters = $request->get_query_params();

    // default search args

    $args = array(
        'post_type'     => $parameters['type'],
        'numberposts'   => 9,
        'offset'        => $parameters['offset'],
        'post_not_in'       => $parameters['exclude'],
        'orderby'       => 'rand',
    );

    // run query

    $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 results
    return new WP_REST_Response($posts, 200);
}
3
  • I am experiencing a similar problem but your answer does only partially solve it I think: I also have the exact same problem but mine is resulting from a WP Post object which is acutally a revision. I tried to prepare the post object like you did, and I also tried to use a revision controller. $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
    Nov 20 '17 at 17:10
  • But I am getting a lot of these: But I am getting a lot of these: <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 /> on different lines.` I think the refer to the lines developer.wordpress.org/reference/classes/… -> line 350 > author
    – Merc
    Nov 20 '17 at 17:14
  • I solved the problem by doing this: stackoverflow.com/a/47402964/1121268 – I don't fully understand why, but with revisions this seems to work...
    – Merc
    Nov 20 '17 at 23:43
2

The accepted answer was helpful. Thanks. But prepare_item_for_response() method was deprecated since v.3.0, so, hope this snippet will help someone with a custom endpoint for WC Orders.

    // Parse all others params
    $args = wp_parse_args( $request->get_params(), $args );

    // Get orders
    $orders = wc_get_orders( $args );

    if ( ! empty( $orders ) && is_array( $orders ) ) {
        $controller = new WC_REST_Orders_Controller ();

        // The response data
        $orders_data = [];
        // We need prepare objects to the response
        foreach ( $orders as $order ) {
            if ( $order instanceof WC_Order ) {
                // Objects
                $prepared_object = $controller->prepare_object_for_response( $order, $request );
                $orders_data[]   = $controller->prepare_response_for_collection( $prepared_object );
            } else {
                // IDs
                $orders_data[] = (int) $order;
            }
        }

        // Return the response
        return new WP_REST_Response( $orders_data, 200 );

    }
1

The above answer forgot to set a new array variable. Once you add that it works great.

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;
}

Output looks just like the normal api response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.