Диагностика проблемы: почему нужно исключать товары по атрибуту из корзины и оформления
В интернет-магазинах на WooCommerce иногда возникает задача исключить определённые товары или варианты из корзины и оформления заказа. Обычно это связано с ограничениями по доставке, акциями, юридическими требованиями или особенностями товара. Например, товары с атрибутом нельзя-доставить нужно запретить к покупке, чтобы избежать конфликтов и возвратов.
Без такой фильтрации пользователь может оформить заказ с запрещёнными товарами, что приведёт к проблемам в обработке и неудовлетворённости клиента.
Как проверить, что товар имеет нужный атрибут
Атрибуты в WooCommerce хранятся как термины таксономии. Чтобы проверить, есть ли у товара атрибут, используйте следующий код:
function has_product_attribute( $product_id, $attribute_slug, $term_slug ) {
$taxonomy = 'pa_' . $attribute_slug; // Префикс pa_ для атрибутов
$terms = wp_get_post_terms( $product_id, $taxonomy );
if ( is_wp_error( $terms ) || empty( $terms ) ) {
return false;
}
foreach ( $terms as $term ) {
if ( $term->slug === $term_slug ) {
return true;
}
}
return false;
}Пример: проверить, есть ли у товара атрибут ne-dostavlyaetsya с термином da (т.е. «нельзя доставить» = «да»).
Пошаговое решение: исключение товаров и вариантов по атрибуту из корзины и оформления заказа
Ниже приведён полный код, который:
- Блокирует добавление в корзину товаров с определённым атрибутом
- Удаляет такие товары из уже существующей корзины при переходе к оформлению
- Выводит уведомление пользователю о причине удаления
add_filter( 'woocommerce_add_to_cart_validation', 'exclude_products_by_attribute', 10, 3 );
function exclude_products_by_attribute( $passed, $product_id, $quantity ) {
if ( has_product_attribute( $product_id, 'ne-dostavlyaetsya', 'da' ) ) {
wc_add_notice( 'Этот товар нельзя добавить в корзину из-за ограничений доставки.', 'error' );
return false;
}
return $passed;
}
add_action( 'woocommerce_check_cart_items', 'remove_excluded_products_from_cart' );
function remove_excluded_products_from_cart() {
$cart = WC()->cart;
$removed = false;
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_product_attribute( $product_id, 'ne-dostavlyaetsya', 'da' ) ) {
$cart->remove_cart_item( $cart_item_key );
$removed = true;
}
}
if ( $removed ) {
wc_add_notice( 'Некоторые товары были удалены из корзины, так как они недоступны для оформления заказа.', 'error' );
}
}Как работает решение
- Фильтр
woocommerce_add_to_cart_validationпредотвращает добавление товара с запрещённым атрибутом в корзину. - Хук
woocommerce_check_cart_itemsсрабатывает при загрузке страницы корзины и оформления, удаляет запрещённые товары из корзины, если они там оказались. - Пользователь получает понятные сообщения об ошибках.
Проверка результата после внедрения
- Попробуйте добавить в корзину товар с атрибутом
ne-dostavlyaetsya=da— добавление должно быть заблокировано с сообщением об ошибке. - Если такой товар уже есть в корзине (например, до внедрения кода), перейдите на страницу корзины — товар автоматически удалится, появится уведомление.
- Обычные товары без этого атрибута добавляются и оформляются без проблем.
Частые ошибки и как их исправить
- Ошибка: Неправильный префикс таксономии атрибута.
Решение: Убедитесь, что используетеpa_+ слаг атрибута, например,pa_ne-dostavlyaetsya. - Ошибка: Атрибут не привязан к товару или термин отсутствует.
Решение: Проверьте, что атрибут и термин созданы в админке WooCommerce и назначены товару. - Ошибка: Товары с вариациями не блокируются.
Решение: При работе с вариациями проверяйте атрибуты вариации, а не только родительского товара. Можно добавить проверку$cart_item['variation_id']. - Ошибка: Сообщения об ошибке не отображаются.
Решение: Проверьте, что в теме корректно выводятся уведомления WooCommerce черезwc_print_notices().
Практические советы по производительности и безопасности
- Кэширование: избегайте кеширования страниц корзины и оформления, чтобы фильтры работали корректно.
- Оптимизация кода: если много товаров и атрибутов, можно кешировать результаты
has_product_attribute()в рамках одного запроса. - Безопасность: всегда проверяйте входные данные и используйте штатные хуки WooCommerce, чтобы не ломать логику оформления.
Таблица сравнений способов исключения товаров по атрибуту
| Метод | Преимущества | Недостатки | Пример кода |
|---|---|---|---|
| Фильтр добавления в корзину | Простое решение, блокирует добавление сразу | Не удаляет уже добавленные товары | woocommerce_add_to_cart_validation |
| Удаление при проверке корзины | Удаляет уже добавленные запрещённые товары | Товар может появиться в корзине на короткое время | woocommerce_check_cart_items |
| JavaScript-блокировка | Улучшает UX (скрывает кнопки) | Легко обходится, небезопасно | JS код на фронтэнде |
| Комбинация фильтров + удаления | Максимальная надёжность и UX | Немного сложнее в реализации | Пример из статьи |