Автоматическое удаление товаров с нулевым запасом в WooCommerce

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

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

Пошаговое решение: реализация автопроверки и удаления через wp_cron

1. Создаем функцию для удаления товаров с нулевым запасом

Для начала напишем функцию, которая найдет и удалит все товары, у которых _stock равен 0 и _stock_status равен outofstock.

function wc_delete_out_of_stock_products() {
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'post_status'    => 'publish',
        'meta_query'     => array(
            array(
                'key'     => '_stock',
                'value'   => '0',
                'compare' => '='
            ),
            array(
                'key'     => '_stock_status',
                'value'   => 'outofstock',
                'compare' => '='
            )
        )
    );

    $products = get_posts($args);

    foreach ($products as $product) {
        wp_delete_post($product->ID, true); // true - удалить без корзины
    }
}

2. Создаем событие cron для периодического запуска функции

Добавим хук, который запустит функцию, например, ежедневно.

if (!wp_next_scheduled('wc_daily_delete_out_of_stock')) {
    wp_schedule_event(time(), 'daily', 'wc_daily_delete_out_of_stock');
}

add_action('wc_daily_delete_out_of_stock', 'wc_delete_out_of_stock_products');

3. Добавляем возможность ручного запуска из админки (опционально)

Для контроля полезно иметь кнопку, которая вызовет удаление вручную.

add_action('admin_menu', function() {
    add_submenu_page('woocommerce', 'Удалить товары без запаса', 'Удалить товары без запаса', 'manage_woocommerce', 'wc-delete-out-of-stock', function() {
        if (isset($_POST['wc_delete_out_of_stock'])) {
            wc_delete_out_of_stock_products();
            echo '<div class="updated notice">Товары с нулевым запасом удалены.</div>';
        }
        echo '<form method="post"><input type="submit" name="wc_delete_out_of_stock" class="button button-primary" value="Удалить товары с нулевым запасом" /></form>';
    });
});

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

  • Проверьте, что cron событие запланировано: выполните в консоли wp cron event list (если WP-CLI доступен) и ищите wc_daily_delete_out_of_stock.
  • Создайте тестовый товар с запасом 0 и статусом outofstock, после запуска cron он должен удалиться.
  • Ручной запуск из админки должен удалять все подходящие товары сразу.

Частые ошибки и способы исправления

  • Товары не удаляются, хотя запасы нулевые: проверьте, что мета-ключи _stock и _stock_status действительно существуют и совпадают с условиями запроса. Часто у товаров используется другой способ учета запасов.
  • Cron событие не запускается: убедитесь, что на сайте правильно работает WP Cron. В некоторых случаях необходимо настроить системный cron для надежности.
  • Удаляются не те товары: проверьте условия meta_query, возможно, стоит уточнить статус публикации или добавить дополнительные фильтры.

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

  • Для больших магазинов используйте постраничный запрос с posts_per_page по 50-100 товаров, чтобы избежать превышения времени выполнения скрипта:
function wc_delete_out_of_stock_products_paged($page = 1) {
    $args = array(
        'post_type'      => 'product',
        'posts_per_page' => 50,
        'paged'          => $page,
        'post_status'    => 'publish',
        'meta_query'     => array(
            array(
                'key'     => '_stock',
                'value'   => '0',
                'compare' => '='
            ),
            array(
                'key'     => '_stock_status',
                'value'   => 'outofstock',
                'compare' => '='
            )
        )
    );

    $products = get_posts($args);
    if (empty($products)) {
        return false; // Нет товаров
    }

    foreach ($products as $product) {
        wp_delete_post($product->ID, true);
    }

    return count($products) === 50 ? $page + 1 : false;
}

// Для запуска используйте цикл в cron
$page = 1;
do {
    $page = wc_delete_out_of_stock_products_paged($page);
} while ($page !== false);
  • Перед удалением сделайте резервную копию базы данных.
  • Можно вместо удаления переводить товары в черновики, если хотите сохранить данные:
wp_update_post(array(
    'ID' => $product->ID,
    'post_status' => 'draft'
));

Сравнение вариантов реализации

МетодПлюсыМинусыКомпромисс
Удаление через wp_cronАвтоматизация, не требует вмешательстваЗависит от работы WP Cron, возможен таймаут на больших базахИспользовать постраничный удаленный процесс
Ручное удаление через админкуКонтроль и безопасностьНужно вмешательство администратораКомбинировать с автоматикой
Перевод в черновикиБезопасно, можно восстановитьНе освобождает базу полностьюИспользовать для товаров с возможным возвратом
Запрет доступа по IP в WordPress через .htaccess: решение задачи защиты
27.12.2025
WooCommerce: как автоматически удалять просроченные заказы
26.04.2026
Автоматическое удаление товаров с нулевым запасом в WooCommerce
19.04.2026
Как установить ограничения на подробное отображение пользователей в WordPress
29.01.2026
Как создать автоматический импорт товара из Excel в WooCommerce без плагинов
17.02.2026