Диагностика: зачем исключать товары из корзины по атрибутам
В интернет-магазинах на WooCommerce иногда возникает задача запретить покупку определённых товаров в одной корзине. Например, товары с определённым атрибутом (цвет, размер, материал) не должны добавляться одновременно с другими товарами, либо вовсе не должны попадать в корзину для определённых условий. Это нужно для соблюдения правил продажи, акций или технических ограничений.
Если попытаться реализовать это вручную, без проверки и фильтрации корзины, можно получить баги с неверным подсчётом стоимости или некорректной работой оформления заказа.
Как проверить текущие товары в корзине и их атрибуты
Чтобы исключить товары по атрибутам, сначала нужно уметь получать атрибуты каждого товара в корзине. В WooCommerce атрибуты товара хранятся в объекте WC_Product. Через объект строки корзины (WC_Cart_Item) можно получить ID продукта и его атрибуты.
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
$product = $cart_item['data']; // WC_Product
$attributes = $product->get_attributes();
// attributes - массив WC_Product_Attribute объектов
}Для простых атрибутов, созданных через админку, получить значения можно так:
$attribute_taxonomies = wc_get_attribute_taxonomies();
foreach ( $attributes as $attribute_name => $attribute ) {
if ( $attribute->is_taxonomy() ) {
$terms = wp_get_post_terms( $product->get_id(), $attribute_name );
foreach ( $terms as $term ) {
// $term->slug, $term->name - значения атрибутов
}
}
}Пошаговое решение: исключение товаров из корзины по атрибутам
Реализуем фильтр, который при добавлении товара в корзину проверит наличие запрещённых атрибутов у уже добавленных товаров и нового товара, и предотвратит добавление, если условие нарушается.
1. Определяем запрещённые атрибуты
$excluded_attributes = [
'pa_color' => ['red', 'blue'], // пример: запрещаем цвета red и blue
];2. Проверяем атрибуты товара
function has_excluded_attribute( $product, $excluded_attributes ) {
if ( ! $product instanceof WC_Product ) {
return false;
}
foreach ( $excluded_attributes as $taxonomy => $excluded_terms ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
continue;
}
$terms = wp_get_post_terms( $product->get_id(), $taxonomy, ['fields' => 'slugs'] );
if ( array_intersect( $terms, $excluded_terms ) ) {
return true;
}
}
return false;
}3. Фильтруем добавление товара в корзину
add_filter( 'woocommerce_add_to_cart_validation', 'exclude_products_by_attributes_in_cart', 10, 3 );
function exclude_products_by_attributes_in_cart( $passed, $product_id, $quantity ) {
$excluded_attributes = [
'pa_color' => ['red', 'blue'],
];
$product = wc_get_product( $product_id );
if ( has_excluded_attribute( $product, $excluded_attributes ) ) {
// Проверяем товары в корзине
foreach ( WC()->cart->get_cart() as $cart_item ) {
$cart_product = $cart_item['data'];
if ( has_excluded_attribute( $cart_product, $excluded_attributes ) ) {
// Продукт с запрещённым атрибутом уже в корзине
wc_add_notice( 'Товар с выбранным атрибутом нельзя добавлять в корзину вместе с другими такими товарами.', 'error' );
return false;
}
}
}
return $passed;
}Проверка результата после внедрения
Чтобы проверить, что решение сработало:
- Добавьте товар с запрещённым атрибутом, например цветом
redв корзину. - Попытайтесь добавить ещё один товар с тем же или другим запрещённым цветом.
- Должно появиться сообщение об ошибке, и товар не добавится.
- Добавьте товар с разрешённым атрибутом — он должен добавляться без ошибок.
Проверяйте в разных браузерах, а также с отключенными плагинами кэширования, чтобы не получить ложное поведение.
Частые ошибки и как их исправить
- Не работает определение атрибутов — проверьте, что атрибуты действительно являются таксономиями (pa_...), а не пользовательскими свойствами.
- Ошибка с кешированием — если сайт использует кэш, очистите его после внесения изменений.
- Сообщения об ошибках не выводятся — убедитесь, что в теме поддерживается вывод уведомлений
wc_add_notice. - Неверные таксономии в массиве исключений — используйте точные имена атрибутов, как в WooCommerce (например,
pa_color, а не простоcolor).
Практические советы по производительности и безопасности
- Минимизируйте количество запросов к базе, кэшируя результаты
wp_get_post_terms, если в корзине много товаров. - Обрабатывайте ошибки и предупреждения, чтобы не сломать оформление заказа.
- Проверяйте совместимость с другими плагинами, которые могут влиять на корзину (например, плагинами скидок).
- Используйте фильтры и хуки WooCommerce, чтобы не модифицировать ядро и облегчить поддержку кода.
Сравнение решений: плагин vs кастомный код
| Критерий | Кастомный код | Плагин | Компромисс |
|---|---|---|---|
| Гибкость | Высокая, под конкретные задачи | Ограничена функционалом | Код + плагин для базового контроля |
| Производительность | Оптимальный при правильной реализации | Может нагружать систему | Оптимизировать плагин или код |
| Простота использования | Требует навыков разработки | Прост в настройке | Использовать плагины с возможностью добавлять кастомные фильтры |
| Поддержка и обновления | Самостоятельная поддержка | Обновления от разработчиков | Комбинировать для стабильности |