Диагностика проблемы с накоплением заказов в WooCommerce
Магазины на WooCommerce часто сталкиваются с проблемой накопления отменённых и неоплаченных заказов. Это приводит к раздуванию базы данных, замедлению админки и потенциальным ошибкам при генерации отчетов. Особенно актуально для магазинов с высоким трафиком и большим количеством заказов.
Чтобы проверить, есть ли проблема, можно выполнить SQL-запрос в базе данных:
SELECT post_status, COUNT(*) as total FROM wp_posts WHERE post_type = 'shop_order' GROUP BY post_status;Если количество заказов со статусами wc-cancelled и wc-pending превышает несколько тысяч, стоит задуматься об автоматизации очистки.
Пошаговое решение: автоматическое удаление заказов по срокам
1. Добавляем планировщик задач (WP-Cron)
В functions.php или в собственном плагине регистрируем событие для ежедневного запуска удаления заказов:
if ( ! wp_next_scheduled( 'wpcoder_delete_old_orders' ) ) {
wp_schedule_event( time(), 'daily', 'wpcoder_delete_old_orders' );
}2. Создаем функцию удаления заказов
Функция будет искать старые отменённые и неоплаченные заказы и удалять их:
function wpcoder_delete_old_orders() {
global $wpdb;
// Период хранения в днях
$days_to_keep_cancelled = 30;
$days_to_keep_pending = 7;
$date_cancelled = date( 'Y-m-d H:i:s', strtotime( "-{$days_to_keep_cancelled} days" ) );
$date_pending = date( 'Y-m-d H:i:s', strtotime( "-{$days_to_keep_pending} days" ) );
// Получаем ID отменённых заказов старше 30 дней
$cancelled_orders = $wpdb->get_col( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_status = 'wc-cancelled' AND post_date < %s",
$date_cancelled
) );
// Получаем ID неоплаченных заказов старше 7 дней
$pending_orders = $wpdb->get_col( $wpdb->prepare(
"SELECT ID FROM {$wpdb->posts} WHERE post_type = 'shop_order' AND post_status = 'wc-pending' AND post_date < %s",
$date_pending
) );
$orders_to_delete = array_merge( $cancelled_orders, $pending_orders );
if ( ! empty( $orders_to_delete ) ) {
foreach ( $orders_to_delete as $order_id ) {
wp_delete_post( $order_id, true ); // true — без перемещения в корзину
}
}
}3. Добавляем хук для запуска функции по расписанию
add_action( 'wpcoder_delete_old_orders', 'wpcoder_delete_old_orders' );Проверка результата после внедрения
Чтобы проверить, что удаление сработало:
- В админке WooCommerce перейдите в Заказы и фильтруйте по статусам "Отменён" и "Ожидает оплаты". Количество должно уменьшиться спустя сутки после срабатывания WP-Cron.
- Можно вручную вызвать функцию из консоли WP-CLI:
wp eval 'wpcoder_delete_old_orders();'и проверить, что заказы удалились сразу. - Проверить логи сервера и/или плагинов для мониторинга ошибок.
Частые ошибки и как их исправить
- WP-Cron не срабатывает: если сайт мало посещаемый, WP-Cron может не запускаться. Решение — настроить системный cron на сервере для вызова
wp-cron.phpили использовать плагин для управления cron. - Заказы не удаляются: проверьте, что функция
wp_delete_post()вызывается с флагомtrue, чтобы удаление было безвозвратным. Также убедитесь, что у пользователя, под которым выполняется скрипт, есть права на удаление. - Удаляются нужные заказы: проверьте даты и статусы в запросах. Можно добавить логи для отладки, например
error_log().
Практические советы по безопасности и производительности
- Используйте транзакции или батчи при удалении большого количества заказов, чтобы избежать превышения лимита выполнения скрипта.
- Создайте резервную копию базы перед внедрением, особенно на живом сайте.
- Ограничьте количество заказов для удаления за один запуск (например, по 100), чтобы не перегружать сервер.
- Для крупных магазинов лучше переносить устаревшие заказы в отдельную таблицу или архив, а не удалять сразу.
Сравнение вариантов автоматического удаления заказов
| Метод | Плагин | Код | Компромисс |
|---|---|---|---|
| Удаление заказов | Плагины типа "Advanced Order Cleanup" | Собственный код с WP-Cron | Плагины удобны, но могут нагружать сайт; код гибкий, требует поддержки |
| Настройка расписания | WP-Cron или системный Cron | WP-Cron + хуки | WP-Cron зависит от трафика, системный cron надежнее |