WooCommerce: как автоматически отключать товары по заданным условиям

Диагностика проблемы: зачем и когда нужно отключать товары автоматически

В интернет-магазинах на WooCommerce часто возникает задача временно или постоянно отключать товары из каталога при выполнении определённых условий: отсутствие на складе, истечение срока годности, низкая популярность или завершение акции. Ручное управление этим процессом неудобно и ошибочно, особенно при большом ассортименте.

Типичная ошибка — пытаться удалять товары, что приводит к потере данных и SEO. Лучше переводить товары в статус «черновик» или отключать их отображение.

Как определить, что товар нужно отключить

Для автоматизации необходимо чётко определить критерии, по которым товар должен быть выключен. Примеры:

  • Товар отсутствует на складе (stock_quantity = 0)
  • Товар не продаётся более 90 дней (last_sale_date - требуется хранить в метаполях)
  • Дата окончания акции прошла (sale_end_date в метаполях)
  • Товар помечен флагом «неактивен» в пользовательском поле

Пошаговое решение: автоматическое отключение товаров по запасам и дате

1. Создаём пользовательское поле для даты последней продажи

WooCommerce по умолчанию не хранит дату последней продажи, поэтому можно добавить метаполе _last_sale_date и обновлять его при каждом заказе.

add_action('woocommerce_order_status_completed', 'update_last_sale_date_for_products', 10, 1);function update_last_sale_date_for_products( $order_id ) {  $order = wc_get_order( $order_id );  if ( ! $order ) return;  $date = current_time('mysql');  foreach ( $order->get_items() as $item ) {    $product_id = $item->get_product_id();    update_post_meta( $product_id, '_last_sale_date', $date );  }}

2. Создаём функцию, которая отключает товары

Проверяем товары на складе и дату последней продажи. Если условия выполнены, меняем статус товара на «черновик».

function auto_disable_products() {  $args = array(    'post_type' => 'product',    'posts_per_page' => -1,    'post_status' => 'publish',  );  $products = get_posts( $args );  $today = current_time('Y-m-d H:i:s');  foreach ( $products as $product_post ) {    $stock = get_post_meta( $product_post->ID, '_stock', true );    $last_sale = get_post_meta( $product_post->ID, '_last_sale_date', true );    $disable = false;    if ( intval($stock) === 0 ) {      $disable = true;    } elseif ( $last_sale ) {      $diff = ( strtotime($today) - strtotime($last_sale) ) / (60*60*24); // в днях      if ( $diff > 90 ) {        $disable = true;      }    }    if ( $disable ) {      // меняем статус на черновик      $post_update = array(        'ID' => $product_post->ID,        'post_status' => 'draft'      );      wp_update_post( $post_update );    }  }}

3. Автоматизируем запуск с помощью WP-Cron

Добавим ежедневное событие для проверки товаров.

if ( ! wp_next_scheduled( 'auto_disable_products_daily' ) ) {  wp_schedule_event( time(), 'daily', 'auto_disable_products_daily' );}add_action( 'auto_disable_products_daily', 'auto_disable_products' );

Как проверить, что автоматическое отключение сработало

  • Создайте тестовый товар с количеством 0 или без продаж более 90 дней (можно вручную установить дату в метаполе _last_sale_date)
  • Запустите функцию вручную через WP-CLI: wp eval 'auto_disable_products();' и проверьте статус товара в админке (должен стать «черновик»)
  • Проверьте, что при следующем cron-запуске статусы обновляются автоматически

Частые ошибки и способы их устранения

  • Отсутствие данных о последней продаже: без обновления метаполя _last_sale_date отключение по дате не сработает. Проверьте, что хук woocommerce_order_status_completed подключён и работает.
  • Функция слишком тяжёлая для cron: при большом каталоге нужно разбивать запросы на части с помощью пагинации, иначе возможны тайм-ауты.
  • Статус товара не меняется: проверьте права пользователя, под которым запускается cron, и корректность ID товара.

Практические советы по безопасности и производительности

  • Для больших магазинов не используйте posts_per_page = -1, а разбивайте запрос на порции по 100 товаров.
  • Добавьте логи в функцию для отслеживания отключаемых товаров, например, записывайте ID в отдельный лог-файл.
  • Проверьте совместимость с плагинами кэширования и очистку кэша после изменения статуса товара (например, с помощью wc_delete_product_transients($product_id)).
  • Не удаляйте товары — меняйте статус, чтобы сохранить SEO и историю продаж.
  • Используйте WP-Cron вместо системных cron для совместимости с хостингом, но если возможно, настройте системный cron для стабильности.

Сравнение вариантов реализации отключения товаров

Вариант Плюсы Минусы
Ручное отключение в админке Простота, контроль Много времени, ошибки при большом каталоге
Автоматизация через WP-Cron и код Полная автоматизация, гибкость настроек Требует навыков, возможно увеличение нагрузки
Плагины автоматизации (например, WPRemark) Готовые решения, поддержка Потенциальные ограничения, цена
Оптимизация загрузки сайтов WordPress: практические решения и примеры кода
22.11.2025
Как установить и настроить WPRemark для автоматизации управления отзывами в WordPress
31.03.2026
Как удалить или скрыть товары в WooCommerce по атрибутам
17.12.2025
Как использовать WP-CLI для автоматизации задач WordPress
10.12.2025
Как добавить автоматическое сохранение изменений в WordPress
10.11.2025