Как сделать meta query через REST-API в WordPress 4.7+?

30 июн. 2017 г., 15:11:24
Просмотры: 35.6K
Голосов: 18

Я пытаюсь сделать фильтрацию через meta query, но что бы я ни пробовал, ничего не работает.

По сути, я хочу сделать такой запрос через REST API:

wp-json/wp/v2/books?meta_query[relation]=OR&meta_query[0][key]=arkivera&meta_query[0][value]=1&meta_query[0][compare]==

Я пробовал несколько разных произвольных полей, но он всегда возвращает все объекты постов.

В моем файле functions.php я добавил:

function api_allow_meta_query( $valid_vars ) {
    // Объединяем массивы для добавления meta_query
    $valid_vars = array_merge( $valid_vars, array( 'meta_query') );
    return $valid_vars;
}
add_filter( 'rest_query_vars', 'api_allow_meta_query' );

Я пытался найти документацию по этому вопросу, но не смог, также большинство похожих вопросов не относятся к WordPress 4.7, так как filter[xxx] был удален.

1
Комментарии

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

bueltge bueltge
2 янв. 2018 г. 15:05:34
Все ответы на вопрос 3
2
21

Используйте фильтр rest_{CUSTOM_POST_TYPE}_query для добавления поддержки метаданных записей в WP REST API для любого типа записи.

Ознакомьтесь с Gist поиск записей по метаданным с помощью REST API.

Как использовать?

http://example.org/wp-json/wp/v2/post?meta_key=<my_meta_key>&meta_value=<my_meta_value>

Пример

Получение записей, у которых метаданное поле already-visited имеет значение true.

http://example.org/wp-json/wp/v2/post?meta_key=already-visited&meta_value=true

Будут выведены ТОЛЬКО записи, у которых метаданное поле already-visited имеет значение true.

Для справки: Поиск записей по метаданным с помощью REST API.

Доступные фильтры

  • rest_post_query
  • rest_page_query
  • rest_attachment_query
5 июн. 2018 г. 13:59:21
Комментарии

Спасибо за это! Думаю, этот ответ с большей вероятностью должен быть принятым.

jagershark jagershark
1 окт. 2018 г. 21:04:29

А как насчет строковых полей, если мы хотим поле со значением (не null)? Я могу получить поля latitude, которые больше определенного значения: filter[meta_key]=latitude&filter[meta_compare]=%3C&filter[meta_value]=34.7. Но мне нужно еще одно строковое поле, которое имеет значение.

saber tabatabaee yazdi saber tabatabaee yazdi
20 февр. 2019 г. 16:28:31
1
12

Вы можете написать собственный обработчик REST для пользовательских запросов, если хотите. В вашем случае запрос можно выполнить следующим образом:

// Регистрация REST маршрута
add_action( 'rest_api_init', function () {
    // Путь к маршруту мета-запроса
    register_rest_route( 'tchernitchenko/v2', '/my_meta_query/', array(
            'methods' => 'GET', 
            'callback' => 'custom_meta_query' 
    ) );
});

// Выполнение запроса и возврат данных
function custom_meta_query(){
    if(isset($_GET['meta_query'])) {
        $query = $_GET['meta_query'];
        // Установка аргументов на основе параметров GET
        $args = array (
            'relation' => $query[0]['relation'],
            array(
                'key' => $query[0]['key'],
                'value' => $query[0]['value'],
                'compare' => '=',
            ),
        );
        // Запуск пользовательского запроса
        $meta_query = new WP_Query($args);
        if($meta_query->have_posts()) {
            // Определение пустого массива
            $data = array();
            // Сохранение заголовка каждой записи в массиве
            while($meta_query->have_posts()) {
                $meta_query->the_post();
                $data[] =  get_the_title();
            }
            // Возврат данных
            return $data;
        } else {
            // Если нет записей
            return 'Нет записей для отображения';
        }
    }
}

Теперь все, что вам нужно сделать, это обратиться по адресу:

wp-json/tchernitchenko/v2/my_meta_query?meta_query[relation]=OR&meta_query[0][key]=arkivera&meta_query[0][value]=1&meta_query[0][compare]==
30 июн. 2017 г. 16:34:42
Комментарии

Есть ли способ расширить это для WooCommerce Legacy API?

Amjad Amjad
16 янв. 2021 г. 01:49:41
9

Следующий код добавляет возможность множественных мета-запросов для всех типов записей. Он поддерживает CPT (пользовательские типы записей) и ACF (Advanced Custom Fields). Исходный код также доступен на Github.

Добавьте его в ваш function.php

add_action( 'rest_api_init', 'wp_rest_filter_add_filters' );
 /**
  * Добавляем необходимый фильтр к каждому типу записи
  **/
function wp_rest_filter_add_filters() {
    foreach ( get_post_types( array( 'show_in_rest' => true ), 'objects' ) as $post_type ) {
        add_filter( 'rest_' . $post_type->name . '_query', 'wp_rest_filter_add_filter_param', 10, 2 );
    }
}
/**
 * Добавляем параметр фильтра
 *
 * @param  array           $args    Аргументы запроса.
 * @param  WP_REST_Request $request Полная информация о запросе.
 * @return array $args.
 **/
function wp_rest_filter_add_filter_param( $args, $request ) {
    // Выходим, если параметр filter не установлен
    if ( empty( $request['filter'] ) || ! is_array( $request['filter'] ) ) {
        return $args;
    }
    $filter = $request['filter'];
    if ( isset( $filter['posts_per_page'] ) && ( (int) $filter['posts_per_page'] >= 1 && (int) $filter['posts_per_page'] <= 100 ) ) {
        $args['posts_per_page'] = $filter['posts_per_page'];
    }
    global $wp;
    $vars = apply_filters( 'rest_query_vars', $wp->public_query_vars );
    function allow_meta_query( $valid_vars )
    {
        $valid_vars = array_merge( $valid_vars, array( 'meta_query', 'meta_key', 'meta_value', 'meta_compare' ) );
        return $valid_vars;
    }
    $vars = allow_meta_query( $vars );

    foreach ( $vars as $var ) {
        if ( isset( $filter[ $var ] ) ) {
            $args[ $var ] = $filter[ $var ];
        }
    }
    return $args;
}

По моему мнению, лучшим решением будет вынести дополнительную функцию в отдельный плагин. Таким образом, даже если пользователь сменит тему, ваши API-запросы не пострадают.

Поэтому я разработал плагин для мета-запросов в WordPress. Более того, он поддерживает ACF!

WP REST Filter

После установки просто выполните GET запрос в следующем формате.

https://domain.com/wp-json/acf/v3/customposttype?filter[meta_key]=acfkey&filter[meta_value]=acfvalue

Исходный код плагина доступен на Github.

24 янв. 2018 г. 22:58:04
Комментарии

Отличный плагин, но сортировка по дате не работает для полей ACF с типом дата!

Advena Advena
30 апр. 2018 г. 13:43:05

Привет, Tanckom. Спасибо за ваше сообщение. Не могли бы вы подробнее описать вашу проблему? Что вы уже пробовали? Пожалуйста, создайте тикет на https://wordpress.org/support/plugin/wp-rest-filter. Наша служба поддержки свяжется с вами там. Спасибо.

Jack Song Jack Song
30 апр. 2018 г. 20:43:29

Привет, Jack, Я разобрался, что правильный URL для получения даты из поля ACF и сортировки по возрастанию или убыванию выглядит так: https://domain.com/wp-json/wp/v2/events?filter[meta_key].acf=evt_date&per_page=100&filter[order]=asc

Advena Advena
30 апр. 2018 г. 23:49:44

Отлично! Рады, что наш плагин помог! :D

Jack Song Jack Song
1 мая 2018 г. 06:53:08

Действительно помог, так держать! :)

Advena Advena
1 мая 2018 г. 13:21:13

Один вопрос: как можно фильтровать даты в формате "2018-09-25 19:30:00 GMT+02:00"? Date and Time Picker для ACF не поддерживает ISO-формат :( Пробовал так, но без успеха domain.com/wp-json/wp/v2/events?filter[meta_key].acf=date&[meta_value]=2018-09-25

Advena Advena
1 мая 2018 г. 19:50:08

Преобразуйте в GMT время в формате yyyy-mm-dd'T'HH:mm:ss, затем domain.com/wp-json/wp/v2/events?filter[meta_key]=date&[meta_value]=2018-09-25T23:59:59. Я полагаю, что ACF сохраняет данные в формате IOS в MySQL, поэтому это должно сработать.

Jack Song Jack Song
2 мая 2018 г. 05:12:42

К сожалению, невозможно получить Дату и Время без пробелов с помощью дополнения ACF "Date and Time Picker" :/ Именно поэтому мне пришлось сделать таким образом.

Advena Advena
2 мая 2018 г. 18:20:08

Мы можем помочь с этим. Пожалуйста, отправьте нам письмо с деталями проблемы на hi@sk8.tech. Мы ответим вам как можно скорее.

Jack Song Jack Song
3 мая 2018 г. 00:55:13
Показать остальные 4 комментариев