Автоматическое изменение стоимости последних товаров в корзине WooCommerce

Диагностика задачи: зачем менять цену последних товаров в корзине

В некоторых случаях требуется динамически корректировать цену товаров, добавленных в корзину последними, например, чтобы предоставить скидку на последние позиции или изменить стоимость по специальному правилу. WooCommerce по умолчанию не предоставляет простых инструментов для такой гибкой логики ценообразования. Поэтому необходимо реализовать кастомное решение с помощью хуков и фильтров.

Пошаговое решение: как изменить цену последних товаров в корзине

1. Определение последних добавленных товаров

WooCommerce сохраняет товары в корзине в массиве WC()->cart->get_cart(), упорядоченном по времени добавления. Последние добавленные товары — это элементы в конце массива. Для примера возьмем последние 2 товара.

function get_last_cart_items($count = 2) {
    $cart = WC()->cart->get_cart();
    return array_slice($cart, -$count, $count, true);
}

2. Изменение цены этих товаров

Для изменения цены используем хук woocommerce_before_calculate_totals. Важно делать это только один раз и учитывать, что цена может быть изменена только на объекте WC_Cart_Item.

add_action('woocommerce_before_calculate_totals', 'custom_modify_last_items_price', 20);
function custom_modify_last_items_price( $cart ) {
    if ( is_admin() && ! defined( 'DOING_AJAX' ) ) return;
    // Количество последних товаров для изменения
    $count = 2;
    $last_items = get_last_cart_items($count);

    foreach ( $last_items as $cart_item_key => $cart_item ) {
        // Новая цена, например, скидка 10%
        $original_price = $cart_item['data']->get_price();
        $new_price = $original_price * 0.9;
        $cart_item['data']->set_price( $new_price );
    }
}

3. Проверка корректности работы

Добавьте в корзину несколько товаров, убедитесь, что цена изменилась только у последних двух. В админке и на фронтенде цена должна отображаться с учетом скидки.

Проверка результата после внедрения

  • Добавьте 3-4 товара в корзину, проверьте цену каждого.
  • Убедитесь, что скидка применяется только к последним двум позициям.
  • Проверьте оформление заказа, чтобы цена сохранялась в заказе.
  • Протестируйте повторное добавление и удаление товаров — скидка должна обновляться корректно.

Частые ошибки и как их исправить

  • Изменение цены на объекте товара вместо объекта корзины. Цена в WC_Product не должна изменяться глобально, только в объекте корзины ($cart_item['data']).
  • Множественные изменения цены при нескольких вызовах хука. Решается добавлением флага, например, did_action, чтобы не изменять цену несколько раз.
  • Некорректное определение последних товаров. Убедитесь, что используете array_slice на массиве корзины без сброса ключей, иначе потеряется связь с ключом товара.
  • Не учитывается Ajax-обновление корзины. Проверьте, что функция работает и при Ajax-запросах, иначе цена не обновится на фронтенде.

Практические советы по оптимизации и безопасности

  • Не изменяйте цену товара глобально через WC_Product, это может привести к неверным данным в других местах.
  • Для сложных правил используйте мета данные корзины или пользовательские сессии, чтобы хранить информацию о скидках.
  • Проверяйте, что изменения цены не конфликтуют с другими плагинами и скидками WooCommerce.
  • Для улучшения производительности минимизируйте количество переборов корзины и избегайте лишних запросов к базе данных.

Сравнение вариантов реализации

МетодПлюсыМинусыПрименимость
Изменение цены через woocommerce_before_calculate_totalsПрямой контроль, гибкостьНеобходим мониторинг повторных вызововПодходит для динамических цен и скидок
Использование плагинов скидок (например, WooCommerce Dynamic Pricing)Простота настройки, UIМожет быть избыточным, ограниченная кастомизацияДля типовых скидок и промоакций
Создание кастомных правил через фильтры ценВысокая гибкостьСложность реализации, требует поддержкиДля сложных бизнес-логик

Скачать WP с оф. сайта Магазин проверенных платных тем