wpcontrol.ru wordpress WPControl.ru

Автоматическое удаление отменённых и возвращённых заказов в WooCommerce

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

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

Однако стандартный WooCommerce не предлагает встроенного способа автоматического удаления заказов по статусам и дате. Поэтому задача — автоматизировать этот процесс с помощью кода.

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

1. Добавление пользовательской задачи в WP-Cron

Создадим в functions.php вашей темы или в плагине следующий код, который будет запускать удаление заказов ежедневно:

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

2. Обработка события удаления заказов

Подпишемся на событие и добавим функцию удаления заказов со статусами cancelled и refunded старше 30 дней:

add_action('daily_order_cleanup_event', 'delete_old_cancelled_and_refunded_orders');
function delete_old_cancelled_and_refunded_orders() {
    global $wpdb;
    $date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));

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

    if (empty($order_ids)) {
        return;
    }

    foreach ($order_ids as $order_id) {
        wp_delete_post($order_id, true); // true — удаление без возможности восстановления
    }
}

3. Очистка задачи при деактивации плагина или темы

Чтобы не оставлять запланированные задачи, добавьте удаление расписания при отключении:

register_deactivation_hook(__FILE__, 'remove_daily_order_cleanup_schedule');
function remove_daily_order_cleanup_schedule() {
    $timestamp = wp_next_scheduled('daily_order_cleanup_event');
    if ($timestamp) {
        wp_unschedule_event($timestamp, 'daily_order_cleanup_event');
    }
}

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

  • Проверьте наличие запланированной задачи через плагин WP Crontrol — должна появиться задача daily_order_cleanup_event.
  • Добавьте тестовый заказ со статусом cancelled или refunded с датой старше 30 дней в базе (через phpMyAdmin или SQL-запрос).
  • Запустите вручную хук из WP Crontrol или измените дату запуска задачи на текущее время, чтобы проверить удаление.
  • Убедитесь, что заказ удалён без ошибок и в базе не осталось связанных записей.

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

  • Заказы не удаляются: Проверьте, что статусы указаны корректно с префиксом wc-, например wc-cancelled. Без wc- статусы не найдутся.
  • Задача WP-Cron не запускается: На некоторых хостингах WP-Cron требует посещения сайта или настройки реального cron. Проверьте работу WP-Cron через плагин WP Crontrol.
  • Удаление происходит с ошибками прав доступа: Убедитесь, что пользователь, под которым выполняется PHP, имеет права на удаление записей в базе.
  • Память или время выполнения скрипта исчерпывается: Если много заказов, делайте удаление партиями по 50-100 заказов за раз.

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

  • Резервное копирование: Перед автоматическим удалением регулярно делайте резервные копии базы данных, чтобы избежать потери важных данных.
  • Удаление по партиям: Для больших магазинов модифицируйте функцию удаления, чтобы обрабатывать заказы пакетами, например, по 50 штук, с помощью аргумента LIMIT в SQL.
  • Логирование: Добавьте логирование удалённых заказов в файл, чтобы отслеживать процесс и возможные ошибки:
function delete_old_cancelled_and_refunded_orders() {
    global $wpdb;
    $date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));
    $order_ids = $wpdb->get_col($wpdb->prepare(
        "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order' 
         AND post_status IN ('wc-cancelled', 'wc-refunded') 
         AND post_date < %s LIMIT 50",
         $date_threshold
    ));
    if (empty($order_ids)) {
        return;
    }
    $log_file = WP_CONTENT_DIR . '/order_cleanup.log';
    foreach ($order_ids as $order_id) {
        if (wp_delete_post($order_id, true)) {
            error_log("Deleted order ID: {$order_id}\n", 3, $log_file);
        } else {
            error_log("Failed to delete order ID: {$order_id}\n", 3, $log_file);
        }
    }
}

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

СпособПлюсыМинусы
Ручное удаление через админкуПростота, не требует кодаТрудоёмко при большом количестве заказов
SQL-запросы в базеБыстро, можно настроить сложные условияРиск ошибок, требуется осторожность, нет автоматизации
Автоматизация через WP-Cron и PHPАвтоматический процесс, гибкость настройки, безопасно при правильной реализацииТребует знаний PHP, настройка WP-Cron
×
WordPress
дай сайту суперсилу!

Скидки на топовые темы и плагины

Активировать суперсилу ⋙