Проблема: стандартный пересчет при удалении товара из корзины в WooCommerce
По умолчанию при удалении товара из корзины WooCommerce автоматически пересчитывает стоимость всей корзины. В некоторых сценариях, например, при сложной кастомизации цены или при интеграции со сторонними сервисами, это поведение может приводить к некорректному отображению или сбросу пользовательских данных.
Диагностика проблемы
Для начала убедитесь, что при удалении товара из корзины происходит полный пересчет через AJAX или при обновлении страницы. Это можно проверить так:
- Откройте корзину на фронтенде;
- Удалите товар;
- Обратите внимание, обновилась ли сумма в корзине и были ли вызваны AJAX-запросы;
- Проверьте консоль браузера на наличие ошибок JavaScript;
- Посмотрите логи PHP на предмет ошибок или предупреждений.
Если пересчет приводит к изменению или сбросу нужных данных, значит нужно вмешаться в процесс пересчета.
Пошаговое решение: отключение автоматического пересчета при удалении товара
Для управления пересчетом корзины в WooCommerce нужно работать с AJAX-хуками и фильтрами, которые вызывают обновление. Вот базовый пример, как можно отключить автоматический пересчет при удалении товара из корзины.
1. Отключаем AJAX-пересчет через JavaScript
WooCommerce использует событие removed_from_cart для запуска пересчета. Можно отменить этот обработчик.
jQuery(function($){
$(document.body).off('removed_from_cart');
});Этот код нужно добавить в файл вашей темы (например, functions.php) через подключение собственного скрипта или вставить напрямую в футер.
2. Отключаем пересчет на PHP-стороне
Можно отключить функцию, которая отвечает за пересчет корзины при удалении. В WooCommerce пересчет вызывается через AJAX-экшен woocommerce_remove_cart_item. Можно использовать фильтр woocommerce_cart_item_removed для запуска кастомного кода без пересчета.
add_filter('woocommerce_cart_item_removed', function($cart_item_key) {
// Не вызываем WC()->cart->calculate_totals();
// Можно добавить логику для обновления данных по-другому
return $cart_item_key;
});Но этот фильтр не отменяет пересчет полностью, поэтому следующий шаг — переопределение AJAX-обработчика.
3. Переопределяем AJAX-обработчик удаления товара
Создайте свой AJAX-обработчик, который удаляет товар из корзины без вызова calculate_totals():
add_action('wp_ajax_custom_remove_cart_item', 'custom_remove_cart_item_handler');
add_action('wp_ajax_nopriv_custom_remove_cart_item', 'custom_remove_cart_item_handler');
function custom_remove_cart_item_handler() {
$cart_item_key = sanitize_text_field($_POST['cart_item_key'] ?? '');
if (!$cart_item_key) {
wp_send_json_error('Cart item key missing');
wp_die();
}
WC()->cart->remove_cart_item($cart_item_key);
// Не вызываем WC()->cart->calculate_totals();
wp_send_json_success(['removed' => $cart_item_key]);
wp_die();
}Далее замените стандартный JS вызов удаления товара на вызов вашего AJAX-обработчика.
Проверка результата
- Откройте корзину;
- Удалите товар;
- Проверьте, что товар исчез, но сумма корзины не пересчиталась;
- Убедитесь, что нет ошибок в консоли браузера и на сервере;
- Проверьте, что другие кастомные данные в корзине не сбрасываются.
Частые ошибки и их исправление
- Ошибка: После удаления товара корзина не обновляется визуально.
Причина: Отмена стандартного AJAX-пересчета отключила обновление фронтенда.
Решение: Добавьте ручное обновление блока с суммой и количеством через JS после успешного удаления. - Ошибка: Кастомные данные в сессии сбрасываются.
Причина: В другом месте кода вызываетсяcalculate_totals().
Решение: Проверьте плагин или тему на лишние вызовы пересчета и оптимизируйте. - Ошибка: AJAX-запросы конфликтуют с другими плагинами.
Причина: Несовместимость JS-кода.
Решение: Используйте уникальные имена функций и событий, минимизируйте вмешательство в стандартный JS WooCommerce.
Практические советы по безопасности и производительности
- Всегда проверяйте и фильтруйте входящие данные в AJAX-обработчиках (
sanitize_text_field,intvalи т.п.). - Минимизируйте количество пересчетов корзины — это нагрузка на базу и сервер.
- Если отключаете стандартные AJAX-вызовы, обеспечьте корректное обновление интерфейса пользователя.
- Тестируйте на разных версиях WooCommerce, чтобы избежать несовместимостей.
Сравнение вариантов решения
| Метод | Плюсы | Минусы |
|---|---|---|
Отключение JS-обработчика removed_from_cart | Простая реализация, быстро | Не обновляется интерфейс, нужен доп. JS |
Фильтр woocommerce_cart_item_removed | Работает на PHP, можно добавить логику | Не отменяет пересчет полностью |
| Переопределение AJAX-обработчика удаления | Полный контроль над процессом | Сложнее реализовать, требует замены JS |