Диагностика задачи: зачем нужно автоматическое изменение цен
В интернет-магазинах на WooCommerce часто требуется менять цены товаров в зависимости от времени: например, запускать акции в определённые дни, автоматически снижать стоимость на устаревшие товары или повышать цены по окончании распродажи. Ручное изменение цен неудобно и чревато ошибками, особенно при большом ассортименте. Автоматизация решает эту задачу.
Как работает автоматическое изменение цен в WooCommerce
Цены в WooCommerce хранятся в мета-полях товаров: _regular_price — обычная цена, _sale_price — цена со скидкой, _price — текущая цена для отображения. Для изменения цены по расписанию нужно программно менять эти значения и обновлять кэш корзины и страниц.
Реализация чаще всего строится на WP-Cron — встроенном планировщике задач WordPress, который запускает функцию в заданное время.
Пошаговое решение: пример автоматического понижения цены на 20% с 1 по 7 число каждого месяца
1. Добавляем функцию для изменения цен
function wpshab_apply_scheduled_discount() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_regular_price',
'compare' => 'EXISTS'
]
]
];
$products = get_posts($args);
foreach ($products as $product_post) {
$product = wc_get_product($product_post->ID);
if (!$product) continue;
$regular_price = (float) $product->get_regular_price();
if ($regular_price <= 0) continue;
// Рассчитываем скидочную цену
$sale_price = round($regular_price * 0.8, 2); // 20% скидка
// Устанавливаем цену со скидкой
update_post_meta($product->get_id(), '_sale_price', $sale_price);
update_post_meta($product->get_id(), '_price', $sale_price);
// Обновляем дату скидки (опционально)
update_post_meta($product->get_id(), '_sale_price_dates_from', strtotime(date('Y-m-01')));
update_post_meta($product->get_id(), '_sale_price_dates_to', strtotime(date('Y-m-07 23:59:59')));
}
// Очищаем кэш корзины и сессий
if (function_exists('wc_delete_product_transients')) {
wc_delete_product_transients();
}
}
2. Добавляем задачу WP-Cron для запуска функции 1 числа каждого месяца
function wpshab_schedule_monthly_discount() {
if (!wp_next_scheduled('wpshab_monthly_discount_hook')) {
// Запускаем 1 число каждого месяца в 00:05
wp_schedule_event(strtotime('first day of next month 00:05'), 'monthly', 'wpshab_monthly_discount_hook');
}
}
add_action('wp', 'wpshab_schedule_monthly_discount');
add_action('wpshab_monthly_discount_hook', 'wpshab_apply_scheduled_discount');
3. Добавляем функцию для снятия скидок 8 числа
function wpshab_remove_scheduled_discount() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_sale_price',
'compare' => 'EXISTS'
]
]
];
$products = get_posts($args);
foreach ($products as $product_post) {
$product = wc_get_product($product_post->ID);
if (!$product) continue;
// Убираем скидочную цену
delete_post_meta($product->get_id(), '_sale_price');
delete_post_meta($product->get_id(), '_price');
delete_post_meta($product->get_id(), '_sale_price_dates_from');
delete_post_meta($product->get_id(), '_sale_price_dates_to');
// Восстанавливаем регулярную цену как текущую
$regular_price = (float) $product->get_regular_price();
update_post_meta($product->get_id(), '_price', $regular_price);
}
if (function_exists('wc_delete_product_transients')) {
wc_delete_product_transients();
}
}
function wpshab_schedule_discount_removal() {
if (!wp_next_scheduled('wpshab_remove_discount_hook')) {
// Запускаем 8 число каждого месяца в 00:10
wp_schedule_event(strtotime('first day of this month +7 days 00:10'), 'monthly', 'wpshab_remove_discount_hook');
}
}
add_action('wp', 'wpshab_schedule_discount_removal');
add_action('wpshab_remove_discount_hook', 'wpshab_remove_scheduled_discount');
Проверка результата после внедрения
- Убедитесь, что в таблице
wp_postmetaпоявились и обновились мета-поля_sale_priceи_priceдля товаров. - В админке WooCommerce на странице редактирования товара проверьте наличие цены со скидкой в указанный период.
- Проверьте отображение цен на сайте в клиентской части — цена должна быть изменена с 1 по 7 число.
- Для тестирования можно вручную запустить WP-Cron через плагин «WP Control» или вызвать функции напрямую.
Частые ошибки и как их исправить
- Задачи WP-Cron не запускаются автоматически: На некоторых сайтах WP-Cron зависит от посещений. Проверьте, что планировщик работает, или настройте системный cron для запуска
wp-cron.php. - Цены не обновляются на сайте: Проверьте, вызов функции
wc_delete_product_transients()для очистки кэша WooCommerce. - Скидочная цена не отображается: Убедитесь, что в товаре есть задана регулярная цена и что поля
_sale_priceи_priceобновляются в базе. - Функция обновления тормозит сайт: Ограничьте количество товаров в запросе или используйте пакетную обработку (пагинацию) для больших магазинов.
Практические советы по безопасности и производительности
- Не храните логику изменения цен в темах — делайте это в плагине или в functions.php дочерней темы.
- Для больших магазинов с тысячами товаров используйте WP-CLI для запуска задач или внешние cron, чтобы не нагружать сайт при посещениях.
- Добавляйте проверку даты в функции, чтобы не применять скидку вне нужного периода, даже если задача запустилась вручную.
- Регулярно проверяйте журнал ошибок сервера и WP_DEBUG для выявления скрытых проблем с WP-Cron и обновлением метаданных.
Сравнение способов автоматизации изменения цен
| Метод | Плюсы | Минусы |
|---|---|---|
| WP-Cron + пользовательский код | Гибко, бесплатно, без сторонних плагинов | Зависит от посещаемости сайта, требует навыков PHP |
| Плагины для акций (например, WooCommerce Dynamic Pricing) | Готовый функционал, удобный интерфейс | Платные, может нагружать сайт, не всегда гибкие под сложные сценарии |
| Внешний скрипт + WP-CLI | Надежно для больших магазинов, точное время запуска | Сложнее в настройке, нужен доступ к серверу |