Вопрос или проблема
Я пытаюсь использовать сервис 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 формате, наблюдаются следующие проблемы:
- Иногда запрос возвращает пустую строку без результатов.
- В некоторых случаях результаты включают данные, которые не соответствуют установленным фильтрам.
Код реализации
Вы представили следующий код для выполнения API-запроса:
$body = array(
'bool' => array(
'must' => array(
array(
'terms' => array(
'type' => array('1', '2', '8')
)
),
array(
'terms' => array(
'status' => array('31094501', '31094502')
)
)
)
)
);
В этом коде вы создаете запрос, который должен фильтровать результаты на основании указанных параметров. Однако, как Вы заметили, при выполнении функций в WordPress результаты не всегда соответствуют ожиданиям.
Возможные причины и решения
-
Проблемы с форматом и структурой данных:
- Удостоверьтесь, что данные, отправляемые в теле запроса, корректно сериализуются в JSON. Отладьте вывод значения переменной
$body
, используяerror_log()
, для того чтобы удостовериться, что формат соответствует требованиям API.
error_log(json_encode($body));
- Удостоверьтесь, что данные, отправляемые в теле запроса, корректно сериализуются в JSON. Отладьте вывод значения переменной
-
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
-
Отладка результатов API:
- Вы можете выполнить отладку, добавив вывод ответа от API для проверки, что именно возвращает сервер и какие данные он получает с фильтром.
error_log(print_r($response_body, true));
-
Проблемы с кэшированием:
- Убедитесь, что результаты не кэшируются в вашем WordPress-сайте, так как это может привести к получению устаревших данных. Вы можете временно отключить кэширование или использовать параметры в URL-запросе для принудительного обновления данных.
-
Сравнение с POSTMAN:
- Поскольку запрос в POSTMAN работает корректно, возможно, стоит сравнить заголовки и тело запроса в POSTMAN и WordPress. Убедитесь, что все параметры (такие как Content-Type) соответствуют ожидаемым сервером.
Заключение
При работе с API, особенно с фильтрами и сложными запросами, важно внимательно следить за форматом и структурой данных, которые отправляются и принимаются. Примените вышеперечисленные решения и дополнительные отладочные методы, чтобы локализовать источник проблемы и обеспечить корректную передачу фильтров. Постоянный мониторинг и отладка в процессе могут значительно облегчить выявление ошибок. Также рекомендуется обратиться к документации API на предмет более детальной информации о возможных результатах при запросах с фильтрами.
Благодаря этим действиям вы сможете добиться стабильной работы вашего проекта и корректно интегрировать API EU F&T Portal с WordPress.