WooCommerce: как автоматически отключать неактивные товары по времени

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

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

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

Как автоматически отключать товары, неактивные по времени

Определяем критерии неактивности товара

Самый распространенный способ — отключать товары, которые не обновлялись и не продавались в течение заданного периода. Например, если товар не продавался и не обновлялся 180 дней — отключаем.

Можно использовать даты последнего изменения товара (post_modified) и дату последней продажи (мета-данные заказа).

Пошаговое решение через WP-Cron и кастомный PHP-код

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

function disable_inactive_products() {
    $days_inactive = 180; // количество дней неактивности
    $date_threshold = date('Y-m-d H:i:s', strtotime('-' . $days_inactive . ' days'));

    // Получаем товары, которые не обновлялись с даты порога и имеют статус publish
    $args = [
        'post_type' => 'product',
        'post_status' => 'publish',
        'date_query' => [
            [
                'column' => 'post_modified',
                'before' => $date_threshold,
            ],
        ],
        'posts_per_page' => -1,
        'fields' => 'ids',
    ];

    $query = new WP_Query($args);
    if (!$query->have_posts()) {
        return; // Нет товаров для отключения
    }

    foreach ($query->posts as $product_id) {
        // Проверяем дату последней продажи
        $last_order_date = get_post_meta($product_id, '_last_order_date', true);
        if ($last_order_date && strtotime($last_order_date) > strtotime($date_threshold)) {
            continue; // Товар недавно продавался
        }

        // Меняем статус на 'draft' (черновик)
        wp_update_post([
            'ID' => $product_id,
            'post_status' => 'draft',
        ]);
    }
}

2. Создаем WP-Cron задачу для регулярного запуска функции:

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

3. Добавляем обновление мета-поля _last_order_date при каждой продаже товара:

function update_last_order_date($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item) {
        $product_id = $item->get_product_id();
        update_post_meta($product_id, '_last_order_date', current_time('mysql'));
    }
}
add_action('woocommerce_thankyou', 'update_last_order_date');

Как проверить, что решение работает

  • Проверьте, что WP-Cron запланирован: в админке WP или с помощью плагина WP Crontrol должен быть событие disable_inactive_products_cron.
  • Создайте тестовый товар и установите дату последнего обновления в прошлое (через базу данных или программно).
  • Убедитесь, что у товара нет мета _last_order_date или он старше 180 дней.
  • Запустите вручную функцию disable_inactive_products() (например, через admin-ajax или WP-CLI) и проверьте, что статус товара изменился на draft.
  • Проверьте логи сервера на ошибки и корректность выполнения WP-Cron.

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

  • WP-Cron не запускается: причина — низкий трафик сайта или отключенный WP-Cron в wp-config.php. Решение — использовать системный cron на сервере для запуска wp-cron.php или плагин для управления cron.
  • Метаданные даты продажи не обновляются: проверьте, подключен ли хук woocommerce_thankyou и нет ли конфликтов с другими плагинами, блокирующими обновление мета.
  • Товары не переходят в статус draft: убедитесь, что у пользователя, от имени которого выполняется скрипт, есть права на редактирование постов, и что нет фильтров, которые блокируют смену статуса.
  • Функция выбирает слишком много товаров и нагрузка растет: добавьте пагинацию и ограничьте количество товаров на итерацию, чтобы не создавать нагрузку.

Практические советы по оптимизации и безопасности

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

Сравнение вариантов реализации

ВариантПреимуществаНедостатки
Плагин с автоматическим отключениемБыстрая настройка, интерфейс, поддержкаМожет быть избыточным, нагрузка, ограниченная кастомизация
Кастомный код с WP-Cron (как в статье)Полный контроль, точная логика, минимальная нагрузкаТребует навыков, отладка, ответственность за обновления
Ручное отключениеМинимум кода, быстроТрудоемко, риск пропустить товары, ошибки
Как создать выбор поля в форме WordPress с динамическими значениями
13.12.2025
WooCommerce: автоматическое изменение стоимости товаров по расписанию
02.06.2026
Как сделать собственную авторизацию в WordPress с помощью shortcode
21.01.2026
Как создать автоматический отчет о проблемах WordPress
28.01.2026
Как использовать WP-Cron для автоматизации задач в WordPress
03.05.2026