Диагностика проблемы: почему автоматическое удаление товаров не работает
Часто в WooCommerce возникает задача автоматически удалять товары, по которым не было заказов за определённый период. Это помогает поддерживать каталог в актуальном состоянии и ускоряет работу магазина. Однако стандартных средств для этого нет, и реализуемый код или плагины могут не работать корректно. Основные причины сбоев:
- Неправильный выбор статуса заказа для проверки (например, учитываются только
completed, а заказы в статусеprocessingигнорируются). - Отсутствие правильной фильтрации по дате — учитываются все заказы, или дата заказа не проверяется.
- Ошибки в SQL-запросах, которые не возвращают корректный список товаров.
- Кэширование, из-за которого скрипт не видит актуальные данные.
- Проблемы с правами пользователя, под которым запускается скрипт удаления.
Пошаговое решение: как правильно настроить автоматическое удаление товаров без заказов
1. Определение периода и статусов заказов
Для начала определите, за какой период товаров без заказов нужно удалять, и какие статусы заказов считать:
$period_days = 90; // Товары без заказов за последние 90 дней будут удалены
$order_statuses = array('wc-completed', 'wc-processing'); // Учесть только эти статусы
2. Получение ID товаров с заказами
Используйте WP_Query с meta-запросом по заказам и статусам, чтобы получить ID товаров, которые были в заказах за период:
$date_threshold = date('Y-m-d H:i:s', strtotime('-' . $period_days . ' days'));
$args = array(
'post_type' => 'shop_order',
'post_status' => $order_statuses,
'date_query' => array(
array(
'after' => $date_threshold,
'inclusive' => true,
),
),
'posts_per_page' => -1,
'fields' => 'ids',
);
$order_query = new WP_Query($args);
$orders_ids = $order_query->posts;
3. Получение ID товаров из заказов
Извлеките товары из заказов и составьте список ID:
$products_in_orders = array();
foreach ($orders_ids as $order_id) {
$order = wc_get_order($order_id);
if (!$order) continue;
foreach ($order->get_items() as $item) {
$product_id = $item->get_product_id();
$products_in_orders[$product_id] = true;
}
}
$products_with_orders = array_keys($products_in_orders);
4. Получение всех ID товаров и фильтрация на удаление
Получите все товары и исключите те, что были в заказах:
$all_products = get_posts(array(
'post_type' => 'product',
'posts_per_page' => -1,
'fields' => 'ids',
));
$products_to_delete = array_diff($all_products, $products_with_orders);
5. Удаление товаров
Удалите товары программно, используя wp_delete_post() с параметром true для безвозвратного удаления:
foreach ($products_to_delete as $product_id) {
wp_delete_post($product_id, true);
}
6. Автоматизация через WP-Cron
Для регулярного запуска добавьте cron задачу:
if (!wp_next_scheduled('auto_delete_unused_products')) {
wp_schedule_event(time(), 'daily', 'auto_delete_unused_products');
}
add_action('auto_delete_unused_products', function() use ($period_days, $order_statuses) {
// Весь код удаления из предыдущих шагов здесь
});
Проверка результата после внедрения
Чтобы убедиться, что удаление сработало:
- Проверьте, что на сайте исчезли товары без заказов за указанный период.
- Включите журнал ошибок WP и проверьте, нет ли ошибок при выполнении задачи.
- Выполните скрипт вручную (через вызов функции или WP-CLI), чтобы убедиться, что товары удаляются корректно.
- Проверьте, что товары, по которым были заказы, остались в каталоге.
Частые ошибки и как их исправить
- Неправильные статусы заказов: Если учитывать только
wc-completed, можно пропустить товары с заказами в статусеprocessing. Добавьте все релевантные статусы. - Не учитывается дата заказа: Без фильтра по дате удаляются товары, которые могли быть заказаны недавно.
- Отсутствие проверки на существование заказа: Используйте
wc_get_order()и проверяйте, что объект заказа неnull. - Удаление без подтверждения: При разработке используйте флаг
wp_delete_post($id, false)для перемещения в корзину, чтобы избежать потери данных. - Проблемы с правами: Запуск кода должен быть от имени администратора или пользователя с правами на удаление товаров.
Практические советы по безопасности и производительности
- Перед массовым удалением товаров сделайте резервную копию базы данных.
- Учитывайте нагрузку на сервер при запуске cron-задачи: делайте её в ночное время или разбивайте удаление на части.
- Используйте транзиенты или кеширование для хранения списка товаров с заказами, чтобы не делать тяжелые запросы каждый раз.
- Проверяйте, не зависят ли другие плагины или кастомный функционал от удаляемых товаров.
- Рассмотрите использование плагина Clearfy Pro для оптимизации базы и удаления дубликатов и неиспользуемых данных (https://wpshop.ru/plugins/clearfy?utm_source=wpengine.ru&utm_medium=article&utm_campaign=woocommerce-reshenie-problem-s-avtomaticheskim-udaleniem-tovarov-bez-zakazov).
Сравнение вариантов реализации удаления товаров
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
| Ручное удаление через админку | Удаление товаров вручную в WooCommerce | Простой способ, без кода | Неэффективно для большого каталога |
| Плагин для удаления неактивных товаров | Использование готовых плагинов | Автоматизация, удобный интерфейс | Может быть ресурсозатратным, ограниченная гибкость |
| Кастомный код с WP-Cron | Собственная реализация автоматического удаления | Полный контроль, настройка под задачи | Требует навыков разработки, риск ошибок |