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

Почему важно автоматически отключать неактивные товары в WooCommerce

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

Диагностика: как определить неактивные товары

Для автоматического отключения сначала нужно выявить товары, которые не покупались определённое время (например, 6 месяцев). В WooCommerce дата последней покупки не хранится в метаполях товара напрямую, поэтому нужно анализировать заказы и искать последние даты покупок для каждого товара.

Проверка товаров с помощью SQL-запроса:

SELECT p.ID, p.post_title, MAX(o.post_date) AS last_order_date
FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_posts o ON oi.order_id = o.ID AND o.post_type = 'shop_order' AND o.post_status IN ('wc-completed', 'wc-processing')
WHERE p.post_type = 'product'
GROUP BY p.ID
ORDER BY last_order_date ASC;

Этот запрос показывает дату последнего заказа для каждого товара. Если дата отсутствует или слишком старая, товар можно считать неактивным.

Пошаговое решение: автоматическое отключение товаров

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

function get_inactive_products( $months = 6 ) {
    global $wpdb;
    $date_limit = date( 'Y-m-d H:i:s', strtotime( "-{$months} months" ) );

    $query = $wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->posts} p
        LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.post_title
        LEFT JOIN {$wpdb->posts} o ON oi.order_id = o.ID AND o.post_type = 'shop_order' AND o.post_status IN ('wc-completed', 'wc-processing')
        WHERE p.post_type = 'product'
        GROUP BY p.ID
        HAVING MAX(o.post_date) IS NULL OR MAX(o.post_date) < %s",
        $date_limit
    );

    return $wpdb->get_col( $query );
}

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

function disable_inactive_products( $months = 6 ) {
    $inactive_products = get_inactive_products( $months );

    if ( empty( $inactive_products ) ) {
        return 0;
    }

    foreach ( $inactive_products as $product_id ) {
        wp_update_post([
            'ID' => $product_id,
            'post_status' => 'draft' // или 'private' для скрытия от посетителей
        ]);
    }

    return count( $inactive_products );
}

3. Настраиваем запуск автоматического отключения через WP-Cron

if ( ! wp_next_scheduled( 'disable_inactive_products_daily' ) ) {
    wp_schedule_event( time(), 'daily', 'disable_inactive_products_daily' );
}

add_action( 'disable_inactive_products_daily', function() {
    $count = disable_inactive_products( 6 );
    error_log( "Disabled {$count} inactive WooCommerce products." );
});

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

  • Запустите функцию disable_inactive_products(6) вручную в среде разработки и проверьте, что товары со сроком последней покупки более 6 месяцев получают статус draft.
  • Проверьте в админке WooCommerce, что такие товары действительно скрыты с публичной части сайта.
  • Убедитесь, что по расписанию (например, через сутки) в логах появляется запись о количестве отключённых товаров.

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

  • Неправильный статус заказа учтён: учитывайте только статусы wc-completed и wc-processing, иначе товары могут остаться активными из-за отменённых или возвратных заказов.
  • Некорректный SQL-запрос из-за изменений префикса таблиц: всегда используйте $wpdb->prefix и $wpdb->posts для портируемости.
  • Отсутствие расписания WP-Cron: убедитесь, что WP-Cron работает и не отключён на сервере, иначе автоматическое отключение не сработает.

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

  • Для больших магазинов с тысячами товаров и заказов оптимизируйте SQL-запрос, добавляя индексы или разбивая выборку на части.
  • Перед массовым изменением статусов делайте резервные копии базы данных или используйте тестовую среду.
  • Для повышения безопасности не давайте доступ к этой функции неавторизованным пользователям и не запускайте её из публичного интерфейса.

Сравнение способов реализации автоматического отключения

МетодПлюсыМинусы
SQL-запрос + WP-Cron (как в статье)Контроль, гибкость, отсутствие сторонних плагиновТребует навыков SQL, риск ошибок при неправильном запросе
Плагины для управления товарамиПростота использования, интерфейсМожет замедлять сайт, ограниченная кастомизация
Ручное отключение через админкуМинимум технических знанийНеэффективно для большого каталога, трудозатратно
Удаление неиспользуемых CSS и JS в WordPress для ускорения загрузки
23.12.2025
Как отладить и решить ошибки Fatal Error в WordPress
25.01.2026
Как добавить динамические метаданные в WordPress для улучшения SEO
19.12.2025
Как установить ограничения на размер загружаемых файлов в WordPress
10.03.2026
Как создать собственный шорткод в WordPress
05.11.2025