Вопрос или проблема
В настоящее время я пытаюсь создать плагин для WordPress, который создает записи в базе данных WordPress на основе данных из внешнего JSON API. В качестве примера можно использовать этот поток NewsAPI:
https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=81143272da6c48d58bc38fe80dd110d6
Плагин, который я написал, декодирует данные JSON с помощью json_decode
и проходит по объекту article
в потоке JSON. Наконец, записи вставляются программно с помощью wp_insert_post
:
<?php
/**
* Название плагина: Автоматический импорт новостного потока
* Версия: 1.0.0
*/
function news_importer() {
$url = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=81143272da6c48d58bc38fe80dd110d6";
$response = wp_remote_get( $url );
$data = json_decode( wp_remote_retrieve_body( $response ) );
foreach( $data->articles as $news ) {
$post_title = $news->title;
$post_content = $news->content;
$post_date = $news->publishedAt;
$post = array(
'post_title' => $post_title,
'post_content' => $post_content,
'post_date' => $post_date,
'post_status' => 'publish',
'post_type' => 'post'
);
wp_insert_post( $post );
}
}
Моя проблема в том, что когда плагин активирован, записи не создаются и не добавляются в базу данных. Когда новая запись загружается и появляется в потоке, она должна загружаться автоматически (асинхронно).
Есть идеи, почему это не работает?
Проверяя, существует ли объект ‘products’ в условии if
и проходя по объектам (как в приведенном выше коде), функция, похоже, работает:
function json_to_post() {
$response = wp_remote_get('https://dummyjson.com/products');
$json_data = wp_remote_retrieve_body($response);
$data = json_decode($json_data, true);
if (isset($data['products'])) {
$products = $data['products'];
foreach ($products as $post) {
$title = $post['title'];
$content = $post['description'];
$new_post = array(
'post_title' => $title,
'post_content' => $content,
'post_status' => 'publish',
'post_type' => 'post'
);
wp_insert_post($new_post);
}
}
}
add_action('init', 'json_to_post');
Существует готовый плагин, который делает именно это:
Ответ или решение
Для создания плагина WordPress, который будет программно генерировать записи на основе данных из внешнего JSON-API, важным этапом является асинхронная работа с API и корректная вставка записей в базу данных. Давайте рассмотрим ваш код и разберем возможные проблемы, а также предложим корректное решение.
Анализ Проблемы
-
Отсутствие Асинхронного Запроса: Ваша текущая реализация пытается создать записи при инициализации WordPress с помощью хука
init
. Однако это может привести к тому, что плагин будет выполняться при каждом загрузке страницы, если не применить дополнительные условия. -
Отсутствие Проверок: Проверьте, получаете ли вы данные от API. Если данные не поступают,
wp_insert_post
не будет выполняться. -
Дублирование Записей: Ваша логика не учитывает уже существующие записи, что может привести к созданию дубликатов.
Предложенное Решение
Для эффективного создания записей и обеспечения асинхронного поведения вы можете использовать cron-задания в WordPress. Это позволит автоматически загружать данные из API через определенные интервалы времени.
Пример Реализации Плагина
Вот пример того, как вы можете реализовать данное решение:
<?php
/**
* Plugin Name: Automatic News Feed Importer
* Version: 1.0.0
* Description: This plugin fetches articles from an external JSON feed and creates posts automatically.
*/
// Создание запланированного события
register_activation_hook(__FILE__, 'my_custom_cron_schedule');
function my_custom_cron_schedule() {
if (!wp_next_scheduled('fetch_news_articles')) {
wp_schedule_event(time(), 'hourly', 'fetch_news_articles');
}
}
// Удаление события при деактивации плагина
register_deactivation_hook(__FILE__, 'my_custom_cron_deactivate');
function my_custom_cron_deactivate() {
wp_clear_scheduled_hook('fetch_news_articles');
}
// Функция для запроса к API и создания записей
add_action('fetch_news_articles', 'news_importer');
function news_importer() {
$url = "https://newsapi.org/v2/top-headlines?sources=techcrunch&apiKey=81143272da6c48d58bc38fe80dd110d6";
$response = wp_remote_get($url);
if (is_wp_error($response)) {
return; // Обработка ошибки
}
$data = json_decode(wp_remote_retrieve_body($response), true);
if (isset($data['articles'])) {
foreach ($data['articles'] as $news) {
// Проверка на наличие поста с таким заголовком
if (!post_exists($news['title'])) {
$post = array(
'post_title' => $news['title'],
'post_content' => $news['content'],
'post_date' => date('Y-m-d H:i:s', strtotime($news['publishedAt'])),
'post_status' => 'publish',
'post_type' => 'post'
);
wp_insert_post($post);
}
}
}
}
Объяснение Кода:
-
Запланированное Событие: Используя функции
wp_schedule_event
иwp_clear_scheduled_hook
, вы создаете cron-задачу, которая будет вызываться каждый час. Это обеспечит автоматическую проверку наличия новых статей. -
Проверка на Ошибки: Используется
is_wp_error
, чтобы убедиться, что запрос к API прошел успешно. -
Уникальность Постов: Перед вставкой записи проверяется, существует ли уже пост с таким заголовком с помощью функции
post_exists
. -
Обработка Дат: Дата публикации формируется в формате, принятый в базе данных.
Заключение
Данное решение позволяет вашему плагину автоматически создавать записи на основе внешнего JSON-API без необходимости вручную инициировать процесс. Теперь вы обеспечите асинхронное заполнение базы данных новыми записями регулярно. Не забудьте протестировать плагин в безопасной среде перед его развертыванием на производственном сайте.
Если у вас будут дополнительные вопросы или потребуется помощь, не стесняйтесь обращаться!