Диагностика проблемы: когда необходимо удалять товар из корзины программно
В WooCommerce иногда требуется автоматически удалить товар из корзины по определённым условиям — например, если товар устарел, закончился на складе, или пользователь изменил атрибут товара, несовместимый с остальными позициями. Стандартного интерфейса для таких задач нет, поэтому приходится вручную управлять корзиной через код.
Пошаговое решение: удаление товара из корзины с помощью хука
1. Определяем момент для удаления товара
Удаление товара из корзины нужно выполнить в момент, когда корзина уже загружена, но перед выводом страниц корзины и оформления заказа. Для этого подходит хук woocommerce_before_calculate_totals или woocommerce_cart_loaded_from_session.
2. Получаем ID товара для удаления
Допустим, мы хотим удалить товар с ID = 123 из корзины при определённом условии (например, если в корзине есть товар с ID 456).
3. Код для удаления товара из корзины
add_action('woocommerce_before_calculate_totals', 'custom_remove_product_from_cart', 10, 1);
function custom_remove_product_from_cart( $cart ) {
if ( is_admin() && ! defined( 'DOING_AJAX' ) ) {
return;
}
$target_product_id = 123; // ID товара, который хотим удалить
$trigger_product_id = 456; // ID товара, наличие которого запускает удаление
$has_trigger_product = false;
// Проверяем, есть ли товар-триггер в корзине
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( $cart_item['product_id'] == $trigger_product_id ) {
$has_trigger_product = true;
break;
}
}
if ( ! $has_trigger_product ) {
return; // условие не выполнено, не удаляем
}
// Удаляем целевой товар из корзины
foreach ( $cart->get_cart() as $cart_item_key => $cart_item ) {
if ( $cart_item['product_id'] == $target_product_id ) {
$cart->remove_cart_item( $cart_item_key );
}
}
}
4. Альтернатива: удаление при добавлении товара
Можно также удалять товар в момент добавления в корзину с помощью хука woocommerce_add_to_cart:
add_action('woocommerce_add_to_cart', 'remove_product_on_add_cart', 10, 6);
function remove_product_on_add_cart($cart_item_key, $product_id, $quantity, $variation_id, $variation, $cart_item_data) {
$remove_product_id = 123;
WC()->cart->remove_cart_item( $cart_item_key ); // удаляем только что добавленный товар
// удаляем товар с ID 123, если он есть
foreach ( WC()->cart->get_cart() as $key => $item ) {
if ( $item['product_id'] == $remove_product_id ) {
WC()->cart->remove_cart_item( $key );
}
}
}
Проверка результата после внедрения
- Добавьте в корзину товар с ID 456 (триггерный товар).
- Добавьте товар с ID 123 (целевой для удаления).
- Перейдите в корзину — товар с ID 123 должен отсутствовать.
- Если триггерный товар отсутствует, товар с ID 123 остается в корзине.
Для проверки ID товаров используйте панель администратора WooCommerce или в консоли браузера через JavaScript отследите cart-объект.
Частые ошибки и как их исправить
- Не срабатывает удаление товара: Проверьте, что хук подключён правильно и приоритет достаточный (10 обычно подходит). Убедитесь, что код не выполняется в админке без AJAX.
- Удаление происходит слишком рано: Вызовите удаление на хуке
woocommerce_before_calculate_totals, а неinitилиwp_loaded. - Корзина не обновляется на фронтенде: Обеспечьте вызов
wc()->cart->calculate_totals();после изменений, если делаете их вне стандартных хуков. - Ошибка при вызове
remove_cart_item: Проверьте, что аргумент — ключ элемента корзины, а не ID товара.
Практические советы по безопасности и производительности
- Всегда проверяйте, что код не выполняется в админке без AJAX, чтобы избежать лишних операций.
- Используйте минимально необходимые условия для удаления товаров — избегайте циклов внутри циклов.
- Кэшируйте результаты проверок, если логика сложная.
- Тестируйте на staging-среде, чтобы не нарушить работу корзины.
Сравнение способов удаления товара из корзины
| Метод | Плюсы | Минусы |
|---|---|---|
| woocommerce_before_calculate_totals | Работает перед расчетом стоимости, подходит для динамического удаления | Может не сработать при AJAX-обновлениях без дополнительного кода |
| woocommerce_add_to_cart | Удаление прямо при добавлении товара, мгновенный эффект | Не подходит для удаления товаров уже в корзине, сложнее реализовать комплексные условия |
| Прямое удаление через WC_Cart API | Гибкость, можно удалять в любой момент | Требует аккуратности с ключами корзины и правильным вызовом расчетов |