Как автоматически отключать неиспользуемые вариации товаров в WooCommerce

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

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

Чтобы проверить, есть ли неиспользуемые вариации, выполните SQL-запрос к базе данных:

SELECT COUNT(*) AS inactive_variations FROM wp_posts 
WHERE post_type = 'product_variation' AND post_status = 'private';

Статус private или draft у вариаций может указывать на их неактивность. Также можно проверить вариации с низким или нулевым количеством продаж за последние 6 месяцев, используя запросы к таблице заказов.

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

1. Определяем критерии отключения

  • Вариация не продавалась в последние 180 дней
  • Вариация в статусе publish, но с нулевым остатком
  • Вариация неактивна и не отображается на сайте

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

Добавьте следующий код в файл functions.php вашей темы или в кастомный плагин:

function disable_unused_variations() {
    global $wpdb;
    $date_limit = date('Y-m-d H:i:s', strtotime('-180 days'));

    // Получаем ID вариаций без продаж за 180 дней и с нулевым остатком
    $variations = $wpdb->get_col( $wpdb->prepare(
        "SELECT p.ID FROM {$wpdb->prefix}posts p
        LEFT JOIN {$wpdb->prefix}woocommerce_order_items oi ON oi.order_item_name = p.ID
        LEFT JOIN {$wpdb->prefix}woocommerce_order_itemmeta oim ON oi.order_item_id = oim.order_item_id AND oim.meta_key = '_product_id'
        WHERE p.post_type = 'product_variation'
        AND p.post_status = 'publish'
        AND p.ID NOT IN (
            SELECT oim.meta_value FROM {$wpdb->prefix}woocommerce_order_itemmeta oim
            INNER JOIN {$wpdb->prefix}woocommerce_order_items oi ON oim.order_item_id = oi.order_item_id
            INNER JOIN {$wpdb->prefix}posts po ON oi.order_id = po.ID
            WHERE oim.meta_key = '_product_id'
            AND po.post_date > %s
        )
        AND p.ID IN (
            SELECT post_id FROM {$wpdb->prefix}postmeta WHERE meta_key = '_stock' AND meta_value = '0'
        )",
        $date_limit
    ) );

    if (empty($variations)) {
        return;
    }

    // Меняем статус на 'private' для отключения
    foreach ($variations as $variation_id) {
        wp_update_post(array(
            'ID' => $variation_id,
            'post_status' => 'private'
        ));
    }
}

// Запускаем функцию раз в сутки через WP-Cron
if (!wp_next_scheduled('disable_unused_variations_cron')) {
    wp_schedule_event(time(), 'daily', 'disable_unused_variations_cron');
}
add_action('disable_unused_variations_cron', 'disable_unused_variations');

3. Тестируем работу функции вручную

Для проверки можно вызвать функцию вручную в консоли WP-CLI:

wp eval 'disable_unused_variations();'

После выполнения проверьте, что статус некоторых вариаций изменился на private. Их можно увидеть в админке WooCommerce, отфильтровав по статусу.

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

  • В админке WooCommerce перейдите в раздел «Товары» → «Вариации» и используйте фильтр по статусу «private» или «черновик» — должны появиться отключенные вариации.
  • Проверьте на фронтенде, что эти вариации не доступны для выбора покупателями.
  • Запустите SQL-запрос из раздела диагностики, чтобы убедиться, что количество активных вариаций уменьшилось.
  • Наблюдайте за производительностью сайта: уменьшение количества запросов к вариациям и снижение нагрузки на базу данных.

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

  • Ошибка: Функция не отключает вариации.
    Причина: Некорректный статус вариаций или неверные условия выборки.
    Исправление: Проверьте, что вариации действительно имеют статус publish и что мета-ключ _stock хранится корректно.
  • Ошибка: Скрипт отключает нужные вариации.
    Причина: Слишком жесткие условия времени или остатков.
    Исправление: Уточните условия, например, увеличить период отсутствия продаж или учитывать только вариации с 0 в наличии и без активных заказов.
  • Ошибка: WP-Cron не запускается автоматически.
    Причина: Отсутствие трафика или отключение WP-Cron.
    Исправление: Настройте системный cron на вызов wget https://site.ru/wp-cron.php или используйте WP-CLI для запуска.

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

  • Перед внесением изменений сделайте резервную копию базы данных.
  • Разграничьте права доступа к коду и базе, чтобы исключить случайное изменение данных.
  • Для больших магазинов используйте пагинацию выборки вариаций, чтобы не перегружать память сервера.
  • Комбинируйте отключение вариаций с регулярной оптимизацией базы данных, например, через Clearfy Pro (https://wpshop.ru/plugins/clearfy?utm_source=wp-market.ru&utm_medium=article&utm_campaign=kak-avtomaticheski-otklyuchat-neispolzuemye-variacii-tovarov-woocommerce) для удаления мусора.

Сравнение подходов: плагин vs код

МетодПлюсыМинусыКомпромисс
Код (как в статье)Гибкость, контроль, без дополнительной нагрузкиТребует навыков, возможны ошибки при неправильном кодеИспользовать в связке с WP-CLI и регулярным бэкапом
Плагин автоматизацииУдобство, интерфейс, поддержкаМожет замедлять сайт, менее гибкийВыбирать проверенные плагины, настраивать фильтры
Как создать динамический шорткод в WordPress с применением PHP
06.11.2025
Как создать автоматический импорт продуктов в WooCommerce с помощью WPMarket
25.12.2025
Как создать настройки для плагина с AJAX в WordPress
28.02.2026
Как создать настройку мультиязычности в WordPress без плагинов
25.01.2026
Как удалить старые вариации товаров WooCommerce и ускорить базу
02.05.2026