WooCommerce: как автоматически удалять непроданные товары за указанный период

Диагностика проблемы: зачем и когда нужно удалять непроданные товары

В интернет-магазинах на WooCommerce со временем накапливаются товары, которые не пользуются спросом. Такие товары занимают место в базе данных, загромождают каталог и снижают качество пользовательского опыта. Автоматизация удаления непроданных товаров за определённый период поможет поддерживать актуальность ассортимента и улучшить производительность сайта.

Перед автоматизацией важно проверить, действительно ли есть товары без продаж и как долго они находятся в каталоге.

Как проверить наличие непроданных товаров

SELECT p.ID, p.post_title, p.post_date FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.ID
WHERE p.post_type = 'product' AND oi.order_item_id IS NULL
AND p.post_date < DATE_SUB(NOW(), INTERVAL 90 DAY);

Этот SQL-запрос выведет товары, которые не связаны с заказами и были добавлены более 90 дней назад. Если таких товаров много, стоит автоматизировать их удаление.

Пошаговое решение: автоматическое удаление непроданных товаров через WP-Cron

1. Создаём функцию удаления непроданных товаров

function wpbit_delete_unsold_products() {
    $days = 90; // Период в днях
    $date_threshold = date('Y-m-d H:i:s', strtotime("-{$days} days"));

    // Получаем ID товаров без продаж старше $days дней
    $args = [
        'post_type' => 'product',
        'posts_per_page' => -1,
        'date_query' => [
            [
                'before' => $date_threshold,
                'inclusive' => true,
            ],
        ],
        'meta_query' => [
            [
                'key' => '_wc_average_rating', // Используем рейтинг для фильтрации не проданных товаров
                'compare' => 'NOT EXISTS',
            ],
        ],
        'fields' => 'ids',
        'tax_query' => [
            [
                'taxonomy' => 'product_visibility',
                'field' => 'name',
                'terms' => 'exclude-from-catalog',
                'operator' => 'NOT IN',
            ],
        ],
    ];

    $query = new WP_Query($args);

    if ($query->have_posts()) {
        foreach ($query->posts as $product_id) {
            // Проверяем продажи через WC_Order_Item_Product
            $sales = get_post_meta($product_id, 'total_sales', true);
            if (empty($sales) || (int)$sales === 0) {
                wp_delete_post($product_id, true); // Удаление без помещения в корзину
            }
        }
    }
    wp_reset_postdata();
}

2. Регистрируем WP-Cron событие для регулярного запуска

if (!wp_next_scheduled('wpbit_daily_delete_unsold_products')) {
    wp_schedule_event(time(), 'daily', 'wpbit_daily_delete_unsold_products');
}
add_action('wpbit_daily_delete_unsold_products', 'wpbit_delete_unsold_products');

3. Добавляем очистку cron при деактивации плагина или темы

function wpbit_deactivate_cleanup() {
    $timestamp = wp_next_scheduled('wpbit_daily_delete_unsold_products');
    if ($timestamp) {
        wp_unschedule_event($timestamp, 'wpbit_daily_delete_unsold_products');
    }
}
register_deactivation_hook(__FILE__, 'wpbit_deactivate_cleanup');

Проверка результата после внедрения

Чтобы проверить, что автоматическое удаление работает, выполните следующие действия:

  • Добавьте тестовый товар старше 90 дней без продаж.
  • Запустите функцию вручную через WP-CLI: wp eval 'wpbit_delete_unsold_products();'
  • Проверьте, что тестовый товар удалён из админки и базы данных.
  • Проверьте логи сервера и WP-Cron, чтобы убедиться в отсутствии ошибок.

Частые ошибки и как их исправить

  • Неправильный период времени: Использование неподходящего интервала (например, 30 дней вместо 90) может привести к удалению нужных товаров. Проверяйте значение переменной $days.
  • Удаление товаров с продажами: Ошибка в логике фильтрации может удалить товары с реальными заказами. Всегда проверяйте мета-ключ total_sales.
  • WP-Cron не работает: На некоторых хостингах WP-Cron отключён или работает некорректно. Используйте системный cron для вызова wp-cron.php по расписанию.
  • Потеря данных: Удаление происходит сразу без корзины (параметр true в wp_delete_post). Делайте резервные копии перед внедрением.

Практические советы по безопасности и производительности

  • Перед запуском на реальном сайте тестируйте на локальной копии.
  • Добавьте логирование в функцию для отслеживания удалённых товаров, например, в отдельный файл или системный лог.
  • Чтобы уменьшить нагрузку, разбивайте удаление на партии по 50–100 товаров, используя пагинацию.
  • Регулярно оптимизируйте базу данных после удаления.
  • Для более гибкого управления используйте фильтры и настройки через админку с кастомным плагином.

Таблица сравнения способов удаления непроданных товаров

МетодАвтоматизацияГибкостьРискиПростота внедрения
WP-Cron + код (как в статье)Да, ежедневный запускВысокая, можно настроить интервал и фильтрыУдаление без корзины, требует резервных копийСредняя, требует навыков разработки
Плагины очистки товаров (например, WP Sweep)Некоторые с автоматизациейОграниченная, настройки через UIМогут удалять лишнее, без тонкой настройкиВысокая, подходит новичкам
Ручное удаление через админкуНетПолный контрольТрудозатратно, риск пропуска товаровПростое, но неэффективное
WooCommerce: как автоматически удалять непроданные товары за указанный период
09.06.2026
WooCommerce: как настроить автоматический возврат денег по встроенным правилам
23.06.2026
WooCommerce: как исключить товары из корзины по атрибутам
02.05.2026
WooCommerce: автоматическое удаление товаров из магазина по статусу заказов
04.06.2026
Как автоматизировать удаление старых неиспользуемых медиафайлов в WordPress
19.02.2026