Диагностика проблемы: зачем исключать товары из корзины по категориям
В интернет-магазинах на WooCommerce иногда требуется блокировать добавление в корзину товаров из определённых категорий. Например, товары с ограниченной доставкой, акционные позиции, либо товары, которые продаются только оптом и требуют отдельного оформления заказа. Стандартными средствами WooCommerce таких ограничений нет, поэтому пользователям приходится искать кастомные решения.
Как настроить автоматическое исключение товаров из корзины по категориям
Пошаговое решение через хук woocommerce_add_to_cart_validation
Для реализации исключения товаров из корзины по категориям нужно использовать фильтр woocommerce_add_to_cart_validation. Он позволяет остановить добавление товара в корзину при выполнении заданных условий.
Ниже пример кода, который запрещает добавлять товары из категорий с ID 15 и 22.
add_filter('woocommerce_add_to_cart_validation', 'exclude_products_by_category_from_cart', 10, 3);function exclude_products_by_category_from_cart($passed, $product_id, $quantity) { $excluded_cat_ids = array(15, 22); if (has_term($excluded_cat_ids, 'product_cat', $product_id)) { wc_add_notice('Товар из выбранной категории нельзя добавить в корзину.', 'error'); return false; } return $passed;}Объяснение кода
- Функция
has_termпроверяет, принадлежит ли товар к одной из запрещённых категорий. - При совпадении возвращается
false, и добавление в корзину блокируется. - Сообщение об ошибке выводится через
wc_add_notice.
Проверка результата после внедрения
Для проверки:
- Попробуйте добавить в корзину товар из запрещённой категории — должен появиться вывод ошибки, а товар не добавится.
- Добавьте товар из допустимой категории — он должен успешно попасть в корзину.
Также проверьте работу на нескольких браузерах и с отключёнными кэш-плагинами, чтобы исключить кеширование ошибок.
Частые ошибки и способы их исправления
- Ошибка: сообщение об ошибке не выводится. Проверьте, правильно ли подключён хук, нет ли конфликтов с другими плагинами, и включена ли поддержка уведомлений WooCommerce (функция
wc_print_notices()должна выводиться в шаблоне). - Ошибка: товары всё равно добавляются. Возможно, ID категорий указаны неверно — проверьте через админку WooCommerce или используйте функцию
print_r(wp_get_post_terms($product_id, 'product_cat'))для отладки. - Ошибка: код мешает работе других функций корзины. Убедитесь, что функция всегда возвращает
$passedдля разрешённых товаров.
Практические советы по безопасности и производительности
- Не храните массив категорий напрямую в коде, лучше вынести в настройки темы или плагина.
- Если категорий много, кешируйте их ID или используйте слаг категории для удобства.
- Избегайте дублирования проверок в других хуках, чтобы не замедлять процесс добавления в корзину.
- Тестируйте на staging-версии сайта, чтобы не нарушить пользовательский опыт на рабочем магазине.
Дополнительный вариант: удаление товаров из корзины после добавления
Если нужно не блокировать добавление, а автоматически удалять товары из определённых категорий из уже существующей корзины, используйте следующий код:
add_action('woocommerce_before_calculate_totals', 'remove_excluded_category_products_from_cart');function remove_excluded_category_products_from_cart($cart) { if (is_admin() && !defined('DOING_AJAX')) { return; } $excluded_cat_ids = array(15, 22); foreach ($cart->get_cart() as $cart_item_key => $cart_item) { $product_id = $cart_item['product_id']; if (has_term($excluded_cat_ids, 'product_cat', $product_id)) { $cart->remove_cart_item($cart_item_key); wc_add_notice('Товар из запрещённой категории был удалён из корзины.', 'notice'); } }}Сравнение подходов
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_add_to_cart_validation | Блокирует добавление товара из категории | Простое решение, пользователь сразу видит ошибку | Не удаляет товары, добавленные до установки |
Хук woocommerce_before_calculate_totals | Удаляет запрещённые товары из корзины | Обрабатывает старые товары в корзине, универсально | Пользователь может сначала добавить товар, потом его удалят |