Проблемы с применением фильтров JSON-тела в API поиска портала ЕС F&T с интеграцией WordPress

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

Я пытаюсь использовать сервис API поиска публичных REST API Портала ЕС по финансированию и тендерам, чтобы получать данные для дальнейшей интеграции с моим проектом, но у меня возникают некоторые проблемы. Я использую WordPress в качестве CMS с плагином ACF | Advanced Custom Fields. Цель системы заключается в том, чтобы сделать вызов API, получить все результаты и сохранить каждый параметр в настраиваемом поле, не делая постоянные вызовы API. Согласно документации API (Программные интерфейсы приложений Портала финансирования и тендеров (API)), говорится, что «Критерии поиска (запрос) могут быть отправлены в “Данными формы” POST-запроса в формате JSON», но у меня возникают проблемы с реализацией фильтра в WordPress. В документации указано, как получить запрос для фильтра, так что я хочу применить что-то вроде этого:

{"bool":{"must":[{"terms":{"type":["1","2","8"]}},{"terms":{"status":["31094501","31094502"]}}]}}

Таким образом, я должен получать только ответы, у которых статус 31094501 (Предстоящий) или 31094502 (Открытый для подачи). Но когда я делаю вызов API, иногда я не получаю результатов, а иногда получаю результаты, которые не соответствуют примененному фильтру. Я пытался применить фильтр таким образом:

add_action('init', 'register_EUopportunity');

function register_EUopportunity() {
    register_post_type('opportunity', [
        'label' => 'EU opportunities',
        'public' => true,
        'capability_type' => 'post',
    ]);
}

add_action('wp_ajax_nopriv_get_opportunities_from_api', 'get_opportunities_from_api');
add_action('wp_ajax_get_opportunities_from_api', 'get_opportunities_from_api');

function get_opportunities_from_api() {
    $current_page = ( ! empty($_POST['current_page']) ) ? $_POST['current_page'] : 1;
    $opportunities = [];

    $body = array(
        'bool' => array(
            'must' => array(
                array(
                    'terms' => array(
                        'type' => array('1', '2', '8')
                    )
                ),
                array(
                    'terms' => array(
                        'status' => array('31094501', '31094502')
                    )
                )
            )
        )
    );

    $args = array(
        'headers' => array(
            'Content-Type' => 'application/json'
        ),
        'body' => json_encode($body),
    );

    $response = wp_remote_post('https://api.tech.ec.europa.eu/search-api/prod/rest/search?apiKey=SEDIA&text=***&pageSize=50&pageNumber=" . $current_page, $args);

    if (is_wp_error($response)) {
        return false;
    }

    $response_body = wp_remote_retrieve_body($response);
    $response_body = json_decode($response_body, true);

    if (!is_array($response_body) || empty($response_body["results"])) {
        return false;
    }

    $opportunities = $response_body['results'];

    foreach ($opportunities as $opportunity) {
        $opportunity_slug = sanitize_title($opportunity['reference']);
        $inserted_opportunity = wp_insert_post([
            'post_name' => $opportunity_slug,
            'post_title' => $opportunity_slug,
            'post_type' => 'opportunity',
            'post_status' => 'publish'
        ]);

        if (is_wp_error($inserted_opportunity)) {
            continue;
        }

        $fillable = [
            'field_6708df10da74e' => 'reference',
            'field_6708d325a3d11' => 'url',
            'field_6708d52fe3556' => 'summary',
            'field_6708f69748573' => 'frameworkProgramme',
            'field_670901cfc55e8' => 'deadlineDate',
            'field_67090647166a6' => 'callTitle',
            'field_67090684813cd' => 'identifier',
            'field_6709088554ec8' => 'descriptionByte',
            'field_670f704b8482f' => 'status',
        ];

        foreach ($fillable as $key => $name) {
            if ($name === 'frameworkProgramme' && !empty($opportunity['metadata']['frameworkProgramme'])) {
                update_field($key, $opportunity['metadata']['frameworkProgramme'][0], $inserted_opportunity); 
            } elseif($name === 'deadlineDate' && !empty($opportunity['metadata']['deadlineDate'])){
                update_field($key, $opportunity['metadata']['deadlineDate'][0], $inserted_opportunity);
            } elseif($name === 'callTitle' && !empty($opportunity['metadata']['callTitle'])){
                update_field($key, $opportunity['metadata']['callTitle'][0], $inserted_opportunity);
            } elseif($name === 'identifier' && !empty($opportunity['metadata']['identifier'])){
                update_field($key, $opportunity['metadata']['identifier'][0], $inserted_opportunity);
            } elseif($name === 'descriptionByte' && !empty($opportunity['metadata']['descriptionByte'])){
                update_field($key, $opportunity['metadata']['descriptionByte'][0], $inserted_opportunity);
            } elseif($name === 'status' && !empty($opportunity['metadata']['status'])){
                update_field($key, $opportunity['metadata']['status'][0], $inserted_opportunity);
            } elseif (!empty($opportunity[$name])) {
                update_field($key, $opportunity[$name], $inserted_opportunity);
            }
        }
    }

    $current_page = $current_page + 1;
    wp_remote_post(admin_url('admin-ajax.php?action=get_opportunities_from_api'), [
        'blocking' => false,
        'sslverify' => false,
        'body' => [
            'current_page' => $current_page
        ]
    ]);
}

Если я не применяю никакие фильтры, код, похоже, работает нормально. Результаты получаются, добавляются как записи, и настраиваемые поля заполняются. Но когда я применяю фильтры, я должен получать только результаты, у которых статус 31094501 или 31094502, но, как я уже говорил, кажется, что фильтр не работает, и иногда я не получаю результатов, а иногда получаю результаты, статус которых отличается от 31094501 или 31094502.

Что может происходить? Я также пробовал использовать точно такой же фильтр в POSTMAN. Там все работает нормально, и ожидаемые результаты получаются. Но в WordPress это, похоже, не работает.

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

Проблема применения фильтров JSON в API поиска EU F&T Portal с интеграцией WordPress

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

Описание проблемы

Вы планируете сделать запрос к API для получения данных о возможностях финансирования и затем сохранить эти данные в пользовательские поля через ACF. Ваша цель — использовать фильтр для выбора только тех записей, которые соответствуют определенным статусам, таким как 31094501 (Предстоящий) или 31094502 (Открыт для подачи). Несмотря на настройку фильтра в JSON формате, наблюдаются следующие проблемы:

  1. Иногда запрос возвращает пустую строку без результатов.
  2. В некоторых случаях результаты включают данные, которые не соответствуют установленным фильтрам.

Код реализации

Вы представили следующий код для выполнения API-запроса:

$body = array(
    'bool' => array(
        'must' => array(
            array(
                'terms' => array(
                    'type' => array('1', '2', '8')
                )
            ),
            array(
                'terms' => array(
                    'status' => array('31094501', '31094502')
                )
            )
        )
    )
);

В этом коде вы создаете запрос, который должен фильтровать результаты на основании указанных параметров. Однако, как Вы заметили, при выполнении функций в WordPress результаты не всегда соответствуют ожиданиям.

Возможные причины и решения

  1. Проблемы с форматом и структурой данных:

    • Удостоверьтесь, что данные, отправляемые в теле запроса, корректно сериализуются в JSON. Отладьте вывод значения переменной $body, используя error_log(), для того чтобы удостовериться, что формат соответствует требованиям API.
    error_log(json_encode($body));
  2. API-ключ и параметры запроса:

    • Проверьте, что API-ключ действителен и имеет соответствующие разрешения для выполнения фильтрованных запросов.
    • Убедитесь, что вы не добавляете лишние параметры или символы в URL-адрес. Ваш запрос заканчивается некорректной строкой:
    ... "pageNumber=" . $current_page

    Измените это на:

    'https://api.tech.ec.europa.eu/search-api/prod/rest/search?apiKey=SEDIA&text=***&pageSize=50&pageNumber=' . $current_page
  3. Отладка результатов API:

    • Вы можете выполнить отладку, добавив вывод ответа от API для проверки, что именно возвращает сервер и какие данные он получает с фильтром.
    error_log(print_r($response_body, true));
  4. Проблемы с кэшированием:

    • Убедитесь, что результаты не кэшируются в вашем WordPress-сайте, так как это может привести к получению устаревших данных. Вы можете временно отключить кэширование или использовать параметры в URL-запросе для принудительного обновления данных.
  5. Сравнение с POSTMAN:

    • Поскольку запрос в POSTMAN работает корректно, возможно, стоит сравнить заголовки и тело запроса в POSTMAN и WordPress. Убедитесь, что все параметры (такие как Content-Type) соответствуют ожидаемым сервером.

Заключение

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

Благодаря этим действиям вы сможете добиться стабильной работы вашего проекта и корректно интегрировать API EU F&T Portal с WordPress.

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

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