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

Почему нужно исключать товары из корзины по атрибутам?

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

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

Для начала нужно понять, какие атрибуты есть у товаров, и как WooCommerce хранит их данные. Атрибуты в WooCommerce — это термины таксономии, например, pa_color, pa_size. В корзине каждый объект содержит ID товара, но не сразу атрибуты.

Чтобы вывести атрибуты товаров в корзине для диагностики, можно использовать следующий код, добавив его в functions.php темы:

add_action('woocommerce_before_cart', function() {
    foreach (WC()->cart->get_cart() as $cart_item) {
        $product = $cart_item['data'];
        echo '<pre>';
        print_r($product->get_attributes());
        echo '</pre>';
    }
});

После этого на странице корзины вы увидите массивы атрибутов товаров. Это поможет определить ключи и значения атрибутов для фильтрации.

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

Основная идея — использовать хук woocommerce_check_cart_items для проверки корзины перед оформлением заказа и удалять товары с нужными атрибутами или блокировать оформление заказа.

Пример кода, который удаляет товары с атрибутом pa_discount со значением 50% из корзины с уведомлением:

add_action('woocommerce_check_cart_items', function() {
    $cart = WC()->cart;
    $items_to_remove = [];

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

        if (isset($attributes['pa_discount'])) {
            // Получаем значение атрибута из объекта WC_Product
            $terms = wp_get_post_terms($product->get_id(), 'pa_discount', ['fields' => 'names']);
            if (in_array('50%', $terms)) {
                $items_to_remove[] = $cart_item_key;
            }
        }
    }

    if (!empty($items_to_remove)) {
        foreach ($items_to_remove as $key) {
            $cart->remove_cart_item($key);
        }
        wc_add_notice('Некоторые товары с атрибутом "Скидка 50%" были удалены из корзины.', 'error');
    }
});

Если нужно просто запретить оформление заказа, а не удалять товары, можно заменить логику на добавление wc_add_notice с ошибкой и вызовом wp_safe_redirect для возврата на страницу корзины.

Альтернативный способ: блокировка добавления в корзину

Чтобы предотвратить добавление товара с определённым атрибутом в корзину, используйте фильтр woocommerce_add_to_cart_validation:

add_filter('woocommerce_add_to_cart_validation', function($passed, $product_id) {
    $terms = wp_get_post_terms($product_id, 'pa_discount', ['fields' => 'names']);
    if (in_array('50%', $terms)) {
        wc_add_notice('Товар с атрибутом "Скидка 50%" нельзя добавить в корзину.', 'error');
        return false;
    }
    return $passed;
}, 10, 2);

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

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

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

  • Неверное имя атрибута: В WooCommerce атрибуты имеют префикс pa_. Убедитесь, что используете правильный слаг (slug) атрибута, например, pa_color, а не просто color.
  • Атрибуты не передаются в объект WC_Product: Метод get_attributes() возвращает массив объектов WC_Product_Attribute, а не значения термов. Для получения значений используйте wp_get_post_terms().
  • Удаление товара не работает: Убедитесь, что вы вызываете $cart->remove_cart_item($cart_item_key) с правильным ключом корзины.
  • Сообщения не отображаются: Проверьте, что шаблон темы выводит уведомления WooCommerce, через функцию wc_print_notices() или woocommerce_output_all_notices().

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

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

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

МетодПлюсыМинусыКогда использовать
Удаление товаров из корзины (woocommerce_check_cart_items)Гарантированное удаление, можно показывать уведомлениеМожет раздражать пользователя, если товар уже добавленЕсли нельзя продавать товар в принципе
Блокировка добавления в корзину (woocommerce_add_to_cart_validation)Пользователь сразу информирован, товар не попадает в корзинуНе помогает, если товар уже в корзинеПредотвратить добавление запрещённых товаров
Блокировка оформления заказаНе удаляет товары, можно дать разъясненияПользователь может быть расстроен на последнем шагеЕсли нужно разрешить просмотр, но не покупку
Как создать свой плагин для WordPress с примерами кода
21.11.2025
Как удалить или изменить URL страницы в WordPress без потери SEO
05.01.2026
Как добавить дополнительное поле в форму регистрации WordPress
22.12.2025
WooCommerce: как отключить кэширование страницы корзины для корректной работы
01.07.2026
WooCommerce: как автоматически удалять заказы по статусу после оплаты
31.05.2026