Почему может потребоваться автоматическое удаление заказов в WooCommerce
В интернет-магазинах на WooCommerce накапливается большое количество заказов, в том числе с неактивным статусом, например, отменённые или не оплаченные. Это может замедлять работу админки, увеличивать размер базы данных и негативно влиять на производительность. Автоматическое удаление таких заказов по истечении заданного времени помогает поддерживать базу данных в порядке без ручного вмешательства.
Диагностика проблемы: как понять, что нужно чистить заказы
Для начала проверьте, сколько заказов с разными статусами хранится в базе. Для этого можно использовать SQL-запрос в phpMyAdmin или в консоли:
SELECT post_status, COUNT(*) as count FROM wp_posts WHERE post_type = 'shop_order' GROUP BY post_status;Обратите внимание на статусы wc-cancelled, wc-failed, wc-pending и wc-on-hold. Если их количество исчисляется тысячами и вы уверены, что старые заказы с такими статусами не нужны, можно настроить автоматическое удаление.
Пошаговое решение: автоматическое удаление заказов по статусу и возрасту
1. Создаем функцию удаления заказов
Вставьте следующий код в файл functions.php вашей дочерней темы или в отдельный плагин. Код удаляет заказы старше 30 дней со статусами 'cancelled' и 'failed'.
function wpskills_delete_old_wc_orders() {
$statuses_to_delete = array('wc-cancelled', 'wc-failed');
$days_old = 30;
$date_query = array(
'column' => 'post_date',
'before' => date('Y-m-d H:i:s', strtotime("-{$days_old} days")),
);
$args = array(
'post_type' => 'shop_order',
'post_status' => $statuses_to_delete,
'date_query' => array($date_query),
'posts_per_page' => -1,
'fields' => 'ids',
'no_found_rows' => true,
'update_post_meta_cache' => false,
'update_post_term_cache' => false,
);
$query = new WP_Query($args);
if ($query->have_posts()) {
foreach ($query->posts as $order_id) {
wp_delete_post($order_id, true); // true - без помещения в корзину
}
}
}
2. Создаем WP-Cron задачу для регулярного запуска
Добавьте код для регистрации и запуска задачи ежесуточно:
// Регистрируем событие при активации темы или плагина
if (!wp_next_scheduled('wpskills_daily_delete_old_orders')) {
wp_schedule_event(time(), 'daily', 'wpskills_daily_delete_old_orders');
}
// Хук на выполнение задачи
add_action('wpskills_daily_delete_old_orders', 'wpskills_delete_old_wc_orders');
// Очистка при деактивации (если делаете плагин)
function wpskills_deactivate_cleanup() {
$timestamp = wp_next_scheduled('wpskills_daily_delete_old_orders');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpskills_daily_delete_old_orders');
}
}
// register_deactivation_hook(__FILE__, 'wpskills_deactivate_cleanup');
Как проверить, что автоматическое удаление работает
- Зайдите в WooCommerce → Заказы и посчитайте количество заказов с нужными статусами.
- Измените дату нескольких заказов в базе на старше 30 дней вручную (через phpMyAdmin в таблице
wp_postsв полеpost_date). - Запустите функцию вручную, вызвав
wpskills_delete_old_wc_orders();либо дождитесь планового запуска. - Проверьте, что старые заказы удалились из базы и в админке.
- Для отладки можно добавить
error_log()или записи в лог для контроля удаления.
Частые ошибки и способы их устранения
- Заказы не удаляются: проверьте, что статусы указаны точно с префиксом
wc-. Используйте var_dump или error_log для отладки WP_Query. - Функция запускается слишком редко или не запускается: убедитесь, что WP-Cron включён и что на сайт заходят посетители, запускающие cron. Альтернативно используйте системный cron для вызова
wp-cron.php. - Удаление без восстановления: используйте
wp_delete_post($id, true);для полного удаления без корзины, иначе заказы будут попадать в корзину. - Проблемы с правами доступа в БД: убедитесь, что пользователь БД имеет права на удаление записей.
Практические советы по безопасности и производительности
- Перед удалением желательно делать резервную копию базы.
- Не удаляйте заказы, которые могут понадобиться для отчётности или бухгалтерии.
- Ограничьте количество заказов, обрабатываемых за один запуск, чтобы не перегружать сервер. Для этого добавьте параметр
'posts_per_page' => 100и запускайте задачу чаще. - Если база большая, используйте прямые SQL-запросы для удаления, но с осторожностью.
- Для отслеживания работы cron используйте плагины типа WP Crontrol.
Сравнение подходов к автоматическому удалению заказов
| Метод | Плюсы | Минусы |
|---|---|---|
| WP_Query + wp_delete_post() | Безопасный, учитывает все связанные данные | Медленнее на больших базах |
| Прямой SQL DELETE | Очень быстро на больших базах | Риск нарушить связи, нужно удалять метаданные вручную |
| Плагины очистки | Простота настройки, интерфейс | Зависимость от стороннего кода, возможные уязвимости |