Диагностика задачи: зачем исключать товары по атрибуту из корзины и оформления заказа
В ряде проектов WooCommerce возникают ситуации, когда необходимо ограничить покупку определённых товаров по атрибутам. Например, товары с определённым атрибутом "Распродажа" или "Пробный" нельзя допустить к оплате или отправке в корзину. Это связано с бизнес-логикой, например, чтобы избежать повторных заказов, ограничить акции или запретить оформление заказов с товаром, не предназначенным для продажи онлайн.
Стандартного функционала WooCommerce для такого ограничения нет. Поэтому чаще всего приходится писать кастомный код, который блокирует товары с нужными атрибутами при добавлении в корзину или при попытке оформить заказ.
Пошаговое решение: фильтрация товаров по атрибуту в корзине и оформлении
1. Определение атрибута для исключения
Для примера возьмём атрибут "exclude_from_checkout" с термином "yes". Черновой код будет проверять наличие этого атрибута у товаров в корзине.
2. Блокировка добавления товара с атрибутом
Для предотвращения добавления товара с нужным атрибутом используем фильтр woocommerce_add_to_cart_validation. Он проверяет товар при попытке добавления в корзину.
add_filter('woocommerce_add_to_cart_validation', 'wpreg_exclude_product_by_attribute', 10, 3);
function wpreg_exclude_product_by_attribute($passed, $product_id, $quantity) {
$taxonomy = 'pa_exclude_from_checkout'; // системное имя атрибута с префиксом pa_
$terms = wp_get_post_terms($product_id, $taxonomy);
foreach ($terms as $term) {
if ($term->slug === 'yes') {
wc_add_notice('Этот товар нельзя добавить в корзину.', 'error');
return false;
}
}
return $passed;
}3. Исключение товара с атрибутом из уже добавленных в корзину при оформлении
Если по каким-то причинам товар с таким атрибутом попал в корзину, нужно запретить оформление заказа и уведомить пользователя. Для этого используем хук woocommerce_check_cart_items:
add_action('woocommerce_check_cart_items', 'wpreg_block_checkout_if_excluded_product');
function wpreg_block_checkout_if_excluded_product() {
$taxonomy = 'pa_exclude_from_checkout';
foreach (WC()->cart->get_cart() as $cart_item) {
$product_id = $cart_item['product_id'];
$terms = wp_get_post_terms($product_id, $taxonomy);
foreach ($terms as $term) {
if ($term->slug === 'yes') {
wc_add_notice('В корзине есть товар, который нельзя заказать.', 'error');
return;
}
}
}
}4. Исключение товара из отображения в корзине (необязательно)
Если нужно полностью скрыть товар из корзины, можно фильтровать вывод корзины, но это не рекомендуется с точки зрения UX и прозрачности для пользователя.
Проверка результата после внедрения
- Попытайтесь добавить товар с атрибутом
exclude_from_checkout: yes— должно появиться сообщение об ошибке и товар не добавится. - Добавьте товар без атрибута — он добавится без проблем.
- Если вручную добавить товар с запрещённым атрибутом в корзину (например, через PHP), при попытке оформить заказ появится сообщение и оформление будет заблокировано.
Частые ошибки и как их исправить
- Неправильное имя таксономии атрибута: системное имя атрибута всегда начинается с
pa_, например, для атрибута «exclude_from_checkout» этоpa_exclude_from_checkout. Проверьте правильность. - Отсутствие термина с нужным slug: убедитесь, что у товара действительно есть термин с нужным slug (
yes) в данном атрибуте. - Кэширование: если на сайте используется кэш, почистите его после добавления кода.
- Конфликт с другими плагинами: отключите другие плагины, чтобы проверить, что код работает корректно.
Практические советы по производительности и безопасности
- Не делайте лишних запросов к базе: лучше запомнить результат проверки атрибута в кэше на время сессии.
- Используйте правильные хуки WooCommerce, чтобы не влиять на процесс добавления товара и оформления без необходимости.
- Обрабатывайте сообщения ошибок через
wc_add_noticeдля правильного вывода в интерфейсе. - Проверяйте производительность при большом количестве товаров в корзине, чтобы избежать задержек.
Сравнение вариантов реализации ограничения по атрибутам WooCommerce
| Метод | Преимущества | Недостатки |
|---|---|---|
| Код в functions.php | Не требует плагинов, гибко настраивается | Требует знаний PHP, может конфликтовать с темой |
| Плагины блокировки товаров | Удобный интерфейс, дополнительные функции | Может замедлять сайт, не всегда поддерживает атрибуты |
| Изменение шаблонов WooCommerce | Полный контроль над выводом | Сложно поддерживать, требует навыков |