Диагностика задачи: зачем исключать товары из категории из корзины
В WooCommerce иногда требуется запретить добавление в корзину товаров из определённых категорий, например, для товаров под заказ, услуг или акционных позиций, которые нельзя купить вместе с другими товарами. Это повышает удобство клиента и предотвращает ошибки оформления заказа.
Какие способы исключения товаров из категории из корзины существуют
Для решения задачи есть три основных подхода:
- Запрет добавления товара из категории в корзину (через хук
woocommerce_add_to_cart_validation); - Автоматическое удаление товара из корзины при наличии товара из запрещённой категории (через
woocommerce_before_calculate_totalsилиwoocommerce_check_cart_items); - Скрытие кнопки "Добавить в корзину" на странице товара и архивах.
В статье рассмотрим самый универсальный вариант — запретить добавление таких товаров и автоматически очищать корзину от запрещённых товаров, если они там есть.
Пошаговое решение: запрет добавления и очистка корзины
1. Определяем ID категорий, которые нужно исключить
Для примера возьмём категорию с ярлыком excluded-category. Получим её ID программно или через админку.
2. Запрет добавления в корзину товаров из категории
Добавим следующий код в functions.php вашей темы или в кастомный плагин:
add_filter('woocommerce_add_to_cart_validation', 'exclude_category_from_cart', 10, 3);
function exclude_category_from_cart($passed, $product_id, $quantity) {
// ID категорий для исключения
$excluded_cat_slugs = array('excluded-category');
// Получаем категории товара
$terms = get_the_terms($product_id, 'product_cat');
if (!$terms || is_wp_error($terms)) {
return $passed;
}
foreach ($terms as $term) {
if (in_array($term->slug, $excluded_cat_slugs)) {
wc_add_notice('Товары из категории "' . $term->name . '" нельзя добавлять в корзину.', 'error');
return false;
}
}
return $passed;
}3. Автоматическая очистка корзины от запрещённых товаров
Чтобы избежать ситуации, когда запрещённые товары уже есть в корзине, добавим проверку при загрузке корзины:
add_action('woocommerce_check_cart_items', 'remove_excluded_category_from_cart');
function remove_excluded_category_from_cart() {
$excluded_cat_slugs = array('excluded-category');
$cart = WC()->cart->get_cart();
foreach ($cart as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$terms = get_the_terms($product_id, 'product_cat');
if (!$terms || is_wp_error($terms)) {
continue;
}
foreach ($terms as $term) {
if (in_array($term->slug, $excluded_cat_slugs)) {
WC()->cart->remove_cart_item($cart_item_key);
wc_add_notice('Товар "' . $cart_item['data']->get_name() . '" был удалён из корзины, так как он относится к запрещённой категории.', 'notice');
break;
}
}
}
}Проверка результата после внедрения
- Попробуйте добавить в корзину товар из категории
excluded-category. Вы должны увидеть ошибку и товар не добавится. - Добавьте товар из другой категории — он добавится как обычно.
- Если в корзине были запрещённые товары, зайдите на страницу корзины и убедитесь, что они автоматически удалились с соответствующим уведомлением.
Частые ошибки и как их исправить
- Ошибка: товары из категории продолжают добавляться. Проверьте, что slug категории указан правильно. Используйте
print_r(get_terms('product_cat'));для поиска slug. - Уведомления не отображаются. Убедитесь, что в теме есть вызов
wc_print_notices()в шаблоне корзины и на страницах магазина. - Кэш мешает увидеть изменения. Очистите кэш сайта и браузера.
- Конфликты с другими плагинами корзины. Отключите сторонние плагины, чтобы проверить влияние.
Практические советы по безопасности и производительности
- Для производительности кешируйте ID категорий и slug, чтобы не выполнять повторные запросы в базе для каждого товара.
- В больших магазинах при большом количестве товаров проверяйте, чтобы код не вызывал лишних нагрузок — например, используйте
wp_cache_getдля кеша. - Для безопасности не выводите в сообщениях слуг категорий, а только человекочитаемые имена.
Сравнение подходов: запрет добавления vs очистка корзины vs скрытие кнопок
| Метод | Плюсы | Минусы | Компромисс |
|---|---|---|---|
| Запрет добавления (код) | Чёткий контроль, пользователь сразу видит ошибку | Не защищает от уже добавленных товаров | Совместить с очисткой корзины |
| Автоочистка корзины | Удаляет запрещённые товары, защищает оформление заказа | Пользователь может быть недоволен удалением без предупреждения заранее | Добавить уведомления |
| Скрытие кнопок | Простое UX-решение | Можно обойти через прямые ссылки, не защищает полностью | Использовать вместе с серверными проверками |