Диагностика проблемы: зачем удалять товары без активных заказов
В больших магазинах на WooCommerce часто накапливаются товары, которые не продаются и не имеют связанных с ними заказов. Это приводит к избыточной нагрузке на базу данных, усложняет навигацию и снижает производительность сайта. Автоматическое удаление таких товаров помогает поддерживать каталог в актуальном состоянии без лишних затрат времени.
Как определить товары без активных заказов
Под активными заказами понимаются заказы в статусах, означающих потенциальную или завершенную покупку товара (например, 'processing', 'completed'). Если товар не связан ни с одним таким заказом, его можно считать неактивным.
Для диагностики можно использовать следующий SQL-запрос, который покажет ID товаров без активных заказов:
SELECT p.ID, p.post_title FROM wp_posts p WHERE p.post_type = 'product' AND NOT EXISTS ( SELECT 1 FROM wp_woocommerce_order_items oi JOIN wp_woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id JOIN wp_posts o ON o.ID = oi.order_id WHERE oi.order_item_type = 'line_item' AND o.post_status IN ('wc-processing', 'wc-completed') AND oim.meta_key = '_product_id' AND oim.meta_value = p.ID );Запустите этот запрос в phpMyAdmin или другом инструменте для работы с базой данных, чтобы получить список товаров-кандидатов на удаление.
Пошаговое решение: автоматическое удаление товаров без активных заказов
1. Создаем WP-Cron задачу
Добавьте в файл functions.php вашей темы или в плагин следующий код для регистрации еженедельного события:
if ( ! wp_next_scheduled( 'wpc_remove_inactive_products' ) ) { wp_schedule_event( time(), 'weekly', 'wpc_remove_inactive_products' );}2. Реализуем функцию удаления товаров
Функция подключается к событию WP-Cron и удаляет товары без активных заказов:
add_action( 'wpc_remove_inactive_products', 'wpc_delete_products_without_active_orders' );function wpc_delete_products_without_active_orders() { global $wpdb; $inactive_products = $wpdb->get_col( "SELECT p.ID FROM {$wpdb->posts} p WHERE p.post_type = 'product' AND NOT EXISTS ( SELECT 1 FROM {$wpdb->prefix}woocommerce_order_items oi JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id JOIN {$wpdb->posts} o ON o.ID = oi.order_id WHERE oi.order_item_type = 'line_item' AND o.post_status IN ('wc-processing', 'wc-completed') AND oim.meta_key = '_product_id' AND oim.meta_value = p.ID ) " ); if ( empty( $inactive_products ) ) { return; // Нет товаров для удаления } foreach ( $inactive_products as $product_id ) { wp_delete_post( $product_id, true ); // Принудительное удаление без корзины }}3. Проверяем работу WP-Cron
Для отладки можно вызвать функцию вручную, например, через консоль WP-CLI:
wp eval 'wpc_delete_products_without_active_orders();'Или временно заменить wp_schedule_event на более частый интервал и отслеживать логи.
Проверка результата после внедрения
- Запустите SQL-запрос из раздела диагностики до и после удаления: количество товаров без заказов должно уменьшиться до нуля.
- Проверьте, что товары действительно удалены из панели WooCommerce.
- Просмотрите логи сервера на предмет ошибок во время выполнения WP-Cron.
Частые ошибки и как их исправить
- Товары не удаляются: Убедитесь, что WP-Cron работает. Проверьте, что событие
wpc_remove_inactive_productsзапланировано вwp-cron. - Удаляются товары с активными заказами: Проверьте правильность SQL-запроса, убедитесь, что статусы заказов прописаны верно ('wc-processing', 'wc-completed').
- Производительность падает при удалении: Если товаров много, удаляйте партиями, например по 50 штук за раз, используя LIMIT и OFFSET.
Практические советы по безопасности и производительности
- Перед удалением сделайте резервную копию базы данных.
- Для больших магазинов рекомендуем разбивать удаление на пачки с помощью
LIMITи запускать cron чаще. - Добавьте логирование удаленных товаров в отдельный файл для аудита.
- Чтобы избежать случайного удаления, можно сначала помечать товары мета-полем, а потом удалять через неделю.
Таблица сравнения способов удаления товаров без заказов
| Метод | Преимущества | Недостатки |
|---|---|---|
| Ручной SQL-запрос + удаление через админку | Простота, контроль | Трудоемко, риск ошибки |
| WP-Cron с кастомной функцией (код) | Автоматизация, гибкость | Требует настройки, возможны проблемы с WP-Cron |
| Плагины очистки WooCommerce | Готовые решения, UI | Может быть избыточно, не всегда гибко |