Диагностика проблемы: зачем удалять заказы с определенными статусами
В WooCommerce со временем накапливаются заказы со статусами "Отменен" и "Возврат". Они не влияют на продажи, но замусоривают базу данных и могут замедлять работу админ-панели и отчётов. Вручную удалять такие заказы неудобно, особенно при большом объеме продаж.
Проверить количество заказов со статусом "Отменен" и "Возврат" можно так:
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_orders_by_status( $statuses = array() ) {
if ( empty( $statuses ) ) {
return;
}
$args = array(
'post_type' => 'shop_order',
'post_status' => $statuses,
'posts_per_page' => 100,
'fields' => 'ids',
);
$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 для периодического запуска
Добавьте регистрацию задачи и хук для запуска функции с нужными статусами:
add_action( 'wpmentor_delete_cancelled_refunded_orders', 'wpmentor_cron_delete_orders' );
function wpmentor_cron_delete_orders() {
$statuses_to_delete = array( 'wc-cancelled', 'wc-refunded' );
wpmentor_delete_orders_by_status( $statuses_to_delete );
}
// Регистрируем событие при активации темы или плагина
if ( ! wp_next_scheduled( 'wpmentor_delete_cancelled_refunded_orders' ) ) {
wp_schedule_event( time(), 'daily', 'wpmentor_delete_cancelled_refunded_orders' );
}3. Удаление задачи при деактивации
Чтобы избежать накопления задач, удалите их при деактивации темы или плагина:
function wpmentor_clear_cron_on_deactivation() {
$timestamp = wp_next_scheduled( 'wpmentor_delete_cancelled_refunded_orders' );
if ( $timestamp ) {
wp_unschedule_event( $timestamp, 'wpmentor_delete_cancelled_refunded_orders' );
}
}
register_deactivation_hook( __FILE__, 'wpmentor_clear_cron_on_deactivation' );Проверка результата после внедрения
- Запустите задачу вручную, вызвав функцию
wpmentor_cron_delete_orders()через WP-CLI или временно добавив вызов вfunctions.php. - Проверьте, что заказы со статусами
wc-cancelledиwc-refundedудалены из базы. - Для проверки работы WP-Cron используйте плагин WP Crontrol — он позволит увидеть и запустить задачи вручную.
Частые ошибки и как их исправить
- Заказы не удаляются: возможно, функция wp_delete_post не вызывается из-за отсутствия прав или ошибок в коде. Проверьте логи ошибок и убедитесь, что код подключен.
- WP-Cron не срабатывает: на серверах без посещаемости WordPress задачи WP-Cron не запускаются. Решение — настроить системный cron для вызова
wp-cron.phpили использовать плагин, например WP Crontrol. - Удаляются не те заказы: проверьте правильность статусов в массиве
$statuses_to_delete. Статусы должны быть с префиксомwc-.
Практические советы по безопасности и производительности
- Удаление заказов — необратимая операция. Рекомендуется делать резервную копию базы данных перед внедрением.
- Для больших магазинов разделите удаление на партии по 100 заказов, чтобы избежать таймаутов.
- Используйте
wp_delete_post( $order_id, true )для полного удаления без перемещения в корзину. - Регулярно проверяйте логи сервера и WordPress для выявления возможных ошибок.
Сравнение методов удаления заказов
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Ручное удаление через админку | Просто, без кода | Долго, неудобно при большом объеме | Подходит для малых магазинов |
| Автоматическое удаление через WP-Cron | Полная автоматизация, регулярность | Зависит от корректной работы WP-Cron | Лучший вариант для средних и больших магазинов |
| Плагины очистки базы | Удобный интерфейс, дополнительные функции | Могут нагружать сервер, не всегда гибкие | Использовать с осторожностью, проверяя совместимость |