Диагностика проблемы: зачем удалять товары без остатков и заказов
С течением времени в WooCommerce накапливаются товары, которые не продаются, не имеют остатков на складе и не участвуют в заказах. Такие записи занимают базу данных, замедляют админку и усложняют управление магазином. Автоматизация удаления таких товаров поможет держать каталог в порядке и улучшить производительность.
Как определить товары для удаления
Для удаления нам нужны товары, у которых одновременно:
- Количество на складе (stock quantity) равно 0 или NULL
- Нет связанных заказов в статусах обработки, завершен и т.п.
В WooCommerce товары — это тип записи product, а остатки хранятся в метаполе _stock. Заказы и их позиции — отдельная сущность, для проверки заказов с товаром нужно проверить таблицу woocommerce_order_items и woocommerce_order_itemmeta.
Пошаговое решение: код для автоматического удаления
1. Запрос товаров без остатков
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_stock',
'value' => 0,
'compare' => '=',
'type' => 'NUMERIC',
],
],
'fields' => 'ids',
];
$products = get_posts($args);2. Проверка заказов с этими товарами
Чтобы проверить, есть ли у товара заказы, используем прямой SQL-запрос по таблицам WooCommerce:
global $wpdb;
$products_to_delete = [];
foreach ($products as $product_id) {
$order_exists = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$wpdb->prefix}woocommerce_order_items AS oi
INNER JOIN {$wpdb->prefix}woocommerce_order_itemmeta AS oim ON oi.order_item_id = oim.order_item_id
INNER JOIN {$wpdb->posts} AS p ON oi.order_id = p.ID
WHERE oim.meta_key = '_product_id' AND oim.meta_value = %d
AND p.post_status IN ('wc-processing', 'wc-completed', 'wc-on-hold')",
$product_id
));
if (!$order_exists) {
$products_to_delete[] = $product_id;
}
}3. Удаление товаров
Удаляем товары программно, используя wp_delete_post() с параметром true для безвозвратного удаления:
foreach ($products_to_delete as $product_id) {
wp_delete_post($product_id, true);
}Как запустить автоматизацию на регулярной основе
Добавьте функцию удаления в хук планировщика WP-Cron, чтобы запускать ежедневно или раз в неделю:
function wc_delete_out_of_stock_products() {
// Здесь код из предыдущих шагов
}
if (!wp_next_scheduled('wc_delete_out_of_stock_products_hook')) {
wp_schedule_event(time(), 'daily', 'wc_delete_out_of_stock_products_hook');
}
add_action('wc_delete_out_of_stock_products_hook', 'wc_delete_out_of_stock_products');Проверка результата после внедрения
1. В админке WooCommerce проверьте, что исчезли товары с нулевыми остатками и без заказов.
2. Запустите вручную функцию (через WP-CLI или временно вызвав в коде) и проверьте логи ошибок.
3. Используйте запрос к базе данных, чтобы убедиться, что товары с остатками 0 и без заказов отсутствуют.
Частые ошибки и как их исправить
- Удаляются товары с активными заказами — проверьте корректность SQL-запроса и статусы заказов.
- Не удаляются товары — убедитесь, что функция вызывается, нет ограничений по правам, нет ошибок в коде.
- Производительность падает при большом количестве товаров — добавьте пагинацию запросов и удаление партиями.
Практические советы по безопасности и производительности
- Перед удалением делайте резервную копию базы данных.
- Запускайте удаление в низкую нагрузку сервера.
- Логируйте ID удалённых товаров для аудита.
- Для больших магазинов используйте WP-CLI команду, чтобы избежать ограничений по времени выполнения.
Сравнение способов удаления товаров без остатков и заказов
| Метод | Плюсы | Минусы | Рекомендуется для |
|---|---|---|---|
| Ручное удаление в админке | Простота, контроль | Трудозатратно, риск пропустить товары | Магазины с небольшим количеством товаров |
| Плагин для очистки товаров | Автоматизация, удобство | Зависимость от стороннего кода, может быть платным | Средние магазины |
| Кастомный код с WP-Cron | Полный контроль, гибкость | Требуется разработка и тестирование | Крупные магазины, разработчики |