Диагностика задачи: зачем исключать товары из корзины по атрибутам
В интернет-магазине на WooCommerce иногда требуется запретить добавление в корзину или оформление заказа товаров с определёнными атрибутами. Например, нельзя продавать одновременно товары с атрибутом «Распродажа» и «Подарок» в одной корзине или блокировать заказ товаров с определённым цветом или размером.
Без кастомных решений WooCommerce не предоставляет встроенных фильтров для исключения товаров по атрибутам на этапе корзины. Значит, нужно написать код, который проверит атрибуты товаров в корзине и, при необходимости, заблокирует оформление или удалит товар.
Пошаговое решение: фильтрация товаров по атрибутам в корзине
1. Получение атрибутов товаров в корзине
Атрибуты у товаров хранятся в объекте WC_Product. Их можно получить через метод get_attributes(). Для вариативных товаров атрибуты берутся из вариации.
function get_product_attributes_from_cart_item($cart_item) {
$product = $cart_item['data'];
$attributes = [];
if ($product->is_type('variation')) {
$attributes = $product->get_variation_attributes();
} else {
$attributes = $product->get_attributes();
}
return $attributes;
}2. Проверка атрибутов и исключение товаров из корзины
Добавим функцию, которая при добавлении или обновлении корзины проверит наличие запрещённых атрибутов и удалит товары с ними.
add_action('woocommerce_check_cart_items', 'exclude_products_by_attributes_from_cart');
function exclude_products_by_attributes_from_cart() {
$forbidden_attributes = [
'pa_color' => ['red', 'black'], // пример: исключаем товары с цветом красный и чёрный
'pa_size' => ['xl']
];
foreach (WC()->cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
// Получаем атрибуты вариации или товара
$attributes = [];
if ($product->is_type('variation')) {
$attributes = $product->get_variation_attributes();
} else {
// Для простых товаров атрибуты могут быть глобальными
$attributes = [];
foreach ($product->get_attributes() as $attr_name => $attr_obj) {
if ($attr_obj->is_taxonomy()) {
$terms = wp_get_post_terms($product->get_id(), $attr_name, ['fields' => 'slugs']);
$attributes[$attr_name] = $terms;
}
}
}
foreach ($forbidden_attributes as $attr_name => $forbidden_values) {
if (!empty($attributes[$attr_name])) {
$product_attr_values = (array)$attributes[$attr_name];
if (array_intersect($product_attr_values, $forbidden_values)) {
WC()->cart->remove_cart_item($cart_item_key);
wc_add_notice(sprintf('Товар "%s" удалён из корзины, так как содержит запрещённый атрибут.', $product->get_name()), 'error');
}
}
}
}
}Проверка результата после внедрения
Чтобы убедиться, что исключение работает:
- Добавьте в магазин товар с запрещённым атрибутом (например, цвет «red»).
- Добавьте этот товар в корзину.
- Перейдите на страницу корзины — товар должен автоматически удалиться, а на странице отобразится сообщение об ошибке.
- Добавьте товар без запрещённых атрибутов — он должен остаться в корзине.
Частые ошибки и как их исправить
- Неправильное имя атрибута: WooCommerce использует имена атрибутов с префиксом
pa_для глобальных атрибутов. Проверьте точное имя атрибута черезProducts > Attributesв админке. - Проверка атрибутов для простых товаров: Простые товары могут иметь атрибуты, которые не являются вариациями и хранятся иначе — используйте
wp_get_post_terms()для таксономий. - Удаление товара не срабатывает: Убедитесь, что функция подключена к хуку
woocommerce_check_cart_items— он вызывается при обновлении корзины и перед оформлением заказа. - Сообщение для пользователя не видно: Используйте
wc_add_notice()с типом'error'для информирования клиента.
Практические советы по безопасности и производительности
- Не используйте тяжелые запросы к базе в цикле корзины — получайте таксономии один раз и сохраняйте в кэш.
- Проверяйте, что исключаете только те товары, для которых это действительно нужно — избегайте лишних удалений для улучшения UX.
- Добавьте логирование ошибок при разработке, например, через
error_log(), чтобы отслеживать, какие товары и атрибуты блокируются.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы | Когда использовать |
|---|---|---|---|
| Код в functions.php | Прямой контроль, бесплатно, быстро | Требует навыков, обновления темы могут стереть код | Малые и средние проекты, кастомная логика |
| Плагин фильтрации корзины | Готовое решение, поддержка | Может быть тяжеловесным, не всегда подходит под задачу | Без навыков программирования, стандартные сценарии |
| Модификация шаблонов WooCommerce | Гибкость интерфейса | Сложнее поддерживать, требует знаний шаблонов | Если нужен кастомный UI помимо логики |