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

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

В интернет-магазинах на WooCommerce часто возникает необходимость скрыть из корзины и процесса оформления определённые товары или их вариации по заданному атрибуту. Например, товары с атрибутом "Снято с производства" или вариации типа "Тестовые" нельзя продавать. Это не только улучшает UX, но и предотвращает ошибки с заказами недоступных позиций.

Без корректной фильтрации такие товары могут остаться в корзине, что приведёт к проблемам с оплатой, логистикой и поддержкой клиентов.

Как проверить, что в корзине есть товары с нужным атрибутом

Для диагностики используйте следующий сниппет. Он выведет названия товаров с заданным атрибутом (например, pa_status со значением discontinued) в лог ошибок PHP:

add_action('woocommerce_check_cart_items', function() {
    $attribute_name = 'pa_status'; // имя атрибута
    $attribute_value = 'discontinued'; // значение атрибута

    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        if ($product->is_type('variation')) {
            $variation_attributes = $product->get_variation_attributes();
            if (isset($variation_attributes[$attribute_name]) && $variation_attributes[$attribute_name] === $attribute_value) {
                error_log('В корзине товар с атрибутом discontinued: ' . $product->get_name());
            }
        } else {
            $product_attributes = $product->get_attributes();
            if (isset($product_attributes[$attribute_name])) {
                $terms = wc_get_product_terms($product->get_id(), $attribute_name, array('fields' => 'slugs'));
                if (in_array($attribute_value, $terms)) {
                    error_log('В корзине товар с атрибутом discontinued: ' . $product->get_name());
                }
            }
        }
    }
});

Проверьте логи PHP (обычно error_log) после добавления товаров в корзину. Если сообщения появляются, значит задачи фильтрации актуальна.

Пошаговое решение: исключение товаров и вариантов по атрибуту из корзины и оформления

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

1. Удаление товаров с заданным атрибутом из корзины

add_action('woocommerce_before_calculate_totals', function() {
    $attribute_name = 'pa_status';
    $attribute_value = 'discontinued';

    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $remove = false;

        if ($product->is_type('variation')) {
            $variation_attributes = $product->get_variation_attributes();
            if (isset($variation_attributes[$attribute_name]) && $variation_attributes[$attribute_name] === $attribute_value) {
                $remove = true;
            }
        } else {
            $product_attributes = $product->get_attributes();
            if (isset($product_attributes[$attribute_name])) {
                $terms = wc_get_product_terms($product->get_id(), $attribute_name, array('fields' => 'slugs'));
                if (in_array($attribute_value, $terms)) {
                    $remove = true;
                }
            }
        }

        if ($remove) {
            WC()->cart->remove_cart_item($cart_item_key);
        }
    }
});

2. Блокировка оформления заказа при наличии таких товаров

add_action('woocommerce_check_cart_items', function() {
    $attribute_name = 'pa_status';
    $attribute_value = 'discontinued';

    foreach (WC()->cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        if ($product->is_type('variation')) {
            $variation_attributes = $product->get_variation_attributes();
            if (isset($variation_attributes[$attribute_name]) && $variation_attributes[$attribute_name] === $attribute_value) {
                wc_add_notice('В корзине есть товары, которые нельзя заказать: "' . $product->get_name() . '".', 'error');
                break;
            }
        } else {
            $product_attributes = $product->get_attributes();
            if (isset($product_attributes[$attribute_name])) {
                $terms = wc_get_product_terms($product->get_id(), $attribute_name, array('fields' => 'slugs'));
                if (in_array($attribute_value, $terms)) {
                    wc_add_notice('В корзине есть товары, которые нельзя заказать: "' . $product->get_name() . '".', 'error');
                    break;
                }
            }
        }
    }
});

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

  • Добавьте в магазин товар или вариацию с атрибутом pa_status=discontinued.
  • Положите этот товар в корзину.
  • Проверьте, что товар автоматически удаляется при обновлении корзины или выводится ошибка при попытке оформить заказ.
  • Посмотрите логи PHP, чтобы убедиться, что сниппеты работают корректно (если добавляли диагностический код).

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

  • Неправильное имя атрибута: WooCommerce добавляет префикс pa_ к пользовательским атрибутам. Проверьте точное имя атрибута в админке в разделе Товары – Атрибуты.
  • Атрибут не привязан к товару: убедитесь, что атрибут назначен товарам и что у вариаций есть правильные значения.
  • Кэширование корзины: если используется плагин кэширования, отключите кэширование страниц корзины и оформления заказа, иначе изменения не будут видны.
  • Конфликты с другими плагинами: временно деактивируйте плагины, влияющие на корзину, чтобы проверить корректность работы кода.

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

  • Для больших магазинов избегайте перебора всех товаров в корзине слишком часто. Используйте хуки, которые срабатывают только по необходимости (например, woocommerce_before_calculate_totals).
  • Кэшируйте результаты запросов атрибутов, если планируете расширять функцию.
  • Не выводите в пользовательский интерфейс подробные технические сообщения — используйте только понятные уведомления.
  • Тестируйте изменения на копии сайта, чтобы избежать сбоев в рабочем магазине.

Сравнение вариантов решения

МетодПлюсыМинусыПример
Фильтрация через код (хук)Максимальный контроль, без лишних плагиновТребует навыков PHP, нужно тестироватьКод из статьи
Плагины с фильтрацией по атрибутамПростота настройки, готовые решенияЧасто платные, могут влиять на производительностьWooCommerce Conditional Shipping and Payments
Использование групп цен или статусов товараГибкое управление на уровне WooCommerceСложнее настроить, требует дополнительных плагиновГруппы пользователей + цены
Исключение товаров и вариантов WooCommerce по атрибуту: практическое руководство
22.04.2026
Как избежать конфликтов между плагинами в WordPress
26.12.2025
Автоматическое удаление оставшихся частей кода в WordPress после деактивации плагинов
20.11.2025
Как удалить зависшие варианты рубрик в WordPress
17.02.2026
Обновление WordPress без проблем: практическое руководство от WPReg
31.10.2025