Проблема: необходимость исключить товары по атрибуту из оформления заказа
В интернет-магазине на WooCommerce может возникнуть задача запретить покупку определённых товаров или вариантов товаров на основании заданного атрибута. Например, это нужно для товаров с ограничениями по доставке, или для временно снятых с продажи позиций, которые нельзя удалять из каталога.
По умолчанию WooCommerce не предоставляет такой функционал, поэтому требуется кастомный код, который будет проверять товары в корзине и блокировать оформление заказа, если там есть товары с указанным атрибутом.
Диагностика проблемы: как определить, что товар нельзя купить
Для диагностики убедитесь, что у товара или варианта действительно есть нужный атрибут. В админке WooCommerce откройте карточку товара и проверьте вкладку "Атрибуты".
Для программной проверки используйте следующий код в консоли или через сниппет:
global $product;
$attributes = $product->get_attributes();
var_dump($attributes);Это позволит понять структуру атрибутов и ключи, по которым можно фильтровать товары.
Пошаговое решение: блокировка товаров с определённым атрибутом в корзине и оформлении заказа
Добавим проверку в хук woocommerce_check_cart_items, который вызывается перед оформлением заказа:
add_action('woocommerce_check_cart_items', 'block_products_by_attribute_in_cart');
function block_products_by_attribute_in_cart() {
$blocked_attribute = 'zapreshchennyy'; // slug атрибута
$blocked_term = 'neprodavaemyj'; // slug значения атрибута
foreach (WC()->cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$attributes = $product->get_attributes();
if (isset($attributes[$blocked_attribute])) {
$attribute_obj = $attributes[$blocked_attribute];
if ($attribute_obj->is_taxonomy()) {
$terms = wp_get_post_terms($product->get_id(), $attribute_obj->get_name(), array('fields' => 'slugs'));
if (in_array($blocked_term, $terms)) {
wc_add_notice(__('В корзине есть товар, который нельзя заказать.'), 'error');
break;
}
} else {
$values = explode('|', $attribute_obj->get_options());
if (in_array($blocked_term, $values)) {
wc_add_notice(__('В корзине есть товар, который нельзя заказать.'), 'error');
break;
}
}
}
}
}Объяснение:
$blocked_attribute— slug атрибута, например,pa_zapreshchennyy(префиксpa_означает таксономию атрибутов в WooCommerce).$blocked_term— slug значения атрибута, по которому делаем блокировку.- Проверяем каждый товар в корзине на наличие заданного атрибута и значения.
- Если найдён запрещённый товар — выводим ошибку и блокируем оформление.
Как исключить варианты товаров (variable products)
Для вариативных товаров атрибуты могут быть у варианта (variation), а не у родительского товара. Тогда нужно проверять атрибуты варианта:
foreach (WC()->cart->get_cart() as $cart_item) {
$product = $cart_item['data'];
$attributes = $product->get_attributes();
// Аналогичная проверка, как выше
}У объекта варианта атрибуты хранятся также, и функция выше работает одинаково для simple и variation продуктов.
Проверка результата после внедрения
1. Добавьте в корзину товар с запрещённым атрибутом и значением.
2. Перейдите к оформлению заказа — должна появиться ошибка и оформление будет заблокировано.
3. Если убрать из корзины запрещённый товар, оформление становится доступным.
Для дополнительной проверки можно временно добавить дебаг-логи:
error_log('Проверка товара ID: ' . $product->get_id());Частые ошибки и их исправления
- Неправильный slug атрибута: в WooCommerce атрибуты таксономии всегда с префиксом
pa_. Проверьте точное имя атрибута в разделе Продукты - Атрибуты. - Значение атрибута не совпадает: убедитесь, что значение атрибута соответствует slug термина, а не его названию.
- Кэширование мешает изменениям: очистите кэш сайта и браузера.
- Проверка у варианта товара: если проверять только у родителя, атрибут варианта может не учитываться. Всегда проверяйте у объекта товара из корзины, который уже является вариантом если это вариативный товар.
Практические советы по безопасности и производительности
- Код добавляйте в дочернюю тему или в специальный плагин для пользовательских функций, чтобы не потерять при обновлениях.
- Используйте хуки WooCommerce, не меняйте ядро плагина.
- Для большого каталога не делайте сложные запросы в цикле — используйте кэширование результатов, если проверка атрибутов занимает много времени.
- Для повышения UX выведите причину блокировки прямо в корзину, чтобы пользователь понимал почему товар нельзя заказать.
Сравнение решений: плагин vs кастомный код
| Критерий | Плагин | Кастомный код |
|---|---|---|
| Гибкость | Часто ограничена настройками | Полный контроль по атрибутам и логике |
| Производительность | Может быть тяжелее из-за лишнего функционала | Оптимизирован под задачу |
| Обновления | Требуют внимания, возможны несовместимости | Контролируете сами, но нужно тестировать |
| Время внедрения | Быстрое решение | Требует навыков программирования |