Reputation: 53
I created custom endpoint for products, now im geting my products from Wp Rest Api (/wp-json/wl/v1/products) and everything goes nice, my problem is that my custom endpoint or route(whatever) doesn
t return headers like (X-WP-Total, X-WP-TotalPages - im getting null) that i need for pagination, actually i
ve found the ansewer here https://wordpress.stackexchange.com/questions/270005/custom-endpoint-and-x-wp-totalpages-headersbut i dont know where i shold put that php code, becouse i`m using the WP_REST_Controller class and i a little bit confused with placing of php code, please help me to know =)
$response = rest_ensure_response( $posts );
$response->header( 'X-WP-Total', (int) $total_posts );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
return $response;
where:
$total_posts = $posts_query->found_posts;
$max_pages = $posts_query->max_num_pages;
so what i have the solution
$total_posts = $posts_query->found_posts;
$max_pages = $posts_query->max_num_pages;
$response = rest_ensure_response( $posts );
$response->header( 'X-WP-Total', (int) $total_posts );
$response->header( 'X-WP-TotalPages', (int) $max_pages );
return $response;
and my Wp rest controller class
<?php
/**
* Plugin Name: Custom API Plugin
* Description: That plugin creates some custom end points for wp-admin
* Author: Ahma
* Version: 1
*/
add_action( 'rest_api_init', 'prefix_register_my_rest_routes' );
function prefix_register_my_rest_routes() {
$controller = new My_REST_Posts_Controller();
$controller->register_routes();
}
class My_REST_Posts_Controller extends WP_REST_Controller {
function __construct(){
$this->namespace = 'wl/v1';
$this->rest_base = 'products';
}
function register_routes(){
register_rest_route( $this->namespace, "/$this->rest_base", [
[
'methods' => 'GET',
'callback' => [ $this, 'get_items' ],
],
'schema' => [ $this, 'get_item_schema' ],
] );
register_rest_route( $this->namespace, "/$this->rest_base/(?P<id>[\w]+)", [
[
'methods' => 'GET',
'callback' => [ $this, 'get_item' ],
],
'schema' => [ $this, 'get_item_schema' ],
] );
}
/**
* Получает последние посты и отдает их в виде rest ответа.
*
* @param WP_REST_Request $request Текущий запрос.
*
* @return WP_Error|array
*/
function get_items($request ){
$data = [];
$posts = get_posts( array(
'post_per_page' => 3,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'products',
));
if ( empty( $posts ) )
return $data;
foreach( $posts as $post ){
$response = $this->prepare_item_for_response( $post, $request );
$data[] = $this->prepare_response_for_collection( $response );
}
return $data;
}
/**
* Получает отдельный ресурс.
*
* @param WP_REST_Request $request Текущий запрос.
*
* @return array
*/
function get_item( $request ){
$id = (int) $request['id'];
$post = get_post( $id );
if( ! $post )
return array();
return $this->prepare_item_for_response( $post, $request );
}
/**
* Собирает данные ресурса в соответствии со схемой ресурса.
*
* @param WP_Post $post Объект ресурса, из которого будут взяты оригинальные данные.
* @param WP_REST_Request $request Текущий запрос.
*
* @return array
*/
function prepare_item_for_response( $post, $request ){
$post_data = [];
$schema = $this->get_item_schema();
// We are also renaming the fields to more understandable names.
if ( isset( $schema['properties']['id'] ) )
$post_data['id'] = (int) $post->ID;
if ( isset( $schema['properties']['title'] ) )
$post_data['title'] = apply_filters( 'the_title', $post->post_title, $post );
if ( isset( $schema['properties']['content'] ) )
$post_data['content'] = apply_filters( 'the_content', $post->post_content, $post );
if ( isset( $schema['properties']['featured_image'] ) )
$post_data['featured_image'] = get_the_post_thumbnail_url($post->ID, 'full');
if ( isset( $schema['properties']['product_data_brand'] ) )
$post_data['product_data_brand'] = carbon_get_post_meta($post->ID,'product_data_brand');
if ( isset( $schema['properties']['product_data_model'] ) )
$post_data['product_data_model'] = carbon_get_post_meta($post->ID,'product_data_model');
if ( isset( $schema['properties']['product_data_size'] ) )
$post_data['product_data_size'] = carbon_get_post_meta($post->ID,'product_data_size');
if ( isset( $schema['properties']['product_data_type'] ) )
$post_data['product_data_type'] = carbon_get_post_meta($post->ID,'product_data_type');
if ( isset( $schema['properties']['product_data_tread'] ) )
$post_data['product_data_tread'] = carbon_get_post_meta($post->ID,'product_data_tread');
if ( isset( $schema['properties']['product_data_price'] ) )
$post_data['product_data_price'] = carbon_get_post_meta($post->ID,'product_data_price');
if ( isset( $schema['properties']['product_data_images'] ) )
$post_data['product_data_images'] = carbon_get_post_meta($post->ID,'product_data_images');
if ( isset( $schema['properties']['product_data_desc'] ) )
$post_data['product_data_desc'] = carbon_get_post_meta($post->ID,'product_data_desc');
if ( isset( $schema['properties']['category'] ) )
$post_data['categories'] = wp_get_post_terms($post->ID, 'category_of_product', array('fields' => 'ids'));
return $post_data;
}
/**
* Подготавливает ответ отдельного ресурса для добавления его в коллекцию ресурсов.
*
* @param WP_REST_Response $response Response object.
*
* @return array|mixed Response data, ready for insertion into collection data.
*/
function prepare_response_for_collection( $response ){
if ( ! ( $response instanceof WP_REST_Response ) ){
return $response;
}
$data = (array) $response->get_data();
$server = rest_get_server();
if ( method_exists( $server, 'get_compact_response_links' ) ){
$links = call_user_func( [ $server, 'get_compact_response_links' ], $response );
}
else {
$links = call_user_func( [ $server, 'get_response_links' ], $response );
}
if ( ! empty( $links ) ){
$data['_links'] = $links;
}
return $data;
}
## Схема ресурса.
function get_item_schema(){
$schema = [
// показывает какую версию схемы мы используем - это draft 4
'$schema' => 'http://json-schema.org/draft-04/schema#',
// определяет ресурс который описывает схема
'title' => 'product',
'type' => 'object',
// в JSON схеме нужно указывать свойства в атрибуете 'properties'.
'properties' => [
'id' => [
'type' => 'integer',
],
'title' => [
'type' => 'string',
],
'product_data_brand' => [
'type' => 'string',
],
'featured_image' => [
'type' => 'string',
],
'product_data_model' => [
'type' => 'string',
],
'product_data_size' => [
'type' => 'string',
],
'product_data_type' => [
'type' => 'string',
],
'product_data_tread' => [
'type' => 'string',
],
'product_data_price' => [
'type' => 'string',
],
'product_data_images' => [
'type' => 'array',
],
'product_data_desc' => [
'type' => 'string',
],
'category' => [
'type' => 'array',
],
// TODO добавить поля
// []
],
];
return $schema;
}
}
?>
Upvotes: 0
Views: 2049
Reputation: 358
$posts= new WP_Query(array(
'post_per_page' => 3,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'products',
));
// Create the response object
$response = new WP_REST_Response( $data );
// set header for X-WP-Total and X-WP-TotalPages
$max_pages = $posts->max_num_pages;
$total_posts = $posts->found_posts;
$response->header( 'X-WP-Total', $total_posts );
$response->header( 'X-WP-TotalPages', $max_pages);
// Add a custom status code
$response->set_status( 200 );
return $response;
Upvotes: 1
Reputation: 53
Here is my solution. now i have in that Rest Api headers that i needed and it does search too ^_^
<?php
/**
* Plugin Name: Custom API Plugin
* Description: That plugin creates some custom end points for wp-admin
* Author: Ahma
* Version: 1
*/
add_action( 'rest_api_init', 'prefix_register_my_rest_routes' );
function prefix_register_my_rest_routes() {
$controller = new My_REST_Posts_Controller();
$controller->register_routes();
}
class My_REST_Posts_Controller extends WP_REST_Controller {
function __construct(){
$this->namespace = 'wl/v1';
$this->rest_base = 'products';
}
function register_routes(){
register_rest_route( $this->namespace, "/$this->rest_base", [
[
'methods' => 'GET',
'callback' => [ $this, 'get_items' ],
],
'schema' => [ $this, 'get_item_schema' ],
] );
register_rest_route( $this->namespace, "/$this->rest_base/(?P<id>[\w]+)", [
[
'methods' => 'GET',
'callback' => [ $this, 'get_item' ],
],
'schema' => [ $this, 'get_item_schema' ],
] );
}
/**
* Получает последние посты и отдает их в виде rest ответа.
*
* @param WP_REST_Request $request Текущий запрос.
*
* @return WP_Error|array
*/
function get_items($request ){
$data = [];
$page = isset($request->get_params()['page'])? $request->get_params()['page']: 1;
$search_query = isset($request->get_params()['sq'])? $request->get_params()['sq']: null;
$posts = new WP_Query(array(
'posts_per_page' => 10,
'orderby' => 'date',
'order' => 'DESC',
'post_type' => 'products',
'paged' => $page,
's' => $search_query
));
if ( empty( $posts ) )
return $data;
foreach( $posts->posts as $post ){
$response = $this->prepare_item_for_response( $post, $request );
$data[] = $this->prepare_response_for_collection( $response );
}
$max_pages = $posts->max_num_pages;
$total_posts = $posts->found_posts;
$data = new WP_REST_Response( $data, 200 );
$data->header( 'X-WP-Total', $total_posts );
$data->header( 'X-WP-TotalPages', $max_pages);
return $data;
}
/**
* Получает отдельный ресурс.
*
* @param WP_REST_Request $request Текущий запрос.
*
* @return array
*/
function get_item( $request ){
$id = (int) $request['id'];
$post = get_post( $id );
if( ! $post )
return array();
return $this->prepare_item_for_response( $post, $request );
}
/**
* Собирает данные ресурса в соответствии со схемой ресурса.
*
* @param WP_Post $post Объект ресурса, из которого будут взяты оригинальные данные.
* @param WP_REST_Request $request Текущий запрос.
*
* @return array
*/
function prepare_item_for_response( $post, $request ){
$post_data = [];
$schema = $this->get_item_schema();
// We are also renaming the fields to more understandable names.
if ( isset( $schema['properties']['id'] ) )
$post_data['id'] = (int) $post->ID;
if ( isset( $schema['properties']['title'] ) )
$post_data['title'] = apply_filters( 'the_title', $post->post_title, $post );
if ( isset( $schema['properties']['content'] ) )
$post_data['content'] = apply_filters( 'the_content', $post->post_content, $post );
if ( isset( $schema['properties']['featured_image'] ) )
$post_data['featured_image'] = get_the_post_thumbnail_url($post->ID, 'full');
if ( isset( $schema['properties']['product_data_brand'] ) )
$post_data['product_data_brand'] = carbon_get_post_meta($post->ID,'product_data_brand');
if ( isset( $schema['properties']['product_data_model'] ) )
$post_data['product_data_model'] = carbon_get_post_meta($post->ID,'product_data_model');
if ( isset( $schema['properties']['product_data_size'] ) )
$post_data['product_data_size'] = carbon_get_post_meta($post->ID,'product_data_size');
if ( isset( $schema['properties']['product_data_type'] ) )
$post_data['product_data_type'] = carbon_get_post_meta($post->ID,'product_data_type');
if ( isset( $schema['properties']['product_data_tread'] ) )
$post_data['product_data_tread'] = carbon_get_post_meta($post->ID,'product_data_tread');
if ( isset( $schema['properties']['product_data_price'] ) )
$post_data['product_data_price'] = carbon_get_post_meta($post->ID,'product_data_price');
if ( isset( $schema['properties']['product_data_images'] ) )
$post_data['product_data_images'] = carbon_get_post_meta($post->ID,'product_data_images');
if ( isset( $schema['properties']['product_data_desc'] ) )
$post_data['product_data_desc'] = carbon_get_post_meta($post->ID,'product_data_desc');
if ( isset( $schema['properties']['category'] ) )
$post_data['categories'] = wp_get_post_terms($post->ID, 'category_of_product', array('fields' => 'ids'));
return $post_data;
}
/**
* Подготавливает ответ отдельного ресурса для добавления его в коллекцию ресурсов.
*
* @param WP_REST_Response $response Response object.
*
* @return array|mixed Response data, ready for insertion into collection data.
*/
function prepare_response_for_collection( $response ){
if ( ! ( $response instanceof WP_REST_Response ) ){
return $response;
}
$data = (array) $response->get_data();
$server = rest_get_server();
if ( method_exists( $server, 'get_compact_response_links' ) ){
$links = call_user_func( [ $server, 'get_compact_response_links' ], $response );
}
else {
$links = call_user_func( [ $server, 'get_response_links' ], $response );
}
if ( ! empty( $links ) ){
$data['_links'] = $links;
}
return $data;
}
## Схема ресурса.
function get_item_schema(){
$schema = [
// показывает какую версию схемы мы используем - это draft 4
'$schema' => 'http://json-schema.org/draft-04/schema#',
// определяет ресурс который описывает схема
'title' => 'product',
'type' => 'object',
// в JSON схеме нужно указывать свойства в атрибуете 'properties'.
'properties' => [
'id' => [
'type' => 'integer',
],
'title' => [
'type' => 'string',
],
'product_data_brand' => [
'type' => 'string',
],
'featured_image' => [
'type' => 'string',
],
'product_data_model' => [
'type' => 'string',
],
'product_data_size' => [
'type' => 'string',
],
'product_data_type' => [
'type' => 'string',
],
'product_data_tread' => [
'type' => 'string',
],
'product_data_price' => [
'type' => 'string',
],
'product_data_images' => [
'type' => 'array',
],
'product_data_desc' => [
'type' => 'string',
],
'category' => [
'type' => 'array',
],
// TODO добавить поля
// []
],
];
return $schema;
}
}
?>
Upvotes: 2