Проблема: как автоматически отключать товары после окончания акции в WooCommerce
В интернет-магазинах на WooCommerce часто используются акции с ограниченным сроком действия. После окончания периода скидок необходимо оперативно скрыть или отключить товары с акцией, чтобы не вводить покупателей в заблуждение. В ручном режиме это неудобно и приводит к ошибкам. В статье разберём, как реализовать автоматическое отключение товаров по дате окончания акции с помощью кода, без дополнительных плагинов.
Диагностика текущей ситуации
Чаще всего для акций в WooCommerce используется поле Распродажа (Sale price) с указанием даты начала/окончания распродажи (Sale price dates from/to). Если даты не заданы, отключение нужно делать по другим признакам. Проверим, что у товара правильно заполнено поле даты окончания акции:
global $product;
$sale_end_date = get_post_meta($product->get_id(), '_sale_price_dates_to', true);
if ($sale_end_date) {
echo 'Дата окончания акции: ' . date('Y-m-d H:i:s', $sale_end_date);
} else {
echo 'Дата окончания акции не установлена';
}Если даты не установлены, автоматизация отключения невозможна без дополнительного поля или логики.
Пошаговое решение автоматического отключения товаров
1. Добавление Cron-задачи для проверки товаров
Создаём задачу, которая будет запускаться ежедневно, проверять товары с истёкшей датой акции и отключать их (статус переводим в черновик).
function wplinks_deactivate_expired_sale_products() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_sale_price_dates_to',
'value' => time(),
'compare' => '<',
'type' => 'NUMERIC',
],
[
'key' => '_sale_price_dates_to',
'compare' => 'EXISTS',
],
],
'post_status' => 'publish',
];
$products = get_posts($args);
foreach ($products as $product) {
// Переводим товар в черновик
wp_update_post([
'ID' => $product->ID,
'post_status' => 'draft',
]);
}
}
// Регистрируем событие при активации темы или плагина
if (!wp_next_scheduled('wplinks_daily_deactivation_hook')) {
wp_schedule_event(time(), 'daily', 'wplinks_daily_deactivation_hook');
}
add_action('wplinks_daily_deactivation_hook', 'wplinks_deactivate_expired_sale_products');2. Очистка Cron при деактивации
function wplinks_clear_daily_deactivation_cron() {
$timestamp = wp_next_scheduled('wplinks_daily_deactivation_hook');
if ($timestamp) {
wp_unschedule_event($timestamp, 'wplinks_daily_deactivation_hook');
}
}
register_deactivation_hook(__FILE__, 'wplinks_clear_daily_deactivation_cron');3. Восстановление товара при повторном запуске акции
Если нужно автоматически возвращать товар в публикацию при повторном запуске акции, добавьте аналогичный код, который по дате начала акции переводит статус обратно в publish.
function wplinks_activate_products_with_active_sale() {
$args = [
'post_type' => 'product',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => '_sale_price_dates_from',
'value' => time(),
'compare' => '<=',
'type' => 'NUMERIC',
],
[
'key' => '_sale_price_dates_to',
'value' => time(),
'compare' => '>=',
'type' => 'NUMERIC',
],
],
'post_status' => 'draft',
];
$products = get_posts($args);
foreach ($products as $product) {
wp_update_post([
'ID' => $product->ID,
'post_status' => 'publish',
]);
}
}
add_action('wplinks_daily_deactivation_hook', 'wplinks_activate_products_with_active_sale');Как проверить, что автоматическое отключение сработало
- Перейдите в админку WooCommerce → Товары и отфильтруйте по статусу
Черновик. Там должны появиться товары, срок акции которых истёк. - В базе данных в таблице
wp_postsпроверьте полеpost_statusдля соответствующих товаров. - Проверьте логи Cron задач с помощью плагина WP Crontrol или аналогичных.
- Проверьте дату окончания акции у товаров, чтобы подтвердить соответствие условию.
Частые ошибки и как их исправить
- Неверный формат даты окончания акции. WooCommerce хранит дату в Unix timestamp. При использовании кастомных полей убедитесь, что сравнение происходит с типом
NUMERIC. - Cron-задача не срабатывает. Проверьте, не отключён ли WP Cron в
wp-config.php(define('DISABLE_WP_CRON', true);). Если да, настройте системный cron на вызовwp-cron.php. - Товары не переводятся в статус «черновик». Проверьте права пользователя, от имени которого выполняется код, а также отсутствие конфликтов с другими плагинами, которые могут изменять статус.
- Отсутствие даты окончания акции. Если дата окончания не заполнена, код не сможет определить истечение акции. Добавьте проверку и предупреждение в админку или используйте альтернативные метки.
Практические советы по безопасности и производительности
- Запускайте Cron-задачу не чаще раза в сутки, чтобы не нагружать сервер.
- Добавьте лимит постов в запросе и реализуйте постраничную обработку, если товаров много.
- Используйте транзиенты для кеширования результатов, если выполняете дополнительные проверки.
- В продакшене рекомендуем использовать системный cron вместо WP Cron для надёжности.
- Минимизируйте права доступа к функциям, которые изменяют статус товаров, чтобы избежать случайных изменений.
Сравнение вариантов реализации автоматического отключения товаров
| Метод | Преимущества | Недостатки | Пример |
|---|---|---|---|
| Код с WP Cron | Нет плагинов, гибкость, контроль | Зависимость от WP Cron, требует навыков | Код из статьи |
| Плагин автоматизации (например, Scheduled Sale Manager) | Простота настройки, UI | Доп. нагрузка, лицензии | Плагин в репозитории |
| Ручное отключение | Простота | Человеческий фактор, ошибки | Админка WooCommerce |