Проблема: автоматическое изменение цены товара по акции в WooCommerce
Для интернет-магазинов на WooCommerce часто требуется запускать акции с временным снижением цен. Ручное изменение цен неудобно и чревато ошибками, особенно при большом количестве товаров и ограниченных сроках акции. Нужно настроить автоматическое изменение цены товаров по заданному условию и времени.
Диагностика задачи: что нужно учесть
- Какие товары участвуют в акции — все или по категории/тегу/атрибуту.
- Тип изменения цены — фиксированная скидка, процент, новая цена.
- Период действия акции — дата начала и окончания.
- Обратное изменение цены после окончания акции.
- Совместимость с другими скидками и правилами WooCommerce.
Пошаговое решение: настройка автоматического изменения цены с помощью кода
1. Добавляем метаполя для акционных параметров
Чтобы задать параметры акции для товара, лучше использовать пользовательские поля. К примеру, добавим три поля: sale_price_percent — процент скидки, sale_start_date и sale_end_date — даты начала и окончания акции.
function add_custom_sale_fields() {
woocommerce_wp_text_input( array(
'id' => 'sale_price_percent',
'label' => 'Процент скидки (%)',
'description' => 'Укажите процент скидки на товар в акции',
'type' => 'number',
'custom_attributes' => array('min' => 0, 'max' => 100),
) );
woocommerce_wp_text_input( array(
'id' => 'sale_start_date',
'label' => 'Дата начала акции',
'description' => 'Формат: YYYY-MM-DD',
'type' => 'date',
) );
woocommerce_wp_text_input( array(
'id' => 'sale_end_date',
'label' => 'Дата окончания акции',
'description' => 'Формат: YYYY-MM-DD',
'type' => 'date',
) );
}
add_action( 'woocommerce_product_options_pricing', 'add_custom_sale_fields' );
function save_custom_sale_fields( $post_id ) {
$percent = isset( $_POST['sale_price_percent'] ) ? sanitize_text_field( $_POST['sale_price_percent'] ) : '';
$start = isset( $_POST['sale_start_date'] ) ? sanitize_text_field( $_POST['sale_start_date'] ) : '';
$end = isset( $_POST['sale_end_date'] ) ? sanitize_text_field( $_POST['sale_end_date'] ) : '';
update_post_meta( $post_id, 'sale_price_percent', $percent );
update_post_meta( $post_id, 'sale_start_date', $start );
update_post_meta( $post_id, 'sale_end_date', $end );
}
add_action( 'woocommerce_process_product_meta', 'save_custom_sale_fields' );2. Применяем скидку динамически на фронтенде
Используем фильтр woocommerce_get_price для изменения цены товара при отображении, если сейчас в период акции.
function apply_custom_sale_price( $price, $product ) {
$percent = (int) get_post_meta( $product->get_id(), 'sale_price_percent', true );
$start_date = get_post_meta( $product->get_id(), 'sale_start_date', true );
$end_date = get_post_meta( $product->get_id(), 'sale_end_date', true );
if ( $percent > 0 && $start_date && $end_date ) {
$now = current_time( 'Y-m-d' );
if ( $now >= $start_date && $now <= $end_date ) {
$discount = $price * $percent / 100;
$new_price = $price - $discount;
return max( $new_price, 0 );
}
}
return $price;
}
add_filter( 'woocommerce_get_price', 'apply_custom_sale_price', 10, 2 );3. Обработка вариативных товаров
Для вариативных товаров нужно аналогично применять скидку для каждой вариации. Это можно сделать, заменив фильтр woocommerce_get_price на woocommerce_product_get_price и проверяя тип продукта.
Проверка результата после внедрения
- В админке добавьте в товар значения для
sale_price_percent,sale_start_date,sale_end_date. - Перейдите на страницу товара на фронтенде в указанный период акции.
- Убедитесь, что цена товара изменилась согласно заданной скидке.
- Проверьте, что после окончания даты акция перестает действовать, и цена возвращается к обычной.
- Проверьте в корзине и на странице оформления заказа, что цены корректно изменяются.
Частые ошибки и как их исправить
- Цена не меняется: проверьте правильность сохранения метаполей и формат даты. Используйте
error_log()для отладки. - Дата задается в неверном формате: используйте формат
YYYY-MM-DD, который поддерживается HTML5input type=date. - Скидка применяется вне периода: проверьте локальное время сервера и функцию
current_time('Y-m-d'). - Проблемы с вариативными товарами: убедитесь, что фильтр применяется ко всем типам продуктов, включая вариации.
- Конфликты с другими плагинами скидок: тестируйте на чистой установке, при необходимости используйте приоритеты фильтров.
Практические советы по безопасности и производительности
- Не сохраняйте необработанные данные напрямую — используйте функции санитизации данных.
- Для большого количества товаров с акциями рассмотрите кеширование вычисляемых цен, чтобы не нагружать базу на каждом запросе.
- Используйте транзиенты для кеширования текущих дат акций, если даты массово не меняются.
- Проверяйте совместимость с WooCommerce и WordPress при обновлениях.
Сравнение вариантов реализации автоматической акции
| Метод | Преимущества | Недостатки |
|---|---|---|
| Код через фильтр цены | Гибкость, нет необходимости менять реальные цены, автоматическое отключение | Сложнее для новичков, может конфликтовать с другими скидками |
| Использование стандартного поля Sale price | Простота, поддержка WooCommerce | Нет автоматического включения/отключения, нужно вручную менять цену и даты |
| Плагин для акций и скидок | Готовые интерфейсы, дополнительные функции | Может быть избыточным, влияет на производительность, платные |