Корректно проходите по страницам и выполняйте пагинацию при каждом вызове функции.

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

Хорошо, мне нужна помощь, и я не знаю, делаю ли я это правильно, но я хотел бы узнать, может ли сообщество направить меня в лучшую сторону.

Вот что происходит:

  1. У меня есть register_rest_route(), который вызывает функцию (не включена в этот код).

  2. Я делаю вызов, чтобы получить заголовки конечной точки, где содержится общее количество страниц $headers['headers']['x-wp-totalpages'], которое равно 80.

  3. Затем я перебираю все страницы и вызываю wp_remote_get, чтобы получить 25 постов с каждой страницы.

  4. После этого я просматриваю каждый пост из 25 постов и создаю посты на новом сайте.

Некоторые детали:

У меня есть 795 постов на сайте, которые содержат все данные. Когда я запускаю текущую функцию, она проходит через все 795 постов и фактически импортирует их, так что она частично работает, но есть ошибки.


Что я пытаюсь достичь:

Кто-нибудь знает, как я могу отформатировать эту функцию, чтобы мой параметр wp_remote_get() $page увеличивался только тогда, когда я захожу на конечную точку до $headers['headers']['x-wp-totalpages'], а затем сбрасывался обратно на $page=1, и не использовать цикл for, который автоматически проходит через все 80 страниц за один запрос?


Итак, у меня есть следующая функция:

public function get_posts_via_rest_api(): void
    {
        // Подключаем метод post_exists для конечных точек.
        if (!is_admin()) {
            require_once(ABSPATH . 'wp-admin/includes/post.php');
        }

        // Получаем заголовки REST API
        $headers = wp_remote_head('https://website-im-getting-data-from.com/wp-json/wp/v2/posts');

        // Начинаем с 1 страницы и проходим через все 80 страниц от x-wp-totalpages
        for ($i = 1; $i <= $headers['headers']['x-wp-totalpages']; $i++) {
            $response = wp_remote_get(
                add_query_arg( [
                    'page' => $i,
                    'per_page' => 25,
                    'post_status' => 'publish',
                ], 'https://website-im-getting-data-from.com/wp-json/wp/v2/posts')
            );

            // Успешный ответ? Продолжаем.
            if (wp_remote_retrieve_response_code($response) === 200) {
                try {
                    $posts = json_decode(
                        wp_remote_retrieve_body($response),
                        false,
                        512,
                        JSON_THROW_ON_ERROR
                    );
                } catch (Exception) {
                    return;
                }

                // Перебираем 25 постов с указанной страницы
                foreach ($posts as $post) {
                    $current_post_id = post_exists($post->title->rendered);
                    if ($current_post_id === 0) {
                        $my_post = [
                            'post_type'     => 'post',
                            'post_status'   => 'pending',
                            'post_title'    => wp_strip_all_tags($post->title->rendered),
                            'post_content'  => wp_strip_all_tags($post->content->rendered),
                            'post_excerpt'  => wp_strip_all_tags($post->excerpt->rendered),
                            'post_author'   => 1,
                            'post_date'     => $post->date,
                        ];

                        // Вставляем пост.
                        $post_id = wp_insert_post($my_post);
                        wp_set_object_terms($post_id, 'Global', 'category');
                        wp_set_object_terms($post_id, 'Global', 'post_tag');
                        echo "ID: " . $post->id . " - Title: " . $post->title->rendered . " был импортирован.\n";
                    }
                }
            }
        }
    }

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

Таким образом, вы получаете номер следующей страницы, получаете ее, обрабатываете посты, затем обновляете параметры общих страниц, используя новый заголовок из этого запроса, добавляете 1 к опции следующей страницы и сохраняете ее. Если следующая страница больше, чем общее количество страниц, сбрасываете ее на 1.

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

Для того чтобы правильно обработать пагинацию при получении данных из REST API с помощью функции wp_remote_get() в WordPress, мы можем использовать стратегию поэтапного выполнения запросов. Вместо однократного запроса, который обрабатывает все страницы, мы будем запрашивать данные поэтапно, увеличивая номер страницы после каждого успешного запроса и обновляя общее количество страниц на основе заголовков ответа.

Что мы собираемся сделать

  1. Инициализация: Начнем с установки параметров для хранения текущей страницы и общего количества страниц.
  2. Получение данных: Запросим данные с текущей страницы. Если запрос успешен, обработаем полученные записи.
  3. Обработка ответов: Обновим информацию о текущей странице и общем количестве страниц.
  4. Сохранение состояния: Сохраним состояние (текущую страницу) в опции WordPress, чтобы в следующем вызове функции продолжить с правильной страницы.

Пример кода с улучшенной логикой пагинации

Вот пример кода, который осуществляет вышеописанные шаги:

public function get_posts_via_rest_api(): void
{
    // Подключение функций для работы с постами
    if (!is_admin()) {
        require_once(ABSPATH . 'wp-admin/includes/post.php');
    }

    // Получаем текущие значения из опций
    $current_page = get_option('api_current_page', 1);
    $total_pages = get_option('api_total_pages', 0);

    // Получаем данные с текущей страницы
    $response = wp_remote_get(
        add_query_arg( [
            'page' => $current_page,
            'per_page' => 25,
            'post_status' => 'publish',
        ], 'https://website-im-getting-data-from.com/wp-json/wp/v2/posts')
    );

    // Проверяем успешность запроса
    if (is_wp_error($response)) {
        error_log('Ошибка при работе с API: ' . $response->get_error_message());
        return;
    }

    // Обновляем количество страниц на основе заголовков
    $headers = wp_remote_retrieve_headers($response);
    if (isset($headers['x-wp-totalpages'])) {
        $total_pages = $headers['x-wp-totalpages'];
        update_option('api_total_pages', $total_pages);
    }

    // Обрабатываем полученные данные
    $posts = json_decode(wp_remote_retrieve_body($response), true);
    foreach ($posts as $post) {
        // Проверяем существует ли пост, если нет - создаем новый
        $current_post_id = post_exists($post['title']['rendered']);
        if ($current_post_id === 0) {
            $my_post = [
                'post_type'     => 'post',
                'post_status'   => 'pending',
                'post_title'    => wp_strip_all_tags($post['title']['rendered']),
                'post_content'  => wp_strip_all_tags($post['content']['rendered']),
                'post_excerpt'  => wp_strip_all_tags($post['excerpt']['rendered']),
                'post_author'   => 1,
                'post_date'     => $post['date'],
            ];
            // Вставка поста
            $post_id = wp_insert_post($my_post);
            wp_set_object_terms($post_id, 'Global', 'category');
            wp_set_object_terms($post_id, 'Global', 'post_tag');
            echo "ID: " . $post['id'] . " - Title: " . $post['title']['rendered'] . " has been imported.\n";
        }
    }

    // Увеличиваем номер страницы или сбрасываем его
    if ($current_page < $total_pages) {
        $current_page++;
    } else {
        $current_page = 1; // Сброс до первой страницы
    }

    // Сохраняем обновленные значения
    update_option('api_current_page', $current_page);
}

Комментарии к коду

  1. Инициализация состояния: Мы используем get_option() для получения текущей страницы и общего количества страниц. Если ранее не было сохранено значения, мы устанавливаем значение по умолчанию.

  2. Запрос данных: Используем wp_remote_get() для запроса данных с текущей страницы. Обрабатываем ошибки, если они возникли.

  3. Обработка ответов: После успешного запроса обновляем общее количество страниц и обрабатываем полученные записи, добавляя новые посты только в случае их отсутствия в базе.

  4. Управление пагинацией: Номер страницы увеличивается при каждом вызове, а если достигнут конец, сбрасываем его до 1.

Заключение

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

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

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