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

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

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

Типичная ошибка — попытка убрать товар из корзины по ID, что неудобно при большом ассортименте с динамическими атрибутами. Правильнее работать именно с атрибутами, чтобы решение было универсальным.

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

В WooCommerce атрибуты хранятся в объекте товара WC_Product. Их можно получить через метод get_attributes(). В корзине нужно пройтись по всем элементам и проверить атрибуты товара.

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
    $product = $cart_item['data'];
    $attributes = $product->get_attributes();
    // $attributes - массив WC_Product_Attribute объектов
}

Пример: как вывести все атрибуты товара в корзине

foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
    $product = $cart_item['data'];
    $attributes = $product->get_attributes();
    foreach ( $attributes as $attribute ) {
        // Получаем имя атрибута
        $name = $attribute->get_name();
        // Получаем значения атрибута (массив или строка)
        $options = $attribute->get_options();
        error_log('Атрибут: ' . $name . '; Значения: ' . implode(', ', $options));
    }
}

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

Допустим, нужно исключить все товары с атрибутом pa_sale и значением no. Это значит, что товары с этим атрибутом не должны попадать в корзину.

Шаг 1. Создаём фильтр на добавление товара в корзину

add_filter('woocommerce_add_to_cart_validation', 'exclude_products_by_attribute', 10, 3);
function exclude_products_by_attribute($passed, $product_id, $quantity) {
    $product = wc_get_product($product_id);
    if ( ! $product ) {
        return $passed;
    }
    $attributes = $product->get_attributes();
    // Проверяем наличие нужного атрибута
    if ( isset($attributes['pa_sale']) ) {
        $attribute = $attributes['pa_sale'];
        $options = $attribute->get_options();
        // Если значение "no" найдено, блокируем добавление
        if ( in_array('no', $options) ) {
            wc_add_notice('Этот товар нельзя добавить в корзину.', 'error');
            return false;
        }
    }
    return $passed;
}

Шаг 2. Удаляем товары с этим атрибутом из уже добавленных (например, при обновлении корзины)

add_action('woocommerce_check_cart_items', 'remove_products_by_attribute_from_cart');
function remove_products_by_attribute_from_cart() {
    foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
        $product = $cart_item['data'];
        $attributes = $product->get_attributes();
        if ( isset($attributes['pa_sale']) ) {
            $attribute = $attributes['pa_sale'];
            $options = $attribute->get_options();
            if ( in_array('no', $options) ) {
                WC()->cart->remove_cart_item($cart_item_key);
                wc_add_notice('Товар "' . $product->get_name() . '" удалён из корзины, так как не может быть куплен.', 'notice');
            }
        }
    }
}

Проверка результата

  • Попробуйте добавить в корзину товар с атрибутом pa_sale=no. Добавление должно быть заблокировано с сообщением об ошибке.
  • Если товар уже в корзине, обновите корзину — товар должен автоматически удалиться с уведомлением.
  • Проверьте через error_log или отладчик, что фильтр срабатывает именно на нужных товарах.

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

  • Ошибка: Атрибуты не проверяются, потому что используете slug атрибута без префикса pa_.
    Решение: WooCommerce добавляет префикс pa_ для пользовательских атрибутов. Обязательно используйте его.
  • Ошибка: Значения атрибута не совпадают, т.к. сравниваете с неправильным регистром или форматом.
    Решение: Проверяйте через error_log реальные значения из $attribute->get_options() — они всегда в нижнем регистре и без пробелов.
  • Ошибка: Товар с атрибутом удаляется, но страница корзины не обновляется.
    Решение: После удаления используйте принудительное обновление корзины или AJAX, если корзина динамическая.

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

  • Не используйте запросы к базе напрямую для проверки атрибутов — это замедляет работу. Используйте объектные методы WooCommerce.
  • Фильтр woocommerce_add_to_cart_validation срабатывает быстро, поэтому лучше проверять атрибуты именно там, чтобы не добавлять лишние товары в корзину.
  • Если атрибутов много, кэшируйте результаты проверки в сессии или transient, чтобы не делать повторные вызовы.
  • Добавляйте пользовательские сообщения через wc_add_notice, чтобы пользователь понимал причину блокировки товара.

Сравнение способов исключения товаров из корзины

МетодОписаниеПлюсыМинусы
Фильтр woocommerce_add_to_cart_validation Блокировка добавления товара сразу Лёгкий, предотвращает попадание товара в корзину Не удаляет товар, добавленный ранее
Хук woocommerce_check_cart_items Удаление товаров уже в корзине Работает при обновлении корзины, гарантирует чистоту корзины Может вызвать неудобства из-за внезапного удаления товара
JS-валидация в фронтенде Блокировка на клиенте Быстрая реакция, удобство для пользователя Можно обойти, не безопасно
Как отключить эмодзи в WordPress без потери функционала
13.12.2025
Как создать шорткод для вывода случайного поста в WordPress
29.11.2025
Оптимизация базы данных WordPress: практические советы от WPID
04.11.2025
Как сделать автоматическое удаление старого контента в WordPress
26.12.2025
Как удалить или изменить URL страницы в WordPress без потери SEO
05.01.2026