J'ai un point de terminaison personnalisé défini comme suit:
add_action( 'rest_api_init', function () {
register_rest_route( 'menc/v1', '/crosscat/(?P<dept>[\w-]+)/(?P<cat>[\w-]+)', array(
'methods' => 'GET',
'callback' => 'dept_cat_api',
'args' => array(
'dept' => array(
'sanitize_callback' => function($param, $request, $key) {
return sanitize_text_field( $param );
}
),
'cat' => array(
'sanitize_callback' => function($param, $request, $key) {
return sanitize_text_field( $param );
}
),
'per_page' => array(
'default' => 10,
'sanitize_callback' => 'absint',
),
'page' => array(
'default' => 1,
'sanitize_callback' => 'absint',
),
'orderby' => array(
'default' => 'date',
'sanitize_callback' => 'sanitize_text_field',
),
'order' => array(
'default' => 'desc',
'sanitize_callback' => 'sanitize_text_field',
),
),
) );
} );
function dept_cat_api( $request ) {
$args = array(
'post_type' => 'post',
'tax_query' => array(
'relation' => 'AND',
array(
'taxonomy' => 'crosspost',
'field' => 'slug',
'terms' => array( $request['dept'] ),
),
array(
'taxonomy' => 'category',
'field' => 'slug',
'terms' => array( $request['cat'] ),
),
),
'per_page' => $request['per_page'],
'page' => $request['page'],
'orderby' => $request['orderby'],
'order' => $request['order']
);
$posts = get_posts( $args );
if ( empty( $posts ) ) return new WP_Error( 'no_posts', 'Invalid term(s)', array( 'status' => 404 ) );
$controller = new WP_REST_Posts_Controller('post');
foreach ( $posts as $post ) {
$response = $controller->prepare_item_for_response( $post, $request );
$data[] = $controller->prepare_response_for_collection( $response );
}
// return results
return new WP_REST_Response($data, 200);
}
À distance, j'ai un problème. Lorsque j'appelle la route, tout semble aller pour le contenu, mais X-WP-TotalPages
et X-WP-Total
renvoient des réponses vides.
object(Requests_Utility_CaseInsensitiveDictionary)#991 (1) {
["data":protected]=>
array(20) {
["server"]=>
string(5) "nginx"
["date"]=>
string(29) "Wed, 14 Jun 2017 14:07:51 GMT"
["content-type"]=>
string(31) "application/json; charset=UTF-8"
["content-length"]=>
string(6) "104787"
["expires"]=>
string(29) "Thu, 19 Nov 1981 08:52:00 GMT"
["pragma"]=>
string(8) "no-cache"
["x-robots-tag"]=>
string(7) "noindex"
["link"]=>
string(65) "; rel="https://api.w.org/""
["x-content-type-options"]=>
string(7) "nosniff"
["access-control-expose-headers"]=>
string(27) "X-WP-Total, X-WP-TotalPages"
["access-control-allow-headers"]=>
string(27) "Authorization, Content-Type"
["allow"]=>
string(3) "GET"
["x-cacheable"]=>
string(5) "SHORT"
["vary"]=>
string(22) "Accept-Encoding,Cookie"
["cache-control"]=>
string(28) "max-age=600, must-revalidate"
["accept-ranges"]=>
string(5) "bytes"
["x-cache"]=>
string(6) "HIT: 1"
["x-pass-why"]=>
string(0) ""
["x-cache-group"]=>
string(6) "normal"
["x-type"]=>
string(7) "default"
}
}
Idéalement, j'ai besoin que les deux soient peuplés, mais je pourrais me contenter d'un seul. J'ai supposé que WordPress les calculait/les remplissait via le contrôleur. Dois-je les renseigner manuellement? Ai-je mal fait quelque chose? Est-ce que je rencontre un bug?
J'ai jeté un coup d'œil rapide et voici comment les en-têtes sont définis dans la méthode WP_REST_Posts_Controller::get_items()
:
$response = rest_ensure_response( $posts );
// ...
$response->header( 'X-WP-Total', (int) $total_posts );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
// ...
return $response;
où:
$total_posts = $posts_query->found_posts;
et nous pourrions utiliser comme @jshwlkr suggéré :
$max_pages = $posts_query->max_num_pages;
Vous pouvez émuler cela pour votre point de terminaison personnalisé, en utilisant WP_Query
au lieu de get_posts()
.
Merci à @DenisUyeda pour corriger la faute de frappe .