Це рішення працює з get_items()
в /lib/endpoints/class-wp-rest-posts-controller.php
з v2 WP Rest API
.
По-перше, ви хочете побудувати GET
аргументи на зразок того, що було б для a new WP_Query()
. Найпростіший спосіб зробити це за допомогою http_build_query()
.
$args = array (
'filter' => array (
'meta_query' => array (
'relation' => 'AND',
array (
'key' => 'color',
'value' => 'blue',
'compare' => '=',
),
array (
'key' => 'test',
'value' => 'testing',
'compare' => '=',
),
),
),
);
$field_string = http_build_query( $args );
Це створить щось на кшталт:
filter%5Bmeta_query%5D%5Brelation%5D=AND&filter%5Bmeta_query%5D%5B0%5D%5Bkey%5D=color&filter%5Bmeta_query%5D%5B0%5D%5Bvalue%5D=blue&filter%5Bmeta_query%5D%5B0%5D%5Bcompare%5D=%3D&filter%5Bmeta_query%5D%5B1%5D%5Bkey%5D=test&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D=testing&filter%5Bmeta_query%5D%5B1%5D%5Bcompare%5D=%3D
Якщо ви хочете читати, ви також можете скористатися інструментами Chrome і decodeURIComponent('your-query-here')
полегшити їх читання, перекинувши його в URL-адресу API JSON Rest API :
https://demo.wp-api.org/wp-json/wp/v2/product?filter[meta_query][relation]=AND&filter[meta_query][0][key]=color&filter[meta_query][0][value]=blue&filter[meta_query][0][compare]==&filter[meta_query][1][key]=test&filter[meta_query][1][value]=testing&filter[meta_query][1][compare]==
Примітка. Щоб використовувати власний тип публікації, який ви розміщували product
раніше?
/wp-json/wp/v2/<custom-post-type>?filter[meta_query]
Отже, у вас є ваш запит, але нам потрібно доручити WP, як поводитися з кількома речами:
- Додавання підтримки REST для користувацького типу публікації
product
- Дозволення аргументів запиту
meta_query
- Розбір
meta_query
// 1) Add CPT Support <product>
function wpse_20160526_add_product_rest_support() {
global $wp_post_types;
//be sure to set this to the name of your post type!
$post_type_name = 'product';
if( isset( $wp_post_types[ $post_type_name ] ) ) {
$wp_post_types[$post_type_name]->show_in_rest = true;
$wp_post_types[$post_type_name]->rest_base = $post_type_name;
$wp_post_types[$post_type_name]->rest_controller_class = 'WP_REST_Posts_Controller';
}
}
add_action( 'init', 'wpse_20160526_add_product_rest_support', 25 );
// 2) Add `meta_query` support in the GET request
function wpse_20160526_rest_query_vars( $valid_vars ) {
$valid_vars = array_merge( $valid_vars, array( 'meta_query' ) ); // Omit meta_key, meta_value if you don't need them
return $valid_vars;
}
add_filter( 'rest_query_vars', 'wpse_20160526_rest_query_vars', PHP_INT_MAX, 1 );
// 3) Parse Custom Args
function wpse_20160526_rest_product_query( $args, $request ) {
if ( isset( $args[ 'meta_query' ] ) ) {
$relation = 'AND';
if( isset($args['meta_query']['relation']) && in_array($args['meta_query']['relation'], array('AND', 'OR'))) {
$relation = sanitize_text_field( $args['meta_query']['relation'] );
}
$meta_query = array(
'relation' => $relation
);
foreach ( $args['meta_query'] as $inx => $query_req ) {
/*
Array (
[key] => test
[value] => testing
[compare] => =
)
*/
$query = array();
if( is_numeric($inx)) {
if( isset($query_req['key'])) {
$query['key'] = sanitize_text_field($query_req['key']);
}
if( isset($query_req['value'])) {
$query['value'] = sanitize_text_field($query_req['value']);
}
if( isset($query_req['type'])) {
$query['type'] = sanitize_text_field($query_req['type']);
}
if( isset($query_req['compare']) && in_array($query_req['compare'], array('=', '!=', '>','>=','<','<=','LIKE','NOT LIKE','IN','NOT IN','BETWEEN','NOT BETWEEN', 'NOT EXISTS')) ) {
$query['compare'] = sanitize_text_field($query_req['compare']);
}
}
if( ! empty($query) ) $meta_query[] = $query;
}
// replace with sanitized query args
$args['meta_query'] = $meta_query;
}
return $args;
}
add_action( 'rest_product_query', 'wpse_20160526_rest_product_query', 10, 2 );