Фильтр ответа API WordPress по значению ACF

Вопрос или проблема

Я создаю сайт с использованием API WordPress. Я использую Advanced Custom Fields, а также плагин ACF to Rest API для экспозиции данных ACF в API: https://github.com/airesvsg/acf-to-rest-api

Теперь я пытаюсь отфильтровать ответ по значениям ACF. Мне удалось найти этот фрагмент кода, который помогает с этим:

add_filter( 'rest_product_query', function( $args ) {

    $ignore = array('per_page', 'search', 'order', 'orderby', 'slug');

    foreach ( $_GET as $key => $value ) {
      if (!in_array($key, $ignore)) {
        $args['meta_query'][] = array(
          'key'   => $key,
          'value' => $value,
        );
      }
    }

    return $args;
  });

Теперь я могу фильтровать запросы таким образом: https://example.com/wp-json/wp/v2/product?length=Customizable

Проблема в том, что теперь я не могу получить доступ к страницам API, таким как https://example.com/wp-json/wp/v2/product?page=2, что мне нужно сделать.

Есть ли способ рефакторинга этого, чтобы все еще можно было использовать фильтры/поиск API WordPress по умолчанию?

Или есть ли какой-нибудь альтернативный способ сделать то же самое?

Хорошо, я понял, что мне стоит просто добавить каждый ключ WP по умолчанию в массив $ignore следующим образом, я добавил ‘page’:

$ignore = array('page', 'per_page', 'search', 'order', 'orderby', 'slug');

Ответ или решение

Для решения вашей задачи по фильтрации API-ответов WordPress с использованием значений пользовательских полей Advanced Custom Fields (ACF), давайте подробно рассмотрим предложенное решение и возможные его улучшения.

Проблема с фильтрацией по ACF и пагинацией

Вы столкнулись с тем, что после добавления фильтрации по ACF значение по умолчанию для пагинации (page) было исключено, что затрудняет доступ к страницам API, например, к https://example.com/wp-json/wp/v2/product?page=2. Важно, чтобы функциональность фильтрации по пользовательским полям не мешала стандартной работе API, включая пагинацию.

Решение с использованием массива $ignore

Как вы уже отметили, можно просто добавить ключи пагинации в массив $ignore. Это позволит приватным параметрам API, таким как page, per_page, search, order, orderby, и slug, продолжать работать как обычно, без вмешательства в процессы запроса.

Вот измененный пример кода, который учитывает вашу поправку:

add_filter('rest_product_query', function($args) {
    $ignore = array('page', 'per_page', 'search', 'order', 'orderby', 'slug'); // добавление ключа 'page'

    foreach ($_GET as $key => $value) {
        if (!in_array($key, $ignore)) {
            $args['meta_query'][] = array(
                'key'   => $key,
                'value' => $value,
                'compare' => 'LIKE' // Добавьте оператор сравнения по мере необходимости
            );
        }
    }

    return $args;
});

Оптимизация работы с мета-запросами

Если у вас большое количество пользовательских полей и вы ожидаете, что пользователи будут фильтровать результаты по этим полям, то имеет смысл добавить поддержку множества операторов сравнения, таких как = (равно), != (не равно), LIKE, и т.д., в зависимости от конкретных потребностей.

Альтернативный подход

Есть еще один альтернативный способ фильтрации, который может быть более гибким: использование параметров фильтрации в запросах REST API, которые предоставляются через кастомные эндпоинты. Это позволит вам создать более структурированный и управляемый подход к фильтрации данных.

  1. Создание кастомного эндпоинта с использованием register_rest_route.
  2. Внедрение логики фильтрации прямо в эти эндпоинты, что позволяет лучше контролировать ответ API.

Пример:

add_action('rest_api_init', function () {
    register_rest_route('custom/v1', '/products/', array(
        'methods' => 'GET',
        'callback' => 'custom_get_products',
    ));
});

function custom_get_products($request) {
    $args = array('post_type' => 'product');

    // Логика фильтрации
    foreach ($request->get_params() as $key => $value) {
        if ($key !== 'page' && $key !== 'per_page') {
            $args['meta_query'][] = array(
                'key' => $key,
                'value' => $value,
                'compare' => 'LIKE' // используйте нужный оператор
            );
        }
    }

    $query = new WP_Query($args);
    return rest_ensure_response($query->posts);
}

Заключение

Таким образом, добавление ключа пагинации в массив $ignore – это правильное решение, но нужно также рассмотреть возможность использования кастомных эндпоинтов для более гибкой настройки фильтрации данных. Все вышеперечисленные шаги позволят вам эффективно управлять фильтрацией по ACF значениям, не нарушая стандартные функции WordPress API.

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

Оцените материал
Добавить комментарий

Капча загружается...