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

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

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

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

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

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

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

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

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

1. Определяем атрибут и значение для исключения

Допустим, у нас есть атрибут pa_availability (па — префикс для Product Attribute), и мы хотим исключить товары с значением no-online.

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

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

add_filter('woocommerce_add_to_cart_validation', function($passed, $product_id, $quantity) {
    $product = wc_get_product($product_id);
    $attributes = $product->get_attributes();

    if (isset($attributes['pa_availability'])) {
        $terms = wp_get_post_terms($product_id, 'pa_availability', array('fields' => 'slugs'));
        if (in_array('no-online', $terms)) {
            wc_add_notice('Этот товар недоступен для онлайн-покупки.', 'error');
            return false;
        }
    }
    return $passed;
}, 10, 3);

3. Исключение товара из корзины, если он там уже есть

Если товар уже в корзине (например, добавлен до внедрения проверки), нужно автоматически удалить его:

add_action('woocommerce_before_cart', function() {
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
        $product_id = $cart_item['product_id'];
        $terms = wp_get_post_terms($product_id, 'pa_availability', array('fields' => 'slugs'));
        if (in_array('no-online', $terms)) {
            WC()->cart->remove_cart_item($cart_item_key);
            wc_add_notice('Товар с ограничением онлайн-продажи был удалён из корзины.', 'notice');
        }
    }
});

4. Проверка перед оформлением заказа

Для страховки добавьте проверку перед оформлением заказа, чтобы заблокировать оформление, если в корзине остались запрещённые товары:

add_action('woocommerce_check_cart_items', function() {
    foreach (WC()->cart->get_cart() as $cart_item) {
        $product_id = $cart_item['product_id'];
        $terms = wp_get_post_terms($product_id, 'pa_availability', array('fields' => 'slugs'));
        if (in_array('no-online', $terms)) {
            wc_add_notice('В корзине есть товары, которые нельзя приобрести онлайн.', 'error');
            break;
        }
    }
});

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

  • Попытайтесь добавить в корзину товар с атрибутом pa_availability=no-online — он не должен добавиться, появится сообщение об ошибке.
  • Если такой товар уже в корзине, обновите страницу корзины — товар должен удалиться автоматически.
  • Попытка оформить заказ с запрещённым товаром должна блокироваться с ошибкой.

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

  • Неправильное имя атрибута или его значение. Проверьте точное имя атрибута через админку или функцию get_attributes().
  • Атрибут задан в виде текстового поля, а не термина. В WooCommerce атрибуты бывают пользовательскими (пользовательский текст) и глобальными (терминами). Для фильтрации используйте именно термины.
  • Кэширование корзины не обновляется. Очистите кэш браузера и серверный кэш (если используется).
  • Конфликт с другими плагинами, которые управляют корзиной. Временно отключите сторонние плагины для теста.

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

  • Не добавляйте тяжелые запросы в хуки, которые срабатывают на каждом просмотре корзины — кэшируйте результаты, если товарная база большая.
  • Используйте проверку не только по атрибуту, но и по статусу товара ($product->is_purchasable()), чтобы избежать добавления недоступных товаров.
  • Для больших магазинов рассмотрите вариант кеширования атрибутов товаров, чтобы не выполнять лишних запросов к базе в цикле.

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

МетодПлюсыМинусы
Фильтрация добавления в корзину (woocommerce_add_to_cart_validation)Не допускает добавления запрещённых товаров, пользователь сразу получает ошибкуНе убирает товары, добавленные до внедрения
Удаление товаров из корзины (woocommerce_before_cart)Автоматически очищает корзину от запрещённых товаровМожет создавать неудобства, если пользователь не сразу поймёт причину удаления
Проверка оформления заказа (woocommerce_check_cart_items)Финальная страховка, блокирует заказПоздняя проверка, пользователь уже прошёл часть процесса
Как массово удалить неиспользуемые медиа файлы в WordPress
09.12.2025
Как исключить товары WooCommerce по атрибуту из корзины и оформления заказа
03.05.2026
Как использовать WooCommerce хуки для настройки процесса оформления заказа
22.04.2026
Автоматическое удаление неактивных клиентов в WooCommerce
07.06.2026
Как удалить неиспользуемые таксономии и термины в WordPress
02.01.2026