Проблема: как автоматически менять цены товаров в WooCommerce по расписанию
Владельцы интернет-магазинов на WooCommerce часто сталкиваются с необходимостью менять цены товаров по расписанию: акции, скидки на выходные, сезонные изменения. Использовать сторонние плагины не всегда удобно из-за лишней нагрузки или стоимости. В статье покажу, как реализовать автоматическое изменение стоимости товаров по расписанию через WP-Cron и хуки WooCommerce, используя PHP-код в functions.php или в собственном плагине.
Диагностика задачи и подготовка
Перед началом убедитесь, что:
- WooCommerce установлен и работает корректно.
- Вы имеете доступ к файлам темы или можете создать кастомный плагин для добавления кода.
- Понимаете, какие товары и на какой период должны менять цену.
В примерах ниже автоматизируем изменение цены всех товаров на 10% вниз каждую пятницу с 00:00 и возврат к исходной цене в понедельник в 00:00.
Шаг 1. Регистрация WP-Cron задачи
Добавим задачу в расписание WordPress, которая будет запускать функцию изменения цен по расписанию.
add_action('init', function() {
if (!wp_next_scheduled('update_woocommerce_prices_cron')) {
wp_schedule_event(strtotime('friday midnight'), 'weekly', 'update_woocommerce_prices_cron');
wp_schedule_event(strtotime('monday midnight'), 'weekly', 'reset_woocommerce_prices_cron');
}
});Здесь мы ставим две задачи: update_woocommerce_prices_cron для снижения цены по пятницам и reset_woocommerce_prices_cron для возврата цен в понедельник.
Шаг 2. Функции для изменения и сброса цен
Создадим две функции, на которые повесим наши хук-события.
add_action('update_woocommerce_prices_cron', 'apply_discount_to_all_products');
add_action('reset_woocommerce_prices_cron', 'reset_prices_to_original');
function apply_discount_to_all_products() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
];
$products = get_posts($args);
foreach ($products as $product_post) {
$product = wc_get_product($product_post->ID);
$regular_price = $product->get_regular_price();
if (!$regular_price) continue;
// Сохраняем оригинальную цену в мета
update_post_meta($product->get_id(), '_original_regular_price', $regular_price);
// Вычисляем новую цену со скидкой 10%
$discounted_price = round($regular_price * 0.9, 2);
$product->set_price($discounted_price);
$product->save();
}
}
function reset_prices_to_original() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'post_status' => 'publish',
'meta_query' => [[
'key' => '_original_regular_price',
'compare' => 'EXISTS'
]]
];
$products = get_posts($args);
foreach ($products as $product_post) {
$product = wc_get_product($product_post->ID);
$original_price = get_post_meta($product->get_id(), '_original_regular_price', true);
if (!$original_price) continue;
$product->set_price($original_price);
$product->save();
// Удаляем мета, так как возврат произведён
delete_post_meta($product->get_id(), '_original_regular_price');
}
}Шаг 3. Проверка результата
Для проверки работы решения:
- Вручную запустите WP-Cron задачу через плагин WP Crontrol или аналог, вызвав событие
update_woocommerce_prices_cron. Убедитесь, что цены товаров уменьшились на 10%. - Запустите событие
reset_woocommerce_prices_cronи проверьте возврат цен к исходным. - Проверьте в админке WooCommerce, что цены отображаются корректно, а в базе есть или удалены метаданные
_original_regular_price.
Частые ошибки и их исправление
- Задачи WP-Cron не запускаются: Обычно связано с редиректами, кешами или отсутствием посетителей на сайте. Для проверки используйте плагин WP Crontrol, чтобы запускать задачи вручную.
- Цены не меняются: Проверьте, что функция получает корректные цены с помощью
get_regular_price(). Возможно, цены товаров не установлены или используются вариативные продукты — для них нужен отдельный подход. - Исходные цены перезаписываются: Убедитесь, что метаданные
_original_regular_priceсохраняются только при первом снижении цены, а не при каждом запуске. В примере выше это не учтено — добавьте проверку перед обновлением мета.
Практические советы по улучшению и безопасности
- Для вариативных товаров реализуйте аналогичную логику для каждого варианта через
WC_Product_Variation. - Добавьте проверку текущей даты в функциях, чтобы точно попадать в нужный временной интервал, на случай если WP-Cron запускается с задержкой.
- Не храните оригинальные цены в пользовательских метаданных, если на сайте много товаров — это нагрузит базу. Лучше использовать transient или отдельную таблицу при больших объемах.
- Используйте nonce и проверки прав при добавлении интерфейса для управления скидками, если планируете расширять функционал.
Сравнение вариантов реализации
| Метод | Плюсы | Минусы |
|---|---|---|
| Использование WP-Cron + PHP | Бесплатно, гибко, без сторонних плагинов, легко кастомизируется | Зависит от посещаемости сайта, требует навыков кода, может быть сложно отлаживать |
| Плагины автоматического изменения цен | Простота использования, часто с GUI, поддержка акций и условий | Нагрузка на сайт, возможны конфликты, платные решения |
| Внешние скрипты (cron на сервере + WP REST API) | Надежно и точно по времени, не зависит от посещаемости | Сложнее в настройке, требует доступа к серверу |