Диагностика задачи: зачем и когда нужна автоматическая смена цены
В WooCommerce часто возникает необходимость менять цену товара динамически, например, при запуске временной акции, скидок по количеству или при использовании купонов, которые требуют особой логики. Вручную обновлять цены неудобно и рискованно, особенно если товаров много. Автоматизация с помощью хуков и фильтров WordPress позволяет решить эту задачу эффективно.
Пошаговое решение: реализация автоматического изменения цены товара
1. Используем фильтр woocommerce_get_price
Этот фильтр позволяет изменить цену товара на лету перед выводом на сайте. Ниже пример кода, который снижает цену на 20%, если сегодня действует акция.
add_filter('woocommerce_get_price', 'wps_change_price_for_promo', 10, 2);
function wps_change_price_for_promo($price, $product) {
$promo_start = strtotime('2024-07-01');
$promo_end = strtotime('2024-07-07');
$today = current_time('timestamp');
if ($today >= $promo_start && $today <= $promo_end) {
// Уменьшаем цену на 20%
$price = $price * 0.8;
}
return $price;
}2. Обновляем цену в корзине с помощью фильтра woocommerce_before_calculate_totals
Чтобы скидка учитывалась при оформлении заказа, нужно изменить цену в объекте товара в корзине.
add_action('woocommerce_before_calculate_totals', 'wps_apply_promo_price_cart', 20, 1);
function wps_apply_promo_price_cart($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
$promo_start = strtotime('2024-07-01');
$promo_end = strtotime('2024-07-07');
$today = current_time('timestamp');
if ($today >= $promo_start && $today <= $promo_end) {
foreach ($cart->get_cart() as $cart_item) {
$original_price = $cart_item['data']->get_price();
$discounted_price = $original_price * 0.8;
$cart_item['data']->set_price($discounted_price);
}
}
}Проверка результата после внедрения
- Перейдите на страницу товара в период акции (например, 1-7 июля 2024) — цена должна отображаться с 20% скидкой.
- Добавьте товар в корзину и проверьте, что в корзине и при оформлении заказа применяется скидка.
- Вне периода акции цена должна показываться и учитываться без изменений.
Частые ошибки и как их исправить
- Цена не меняется в корзине — проверьте, что используется
woocommerce_before_calculate_totalsдля изменения цены объекта товара в корзине, а не только фильтр вывода цены. - Цена меняется для администраторов или в бекенде — добавьте проверку
if (is_admin() && !defined('DOING_AJAX')) return;в обработчике для корзины, чтобы не ломать админку. - Цена не обновляется при AJAX добавлении товара — убедитесь, что хук подключён с приоритетом и нет конфликтов с другими плагинами кеширования или оптимизации.
Практические советы по производительности и безопасности
- Храните даты акции в настройках, чтобы не менять код при каждом обновлении. Используйте
get_option()и административную панель для управления. - Если скидки зависят от условий пользователя (роль, купоны), добавляйте соответствующие проверки в функцию.
- Избегайте перезаписи цены в базе данных — работайте только с выводом и объектами в памяти, чтобы не ломать историю заказов.
Сравнение вариантов реализации
| Метод | Описание | Плюсы | Минусы |
|---|---|---|---|
Фильтр woocommerce_get_price | Изменение цены при выводе на страницы магазина | Простота, не меняет базу данных | Не меняет цену в корзине и заказах без доп. действий |
Хук woocommerce_before_calculate_totals | Изменение цены в корзине и на этапе оформления заказа | Скидка учитывается корректно в заказе | Сложнее отлаживать, требует проверки условий |
| Обновление цены в базе (не рекомендуется) | Меняет цену товара в базе данных | Постоянное изменение цены | Риск сломать историю заказов, хуже для производительности |