wpcat.ru wordpress WPCat.ru

WooCommerce: автоматическое удаление заказов по устаревшим статусам без плагинов

Диагностика проблемы: зачем удалять заказы по устаревшим статусам

В WooCommerce с течением времени накапливаются заказы, которые не имеют актуального статуса — например, отменённые, отклонённые или ожидающие оплаты за длительный период. Это увеличивает размер базы данных, замедляет работу административной панели и затрудняет поиск актуальных заказов. Удаление таких заказов вручную — трудоёмкий процесс, особенно при большом объёме.

Задача — автоматически и безопасно удалять заказы с определёнными статусами старше заданного срока без использования сторонних плагинов.

Пошаговое решение: реализация автоудаления заказов по статусу

1. Определяем, какие статусы считать устаревшими

Чаще всего имеют смысл следующие статусы: cancelled, failed, refunded, pending (если не оплачены долгое время). Можно расширить список по необходимости.

2. Создаём функцию для удаления заказов старше N дней по этим статусам

Пример кода для файла functions.php вашей темы или отдельного кастомного плагина:

function wpcat_delete_old_orders() {
    // Количество дней, по истечении которых заказы считаются устаревшими
    $days_old = 30;
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_old . ' days'));

    // Статусы заказов для удаления
    $statuses = array('cancelled', 'failed', 'refunded', 'pending');

    // Аргументы для WP_Query
    $args = array(
        'post_type'      => 'shop_order',
        'post_status'    => array_map(function($status) { return 'wc-' . $status; }, $statuses),
        'posts_per_page' => -1,
        'date_query'     => array(
            array(
                'column' => 'post_date',
                'before' => $date_threshold,
            ),
        ),
        'fields'         => 'ids',
        'no_found_rows'  => true,
    );

    $query = new WP_Query($args);

    if (!empty($query->posts)) {
        foreach ($query->posts as $order_id) {
            wp_delete_post($order_id, true); // true — безвозвратно
        }
    }
}

3. Настраиваем регулярный запуск через WP-Cron

Добавим событие, которое будет запускать функцию ежедневно:

function wpcat_schedule_delete_old_orders() {
    if (!wp_next_scheduled('wpcat_delete_old_orders_daily')) {
        wp_schedule_event(time(), 'daily', 'wpcat_delete_old_orders_daily');
    }
}
add_action('wp', 'wpcat_schedule_delete_old_orders');

add_action('wpcat_delete_old_orders_daily', 'wpcat_delete_old_orders');

Проверка результата после внедрения

1. Проверьте, что событие запланировано: в админке используйте плагин WP Crontrol или аналог для просмотра запланированных задач. Там должно быть событие wpcat_delete_old_orders_daily.

2. Создайте тестовый заказ с одним из статусов cancelled, failed или pending, выставьте дату создания более 30 дней назад (можно сделать через базу данных или изменить дату через WP-CLI).

3. Запустите событие вручную через WP Crontrol, выбрав wpcat_delete_old_orders_daily и выполнив её.

4. Проверьте, что заказ удалён из базы (через админку или запрос в базе SELECT * FROM wp_posts WHERE ID = [order_id]; — запись отсутствует).

Частые ошибки и как их исправить

  • Ошибка: заказы не удаляются. Проверьте, что функция подключена и событие WP-Cron срабатывает. На локальной среде WP-Cron может не запускаться без посещения сайта — используйте внешние Cron или запускайте вручную.
  • Ошибка: удаляются не те заказы. Проверьте, что в массиве статусов $statuses указаны правильные статусы с префиксом wc- в запросе.
  • Ошибка: удаление происходит, но остаются метаданные. Функция wp_delete_post($order_id, true) удаляет все связанные данные, но если есть сторонние плагины с кастомными таблицами, их нужно чистить отдельно.
  • Ошибка: слишком много запросов к базе. Если заказов очень много, разбейте удаление на части — добавьте параметр posts_per_page с лимитом, и делайте удаление пачками.

Практические советы по безопасности и производительности

  • Создайте резервную копию базы данных перед внедрением автоудаления заказов.
  • Используйте транзакции или дополнительную логику, чтобы не удалять заказы, связанные с активными возвратами или спорами.
  • Для больших магазинов разбивайте удаление на небольшие партии, например по 50 заказов за раз, чтобы избежать таймаутов и блокировок БД.
  • Не удаляйте заказы с важными статусами (например, «выполнен» или «обработка»), чтобы избежать потери истории продаж.
  • Для мониторинга можно добавить логирование удалённых заказов в отдельный файл для аудита.

Сравнение вариантов решения задачи

ВариантПлюсыМинусы
Использование кода в functions.php и WP-CronКонтроль, нет зависимости от плагинов, лёгкость кастомизацииТребует базовых знаний, возможны сложности с WP-Cron на локалках
Плагины для очистки WooCommerce заказовПростота настройки, готовые функции, поддержкаНагрузка на сайт, дополнительные зависимости, возможные конфликты
Удаление заказов вручную из базыПолный контроль, быстрый результатРиск ошибок, потеря данных, требует навыков SQL
×
Обнови свой WordPress!

Держи скидку 15% на премиум тему Reboot

Купить со скидкой ⋙