Диагностика задачи: зачем изменять цены и состав корзины динамически
В WooCommerce часто возникает необходимость изменять цены товаров или добавлять/удалять элементы в корзине автоматически — например, при акциях, скидках для конкретных пользователей, минимальной сумме заказа или при добавлении комплектов. Важно сделать это корректно, чтобы избежать конфликтов с кэшированием, не сломать логику оформления заказа и обеспечить корректное отображение на фронтенде.
Какие хуки WooCommerce использовать для изменения цены товара в корзине
Для изменения цены товаров в корзине есть несколько популярных хуков:
woocommerce_before_calculate_totals— позволяет изменить цену товаров в объекте корзины перед подсчётом итогов.woocommerce_cart_item_price— фильтр для изменения отображения цены товара в корзине (не влияет на итоговую сумму).
Для динамического изменения цены нужно использовать woocommerce_before_calculate_totals, так как именно в этот момент пересчитываются все суммы.
Пример: установка скидки 10% для всех товаров в корзине
add_action('woocommerce_before_calculate_totals', 'apply_10_percent_discount_to_cart', 10, 1);
function apply_10_percent_discount_to_cart( $cart ) {
if ( is_admin() && ! defined('DOING_AJAX') ) return;
// Проходим по всем товарам в корзине
foreach ( $cart->get_cart() as $cart_item ) {
$original_price = $cart_item['data']->get_regular_price();
$discounted_price = $original_price * 0.9; // скидка 10%
$cart_item['data']->set_price( $discounted_price );
}
}Добавление или удаление товаров из корзины программно
Иногда нужно автоматически добавить товар в корзину при выполнении условия — например, бесплатный подарок при покупке на сумму от 5000 руб. Для этого используйте функции WooCommerce WC()->cart->add_to_cart() и WC()->cart->remove_cart_item().
Пример: добавить подарок при сумме корзины от 5000 руб.
add_action('woocommerce_before_calculate_totals', 'add_free_gift_for_large_orders');
function add_free_gift_for_large_orders() {
if ( is_admin() && ! defined('DOING_AJAX') ) return;
$cart_total = WC()->cart->subtotal;
$gift_product_id = 123; // ID подарочного товара
// Проверяем, есть ли подарок в корзине
$gift_in_cart = false;
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( $cart_item['product_id'] == $gift_product_id ) {
$gift_in_cart = true;
break;
}
}
if ( $cart_total >= 5000 && ! $gift_in_cart ) {
WC()->cart->add_to_cart( $gift_product_id );
} elseif ( $cart_total < 5000 && $gift_in_cart ) {
// Удаляем подарок, если сумма меньше 5000
foreach ( WC()->cart->get_cart() as $cart_item_key => $cart_item ) {
if ( $cart_item['product_id'] == $gift_product_id ) {
WC()->cart->remove_cart_item( $cart_item_key );
break;
}
}
}
}Проверка результата после внедрения
- Добавьте товар в корзину и проверьте, что цена изменилась согласно логике (например, скидка 10%).
- Проверьте, что подарок появляется только при сумме от 5000 руб. и исчезает при уменьшении суммы.
- Обновите страницу корзины, убедитесь, что итоговые суммы соответствуют ожиданиям.
- Проверьте в консоли браузера и в логах ошибок PHP, что нет предупреждений и ошибок.
Частые ошибки при работе с хуками WooCommerce для корзины
- Изменение цены вне хука
woocommerce_before_calculate_totals: цена не пересчитается корректно, итоговые суммы будут некорректны. - Повторное добавление подарка при каждом обновлении корзины: из-за отсутствия проверки, подарок добавляется несколько раз. Решение — проверять наличие товара в корзине перед добавлением.
- Изменение цены напрямую в базе данных или мета-полях без правильного хука — не влияет на отображение и расчёты.
- Игнорирование проверки
is_admin() && ! defined('DOING_AJAX')— действия могут выполняться в админке и вызывать ошибки.
Практические советы по безопасности и производительности
- Не используйте тяжелые запросы или вычисления внутри хука
woocommerce_before_calculate_totals, так как он вызывается часто. - Всегда проверяйте условия, чтобы не выполнять лишний код при каждом обновлении корзины.
- Избегайте изменения данных товара напрямую — используйте API WooCommerce.
- Тестируйте на разных этапах оформления заказа, чтобы убедиться в корректности работы.
Сравнение подходов изменения цены и состава корзины
| Метод | Преимущества | Недостатки |
|---|---|---|
Хуки WooCommerce (woocommerce_before_calculate_totals) | Прямое изменение цены в корзине, гибкость, корректные расчёты | Требует аккуратного кодирования, может влиять на производительность при ошибках |
Добавление/удаление товаров через WC()->cart | Можно автоматически добавлять подарки или комплекты | Риск дублирования, если не проверять наличие товара |
Изменение цен через фильтр woocommerce_cart_item_price | Простое изменение отображения цены | Не влияет на итоговую сумму |