Intereting Posts
Как зарегистрировать / вставить собственный файл CSS? Является ли WP уязвимым при обновлении плагинов или тем? Пользовательский / page / 2 / template (отличается от index.php) Можно ли переименовать таксономию «почтовые теги» по умолчанию? Выбор CMB с данными из CPT Можно ли использовать один пул для множественных таксономий? Не удается получить доступ к идентификатору текущей записи в пользовательском плагине Вызов неопределенной функции wp_get_sites () Получите переменную область всех комментариев текущего сообщения Наличие пользовательского пула сообщений, который сталкивается с существующим каталогом Вставить изображения на главной высоте Как определить, существует ли определенный член в массиве? Ясность, необходимая для использования нескольких 403 запрещенных функций header () в начале файлов плагинов Создайте роль под-администратора, которая может делать все, кроме использования, или увидеть редактор кода Ссылка new_excerpt_more не работает должным образом

Фильтрация нескольких настраиваемых полей с помощью WP REST API 2

Я хочу фильтровать сообщения на основе нескольких настраиваемых полей acf с отношением AND. Что-то вроде этого:

$args = array( 'post_type' => 'product', 'meta_query' => array( 'relation' => 'AND', array( 'key' => 'color', 'value' => 'blue', 'compare' => '=', ), array( 'key' => 'price', 'value' => array( 20, 100 ), 'type' => 'numeric', 'compare' => 'BETWEEN', ), ), ); 

У меня может быть больше фильтров. Как я могу преобразовать их в фильтры REST API 2?

Solutions Collecting From Web of "Фильтрация нескольких настраиваемых полей с помощью WP REST API 2"

Это решение работает с get_items() в /lib/endpoints/class-wp-rest-posts-controller.php v2 WP Rest API /lib/endpoints/class-wp-rest-posts-controller.php v2 WP Rest API .


Во-первых, вы захотите построить аргументы GET как и для 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, как обрабатывать несколько вещей:

  1. Добавление поддержки REST для настраиваемого product типа post
  2. meta_query запрос args meta_query
  3. Анализ 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 ); 

Вот тест, который я сделал на Localhost:

По соображениям безопасности мета-запрос не разрешен в WP Api, сначала вам нужно добавить meta_query в разрешенный rest_query, добавив эту функцию в вашу WordPress тему functions.php

 function api_allow_meta_query( $valid_vars ) { $valid_vars = array_merge( $valid_vars, array( 'meta_query') ); return $valid_vars; } add_filter( 'rest_query_vars', 'api_allow_meta_query' ); 

после этого вам понадобится построить html-запрос, используя эту функцию на другом веб-сайте, который получит данные с сайта wordpress

 $curl = curl_init(); $fields = array ( 'filter[meta_query]' => array ( 'relation' => 'AND', array ( 'key' => 'color', 'value' => 'blue', 'compare' => '=' ), array ( 'key' => 'price', 'value' => array ( 20, 100 ), 'type' => 'numeric', 'compare' => 'BETWEEN' ), ), ); $field_string = http_build_query($fields); curl_setopt_array($curl, array ( CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => 'http://yourwordpreswebssite.com/wp-json/wp/v2/posts?' . $field_string ) ); $result = curl_exec($curl); echo htmlentities($result); 

Я изменяю массив полей так, чтобы теперь выглядеть ваши аргументы запроса. Строка закодированного запроса будет выглядеть так:

 http://yourwordpreswebssite.com/wp-json/wp/v2/posts?filter%5Btaxonomy%5D=product&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=price&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D%5B0%5D=20&filter%5Bmeta_query%5D%5B1%5D%5Bvalue%5D%5B1%5D=100&filter%5Bmeta_query%5D%5B1%5D%5Btype%5D=numeric&filter%5Bmeta_query%5D%5B1%5D%5Bcompare%5D=BETWEEN 

Используя urldecode() , который в этом случае будет: urldecode('http://yourwordpreswebssite.com/wp-json/wp/v2/posts?' . $field_string); у вас будет такой URL-адрес:

 http://yourwordpreswebssite.com/wp-json/wp/v2/posts?filter[taxonomy]=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]=price&filter[meta_query][1][value][0]=20&filter[meta_query][1][value][1]=100&filter[meta_query][1][type]=numeric&filter[meta_query][1][compare]=BETWEEN 

Если вы можете предоставить нам свой URL-адрес в прямом эфире, чтобы мы могли протестировать его с помощью почтальона непосредственно на вашем веб-сайте, потому что для его проверки на локальном хосте или любом существующем сайте WordPress потребуется создать пользовательский тип сообщения и добавить мета-поля и т. Д. И т.д. Cheers!

Вы можете сделать это без Rest API Как это (это мой фильтр сообщений)

     $ paged = (get_query_var ('paged'))?  get_query_var ('paged'): 1;
 $ args = array (
         «paged» => $ paged,
         'orderby' => 'date', // сортировка по дате у нас будет в любом случае (но вы можете изменить / доработать это)
         'order' => 'DESC',
     );

     // создаём массив $ args ['meta_query'] если указана хотя бы одна цена или отмечен чекбокс
     if (isset ($ _GET ['price_min']) || isset ($ _GET ['price_max']) || isset ($ _GET ['type']))
         $ args ['meta_query'] = массив ('отношение' => 'AND');  // И значит все условия meta_query должны выполняться


     if ($ type) {
         $ args ['meta_query'] [] = массив (
             'key' => 'type',
             'value' => $ type,
         );
     };

     if ($ plan) {
         $ args ['meta_query'] [] = массив (
             'key' => 'plan',
             'value' => $ plan,
         );
     };

     if ($ room_num) {
         $ args ['meta_query'] [] = массив (
             'key' => 'room_num',
             'value' => $ room_num,
         );
     };

     if ($ etage) {
         $ args ['meta_query'] [] = массив (
             'key' => 'etage',
             'value' => $ etage,
         );
     };  

     if ($ price_min || $ price_max) {
         $ args ['meta_query'] [] = массив (
             'ключ' => 'цена',
             'value' => array ($ price_min, $ price_max),
             'type' => 'numeric',
             'compare' => 'BETWEEN'
         );
     };  

     if ($ area_min || $ area_max) {
         $ args ['meta_query'] [] = массив (
             'key' => 'area',
             'value' => array ($ area_min, $ area_max),
             'type' => 'numeric',
             'compare' => 'BETWEEN'
         );
     };

В WordPress 4.7 аргумент filter удален.

Вы можете активировать его, установив этот плагин, предоставленный командой WordPress. Только после этого вы можете использовать одно из решений, предложенное в других ответах.

Я еще не нашел решение сделать то же самое без установки плагина.