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

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

В WooCommerce часто возникает задача запретить покупку или исключить из корзины товары с определёнными атрибутами (например, товары с пометкой "Распродажа", "Пробный образец" или товары, не подлежащие продаже через корзину). Это может понадобиться для соблюдения бизнес-правил, предотвращения конфликтов в заказах или управления ассортиментом.

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

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

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

Сначала определите, какие именно атрибуты будут служить фильтром. Например, допустим, у вас есть атрибут pa_sale_status с терминами: regular, clearance, sample. Нужно исключить из корзины товары с атрибутом pa_sale_status=sample.

2. Добавление фильтра в functions.php или через плагин

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

add_action('woocommerce_check_cart_items', 'exclude_products_by_attribute_from_cart');
function exclude_products_by_attribute_from_cart() {
    // Атрибут и значение, по которым исключаем товары
    $attribute_name = 'pa_sale_status';
    $excluded_term_slug = 'sample';

    // Получаем корзину
    foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
        $product = $cart_item['data'];
        $product_id = $product->get_id();

        // Получаем термины атрибута у товара
        $terms = wp_get_post_terms($product_id, $attribute_name, array('fields' => 'slugs'));

        if (in_array($excluded_term_slug, $terms)) {
            // Удаляем товар из корзины
            WC()->cart->remove_cart_item($cart_item_key);

            // Добавляем уведомление для пользователя
            wc_add_notice(sprintf('Товар "%s" исключен из корзины, так как не подлежит продаже через корзину.', $product->get_name()), 'error');
        }
    }
}

3. Кэширование и оптимизация

Функция wp_get_post_terms вызывается для каждого товара в корзине, что при большом количестве товаров может влиять на производительность. Для оптимизации можно закешировать результаты в статической переменной:

add_action('woocommerce_check_cart_items', 'exclude_products_by_attribute_from_cart_optimized');
function exclude_products_by_attribute_from_cart_optimized() {
    $attribute_name = 'pa_sale_status';
    $excluded_term_slug = 'sample';
    static $product_terms_cache = [];

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

        if (!isset($product_terms_cache[$product_id])) {
            $product_terms_cache[$product_id] = wp_get_post_terms($product_id, $attribute_name, array('fields' => 'slugs'));
        }

        if (in_array($excluded_term_slug, $product_terms_cache[$product_id])) {
            WC()->cart->remove_cart_item($cart_item_key);
            wc_add_notice(sprintf('Товар "%s" исключен из корзины, так как не подлежит продаже через корзину.', $product->get_name()), 'error');
        }
    }
}

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

  1. Добавьте в магазин товар с атрибутом pa_sale_status=sample.
  2. Добавьте этот товар в корзину вместе с обычным товаром.
  3. Перейдите в корзину или оформление заказа.
  4. Убедитесь, что товар с атрибутом sample автоматически удаляется из корзины и появляется уведомление об удалении.
  5. Если товар остался, проверьте логи сервера и логи WooCommerce на наличие ошибок.

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

  • Атрибут указан неверно: Убедитесь, что в коде указан правильный slug атрибута, он всегда начинается с pa_ и совпадает со slugом в WooCommerce.
  • Товары не удаляются, уведомление не появляется: Возможно, конфликт с другим плагином, который перехватывает woocommerce_check_cart_items. Проверьте деактивацию других плагинов или поместите код в плагин с более высоким приоритетом.
  • Производительность падает при большом количестве товаров: Используйте кеширование термов, как показано в оптимизированном варианте кода.
  • Удаление товара в корзине не обновляется визуально: Проверьте, что корзина перезагружается при изменениях, при необходимости добавьте JavaScript для обновления.

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

  • Не выполняйте запросы к базе данных внутри циклов без кеширования.
  • Проверяйте, что пользователь имеет права на просмотр товаров, чтобы избежать утечки информации.
  • Для больших магазинов используйте transient API для кэширования результатов запросов к атрибутам.
  • Добавляйте уведомления через wc_add_notice в пользовательском контексте, не блокируя процесс оформления заказа.

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

МетодПреимуществаНедостаткиПрименение
Код на хуке woocommerce_check_cart_itemsГибкий, не требует плагинов, можно точно настроитьТребует навыков PHP, возможны конфликты с плагинамиМалые и средние магазины с кастомными требованиями
Плагины для фильтрации корзиныПростота установки, готовые настройкиМогут быть ограничены в функционале, нагрузкаБыстрое решение без кастомизации
Модификация шаблонов WooCommerceКонтроль над отображением, UXНе исключает товары из корзины, только скрываетДополнительный UX, не основное решение
Автоматическое изменение метаданных SEO в WordPress
22.03.2026
WooCommerce: автоматическое удаление товаров из магазина по статусу заказов
04.06.2026
WooCommerce: как автоматически удалять неактивных клиентов по истории заказов
13.07.2026
Как добавить автоматическое отображение отзывов в WordPress
16.04.2026
Как автоматизировать создание и удаление туториалов в WordPress
26.02.2026