Диагностика проблемы: зачем удалять отменённые и возвращённые заказы
В крупных интернет-магазинах на 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 |