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

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

В интернет-магазинах на WooCommerce иногда требуется запретить покупку товаров с определёнными атрибутами в одной корзине или полностью блокировать добавление таких товаров. Например, если товар содержит атрибут «Тип: Скидка» или «Состояние: Распродажа», и вы хотите запретить их совместное приобретение с другими товарами или исключить из корзины. Это может быть связано с акциями, ограничениями поставщиков или логистикой.

Рассмотрим, как программно убрать из корзины товары с заданными атрибутами и уведомить пользователя.

Пошаговое решение: удаление товаров по атрибутам из корзины

1. Получение атрибутов товара в корзине

Для проверки атрибутов используем объект WC_Product из элемента корзины WC_Cart_Item. Атрибуты находятся в методе get_attributes(), но для пользовательских атрибутов лучше получить метаданные варианта или товара.

function has_attribute( $product, $attribute_name, $attribute_value ) {
    $attributes = $product->get_attributes();
    foreach ( $attributes as $attribute ) {
        if ( $attribute->is_taxonomy() ) {
            $terms = wp_get_post_terms( $product->get_id(), $attribute->get_name(), array('fields' => 'names') );
            if ( in_array( $attribute_value, $terms, true ) ) {
                return true;
            }
        } else {
            // Для пользовательских атрибутов
            if ( $attribute->get_name() === $attribute_name && $attribute->get_options() ) {
                if ( in_array( $attribute_value, $attribute->get_options(), true ) ) {
                    return true;
                }
            }
        }
    }
    return false;
}

2. Фильтрация корзины и удаление товаров

Добавим проверку на событие woocommerce_before_calculate_totals, чтобы пройти по корзине и удалить товары с нужным атрибутом. Также уведомим пользователя через сессионное сообщение.

add_action( 'woocommerce_before_calculate_totals', 'remove_products_by_attribute_from_cart', 10, 1 );
function remove_products_by_attribute_from_cart( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
        return;
    }

    $attribute_name  = 'pa_sostoyanie'; // пример: slug атрибута
    $attribute_value = 'rasprodazha'; // значение атрибута

    $removed = false;

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

        if ( has_attribute( $product, $attribute_name, $attribute_value ) ) {
            $cart->remove_cart_item( $cart_item_key );
            $removed = true;
        }
    }

    if ( $removed ) {
        wc_add_notice( 'Из корзины были удалены товары с атрибутом "Распродажа".', 'error' );
    }
}

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

  • Добавьте в каталог товар с нужным атрибутом (например, pa_sostoyanie=rasprodazha).
  • Попробуйте добавить этот товар в корзину.
  • После обновления корзины товар должен автоматически удалиться, а пользователь увидит сообщение об удалении.
  • Товары без указанного атрибута остаются в корзине без изменений.

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

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

  • Неправильный slug атрибута: В WooCommerce для глобальных атрибутов используется prefix pa_. Проверьте slug атрибута в админке (Товары → Атрибуты).
  • Атрибут не глобальный, а пользовательский: В этом случае атрибуты могут храниться иначе, и их нужно получать из мета полей товара или варианта.
  • Удаление товаров с вариациями: Если в корзине вариации, проверяйте атрибуты вариации, а не родительского товара.
  • Сообщение не выводится: Убедитесь, что функция wc_add_notice вызывается в правильном месте и что шаблон корзины поддерживает вывод уведомлений.

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

  • Вызывайте функцию удаления только на фронтенде, чтобы не влиять на админ-панель и AJAX-запросы без необходимости.
  • Кэширование: При активных плагинах кэширования убедитесь, что корзина обновляется корректно и сообщения выводятся сразу.
  • Логирование: Для отладки добавьте временный лог в файл, чтобы отслеживать срабатывание удаления.
  • Улучшение UX: Можно добавить JavaScript-уведомления и блокировать кнопку оформления заказа, если в корзине остаются запрещённые товары.

Сравнение вариантов реализации удаления товаров по атрибутам

МетодПлюсыМинусыПрименимость
PHP-хук woocommerce_before_calculate_totalsПолный контроль, сразу удаляет товары при обновлении корзиныНельзя предотвратить добавление товара, только удалять послеПодходит для большинства случаев
Валидация при добавлении в корзину (woocommerce_add_to_cart_validation)Предотвращает добавление нежелательных товаровСложнее проверять уже добавленные товары, требуется дополнительная логикаЕсли нужно блокировать добавление заранее
JavaScript на фронтендеБыстрая реакция, можно предупредить пользователяМожно отключить, не защищает серверДля улучшения UX, но не как основное решение
Как отключить Gutenberg и оставить классический редактор в WordPress
25.02.2026
Оптимизация базы данных WordPress без повышения нагрузки на сервер
11.12.2025
Как создать автоматический импорт из внешнего источника с обработкой ошибок в WordPress
17.04.2026
Как создать автоматически обновляемый сайт на WordPress с помощью WPRemark
12.03.2026
Как защитить WordPress от ботов и спама с помощью плагинов и кода
04.02.2026