Formatarea răspunsului pentru endpointuri personalizate în WP-API v2
Încerc să folosesc un endpoint personalizat (pentru a implementa o sortare aleatoare) și folosesc următorul cod:
// Endpoint personalizat pentru WP API
function theme_enable_random_api() {
// creează 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;
}
));
});
// gestionează cererea
function wp_json_offers_v2__posts($request) {
// parametri json-api
$parameters = $request->get_query_params();
// argumente implicite de căutare
$args = array(
'post_type' => $parameters['type'],
'numberposts' => 9,
'offset' => $parameters['offset'],
'post_not_in' => $parameters['exclude'],
'orderby' => 'rand',
);
// rulează interogarea
$posts = get_posts($args);
// returnează rezultatele
return new WP_REST_Response($posts, 200);
}
}
add_action('init', 'theme_enable_random_api');
Totuși, răspunsul pe care îl primesc nu este același ca răspunsul pe care l-aș primi de la un apel standard către API.
Standard:
Endpoint personalizat:
Problema este că nu pot accesa informațiile despre taxonomii/câmpuri ACF așa cum pot face în cazul standard. Nu sunt expert în PHP, așa că probabil nu le obțin corect.
Mulțumesc.
Puteți apela metodele API REST pentru a vă pregăti rezultatul în același mod în care o face implicit pluginul, acest lucru va permite, de asemenea, oricăror pluginuri să se conecteze la rezultat, așa cum ați folosit pluginul AFC, așa cum se vede în exemplul dvs. de rezultat.
Clasa WP_REST_Posts_Controller
are următoarele în metoda sa de obținere a postărilor:
$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 );
}
Deci, ați putea instantia o nouă instanță a WP_REST_Posts_Controller
și apela metodele prepare_item_for_response
și prepare_response_for_collection
pe datele dvs. pentru a le formata identic cu punctele finale implicite.
Ceva similar cu următoarele ar trebui să funcționeze (netestat)
function wp_json_offers_v2__posts($request) {
// parametrii json-api
$parameters = $request->get_query_params();
// argumente implicite de căutare
$args = array(
'post_type' => $parameters['type'],
'numberposts' => 9,
'offset' => $parameters['offset'],
'post_not_in' => $parameters['exclude'],
'orderby' => 'rand',
);
// execută interogarea
$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 );
}
// returnează rezultatele
return new WP_REST_Response($posts, 200);
}

Am întâmpinat o problemă similară, dar răspunsul tău o rezolvă doar parțial, cred: am exact aceeași problemă, dar în cazul meu provine de la un obiect WP Post care este de fapt o revizie.
Am încercat să pregătesc obiectul post cum ai făcut tu, și am încercat să folosesc un controller de revizii.
$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);

Dar primesc o mulțime de astfel de mesaje: <b>Notice</b>: Încercare de a obține proprietate de la non-obiect în <b>/Users/jones/Documents/github/lucid/sos-aerzte-api/wp/wp-includes/rest-api/endpoints/class-wp-rest-revisions-controller.php</b> la linia <b>350</b><br />
pe diferite linii.`
Cred că se referă la liniile https://developer.wordpress.org/reference/classes/wp_rest_revisions_controller/ -> linia 350 > autor

Am rezolvat problema făcând astfel: https://stackoverflow.com/a/47402964/1121268 – Nu înțeleg pe deplin de ce, dar cu reviziile asta pare să funcționeze...

Răspunsul acceptat a fost util. Mulțumesc. Însă metoda prepare_item_for_response() a fost învechită începând cu versiunea 3.0, așadar, sper că acest fragment de cod va ajuta pe cineva cu un endpoint personalizat pentru Comenzile WooCommerce.
// Parsează toți ceilalți parametri
$args = wp_parse_args( $request->get_params(), $args );
// Obține comenzile
$orders = wc_get_orders( $args );
if ( ! empty( $orders ) && is_array( $orders ) ) {
$controller = new WC_REST_Orders_Controller ();
// Datele pentru răspuns
$orders_data = [];
// Trebuie să pregătim obiectele pentru răspuns
foreach ( $orders as $order ) {
if ( $order instanceof WC_Order ) {
// Obiecte
$prepared_object = $controller->prepare_object_for_response( $order, $request );
$orders_data[] = $controller->prepare_response_for_collection( $prepared_object );
} else {
// ID-uri
$orders_data[] = (int) $order;
}
}
// Returnează răspunsul
return new WP_REST_Response( $orders_data, 200 );
}

Răspunsul de mai sus a uitat să seteze o nouă variabilă de tip array. Odată ce adaugi asta, funcționează perfect.
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;
}
Rezultatul arată exact ca răspunsul normal al API-ului.
