Проблема: повторное добавление товара в корзину в WooCommerce
По умолчанию WooCommerce позволяет пользователям добавлять один и тот же товар в корзину несколько раз, увеличивая количество этого товара. В некоторых случаях, например, при продаже уникальных или ограниченных товаров, это нежелательно. В этой статье рассмотрим, как отключить повторное добавление и вместо этого показывать уведомление или блокировать действие.
Диагностика
Для начала убедитесь, что в вашем магазине товары действительно могут добавляться в корзину несколько раз. Добавьте товар с количеством 1, затем попробуйте добавить его снова. Если количество увеличивается, значит стандартное поведение не изменено.
Также проверьте, не использует ли ваша тема или плагины кастомное поведение корзины, которое может влиять на добавление товаров.
Пошаговое решение: отключаем повторное добавление товара
1. Использование хука woocommerce_add_to_cart_validation для проверки добавления товара
Добавьте следующий код в файл functions.php вашей дочерней темы или в свой кастомный плагин:
add_filter('woocommerce_add_to_cart_validation', 'disable_duplicate_add_to_cart', 10, 3);
function disable_duplicate_add_to_cart($passed, $product_id, $quantity) {
// Получаем корзину
foreach (WC()->cart->get_cart() as $cart_item_key => $values) {
if ($values['product_id'] == $product_id) {
// Товар уже в корзине, блокируем добавление
wc_add_notice(__('Этот товар уже в вашей корзине.'), 'error');
return false;
}
}
return $passed;
}
Что делает код: перед добавлением товара проверяет, есть ли он уже в корзине. Если есть — блокирует добавление и выводит сообщение об ошибке.
2. Отключение кнопки добавления при уже добавленном товаре
Чтобы улучшить UX, можно скрыть или отключить кнопку "Добавить в корзину" для товаров, которые уже в корзине. Добавьте такой код:
add_filter('woocommerce_is_purchasable', 'disable_add_to_cart_button_if_in_cart', 10, 2);
function disable_add_to_cart_button_if_in_cart($purchasable, $product) {
foreach (WC()->cart->get_cart() as $cart_item) {
if ($cart_item['product_id'] == $product->get_id()) {
return false; // Отключаем кнопку
}
}
return $purchasable;
}
Этот фильтр отключит кнопку "Добавить в корзину" на страницах товара, если он уже есть в корзине.
Проверка результата после внедрения
- Перейдите на страницу товара и добавьте его в корзину.
- Попробуйте добавить тот же товар повторно — должно появиться сообщение об ошибке, а добавление не произойдет.
- Кнопка "Добавить в корзину" должна исчезнуть или стать неактивной, если проверка из шага 2 внедрена.
- Проверьте работу на разных товарах и в разных браузерах.
Частые ошибки и как их исправить
- Ошибка: Сообщение об ошибке не выводится, и товар добавляется несколько раз.
Причина: Кэширование страницы или конфликт плагинов.
Решение: Очистите кэш сайта и браузера, отключите плагины, влияющие на корзину, для теста. - Ошибка: Кнопка "Добавить в корзину" не отключается.
Причина: Тема переопределяет шаблоны кнопок или использует кастомные кнопки.
Решение: Проверьте шаблоны темы, попробуйте временно переключиться на стандартную TwentyTwentyThree для проверки. - Ошибка: Поведение работает только для простых товаров, а для вариативных нет.
Причина: Вариативные товары имеют другой ID для вариаций.
Решение: В коде нужно сравнивать ID вариаций — использовать$cart_item['variation_id']при наличии.
Практические советы по производительности и безопасности
- Не добавляйте тяжелых и сложных проверок в хук
woocommerce_add_to_cart_validation, чтобы не замедлять процесс добавления товара. - Кэшируйте результаты проверки, если у вас большой магазин с множеством товаров в корзине.
- Обязательно используйте
wc_add_notice()для вывода ошибок, чтобы пользователь понимал причину блокировки. - Для безопасности не полагайтесь только на клиентскую проверку (например, скрытие кнопок), всегда проверяйте на сервере.
Таблица сравнения вариантов реализации
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_add_to_cart_validation |
Блокирует добавление товара на сервере | Надежность, безопасность | Не изменяет интерфейс, необходимо доп. уведомления |
Фильтр woocommerce_is_purchasable |
Отключает кнопку добавления товара | Улучшает UX, предотвращает попытки добавления | Может конфликтовать с темой или плагинами |
| JavaScript-решения | Отключение кнопок на клиенте | Быстрое визуальное решение | Менее надежно, легко обходится |