Диагностика проблемы с накоплением заказов статусов Отменен и Возврат в WooCommerce
Магазины на WooCommerce с большим количеством заказов сталкиваются с замедлением работы админ-панели и ростом размера базы данных из-за накопления заказов со статусами cancelled (Отменен) и refunded (Возврат). Такие заказы уже не актуальны, но остаются в базе, занимая место и замедляя отчеты. В частности, при большом количестве заказов в админке возникают задержки загрузки страниц заказов и отчетов.
Для диагностики выполните запрос к базе данных, чтобы узнать количество заказов со статусами отменен и возврат:
SELECT post_status, COUNT(*) as count FROM wp_posts
WHERE post_type = 'shop_order'
AND post_status IN ('wc-cancelled', 'wc-refunded')
GROUP BY post_status;Если количество таких заказов исчисляется тысячами, стоит автоматизировать их удаление.
Пошаговое решение: автоматическое удаление заказов по расписанию с помощью WP-Cron
1. Создаем функцию для удаления заказов со статусом отменен и возврат
Добавьте следующий код в файл functions.php вашей дочерней темы или в собственный плагин:
function wpmentor_delete_old_cancelled_refunded_orders() {
global $wpdb;
// Удаляем заказы старше 30 дней
$date_threshold = date('Y-m-d H:i:s', strtotime('-30 days'));
// Получаем ID заказов со статусом wc-cancelled или wc-refunded старше 30 дней
$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 - принудительное удаление без перемещения в корзину
}
}2. Регистрируем WP-Cron для запуска функции ежедневно
Добавьте в тот же файл следующий код для регистрации и запуска задачи ежедневно:
function wpmentor_schedule_order_cleanup() {
if (!wp_next_scheduled('wpmentor_daily_order_cleanup')) {
wp_schedule_event(time(), 'daily', 'wpmentor_daily_order_cleanup');
}
}
add_action('wp', 'wpmentor_schedule_order_cleanup');
add_action('wpmentor_daily_order_cleanup', 'wpmentor_delete_old_cancelled_refunded_orders');3. Очистка WP-Cron при деактивации
Если реализуете код в плагине, не забудьте отменить задачу при деактивации:
function wpmentor_deactivate_order_cleanup() {
$timestamp = wp_next_scheduled('wpmentor_daily_order_cleanup');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpmentor_daily_order_cleanup');
}
}
register_deactivation_hook(__FILE__, 'wpmentor_deactivate_order_cleanup');Проверка результата после внедрения
Для проверки корректности работы:
- Запустите функцию вручную, вызвав
wpmentor_delete_old_cancelled_refunded_orders()черезwp shellили добавив временный вызов вfunctions.php. - Проверьте, что заказы старше 30 дней со статусом отменен и возврат удалились.
- В админке WooCommerce проверьте, что заказы с этими статусами отсутствуют или их количество уменьшилось.
- Проверьте логи ошибок сервера на предмет ошибок удаления.
Можно также вывести количество удаленных заказов в лог:
function wpmentor_delete_old_cancelled_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",
$date_threshold
));
if (empty($order_ids)) {
error_log('No old cancelled or refunded orders to delete');
return;
}
foreach ($order_ids as $order_id) {
wp_delete_post($order_id, true);
error_log('Deleted order ID: ' . $order_id);
}
}Частые ошибки и как их исправить
- Ничего не удаляется: Проверьте правильность статусов заказов. WooCommerce добавляет префикс
wc-, используйте именноwc-cancelledиwc-refunded. - WP-Cron не срабатывает: Убедитесь, что на сайте посещают страницы — WP-Cron зависит от трафика. Для надежности настройте системный Cron или плагин WP Crontrol для ручного запуска событий.
- Удаление не полное, остаются метаданные: Функция
wp_delete_postудаляет все связанные записи, но если есть кэш или сторонние плагины — очистите кэш. - Проблемы с правами доступа: Код должен выполняться от имени администратора или с достаточными правами. Размещайте в плагине или functions.php, протестируйте на локальной копии.
Практические советы по безопасности и производительности
- Не удаляйте заказы без резервных копий. Перед активацией функции сделайте бэкап базы данных.
- Ограничьте удаление заказов старше определенного срока. В нашем примере — 30 дней, но вы можете увеличить или уменьшить.
- Оптимизируйте запрос удаления по пакетам. Если заказов очень много, удаляйте партиями по 50-100 заказов, чтобы избежать таймаутов.
- Для критически загруженных сайтов используйте системный Cron. WP-Cron зависит от посещаемости и может срабатывать с задержкой.
- Добавьте логирование. Для отслеживания работы скрипта используйте error_log или внешние сервисы мониторинга.
Сравнение решений: плагин vs собственный код
| Критерий | Собственный код | Плагин (например, Advanced Database Cleaner) |
|---|---|---|
| Гибкость настроек | Полный контроль, можно адаптировать под свои нужды | Ограничена интерфейсом плагина |
| Ресурсоемкость | Минимальная, выполняется быстро по расписанию | Может нагружать сайт при сканировании базы |
| Удобство | Требуется знание PHP, настройка вручную | Интуитивный интерфейс, подходит новичкам |
| Безопасность | Зависит от качества кода разработчика | Проверяется автором плагина, но зависит от обновлений |
| Поддержка | Ваша ответственность | Обычно есть поддержка и обновления |