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

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

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

Как проверить, что вариант товара был заказан

В WooCommerce информация о заказах хранится в таблицах wp_posts (заказы) и wp_woocommerce_order_items (позиции заказа). Для определения, был ли заказан конкретный вариационный товар, достаточно проверить наличие заказов с этим ID вариации как product_id.

Пример запроса для проверки через WP_Query

$variation_id = 123; // ID вариации

$orders = wc_get_orders(array(
    'limit' => 1,
    'status' => array('completed', 'processing', 'on-hold'),
    'meta_query' => array(
        array(
            'key' => '_product_id',
            'value' => $variation_id,
            'compare' => '='
        ),
    ),
));

if (!empty($orders)) {
    // Вариация была заказана
}

Однако WooCommerce не хранит напрямую _product_id в метаданных заказа, поэтому для точного поиска лучше использовать WC_Order_Item_Product и пройти по всем заказам:

function variation_has_orders($variation_id) {
    $args = array(
        'limit' => -1,
        'status' => array('completed', 'processing', 'on-hold'),
    );
    $orders = wc_get_orders($args);
    foreach ($orders as $order) {
        foreach ($order->get_items() as $item) {
            if ($item->get_product_id() == $variation_id) {
                return true;
            }
        }
    }
    return false;
}

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

Для автоматизации процесса добавим хук на событие создания заказа и проверим, есть ли вариации, которые впервые были заказаны. Если да — удалим их.

Код для functions.php или собственного плагина

add_action('woocommerce_thankyou', 'remove_variations_after_first_order', 10, 1);

function remove_variations_after_first_order($order_id) {
    if (!$order_id) return;

    $order = wc_get_order($order_id);
    if (!$order) return;

    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        if (!$product || $product->get_type() !== 'variation') continue;

        $variation_id = $product->get_id();

        // Проверяем, был ли этот вариант заказан ранее
        if (!variation_has_orders_before($order_id, $variation_id)) {
            // Удаляем вариацию
            wp_delete_post($variation_id, true);
        }
    }
}

function variation_has_orders_before($current_order_id, $variation_id) {
    $args = array(
        'limit' => -1,
        'status' => array('completed', 'processing', 'on-hold'),
        'exclude' => array($current_order_id),
    );
    $orders = wc_get_orders($args);
    foreach ($orders as $order) {
        foreach ($order->get_items() as $item) {
            if ($item->get_product_id() == $variation_id) {
                return true;
            }
        }
    }
    return false;
}

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

  • Сделайте тестовый заказ вариации, которую еще не заказывали.
  • После подтверждения заказа проверьте в админке WooCommerce, что вариация удалена.
  • Попробуйте сделать заказ вариации, которая уже была заказана ранее — она не должна удаляться.
  • Проверьте, что удаление не затрагивает основной товар или другие вариации.

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

  • Не удаляется вариация: проверьте, что хук woocommerce_thankyou срабатывает и что ID вариаций корректно определяется.
  • Удаляются все вариации: убедитесь, что функция variation_has_orders_before правильно исключает текущий заказ и проверяет именно предшествующие заказы.
  • Права доступа: функция wp_delete_post удаляет вариацию навсегда; убедитесь, что у пользователя, под которым работает PHP, есть права на удаление постов.
  • Потеря данных: если вариации связаны с другими объектами (например, отзывы), учтите, что они тоже будут удалены.

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

  • Для ускорения проверки заказов можно кешировать результаты проверки variation_has_orders_before, например, с помощью transient API WordPress.
  • Обязательно делайте резервное копирование базы данных перед внедрением автоматического удаления.
  • Если магазин большой, ограничьте количество проверяемых заказов в wc_get_orders или реализуйте поиск через прямые запросы к базе с индексами.
  • Рассмотрите уведомление админа после удаления вариации для контроля и аудита действий.

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

МетодПлюсыМинусыКомпромисс
PHP-хук на создание заказаПолный контроль, без плагиновНагрузка при большом количестве заказовДобавить кеширование для оптимизации
SQL-запрос для поиска вариацийБыстрее при больших данныхСложность поддержки, риск ошибокИспользовать только для отчётов и проверок
Использование плагина автоматизацииПростота настройкиМожет быть избыточно и влиять на производительностьИспользовать при отсутствии ресурсов на кастомный код

Добавь в закладки и поделись с друзьями:

⭐⭐⭐⭐⭐
Как создать собственный шорткод в WordPress: практическое руководство
04.11.2025
Как сделать автоматический rollback обновлений WordPress при ошибках
25.03.2026
Как удалить записи по автору в WordPress программно
16.01.2026
Как автоматически удалить старые ревизии записей в WordPress
23.01.2026
Как избежать проблем с пересекающимися правилами в WooCommerce
03.05.2026
×
Делай сайт лучше!!

-20% на премиум темы и плагины

Использовать скидку ⋙