Диагностика проблемы с накоплением заказов в WooCommerce
Магазины на WooCommerce часто сталкиваются с проблемой, когда база данных разрастается из-за большого количества «отменённых» и «завершённых» заказов, которые уже не нужны для повседневной работы. Это замедляет работу сайта, увеличивает нагрузку на сервер и усложняет администрирование.
Чтобы убедиться в проблеме, нужно проверить таблицу wp_posts (или с префиксом вашей БД) на предмет количества записей с типом shop_order и статусами cancelled (если есть) и completed. Это можно сделать через phpMyAdmin или с помощью WP-CLI:
wp db query "SELECT post_status, COUNT(*) as count FROM wp_posts WHERE post_type = 'shop_order' GROUP BY post_status;"Если количество «completed» или «cancelled» заказов исчисляется тысячами и вы не нуждаетесь в хранении их истории, стоит автоматизировать процесс удаления.
Пошаговое решение: автоматическое удаление заказов по статусу
1. Создание функции удаления заказов
Чтобы безопасно удалить заказы с определённым статусом, используем WP_Query и встроенные функции WooCommerce:
function wc_delete_orders_by_status( $status = 'completed', $days_old = 30 ) {
$date = date( 'Y-m-d H:i:s', strtotime( "-{$days_old} days" ) );
$args = [
'post_type' => 'shop_order',
'post_status' => $status,
'date_query' => [
[
'column' => 'post_date',
'before' => $date,
]
],
'posts_per_page' => 100,
'fields' => 'ids',
];
$query = new WP_Query( $args );
if ( ! $query->have_posts() ) {
return 0;
}
foreach ( $query->posts as $order_id ) {
wp_delete_post( $order_id, true );
}
return count( $query->posts );
}2. Настройка планового задания (WP-Cron)
Добавим регулярное задание, которое будет запускать функцию удаления заказов:
// Регистрируем событие
add_action( 'wp', function() {
if ( ! wp_next_scheduled( 'wc_delete_old_orders_event' ) ) {
wp_schedule_event( time(), 'daily', 'wc_delete_old_orders_event' );
}
} );
// Хук для выполнения удаления
add_action( 'wc_delete_old_orders_event', function() {
$deleted_completed = wc_delete_orders_by_status( 'wc-completed', 60 ); // Удаляем завершённые старше 60 дней
$deleted_cancelled = wc_delete_orders_by_status( 'wc-cancelled', 30 ); // Удаляем отменённые старше 30 дней
error_log( "Удалено завершённых заказов: {$deleted_completed}, отменённых: {$deleted_cancelled}" );
} );Обратите внимание, что статусы WooCommerce в базе начинаются с префикса wc-, например, wc-completed, wc-cancelled.
Как проверить, что удаление работает
- В phpMyAdmin или WP-CLI выполните запрос по статусам до и после запуска cron-задачи.
- Проверьте логи сервера или файл
debug.log(если включен WP_DEBUG_LOG) — там будет запись с количеством удалённых заказов. - Можно вручную запустить функцию удаления из консоли WP-CLI для теста:
wp eval 'echo wc_delete_orders_by_status("wc-completed", 1);'Эта команда удалит завершённые заказы старше 1 дня и выведет количество удалённых записей.
Частые ошибки и как их исправить
- Неправильный статус заказа: Используйте правильный статус с префиксом
wc-. Без него запрос не вернёт нужных заказов. - Отсутствие прав на удаление: Убедитесь, что код выполняется с правами администратора.
- Планировщик WP-Cron не срабатывает: Проверьте, включён ли WP-Cron и нет ли проблем с вызовом
wp-cron.php. Для отладки используйте плагин WP Crontrol. - Удаление не происходит из-за кеширования: Очистите кеш сайта и сервера после внесения изменений.
Практические советы по безопасности и производительности
- Удаляйте заказы партиями (например, по 100 штук), чтобы избежать превышения лимитов памяти и времени выполнения PHP.
- Всегда делайте резервные копии базы перед массовым удалением данных.
- Не удаляйте заказы, если они всё ещё нужны для бухгалтерии или аналитики.
- Для больших магазинов с сотнями тысяч заказов рекомендуется запускать удаление через WP-CLI, а не WP-Cron, чтобы исключить таймауты.
- Регулярно оптимизируйте таблицы базы данных после удаления (
OPTIMIZE TABLE wp_posts;), чтобы уменьшить размер и ускорить запросы.
Сравнение способов удаления заказов
| Метод | Плюсы | Минусы | Рекомендации |
|---|---|---|---|
| Ручное удаление через админку WooCommerce | Просто, не требует кода | Трудоёмко при большом количестве, не автоматизировано | Подходит для редких случаев |
| Код с WP-Cron (как в статье) | Автоматизация, гибкость, можно настроить периоды | Зависит от работы WP-Cron, возможны таймауты при больших объёмах | Оптимально для средних магазинов |
| WP-CLI скрипты | Высокая производительность, можно запускать вручную | Требует доступа к серверу, знания консоли | Рекомендуется для больших магазинов |