WooCommerce: как автоматически удалять закрытые и отменённые заказы для оптимизации базы данных

Почему важно удалять закрытые и отменённые заказы в WooCommerce

С увеличением количества заказов в интернет-магазине WooCommerce база данных растёт, что влияет на производительность и время резервного копирования. Закрытые (completed) и отменённые (cancelled) заказы, которые уже не нужны для аналитики или бухгалтерии, могут занимать лишнее место. Автоматизация удаления таких заказов помогает поддерживать базу в оптимальном состоянии.

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

Для начала нужно проверить количество заказов по статусам. Для этого можно использовать SQL-запрос к базе данных:

SELECT post_status, COUNT(*) AS count FROM wp_posts WHERE post_type = 'shop_order' GROUP BY post_status;

Если количество заказов со статусами wc-completed и wc-cancelled измеряется тысячами и многие из них старше 6-12 месяцев, это признак, что стоит рассмотреть очистку.

Пошаговое решение: автоматическое удаление заказов через WP-Cron

1. Создание функции удаления старых заказов

Добавьте следующий код в файл functions.php вашей дочерней темы или в кастомный плагин:

function wpengine_delete_old_orders() {
    global $wpdb;
    $interval = 30; // дней
    $date_threshold = date('Y-m-d H:i:s', strtotime("-{$interval} days"));

    // Получаем ID заказов со статусом "completed" и "cancelled" старше $interval дней
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
         WHERE post_type = 'shop_order' 
         AND post_status IN ('wc-completed', 'wc-cancelled') 
         AND post_date < %s",
         $date_threshold
    ));

    if (!empty($order_ids)) {
        foreach ($order_ids as $order_id) {
            wp_delete_post($order_id, true); // Полное удаление без перемещения в корзину
        }
    }
}

2. Регистрация WP-Cron задачи

Добавьте в functions.php следующий код для запуска задачи ежедневно:

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

add_action('wpengine_daily_order_cleanup', 'wpengine_delete_old_orders');

3. Опционально: создание WP-CLI команды для ручного запуска

if (defined('WP_CLI') && WP_CLI) {
    WP_CLI::add_command('wpengine delete_old_orders', function() {
        wpengine_delete_old_orders();
        WP_CLI::success('Old completed and cancelled orders deleted.');
    });
}

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

После установки кода:

  • Проверьте наличие запланированной задачи в разделе wp cron event list через WP-CLI.
  • Запустите вручную через WP-CLI wp wpengine delete_old_orders и убедитесь, что заказы удаляются.
  • Повторно выполните SQL-запрос из раздела диагностики и проверьте уменьшение количества заказов со статусами wc-completed и wc-cancelled.
  • Отслеживайте логи ошибок сервера или WordPress для исключения проблем с удалением.

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

  • Удаление не происходит: Проверьте, активна ли WP-Cron и правильно ли зарегистрирована задача. Для сайтов с низкой посещаемостью стоит настроить системный cron вместо WP-Cron.
  • Удаляются не те заказы: Проверьте правильность статусов и даты в SQL-запросе. Статусы должны быть с префиксом wc-.
  • Ошибка превышения времени выполнения: При большом количестве заказов разделите удаление на партии, например, по 100 заказов за один запуск.
  • Удаление нарушает аналитику: Обязательно убедитесь, что удаление не противоречит требованиям бухгалтерии и аналитики вашего магазина.

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

  • Используйте wp_delete_post($order_id, true) для полного удаления, чтобы не перегружать корзину.
  • Добавьте проверку nonce или ограничьте права пользователей, если будете создавать интерфейс для запуска очистки вручную.
  • При большом объёме заказов используйте пакетную обработку, чтобы избежать тайм-аутов:
function wpengine_delete_old_orders_batch($batch_size = 100) {
    global $wpdb;
    $interval = 30;
    $date_threshold = date('Y-m-d H:i:s', strtotime("-{$interval} days"));

    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} 
         WHERE post_type = 'shop_order' 
         AND post_status IN ('wc-completed', 'wc-cancelled') 
         AND post_date < %s 
         LIMIT %d",
         $date_threshold, $batch_size
    ));

    if (!empty($order_ids)) {
        foreach ($order_ids as $order_id) {
            wp_delete_post($order_id, true);
        }
        return count($order_ids);
    }
    return 0;
}
  • Для автоматизации пакетной обработки можно запускать функцию несколько раз с интервалом.
  • Резервное копирование базы перед внедрением обязательно.

Сравнение способов удаления заказов

МетодПлюсыМинусыКомпромисс
Ручное удаление через админкуПростота, контрольТрудозатратно, риск ошибкиПодходит для редких случаев
WP-Cron с пакетной обработкойАвтоматизация, масштабируемостьЗависит от WP-Cron, возможны тайм-аутыОптимально для средних магазинов
Системный cron + WP-CLIНадёжно, быстро, вне зависимости от трафикаТребует доступа к серверуЛучше для крупных проектов
Плагины очистки базыУдобство, дополнительные функцииРиск конфликтов, нагрузкаИспользовать с осторожностью, проверять совместимость
Как создать собственный виджет в WordPress: подробное руководство с примерами
22.11.2025
Как использовать WPCommunity для создания социальной сети на WordPress
06.01.2026
WooCommerce: автоматическое удаление товаров без заказов за заданный период
17.07.2026
Как использовать REST API в WordPress для создания плагинов
25.11.2025
Как автоматизировать удаление старого и неиспользуемого кода в WordPress
25.02.2026