Диагностика проблемы: зачем нужно удалять старые товары без продаж
В интернет-магазинах на WooCommerce часто накапливаются товары, которые не продаются длительное время. Они занимают место в базе данных, влияют на производительность и усложняют управление каталогом. Автоматическое удаление таких товаров помогает держать магазин в актуальном состоянии и улучшает пользовательский опыт.
Как определить товары без продаж за последние 30 дней
Для удаления нужны товары, у которых отсутствуют заказы за последние 30 дней. Это можно проверить по таблице wp_woocommerce_order_items и связанной wp_posts с типом shop_order. Важно учитывать только заказы со статусом completed или processing.
SQL-запрос для проверки товаров без продаж
SELECT p.ID, p.post_title FROM wp_posts p
WHERE p.post_type = 'product'
AND p.ID NOT IN (
SELECT order_item_meta.meta_value FROM wp_woocommerce_order_items order_items
JOIN wp_woocommerce_order_itemmeta order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
JOIN wp_posts orders ON orders.ID = order_items.order_id
WHERE order_item_meta.meta_key = '_product_id'
AND orders.post_status IN ('wc-completed', 'wc-processing')
AND orders.post_date > DATE_SUB(NOW(), INTERVAL 30 DAY)
);
Этот запрос вернет список ID и названий товаров, которые не продавались последние 30 дней.
Пошаговое решение: скрипт для автоматического удаления товаров
Оптимальный способ — создать WP-Cron задачу, которая будет запускаться ежедневно и удалять товары без продаж за 30 дней.
1. Добавляем функцию удаления в файл functions.php или в плагин
function wpt_delete_old_unsold_products() {
global $wpdb;
// Получаем ID товаров без продаж за 30 дней
$product_ids = $wpdb->get_col(
"SELECT p.ID FROM {$wpdb->posts} p
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
AND p.ID NOT IN (
SELECT order_item_meta.meta_value FROM {$wpdb->prefix}woocommerce_order_items order_items
JOIN {$wpdb->prefix}woocommerce_order_itemmeta order_item_meta ON order_items.order_item_id = order_item_meta.order_item_id
JOIN {$wpdb->posts} orders ON orders.ID = order_items.order_id
WHERE order_item_meta.meta_key = '_product_id'
AND orders.post_status IN ('wc-completed', 'wc-processing')
AND orders.post_date > DATE_SUB(NOW(), INTERVAL 30 DAY)
)"
);
if (empty($product_ids)) {
return; // Нет товаров для удаления
}
foreach ($product_ids as $product_id) {
wp_delete_post($product_id, true); // Полное удаление
}
}
2. Регистрируем WP-Cron задачу
function wpt_schedule_delete_old_products() {
if (!wp_next_scheduled('wpt_daily_delete_old_products')) {
wp_schedule_event(time(), 'daily', 'wpt_daily_delete_old_products');
}
}
add_action('wp', 'wpt_schedule_delete_old_products');
add_action('wpt_daily_delete_old_products', 'wpt_delete_old_unsold_products');
3. Запуск задачи вручную (для теста)
// Для проверки запускаем так:
// wpt_delete_old_unsold_products();
Проверка результата после внедрения
- Выполните SQL-запрос из раздела диагностики до и после запуска скрипта — количество товаров без продаж должно уменьшиться.
- Проверьте раздел «Товары» в админке WooCommerce — старые неактивные товары должны исчезнуть.
- Логи сервера или плагина для отладки WP-Cron покажут события запуска.
Частые ошибки и как их исправить
- Ошибка: Товары не удаляются.
Причина: WP-Cron не срабатывает из-за отсутствия трафика или блокировки.
Решение: Настройте системный cron или используйте плагин для управления cron задачами, например WP Control. - Ошибка: Удаляются товары, которые недавно были проданы.
Причина: Неправильный диапазон дат или статусы заказов.
Решение: Проверьте, что в запросе правильно указаны статусыwc-completedиwc-processing, а дата сравнивается с текущим временем. - Ошибка: Удаляются товары со статусом
draftилиprivate.
Причина: В запросе не фильтруется статусpublish.
Решение: ДобавьтеAND p.post_status = 'publish'в запрос.
Практические советы по безопасности и производительности
- Перед удалением делайте резервную копию базы данных, чтобы избежать потери данных.
- Удаление большого числа товаров может замедлить сайт — выполняйте задачу в период минимальной нагрузки.
- Добавьте логирование удаленных товаров для аудита, например, записывая ID и дату удаления в отдельный файл или таблицу.
- Если магазин большой, разбивайте удаление на партии по 50-100 товаров, чтобы избежать таймаута PHP.
Таблица сравнения методов удаления старых товаров
| Метод | Плюсы | Минусы | Подходит для |
|---|---|---|---|
| Ручное удаление в админке | Просто, без кода | Трудоемко, не масштабируется | Малые магазины |
| SQL запрос с удалением | Быстрое выполнение | Риск ошибок, требует навыков SQL | Опытные администраторы |
| Автоматизация через WP-Cron (код) | Автоматически поддерживает каталог актуальным | Нужен контроль cron и логирование | Средние и крупные магазины |