Formattazione della risposta per endpoint personalizzati in WP-API v2
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:
Endpoint personalizzato:
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.
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);
}

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

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

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

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

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.
