Диагностика задачи: зачем автоматизировать изменение цен по категориям
В WooCommerce часто возникает необходимость применять разные скидки к товарам в разных категориях. Например, на одну категорию действует скидка 10%, на другую — 20%. Если товаров много, вручную менять цены неудобно и рискованно с точки зрения ошибок. Задача — реализовать автоматическое изменение цены товара при отображении на сайте и в корзине, без постоянного редактирования каждой позиции.
Проверяем, что именно нужно:
- Скидка должна применяться динамически, без изменения базовой цены товара в админке.
- Цена на странице товара, в каталоге и в корзине должна показываться уже со скидкой.
- Поддержка разных процентов скидки для категорий.
- Отслеживание правильности отображения в заказах и отчетах.
Пошаговое решение: динамическое изменение цены по категориям
1. Определяем категории и соответствующие скидки
Создадим массив с категориями и скидками в процентах. Например:
function get_category_discounts() {
return [
'sale-category' => 10, // категория 'sale-category' со скидкой 10%
'clearance' => 20, // категория 'clearance' со скидкой 20%
];
}2. Изменяем цену товара на лету с помощью фильтра woocommerce_product_get_price
Добавим функцию, которая проверит категории товара и применит нужную скидку:
add_filter('woocommerce_product_get_price', 'custom_category_based_price', 10, 2);
add_filter('woocommerce_product_get_regular_price', 'custom_category_based_price', 10, 2);
function custom_category_based_price($price, $product) {
$discounts = get_category_discounts();
$categories = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'slugs']);
foreach ($categories as $cat_slug) {
if (isset($discounts[$cat_slug])) {
$discount_percent = $discounts[$cat_slug];
$price = $price * (1 - $discount_percent / 100);
break; // Применяем первую найденную категорию со скидкой
}
}
return round($price, 2);
}3. Обновляем цену для корзины и заказов
Чтобы цена со скидкой корректно отображалась в корзине и учитывалась при оформлении заказа, используем фильтр woocommerce_before_calculate_totals:
add_action('woocommerce_before_calculate_totals', 'custom_category_price_cart', 10, 1);
function custom_category_price_cart($cart) {
if (is_admin() && !defined('DOING_AJAX')) return;
$discounts = get_category_discounts();
foreach ($cart->get_cart() as $cart_item_key => $cart_item) {
$product = $cart_item['data'];
$categories = wp_get_post_terms($product->get_id(), 'product_cat', ['fields' => 'slugs']);
foreach ($categories as $cat_slug) {
if (isset($discounts[$cat_slug])) {
$discount_percent = $discounts[$cat_slug];
$new_price = $product->get_regular_price() * (1 - $discount_percent / 100);
$product->set_price(round($new_price, 2));
break;
}
}
}
}Проверка результата после внедрения
- Перейдите на страницу каталога и убедитесь, что цены товаров из категорий
sale-categoryиclearanceотображаются со скидкой. - Добавьте товары из этих категорий в корзину — цены должны быть пересчитаны.
- Оформите заказ и проверьте, что цена в заказе совпадает с отображаемой со скидкой.
- Проверьте товары из других категорий — их цены не должны изменяться.
Частые ошибки и их исправление
- Цены не меняются на фронтенде: возможно, тема или кэш плагинов кэшируют цену. Очистите кэш и проверьте работу на дефолтной теме.
- Скидка применяется несколько раз: убедитесь, что функция
custom_category_based_priceвызывается только один раз. Избегайте дублирования фильтров. - Некорректное округление цен: всегда используйте
round($price, 2)для правильного формата цены. - Скидка применяется не к тем категориям: проверьте правильность slug категорий и их наличие у товаров.
Практические советы по безопасности и производительности
- Не храните изменённые цены в базе — используйте динамические фильтры, чтобы избежать конфликтов при обновлении товаров.
- Кешируйте результаты
wp_get_post_terms, если на сайте очень много товаров, чтобы снизить нагрузку. - При большом количестве категорий и сложных скидках рассмотрите использование плагинов-кешировщиков WooCommerce, чтобы ускорить выдачу страниц.
- Для управления скидками и акциями более гибко можно использовать плагин Clearfy Pro, который помогает оптимизировать работу магазина и управлять SEO и ценами.
Сравнение вариантов реализации автоматической скидки по категориям
| Метод | Плюсы | Минусы | Пример |
|---|---|---|---|
| Код на хуках WooCommerce | Гибкость, бесплатность, контроль | Требует навыков PHP, возможно замедление без оптимизации | Этот пример статьи |
| Плагины скидок (например, WooCommerce Dynamic Pricing) | Удобство, интерфейс, множество настроек | Платные, нагрузка на сайт | Dynamic Pricing |
| Ручное изменение цен | Простота | Трудозатратно, риск ошибок | Редактирование каждого товара |