Диагностика задачи: зачем и когда нужно автоматическое изменение цен
В интернет-магазинах на WooCommerce часто возникает необходимость автоматически менять цены товаров или их вариаций по расписанию. Например, для проведения акций, сезонных распродаж или динамического ценообразования. Ручное обновление — трудозатратно и подвержено ошибкам, особенно при большом ассортименте и вариациях.
Если у вас нет специализированного плагина для динамического ценообразования или он не поддерживает вариации, решение на уровне кода поможет сэкономить время и избежать потери прибыли.
Как проверить, что автоматическое изменение цен действительно требуется
- Вы хотите менять цену товаров и вариаций по заранее заданному расписанию без вашего вмешательства.
- В вашем магазине много товаров с вариациями, и цены должны меняться индивидуально.
- Не устраивает ручное обновление или существующие плагины.
Пошаговое решение: реализация автоматического изменения цен в WooCommerce
1. Создаем WP-Cron событие для запуска задачи по расписанию
Добавьте в functions.php вашей дочерней темы или в кастомный плагин следующий код. Он регистрирует ежедневное событие для обновления цен:
if ( ! wp_next_scheduled( 'custom_update_product_prices_daily' ) ) {
wp_schedule_event( time(), 'daily', 'custom_update_product_prices_daily' );
}2. Регистрируем функцию-обработчик для обновления цен
Эта функция будет проходить по нужным товарам и менять цену у товаров и их вариаций.
add_action( 'custom_update_product_prices_daily', 'custom_update_product_prices_callback' );
function custom_update_product_prices_callback() {
// Получаем продукты, которые нужно обновить
$args = [
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_price',
'compare' => 'EXISTS',
]
]
];
$products = get_posts( $args );
foreach ( $products as $product_post ) {
$product = wc_get_product( $product_post->ID );
if ( ! $product ) {
continue;
}
// Пример алгоритма изменения цены: уменьшаем цену на 10%, если сегодня понедельник
$today = date( 'w' ); // 1 - понедельник
if ( $today == 1 ) {
if ( $product->is_type( 'variable' ) ) {
// Обновляем цену вариаций
$variations = $product->get_children();
foreach ( $variations as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation ) {
$regular_price = floatval( $variation->get_regular_price() );
$new_price = round( $regular_price * 0.9, 2 );
$variation->set_price( $new_price );
$variation->save();
}
}
} else {
// Обновляем цену простого товара
$regular_price = floatval( $product->get_regular_price() );
$new_price = round( $regular_price * 0.9, 2 );
$product->set_price( $new_price );
$product->save();
}
} else {
// В остальные дни возвращаем цену к регулярной
if ( $product->is_type( 'variable' ) ) {
$variations = $product->get_children();
foreach ( $variations as $variation_id ) {
$variation = wc_get_product( $variation_id );
if ( $variation ) {
$regular_price = $variation->get_regular_price();
$variation->set_price( $regular_price );
$variation->save();
}
}
} else {
$regular_price = $product->get_regular_price();
$product->set_price( $regular_price );
$product->save();
}
}
}
}
3. Дополнительная настройка расписания (по времени и частоте)
Для более гибкого расписания можно зарегистрировать свои интервалы в WP-Cron:
add_filter( 'cron_schedules', 'custom_cron_schedules' );
function custom_cron_schedules( $schedules ) {
$schedules['every_five_minutes'] = [
'interval' => 300, // 300 секунд = 5 минут
'display' => __( 'Every 5 Minutes' ),
];
return $schedules;
}И заменить 'daily' на 'every_five_minutes' в wp_schedule_event, если нужно чаще.
Проверка результата после внедрения
- Убедитесь, что событие запланировано:
wp cron event listчерез WP-CLI или с помощью плагина WP Crontrol. - Проверьте цены товаров и вариаций в админке до и после срабатывания крон-задачи (например, в понедельник, если код выше).
- Для теста можно временно изменить условие даты в коде или вызвать хук вручную:
do_action( 'custom_update_product_prices_daily' ); - Проверьте в базе данных таблицу
wp_postmeta, что мета-ключ_priceизменяется корректно.
Частые ошибки и как их исправить
- Событие WP-Cron не срабатывает: убедитесь, что на сервере правильно настроен вызов
wp-cron.php(например, через системный cron). Можно принудительно вызвать через WP-CLI. - Цены не меняются: проверьте, что функция вызывается, и что у товаров/вариаций есть заполненное поле
_regular_price. Без регулярной цены цена не изменится. - Изменения не отображаются в магазине: может быть активен кэш (объектный кэш, плагин кэширования). Очистите кэш и проверьте снова.
- Ошибки при обновлении вариаций: убедитесь, что используете корректные методы WC_Product_Variation и проверяете объекты на null.
Практические советы по безопасности и производительности
- Не запускайте WP-Cron слишком часто (минимум 5 минут), чтобы не нагружать сервер.
- Для большого каталога используйте пагинацию выборки товаров (например, постраничный запрос через
WP_Query) и batch-обновление, чтобы избежать таймаутов. - Всегда проверяйте наличие объекта товара перед изменением, чтобы избежать фатальных ошибок.
- Для безопасности не используйте пользовательский ввод в функциях без валидации.
- Если нужна сложная логика ценообразования, рассмотрите хранение правил в отдельной таблице или опциях и загружайте их отдельно.
Сравнение вариантов реализации автоматического изменения цен
| Вариант | Преимущества | Недостатки |
|---|---|---|
| Плагин динамического ценообразования | Простота, готовый интерфейс, поддержка вариаций | Платные решения, ограниченная кастомизация, нагрузка |
| Собственный WP-Cron с кодом | Полный контроль, бесплатное решение, можно интегрировать в логику | Требует знаний PHP, возможно сложнее отлаживать |
| Ручное изменение цен | Простота для небольших магазинов | Трудозатратно, ошибки, не подходит для больших каталогов |