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

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

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

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

  • Отсутствие продаж за определённый период (например, 3 месяца)
  • Отсутствие просмотров или интереса (если есть система аналитики)
  • Проверка метаполей с датой последней покупки или обновления

Для большинства задач достаточно ориентироваться на дату последней продажи.

Пошаговое решение: автоматическое отключение товаров без продаж за 90 дней

Реализуем cron-задачу, которая раз в сутки проверяет товары и отключает те, у которых нет продаж более 90 дней.

Шаг 1. Добавление кастомной функции для проверки и отключения товаров

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

    // Получаем ID товаров, у которых не было продаж за последние 90 дней
    $products = $wpdb->get_col($wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN (
            SELECT oi.order_item_id, oim.meta_value as product_id, o.post_date
            FROM {$wpdb->prefix}woocommerce_order_items oi
            JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id AND oim.meta_key = '_product_id'
            JOIN {$wpdb->posts} o ON oi.order_id = o.ID
            WHERE o.post_type = 'shop_order' AND o.post_status IN ('wc-completed', 'wc-processing')
        ) sales ON p.ID = sales.product_id
        WHERE p.post_type = 'product' AND (sales.post_date IS NULL OR sales.post_date < %s) AND p.post_status = 'publish';",
        $date_threshold
    ));

    if (!empty($products)) {
        foreach ($products as $product_id) {
            // Меняем статус товара на 'draft' (черновик), чтобы отключить его из каталога
            wp_update_post(array(
                'ID' => $product_id,
                'post_status' => 'draft'
            ));
        }
    }
}

Шаг 2. Регистрация ежедневного задания WP-Cron

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

add_action('disable_inactive_products_daily', 'disable_inactive_products');

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

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

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

  • Проверьте в базе данных или админке WooCommerce статус товаров, которые не продавались более 90 дней — они должны иметь статус draft.
  • Запустите функцию вручную через disable_inactive_products(); в режиме отладки, чтобы убедиться, что она корректно идентифицирует и изменяет статусы.
  • Проверяйте логи сервера или используйте плагин для отладки (например, Query Monitor), чтобы убедиться, что cron-задача выполняется ежедневно.

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

  • Неправильный статус заказа: учитывайте только статусы wc-completed и wc-processing. Если добавить wc-on-hold или другие, можно получить ложные данные.
  • Не срабатывает WP-Cron: на некоторых хостингах cron требует вызова через системный cron, либо посещения сайта. Проверьте wp-cron.php и настройте системный cron, если нужно.
  • Продукты с вариациями не отключаются: скрипт проверяет только основные продукты, для вариаций нужно дополнительно реализовать логику.
  • Отсутствие обратной связи: добавьте логирование отключённых товаров для мониторинга работы скрипта.

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

  • Для больших магазинов запрос к базе может быть тяжелым. Разбейте обработку на части или используйте WP_Query с пагинацией.
  • Добавьте проверку прав пользователя при ручном запуске функции, чтобы не допустить несанкционированного отключения.
  • Логируйте изменения в отдельный файл или используйте встроенные средства мониторинга, чтобы быстро находить ошибки.
  • Резервное копирование базы перед внедрением автоматических изменений — обязательный пункт.

Сравнение подходов для отключения неактивных товаров

МетодПлюсыМинусы
SQL-запрос + WP-Cron (как в статье)Автоматизация, гибкость, контроль через кодНужно писать и тестировать код, нагрузка на БД
Плагин для управления товарами (например, WooCommerce Smart Manager)Удобный интерфейс, дополнительные функцииПлатные решения, ограниченная кастомизация
Ручное отключение через админкуПростота, никаких технических навыковТрудозатратно, риск пропуска товаров
WooCommerce: как найти и исправить дублирующиеся артикулы (SKU) в продуктах
04.05.2026
WooCommerce: как правильно настроить удаление вариантов товаров по расписанию
04.07.2026
Как удалить или изменить slug в WordPress без потери SEO
14.11.2025
Как создать плагин для WordPress с нуля: подробное руководство с примером кода
21.11.2025
WooCommerce: как автоматически отключать товары без остатков на складе
16.06.2026