Диагностика проблемы: почему нужно удалять товар при изменении количества в корзине
В стандартной работе WooCommerce изменение количества товара в корзине просто обновляет количество. Однако в некоторых сценариях требуется автоматически удалять товар при изменении количества, например, чтобы сбросить скидку, обновить цену или заблокировать повторное добавление. Такая логика не реализована из коробки и требует кастомного кода.
Пошаговое решение: создание кастомного хука для удаления товара при изменении количества
1. Понимание процесса обновления корзины
При обновлении количества WooCommerce выполняет AJAX-запрос на сервер, где вызывается метод WC_Cart::set_quantity(). Нам нужно перехватить изменение количества и если оно было изменено, удалить товар.
2. Добавление функции, которая удалит товар из корзины при изменении количества
В functions.php вашей темы или в кастомном плагине добавьте следующий код:
add_action('woocommerce_before_calculate_totals', 'wp_course_remove_product_on_qty_change', 10, 1);
function wp_course_remove_product_on_qty_change($cart) {
// Проверяем, что корзина не пуста
if (is_admin() && !defined('DOING_AJAX')) return;
if (did_action('wp_course_remove_product_on_qty_change') >= 1) return; // предотвращаем повторное выполнение
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product_id = $cart_item['product_id'];
$cart_item_data = $cart_item;
// Сохраняем предыдущее количество в сессии
$session_key = 'prev_qty_' . $cart_item_key;
$prev_qty = WC()->session->get($session_key, 0);
$current_qty = $cart_item['quantity'];
// Если количество изменилось и не равно нулю, удаляем товар
if ($prev_qty !== 0 && $prev_qty !== $current_qty) {
$cart->remove_cart_item($cart_item_key);
// Очищаем сессию
WC()->session->__unset($session_key);
// Прерываем цикл после удаления, чтобы не вызвать ошибки
break;
} else {
// Сохраняем текущее количество для следующего сравнения
WC()->session->set($session_key, $current_qty);
}
}
do_action('wp_course_remove_product_on_qty_change');
}3. Объяснение работы кода
- Используем хук
woocommerce_before_calculate_totals, который срабатывает перед пересчетом корзины. - Сохраняем прошлое количество товара в сессии WooCommerce.
- Если обнаруживаем, что количество изменилось, удаляем товар из корзины.
- Предотвращаем повторное выполнение функции за один запрос.
Проверка результата после внедрения
Чтобы проверить, что функционал работает:
- Добавьте товар в корзину.
- Перейдите на страницу корзины.
- Измените количество товара (например, с 1 на 2).
- Нажмите кнопку обновления корзины.
- Товар должен автоматически удалиться из корзины.
Если товар остается, проверьте консоль браузера на наличие ошибок и активность сессий WooCommerce.
Частые ошибки и как их исправить
- Товар не удаляется при изменении количества: Проверьте, что WooCommerce сессии корректно работают, и функция подключена.
- Ошибка "Cannot modify header information" или повторное выполнение функции: Используйте проверку
did_action, чтобы избежать повторных вызовов. - Удаление происходит при первом добавлении товара: Код игнорирует первое добавление, так как предыдущего количества нет (0).
- Конфликты с кешированием: Убедитесь, что страницы корзины не кешируются на уровне сервера или плагинов.
Практические советы по безопасности и производительности
- Используйте минимально необходимые хуки —
woocommerce_before_calculate_totalsоптимален для работы с корзиной. - Избегайте хранения большого объёма данных в сессиях WooCommerce.
- Проверяйте совместимость с другими плагинами, которые могут изменять корзину.
- Для сложных условий удаления добавляйте дополнительные проверки по ID товара или пользовательским меткам.
Таблица сравнения способов реализации удаления товара при изменении количества
| Метод | Плюсы | Минусы |
|---|---|---|
| Код в functions.php с сессиями | Быстрая реализация, не требует плагинов, гибкий контроль | Необходима аккуратная работа с сессиями, возможны конфликты |
| Использование AJAX-обработчиков | Более точный контроль, можно добавить уведомления пользователю | Сложнее в реализации, требует JS и PHP |
| Плагины корзины с расширенным функционалом | Готовые решения, часто с поддержкой и обновлениями | Могут быть избыточными и влиять на производительность |