Автоматическое удаление неактивных товаров в WooCommerce

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

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

Как определить неактивные товары для удаления

Основные критерии для определения неактивных товаров:

  • Отсутствие продаж за заданный период (например, 6 месяцев);
  • Отсутствие обновлений или изменений метаданных за тот же период;
  • Статус товара — опубликовать (publish), чтобы не удалять черновики и архивы;
  • Отсутствие связанных заказов с завершенным статусом.

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

Пошаговое решение: настройка автоматического удаления неактивных товаров

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

Код ниже ищет товары, которые не продавались и не обновлялись более 180 дней, и удаляет их безопасно.

function wpsell_delete_inactive_products() {
    $days_inactive = 180; // Период неактивности в днях
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_inactive . ' days'));

    // Получаем ID товаров, обновленных до пороговой даты
    $args = [
        'post_type' => 'product',
        'post_status' => 'publish',
        'date_query' => [
            [
                'column' => 'post_modified',
                'before' => $date_threshold,
            ],
        ],
        'fields' => 'ids',
        'posts_per_page' => -1,
    ];
    $products = get_posts($args);

    if (empty($products)) {
        return; // Нет товаров для удаления
    }

    global $wpdb;

    foreach ($products as $product_id) {
        // Проверяем наличие завершенных заказов с этим товаром
        $order_ids = $wpdb->get_col($wpdb->prepare(
            "SELECT order_id 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->prefix}posts p ON p.ID = oi.order_id
             WHERE oi.order_item_type = 'line_item'
             AND oim.meta_key = '_product_id' AND oim.meta_value = %d
             AND p.post_status IN ('wc-completed', 'wc-processing')",
             $product_id
        ));

        if (empty($order_ids)) {
            // Нет продаж — удаляем товар
            wp_delete_post($product_id, true); // true - полное удаление без корзины
        }
    }
}

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

Добавим запуск функции один раз в сутки.

function wpsell_schedule_inactive_products_deletion() {
    if (!wp_next_scheduled('wpsell_delete_inactive_products_hook')) {
        wp_schedule_event(time(), 'daily', 'wpsell_delete_inactive_products_hook');
    }
}
add_action('wp', 'wpsell_schedule_inactive_products_deletion');

add_action('wpsell_delete_inactive_products_hook', 'wpsell_delete_inactive_products');

3. Отменяем задание при деактивации плагина или темы

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

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

  • Запустите функцию вручную с помощью wpsell_delete_inactive_products() в консоли WP-CLI или временно вызовите ее в functions.php и проверьте удаление товаров.
  • Проверьте наличие товаров с датой обновления больше 180 дней в админке (через фильтр по дате изменения).
  • Просмотрите логи ошибок и убедитесь, что wp_delete_post срабатывает без ошибок.
  • Проверьте, что товары с завершенными заказами не удаляются.

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

  • Удаляются товары с активными заказами: ошибка в запросе проверки заказов. Проверьте правильность JOIN и статусов заказов (wc-completed, wc-processing).
  • Функция не запускается по расписанию: убедитесь, что WP-Cron работает (нет проблем с вызовом wp-cron.php). Для теста можно использовать плагин WP Crontrol.
  • Удаление не происходит: проверьте права пользователя, под которым запускается скрипт, и наличие ошибок в логах PHP.
  • Высокая нагрузка на базу при выполнении: ограничьте количество товаров на удаление за один запуск, например, добавьте параметр 'posts_per_page' => 50 и используйте пагинацию.

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

  • Перед удалением рекомендуется создавать резервные копии базы данных.
  • Для больших магазинов лучше выполнять удаление пакетами, чтобы не блокировать базу длительное время.
  • Используйте транзакции или проверяйте целостность данных после удаления.
  • Отключайте задачу WP-Cron на пиковых нагрузках сайта, чтобы избежать замедлений.

Сравнение вариантов реализации автоматического удаления товаров

МетодПлюсыМинусыКомпромисс
Самописный код с WP-CronПолный контроль, без сторонних плагиновТребует навыков, возможна нагрузка при больших объемахВыполнение пакетами и логирование
Плагины очистки каталогаПростота настройки, готовые решенияМогут быть избыточными, влияние на производительностьИспользовать проверенные плагины с поддержкой
Ручное удаление через админкуБезопасно, минимальные рискиТрудоемко, не подходит для больших магазиновИспользовать вместе с автоматизацией
Как удалить неиспользуемые метаданные в WordPress без риска
05.04.2026
Как добавить атрибуты для оптимизации изображений в WordPress
27.01.2026
Как избежать конфликтов между плагинами WordPress: практические советы и примеры
07.12.2025
Как создать настройку отображения товара в WooCommerce на WordPress
15.11.2025
Как добавить вывод стоимости отсутствующих товаров в корзине WooCommerce
01.05.2026

Совсем скоро здесь заработает сайт о вордпресс. И будет он связан с продажами, магазинами или чем-то таким.