Диагностика задачи: зачем менять цены товаров программно
В WooCommerce иногда требуется динамически менять цены товаров без ручного редактирования — например, при проведении акций, изменении цен в зависимости от пользовательских ролей, или для автоматической корректировки цен по внешним данным.
Ручное обновление цен неудобно и подвержено ошибкам, особенно если товаров много. Правильное решение — использовать хуки WooCommerce, чтобы изменить цену товара на лету, без постоянных изменений в базе данных.
Как автоматически изменить цену товара через фильтр woocommerce_product_get_price
WooCommerce предоставляет несколько фильтров для изменения цены товара при загрузке. Самый универсальный — woocommerce_product_get_price. Он позволяет изменить цену товара перед выводом.
Пример кода, который даёт скидку 10% для всех товаров:
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) {
// Проверяем, что цена задана
if (empty($price)) {
return $price;
}
// Применяем скидку 10%
$new_price = floatval($price) * 0.9;
return round($new_price, 2);
}Обратите внимание: нужно применять фильтр и к woocommerce_product_get_regular_price, чтобы скидка отображалась корректно и в админке.
Как изменить цену в зависимости от роли пользователя
Частая задача — давать скидку определённым ролям, например, оптовикам.
add_filter('woocommerce_product_get_price', 'role_based_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'role_based_price', 10, 2);
function role_based_price($price, $product) {
if (empty($price)) {
return $price;
}
if (current_user_can('wholesale_customer')) { // пример роли
return round($price * 0.8, 2); // скидка 20%
}
return $price;
}Пошаговое решение: как внедрить динамическое ценообразование
- Добавьте код с нужным фильтром в файл
functions.phpвашей дочерней темы или в собственный плагин. - Очистите кэш сайта и браузера, если используете кэширование.
- Проверьте работу на фронтенде и в админке, убедитесь, что цены изменились динамически.
Проверка результата
- Откройте страницу товара на сайте, проверьте цену.
- Войдите под разными пользователями (если применяется роль), убедитесь, что цена меняется.
- В панели администратора проверьте цену товара — она не должна изменяться, если фильтры не применяются на уровне базы.
- Для проверки можно временно добавить
error_log('Price changed to '.$new_price);в функцию, чтобы отследить вызовы.
Частые ошибки и как их исправить
- Цена не меняется на сайте. Убедитесь, что фильтры подключены правильно, и нет конфликтов с другими плагинами. Проверьте приоритет фильтра (10 обычно подходит).
- Цена не меняется в корзине или на странице оформления заказа. В этом случае нужно дополнительно использовать фильтры
woocommerce_before_calculate_totalsдля корректировки цены в корзине. - Изменение цены влияет на базу данных. Используйте только фильтры для вывода цены, не меняйте цену прямо в базе, чтобы избежать проблем с отчетностью и синхронизацией.
- Кэширование мешает видеть изменения. Отключите кэширование или добавьте исключения для страниц с товарами.
Дополнительный пример: корректировка цены в корзине с помощью woocommerce_before_calculate_totals
add_action('woocommerce_before_calculate_totals', 'change_cart_item_price', 20, 1);
function change_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();
// К примеру, скидка 15% для роли wholesale_customer
if (current_user_can('wholesale_customer')) {
$new_price = $price * 0.85;
$product->set_price(round($new_price, 2));
}
}
}Сравнение способов изменения цены в WooCommerce
| Метод | Плюсы | Минусы |
|---|---|---|
Фильтры woocommerce_product_get_price | Изменение цены на выводе, не затрагивает базу, легко внедрять | Не влияет на цену в корзине и заказах без дополнительного кода |
Хук woocommerce_before_calculate_totals | Изменяет цены в корзине и заказах, подходит для динамических скидок | Нужно аккуратно использовать, чтобы не сломать расчёты |
| Изменение цены в базе (прямое обновление) | Цена меняется навсегда, подходит для разовой коррекции | Риск ошибок, нужно обновлять вручную или через скрипты, может сбить статистику |
Практические советы по безопасности и производительности
- Не храните цены для разных условий в базе — используйте фильтры для динамического изменения.
- Избегайте тяжелых запросов в функциях изменения цены, чтобы не замедлять загрузку страниц.
- При использовании кэширования исключайте страницы с динамическими ценами или применяйте AJAX для обновления цены после загрузки.
- Тестируйте изменения на копии сайта, чтобы избежать ошибок в рабочей среде.