Диагностика задачи: зачем исключать товары с определёнными атрибутами из корзины
В интернет-магазинах на WooCommerce часто возникает потребность блокировать покупку товаров с конкретными характеристиками (атрибутами), например, при наличии ограничений по доставке, промоакциях, или исключении несовместимых товаров. Стандартный функционал WooCommerce не предусматривает фильтрацию корзины на основе атрибутов, поэтому требуется кастомизация.
Как определить товары с нужными атрибутами в WooCommerce
Атрибуты товаров в WooCommerce хранятся как таксономии с префиксом pa_. Например, атрибут "Цвет" будет таксономией pa_color. Для поиска товаров в корзине с заданным атрибутом необходимо проверить термины таксономии у каждого товара.
function has_product_attribute( $product_id, $taxonomy, $term_slug ) {
$terms = wp_get_post_terms( $product_id, $taxonomy, array( 'fields' => 'slugs' ) );
if ( is_wp_error( $terms ) ) {
return false;
}
return in_array( $term_slug, $terms );
}Этот код проверяет, есть ли у товара с ID $product_id атрибут $taxonomy с термином $term_slug.
Пошаговое решение: исключение товаров с определёнными атрибутами из корзины
1. Добавляем фильтр для проверки товаров при добавлении в корзину
Для блокировки добавления товаров с запрещёнными атрибутами используем хук woocommerce_add_to_cart_validation. Пример кода:
add_filter( 'woocommerce_add_to_cart_validation', 'exclude_products_by_attribute_from_cart', 10, 3 );
function exclude_products_by_attribute_from_cart( $passed, $product_id, $quantity ) {
// Укажите таксономию и термин атрибута, который нужно исключить
$taxonomy = 'pa_color';
$excluded_term = 'red';
if ( has_product_attribute( $product_id, $taxonomy, $excluded_term ) ) {
wc_add_notice( 'Товар с красным цветом нельзя добавить в корзину.', 'error' );
return false;
}
return $passed;
}2. Удаляем запрещённые товары из уже существующей корзины при загрузке страницы
Чтобы исключить товары с указанными атрибутами, которые уже находятся в корзине, добавим проверку при инициализации WooCommerce:
add_action( 'woocommerce_before_cart', 'remove_excluded_attribute_products_from_cart' );
function remove_excluded_attribute_products_from_cart() {
$taxonomy = 'pa_color';
$excluded_term = 'red';
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product_id = $cart_item['product_id'];
if ( has_product_attribute( $product_id, $taxonomy, $excluded_term ) ) {
WC()->cart->remove_cart_item( $cart_item_key );
wc_add_notice( 'Товар с красным цветом был удалён из корзины.', 'error' );
}
}
}Проверка результата после внедрения
- Попробуйте добавить в корзину товар с атрибутом
pa_color=red. Добавление должно блокироваться с сообщением об ошибке. - Если такой товар уже есть в корзине, при загрузке страницы корзины он должен автоматически удаляться с уведомлением.
- Для проверки атрибутов товаров можно использовать
var_dumpилиerror_logвнутри функцииhas_product_attribute.
Частые ошибки и как их исправить
- Неверное имя таксономии или термина атрибута: Проверьте в админке WooCommerce в разделе "Атрибуты", что префикс
pa_и slug термина точно совпадают. - Кэширование корзины мешает обновлению: Отключите кэш страницы корзины и корзины в плагинах кеширования, иначе удаление не будет видно сразу.
- Код не подключён или подключён некорректно: Убедитесь, что код добавлен в functions.php активной темы или в плагин с правильными правами.
- Конфликты с другими плагинами: Временно отключите остальные плагины, чтобы проверить совместимость.
Практические советы по безопасности и производительности
- Не используйте тяжелые операции в функциях проверки атрибутов, чтобы не замедлять добавление в корзину.
- Для сложных условий фильтрации лучше кешировать результаты проверки атрибутов в transient или объектном кэше.
- Используйте
wc_add_noticeдля вывода ошибок — это стандарт WooCommerce и улучшает UX. - Если необходимо массово исключать товары по нескольким атрибутам, расширьте функцию
has_product_attributeдля проверки массива терминов.
Сравнение вариантов реализации исключения товаров из корзины
| Метод | Преимущества | Недостатки | Когда использовать |
|---|---|---|---|
Фильтр woocommerce_add_to_cart_validation | Блокирует добавление сразу, удобен пользователю | Не удаляет товары уже в корзине | Для предотвращения ошибок при добавлении |
Автоматическое удаление в woocommerce_before_cart | Удаляет запрещённые товары из текущей корзины | Пользователь может сначала добавить товар, потом он исчезнет с ошибкой | Для очистки корзины от запрещённых товаров |
| Комбинация обоих методов | Полный контроль, минимизация ошибок | Сложнее код, требует тестирования | Рекомендуется для надёжной фильтрации |