Formattazione della risposta per endpoint personalizzati in WP-API v2

18 ago 2016, 00:58:45
Visualizzazioni: 14.1K
Voti: 8

Sto cercando di utilizzare un endpoint personalizzato (principalmente per implementare un ordinamento casuale) con il seguente codice:

// Endpoint personalizzato per WP API
function theme_enable_random_api() {

    // crea endpoint 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;
            }
        ));
    });

    // gestisce la richiesta

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

        $parameters = $request->get_query_params();

        // argomenti di ricerca predefiniti

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

        // esegue la query

        $posts = get_posts($args);

        // restituisce i risultati
        return new WP_REST_Response($posts, 200);
    }

}

add_action('init', 'theme_enable_random_api');

Tuttavia la risposta che ottengo non è la stessa che otterrei da una chiamata standard all'API.

Standard:

Screenshot della risposta API standard con dati completi

Endpoint personalizzato:

Screenshot della risposta API personalizzata con dati mancanti

Il problema principale è che non riesco ad accedere alle informazioni sulle tassonomie e sui campi ACF come posso fare con l'endpoint standard. Non sono molto esperto di PHP, quindi probabilmente non lo sto implementando correttamente.

Grazie.

0
Tutte le risposte alla domanda 3
3
10

Puoi chiamare i metodi dell'API REST per preparare il tuo output nello stesso modo in cui lo fa il plugin per impostazione predefinita, questo permetterà anche ad altri plugin di intervenire sull'output come hai utilizzato il plugin ACF nell'esempio mostrato.

La classe WP_REST_Posts_Controller ha il seguente codice nel suo metodo per ottenere i post

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

Quindi potresti creare una nuova istanza di WP_REST_Posts_Controller e chiamare i metodi prepare_item_for_response e prepare_response_for_collection sui tuoi dati per formattarli nello stesso modo degli endpoint predefiniti.

Qualcosa di simile al seguente dovrebbe funzionare (non testato)

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

    $parameters = $request->get_query_params();

    // argomenti di ricerca predefiniti

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

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

    // restituisci risultati
    return new WP_REST_Response($posts, 200);
}
18 ago 2016 12:51:21
Commenti

Sto riscontrando un problema simile ma la tua risposta lo risolve solo parzialmente, credo: ho esattamente lo stesso problema, ma nel mio caso deriva da un oggetto WP Post che in realtà è una revisione. Ho provato a preparare l'oggetto post come hai fatto tu, e ho anche provato a usare un controller di revisione. $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 nov 2017 19:10:59

Ma ottengo molti di questi messaggi: Ma ottengo molti di questi: <b>Notice</b>: Tentativo di accedere a una proprietà di un oggetto non esistente in <b>/Users/jones/Documents/github/lucid/sos-aerzte-api/wp/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php</b> alla riga <b>350</b><br /> su righe diverse.`

Credo che si riferiscano alle righe https://developer.wordpress.org/reference/classes/wp_rest_revisions_controller/ -> riga 350 > author

Merc Merc
20 nov 2017 19:14:45

Ho risolto il problema facendo così: https://stackoverflow.com/a/47402964/1121268 – Non capisco appieno il perché, ma con le revisioni sembra funzionare...

Merc Merc
21 nov 2017 01:43:30
0

La risposta accettata è stata utile. Grazie. Tuttavia, il metodo prepare_item_for_response() è stato deprecato dalla versione 3.0, quindi spero che questo snippet possa aiutare qualcuno con un endpoint personalizzato per gli ordini di WooCommerce.

    // Analizza tutti gli altri parametri
    $args = wp_parse_args( $request->get_params(), $args );

    // Ottieni gli ordini
    $orders = wc_get_orders( $args );

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

        // I dati della risposta
        $orders_data = [];
        // Dobbiamo preparare gli oggetti per la risposta
        foreach ( $orders as $order ) {
            if ( $order instanceof WC_Order ) {
                // Oggetti
                $prepared_object = $controller->prepare_object_for_response( $order, $request );
                $orders_data[]   = $controller->prepare_response_for_collection( $prepared_object );
            } else {
                // ID
                $orders_data[] = (int) $order;
            }
        }

        // Restituisci la risposta
        return new WP_REST_Response( $orders_data, 200 );

    }
14 feb 2020 15:15:04
0

La risposta precedente ha dimenticato di impostare una nuova variabile array. Una volta aggiunta, funziona perfettamente.

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

L'output appare esattamente come la normale risposta dell'API.

28 mar 2018 17:26:44