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

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

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

Как проверить наличие товаров с нулевым остатком?

Для диагностики воспользуйтесь SQL-запросом к базе данных или стандартным фильтром в админке WooCommerce:

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

Этот запрос вернет список опубликованных товаров с остатком <= 0.

В админке перейдите в Товары → Все товары, добавьте фильтр по наличию (через плагин или кастомный фильтр) или вручную проверьте товары с нулевым остатком.

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

1. Использование WP-Cron для регулярного запуска скрипта

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

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

add_action( 'wpmeta_delete_outofstock_products', 'wpmeta_delete_outofstock_products_callback' );

function wpmeta_delete_outofstock_products_callback() {
    $args = [
        'post_type'      => 'product',
        'posts_per_page' => -1,
        'meta_query'     => [
            [
                'key'     => '_stock',
                'value'   => 0,
                'compare' => '<=',
                'type'    => 'NUMERIC',
            ],
        ],
        'post_status'    => 'publish',
        'fields'         => 'ids',
    ];

    $products = get_posts( $args );

    foreach ( $products as $product_id ) {
        wp_trash_post( $product_id ); // Перемещаем в корзину
    }
}

2. Проверка и удаление из корзины (опционально)

Чтобы полностью удалить товар, можно добавить дополнительный скрипт, например, запускать его еженедельно и удалять из корзины:

if ( ! wp_next_scheduled( 'wpmeta_delete_trashed_products' ) ) {
    wp_schedule_event( time(), 'weekly', 'wpmeta_delete_trashed_products' );
}

add_action( 'wpmeta_delete_trashed_products', 'wpmeta_delete_trashed_products_callback' );

function wpmeta_delete_trashed_products_callback() {
    $args = [
        'post_type'   => 'product',
        'post_status' => 'trash',
        'fields'      => 'ids',
        'posts_per_page' => -1,
    ];

    $trashed_products = get_posts( $args );

    foreach( $trashed_products as $product_id ) {
        wp_delete_post( $product_id, true ); // Полное удаление
    }
}

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

1. Проверьте наличие запланированных задач WP-Cron в админке с помощью плагина WP Crontrol (https://ru.wordpress.org/plugins/wp-crontrol/). Там должны быть события wpmeta_delete_outofstock_products и wpmeta_delete_trashed_products.

2. Для проверки можно временно заменить wp_trash_post на error_log('Удаляем товар ID: ' . $product_id); и посмотреть логи, что функция вызывается и обрабатывает товары.

3. После запуска скрипта в базе данных и в админке товары с нулевым остатком должны отсутствовать или находиться в корзине.

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

  • Отсутствие WP-Cron запуска: Если WP-Cron отключен или не запускается (например, на серверах без посещаемости), скрипт не сработает. Решение: настроить системный cron с вызовом wget -q -O - https://example.com/wp-cron.php?doing_wp_cron >/dev/null 2>&1.
  • Неправильный meta_key: Используйте именно _stock для проверки количества на складе. Иногда используется _stock_status, но он хранит просто 'instock' или 'outofstock'. Для числовой проверки нужен _stock.
  • Удаление нужных товаров: Убедитесь, что товары с нулевым остатком действительно следует удалять. Иногда товары временно отсутствуют на складе, но не должны удаляться без проверки.
  • Пропуск вариативных товаров: Для вариативных товаров нужно проверять остаток каждой вариации, либо учитывать, что у вариативного товара может быть остаток на уровне вариаций, а не самого продукта.

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

  • Вместо полного удаления лучше сначала перемещать товары в корзину, чтобы избежать случайных потерь данных.
  • Для крупных магазинов используйте пагинацию в запросах get_posts, чтобы не перегружать память и базу данных.
  • Добавьте проверку прав пользователя, если функция вызывается из админки или вручную, чтобы избежать несанкционированного удаления.
  • Регулярно делайте резервные копии базы данных перед автоматическими операциями.

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

МетодПлюсыМинусы
Плагин (например, WP All Import + Custom Code)Готовый интерфейс, простота настройкиДополнительная нагрузка, лицензии, меньше контроля
Код на WP-Cron (как в статье)Полный контроль, легковесность, бесплатностьТребует навыков, возможно сложность отладки
Ручное удаление через админкуБезопасно, простоТрудозатратно, риск пропуска товаров
Как создать динамические таблицы в WordPress с помощью плагинов и кода
13.12.2025
Как убрать meta robots noindex с отдельных страниц WordPress
13.01.2026
Как создать автоматические уведомления о новых комментариях в WordPress
08.01.2026
Как автоматически добавить атрибуты alt и title к картинкам в WordPress
10.02.2026
Как использовать WPMeta для автоматизации задач в WordPress
18.01.2026

Совсем скоро здесь откроется ресурс о вордпресс.