WooCommerce: автоматическое удаление неиспользуемых вариаций товаров через код

Диагностика проблемы с вариациями товаров в WooCommerce

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

Проверить наличие неиспользуемых вариаций можно через SQL-запрос к базе данных или с помощью кода, который анализирует метаданные товаров.

Пример SQL-запроса для выявления вариаций без заказов и с нулевым запасом:

SELECT p.ID, p.post_title FROM wp_posts p
LEFT JOIN wp_woocommerce_order_items oi ON oi.order_item_name = p.post_title
LEFT JOIN wp_postmeta pm ON pm.post_id = p.ID AND pm.meta_key = '_stock'
WHERE p.post_type = 'product_variation'
GROUP BY p.ID
HAVING COUNT(oi.order_item_id) = 0 AND (pm.meta_value IS NULL OR pm.meta_value = '0');

Этот запрос покажет вариации, которые не были куплены и не имеют запасов. Такие вариации чаще всего можно удалить.

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

Чтобы автоматически удалять неиспользуемые вариации, можно написать функцию, которая:

  • Получает все вариации товаров
  • Проверяет, есть ли у вариации продажи (через связку с заказами)
  • Проверяет наличие запасов
  • Удаляет вариации, которые не продаются и не имеют запасов

Пример кода для размещения в functions.php темы или в отдельном плагине:

function wc_remove_unused_variations() {
    $args = [
        'post_type'      => 'product_variation',
        'posts_per_page' => -1,
        'fields'         => 'ids',
    ];
    $variations = get_posts($args);

    foreach ($variations as $variation_id) {
        // Проверяем продажи вариации
        $orders_with_variation = new WP_Query([
            'post_type'      => 'shop_order',
            'post_status'    => ['wc-completed', 'wc-processing'],
            'posts_per_page' => 1,
            'meta_query'     => [[
                'key'     => '_product_id',
                'value'   => $variation_id,
                'compare' => '=',
            ]],
        ]);

        // Проверяем наличие запаса
        $stock = get_post_meta($variation_id, '_stock', true);

        if (!$orders_with_variation->have_posts() && (empty($stock) || $stock == '0')) {
            wp_delete_post($variation_id, true);
        }
    }
}

// Добавьте вызов этой функции по крону или вручную
// wc_remove_unused_variations();

Обратите внимание, что запрос к заказам в WP_Query по мета-данным вариации требует доработки под структуру WooCommerce, поэтому для точного определения продаж лучше использовать прямые запросы к таблицам woocommerce_order_items и woocommerce_order_itemmeta.

Оптимизированный пример запроса к заказам и удаление вариаций

function wc_remove_unused_variations_optimized() {
    global $wpdb;

    $variation_ids = $wpdb->get_col("SELECT ID FROM {$wpdb->posts} WHERE post_type = 'product_variation'");

    foreach ($variation_ids as $variation_id) {
        // Проверяем продажи вариации
        $order_count = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) 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->posts} p ON p.ID = oi.order_id
             WHERE oim.meta_key = '_variation_id' AND oim.meta_value = %d
             AND p.post_status IN ('wc-completed', 'wc-processing')",
            $variation_id
        ));

        $stock = get_post_meta($variation_id, '_stock', true);

        if ($order_count == 0 && (empty($stock) || $stock == '0')) {
            wp_delete_post($variation_id, true);
        }
    }
}

// Для безопасного запуска рекомендуется привязать к WP-Cron или запускать вручную
// wc_remove_unused_variations_optimized();

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

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

Частые ошибки при автоматическом удалении вариаций и их исправление

  • Удаление вариаций, которые ещё используются в заказах. Причина: неправильный запрос к заказам. Решение: использовать точный SQL с JOIN таблиц woocommerce_order_items и woocommerce_order_itemmeta по ключу _variation_id.
  • Удаление вариаций с запасом. Причина: некорректное получение значения _stock, например, кэширование или нестандартное хранение. Решение: использовать функцию wc_get_product($variation_id)->get_stock_quantity().
  • Высокая нагрузка при запуске функции на больших магазинах. Решение: разбивать обработку на части, например, по 100 вариаций за раз, использовать WP-Cron для регулярного запуска.

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

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

Сравнение методов удаления вариаций

МетодПлюсыМинусыРекомендуемая сфера
Ручное удаление через админку WooCommerceПростота, безопасностьДолгое при большом количестве вариацийМалые магазины
Код на PHP с WP_QueryГибкость, автоматизацияСложный поиск заказов, нагрузкаСредние магазины
Код на PHP с прямыми SQL-запросамиБыстрота, точностьРиск ошибок, требуется опыт работы с БДКрупные магазины с админом-специалистом
Логика оценки продуктивности в WordPress: практическое руководство с примерами
31.12.2025
Как создать эффективный отчет по производительности WordPress
15.04.2026
Удаление неиспользуемых вариаций товаров в WooCommerce через код
14.05.2026
Как создать динамические метаполя для кастомных типов записей в WordPress
07.02.2026
Как создать собственный шорткод для вывода данных из базы WordPress
03.02.2026