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

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

В стандартной настройке WooCommerce товары с нулевым остатком не удаляются и не отключаются автоматически. Это ведет к появлению в каталоге недоступных для покупки товаров, что ухудшает пользовательский опыт и может негативно сказаться на SEO.

Проверить, остались ли в каталоге товары с нулевым остатком, можно так:

SELECT ID, post_title FROM wp_posts AS p
JOIN wp_postmeta AS pm ON p.ID = pm.post_id
WHERE p.post_type = 'product'
AND pm.meta_key = '_stock'
AND CAST(pm.meta_value AS SIGNED) <= 0
AND p.post_status = 'publish';

Если запрос возвращает строки, значит в магазине есть активные товары с нулевым или отрицательным остатком.

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

1. Автоматическое отключение товаров при достижении нулевого остатка

Для автоматического перехода товаров в статус "черновик" при обнулении склада используйте следующий код. Добавьте его в файл functions.php вашей темы или в отдельный плагин:

add_action('woocommerce_reduce_order_stock', 'auto_draft_product_if_zero_stock', 10, 1);
function auto_draft_product_if_zero_stock($order) {
    foreach ($order->get_items() as $item) {
        $product = $item->get_product();
        if (!$product) continue;
        $stock = $product->get_stock_quantity();
        if ($stock !== null && $stock <= 0) {
            $product->set_status('draft');
            $product->save();
        }
    }
}

Объяснение:

  • woocommerce_reduce_order_stock — срабатывает после уменьшения остатков при оформлении заказа;
  • Функция проверяет остаток товара и переводит его в статус draft, если запас равен или меньше нуля;
  • Таким образом товар перестает отображаться на фронтенде.

2. Автоматическое удаление товаров, которые долго находятся с нулевым остатком

Если вы хотите не просто отключать товары, а удалять их через определенный период, добавьте WP-Cron задачу, например, для удаления товаров с нулевым остатком, не менявших статус более 30 дней:

function schedule_cleanup_zero_stock_products() {
    if (!wp_next_scheduled('cleanup_zero_stock_products_hook')) {
        wp_schedule_event(time(), 'daily', 'cleanup_zero_stock_products_hook');
    }
}
add_action('wp', 'schedule_cleanup_zero_stock_products');

add_action('cleanup_zero_stock_products_hook', 'cleanup_zero_stock_products');

function cleanup_zero_stock_products() {
    $args = [
        'post_type' => 'product',
        'post_status' => 'draft',
        'date_query' => [
            [
                'column' => 'post_modified_gmt',
                'before' => '30 days ago',
            ],
        ],
        'meta_query' => [
            [
                'key' => '_stock',
                'value' => 0,
                'compare' => '=',
                'type' => 'NUMERIC',
            ],
        ],
        'fields' => 'ids',
        'posts_per_page' => -1,
    ];

    $products = get_posts($args);
    foreach ($products as $product_id) {
        wp_delete_post($product_id, true);
    }
}

Этот код:

  • Задает ежедневное событие, вызывающее функцию cleanup_zero_stock_products;
  • Функция находит товары со статусом draft, у которых остаток равен 0 и которые не обновлялись 30 дней;
  • Удаляет найденные товары без возможности восстановления (параметр true в wp_delete_post).

Проверка результата после внедрения

  • Оформите заказ, который полностью расходует остаток товара. После успешного оформления заказа проверьте, что товар сменил статус на draft в админке (Товары > Все товары).
  • Для проверки удаления — создайте тестовый товар с нулевым остатком, установите статус draft, измените дату последнего изменения на 31 день назад (через базу или плагин), затем запустите cron вручную:
wp cron event run cleanup_zero_stock_products_hook
  • Проверьте, что товар удален из базы.

Частые ошибки и как исправить

  • Код не срабатывает после оформления заказа
    Проверьте, что у товаров включен учет запасов в WooCommerce (Настройки > Товары > Управление запасами). Без учета запасов хук woocommerce_reduce_order_stock не сработает.
  • Товары не меняют статус
    Проверьте права пользователя, от имени которого выполняется код (обычно это админ). Если используется кеширование, убедитесь, что данные обновляются корректно.
  • Cron задача не запускается
    WordPress cron зависит от посещений сайта. Для сайтов с низкой посещаемостью настройте системный cron для запуска wp-cron.php или запускайте задачи вручную через WP-CLI.

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

  • Безопасность: не удаляйте товары без бэкапа, особенно если это автоматизация на продакшене. Настройте резервное копирование (например, с помощью плагина Clearfy Pro https://wpshop.ru/plugins/clearfy?utm_source=wpcatalog.ru&utm_medium=article&utm_campaign=woocommerce-kak-avtomatizirovat-udaleniye-tovarov-s-nulevym-ostatkom-i-otkluchat-ih).
  • Производительность: при большом количестве товаров оптимизируйте запросы, разбивайте удаление на партии, чтобы избежать таймаутов.
  • Логирование: добавьте логирование действий удаления для аудита и возможности восстановления.

Сравнение методов отключения и удаления товаров с нулевым остатком

МетодПлюсыМинусыРекомендуется для
Отключение (перевод в draft)Безопасно, можно быстро вернуть товар
Простая реализация
Товар остается в базе, может влиять на SEOМагазины с часто возвращаемыми товарами
Автоматическое удалениеЧистит базу, улучшает производительность
Устраняет дубли и мусор
Риск потери данных без бэкапа
Сложнее восстановить товар
Большие магазины с постоянным обновлением ассортимента
Как автоматизировать обновление каталога в WordPress с помощью кода и плагинов
06.04.2026
WooCommerce: автоматический возврат денег после отмены заказа — настройка и устранение проблем
04.06.2026
Как автоматизировать удаление неактивных пользователей в WordPress
28.03.2026
Как использовать REST API в WordPress для каталогов товаров
12.01.2026
Как создать автоматическую регистрацию пользователей в WordPress с использованием хуков
30.01.2026