Диагностика задачи: зачем менять цены автоматически
В WooCommerce часто возникает необходимость менять цены товаров не вручную, а по определённым правилам: например, снижать цену при большом запасе на складе, делать скидки для определённых категорий товаров или автоматически повышать цены при росте себестоимости. Ручное обновление занимает много времени и приводит к ошибкам, поэтому автоматизация – лучший вариант.
Обзор основных методов автоматического изменения цен в WooCommerce
Для автоматического изменения цен есть 2 основных подхода:
- Использование плагинов с функционалом массового изменения цен (например, WooCommerce Dynamic Pricing, Discount Rules и другие).
- Написание пользовательского кода с использованием хуков WooCommerce для динамического изменения цены на лету.
Плагины проще в использовании, но часто имеют ограничения и могут влиять на производительность. Код позволяет гибко настраивать любые условия, но требует навыков разработки.
Сравнение подходов в таблице
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
| Плагин | Удобство, готовые правила, поддержка | Платные, нагрузка на сайт, ограниченная гибкость | WooCommerce Discount Rules |
| Код (хук) | Полная гибкость, бесплатность, высокая скорость | Требует знаний PHP и WooCommerce API | Функция на хуке woocommerce_product_get_price |
Пошаговое решение: изменение цены через хук woocommerce_product_get_price
Допустим, нужно автоматически снижать цену на 10% для товаров из категории "Распродажа" и увеличивать цену на 5% для товаров с запасом меньше 5 штук.
Шаг 1. Добавьте функцию в functions.php вашей темы или в плагин для кастомных функций
add_filter('woocommerce_product_get_price', 'custom_dynamic_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_dynamic_price', 10, 2);
function custom_dynamic_price($price, $product) {
// Получаем ID товара
$product_id = $product->get_id();
// Проверяем категорию
if (has_term('rasprodazha', 'product_cat', $product_id)) {
$price *= 0.9; // скидка 10%
}
// Получаем количество на складе
$stock_quantity = $product->get_stock_quantity();
if ($stock_quantity !== null && $stock_quantity < 5) {
$price *= 1.05; // наценка 5%
}
return round($price, 2);
}Объяснение кода: Мы подключаемся к фильтру, который возвращает цену товара. Проверяем условие по категории и количеству на складе, и корректируем цену.
Шаг 2. Проверка корректности работы
- Очистите кеш сайта и браузера.
- Перейдите на страницу товара, который находится в категории "Распродажа" и посмотрите на цену — она должна быть на 10% меньше базовой.
- Проверьте товары с запасом меньше 5 — их цена должна быть немного выше.
- Для комплексных проверок используйте функцию
error_log()для вывода отладочной информации в лог.
Проверка результата после внедрения
Чтобы убедиться, что цены меняются корректно:
- Проверьте несколько товаров разных категорий и с разным запасом.
- Посмотрите в админке WooCommerce, что базовая цена не изменилась (цены меняются только при выводе).
- Используйте режим инкогнито или другой браузер, чтобы избежать проблем с кешем.
- Если используете кэширование (например, Redis или плагин кэширования), временно отключите его для проверки.
Частые ошибки и как их исправить
- Цена не меняется на фронтенде. Проверьте правильность подключения функции, используйте
add_filterс правильным приоритетом. Очистите кеш. - Цена меняется, но в корзине и на странице оформления заказа отображается базовая цена. Нужно применить и другие фильтры:
woocommerce_product_get_price_including_tax,woocommerce_cart_item_priceили использовать хукwoocommerce_before_calculate_totalsдля изменения цены в корзине. - Изменённая цена сбрасывается после обновления товара. Функция должна работать только на вывод, не изменять базу данных.
- Функция влияет на все цены в админке. Отделяйте логику для фронтенда и админки через
is_admin().
Практические советы по безопасности и производительности
- Всегда тестируйте изменения на staging-сайте, чтобы избежать сбоев на живом ресурсе.
- Старайтесь минимизировать количество запросов к базе данных внутри функции, кэшируйте результаты при необходимости.
- Не изменяйте базовые цены товара в базе, используйте фильтры только для вывода.
- Если у вас большой каталог, рассмотрите использование сторонних плагинов с оптимизированным механизмом динамического ценообразования.
Расширение: изменение цены в корзине
Чтобы цена менялась также и в корзине, добавьте следующий код:
add_action('woocommerce_before_calculate_totals', 'custom_cart_item_price', 20, 1);
function custom_cart_item_price($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
foreach ($cart->get_cart() as &$cart_item) {
$product = $cart_item['data'];
$price = $product->get_price();
if (has_term('rasprodazha', 'product_cat', $product->get_id())) {
$price *= 0.9;
}
$stock_quantity = $product->get_stock_quantity();
if ($stock_quantity !== null && $stock_quantity < 5) {
$price *= 1.05;
}
$cart_item['data']->set_price(round($price, 2));
}
}Этот код изменяет цену товара в корзине согласно тем же правилам, что и на странице товара.