Диагностика задачи: зачем и когда нужно удалять заказы автоматически
В интернет-магазинах на WooCommerce база заказов быстро разрастается, что влияет на производительность и усложняет администрирование. Часто требуется автоматически удалять заказы с определённым статусом (например, отменённые или «ожидающие») старше определённого времени, чтобы освободить место в базе и упростить отчёты.
Как понять, что эта задача актуальна:
- Админка WooCommerce замедляется при загрузке списка заказов.
- В базе данных копятся тысячи неактивных заказов с статусом «отменён» или «ожидает оплаты».
- Регулярный ручной труд по очистке заказов занимает много времени.
Подготовка: проверка и резервное копирование
Перед автоматизацией удаления заказов обязательно сделайте резервную копию базы данных. Удаление — необратимая операция.
Проверьте текущие статусы заказов в базе, например через SQL-запрос:
SELECT DISTINCT post_status FROM wp_posts WHERE post_type = 'shop_order';Типичные статусы: wc-completed, wc-cancelled, wc-pending, wc-failed, wc-processing и др.
Пошаговое решение: создание крона для удаления заказов
1. Создаём функцию удаления заказов по статусу и времени
Добавьте следующий код в файл functions.php вашей дочерней темы или в отдельный плагин:
function wpmarket_delete_old_orders() {
$statuses_to_delete = array('wc-cancelled', 'wc-failed'); // статусы для удаления
$days_old = 30; // удалять заказы старше 30 дней
$date = new DateTime();
$date->modify('-' . $days_old . ' days');
$date_str = $date->format('Y-m-d H:i:s');
$args = array(
'post_type' => 'shop_order',
'post_status' => $statuses_to_delete,
'date_query' => array(
array(
'column' => 'post_date',
'before' => $date_str,
),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$orders = get_posts($args);
if (!empty($orders)) {
foreach ($orders as $order_id) {
wp_delete_post($order_id, true); // true — удаление без корзины
}
}
}2. Регистрируем событие WP-Cron для автоматизации
Добавьте в functions.php:
if (!wp_next_scheduled('wpmarket_daily_delete_orders')) {
wp_schedule_event(time(), 'daily', 'wpmarket_daily_delete_orders');
}
add_action('wpmarket_daily_delete_orders', 'wpmarket_delete_old_orders');Этот код инициирует запуск функции wpmarket_delete_old_orders раз в сутки.
3. Очистка при деактивации (если добавляете код в плагин)
Для плагина добавьте хук деактивации, чтобы отменить крон:
register_deactivation_hook(__FILE__, function() {
$timestamp = wp_next_scheduled('wpmarket_daily_delete_orders');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wpmarket_daily_delete_orders');
}
});Проверка результата после внедрения
- Запустите функцию вручную для теста:
wpmarket_delete_old_orders();или через WP-CLI:
wp eval 'wpmarket_delete_old_orders();'- Проверьте, что старые заказы с нужными статусами удалились через админку WooCommerce в разделе "Заказы".
- Проверьте базу данных, запросом:
SELECT ID, post_status, post_date FROM wp_posts WHERE post_type = 'shop_order' AND post_status IN ('wc-cancelled', 'wc-failed') AND post_date < DATE_SUB(NOW(), INTERVAL 30 DAY);Результат должен быть пустым.
Частые ошибки и как их исправить
- Ничего не удаляется: Проверьте, что статусы точно совпадают с теми, что в базе (с префиксом
wc-). - Удаляются не те заказы: Убедитесь, что в
$statuses_to_deleteуказаны только нужные статусы. - WP-Cron не срабатывает: Проверьте, что на сайте посещения есть или настройте системный cron для запуска WP-Cron (
wp cron event run --due-nowчерез WP-CLI). - Проблемы с правами: Функция
wp_delete_postтребует прав администратора, убедитесь, что код выполняется с нужными правами.
Практические советы по безопасности и производительности
- Удаление большого количества заказов за один проход может сильно нагрузить базу. Если ожидается много заказов — делайте удаление порциями, например по 100 заказов за раз.
- Регулярно создавайте резервные копии базы, особенно перед изменениями в автоматизации.
- Используйте плагин Clearfy Pro для оптимизации базы и удаления мусора, если нужно комплексное решение.
- Для мониторинга cron-событий полезен плагин WP Crontrol.
Дополнительно: удаление заказов порциями с логированием
function wpmarket_delete_old_orders_batch() {
$statuses_to_delete = array('wc-cancelled', 'wc-failed');
$days_old = 30;
$batch_size = 100;
$date = new DateTime();
$date->modify('-' . $days_old . ' days');
$date_str = $date->format('Y-m-d H:i:s');
$args = array(
'post_type' => 'shop_order',
'post_status' => $statuses_to_delete,
'date_query' => array(
array('column' => 'post_date', 'before' => $date_str),
),
'posts_per_page' => $batch_size,
'fields' => 'ids',
);
$orders = get_posts($args);
if (!empty($orders)) {
foreach ($orders as $order_id) {
wp_delete_post($order_id, true);
}
error_log('Deleted ' . count($orders) . ' old orders');
} else {
error_log('No old orders to delete');
}
}Такой подход уменьшит нагрузку и позволит отслеживать процесс в логах сервера.