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

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

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

Как проверить, есть ли в корзине товары с определённым атрибутом

Для начала нужно программно проверить, присутствуют ли товары с нужным атрибутом в корзине. Атрибуты в WooCommerce хранятся в метаданных продукта, и доступны через объект WC_Product.

function cart_has_product_with_attribute( $attribute_name, $attribute_value ) {
  foreach ( WC()->cart->get_cart() as $cart_item ) {
    $product = $cart_item['data'];
    $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_options() && in_array( $attribute_value, $attribute->get_options(), true ) ) {
          return true;
        }
      }
    }
  }
  return false;
}

Этот код проверяет корзину на наличие товара с определённым значением атрибута.

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

Далее реализуем хук woocommerce_add_to_cart_validation, который срабатывает перед добавлением товара в корзину. Если в корзине уже есть товар с запрещённым атрибутом, отменим добавление и покажем сообщение об ошибке.

add_filter( 'woocommerce_add_to_cart_validation', 'prevent_conflicting_attributes_in_cart', 10, 3 );
function prevent_conflicting_attributes_in_cart( $passed, $product_id, $quantity ) {
  $product = wc_get_product( $product_id );

  // Пример: нельзя добавить товар с атрибутом "promo", если в корзине есть товар с "sale"
  $new_product_has_promo = has_term( 'promo', 'pa_special', $product_id );
  $cart_has_sale = cart_has_product_with_attribute( 'pa_special', 'sale' );

  if ( $new_product_has_promo && $cart_has_sale ) {
    wc_add_notice( 'Нельзя добавлять товары с атрибутом "promo" вместе с товарами по акции.', 'error' );
    return false;
  }

  // Аналогично проверяем обратную ситуацию
  $new_product_has_sale = has_term( 'sale', 'pa_special', $product_id );
  $cart_has_promo = cart_has_product_with_attribute( 'pa_special', 'promo' );

  if ( $new_product_has_sale && $cart_has_promo ) {
    wc_add_notice( 'Нельзя добавлять товары по акции вместе с товарами с атрибутом "promo".', 'error' );
    return false;
  }

  return $passed;
}

Здесь pa_special — это slug атрибута, например, «pa_special» для атрибута «Специальные предложения».

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

  • Добавьте в корзину товар с атрибутом sale.
  • Попробуйте добавить товар с атрибутом promo. Вы должны увидеть ошибку и товар не добавится.
  • Проверьте обратную ситуацию — сначала товар с promo, потом с sale.
  • Добавление товаров без конфликтующих атрибутов происходит без ошибок.

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

  • Неправильный slug атрибута или значения. Проверьте в админке WooCommerce в разделе «Атрибуты» точный slug (например, pa_special), а также названия терминов. Ошибки в регистре или опечатки приводят к пропуску проверки.
  • Проверка атрибутов у вариативных продуктов. Если товар вариативный, атрибуты могут находиться в дочерних продуктах (вариациях). Нужно проверять именно вариацию, которая добавляется в корзину.
  • Кэш корзины. Если вы используете плагин кэширования, убедитесь, что корзина обновляется корректно и нет кеширования AJAX-запросов.

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

  • Храните проверяемые атрибуты и их значения в константах или настройках, чтобы можно было быстро менять логику без правки кода.
  • Не используйте тяжелые запросы к базе данных в хуках, вызываемых часто. Кэшируйте результаты, если проверка сложная.
  • Тестируйте на разных версиях WooCommerce и WordPress, особенно если используете кастомные темы или плагинов, которые могут влиять на корзину.
  • Логируйте ошибки с помощью error_log() или специализированных плагинов, чтобы быстро находить проблемы.

Сравнение вариантов реализации

ВариантПлюсыМинусы
Код на hook woocommerce_add_to_cart_validationГибко, без плагинов, точечный контрольТребует навыков PHP, может конфликтовать с кастомными плагинами
Плагин с настройками атрибутовПростота настройки, интерфейсЗависимость от стороннего кода, возможные платные лицензии
JavaScript-валидация на фронтендеБыстрая обратная связь пользователюМожно обойти, не гарантирует защиту на сервере
WooCommerce: как автоматически удалять товары без склада из каталога
10.07.2026
Оптимальные хуки для улучшения производительности WordPress
29.11.2025
Как отключить регистрацию по бесплатным email в WordPress
21.03.2026
Как отключить AJAX в WooCommerce без потери функциональности
08.12.2025
Удаление неиспользуемых изображений в WordPress для оптимизации сайта
20.12.2025